// 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 GetStrokesInternal(CXFA_Node* pNode, bool bNull) { if (!pNode) return {}; std::vector strokes; strokes.resize(8); int32_t i, j; for (i = 0, j = 0; i < 4; i++) { CXFA_CornerData cornerData = CXFA_CornerData(pNode->JSObject()->GetProperty( 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( 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& 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( nIndex, XFA_Element::Edge, nIndex == 0) : nullptr); } std::vector 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 CXFA_BoxData::GetStartAngle() const { if (!m_pNode) return {}; return m_pNode->JSObject()->TryInteger(XFA_Attribute::StartAngle, false); } pdfium::Optional 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( 0, XFA_Element::Fill, bModified); return CXFA_FillData(pFillNode); } CXFA_MarginData CXFA_BoxData::GetMarginData() const { return CXFA_MarginData( m_pNode ? m_pNode->GetChild(0, XFA_Element::Margin, false) : nullptr); } std::tuple CXFA_BoxData::Get3DStyle() const { if (IsArc()) return {XFA_AttributeEnum::Unknown, false, 0.0f}; std::vector 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()}; }