Home | History | Annotate | Download | only in app
      1 // Copyright 2014 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/app/xfa_fftext.h"
      8 
      9 #include "xfa/fwl/fwl_widgetdef.h"
     10 #include "xfa/fwl/fwl_widgethit.h"
     11 #include "xfa/fxfa/app/cxfa_linkuserdata.h"
     12 #include "xfa/fxfa/app/cxfa_pieceline.h"
     13 #include "xfa/fxfa/app/cxfa_textlayout.h"
     14 #include "xfa/fxfa/app/xfa_ffdraw.h"
     15 #include "xfa/fxfa/app/xfa_textpiece.h"
     16 #include "xfa/fxfa/xfa_ffapp.h"
     17 #include "xfa/fxfa/xfa_ffdoc.h"
     18 #include "xfa/fxfa/xfa_ffpageview.h"
     19 #include "xfa/fxfa/xfa_ffwidget.h"
     20 #include "xfa/fxgraphics/cfx_graphics.h"
     21 
     22 CXFA_FFText::CXFA_FFText(CXFA_WidgetAcc* pDataAcc) : CXFA_FFDraw(pDataAcc) {}
     23 
     24 CXFA_FFText::~CXFA_FFText() {}
     25 
     26 void CXFA_FFText::RenderWidget(CFX_Graphics* pGS,
     27                                CFX_Matrix* pMatrix,
     28                                uint32_t dwStatus) {
     29   if (!IsMatchVisibleStatus(dwStatus))
     30     return;
     31 
     32   CFX_Matrix mtRotate = GetRotateMatrix();
     33   if (pMatrix)
     34     mtRotate.Concat(*pMatrix);
     35 
     36   CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
     37 
     38   CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
     39   if (!pTextLayout)
     40     return;
     41 
     42   CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
     43   CFX_RectF rtText = GetRectWithoutRotate();
     44   if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
     45     CXFA_LayoutItem* pItem = this;
     46     if (!pItem->GetPrev() && !pItem->GetNext()) {
     47       XFA_RectWidthoutMargin(rtText, mgWidget);
     48     } else {
     49       FX_FLOAT fLeftInset;
     50       FX_FLOAT fRightInset;
     51       FX_FLOAT fTopInset = 0;
     52       FX_FLOAT fBottomInset = 0;
     53       mgWidget.GetLeftInset(fLeftInset);
     54       mgWidget.GetRightInset(fRightInset);
     55       if (!pItem->GetPrev())
     56         mgWidget.GetTopInset(fTopInset);
     57       else if (!pItem->GetNext())
     58         mgWidget.GetBottomInset(fBottomInset);
     59 
     60       rtText.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);
     61     }
     62   }
     63 
     64   CFX_Matrix mt(1, 0, 0, 1, rtText.left, rtText.top);
     65   CFX_RectF rtClip = rtText;
     66   mtRotate.TransformRect(rtClip);
     67   mt.Concat(mtRotate);
     68   pTextLayout->DrawString(pRenderDevice, mt, rtClip, GetIndex());
     69 }
     70 
     71 bool CXFA_FFText::IsLoaded() {
     72   CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
     73   return pTextLayout && !pTextLayout->m_bHasBlock;
     74 }
     75 bool CXFA_FFText::PerformLayout() {
     76   CXFA_FFDraw::PerformLayout();
     77   CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
     78   if (!pTextLayout) {
     79     return false;
     80   }
     81   if (!pTextLayout->m_bHasBlock) {
     82     return true;
     83   }
     84   pTextLayout->m_Blocks.RemoveAll();
     85   CXFA_LayoutItem* pItem = this;
     86   if (!pItem->GetPrev() && !pItem->GetNext()) {
     87     return true;
     88   }
     89   pItem = pItem->GetFirst();
     90   while (pItem) {
     91     CFX_RectF rtText = pItem->GetRect(false);
     92     if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
     93       if (!pItem->GetPrev()) {
     94         FX_FLOAT fTopInset;
     95         mgWidget.GetTopInset(fTopInset);
     96         rtText.height -= fTopInset;
     97       } else if (!pItem->GetNext()) {
     98         FX_FLOAT fBottomInset;
     99         mgWidget.GetBottomInset(fBottomInset);
    100         rtText.height -= fBottomInset;
    101       }
    102     }
    103     pTextLayout->ItemBlocks(rtText, pItem->GetIndex());
    104     pItem = pItem->GetNext();
    105   }
    106   pTextLayout->m_bHasBlock = false;
    107   return true;
    108 }
    109 
    110 bool CXFA_FFText::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
    111   if (!GetRectWithoutRotate().Contains(point))
    112     return false;
    113 
    114   const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(point);
    115   if (!wsURLContent)
    116     return false;
    117 
    118   SetButtonDown(true);
    119   return true;
    120 }
    121 
    122 bool CXFA_FFText::OnMouseMove(uint32_t dwFlags, const CFX_PointF& point) {
    123   return GetRectWithoutRotate().Contains(point) && !!GetLinkURLAtPoint(point);
    124 }
    125 
    126 bool CXFA_FFText::OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) {
    127   if (!IsButtonDown())
    128     return false;
    129 
    130   SetButtonDown(false);
    131   const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(point);
    132   if (!wsURLContent)
    133     return false;
    134 
    135   CXFA_FFDoc* pDoc = GetDoc();
    136   pDoc->GetDocEnvironment()->GotoURL(pDoc, wsURLContent);
    137   return true;
    138 }
    139 
    140 FWL_WidgetHit CXFA_FFText::OnHitTest(const CFX_PointF& point) {
    141   if (!GetRectWithoutRotate().Contains(point))
    142     return FWL_WidgetHit::Unknown;
    143   if (!GetLinkURLAtPoint(point))
    144     return FWL_WidgetHit::Unknown;
    145   return FWL_WidgetHit::HyperLink;
    146 }
    147 
    148 const FX_WCHAR* CXFA_FFText::GetLinkURLAtPoint(const CFX_PointF& point) {
    149   CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
    150   if (!pTextLayout)
    151     return nullptr;
    152 
    153   CFX_RectF rect = GetRectWithoutRotate();
    154   for (const auto& pPieceLine : *pTextLayout->GetPieceLines()) {
    155     for (const auto& pPiece : pPieceLine->m_textPieces) {
    156       if (pPiece->pLinkData &&
    157           pPiece->rtPiece.Contains(point - rect.TopLeft())) {
    158         return pPiece->pLinkData->GetLinkURL();
    159       }
    160     }
    161   }
    162   return nullptr;
    163 }
    164