| // Copyright 2017 The PDFium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| |
| #include "xfa/fxfa/cxfa_ffline.h" |
| |
| #include "core/fxcrt/notreached.h" |
| #include "xfa/fgas/graphics/cfgas_gecolor.h" |
| #include "xfa/fgas/graphics/cfgas_gegraphics.h" |
| #include "xfa/fgas/graphics/cfgas_gepath.h" |
| #include "xfa/fxfa/parser/cxfa_edge.h" |
| #include "xfa/fxfa/parser/cxfa_line.h" |
| #include "xfa/fxfa/parser/cxfa_value.h" |
| |
| namespace { |
| |
| CFX_GraphStateData::LineCap LineCapToFXGE(XFA_AttributeValue iLineCap) { |
| switch (iLineCap) { |
| case XFA_AttributeValue::Round: |
| return CFX_GraphStateData::LineCap::kRound; |
| case XFA_AttributeValue::Butt: |
| return CFX_GraphStateData::LineCap::kButt; |
| default: |
| return CFX_GraphStateData::LineCap::kSquare; |
| } |
| } |
| |
| } // namespace |
| |
| CXFA_FFLine::CXFA_FFLine(CXFA_Node* pNode) : CXFA_FFWidget(pNode) {} |
| |
| CXFA_FFLine::~CXFA_FFLine() = default; |
| |
| void CXFA_FFLine::GetRectFromHand(CFX_RectF& rect, |
| XFA_AttributeValue iHand, |
| float fLineWidth) { |
| float fHalfWidth = fLineWidth / 2.0f; |
| if (rect.height < 1.0f) { |
| switch (iHand) { |
| case XFA_AttributeValue::Left: |
| rect.top -= fHalfWidth; |
| break; |
| case XFA_AttributeValue::Right: |
| rect.top += fHalfWidth; |
| break; |
| case XFA_AttributeValue::Even: |
| break; |
| default: |
| NOTREACHED_NORETURN(); |
| } |
| } else if (rect.width < 1.0f) { |
| switch (iHand) { |
| case XFA_AttributeValue::Left: |
| rect.left += fHalfWidth; |
| break; |
| case XFA_AttributeValue::Right: |
| rect.left += fHalfWidth; |
| break; |
| case XFA_AttributeValue::Even: |
| break; |
| default: |
| NOTREACHED_NORETURN(); |
| } |
| } else { |
| switch (iHand) { |
| case XFA_AttributeValue::Left: |
| rect.Inflate(fHalfWidth, fHalfWidth); |
| break; |
| case XFA_AttributeValue::Right: |
| rect.Deflate(fHalfWidth, fHalfWidth); |
| break; |
| case XFA_AttributeValue::Even: |
| break; |
| default: |
| NOTREACHED_NORETURN(); |
| } |
| } |
| } |
| |
| void CXFA_FFLine::RenderWidget(CFGAS_GEGraphics* pGS, |
| const CFX_Matrix& matrix, |
| HighlightOption highlight) { |
| if (!HasVisibleStatus()) |
| return; |
| |
| CXFA_Value* value = m_pNode->GetFormValueIfExists(); |
| if (!value) |
| return; |
| |
| FX_ARGB lineColor = 0xFF000000; |
| float fLineWidth = 1.0f; |
| XFA_AttributeValue iStrokeType = XFA_AttributeValue::Unknown; |
| XFA_AttributeValue iCap = XFA_AttributeValue::Unknown; |
| CXFA_Line* line = value->GetLineIfExists(); |
| if (line) { |
| CXFA_Edge* edge = line->GetEdgeIfExists(); |
| if (edge && !edge->IsVisible()) |
| return; |
| |
| if (edge) { |
| lineColor = edge->GetColor(); |
| iStrokeType = edge->GetStrokeType(); |
| fLineWidth = edge->GetThickness(); |
| iCap = edge->GetCapType(); |
| } |
| } |
| |
| CFX_Matrix mtRotate = GetRotateMatrix(); |
| mtRotate.Concat(matrix); |
| |
| CFX_RectF rtLine = GetRectWithoutRotate(); |
| CXFA_Margin* margin = m_pNode->GetMarginIfExists(); |
| XFA_RectWithoutMargin(&rtLine, margin); |
| |
| GetRectFromHand(rtLine, line ? line->GetHand() : XFA_AttributeValue::Left, |
| fLineWidth); |
| CFGAS_GEPath linePath; |
| if (line && line->GetSlope() && rtLine.right() > 0.0f && |
| rtLine.bottom() > 0.0f) { |
| linePath.AddLine(rtLine.TopRight(), rtLine.BottomLeft()); |
| } else { |
| linePath.AddLine(rtLine.TopLeft(), rtLine.BottomRight()); |
| } |
| |
| CFGAS_GEGraphics::StateRestorer restorer(pGS); |
| pGS->SetLineWidth(fLineWidth); |
| pGS->EnableActOnDash(); |
| XFA_StrokeTypeSetLineDash(pGS, iStrokeType, iCap); |
| |
| pGS->SetStrokeColor(CFGAS_GEColor(lineColor)); |
| pGS->SetLineCap(LineCapToFXGE(iCap)); |
| pGS->StrokePath(linePath, mtRotate); |
| } |