cxfa_box.cpp revision 33357cad1fd1321a2b38d2963e2585f27ce980a2
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
13namespace {
14
15void 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
50static 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
78int32_t CXFA_Box::GetHand() const {
79  if (!m_pNode)
80    return XFA_ATTRIBUTEENUM_Even;
81  return m_pNode->GetEnum(XFA_ATTRIBUTE_Hand);
82}
83
84int32_t CXFA_Box::GetPresence() const {
85  if (!m_pNode)
86    return XFA_ATTRIBUTEENUM_Hidden;
87  return m_pNode->GetEnum(XFA_ATTRIBUTE_Presence);
88}
89
90int32_t CXFA_Box::CountEdges() const {
91  if (!m_pNode)
92    return 0;
93  return m_pNode->CountChildren(XFA_Element::Edge);
94}
95
96CXFA_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
102void CXFA_Box::GetStrokes(std::vector<CXFA_Stroke>* strokes) const {
103  GetStrokesInternal(m_pNode, strokes, false);
104}
105
106bool CXFA_Box::IsCircular() const {
107  if (!m_pNode)
108    return false;
109  return m_pNode->GetBoolean(XFA_ATTRIBUTE_Circular);
110}
111
112bool 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
125bool 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
138CXFA_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
146CXFA_Margin CXFA_Box::GetMargin() const {
147  return CXFA_Margin(m_pNode ? m_pNode->GetChild(0, XFA_Element::Margin)
148                             : nullptr);
149}
150
151int32_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