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 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 53 CXFA_Fill::~CXFA_Fill() {} 54 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 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 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 78 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 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 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 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 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 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