// 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_cornerdata.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->JSNode()->GetProperty(i, XFA_Element::Corner, i == 0)); if (cornerData || 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->JSNode()->GetProperty(i, XFA_Element::Edge, i == 0)); if (edgeData || 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 int32_t Style3D(const std::vector& strokes, CXFA_StrokeData& strokeData) { if (strokes.empty()) return 0; strokeData = strokes[0]; for (size_t i = 1; i < strokes.size(); i++) { CXFA_StrokeData find = strokes[i]; if (!find) continue; if (!strokeData) strokeData = find; else if (strokeData.GetStrokeType() != find.GetStrokeType()) strokeData = find; break; } int32_t iType = strokeData.GetStrokeType(); if (iType == XFA_ATTRIBUTEENUM_Lowered || iType == XFA_ATTRIBUTEENUM_Raised || iType == XFA_ATTRIBUTEENUM_Etched || iType == XFA_ATTRIBUTEENUM_Embossed) { return iType; } return 0; } } // namespace int32_t CXFA_BoxData::GetHand() const { if (!m_pNode) return XFA_ATTRIBUTEENUM_Even; return m_pNode->JSNode()->GetEnum(XFA_ATTRIBUTE_Hand); } int32_t CXFA_BoxData::GetPresence() const { if (!m_pNode) return XFA_ATTRIBUTEENUM_Hidden; return m_pNode->JSNode()->GetEnum(XFA_ATTRIBUTE_Presence); } 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->JSNode()->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->JSNode()->GetBoolean(XFA_ATTRIBUTE_Circular); } bool CXFA_BoxData::GetStartAngle(float& fStartAngle) const { fStartAngle = 0; if (!m_pNode) return false; CXFA_Measurement ms; bool bRet = m_pNode->JSNode()->TryMeasure(XFA_ATTRIBUTE_StartAngle, ms, false); if (bRet) fStartAngle = ms.GetValue(); return bRet; } bool CXFA_BoxData::GetSweepAngle(float& fSweepAngle) const { fSweepAngle = 360; if (!m_pNode) return false; CXFA_Measurement ms; bool bRet = m_pNode->JSNode()->TryMeasure(XFA_ATTRIBUTE_SweepAngle, ms, false); if (bRet) fSweepAngle = ms.GetValue(); return bRet; } CXFA_FillData CXFA_BoxData::GetFillData(bool bModified) const { if (!m_pNode) return CXFA_FillData(nullptr); CXFA_Node* pFillNode = m_pNode->JSNode()->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); } int32_t CXFA_BoxData::Get3DStyle(bool& bVisible, float& fThickness) const { if (IsArc()) return 0; std::vector strokes = GetStrokesInternal(m_pNode, true); CXFA_StrokeData strokeData(nullptr); int32_t iType = Style3D(strokes, strokeData); if (iType) { bVisible = strokeData.IsVisible(); fThickness = strokeData.GetThickness(); } return iType; }