blob: 3bc641bbcdddbad13f875ea702fe794c10a2e25e [file] [log] [blame]
// 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 <utility>
#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<XFA_AttributeEnum, CXFA_Stroke*> Style3D(
const std::vector<CXFA_Stroke*>& 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<CJX_Object> 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<CXFA_Edge>(nIndex, XFA_Element::Edge,
nIndex == 0);
}
std::vector<CXFA_Stroke*> CXFA_Box::GetStrokes() {
return GetStrokesInternal(false);
}
bool CXFA_Box::IsCircular() {
return JSObject()->GetBoolean(XFA_Attribute::Circular);
}
Optional<int32_t> CXFA_Box::GetStartAngle() {
return JSObject()->TryInteger(XFA_Attribute::StartAngle, false);
}
Optional<int32_t> CXFA_Box::GetSweepAngle() {
return JSObject()->TryInteger(XFA_Attribute::SweepAngle, false);
}
CXFA_Fill* CXFA_Box::GetFill(bool bModified) {
return JSObject()->GetProperty<CXFA_Fill>(0, XFA_Element::Fill, bModified);
}
CXFA_Margin* CXFA_Box::GetMargin() {
return GetChild<CXFA_Margin>(0, XFA_Element::Margin, false);
}
std::tuple<XFA_AttributeEnum, bool, float> CXFA_Box::Get3DStyle() {
if (IsArc())
return {XFA_AttributeEnum::Unknown, false, 0.0f};
std::vector<CXFA_Stroke*> 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_Stroke*> CXFA_Box::GetStrokesInternal(bool bNull) {
std::vector<CXFA_Stroke*> strokes;
strokes.resize(8);
for (int32_t i = 0, j = 0; i < 4; i++) {
CXFA_Corner* corner =
JSObject()->GetProperty<CXFA_Corner>(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<CXFA_Edge>(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;
}