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