blob: ad0fdbc42ce782d2c268dea2611ed90251b8addc [file] [log] [blame]
Dan Sinclair1770c022016-03-14 14:14:16 -04001// 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
Dan Sinclair398a43d2016-03-23 15:51:01 -04009#include "xfa/fwl/core/fwl_widgetdef.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040010#include "xfa/fxfa/app/xfa_ffdraw.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040011#include "xfa/fxfa/app/xfa_textlayout.h"
dsinclair7222ea62016-04-06 14:33:07 -070012#include "xfa/fxfa/include/xfa_ffapp.h"
13#include "xfa/fxfa/include/xfa_ffdoc.h"
14#include "xfa/fxfa/include/xfa_ffpageview.h"
15#include "xfa/fxfa/include/xfa_ffwidget.h"
Dan Sinclair811b8a42016-03-17 08:59:42 -040016#include "xfa/fxgraphics/include/cfx_graphics.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040017
18CXFA_FFText::CXFA_FFText(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
19 : CXFA_FFDraw(pPageView, pDataAcc) {}
20CXFA_FFText::~CXFA_FFText() {}
21void CXFA_FFText::RenderWidget(CFX_Graphics* pGS,
22 CFX_Matrix* pMatrix,
dsinclair9d6ca992016-06-16 10:51:56 -070023 uint32_t dwStatus) {
Dan Sinclair1770c022016-03-14 14:14:16 -040024 if (!IsMatchVisibleStatus(dwStatus)) {
25 return;
26 }
27 {
28 CFX_Matrix mtRotate;
29 GetRotateMatrix(mtRotate);
30 if (pMatrix) {
31 mtRotate.Concat(*pMatrix);
32 }
33 CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
34 CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
35 if (pTextLayout) {
36 CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
37 CFX_RectF rtText;
38 GetRectWithoutRotate(rtText);
39 if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
40 CXFA_LayoutItem* pItem = this;
dsinclair85d1f2c2016-06-23 12:40:16 -070041 if (!pItem->GetPrev() && !pItem->GetNext()) {
Dan Sinclair1770c022016-03-14 14:14:16 -040042 XFA_RectWidthoutMargin(rtText, mgWidget);
43 } else {
44 FX_FLOAT fLeftInset, fRightInset, fTopInset = 0, fBottomInset = 0;
45 mgWidget.GetLeftInset(fLeftInset);
46 mgWidget.GetRightInset(fRightInset);
dsinclair85d1f2c2016-06-23 12:40:16 -070047 if (!pItem->GetPrev()) {
Dan Sinclair1770c022016-03-14 14:14:16 -040048 mgWidget.GetTopInset(fTopInset);
dsinclair85d1f2c2016-06-23 12:40:16 -070049 } else if (!pItem->GetNext()) {
Dan Sinclair1770c022016-03-14 14:14:16 -040050 mgWidget.GetBottomInset(fBottomInset);
51 }
52 rtText.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);
53 }
54 }
55 CFX_Matrix mt;
56 mt.Set(1, 0, 0, 1, rtText.left, rtText.top);
57 CFX_RectF rtClip = rtText;
58 mtRotate.TransformRect(rtClip);
59 mt.Concat(mtRotate);
60 pTextLayout->DrawString(pRenderDevice, mt, rtClip, GetIndex());
61 }
62 }
63}
64FX_BOOL CXFA_FFText::IsLoaded() {
65 CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
66 return pTextLayout && !pTextLayout->m_bHasBlock;
67}
68FX_BOOL CXFA_FFText::PerformLayout() {
69 CXFA_FFDraw::PerformLayout();
70 CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
71 if (!pTextLayout) {
72 return FALSE;
73 }
74 if (!pTextLayout->m_bHasBlock) {
75 return TRUE;
76 }
77 pTextLayout->m_Blocks.RemoveAll();
78 CXFA_LayoutItem* pItem = this;
dsinclair85d1f2c2016-06-23 12:40:16 -070079 if (!pItem->GetPrev() && !pItem->GetNext()) {
Dan Sinclair1770c022016-03-14 14:14:16 -040080 return TRUE;
81 }
82 pItem = pItem->GetFirst();
83 while (pItem) {
84 CFX_RectF rtText;
85 pItem->GetRect(rtText);
86 if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
dsinclair85d1f2c2016-06-23 12:40:16 -070087 if (!pItem->GetPrev()) {
Dan Sinclair1770c022016-03-14 14:14:16 -040088 FX_FLOAT fTopInset;
89 mgWidget.GetTopInset(fTopInset);
90 rtText.height -= fTopInset;
dsinclair85d1f2c2016-06-23 12:40:16 -070091 } else if (!pItem->GetNext()) {
Dan Sinclair1770c022016-03-14 14:14:16 -040092 FX_FLOAT fBottomInset;
93 mgWidget.GetBottomInset(fBottomInset);
94 rtText.height -= fBottomInset;
95 }
96 }
97 pTextLayout->ItemBlocks(rtText, pItem->GetIndex());
98 pItem = pItem->GetNext();
99 }
100 pTextLayout->m_bHasBlock = FALSE;
101 return TRUE;
102}
tsepez736f28a2016-03-25 14:19:51 -0700103FX_BOOL CXFA_FFText::OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400104 CFX_RectF rtBox;
105 GetRectWithoutRotate(rtBox);
106 if (!rtBox.Contains(fx, fy)) {
107 return FALSE;
108 }
109 const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(fx, fy);
dsinclair85d1f2c2016-06-23 12:40:16 -0700110 if (!wsURLContent) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400111 return FALSE;
112 }
113 SetButtonDown(TRUE);
114 return TRUE;
115}
tsepez736f28a2016-03-25 14:19:51 -0700116FX_BOOL CXFA_FFText::OnMouseMove(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400117 CFX_RectF rtBox;
118 GetRectWithoutRotate(rtBox);
119 if (!rtBox.Contains(fx, fy)) {
120 return FALSE;
121 }
122 const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(fx, fy);
dsinclair85d1f2c2016-06-23 12:40:16 -0700123 if (!wsURLContent) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400124 return FALSE;
125 }
126 return TRUE;
127}
tsepez736f28a2016-03-25 14:19:51 -0700128FX_BOOL CXFA_FFText::OnLButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400129 if (!IsButtonDown()) {
130 return FALSE;
131 }
132 SetButtonDown(FALSE);
133 const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(fx, fy);
dsinclair85d1f2c2016-06-23 12:40:16 -0700134 if (!wsURLContent) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400135 return FALSE;
136 }
137 CXFA_FFDoc* pDoc = GetDoc();
dsinclair577ad2c2016-09-22 10:20:43 -0700138 pDoc->GetDocEnvironment()->GotoURL(pDoc, wsURLContent);
Dan Sinclair1770c022016-03-14 14:14:16 -0400139 return TRUE;
140}
dsinclair89fcde82016-05-03 13:00:25 -0700141FWL_WidgetHit CXFA_FFText::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400142 CFX_RectF rtBox;
143 GetRectWithoutRotate(rtBox);
dsinclair89fcde82016-05-03 13:00:25 -0700144 if (!rtBox.Contains(fx, fy))
145 return FWL_WidgetHit::Unknown;
146 if (!GetLinkURLAtPoint(fx, fy))
147 return FWL_WidgetHit::Unknown;
148 return FWL_WidgetHit::HyperLink;
Dan Sinclair1770c022016-03-14 14:14:16 -0400149}
150const FX_WCHAR* CXFA_FFText::GetLinkURLAtPoint(FX_FLOAT fx, FX_FLOAT fy) {
151 CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
dsinclair85d1f2c2016-06-23 12:40:16 -0700152 if (!pTextLayout) {
153 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400154 }
155 FX_FLOAT x(fx), y(fy);
156 FWLToClient(x, y);
157 const CXFA_PieceLineArray* pPieceLines = pTextLayout->GetPieceLines();
158 int32_t iCount = pPieceLines->GetSize();
159 for (int32_t i = 0; i < iCount; i++) {
160 CXFA_PieceLine* pPieceLine = pPieceLines->GetAt(i);
161 int32_t iPieces = pPieceLine->m_textPieces.GetSize();
162 for (int32_t j = 0; j < iPieces; j++) {
163 XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(j);
164 if (pPiece->pLinkData && pPiece->rtPiece.Contains(x, y)) {
165 return pPiece->pLinkData->GetLinkURL();
166 }
167 }
168 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700169 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400170}
171void CXFA_FFText::FWLToClient(FX_FLOAT& fx, FX_FLOAT& fy) {
172 CFX_RectF rtWidget;
173 GetRectWithoutRotate(rtWidget);
174 fx -= rtWidget.left;
175 fy -= rtWidget.top;
176}