Home | History | Annotate | Download | only in parser
      1 // Copyright 2016 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_box.h"
      8 
      9 #include "xfa/fxfa/parser/cxfa_corner.h"
     10 #include "xfa/fxfa/parser/cxfa_measurement.h"
     11 #include "xfa/fxfa/parser/xfa_object.h"
     12 
     13 namespace {
     14 
     15 void GetStrokesInternal(CXFA_Node* pNode,
     16                         std::vector<CXFA_Stroke>* strokes,
     17                         bool bNull) {
     18   strokes->clear();
     19   if (!pNode)
     20     return;
     21 
     22   strokes->resize(8);
     23   int32_t i, j;
     24   for (i = 0, j = 0; i < 4; i++) {
     25     CXFA_Corner corner =
     26         CXFA_Corner(pNode->GetProperty(i, XFA_Element::Corner, i == 0));
     27     if (corner || i == 0) {
     28       (*strokes)[j] = corner;
     29     } else if (!bNull) {
     30       if (i == 1 || i == 2)
     31         (*strokes)[j] = (*strokes)[0];
     32       else
     33         (*strokes)[j] = (*strokes)[2];
     34     }
     35     j++;
     36     CXFA_Edge edge =
     37         CXFA_Edge(pNode->GetProperty(i, XFA_Element::Edge, i == 0));
     38     if (edge || i == 0) {
     39       (*strokes)[j] = edge;
     40     } else if (!bNull) {
     41       if (i == 1 || i == 2)
     42         (*strokes)[j] = (*strokes)[1];
     43       else
     44         (*strokes)[j] = (*strokes)[3];
     45     }
     46     j++;
     47   }
     48 }
     49 
     50 static int32_t Style3D(const std::vector<CXFA_Stroke>& strokes,
     51                        CXFA_Stroke& stroke) {
     52   if (strokes.empty())
     53     return 0;
     54 
     55   stroke = strokes[0];
     56   for (size_t i = 1; i < strokes.size(); i++) {
     57     CXFA_Stroke find = strokes[i];
     58     if (!find)
     59       continue;
     60 
     61     if (!stroke)
     62       stroke = find;
     63     else if (stroke.GetStrokeType() != find.GetStrokeType())
     64       stroke = find;
     65     break;
     66   }
     67   int32_t iType = stroke.GetStrokeType();
     68   if (iType == XFA_ATTRIBUTEENUM_Lowered || iType == XFA_ATTRIBUTEENUM_Raised ||
     69       iType == XFA_ATTRIBUTEENUM_Etched ||
     70       iType == XFA_ATTRIBUTEENUM_Embossed) {
     71     return iType;
     72   }
     73   return 0;
     74 }
     75 
     76 }  // namespace
     77 
     78 int32_t CXFA_Box::GetHand() const {
     79   if (!m_pNode)
     80     return XFA_ATTRIBUTEENUM_Even;
     81   return m_pNode->GetEnum(XFA_ATTRIBUTE_Hand);
     82 }
     83 
     84 int32_t CXFA_Box::GetPresence() const {
     85   if (!m_pNode)
     86     return XFA_ATTRIBUTEENUM_Hidden;
     87   return m_pNode->GetEnum(XFA_ATTRIBUTE_Presence);
     88 }
     89 
     90 int32_t CXFA_Box::CountEdges() const {
     91   if (!m_pNode)
     92     return 0;
     93   return m_pNode->CountChildren(XFA_Element::Edge);
     94 }
     95 
     96 CXFA_Edge CXFA_Box::GetEdge(int32_t nIndex) const {
     97   return CXFA_Edge(
     98       m_pNode ? m_pNode->GetProperty(nIndex, XFA_Element::Edge, nIndex == 0)
     99               : nullptr);
    100 }
    101 
    102 void CXFA_Box::GetStrokes(std::vector<CXFA_Stroke>* strokes) const {
    103   GetStrokesInternal(m_pNode, strokes, false);
    104 }
    105 
    106 bool CXFA_Box::IsCircular() const {
    107   if (!m_pNode)
    108     return false;
    109   return m_pNode->GetBoolean(XFA_ATTRIBUTE_Circular);
    110 }
    111 
    112 bool CXFA_Box::GetStartAngle(FX_FLOAT& fStartAngle) const {
    113   fStartAngle = 0;
    114   if (!m_pNode)
    115     return false;
    116 
    117   CXFA_Measurement ms;
    118   bool bRet = m_pNode->TryMeasure(XFA_ATTRIBUTE_StartAngle, ms, false);
    119   if (bRet)
    120     fStartAngle = ms.GetValue();
    121 
    122   return bRet;
    123 }
    124 
    125 bool CXFA_Box::GetSweepAngle(FX_FLOAT& fSweepAngle) const {
    126   fSweepAngle = 360;
    127   if (!m_pNode)
    128     return false;
    129 
    130   CXFA_Measurement ms;
    131   bool bRet = m_pNode->TryMeasure(XFA_ATTRIBUTE_SweepAngle, ms, false);
    132   if (bRet)
    133     fSweepAngle = ms.GetValue();
    134 
    135   return bRet;
    136 }
    137 
    138 CXFA_Fill CXFA_Box::GetFill(bool bModified) const {
    139   if (!m_pNode)
    140     return CXFA_Fill(nullptr);
    141 
    142   CXFA_Node* pFillNode = m_pNode->GetProperty(0, XFA_Element::Fill, bModified);
    143   return CXFA_Fill(pFillNode);
    144 }
    145 
    146 CXFA_Margin CXFA_Box::GetMargin() const {
    147   return CXFA_Margin(m_pNode ? m_pNode->GetChild(0, XFA_Element::Margin)
    148                              : nullptr);
    149 }
    150 
    151 int32_t CXFA_Box::Get3DStyle(bool& bVisible, FX_FLOAT& fThickness) const {
    152   if (IsArc())
    153     return 0;
    154 
    155   std::vector<CXFA_Stroke> strokes;
    156   GetStrokesInternal(m_pNode, &strokes, true);
    157   CXFA_Stroke stroke(nullptr);
    158   int32_t iType = Style3D(strokes, stroke);
    159   if (iType) {
    160     bVisible = stroke.IsVisible();
    161     fThickness = stroke.GetThickness();
    162   }
    163   return iType;
    164 }
    165