1 // Copyright 2016 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/parser/cxfa_box.h"
8
9 #include "xfa/fxfa/parser/cxfa_corner.h"
10 #include "xfa/fxfa/parser/cxfa_measurement.h"
11 #include "xfa/fxfa/parser/xfa_object.h"
12
13 namespace {
14
GetStrokesInternal(CXFA_Node * pNode,std::vector<CXFA_Stroke> * strokes,bool bNull)15 void GetStrokesInternal(CXFA_Node* pNode,
16 std::vector<CXFA_Stroke>* strokes,
17 bool bNull) {
18 strokes->clear();
19 if (!pNode)
20 return;
21
22 strokes->resize(8);
23 int32_t i, j;
24 for (i = 0, j = 0; i < 4; i++) {
25 CXFA_Corner corner =
26 CXFA_Corner(pNode->GetProperty(i, XFA_Element::Corner, i == 0));
27 if (corner || i == 0) {
28 (*strokes)[j] = corner;
29 } else if (!bNull) {
30 if (i == 1 || i == 2)
31 (*strokes)[j] = (*strokes)[0];
32 else
33 (*strokes)[j] = (*strokes)[2];
34 }
35 j++;
36 CXFA_Edge edge =
37 CXFA_Edge(pNode->GetProperty(i, XFA_Element::Edge, i == 0));
38 if (edge || i == 0) {
39 (*strokes)[j] = edge;
40 } else if (!bNull) {
41 if (i == 1 || i == 2)
42 (*strokes)[j] = (*strokes)[1];
43 else
44 (*strokes)[j] = (*strokes)[3];
45 }
46 j++;
47 }
48 }
49
Style3D(const std::vector<CXFA_Stroke> & strokes,CXFA_Stroke & stroke)50 static int32_t Style3D(const std::vector<CXFA_Stroke>& strokes,
51 CXFA_Stroke& stroke) {
52 if (strokes.empty())
53 return 0;
54
55 stroke = strokes[0];
56 for (size_t i = 1; i < strokes.size(); i++) {
57 CXFA_Stroke find = strokes[i];
58 if (!find)
59 continue;
60
61 if (!stroke)
62 stroke = find;
63 else if (stroke.GetStrokeType() != find.GetStrokeType())
64 stroke = find;
65 break;
66 }
67 int32_t iType = stroke.GetStrokeType();
68 if (iType == XFA_ATTRIBUTEENUM_Lowered || iType == XFA_ATTRIBUTEENUM_Raised ||
69 iType == XFA_ATTRIBUTEENUM_Etched ||
70 iType == XFA_ATTRIBUTEENUM_Embossed) {
71 return iType;
72 }
73 return 0;
74 }
75
76 } // namespace
77
GetHand() const78 int32_t CXFA_Box::GetHand() const {
79 if (!m_pNode)
80 return XFA_ATTRIBUTEENUM_Even;
81 return m_pNode->GetEnum(XFA_ATTRIBUTE_Hand);
82 }
83
GetPresence() const84 int32_t CXFA_Box::GetPresence() const {
85 if (!m_pNode)
86 return XFA_ATTRIBUTEENUM_Hidden;
87 return m_pNode->GetEnum(XFA_ATTRIBUTE_Presence);
88 }
89
CountEdges() const90 int32_t CXFA_Box::CountEdges() const {
91 if (!m_pNode)
92 return 0;
93 return m_pNode->CountChildren(XFA_Element::Edge);
94 }
95
GetEdge(int32_t nIndex) const96 CXFA_Edge CXFA_Box::GetEdge(int32_t nIndex) const {
97 return CXFA_Edge(
98 m_pNode ? m_pNode->GetProperty(nIndex, XFA_Element::Edge, nIndex == 0)
99 : nullptr);
100 }
101
GetStrokes(std::vector<CXFA_Stroke> * strokes) const102 void CXFA_Box::GetStrokes(std::vector<CXFA_Stroke>* strokes) const {
103 GetStrokesInternal(m_pNode, strokes, false);
104 }
105
IsCircular() const106 bool CXFA_Box::IsCircular() const {
107 if (!m_pNode)
108 return false;
109 return m_pNode->GetBoolean(XFA_ATTRIBUTE_Circular);
110 }
111
GetStartAngle(FX_FLOAT & fStartAngle) const112 bool CXFA_Box::GetStartAngle(FX_FLOAT& fStartAngle) const {
113 fStartAngle = 0;
114 if (!m_pNode)
115 return false;
116
117 CXFA_Measurement ms;
118 bool bRet = m_pNode->TryMeasure(XFA_ATTRIBUTE_StartAngle, ms, false);
119 if (bRet)
120 fStartAngle = ms.GetValue();
121
122 return bRet;
123 }
124
GetSweepAngle(FX_FLOAT & fSweepAngle) const125 bool CXFA_Box::GetSweepAngle(FX_FLOAT& fSweepAngle) const {
126 fSweepAngle = 360;
127 if (!m_pNode)
128 return false;
129
130 CXFA_Measurement ms;
131 bool bRet = m_pNode->TryMeasure(XFA_ATTRIBUTE_SweepAngle, ms, false);
132 if (bRet)
133 fSweepAngle = ms.GetValue();
134
135 return bRet;
136 }
137
GetFill(bool bModified) const138 CXFA_Fill CXFA_Box::GetFill(bool bModified) const {
139 if (!m_pNode)
140 return CXFA_Fill(nullptr);
141
142 CXFA_Node* pFillNode = m_pNode->GetProperty(0, XFA_Element::Fill, bModified);
143 return CXFA_Fill(pFillNode);
144 }
145
GetMargin() const146 CXFA_Margin CXFA_Box::GetMargin() const {
147 return CXFA_Margin(m_pNode ? m_pNode->GetChild(0, XFA_Element::Margin)
148 : nullptr);
149 }
150
Get3DStyle(bool & bVisible,FX_FLOAT & fThickness) const151 int32_t CXFA_Box::Get3DStyle(bool& bVisible, FX_FLOAT& fThickness) const {
152 if (IsArc())
153 return 0;
154
155 std::vector<CXFA_Stroke> strokes;
156 GetStrokesInternal(m_pNode, &strokes, true);
157 CXFA_Stroke stroke(nullptr);
158 int32_t iType = Style3D(strokes, stroke);
159 if (iType) {
160 bVisible = stroke.IsVisible();
161 fThickness = stroke.GetThickness();
162 }
163 return iType;
164 }
165