• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/src/foxitlib.h"
8 #include "xfa/src/fxfa/src/common/xfa_common.h"
9 #include "xfa_ffwidget.h"
10 #include "xfa_ffdraw.h"
11 #include "xfa_fftext.h"
12 #include "xfa_textlayout.h"
13 #include "xfa_ffpageview.h"
14 #include "xfa_ffdoc.h"
15 #include "xfa_ffapp.h"
CXFA_FFText(CXFA_FFPageView * pPageView,CXFA_WidgetAcc * pDataAcc)16 CXFA_FFText::CXFA_FFText(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
17     : CXFA_FFDraw(pPageView, pDataAcc) {}
~CXFA_FFText()18 CXFA_FFText::~CXFA_FFText() {}
RenderWidget(CFX_Graphics * pGS,CFX_Matrix * pMatrix,FX_DWORD dwStatus,int32_t iRotate)19 void CXFA_FFText::RenderWidget(CFX_Graphics* pGS,
20                                CFX_Matrix* pMatrix,
21                                FX_DWORD dwStatus,
22                                int32_t iRotate) {
23   if (!IsMatchVisibleStatus(dwStatus)) {
24     return;
25   }
26   {
27     CFX_Matrix mtRotate;
28     GetRotateMatrix(mtRotate);
29     if (pMatrix) {
30       mtRotate.Concat(*pMatrix);
31     }
32     CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
33     CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
34     if (pTextLayout) {
35       CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
36       CFX_RectF rtText;
37       GetRectWithoutRotate(rtText);
38       if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
39         CXFA_LayoutItem* pItem = this;
40         if (pItem->GetPrev() == NULL && pItem->GetNext() == NULL) {
41           XFA_RectWidthoutMargin(rtText, mgWidget);
42         } else {
43           FX_FLOAT fLeftInset, fRightInset, fTopInset = 0, fBottomInset = 0;
44           mgWidget.GetLeftInset(fLeftInset);
45           mgWidget.GetRightInset(fRightInset);
46           if (pItem->GetPrev() == NULL) {
47             mgWidget.GetTopInset(fTopInset);
48           } else if (pItem->GetNext() == NULL) {
49             mgWidget.GetBottomInset(fBottomInset);
50           }
51           rtText.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);
52         }
53       }
54       CFX_Matrix mt;
55       mt.Set(1, 0, 0, 1, rtText.left, rtText.top);
56       CFX_RectF rtClip = rtText;
57       mtRotate.TransformRect(rtClip);
58       mt.Concat(mtRotate);
59       pTextLayout->DrawString(pRenderDevice, mt, rtClip, GetIndex());
60     }
61   }
62 }
IsLoaded()63 FX_BOOL CXFA_FFText::IsLoaded() {
64   CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
65   return pTextLayout != NULL && !pTextLayout->m_bHasBlock;
66 }
PerformLayout()67 FX_BOOL CXFA_FFText::PerformLayout() {
68   CXFA_FFDraw::PerformLayout();
69   CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
70   if (!pTextLayout) {
71     return FALSE;
72   }
73   if (!pTextLayout->m_bHasBlock) {
74     return TRUE;
75   }
76   pTextLayout->m_Blocks.RemoveAll();
77   CXFA_LayoutItem* pItem = this;
78   if (pItem->GetPrev() == NULL && pItem->GetNext() == NULL) {
79     return TRUE;
80   }
81   pItem = pItem->GetFirst();
82   while (pItem) {
83     CFX_RectF rtText;
84     pItem->GetRect(rtText);
85     if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
86       if (pItem->GetPrev() == NULL) {
87         FX_FLOAT fTopInset;
88         mgWidget.GetTopInset(fTopInset);
89         rtText.height -= fTopInset;
90       } else if (pItem->GetNext() == NULL) {
91         FX_FLOAT fBottomInset;
92         mgWidget.GetBottomInset(fBottomInset);
93         rtText.height -= fBottomInset;
94       }
95     }
96     pTextLayout->ItemBlocks(rtText, pItem->GetIndex());
97     pItem = pItem->GetNext();
98   }
99   pTextLayout->m_bHasBlock = FALSE;
100   return TRUE;
101 }
OnLButtonDown(FX_DWORD dwFlags,FX_FLOAT fx,FX_FLOAT fy)102 FX_BOOL CXFA_FFText::OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
103   CFX_RectF rtBox;
104   GetRectWithoutRotate(rtBox);
105   if (!rtBox.Contains(fx, fy)) {
106     return FALSE;
107   }
108   const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(fx, fy);
109   if (NULL == wsURLContent) {
110     return FALSE;
111   }
112   SetButtonDown(TRUE);
113   return TRUE;
114 }
OnMouseMove(FX_DWORD dwFlags,FX_FLOAT fx,FX_FLOAT fy)115 FX_BOOL CXFA_FFText::OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
116   CFX_RectF rtBox;
117   GetRectWithoutRotate(rtBox);
118   if (!rtBox.Contains(fx, fy)) {
119     return FALSE;
120   }
121   const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(fx, fy);
122   if (NULL == wsURLContent) {
123     return FALSE;
124   }
125   return TRUE;
126 }
OnLButtonUp(FX_DWORD dwFlags,FX_FLOAT fx,FX_FLOAT fy)127 FX_BOOL CXFA_FFText::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
128   if (!IsButtonDown()) {
129     return FALSE;
130   }
131   SetButtonDown(FALSE);
132   const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(fx, fy);
133   if (NULL == wsURLContent) {
134     return FALSE;
135   }
136   CXFA_FFDoc* pDoc = GetDoc();
137   pDoc->GetDocProvider()->GotoURL(pDoc, CFX_WideStringC(wsURLContent), FALSE);
138   return TRUE;
139 }
OnHitTest(FX_FLOAT fx,FX_FLOAT fy)140 FX_DWORD CXFA_FFText::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) {
141   CFX_RectF rtBox;
142   GetRectWithoutRotate(rtBox);
143   if (!rtBox.Contains(fx, fy)) {
144     return FWL_WGTHITTEST_Unknown;
145   }
146   if (!GetLinkURLAtPoint(fx, fy)) {
147     return FWL_WGTHITTEST_Unknown;
148   }
149   return FWL_WGTHITTEST_HyperLink;
150 }
GetLinkURLAtPoint(FX_FLOAT fx,FX_FLOAT fy)151 const FX_WCHAR* CXFA_FFText::GetLinkURLAtPoint(FX_FLOAT fx, FX_FLOAT fy) {
152   CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
153   if (NULL == pTextLayout) {
154     return NULL;
155   }
156   FX_FLOAT x(fx), y(fy);
157   FWLToClient(x, y);
158   const CXFA_PieceLineArray* pPieceLines = pTextLayout->GetPieceLines();
159   int32_t iCount = pPieceLines->GetSize();
160   for (int32_t i = 0; i < iCount; i++) {
161     CXFA_PieceLine* pPieceLine = pPieceLines->GetAt(i);
162     int32_t iPieces = pPieceLine->m_textPieces.GetSize();
163     for (int32_t j = 0; j < iPieces; j++) {
164       XFA_LPTEXTPIECE pPiece = pPieceLine->m_textPieces.GetAt(j);
165       if (pPiece->pLinkData && pPiece->rtPiece.Contains(x, y)) {
166         return pPiece->pLinkData->GetLinkURL();
167       }
168     }
169   }
170   return NULL;
171 }
FWLToClient(FX_FLOAT & fx,FX_FLOAT & fy)172 void CXFA_FFText::FWLToClient(FX_FLOAT& fx, FX_FLOAT& fy) {
173   CFX_RectF rtWidget;
174   GetRectWithoutRotate(rtWidget);
175   fx -= rtWidget.left;
176   fy -= rtWidget.top;
177 }
178