Home | History | Annotate | Download | only in fxfa
      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/cxfa_ffline.h"
      8 
      9 #include "xfa/fxfa/parser/cxfa_edge.h"
     10 #include "xfa/fxfa/parser/cxfa_line.h"
     11 #include "xfa/fxfa/parser/cxfa_value.h"
     12 #include "xfa/fxgraphics/cxfa_gecolor.h"
     13 #include "xfa/fxgraphics/cxfa_gepath.h"
     14 #include "xfa/fxgraphics/cxfa_graphics.h"
     15 
     16 namespace {
     17 
     18 CFX_GraphStateData::LineCap LineCapToFXGE(XFA_AttributeEnum iLineCap) {
     19   switch (iLineCap) {
     20     case XFA_AttributeEnum::Round:
     21       return CFX_GraphStateData::LineCapRound;
     22     case XFA_AttributeEnum::Butt:
     23       return CFX_GraphStateData::LineCapButt;
     24     default:
     25       break;
     26   }
     27   return CFX_GraphStateData::LineCapSquare;
     28 }
     29 
     30 }  // namespace
     31 
     32 CXFA_FFLine::CXFA_FFLine(CXFA_Node* pNode) : CXFA_FFDraw(pNode) {}
     33 
     34 CXFA_FFLine::~CXFA_FFLine() {}
     35 
     36 void CXFA_FFLine::GetRectFromHand(CFX_RectF& rect,
     37                                   XFA_AttributeEnum iHand,
     38                                   float fLineWidth) {
     39   float fHalfWidth = fLineWidth / 2.0f;
     40   if (rect.height < 1.0f) {
     41     switch (iHand) {
     42       case XFA_AttributeEnum::Left:
     43         rect.top -= fHalfWidth;
     44         break;
     45       case XFA_AttributeEnum::Right:
     46         rect.top += fHalfWidth;
     47       case XFA_AttributeEnum::Even:
     48         break;
     49       default:
     50         NOTREACHED();
     51         break;
     52     }
     53   } else if (rect.width < 1.0f) {
     54     switch (iHand) {
     55       case XFA_AttributeEnum::Left:
     56         rect.left += fHalfWidth;
     57         break;
     58       case XFA_AttributeEnum::Right:
     59         rect.left += fHalfWidth;
     60         break;
     61       case XFA_AttributeEnum::Even:
     62         break;
     63       default:
     64         NOTREACHED();
     65         break;
     66     }
     67   } else {
     68     switch (iHand) {
     69       case XFA_AttributeEnum::Left:
     70         rect.Inflate(fHalfWidth, fHalfWidth);
     71         break;
     72       case XFA_AttributeEnum::Right:
     73         rect.Deflate(fHalfWidth, fHalfWidth);
     74         break;
     75       case XFA_AttributeEnum::Even:
     76         break;
     77       default:
     78         NOTREACHED();
     79         break;
     80     }
     81   }
     82 }
     83 
     84 void CXFA_FFLine::RenderWidget(CXFA_Graphics* pGS,
     85                                const CFX_Matrix& matrix,
     86                                uint32_t dwStatus) {
     87   if (!IsMatchVisibleStatus(dwStatus))
     88     return;
     89 
     90   CXFA_Value* value = m_pNode->GetFormValueIfExists();
     91   if (!value)
     92     return;
     93 
     94   FX_ARGB lineColor = 0xFF000000;
     95   float fLineWidth = 1.0f;
     96   XFA_AttributeEnum iStrokeType = XFA_AttributeEnum::Unknown;
     97   XFA_AttributeEnum iCap = XFA_AttributeEnum::Unknown;
     98 
     99   CXFA_Line* line = value->GetLineIfExists();
    100   if (line) {
    101     CXFA_Edge* edge = line->GetEdgeIfExists();
    102     if (edge && !edge->IsVisible())
    103       return;
    104 
    105     if (edge) {
    106       lineColor = edge->GetColor();
    107       iStrokeType = edge->GetStrokeType();
    108       fLineWidth = edge->GetThickness();
    109       iCap = edge->GetCapType();
    110     }
    111   }
    112 
    113   CFX_Matrix mtRotate = GetRotateMatrix();
    114   mtRotate.Concat(matrix);
    115 
    116   CFX_RectF rtLine = GetRectWithoutRotate();
    117   CXFA_Margin* margin = m_pNode->GetMarginIfExists();
    118   if (margin)
    119     XFA_RectWithoutMargin(rtLine, margin);
    120 
    121   GetRectFromHand(rtLine, line ? line->GetHand() : XFA_AttributeEnum::Left,
    122                   fLineWidth);
    123   CXFA_GEPath linePath;
    124   if (line && line->GetSlope() && rtLine.right() > 0.0f &&
    125       rtLine.bottom() > 0.0f) {
    126     linePath.AddLine(rtLine.TopRight(), rtLine.BottomLeft());
    127   } else {
    128     linePath.AddLine(rtLine.TopLeft(), rtLine.BottomRight());
    129   }
    130 
    131   pGS->SaveGraphState();
    132   pGS->SetLineWidth(fLineWidth);
    133   pGS->EnableActOnDash();
    134   XFA_StrokeTypeSetLineDash(pGS, iStrokeType, iCap);
    135 
    136   pGS->SetStrokeColor(CXFA_GEColor(lineColor));
    137   pGS->SetLineCap(LineCapToFXGE(iCap));
    138   pGS->StrokePath(&linePath, &mtRotate);
    139   pGS->RestoreGraphState();
    140 }
    141