blob: 9b646230c20654837b5e674ea80dff616afcff7f [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,
Dan Sinclair1770c022016-03-14 14:14:16 -040027 CFX_Matrix* pMatrix,
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();
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 {
Dan Sinclair05df0752017-03-14 14:43:42 -040049 float fLeftInset;
50 float fRightInset;
51 float fTopInset = 0;
52 float fBottomInset = 0;
Dan Sinclair1b08df12017-02-09 09:17:20 -050053 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);
Dan Sinclair1770c022016-03-14 14:14:16 -040061 }
62 }
Dan Sinclair1b08df12017-02-09 09:17:20 -050063
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());
Dan Sinclair1770c022016-03-14 14:14:16 -040069}
Dan Sinclair1b08df12017-02-09 09:17:20 -050070
tsepezd19e9122016-11-02 15:43:18 -070071bool CXFA_FFText::IsLoaded() {
Dan Sinclair1770c022016-03-14 14:14:16 -040072 CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
73 return pTextLayout && !pTextLayout->m_bHasBlock;
74}
Dan Sinclaired991c72017-04-24 16:26:11 -040075
tsepezd19e9122016-11-02 15:43:18 -070076bool CXFA_FFText::PerformLayout() {
Dan Sinclair1770c022016-03-14 14:14:16 -040077 CXFA_FFDraw::PerformLayout();
78 CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
Tom Sepezfcc309e2017-03-24 14:19:11 -070079 if (!pTextLayout)
tsepezd19e9122016-11-02 15:43:18 -070080 return false;
Tom Sepezfcc309e2017-03-24 14:19:11 -070081 if (!pTextLayout->m_bHasBlock)
tsepezd19e9122016-11-02 15:43:18 -070082 return true;
Tom Sepezfcc309e2017-03-24 14:19:11 -070083
84 pTextLayout->m_Blocks.clear();
Dan Sinclair1770c022016-03-14 14:14:16 -040085 CXFA_LayoutItem* pItem = this;
Dan Sinclaired991c72017-04-24 16:26:11 -040086 if (!pItem->GetPrev() && !pItem->GetNext())
tsepezd19e9122016-11-02 15:43:18 -070087 return true;
Dan Sinclaired991c72017-04-24 16:26:11 -040088
Dan Sinclair1770c022016-03-14 14:14:16 -040089 pItem = pItem->GetFirst();
90 while (pItem) {
Dan Sinclairc2229072017-02-07 09:04:28 -050091 CFX_RectF rtText = pItem->GetRect(false);
Dan Sinclair1770c022016-03-14 14:14:16 -040092 if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
dsinclair85d1f2c2016-06-23 12:40:16 -070093 if (!pItem->GetPrev()) {
Dan Sinclair05df0752017-03-14 14:43:42 -040094 float fTopInset;
Dan Sinclair1770c022016-03-14 14:14:16 -040095 mgWidget.GetTopInset(fTopInset);
96 rtText.height -= fTopInset;
dsinclair85d1f2c2016-06-23 12:40:16 -070097 } else if (!pItem->GetNext()) {
Dan Sinclair05df0752017-03-14 14:43:42 -040098 float fBottomInset;
Dan Sinclair1770c022016-03-14 14:14:16 -040099 mgWidget.GetBottomInset(fBottomInset);
100 rtText.height -= fBottomInset;
101 }
102 }
103 pTextLayout->ItemBlocks(rtText, pItem->GetIndex());
104 pItem = pItem->GetNext();
105 }
tsepezd19e9122016-11-02 15:43:18 -0700106 pTextLayout->m_bHasBlock = false;
107 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400108}
Dan Sinclair1b08df12017-02-09 09:17:20 -0500109
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500110bool CXFA_FFText::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
111 if (!GetRectWithoutRotate().Contains(point))
tsepezd19e9122016-11-02 15:43:18 -0700112 return false;
Dan Sinclair1b08df12017-02-09 09:17:20 -0500113
Dan Sinclair812e96c2017-03-13 16:43:37 -0400114 const wchar_t* wsURLContent = GetLinkURLAtPoint(point);
Dan Sinclair1b08df12017-02-09 09:17:20 -0500115 if (!wsURLContent)
tsepezd19e9122016-11-02 15:43:18 -0700116 return false;
Dan Sinclair1b08df12017-02-09 09:17:20 -0500117
tsepezd19e9122016-11-02 15:43:18 -0700118 SetButtonDown(true);
119 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400120}
Dan Sinclair1b08df12017-02-09 09:17:20 -0500121
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500122bool CXFA_FFText::OnMouseMove(uint32_t dwFlags, const CFX_PointF& point) {
123 return GetRectWithoutRotate().Contains(point) && !!GetLinkURLAtPoint(point);
Dan Sinclair1770c022016-03-14 14:14:16 -0400124}
Dan Sinclair1b08df12017-02-09 09:17:20 -0500125
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500126bool CXFA_FFText::OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) {
127 if (!IsButtonDown())
tsepezd19e9122016-11-02 15:43:18 -0700128 return false;
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500129
tsepezd19e9122016-11-02 15:43:18 -0700130 SetButtonDown(false);
Dan Sinclair812e96c2017-03-13 16:43:37 -0400131 const wchar_t* wsURLContent = GetLinkURLAtPoint(point);
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500132 if (!wsURLContent)
tsepezd19e9122016-11-02 15:43:18 -0700133 return false;
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500134
Dan Sinclair1770c022016-03-14 14:14:16 -0400135 CXFA_FFDoc* pDoc = GetDoc();
dsinclair577ad2c2016-09-22 10:20:43 -0700136 pDoc->GetDocEnvironment()->GotoURL(pDoc, wsURLContent);
tsepezd19e9122016-11-02 15:43:18 -0700137 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400138}
Dan Sinclair1b08df12017-02-09 09:17:20 -0500139
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500140FWL_WidgetHit CXFA_FFText::OnHitTest(const CFX_PointF& point) {
141 if (!GetRectWithoutRotate().Contains(point))
dsinclair89fcde82016-05-03 13:00:25 -0700142 return FWL_WidgetHit::Unknown;
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500143 if (!GetLinkURLAtPoint(point))
dsinclair89fcde82016-05-03 13:00:25 -0700144 return FWL_WidgetHit::Unknown;
145 return FWL_WidgetHit::HyperLink;
Dan Sinclair1770c022016-03-14 14:14:16 -0400146}
Dan Sinclair1b08df12017-02-09 09:17:20 -0500147
Dan Sinclair812e96c2017-03-13 16:43:37 -0400148const wchar_t* CXFA_FFText::GetLinkURLAtPoint(const CFX_PointF& point) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400149 CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
tsepez783a7e02017-01-17 11:05:57 -0800150 if (!pTextLayout)
dsinclair85d1f2c2016-06-23 12:40:16 -0700151 return nullptr;
tsepez783a7e02017-01-17 11:05:57 -0800152
Dan Sinclair1b08df12017-02-09 09:17:20 -0500153 CFX_RectF rect = GetRectWithoutRotate();
tsepez783a7e02017-01-17 11:05:57 -0800154 for (const auto& pPieceLine : *pTextLayout->GetPieceLines()) {
155 for (const auto& pPiece : pPieceLine->m_textPieces) {
Dan Sinclair1b08df12017-02-09 09:17:20 -0500156 if (pPiece->pLinkData &&
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500157 pPiece->rtPiece.Contains(point - rect.TopLeft())) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400158 return pPiece->pLinkData->GetLinkURL();
Dan Sinclair1b08df12017-02-09 09:17:20 -0500159 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400160 }
161 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700162 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400163}