1 // Copyright 2017 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "xfa/fxfa/cxfa_ffline.h"
8
9 #include "xfa/fxfa/parser/cxfa_edge.h"
10 #include "xfa/fxfa/parser/cxfa_line.h"
11 #include "xfa/fxfa/parser/cxfa_value.h"
12 #include "xfa/fxgraphics/cxfa_gecolor.h"
13 #include "xfa/fxgraphics/cxfa_gepath.h"
14 #include "xfa/fxgraphics/cxfa_graphics.h"
15
16 namespace {
17
LineCapToFXGE(XFA_AttributeEnum iLineCap)18 CFX_GraphStateData::LineCap LineCapToFXGE(XFA_AttributeEnum iLineCap) {
19 switch (iLineCap) {
20 case XFA_AttributeEnum::Round:
21 return CFX_GraphStateData::LineCapRound;
22 case XFA_AttributeEnum::Butt:
23 return CFX_GraphStateData::LineCapButt;
24 default:
25 break;
26 }
27 return CFX_GraphStateData::LineCapSquare;
28 }
29
30 } // namespace
31
CXFA_FFLine(CXFA_Node * pNode)32 CXFA_FFLine::CXFA_FFLine(CXFA_Node* pNode) : CXFA_FFDraw(pNode) {}
33
~CXFA_FFLine()34 CXFA_FFLine::~CXFA_FFLine() {}
35
GetRectFromHand(CFX_RectF & rect,XFA_AttributeEnum iHand,float fLineWidth)36 void CXFA_FFLine::GetRectFromHand(CFX_RectF& rect,
37 XFA_AttributeEnum iHand,
38 float fLineWidth) {
39 float fHalfWidth = fLineWidth / 2.0f;
40 if (rect.height < 1.0f) {
41 switch (iHand) {
42 case XFA_AttributeEnum::Left:
43 rect.top -= fHalfWidth;
44 break;
45 case XFA_AttributeEnum::Right:
46 rect.top += fHalfWidth;
47 case XFA_AttributeEnum::Even:
48 break;
49 default:
50 NOTREACHED();
51 break;
52 }
53 } else if (rect.width < 1.0f) {
54 switch (iHand) {
55 case XFA_AttributeEnum::Left:
56 rect.left += fHalfWidth;
57 break;
58 case XFA_AttributeEnum::Right:
59 rect.left += fHalfWidth;
60 break;
61 case XFA_AttributeEnum::Even:
62 break;
63 default:
64 NOTREACHED();
65 break;
66 }
67 } else {
68 switch (iHand) {
69 case XFA_AttributeEnum::Left:
70 rect.Inflate(fHalfWidth, fHalfWidth);
71 break;
72 case XFA_AttributeEnum::Right:
73 rect.Deflate(fHalfWidth, fHalfWidth);
74 break;
75 case XFA_AttributeEnum::Even:
76 break;
77 default:
78 NOTREACHED();
79 break;
80 }
81 }
82 }
83
RenderWidget(CXFA_Graphics * pGS,const CFX_Matrix & matrix,uint32_t dwStatus)84 void CXFA_FFLine::RenderWidget(CXFA_Graphics* pGS,
85 const CFX_Matrix& matrix,
86 uint32_t dwStatus) {
87 if (!IsMatchVisibleStatus(dwStatus))
88 return;
89
90 CXFA_Value* value = m_pNode->GetFormValueIfExists();
91 if (!value)
92 return;
93
94 FX_ARGB lineColor = 0xFF000000;
95 float fLineWidth = 1.0f;
96 XFA_AttributeEnum iStrokeType = XFA_AttributeEnum::Unknown;
97 XFA_AttributeEnum iCap = XFA_AttributeEnum::Unknown;
98
99 CXFA_Line* line = value->GetLineIfExists();
100 if (line) {
101 CXFA_Edge* edge = line->GetEdgeIfExists();
102 if (edge && !edge->IsVisible())
103 return;
104
105 if (edge) {
106 lineColor = edge->GetColor();
107 iStrokeType = edge->GetStrokeType();
108 fLineWidth = edge->GetThickness();
109 iCap = edge->GetCapType();
110 }
111 }
112
113 CFX_Matrix mtRotate = GetRotateMatrix();
114 mtRotate.Concat(matrix);
115
116 CFX_RectF rtLine = GetRectWithoutRotate();
117 CXFA_Margin* margin = m_pNode->GetMarginIfExists();
118 if (margin)
119 XFA_RectWithoutMargin(rtLine, margin);
120
121 GetRectFromHand(rtLine, line ? line->GetHand() : XFA_AttributeEnum::Left,
122 fLineWidth);
123 CXFA_GEPath linePath;
124 if (line && line->GetSlope() && rtLine.right() > 0.0f &&
125 rtLine.bottom() > 0.0f) {
126 linePath.AddLine(rtLine.TopRight(), rtLine.BottomLeft());
127 } else {
128 linePath.AddLine(rtLine.TopLeft(), rtLine.BottomRight());
129 }
130
131 pGS->SaveGraphState();
132 pGS->SetLineWidth(fLineWidth);
133 pGS->EnableActOnDash();
134 XFA_StrokeTypeSetLineDash(pGS, iStrokeType, iCap);
135
136 pGS->SetStrokeColor(CXFA_GEColor(lineColor));
137 pGS->SetLineCap(LineCapToFXGE(iCap));
138 pGS->StrokePath(&linePath, &mtRotate);
139 pGS->RestoreGraphState();
140 }
141