blob: e8d7aa32d02851e3753592e0d9421fdfee6f1b37 [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
dsinclair447b1f32016-12-08 10:06:32 -08009#include "xfa/fwl/fwl_widgetdef.h"
10#include "xfa/fwl/fwl_widgethit.h"
Dan Sinclair1f5d4982017-01-10 16:37:32 -050011#include "xfa/fxfa/app/cxfa_linkuserdata.h"
12#include "xfa/fxfa/app/cxfa_pieceline.h"
13#include "xfa/fxfa/app/cxfa_textlayout.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040014#include "xfa/fxfa/app/xfa_ffdraw.h"
Dan Sinclair1f5d4982017-01-10 16:37:32 -050015#include "xfa/fxfa/app/xfa_textpiece.h"
dsinclair5b493092016-09-29 20:20:24 -070016#include "xfa/fxfa/xfa_ffapp.h"
17#include "xfa/fxfa/xfa_ffdoc.h"
18#include "xfa/fxfa/xfa_ffpageview.h"
19#include "xfa/fxfa/xfa_ffwidget.h"
dsinclair202ad722016-09-29 17:41:42 -070020#include "xfa/fxgraphics/cfx_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 Sinclair1770c022016-03-14 14:14:16 -040026void CXFA_FFText::RenderWidget(CFX_Graphics* pGS,
27 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 {
49 FX_FLOAT fLeftInset;
50 FX_FLOAT fRightInset;
51 FX_FLOAT fTopInset = 0;
52 FX_FLOAT fBottomInset = 0;
53 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}
tsepezd19e9122016-11-02 15:43:18 -070075bool CXFA_FFText::PerformLayout() {
Dan Sinclair1770c022016-03-14 14:14:16 -040076 CXFA_FFDraw::PerformLayout();
77 CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
78 if (!pTextLayout) {
tsepezd19e9122016-11-02 15:43:18 -070079 return false;
Dan Sinclair1770c022016-03-14 14:14:16 -040080 }
81 if (!pTextLayout->m_bHasBlock) {
tsepezd19e9122016-11-02 15:43:18 -070082 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -040083 }
84 pTextLayout->m_Blocks.RemoveAll();
85 CXFA_LayoutItem* pItem = this;
dsinclair85d1f2c2016-06-23 12:40:16 -070086 if (!pItem->GetPrev() && !pItem->GetNext()) {
tsepezd19e9122016-11-02 15:43:18 -070087 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -040088 }
89 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 Sinclair1770c022016-03-14 14:14:16 -040094 FX_FLOAT fTopInset;
95 mgWidget.GetTopInset(fTopInset);
96 rtText.height -= fTopInset;
dsinclair85d1f2c2016-06-23 12:40:16 -070097 } else if (!pItem->GetNext()) {
Dan Sinclair1770c022016-03-14 14:14:16 -040098 FX_FLOAT fBottomInset;
99 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 Sinclairb45ea1f2017-02-21 14:27:59 -0500114 const FX_WCHAR* 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 Sinclairb45ea1f2017-02-21 14:27:59 -0500131 const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(point);
132 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 Sinclairb45ea1f2017-02-21 14:27:59 -0500148const FX_WCHAR* 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}