blob: 274f3bfb619b7caf9dcac5c95954f443e679db02 [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
Dan Sinclair24ef6332017-07-24 10:52:57 -04007#include "xfa/fxfa/cxfa_fftext.h"
Dan Sinclair1770c022016-03-14 14:14:16 -04008
dsinclair447b1f32016-12-08 10:06:32 -08009#include "xfa/fwl/fwl_widgetdef.h"
10#include "xfa/fwl/fwl_widgethit.h"
Dan Sinclair80c48782017-03-23 12:11:20 -040011#include "xfa/fxfa/cxfa_ffapp.h"
12#include "xfa/fxfa/cxfa_ffdoc.h"
Dan Sinclair24ef6332017-07-24 10:52:57 -040013#include "xfa/fxfa/cxfa_ffdraw.h"
Dan Sinclair80c48782017-03-23 12:11:20 -040014#include "xfa/fxfa/cxfa_ffpageview.h"
15#include "xfa/fxfa/cxfa_ffwidget.h"
Dan Sinclair24ef6332017-07-24 10:52:57 -040016#include "xfa/fxfa/cxfa_linkuserdata.h"
17#include "xfa/fxfa/cxfa_pieceline.h"
18#include "xfa/fxfa/cxfa_textlayout.h"
19#include "xfa/fxfa/cxfa_textpiece.h"
Dan Sinclair2b918c82017-07-13 14:47:10 -040020#include "xfa/fxgraphics/cxfa_graphics.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040021
dan sinclairaaf0bdc2017-02-04 10:16:21 -050022CXFA_FFText::CXFA_FFText(CXFA_WidgetAcc* pDataAcc) : CXFA_FFDraw(pDataAcc) {}
23
Dan Sinclair1770c022016-03-14 14:14:16 -040024CXFA_FFText::~CXFA_FFText() {}
dan sinclairaaf0bdc2017-02-04 10:16:21 -050025
Dan Sinclair2b918c82017-07-13 14:47:10 -040026void CXFA_FFText::RenderWidget(CXFA_Graphics* pGS,
Lei Zhang7c9d4c22017-08-17 13:53:52 -070027 const CFX_Matrix& matrix,
dsinclair9d6ca992016-06-16 10:51:56 -070028 uint32_t dwStatus) {
Dan Sinclair1b08df12017-02-09 09:17:20 -050029 if (!IsMatchVisibleStatus(dwStatus))
Dan Sinclair1770c022016-03-14 14:14:16 -040030 return;
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050031
Dan Sinclair1b08df12017-02-09 09:17:20 -050032 CFX_Matrix mtRotate = GetRotateMatrix();
Lei Zhang7c9d4c22017-08-17 13:53:52 -070033 mtRotate.Concat(matrix);
Dan Sinclair1b08df12017-02-09 09:17:20 -050034
Lei Zhang7c9d4c22017-08-17 13:53:52 -070035 CXFA_FFWidget::RenderWidget(pGS, mtRotate, dwStatus);
Dan Sinclair1b08df12017-02-09 09:17:20 -050036
37 CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
38 if (!pTextLayout)
39 return;
40
41 CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
42 CFX_RectF rtText = GetRectWithoutRotate();
43 if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
44 CXFA_LayoutItem* pItem = this;
45 if (!pItem->GetPrev() && !pItem->GetNext()) {
46 XFA_RectWidthoutMargin(rtText, mgWidget);
47 } else {
Dan Sinclair05df0752017-03-14 14:43:42 -040048 float fLeftInset;
49 float fRightInset;
50 float fTopInset = 0;
51 float fBottomInset = 0;
Dan Sinclair1b08df12017-02-09 09:17:20 -050052 mgWidget.GetLeftInset(fLeftInset);
53 mgWidget.GetRightInset(fRightInset);
54 if (!pItem->GetPrev())
55 mgWidget.GetTopInset(fTopInset);
56 else if (!pItem->GetNext())
57 mgWidget.GetBottomInset(fBottomInset);
58
59 rtText.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);
Dan Sinclair1770c022016-03-14 14:14:16 -040060 }
61 }
Dan Sinclair1b08df12017-02-09 09:17:20 -050062
63 CFX_Matrix mt(1, 0, 0, 1, rtText.left, rtText.top);
Jane Liu878b27d2017-08-22 10:50:06 -040064 CFX_RectF rtClip = mtRotate.TransformRect(rtText);
Dan Sinclair1b08df12017-02-09 09:17:20 -050065 mt.Concat(mtRotate);
66 pTextLayout->DrawString(pRenderDevice, mt, rtClip, GetIndex());
Dan Sinclair1770c022016-03-14 14:14:16 -040067}
Dan Sinclair1b08df12017-02-09 09:17:20 -050068
tsepezd19e9122016-11-02 15:43:18 -070069bool CXFA_FFText::IsLoaded() {
Dan Sinclair1770c022016-03-14 14:14:16 -040070 CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
71 return pTextLayout && !pTextLayout->m_bHasBlock;
72}
Dan Sinclaired991c72017-04-24 16:26:11 -040073
tsepezd19e9122016-11-02 15:43:18 -070074bool CXFA_FFText::PerformLayout() {
Dan Sinclair1770c022016-03-14 14:14:16 -040075 CXFA_FFDraw::PerformLayout();
76 CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
Tom Sepezfcc309e2017-03-24 14:19:11 -070077 if (!pTextLayout)
tsepezd19e9122016-11-02 15:43:18 -070078 return false;
Tom Sepezfcc309e2017-03-24 14:19:11 -070079 if (!pTextLayout->m_bHasBlock)
tsepezd19e9122016-11-02 15:43:18 -070080 return true;
Tom Sepezfcc309e2017-03-24 14:19:11 -070081
82 pTextLayout->m_Blocks.clear();
Dan Sinclair1770c022016-03-14 14:14:16 -040083 CXFA_LayoutItem* pItem = this;
Dan Sinclaired991c72017-04-24 16:26:11 -040084 if (!pItem->GetPrev() && !pItem->GetNext())
tsepezd19e9122016-11-02 15:43:18 -070085 return true;
Dan Sinclaired991c72017-04-24 16:26:11 -040086
Dan Sinclair1770c022016-03-14 14:14:16 -040087 pItem = pItem->GetFirst();
88 while (pItem) {
Dan Sinclairc2229072017-02-07 09:04:28 -050089 CFX_RectF rtText = pItem->GetRect(false);
Dan Sinclair1770c022016-03-14 14:14:16 -040090 if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
dsinclair85d1f2c2016-06-23 12:40:16 -070091 if (!pItem->GetPrev()) {
Dan Sinclair05df0752017-03-14 14:43:42 -040092 float fTopInset;
Dan Sinclair1770c022016-03-14 14:14:16 -040093 mgWidget.GetTopInset(fTopInset);
94 rtText.height -= fTopInset;
dsinclair85d1f2c2016-06-23 12:40:16 -070095 } else if (!pItem->GetNext()) {
Dan Sinclair05df0752017-03-14 14:43:42 -040096 float fBottomInset;
Dan Sinclair1770c022016-03-14 14:14:16 -040097 mgWidget.GetBottomInset(fBottomInset);
98 rtText.height -= fBottomInset;
99 }
100 }
101 pTextLayout->ItemBlocks(rtText, pItem->GetIndex());
102 pItem = pItem->GetNext();
103 }
tsepezd19e9122016-11-02 15:43:18 -0700104 pTextLayout->m_bHasBlock = false;
105 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400106}
Dan Sinclair1b08df12017-02-09 09:17:20 -0500107
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500108bool CXFA_FFText::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
109 if (!GetRectWithoutRotate().Contains(point))
tsepezd19e9122016-11-02 15:43:18 -0700110 return false;
Dan Sinclair1b08df12017-02-09 09:17:20 -0500111
Dan Sinclair812e96c2017-03-13 16:43:37 -0400112 const wchar_t* wsURLContent = GetLinkURLAtPoint(point);
Dan Sinclair1b08df12017-02-09 09:17:20 -0500113 if (!wsURLContent)
tsepezd19e9122016-11-02 15:43:18 -0700114 return false;
Dan Sinclair1b08df12017-02-09 09:17:20 -0500115
tsepezd19e9122016-11-02 15:43:18 -0700116 SetButtonDown(true);
117 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400118}
Dan Sinclair1b08df12017-02-09 09:17:20 -0500119
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500120bool CXFA_FFText::OnMouseMove(uint32_t dwFlags, const CFX_PointF& point) {
121 return GetRectWithoutRotate().Contains(point) && !!GetLinkURLAtPoint(point);
Dan Sinclair1770c022016-03-14 14:14:16 -0400122}
Dan Sinclair1b08df12017-02-09 09:17:20 -0500123
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500124bool CXFA_FFText::OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) {
125 if (!IsButtonDown())
tsepezd19e9122016-11-02 15:43:18 -0700126 return false;
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500127
tsepezd19e9122016-11-02 15:43:18 -0700128 SetButtonDown(false);
Dan Sinclair812e96c2017-03-13 16:43:37 -0400129 const wchar_t* wsURLContent = GetLinkURLAtPoint(point);
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500130 if (!wsURLContent)
tsepezd19e9122016-11-02 15:43:18 -0700131 return false;
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500132
Dan Sinclair1770c022016-03-14 14:14:16 -0400133 CXFA_FFDoc* pDoc = GetDoc();
dsinclair577ad2c2016-09-22 10:20:43 -0700134 pDoc->GetDocEnvironment()->GotoURL(pDoc, wsURLContent);
tsepezd19e9122016-11-02 15:43:18 -0700135 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400136}
Dan Sinclair1b08df12017-02-09 09:17:20 -0500137
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500138FWL_WidgetHit CXFA_FFText::OnHitTest(const CFX_PointF& point) {
139 if (!GetRectWithoutRotate().Contains(point))
dsinclair89fcde82016-05-03 13:00:25 -0700140 return FWL_WidgetHit::Unknown;
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500141 if (!GetLinkURLAtPoint(point))
dsinclair89fcde82016-05-03 13:00:25 -0700142 return FWL_WidgetHit::Unknown;
143 return FWL_WidgetHit::HyperLink;
Dan Sinclair1770c022016-03-14 14:14:16 -0400144}
Dan Sinclair1b08df12017-02-09 09:17:20 -0500145
Dan Sinclair812e96c2017-03-13 16:43:37 -0400146const wchar_t* CXFA_FFText::GetLinkURLAtPoint(const CFX_PointF& point) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400147 CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
tsepez783a7e02017-01-17 11:05:57 -0800148 if (!pTextLayout)
dsinclair85d1f2c2016-06-23 12:40:16 -0700149 return nullptr;
tsepez783a7e02017-01-17 11:05:57 -0800150
Dan Sinclair1b08df12017-02-09 09:17:20 -0500151 CFX_RectF rect = GetRectWithoutRotate();
tsepez783a7e02017-01-17 11:05:57 -0800152 for (const auto& pPieceLine : *pTextLayout->GetPieceLines()) {
153 for (const auto& pPiece : pPieceLine->m_textPieces) {
Dan Sinclair1b08df12017-02-09 09:17:20 -0500154 if (pPiece->pLinkData &&
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500155 pPiece->rtPiece.Contains(point - rect.TopLeft())) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400156 return pPiece->pLinkData->GetLinkURL();
Dan Sinclair1b08df12017-02-09 09:17:20 -0500157 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400158 }
159 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700160 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400161}