1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2017 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker
7*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_fill.h"
8*3ac0a46fSAndroid Build Coastguard Worker
9*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/xfa/cjx_node.h"
10*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fgas/graphics/cfgas_gegraphics.h"
11*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_color.h"
12*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_document.h"
13*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_linear.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_node.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_pattern.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_radial.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_stipple.h"
18*3ac0a46fSAndroid Build Coastguard Worker
19*3ac0a46fSAndroid Build Coastguard Worker namespace {
20*3ac0a46fSAndroid Build Coastguard Worker
21*3ac0a46fSAndroid Build Coastguard Worker const CXFA_Node::PropertyData kFillPropertyData[] = {
22*3ac0a46fSAndroid Build Coastguard Worker {XFA_Element::Pattern, 1, {XFA_PropertyFlag::kOneOf}},
23*3ac0a46fSAndroid Build Coastguard Worker {XFA_Element::Solid,
24*3ac0a46fSAndroid Build Coastguard Worker 1,
25*3ac0a46fSAndroid Build Coastguard Worker {XFA_PropertyFlag::kOneOf, XFA_PropertyFlag::kDefaultOneOf}},
26*3ac0a46fSAndroid Build Coastguard Worker {XFA_Element::Stipple, 1, {XFA_PropertyFlag::kOneOf}},
27*3ac0a46fSAndroid Build Coastguard Worker {XFA_Element::Color, 1, {}},
28*3ac0a46fSAndroid Build Coastguard Worker {XFA_Element::Linear, 1, {XFA_PropertyFlag::kOneOf}},
29*3ac0a46fSAndroid Build Coastguard Worker {XFA_Element::Extras, 1, {}},
30*3ac0a46fSAndroid Build Coastguard Worker {XFA_Element::Radial, 1, {XFA_PropertyFlag::kOneOf}},
31*3ac0a46fSAndroid Build Coastguard Worker };
32*3ac0a46fSAndroid Build Coastguard Worker
33*3ac0a46fSAndroid Build Coastguard Worker const CXFA_Node::AttributeData kFillAttributeData[] = {
34*3ac0a46fSAndroid Build Coastguard Worker {XFA_Attribute::Id, XFA_AttributeType::CData, nullptr},
35*3ac0a46fSAndroid Build Coastguard Worker {XFA_Attribute::Use, XFA_AttributeType::CData, nullptr},
36*3ac0a46fSAndroid Build Coastguard Worker {XFA_Attribute::Presence, XFA_AttributeType::Enum,
37*3ac0a46fSAndroid Build Coastguard Worker (void*)XFA_AttributeValue::Visible},
38*3ac0a46fSAndroid Build Coastguard Worker {XFA_Attribute::Usehref, XFA_AttributeType::CData, nullptr},
39*3ac0a46fSAndroid Build Coastguard Worker };
40*3ac0a46fSAndroid Build Coastguard Worker
41*3ac0a46fSAndroid Build Coastguard Worker } // namespace
42*3ac0a46fSAndroid Build Coastguard Worker
CXFA_Fill(CXFA_Document * doc,XFA_PacketType packet)43*3ac0a46fSAndroid Build Coastguard Worker CXFA_Fill::CXFA_Fill(CXFA_Document* doc, XFA_PacketType packet)
44*3ac0a46fSAndroid Build Coastguard Worker : CXFA_Node(doc,
45*3ac0a46fSAndroid Build Coastguard Worker packet,
46*3ac0a46fSAndroid Build Coastguard Worker {XFA_XDPPACKET::kTemplate, XFA_XDPPACKET::kForm},
47*3ac0a46fSAndroid Build Coastguard Worker XFA_ObjectType::Node,
48*3ac0a46fSAndroid Build Coastguard Worker XFA_Element::Fill,
49*3ac0a46fSAndroid Build Coastguard Worker kFillPropertyData,
50*3ac0a46fSAndroid Build Coastguard Worker kFillAttributeData,
51*3ac0a46fSAndroid Build Coastguard Worker cppgc::MakeGarbageCollected<CJX_Node>(
52*3ac0a46fSAndroid Build Coastguard Worker doc->GetHeap()->GetAllocationHandle(),
53*3ac0a46fSAndroid Build Coastguard Worker this)) {}
54*3ac0a46fSAndroid Build Coastguard Worker
55*3ac0a46fSAndroid Build Coastguard Worker CXFA_Fill::~CXFA_Fill() = default;
56*3ac0a46fSAndroid Build Coastguard Worker
IsVisible()57*3ac0a46fSAndroid Build Coastguard Worker bool CXFA_Fill::IsVisible() {
58*3ac0a46fSAndroid Build Coastguard Worker return JSObject()
59*3ac0a46fSAndroid Build Coastguard Worker ->TryEnum(XFA_Attribute::Presence, true)
60*3ac0a46fSAndroid Build Coastguard Worker .value_or(XFA_AttributeValue::Visible) ==
61*3ac0a46fSAndroid Build Coastguard Worker XFA_AttributeValue::Visible;
62*3ac0a46fSAndroid Build Coastguard Worker }
63*3ac0a46fSAndroid Build Coastguard Worker
SetColor(FX_ARGB color)64*3ac0a46fSAndroid Build Coastguard Worker void CXFA_Fill::SetColor(FX_ARGB color) {
65*3ac0a46fSAndroid Build Coastguard Worker CXFA_Color* pColor =
66*3ac0a46fSAndroid Build Coastguard Worker JSObject()->GetOrCreateProperty<CXFA_Color>(0, XFA_Element::Color);
67*3ac0a46fSAndroid Build Coastguard Worker if (!pColor)
68*3ac0a46fSAndroid Build Coastguard Worker return;
69*3ac0a46fSAndroid Build Coastguard Worker
70*3ac0a46fSAndroid Build Coastguard Worker pColor->SetValue(color);
71*3ac0a46fSAndroid Build Coastguard Worker }
72*3ac0a46fSAndroid Build Coastguard Worker
GetFillColor() const73*3ac0a46fSAndroid Build Coastguard Worker FX_ARGB CXFA_Fill::GetFillColor() const {
74*3ac0a46fSAndroid Build Coastguard Worker const auto* pColor = GetChild<CXFA_Color>(0, XFA_Element::Color, false);
75*3ac0a46fSAndroid Build Coastguard Worker return pColor ? pColor->GetValueOrDefault(0xFFFFFFFF) : 0xFFFFFFFF;
76*3ac0a46fSAndroid Build Coastguard Worker }
77*3ac0a46fSAndroid Build Coastguard Worker
GetTextColor() const78*3ac0a46fSAndroid Build Coastguard Worker FX_ARGB CXFA_Fill::GetTextColor() const {
79*3ac0a46fSAndroid Build Coastguard Worker const auto* pColor = GetChild<CXFA_Color>(0, XFA_Element::Color, false);
80*3ac0a46fSAndroid Build Coastguard Worker return pColor ? pColor->GetValueOrDefault(0xFF000000) : 0xFF000000;
81*3ac0a46fSAndroid Build Coastguard Worker }
82*3ac0a46fSAndroid Build Coastguard Worker
GetType() const83*3ac0a46fSAndroid Build Coastguard Worker XFA_Element CXFA_Fill::GetType() const {
84*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* pChild = GetFirstChild();
85*3ac0a46fSAndroid Build Coastguard Worker while (pChild) {
86*3ac0a46fSAndroid Build Coastguard Worker XFA_Element eType = pChild->GetElementType();
87*3ac0a46fSAndroid Build Coastguard Worker if (eType != XFA_Element::Color && eType != XFA_Element::Extras)
88*3ac0a46fSAndroid Build Coastguard Worker return eType;
89*3ac0a46fSAndroid Build Coastguard Worker
90*3ac0a46fSAndroid Build Coastguard Worker pChild = pChild->GetNextSibling();
91*3ac0a46fSAndroid Build Coastguard Worker }
92*3ac0a46fSAndroid Build Coastguard Worker return XFA_Element::Solid;
93*3ac0a46fSAndroid Build Coastguard Worker }
94*3ac0a46fSAndroid Build Coastguard Worker
Draw(CFGAS_GEGraphics * pGS,const CFGAS_GEPath & fillPath,const CFX_RectF & rtWidget,const CFX_Matrix & matrix)95*3ac0a46fSAndroid Build Coastguard Worker void CXFA_Fill::Draw(CFGAS_GEGraphics* pGS,
96*3ac0a46fSAndroid Build Coastguard Worker const CFGAS_GEPath& fillPath,
97*3ac0a46fSAndroid Build Coastguard Worker const CFX_RectF& rtWidget,
98*3ac0a46fSAndroid Build Coastguard Worker const CFX_Matrix& matrix) {
99*3ac0a46fSAndroid Build Coastguard Worker CFGAS_GEGraphics::StateRestorer restorer(pGS);
100*3ac0a46fSAndroid Build Coastguard Worker switch (GetType()) {
101*3ac0a46fSAndroid Build Coastguard Worker case XFA_Element::Radial:
102*3ac0a46fSAndroid Build Coastguard Worker DrawRadial(pGS, fillPath, rtWidget, matrix);
103*3ac0a46fSAndroid Build Coastguard Worker break;
104*3ac0a46fSAndroid Build Coastguard Worker case XFA_Element::Pattern:
105*3ac0a46fSAndroid Build Coastguard Worker DrawPattern(pGS, fillPath, rtWidget, matrix);
106*3ac0a46fSAndroid Build Coastguard Worker break;
107*3ac0a46fSAndroid Build Coastguard Worker case XFA_Element::Linear:
108*3ac0a46fSAndroid Build Coastguard Worker DrawLinear(pGS, fillPath, rtWidget, matrix);
109*3ac0a46fSAndroid Build Coastguard Worker break;
110*3ac0a46fSAndroid Build Coastguard Worker case XFA_Element::Stipple:
111*3ac0a46fSAndroid Build Coastguard Worker DrawStipple(pGS, fillPath, rtWidget, matrix);
112*3ac0a46fSAndroid Build Coastguard Worker break;
113*3ac0a46fSAndroid Build Coastguard Worker default:
114*3ac0a46fSAndroid Build Coastguard Worker pGS->SetFillColor(CFGAS_GEColor(GetFillColor()));
115*3ac0a46fSAndroid Build Coastguard Worker pGS->FillPath(fillPath, CFX_FillRenderOptions::FillType::kWinding,
116*3ac0a46fSAndroid Build Coastguard Worker matrix);
117*3ac0a46fSAndroid Build Coastguard Worker break;
118*3ac0a46fSAndroid Build Coastguard Worker }
119*3ac0a46fSAndroid Build Coastguard Worker }
120*3ac0a46fSAndroid Build Coastguard Worker
DrawStipple(CFGAS_GEGraphics * pGS,const CFGAS_GEPath & fillPath,const CFX_RectF & rtWidget,const CFX_Matrix & matrix)121*3ac0a46fSAndroid Build Coastguard Worker void CXFA_Fill::DrawStipple(CFGAS_GEGraphics* pGS,
122*3ac0a46fSAndroid Build Coastguard Worker const CFGAS_GEPath& fillPath,
123*3ac0a46fSAndroid Build Coastguard Worker const CFX_RectF& rtWidget,
124*3ac0a46fSAndroid Build Coastguard Worker const CFX_Matrix& matrix) {
125*3ac0a46fSAndroid Build Coastguard Worker CXFA_Stipple* stipple =
126*3ac0a46fSAndroid Build Coastguard Worker JSObject()->GetOrCreateProperty<CXFA_Stipple>(0, XFA_Element::Stipple);
127*3ac0a46fSAndroid Build Coastguard Worker if (stipple)
128*3ac0a46fSAndroid Build Coastguard Worker stipple->Draw(pGS, fillPath, rtWidget, matrix);
129*3ac0a46fSAndroid Build Coastguard Worker }
130*3ac0a46fSAndroid Build Coastguard Worker
DrawRadial(CFGAS_GEGraphics * pGS,const CFGAS_GEPath & fillPath,const CFX_RectF & rtWidget,const CFX_Matrix & matrix)131*3ac0a46fSAndroid Build Coastguard Worker void CXFA_Fill::DrawRadial(CFGAS_GEGraphics* pGS,
132*3ac0a46fSAndroid Build Coastguard Worker const CFGAS_GEPath& fillPath,
133*3ac0a46fSAndroid Build Coastguard Worker const CFX_RectF& rtWidget,
134*3ac0a46fSAndroid Build Coastguard Worker const CFX_Matrix& matrix) {
135*3ac0a46fSAndroid Build Coastguard Worker CXFA_Radial* radial =
136*3ac0a46fSAndroid Build Coastguard Worker JSObject()->GetOrCreateProperty<CXFA_Radial>(0, XFA_Element::Radial);
137*3ac0a46fSAndroid Build Coastguard Worker if (radial)
138*3ac0a46fSAndroid Build Coastguard Worker radial->Draw(pGS, fillPath, GetFillColor(), rtWidget, matrix);
139*3ac0a46fSAndroid Build Coastguard Worker }
140*3ac0a46fSAndroid Build Coastguard Worker
DrawLinear(CFGAS_GEGraphics * pGS,const CFGAS_GEPath & fillPath,const CFX_RectF & rtWidget,const CFX_Matrix & matrix)141*3ac0a46fSAndroid Build Coastguard Worker void CXFA_Fill::DrawLinear(CFGAS_GEGraphics* pGS,
142*3ac0a46fSAndroid Build Coastguard Worker const CFGAS_GEPath& fillPath,
143*3ac0a46fSAndroid Build Coastguard Worker const CFX_RectF& rtWidget,
144*3ac0a46fSAndroid Build Coastguard Worker const CFX_Matrix& matrix) {
145*3ac0a46fSAndroid Build Coastguard Worker CXFA_Linear* linear =
146*3ac0a46fSAndroid Build Coastguard Worker JSObject()->GetOrCreateProperty<CXFA_Linear>(0, XFA_Element::Linear);
147*3ac0a46fSAndroid Build Coastguard Worker if (linear)
148*3ac0a46fSAndroid Build Coastguard Worker linear->Draw(pGS, fillPath, GetFillColor(), rtWidget, matrix);
149*3ac0a46fSAndroid Build Coastguard Worker }
150*3ac0a46fSAndroid Build Coastguard Worker
DrawPattern(CFGAS_GEGraphics * pGS,const CFGAS_GEPath & fillPath,const CFX_RectF & rtWidget,const CFX_Matrix & matrix)151*3ac0a46fSAndroid Build Coastguard Worker void CXFA_Fill::DrawPattern(CFGAS_GEGraphics* pGS,
152*3ac0a46fSAndroid Build Coastguard Worker const CFGAS_GEPath& fillPath,
153*3ac0a46fSAndroid Build Coastguard Worker const CFX_RectF& rtWidget,
154*3ac0a46fSAndroid Build Coastguard Worker const CFX_Matrix& matrix) {
155*3ac0a46fSAndroid Build Coastguard Worker CXFA_Pattern* pattern =
156*3ac0a46fSAndroid Build Coastguard Worker JSObject()->GetOrCreateProperty<CXFA_Pattern>(0, XFA_Element::Pattern);
157*3ac0a46fSAndroid Build Coastguard Worker if (pattern)
158*3ac0a46fSAndroid Build Coastguard Worker pattern->Draw(pGS, fillPath, GetFillColor(), rtWidget, matrix);
159*3ac0a46fSAndroid Build Coastguard Worker }
160