Home | History | Annotate | Download | only in parser
      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