• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "core/fxge/render_defines.h"
10 #include "fxjs/xfa/cjx_node.h"
11 #include "third_party/base/ptr_util.h"
12 #include "xfa/fxfa/parser/cxfa_color.h"
13 #include "xfa/fxfa/parser/cxfa_linear.h"
14 #include "xfa/fxfa/parser/cxfa_node.h"
15 #include "xfa/fxfa/parser/cxfa_pattern.h"
16 #include "xfa/fxfa/parser/cxfa_radial.h"
17 #include "xfa/fxfa/parser/cxfa_stipple.h"
18 
19 namespace {
20 
21 const CXFA_Node::PropertyData kFillPropertyData[] = {
22     {XFA_Element::Pattern, 1, XFA_PROPERTYFLAG_OneOf},
23     {XFA_Element::Solid, 1,
24      XFA_PROPERTYFLAG_OneOf | XFA_PROPERTYFLAG_DefaultOneOf},
25     {XFA_Element::Stipple, 1, XFA_PROPERTYFLAG_OneOf},
26     {XFA_Element::Color, 1, 0},
27     {XFA_Element::Linear, 1, XFA_PROPERTYFLAG_OneOf},
28     {XFA_Element::Extras, 1, 0},
29     {XFA_Element::Radial, 1, XFA_PROPERTYFLAG_OneOf},
30 };
31 
32 const CXFA_Node::AttributeData kFillAttributeData[] = {
33     {XFA_Attribute::Id, XFA_AttributeType::CData, nullptr},
34     {XFA_Attribute::Use, XFA_AttributeType::CData, nullptr},
35     {XFA_Attribute::Presence, XFA_AttributeType::Enum,
36      (void*)XFA_AttributeValue::Visible},
37     {XFA_Attribute::Usehref, XFA_AttributeType::CData, nullptr},
38 };
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                 kFillPropertyData,
49                 kFillAttributeData,
50                 pdfium::MakeUnique<CJX_Node>(this)) {}
51 
52 CXFA_Fill::~CXFA_Fill() = default;
53 
IsVisible()54 bool CXFA_Fill::IsVisible() {
55   return JSObject()
56              ->TryEnum(XFA_Attribute::Presence, true)
57              .value_or(XFA_AttributeValue::Visible) ==
58          XFA_AttributeValue::Visible;
59 }
60 
SetColor(FX_ARGB color)61 void CXFA_Fill::SetColor(FX_ARGB color) {
62   CXFA_Color* pColor =
63       JSObject()->GetOrCreateProperty<CXFA_Color>(0, XFA_Element::Color);
64   if (!pColor)
65     return;
66 
67   pColor->SetValue(color);
68 }
69 
GetColor(bool bText)70 FX_ARGB CXFA_Fill::GetColor(bool bText) {
71   CXFA_Color* pColor = GetChild<CXFA_Color>(0, XFA_Element::Color, false);
72   if (!pColor)
73     return bText ? 0xFF000000 : 0xFFFFFFFF;
74   return pColor->GetValueOrDefault(bText ? 0xFF000000 : 0xFFFFFFFF);
75 }
76 
GetType() const77 XFA_Element CXFA_Fill::GetType() const {
78   CXFA_Node* pChild = GetFirstChild();
79   while (pChild) {
80     XFA_Element eType = pChild->GetElementType();
81     if (eType != XFA_Element::Color && eType != XFA_Element::Extras)
82       return eType;
83 
84     pChild = pChild->GetNextSibling();
85   }
86   return XFA_Element::Solid;
87 }
88 
Draw(CXFA_Graphics * pGS,CXFA_GEPath * fillPath,const CFX_RectF & rtWidget,const CFX_Matrix & matrix)89 void CXFA_Fill::Draw(CXFA_Graphics* pGS,
90                      CXFA_GEPath* fillPath,
91                      const CFX_RectF& rtWidget,
92                      const CFX_Matrix& matrix) {
93   pGS->SaveGraphState();
94 
95   switch (GetType()) {
96     case XFA_Element::Radial:
97       DrawRadial(pGS, fillPath, rtWidget, matrix);
98       break;
99     case XFA_Element::Pattern:
100       DrawPattern(pGS, fillPath, rtWidget, matrix);
101       break;
102     case XFA_Element::Linear:
103       DrawLinear(pGS, fillPath, rtWidget, matrix);
104       break;
105     case XFA_Element::Stipple:
106       DrawStipple(pGS, fillPath, rtWidget, matrix);
107       break;
108     default:
109       pGS->SetFillColor(CXFA_GEColor(GetColor(false)));
110       pGS->FillPath(fillPath, FXFILL_WINDING, &matrix);
111       break;
112   }
113 
114   pGS->RestoreGraphState();
115 }
116 
DrawStipple(CXFA_Graphics * pGS,CXFA_GEPath * fillPath,const CFX_RectF & rtWidget,const CFX_Matrix & matrix)117 void CXFA_Fill::DrawStipple(CXFA_Graphics* pGS,
118                             CXFA_GEPath* fillPath,
119                             const CFX_RectF& rtWidget,
120                             const CFX_Matrix& matrix) {
121   CXFA_Stipple* stipple =
122       JSObject()->GetOrCreateProperty<CXFA_Stipple>(0, XFA_Element::Stipple);
123   if (stipple)
124     stipple->Draw(pGS, fillPath, rtWidget, matrix);
125 }
126 
DrawRadial(CXFA_Graphics * pGS,CXFA_GEPath * fillPath,const CFX_RectF & rtWidget,const CFX_Matrix & matrix)127 void CXFA_Fill::DrawRadial(CXFA_Graphics* pGS,
128                            CXFA_GEPath* fillPath,
129                            const CFX_RectF& rtWidget,
130                            const CFX_Matrix& matrix) {
131   CXFA_Radial* radial =
132       JSObject()->GetOrCreateProperty<CXFA_Radial>(0, XFA_Element::Radial);
133   if (radial)
134     radial->Draw(pGS, fillPath, GetColor(false), rtWidget, matrix);
135 }
136 
DrawLinear(CXFA_Graphics * pGS,CXFA_GEPath * fillPath,const CFX_RectF & rtWidget,const CFX_Matrix & matrix)137 void CXFA_Fill::DrawLinear(CXFA_Graphics* pGS,
138                            CXFA_GEPath* fillPath,
139                            const CFX_RectF& rtWidget,
140                            const CFX_Matrix& matrix) {
141   CXFA_Linear* linear =
142       JSObject()->GetOrCreateProperty<CXFA_Linear>(0, XFA_Element::Linear);
143   if (linear)
144     linear->Draw(pGS, fillPath, GetColor(false), rtWidget, matrix);
145 }
146 
DrawPattern(CXFA_Graphics * pGS,CXFA_GEPath * fillPath,const CFX_RectF & rtWidget,const CFX_Matrix & matrix)147 void CXFA_Fill::DrawPattern(CXFA_Graphics* pGS,
148                             CXFA_GEPath* fillPath,
149                             const CFX_RectF& rtWidget,
150                             const CFX_Matrix& matrix) {
151   CXFA_Pattern* pattern =
152       JSObject()->GetOrCreateProperty<CXFA_Pattern>(0, XFA_Element::Pattern);
153   if (pattern)
154     pattern->Draw(pGS, fillPath, GetColor(false), rtWidget, matrix);
155 }
156