// 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_box.h" #include #include "xfa/fxfa/parser/cxfa_corner.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::pair Style3D( const std::vector& strokes) { if (strokes.empty()) return {XFA_AttributeEnum::Unknown, nullptr}; CXFA_Stroke* stroke = strokes[0]; for (size_t i = 1; i < strokes.size(); i++) { CXFA_Stroke* find = strokes[i]; if (!find) continue; if (!stroke) stroke = find; else if (stroke->GetStrokeType() != find->GetStrokeType()) stroke = find; break; } XFA_AttributeEnum iType = stroke->GetStrokeType(); if (iType == XFA_AttributeEnum::Lowered || iType == XFA_AttributeEnum::Raised || iType == XFA_AttributeEnum::Etched || iType == XFA_AttributeEnum::Embossed) { return {iType, stroke}; } return {XFA_AttributeEnum::Unknown, stroke}; } } // namespace CXFA_Box::CXFA_Box(CXFA_Document* pDoc, XFA_PacketType ePacket, uint32_t validPackets, XFA_ObjectType oType, XFA_Element eType, const PropertyData* properties, const AttributeData* attributes, const WideStringView& elementName, std::unique_ptr js_node) : CXFA_Node(pDoc, ePacket, validPackets, oType, eType, properties, attributes, elementName, std::move(js_node)) {} CXFA_Box::~CXFA_Box() = default; XFA_AttributeEnum CXFA_Box::GetHand() { return JSObject()->GetEnum(XFA_Attribute::Hand); } XFA_AttributeEnum CXFA_Box::GetPresence() { return JSObject() ->TryEnum(XFA_Attribute::Presence, true) .value_or(XFA_AttributeEnum::Visible); } int32_t CXFA_Box::CountEdges() { return CountChildren(XFA_Element::Edge, false); } CXFA_Edge* CXFA_Box::GetEdge(int32_t nIndex) { return JSObject()->GetProperty(nIndex, XFA_Element::Edge, nIndex == 0); } std::vector CXFA_Box::GetStrokes() { return GetStrokesInternal(false); } bool CXFA_Box::IsCircular() { return JSObject()->GetBoolean(XFA_Attribute::Circular); } pdfium::Optional CXFA_Box::GetStartAngle() { return JSObject()->TryInteger(XFA_Attribute::StartAngle, false); } pdfium::Optional CXFA_Box::GetSweepAngle() { return JSObject()->TryInteger(XFA_Attribute::SweepAngle, false); } CXFA_Fill* CXFA_Box::GetFill(bool bModified) { return JSObject()->GetProperty(0, XFA_Element::Fill, bModified); } CXFA_Margin* CXFA_Box::GetMargin() { return GetChild(0, XFA_Element::Margin, false); } std::tuple CXFA_Box::Get3DStyle() { if (IsArc()) return {XFA_AttributeEnum::Unknown, false, 0.0f}; std::vector strokes = GetStrokesInternal(true); CXFA_Stroke* stroke; XFA_AttributeEnum iType; std::tie(iType, stroke) = Style3D(strokes); if (iType == XFA_AttributeEnum::Unknown) return {XFA_AttributeEnum::Unknown, false, 0.0f}; return {iType, stroke->IsVisible(), stroke->GetThickness()}; } std::vector CXFA_Box::GetStrokesInternal(bool bNull) { std::vector strokes; strokes.resize(8); for (int32_t i = 0, j = 0; i < 4; i++) { CXFA_Corner* corner = JSObject()->GetProperty(i, XFA_Element::Corner, i == 0); if (corner || i == 0) { strokes[j] = corner; } else if (!bNull) { if (i == 1 || i == 2) strokes[j] = strokes[0]; else strokes[j] = strokes[2]; } j++; CXFA_Edge* edge = JSObject()->GetProperty(i, XFA_Element::Edge, i == 0); if (edge || i == 0) { strokes[j] = edge; } else if (!bNull) { if (i == 1 || i == 2) strokes[j] = strokes[1]; else strokes[j] = strokes[3]; } j++; } return strokes; }