diff options
Diffstat (limited to 'xfa/src/fxfa/app/xfa_fftext.cpp')
-rw-r--r-- | xfa/src/fxfa/app/xfa_fftext.cpp | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/xfa/src/fxfa/app/xfa_fftext.cpp b/xfa/src/fxfa/app/xfa_fftext.cpp new file mode 100644 index 0000000000..2e9abb9f81 --- /dev/null +++ b/xfa/src/fxfa/app/xfa_fftext.cpp @@ -0,0 +1,179 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/src/fxfa/app/xfa_fftext.h" + +#include "xfa/include/fwl/core/fwl_widgetdef.h" +#include "xfa/include/fxgraphics/fx_graphics.h" +#include "xfa/src/fxfa/app/xfa_ffapp.h" +#include "xfa/src/fxfa/app/xfa_ffdoc.h" +#include "xfa/src/fxfa/app/xfa_ffdraw.h" +#include "xfa/src/fxfa/app/xfa_ffpageview.h" +#include "xfa/src/fxfa/app/xfa_ffwidget.h" +#include "xfa/src/fxfa/app/xfa_textlayout.h" + +CXFA_FFText::CXFA_FFText(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc) + : CXFA_FFDraw(pPageView, pDataAcc) {} +CXFA_FFText::~CXFA_FFText() {} +void CXFA_FFText::RenderWidget(CFX_Graphics* pGS, + CFX_Matrix* pMatrix, + FX_DWORD dwStatus, + int32_t iRotate) { + if (!IsMatchVisibleStatus(dwStatus)) { + return; + } + { + CFX_Matrix mtRotate; + GetRotateMatrix(mtRotate); + if (pMatrix) { + mtRotate.Concat(*pMatrix); + } + CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus); + CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout(); + if (pTextLayout) { + CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice(); + CFX_RectF rtText; + GetRectWithoutRotate(rtText); + if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) { + CXFA_LayoutItem* pItem = this; + if (pItem->GetPrev() == NULL && pItem->GetNext() == NULL) { + XFA_RectWidthoutMargin(rtText, mgWidget); + } else { + FX_FLOAT fLeftInset, fRightInset, fTopInset = 0, fBottomInset = 0; + mgWidget.GetLeftInset(fLeftInset); + mgWidget.GetRightInset(fRightInset); + if (pItem->GetPrev() == NULL) { + mgWidget.GetTopInset(fTopInset); + } else if (pItem->GetNext() == NULL) { + mgWidget.GetBottomInset(fBottomInset); + } + rtText.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset); + } + } + CFX_Matrix mt; + mt.Set(1, 0, 0, 1, rtText.left, rtText.top); + CFX_RectF rtClip = rtText; + mtRotate.TransformRect(rtClip); + mt.Concat(mtRotate); + pTextLayout->DrawString(pRenderDevice, mt, rtClip, GetIndex()); + } + } +} +FX_BOOL CXFA_FFText::IsLoaded() { + CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout(); + return pTextLayout && !pTextLayout->m_bHasBlock; +} +FX_BOOL CXFA_FFText::PerformLayout() { + CXFA_FFDraw::PerformLayout(); + CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout(); + if (!pTextLayout) { + return FALSE; + } + if (!pTextLayout->m_bHasBlock) { + return TRUE; + } + pTextLayout->m_Blocks.RemoveAll(); + CXFA_LayoutItem* pItem = this; + if (pItem->GetPrev() == NULL && pItem->GetNext() == NULL) { + return TRUE; + } + pItem = pItem->GetFirst(); + while (pItem) { + CFX_RectF rtText; + pItem->GetRect(rtText); + if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) { + if (pItem->GetPrev() == NULL) { + FX_FLOAT fTopInset; + mgWidget.GetTopInset(fTopInset); + rtText.height -= fTopInset; + } else if (pItem->GetNext() == NULL) { + FX_FLOAT fBottomInset; + mgWidget.GetBottomInset(fBottomInset); + rtText.height -= fBottomInset; + } + } + pTextLayout->ItemBlocks(rtText, pItem->GetIndex()); + pItem = pItem->GetNext(); + } + pTextLayout->m_bHasBlock = FALSE; + return TRUE; +} +FX_BOOL CXFA_FFText::OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) { + CFX_RectF rtBox; + GetRectWithoutRotate(rtBox); + if (!rtBox.Contains(fx, fy)) { + return FALSE; + } + const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(fx, fy); + if (NULL == wsURLContent) { + return FALSE; + } + SetButtonDown(TRUE); + return TRUE; +} +FX_BOOL CXFA_FFText::OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) { + CFX_RectF rtBox; + GetRectWithoutRotate(rtBox); + if (!rtBox.Contains(fx, fy)) { + return FALSE; + } + const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(fx, fy); + if (NULL == wsURLContent) { + return FALSE; + } + return TRUE; +} +FX_BOOL CXFA_FFText::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) { + if (!IsButtonDown()) { + return FALSE; + } + SetButtonDown(FALSE); + const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(fx, fy); + if (NULL == wsURLContent) { + return FALSE; + } + CXFA_FFDoc* pDoc = GetDoc(); + pDoc->GetDocProvider()->GotoURL(pDoc, CFX_WideStringC(wsURLContent), FALSE); + return TRUE; +} +FX_DWORD CXFA_FFText::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) { + CFX_RectF rtBox; + GetRectWithoutRotate(rtBox); + if (!rtBox.Contains(fx, fy)) { + return FWL_WGTHITTEST_Unknown; + } + if (!GetLinkURLAtPoint(fx, fy)) { + return FWL_WGTHITTEST_Unknown; + } + return FWL_WGTHITTEST_HyperLink; +} +const FX_WCHAR* CXFA_FFText::GetLinkURLAtPoint(FX_FLOAT fx, FX_FLOAT fy) { + CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout(); + if (NULL == pTextLayout) { + return NULL; + } + FX_FLOAT x(fx), y(fy); + FWLToClient(x, y); + const CXFA_PieceLineArray* pPieceLines = pTextLayout->GetPieceLines(); + int32_t iCount = pPieceLines->GetSize(); + for (int32_t i = 0; i < iCount; i++) { + CXFA_PieceLine* pPieceLine = pPieceLines->GetAt(i); + int32_t iPieces = pPieceLine->m_textPieces.GetSize(); + for (int32_t j = 0; j < iPieces; j++) { + XFA_TEXTPIECE* pPiece = pPieceLine->m_textPieces.GetAt(j); + if (pPiece->pLinkData && pPiece->rtPiece.Contains(x, y)) { + return pPiece->pLinkData->GetLinkURL(); + } + } + } + return NULL; +} +void CXFA_FFText::FWLToClient(FX_FLOAT& fx, FX_FLOAT& fy) { + CFX_RectF rtWidget; + GetRectWithoutRotate(rtWidget); + fx -= rtWidget.left; + fy -= rtWidget.top; +} |