Merge to XFA: Use stdint.h types throughout PDFium.
[pdfium.git] / xfa / src / fxfa / src / app / xfa_fftext.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../../../foxitlib.h"\r
8 #include "../common/xfa_common.h"\r
9 #include "xfa_ffwidget.h"\r
10 #include "xfa_ffdraw.h"\r
11 #include "xfa_fftext.h"\r
12 #include "xfa_textlayout.h"\r
13 #include "xfa_ffpageview.h"\r
14 #include "xfa_ffdoc.h"\r
15 #include "xfa_ffapp.h"\r
16 CXFA_FFText::CXFA_FFText(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)\r
17     : CXFA_FFDraw(pPageView, pDataAcc)\r
18 {\r
19 }\r
20 CXFA_FFText::~CXFA_FFText()\r
21 {\r
22 }\r
23 void CXFA_FFText::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_DWORD dwStatus , int32_t iRotate )\r
24 {\r
25     if (!IsMatchVisibleStatus(dwStatus)) {\r
26         return;\r
27     }\r
28     {\r
29         CFX_Matrix mtRotate;\r
30         GetRotateMatrix(mtRotate);\r
31         if (pMatrix) {\r
32             mtRotate.Concat(*pMatrix);\r
33         }\r
34         CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);\r
35         CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();\r
36         if (pTextLayout) {\r
37             CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();\r
38             CFX_RectF rtText;\r
39             GetRectWithoutRotate(rtText);\r
40             if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {\r
41                 CXFA_LayoutItem* pItem = this->GetLayoutItem();\r
42                 if (pItem->GetPrev() == NULL && pItem->GetNext() == NULL) {\r
43                     XFA_RectWidthoutMargin(rtText, mgWidget);\r
44                 } else {\r
45                     FX_FLOAT fLeftInset, fRightInset, fTopInset = 0, fBottomInset = 0;\r
46                     mgWidget.GetLeftInset(fLeftInset);\r
47                     mgWidget.GetRightInset(fRightInset);\r
48                     if (pItem->GetPrev() == NULL) {\r
49                         mgWidget.GetTopInset(fTopInset);\r
50                     } else if (pItem->GetNext() == NULL) {\r
51                         mgWidget.GetBottomInset(fBottomInset);\r
52                     }\r
53                     rtText.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);\r
54                 }\r
55             }\r
56             CFX_Matrix mt;\r
57             mt.Set(1, 0, 0, 1, rtText.left, rtText.top);\r
58             CFX_RectF rtClip = rtText;\r
59             mtRotate.TransformRect(rtClip);\r
60             mt.Concat(mtRotate);\r
61             pTextLayout->DrawString(pRenderDevice, mt, rtClip, this->GetLayoutItem()->GetIndex());\r
62         }\r
63     }\r
64 }\r
65 FX_BOOL CXFA_FFText::IsLoaded()\r
66 {\r
67     CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();\r
68     return pTextLayout != NULL && !pTextLayout->m_bHasBlock;\r
69 }\r
70 FX_BOOL CXFA_FFText::LayoutWidget()\r
71 {\r
72     CXFA_FFDraw::LayoutWidget();\r
73     CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();\r
74     if (!pTextLayout) {\r
75         return FALSE;\r
76     }\r
77     if (!pTextLayout->m_bHasBlock) {\r
78         return TRUE;\r
79     }\r
80     pTextLayout->m_Blocks.RemoveAll();\r
81     CXFA_LayoutItem* pItem = this->GetLayoutItem();\r
82     if (pItem->GetPrev() == NULL && pItem->GetNext() == NULL) {\r
83         return TRUE;\r
84     }\r
85     pItem = pItem->GetFirst();\r
86     while (pItem) {\r
87         CFX_RectF rtText;\r
88         pItem->GetRect(rtText);\r
89         if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {\r
90             if (pItem->GetPrev() == NULL) {\r
91                 FX_FLOAT fTopInset;\r
92                 mgWidget.GetTopInset(fTopInset);\r
93                 rtText.height -= fTopInset;\r
94             } else if (pItem->GetNext() == NULL) {\r
95                 FX_FLOAT fBottomInset;\r
96                 mgWidget.GetBottomInset(fBottomInset);\r
97                 rtText.height -= fBottomInset;\r
98             }\r
99         }\r
100         pTextLayout->ItemBlocks(rtText, pItem->GetIndex());\r
101         pItem = pItem->GetNext();\r
102     }\r
103     pTextLayout->m_bHasBlock = FALSE;\r
104     return TRUE;\r
105 }\r
106 FX_BOOL CXFA_FFText::OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)\r
107 {\r
108     CFX_RectF rtBox;\r
109     GetRectWithoutRotate(rtBox);\r
110     if (!rtBox.Contains(fx, fy)) {\r
111         return FALSE;\r
112     }\r
113     FX_LPCWSTR wsURLContent = GetLinkURLAtPoint(fx, fy);\r
114     if (NULL == wsURLContent) {\r
115         return FALSE;\r
116     }\r
117     SetButtonDown(TRUE);\r
118     return TRUE;\r
119 }\r
120 FX_BOOL CXFA_FFText::OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)\r
121 {\r
122     CFX_RectF rtBox;\r
123     GetRectWithoutRotate(rtBox);\r
124     if (!rtBox.Contains(fx, fy)) {\r
125         return FALSE;\r
126     }\r
127     FX_LPCWSTR wsURLContent = GetLinkURLAtPoint(fx, fy);\r
128     if (NULL == wsURLContent) {\r
129         return FALSE;\r
130     }\r
131     return TRUE;\r
132 }\r
133 FX_BOOL CXFA_FFText::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)\r
134 {\r
135     if (!IsButtonDown()) {\r
136         return FALSE;\r
137     }\r
138     SetButtonDown(FALSE);\r
139     FX_LPCWSTR wsURLContent = GetLinkURLAtPoint(fx, fy);\r
140     if (NULL == wsURLContent) {\r
141         return FALSE;\r
142     }\r
143     CXFA_FFDoc* pDoc = GetDoc();\r
144     pDoc->GetDocProvider()->GotoURL(pDoc, CFX_WideStringC(wsURLContent), FALSE);\r
145     return TRUE;\r
146 }\r
147 FX_DWORD CXFA_FFText::OnHitTest(FX_FLOAT fx, FX_FLOAT fy)\r
148 {\r
149     CFX_RectF rtBox;\r
150     GetRectWithoutRotate(rtBox);\r
151     if (!rtBox.Contains(fx, fy)) {\r
152         return FWL_WGTHITTEST_Unknown;\r
153     }\r
154     FX_LPCWSTR wsURLContent = GetLinkURLAtPoint(fx, fy);\r
155     if (NULL == wsURLContent) {\r
156         return FWL_WGTHITTEST_Unknown;\r
157     }\r
158     return FWL_WGTHITTEST_Transparent;\r
159 }\r
160 FX_LPCWSTR CXFA_FFText::GetLinkURLAtPoint(FX_FLOAT fx, FX_FLOAT fy)\r
161 {\r
162     CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();\r
163     if ( NULL == pTextLayout) {\r
164         return NULL;\r
165     }\r
166     FX_FLOAT x(fx), y(fy);\r
167     FWLToClient(x, y);\r
168     const CXFA_PieceLineArray* pPieceLines = pTextLayout->GetPieceLines();\r
169     int32_t iCount = pPieceLines->GetSize();\r
170     for (int32_t i = 0; i < iCount; i++) {\r
171         CXFA_PieceLine *pPieceLine = pPieceLines->GetAt(i);\r
172         int32_t iPieces = pPieceLine->m_textPieces.GetSize();\r
173         for (int32_t j = 0; j < iPieces; j++) {\r
174             XFA_LPTEXTPIECE pPiece = pPieceLine->m_textPieces.GetAt(j);\r
175             if (pPiece->pLinkData && pPiece->rtPiece.Contains(x, y)) {\r
176                 return pPiece->pLinkData->GetLinkURL();\r
177             }\r
178         }\r
179     }\r
180     return NULL;\r
181 }\r
182 void CXFA_FFText::FWLToClient(FX_FLOAT &fx, FX_FLOAT &fy)\r
183 {\r
184     CFX_RectF rtWidget;\r
185     GetRectWithoutRotate(rtWidget);\r
186     fx -= rtWidget.left;\r
187     fy -= rtWidget.top;\r
188 }\r