• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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