| // Copyright 2016 PDFium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| |
| #include "xfa/fxfa/parser/cxfa_boxdata.h" |
| |
| #include "xfa/fxfa/parser/cxfa_corner.h" |
| #include "xfa/fxfa/parser/cxfa_cornerdata.h" |
| #include "xfa/fxfa/parser/cxfa_edge.h" |
| #include "xfa/fxfa/parser/cxfa_fill.h" |
| #include "xfa/fxfa/parser/cxfa_margin.h" |
| #include "xfa/fxfa/parser/cxfa_measurement.h" |
| #include "xfa/fxfa/parser/cxfa_node.h" |
| |
| namespace { |
| |
| std::vector<CXFA_StrokeData> GetStrokesInternal(CXFA_Node* pNode, bool bNull) { |
| if (!pNode) |
| return {}; |
| |
| std::vector<CXFA_StrokeData> strokes; |
| strokes.resize(8); |
| int32_t i, j; |
| for (i = 0, j = 0; i < 4; i++) { |
| CXFA_CornerData cornerData = |
| CXFA_CornerData(pNode->JSObject()->GetProperty<CXFA_Corner>( |
| i, XFA_Element::Corner, i == 0)); |
| if (cornerData.HasValidNode() || i == 0) { |
| strokes[j] = cornerData; |
| } else if (!bNull) { |
| if (i == 1 || i == 2) |
| strokes[j] = strokes[0]; |
| else |
| strokes[j] = strokes[2]; |
| } |
| j++; |
| CXFA_EdgeData edgeData = |
| CXFA_EdgeData(pNode->JSObject()->GetProperty<CXFA_Edge>( |
| i, XFA_Element::Edge, i == 0)); |
| if (edgeData.HasValidNode() || i == 0) { |
| strokes[j] = edgeData; |
| } else if (!bNull) { |
| if (i == 1 || i == 2) |
| strokes[j] = strokes[1]; |
| else |
| strokes[j] = strokes[3]; |
| } |
| j++; |
| } |
| return strokes; |
| } |
| |
| static XFA_AttributeEnum Style3D(const std::vector<CXFA_StrokeData>& strokes, |
| CXFA_StrokeData& strokeData) { |
| if (strokes.empty()) |
| return XFA_AttributeEnum::Unknown; |
| |
| strokeData = strokes[0]; |
| for (size_t i = 1; i < strokes.size(); i++) { |
| CXFA_StrokeData find = strokes[i]; |
| if (!find.HasValidNode()) |
| continue; |
| |
| if (!strokeData.HasValidNode()) |
| strokeData = find; |
| else if (strokeData.GetStrokeType() != find.GetStrokeType()) |
| strokeData = find; |
| break; |
| } |
| |
| XFA_AttributeEnum iType = strokeData.GetStrokeType(); |
| if (iType == XFA_AttributeEnum::Lowered || |
| iType == XFA_AttributeEnum::Raised || |
| iType == XFA_AttributeEnum::Etched || |
| iType == XFA_AttributeEnum::Embossed) { |
| return iType; |
| } |
| return XFA_AttributeEnum::Unknown; |
| } |
| |
| } // namespace |
| |
| XFA_AttributeEnum CXFA_BoxData::GetHand() const { |
| if (!m_pNode) |
| return XFA_AttributeEnum::Even; |
| return m_pNode->JSObject()->GetEnum(XFA_Attribute::Hand); |
| } |
| |
| XFA_AttributeEnum CXFA_BoxData::GetPresence() const { |
| if (!m_pNode) |
| return XFA_AttributeEnum::Hidden; |
| return m_pNode->JSObject() |
| ->TryEnum(XFA_Attribute::Presence, true) |
| .value_or(XFA_AttributeEnum::Visible); |
| } |
| |
| int32_t CXFA_BoxData::CountEdges() const { |
| if (!m_pNode) |
| return 0; |
| return m_pNode->CountChildren(XFA_Element::Edge, false); |
| } |
| |
| CXFA_EdgeData CXFA_BoxData::GetEdgeData(int32_t nIndex) const { |
| return CXFA_EdgeData(m_pNode ? m_pNode->JSObject()->GetProperty<CXFA_Edge>( |
| nIndex, XFA_Element::Edge, nIndex == 0) |
| : nullptr); |
| } |
| |
| std::vector<CXFA_StrokeData> CXFA_BoxData::GetStrokes() const { |
| return GetStrokesInternal(m_pNode, false); |
| } |
| |
| bool CXFA_BoxData::IsCircular() const { |
| if (!m_pNode) |
| return false; |
| return m_pNode->JSObject()->GetBoolean(XFA_Attribute::Circular); |
| } |
| |
| pdfium::Optional<int32_t> CXFA_BoxData::GetStartAngle() const { |
| if (!m_pNode) |
| return {}; |
| return m_pNode->JSObject()->TryInteger(XFA_Attribute::StartAngle, false); |
| } |
| |
| pdfium::Optional<int32_t> CXFA_BoxData::GetSweepAngle() const { |
| if (!m_pNode) |
| return {}; |
| return m_pNode->JSObject()->TryInteger(XFA_Attribute::SweepAngle, false); |
| } |
| |
| CXFA_FillData CXFA_BoxData::GetFillData(bool bModified) const { |
| if (!m_pNode) |
| return CXFA_FillData(nullptr); |
| |
| CXFA_Node* pFillNode = m_pNode->JSObject()->GetProperty<CXFA_Fill>( |
| 0, XFA_Element::Fill, bModified); |
| return CXFA_FillData(pFillNode); |
| } |
| |
| CXFA_Margin* CXFA_BoxData::GetMargin() const { |
| return m_pNode ? m_pNode->GetChild<CXFA_Margin>(0, XFA_Element::Margin, false) |
| : nullptr; |
| } |
| |
| std::tuple<XFA_AttributeEnum, bool, float> CXFA_BoxData::Get3DStyle() const { |
| if (IsArc()) |
| return {XFA_AttributeEnum::Unknown, false, 0.0f}; |
| |
| std::vector<CXFA_StrokeData> strokes = GetStrokesInternal(m_pNode, true); |
| CXFA_StrokeData strokeData(nullptr); |
| XFA_AttributeEnum iType = Style3D(strokes, strokeData); |
| if (iType == XFA_AttributeEnum::Unknown) |
| return {XFA_AttributeEnum::Unknown, false, 0.0f}; |
| |
| return {iType, strokeData.IsVisible(), strokeData.GetThickness()}; |
| } |