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/xfa_object.h"
11
12 namespace {
13
GetStrokesInternal(CXFA_Node * pNode,CXFA_StrokeArray & strokes,FX_BOOL bNull)14 void GetStrokesInternal(CXFA_Node* pNode,
15 CXFA_StrokeArray& strokes,
16 FX_BOOL bNull) {
17 strokes.RemoveAll();
18 if (!pNode)
19 return;
20
21 strokes.SetSize(8);
22 int32_t i, j;
23 for (i = 0, j = 0; i < 4; i++) {
24 CXFA_Corner corner =
25 CXFA_Corner(pNode->GetProperty(i, XFA_Element::Corner, i == 0));
26 if (corner || i == 0)
27 strokes.SetAt(j, corner);
28 else if (bNull)
29 strokes.SetAt(j, CXFA_Stroke(nullptr));
30 else if (i == 1)
31 strokes.SetAt(j, strokes[0]);
32 else if (i == 2)
33 strokes.SetAt(j, strokes[0]);
34 else
35 strokes.SetAt(j, strokes[2]);
36
37 j++;
38 CXFA_Edge edge =
39 CXFA_Edge(pNode->GetProperty(i, XFA_Element::Edge, i == 0));
40 if (edge || i == 0)
41 strokes.SetAt(j, edge);
42 else if (bNull)
43 strokes.SetAt(j, CXFA_Stroke(nullptr));
44 else if (i == 1)
45 strokes.SetAt(j, strokes[1]);
46 else if (i == 2)
47 strokes.SetAt(j, strokes[1]);
48 else
49 strokes.SetAt(j, strokes[3]);
50
51 j++;
52 }
53 }
54
Style3D(const CXFA_StrokeArray & strokes,CXFA_Stroke & stroke)55 static int32_t Style3D(const CXFA_StrokeArray& strokes, CXFA_Stroke& stroke) {
56 int32_t iCount = strokes.GetSize();
57 if (iCount < 1)
58 return 0;
59
60 stroke = strokes[0];
61 for (int32_t i = 1; i < iCount; i++) {
62 CXFA_Stroke find = strokes[i];
63 if (!find)
64 continue;
65
66 if (!stroke)
67 stroke = find;
68 else if (stroke.GetStrokeType() != find.GetStrokeType())
69 stroke = find;
70 break;
71 }
72 int32_t iType = stroke.GetStrokeType();
73 if (iType == XFA_ATTRIBUTEENUM_Lowered || iType == XFA_ATTRIBUTEENUM_Raised ||
74 iType == XFA_ATTRIBUTEENUM_Etched ||
75 iType == XFA_ATTRIBUTEENUM_Embossed) {
76 return iType;
77 }
78 return 0;
79 }
80
81 } // namespace
82
GetHand() const83 int32_t CXFA_Box::GetHand() const {
84 if (!m_pNode)
85 return XFA_ATTRIBUTEENUM_Even;
86 return m_pNode->GetEnum(XFA_ATTRIBUTE_Hand);
87 }
88
GetPresence() const89 int32_t CXFA_Box::GetPresence() const {
90 if (!m_pNode)
91 return XFA_ATTRIBUTEENUM_Hidden;
92 return m_pNode->GetEnum(XFA_ATTRIBUTE_Presence);
93 }
94
CountEdges() const95 int32_t CXFA_Box::CountEdges() const {
96 if (!m_pNode)
97 return 0;
98 return m_pNode->CountChildren(XFA_Element::Edge);
99 }
100
GetEdge(int32_t nIndex) const101 CXFA_Edge CXFA_Box::GetEdge(int32_t nIndex) const {
102 return CXFA_Edge(
103 m_pNode ? m_pNode->GetProperty(nIndex, XFA_Element::Edge, nIndex == 0)
104 : nullptr);
105 }
106
GetStrokes(CXFA_StrokeArray & strokes) const107 void CXFA_Box::GetStrokes(CXFA_StrokeArray& strokes) const {
108 GetStrokesInternal(m_pNode, strokes, FALSE);
109 }
110
IsCircular() const111 FX_BOOL CXFA_Box::IsCircular() const {
112 if (!m_pNode)
113 return FALSE;
114 return m_pNode->GetBoolean(XFA_ATTRIBUTE_Circular);
115 }
116
GetStartAngle(FX_FLOAT & fStartAngle) const117 FX_BOOL CXFA_Box::GetStartAngle(FX_FLOAT& fStartAngle) const {
118 fStartAngle = 0;
119 if (!m_pNode)
120 return FALSE;
121
122 CXFA_Measurement ms;
123 FX_BOOL bRet = m_pNode->TryMeasure(XFA_ATTRIBUTE_StartAngle, ms, FALSE);
124 if (bRet)
125 fStartAngle = ms.GetValue();
126
127 return bRet;
128 }
129
GetSweepAngle(FX_FLOAT & fSweepAngle) const130 FX_BOOL CXFA_Box::GetSweepAngle(FX_FLOAT& fSweepAngle) const {
131 fSweepAngle = 360;
132 if (!m_pNode)
133 return FALSE;
134
135 CXFA_Measurement ms;
136 FX_BOOL bRet = m_pNode->TryMeasure(XFA_ATTRIBUTE_SweepAngle, ms, FALSE);
137 if (bRet)
138 fSweepAngle = ms.GetValue();
139
140 return bRet;
141 }
142
GetFill(FX_BOOL bModified) const143 CXFA_Fill CXFA_Box::GetFill(FX_BOOL bModified) const {
144 if (!m_pNode)
145 return CXFA_Fill(nullptr);
146
147 CXFA_Node* pFillNode = m_pNode->GetProperty(0, XFA_Element::Fill, bModified);
148 return CXFA_Fill(pFillNode);
149 }
150
GetMargin() const151 CXFA_Margin CXFA_Box::GetMargin() const {
152 return CXFA_Margin(m_pNode ? m_pNode->GetChild(0, XFA_Element::Margin)
153 : nullptr);
154 }
155
Get3DStyle(FX_BOOL & bVisible,FX_FLOAT & fThickness) const156 int32_t CXFA_Box::Get3DStyle(FX_BOOL& bVisible, FX_FLOAT& fThickness) const {
157 if (IsArc())
158 return 0;
159
160 CXFA_StrokeArray strokes;
161 GetStrokesInternal(m_pNode, strokes, TRUE);
162 CXFA_Stroke stroke(nullptr);
163 int32_t iType = Style3D(strokes, stroke);
164 if (iType) {
165 bVisible = stroke.IsVisible();
166 fThickness = stroke.GetThickness();
167 }
168 return iType;
169 }
170