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