xref: /aosp_15_r20/external/pdfium/xfa/fxfa/cxfa_ffline.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2017 The PDFium Authors
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 "third_party/base/notreached.h"
10 #include "xfa/fgas/graphics/cfgas_gecolor.h"
11 #include "xfa/fgas/graphics/cfgas_gegraphics.h"
12 #include "xfa/fgas/graphics/cfgas_gepath.h"
13 #include "xfa/fxfa/parser/cxfa_edge.h"
14 #include "xfa/fxfa/parser/cxfa_line.h"
15 #include "xfa/fxfa/parser/cxfa_value.h"
16 
17 namespace {
18 
LineCapToFXGE(XFA_AttributeValue iLineCap)19 CFX_GraphStateData::LineCap LineCapToFXGE(XFA_AttributeValue iLineCap) {
20   switch (iLineCap) {
21     case XFA_AttributeValue::Round:
22       return CFX_GraphStateData::LineCap::kRound;
23     case XFA_AttributeValue::Butt:
24       return CFX_GraphStateData::LineCap::kButt;
25     default:
26       return CFX_GraphStateData::LineCap::kSquare;
27   }
28 }
29 
30 }  // namespace
31 
CXFA_FFLine(CXFA_Node * pNode)32 CXFA_FFLine::CXFA_FFLine(CXFA_Node* pNode) : CXFA_FFWidget(pNode) {}
33 
34 CXFA_FFLine::~CXFA_FFLine() = default;
35 
GetRectFromHand(CFX_RectF & rect,XFA_AttributeValue iHand,float fLineWidth)36 void CXFA_FFLine::GetRectFromHand(CFX_RectF& rect,
37                                   XFA_AttributeValue iHand,
38                                   float fLineWidth) {
39   float fHalfWidth = fLineWidth / 2.0f;
40   if (rect.height < 1.0f) {
41     switch (iHand) {
42       case XFA_AttributeValue::Left:
43         rect.top -= fHalfWidth;
44         break;
45       case XFA_AttributeValue::Right:
46         rect.top += fHalfWidth;
47         break;
48       case XFA_AttributeValue::Even:
49         break;
50       default:
51         NOTREACHED_NORETURN();
52     }
53   } else if (rect.width < 1.0f) {
54     switch (iHand) {
55       case XFA_AttributeValue::Left:
56         rect.left += fHalfWidth;
57         break;
58       case XFA_AttributeValue::Right:
59         rect.left += fHalfWidth;
60         break;
61       case XFA_AttributeValue::Even:
62         break;
63       default:
64         NOTREACHED_NORETURN();
65     }
66   } else {
67     switch (iHand) {
68       case XFA_AttributeValue::Left:
69         rect.Inflate(fHalfWidth, fHalfWidth);
70         break;
71       case XFA_AttributeValue::Right:
72         rect.Deflate(fHalfWidth, fHalfWidth);
73         break;
74       case XFA_AttributeValue::Even:
75         break;
76       default:
77         NOTREACHED_NORETURN();
78     }
79   }
80 }
81 
RenderWidget(CFGAS_GEGraphics * pGS,const CFX_Matrix & matrix,HighlightOption highlight)82 void CXFA_FFLine::RenderWidget(CFGAS_GEGraphics* pGS,
83                                const CFX_Matrix& matrix,
84                                HighlightOption highlight) {
85   if (!HasVisibleStatus())
86     return;
87 
88   CXFA_Value* value = m_pNode->GetFormValueIfExists();
89   if (!value)
90     return;
91 
92   FX_ARGB lineColor = 0xFF000000;
93   float fLineWidth = 1.0f;
94   XFA_AttributeValue iStrokeType = XFA_AttributeValue::Unknown;
95   XFA_AttributeValue iCap = XFA_AttributeValue::Unknown;
96   CXFA_Line* line = value->GetLineIfExists();
97   if (line) {
98     CXFA_Edge* edge = line->GetEdgeIfExists();
99     if (edge && !edge->IsVisible())
100       return;
101 
102     if (edge) {
103       lineColor = edge->GetColor();
104       iStrokeType = edge->GetStrokeType();
105       fLineWidth = edge->GetThickness();
106       iCap = edge->GetCapType();
107     }
108   }
109 
110   CFX_Matrix mtRotate = GetRotateMatrix();
111   mtRotate.Concat(matrix);
112 
113   CFX_RectF rtLine = GetRectWithoutRotate();
114   CXFA_Margin* margin = m_pNode->GetMarginIfExists();
115   XFA_RectWithoutMargin(&rtLine, margin);
116 
117   GetRectFromHand(rtLine, line ? line->GetHand() : XFA_AttributeValue::Left,
118                   fLineWidth);
119   CFGAS_GEPath linePath;
120   if (line && line->GetSlope() && rtLine.right() > 0.0f &&
121       rtLine.bottom() > 0.0f) {
122     linePath.AddLine(rtLine.TopRight(), rtLine.BottomLeft());
123   } else {
124     linePath.AddLine(rtLine.TopLeft(), rtLine.BottomRight());
125   }
126 
127   CFGAS_GEGraphics::StateRestorer restorer(pGS);
128   pGS->SetLineWidth(fLineWidth);
129   pGS->EnableActOnDash();
130   XFA_StrokeTypeSetLineDash(pGS, iStrokeType, iCap);
131 
132   pGS->SetStrokeColor(CFGAS_GEColor(lineColor));
133   pGS->SetLineCap(LineCapToFXGE(iCap));
134   pGS->StrokePath(linePath, mtRotate);
135 }
136