blob: 31fefbf93db1e5b88210c42646d48b413e24d54a [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_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()};
}