diff options
Diffstat (limited to 'xfa/fxfa/app/cxfa_textlayout.cpp')
-rw-r--r-- | xfa/fxfa/app/cxfa_textlayout.cpp | 1304 |
1 files changed, 0 insertions, 1304 deletions
diff --git a/xfa/fxfa/app/cxfa_textlayout.cpp b/xfa/fxfa/app/cxfa_textlayout.cpp deleted file mode 100644 index 489df9ab9c..0000000000 --- a/xfa/fxfa/app/cxfa_textlayout.cpp +++ /dev/null @@ -1,1304 +0,0 @@ -// Copyright 2017 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/fxfa/app/cxfa_textlayout.h" - -#include <algorithm> -#include <utility> - -#include "core/fxcrt/xml/cfx_xmlelement.h" -#include "core/fxcrt/xml/cfx_xmlnode.h" -#include "core/fxcrt/xml/cfx_xmltext.h" -#include "third_party/base/ptr_util.h" -#include "third_party/base/stl_util.h" -#include "xfa/fde/cfde_brush.h" -#include "xfa/fde/cfde_path.h" -#include "xfa/fde/cfde_pen.h" -#include "xfa/fde/cfde_renderdevice.h" -#include "xfa/fde/css/cfde_csscomputedstyle.h" -#include "xfa/fde/css/cfde_cssstyleselector.h" -#include "xfa/fxfa/app/cxfa_linkuserdata.h" -#include "xfa/fxfa/app/cxfa_loadercontext.h" -#include "xfa/fxfa/app/cxfa_pieceline.h" -#include "xfa/fxfa/app/cxfa_textparsecontext.h" -#include "xfa/fxfa/app/cxfa_textpiece.h" -#include "xfa/fxfa/app/cxfa_textprovider.h" -#include "xfa/fxfa/app/cxfa_texttabstopscontext.h" -#include "xfa/fxfa/app/cxfa_textuserdata.h" -#include "xfa/fxfa/parser/cxfa_font.h" -#include "xfa/fxfa/parser/cxfa_node.h" -#include "xfa/fxfa/parser/cxfa_para.h" - -#define XFA_LOADERCNTXTFLG_FILTERSPACE 0x001 - -CXFA_TextLayout::CXFA_TextLayout(CXFA_TextProvider* pTextProvider) - : m_bHasBlock(false), - m_pTextProvider(pTextProvider), - m_pTextDataNode(nullptr), - m_bRichText(false), - m_iLines(0), - m_fMaxWidth(0), - m_bBlockContinue(true) { - ASSERT(m_pTextProvider); -} - -CXFA_TextLayout::~CXFA_TextLayout() { - m_textParser.Reset(); - Unload(); -} - -void CXFA_TextLayout::Unload() { - m_pieceLines.clear(); - m_pBreak.reset(); -} - -void CXFA_TextLayout::GetTextDataNode() { - if (!m_pTextProvider) - return; - - CXFA_Node* pNode = m_pTextProvider->GetTextNode(m_bRichText); - if (pNode && m_bRichText) - m_textParser.Reset(); - - m_pTextDataNode = pNode; -} - -CFX_XMLNode* CXFA_TextLayout::GetXMLContainerNode() { - if (!m_bRichText) - return nullptr; - - CFX_XMLNode* pXMLRoot = m_pTextDataNode->GetXMLMappingNode(); - if (!pXMLRoot) - return nullptr; - - CFX_XMLNode* pXMLContainer = nullptr; - for (CFX_XMLNode* pXMLChild = pXMLRoot->GetNodeItem(CFX_XMLNode::FirstChild); - pXMLChild; - pXMLChild = pXMLChild->GetNodeItem(CFX_XMLNode::NextSibling)) { - if (pXMLChild->GetType() == FX_XMLNODE_Element) { - CFX_XMLElement* pXMLElement = static_cast<CFX_XMLElement*>(pXMLChild); - CFX_WideString wsTag = pXMLElement->GetLocalTagName(); - if (wsTag == L"body" || wsTag == L"html") { - pXMLContainer = pXMLChild; - break; - } - } - } - return pXMLContainer; -} - -std::unique_ptr<CFX_RTFBreak> CXFA_TextLayout::CreateBreak(bool bDefault) { - uint32_t dwStyle = FX_LAYOUTSTYLE_ExpandTab; - if (!bDefault) - dwStyle |= FX_LAYOUTSTYLE_Pagination; - - auto pBreak = pdfium::MakeUnique<CFX_RTFBreak>(dwStyle); - pBreak->SetLineBreakTolerance(1); - pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, nullptr)); - pBreak->SetFontSize(m_textParser.GetFontSize(m_pTextProvider, nullptr)); - return pBreak; -} - -void CXFA_TextLayout::InitBreak(float fLineWidth) { - CXFA_Font font = m_pTextProvider->GetFontNode(); - CXFA_Para para = m_pTextProvider->GetParaNode(); - float fStart = 0; - float fStartPos = 0; - if (para) { - CFX_RTFLineAlignment iAlign = CFX_RTFLineAlignment::Left; - switch (para.GetHorizontalAlign()) { - case XFA_ATTRIBUTEENUM_Center: - iAlign = CFX_RTFLineAlignment::Center; - break; - case XFA_ATTRIBUTEENUM_Right: - iAlign = CFX_RTFLineAlignment::Right; - break; - case XFA_ATTRIBUTEENUM_Justify: - iAlign = CFX_RTFLineAlignment::Justified; - break; - case XFA_ATTRIBUTEENUM_JustifyAll: - iAlign = CFX_RTFLineAlignment::Distributed; - break; - } - m_pBreak->SetAlignment(iAlign); - - fStart = para.GetMarginLeft(); - if (m_pTextProvider->IsCheckButtonAndAutoWidth()) { - if (iAlign != CFX_RTFLineAlignment::Left) - fLineWidth -= para.GetMarginRight(); - } else { - fLineWidth -= para.GetMarginRight(); - } - if (fLineWidth < 0) - fLineWidth = fStart; - - fStartPos = fStart; - float fIndent = para.GetTextIndent(); - if (fIndent > 0) - fStartPos += fIndent; - } - - m_pBreak->SetLineBoundary(fStart, fLineWidth); - m_pBreak->SetLineStartPos(fStartPos); - if (font) { - m_pBreak->SetHorizontalScale((int32_t)font.GetHorizontalScale()); - m_pBreak->SetVerticalScale((int32_t)font.GetVerticalScale()); - m_pBreak->SetCharSpace(font.GetLetterSpacing()); - } - - float fFontSize = m_textParser.GetFontSize(m_pTextProvider, nullptr); - m_pBreak->SetFontSize(fFontSize); - m_pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, nullptr)); - m_pBreak->SetLineBreakTolerance(fFontSize * 0.2f); -} - -void CXFA_TextLayout::InitBreak(CFDE_CSSComputedStyle* pStyle, - FDE_CSSDisplay eDisplay, - float fLineWidth, - CFX_XMLNode* pXMLNode, - CFDE_CSSComputedStyle* pParentStyle) { - if (!pStyle) { - InitBreak(fLineWidth); - return; - } - - if (eDisplay == FDE_CSSDisplay::Block || - eDisplay == FDE_CSSDisplay::ListItem) { - CFX_RTFLineAlignment iAlign = CFX_RTFLineAlignment::Left; - switch (pStyle->GetTextAlign()) { - case FDE_CSSTextAlign::Right: - iAlign = CFX_RTFLineAlignment::Right; - break; - case FDE_CSSTextAlign::Center: - iAlign = CFX_RTFLineAlignment::Center; - break; - case FDE_CSSTextAlign::Justify: - iAlign = CFX_RTFLineAlignment::Justified; - break; - case FDE_CSSTextAlign::JustifyAll: - iAlign = CFX_RTFLineAlignment::Distributed; - break; - default: - break; - } - m_pBreak->SetAlignment(iAlign); - - float fStart = 0; - const FDE_CSSRect* pRect = pStyle->GetMarginWidth(); - const FDE_CSSRect* pPaddingRect = pStyle->GetPaddingWidth(); - if (pRect) { - fStart = pRect->left.GetValue(); - fLineWidth -= pRect->right.GetValue(); - if (pPaddingRect) { - fStart += pPaddingRect->left.GetValue(); - fLineWidth -= pPaddingRect->right.GetValue(); - } - if (eDisplay == FDE_CSSDisplay::ListItem) { - const FDE_CSSRect* pParRect = pParentStyle->GetMarginWidth(); - const FDE_CSSRect* pParPaddingRect = pParentStyle->GetPaddingWidth(); - if (pParRect) { - fStart += pParRect->left.GetValue(); - fLineWidth -= pParRect->right.GetValue(); - if (pParPaddingRect) { - fStart += pParPaddingRect->left.GetValue(); - fLineWidth -= pParPaddingRect->right.GetValue(); - } - } - FDE_CSSRect pNewRect; - pNewRect.left.Set(FDE_CSSLengthUnit::Point, fStart); - pNewRect.right.Set(FDE_CSSLengthUnit::Point, pRect->right.GetValue()); - pNewRect.top.Set(FDE_CSSLengthUnit::Point, pRect->top.GetValue()); - pNewRect.bottom.Set(FDE_CSSLengthUnit::Point, pRect->bottom.GetValue()); - pStyle->SetMarginWidth(pNewRect); - } - } - m_pBreak->SetLineBoundary(fStart, fLineWidth); - float fIndent = pStyle->GetTextIndent().GetValue(); - if (fIndent > 0) - fStart += fIndent; - - m_pBreak->SetLineStartPos(fStart); - m_pBreak->SetTabWidth(m_textParser.GetTabInterval(pStyle)); - if (!m_pTabstopContext) - m_pTabstopContext = pdfium::MakeUnique<CXFA_TextTabstopsContext>(); - m_textParser.GetTabstops(pStyle, m_pTabstopContext.get()); - for (const auto& stop : m_pTabstopContext->m_tabstops) - m_pBreak->AddPositionedTab(stop.fTabstops); - } - float fFontSize = m_textParser.GetFontSize(m_pTextProvider, pStyle); - m_pBreak->SetFontSize(fFontSize); - m_pBreak->SetLineBreakTolerance(fFontSize * 0.2f); - m_pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, pStyle)); - m_pBreak->SetHorizontalScale( - m_textParser.GetHorScale(m_pTextProvider, pStyle, pXMLNode)); - m_pBreak->SetVerticalScale(m_textParser.GetVerScale(m_pTextProvider, pStyle)); - m_pBreak->SetCharSpace(pStyle->GetLetterSpacing().GetValue()); -} - -int32_t CXFA_TextLayout::GetText(CFX_WideString& wsText) { - GetTextDataNode(); - wsText.clear(); - if (!m_bRichText) - wsText = m_pTextDataNode->GetContent(); - return wsText.GetLength(); -} - -float CXFA_TextLayout::GetLayoutHeight() { - if (!m_pLoader) - return 0; - - if (m_pLoader->m_lineHeights.empty() && m_pLoader->m_fWidth > 0) { - CFX_SizeF szMax(m_pLoader->m_fWidth, m_pLoader->m_fHeight); - CFX_SizeF szDef; - m_pLoader->m_bSaveLineHeight = true; - m_pLoader->m_fLastPos = 0; - CalcSize(szMax, szMax, szDef); - m_pLoader->m_bSaveLineHeight = false; - return szDef.height; - } - - float fHeight = m_pLoader->m_fHeight; - if (fHeight < 0.1f) { - fHeight = 0; - for (float value : m_pLoader->m_lineHeights) - fHeight += value; - } - return fHeight; -} - -float CXFA_TextLayout::StartLayout(float fWidth) { - if (!m_pLoader) - m_pLoader = pdfium::MakeUnique<CXFA_LoaderContext>(); - - if (fWidth < 0 || - (m_pLoader->m_fWidth > -1 && fabs(fWidth - m_pLoader->m_fWidth) > 0)) { - m_pLoader->m_lineHeights.clear(); - m_Blocks.clear(); - Unload(); - m_pLoader->m_fStartLineOffset = 0; - } - m_pLoader->m_fWidth = fWidth; - - if (fWidth < 0) { - CFX_SizeF szMax; - CFX_SizeF szDef; - m_pLoader->m_bSaveLineHeight = true; - m_pLoader->m_fLastPos = 0; - CalcSize(szMax, szMax, szDef); - m_pLoader->m_bSaveLineHeight = false; - fWidth = szDef.width; - } - return fWidth; -} - -bool CXFA_TextLayout::DoLayout(int32_t iBlockIndex, - float& fCalcHeight, - float fContentAreaHeight, - float fTextHeight) { - if (!m_pLoader) - return false; - - int32_t iBlockCount = pdfium::CollectionSize<int32_t>(m_Blocks); - float fHeight = fTextHeight; - if (fHeight < 0) - fHeight = GetLayoutHeight(); - - m_pLoader->m_fHeight = fHeight; - if (fContentAreaHeight < 0) - return false; - - m_bHasBlock = true; - if (iBlockCount == 0 && fHeight > 0) { - fHeight = fTextHeight - GetLayoutHeight(); - if (fHeight > 0) { - int32_t iAlign = m_textParser.GetVAlign(m_pTextProvider); - if (iAlign == XFA_ATTRIBUTEENUM_Middle) - fHeight /= 2.0f; - else if (iAlign != XFA_ATTRIBUTEENUM_Bottom) - fHeight = 0; - m_pLoader->m_fStartLineOffset = fHeight; - } - } - - float fLinePos = m_pLoader->m_fStartLineOffset; - int32_t iLineIndex = 0; - if (iBlockCount > 1) { - if (iBlockCount >= (iBlockIndex + 1) * 2) { - iLineIndex = m_Blocks[iBlockIndex * 2]; - } else { - iLineIndex = m_Blocks[iBlockCount - 1] + m_Blocks[iBlockCount - 2]; - } - if (!m_pLoader->m_BlocksHeight.empty()) { - for (int32_t i = 0; i < iBlockIndex; i++) - fLinePos -= m_pLoader->m_BlocksHeight[i * 2 + 1]; - } - } - - int32_t iCount = pdfium::CollectionSize<int32_t>(m_pLoader->m_lineHeights); - int32_t i = 0; - for (i = iLineIndex; i < iCount; i++) { - float fLineHeight = m_pLoader->m_lineHeights[i]; - if (i == iLineIndex && fLineHeight - fContentAreaHeight > 0.001) { - fCalcHeight = 0; - return true; - } - if (fLinePos + fLineHeight - fContentAreaHeight > 0.001) { - if (iBlockCount >= (iBlockIndex + 1) * 2) { - m_Blocks[iBlockIndex * 2] = iLineIndex; - m_Blocks[iBlockIndex * 2 + 1] = i - iLineIndex; - } else { - m_Blocks.push_back(iLineIndex); - m_Blocks.push_back(i - iLineIndex); - } - if (i == iLineIndex) { - if (fCalcHeight <= fLinePos) { - if (pdfium::CollectionSize<int32_t>(m_pLoader->m_BlocksHeight) > - iBlockIndex * 2 && - (m_pLoader->m_BlocksHeight[iBlockIndex * 2] == iBlockIndex)) { - m_pLoader->m_BlocksHeight[iBlockIndex * 2 + 1] = fCalcHeight; - } else { - m_pLoader->m_BlocksHeight.push_back((float)iBlockIndex); - m_pLoader->m_BlocksHeight.push_back(fCalcHeight); - } - } - return true; - } - - fCalcHeight = fLinePos; - return true; - } - fLinePos += fLineHeight; - } - return false; -} - -int32_t CXFA_TextLayout::CountBlocks() const { - int32_t iCount = pdfium::CollectionSize<int32_t>(m_Blocks) / 2; - return iCount > 0 ? iCount : 1; -} - -bool CXFA_TextLayout::CalcSize(const CFX_SizeF& minSize, - const CFX_SizeF& maxSize, - CFX_SizeF& defaultSize) { - defaultSize.width = maxSize.width; - if (defaultSize.width < 1) - defaultSize.width = 0xFFFF; - - m_pBreak = CreateBreak(false); - float fLinePos = 0; - m_iLines = 0; - m_fMaxWidth = 0; - Loader(defaultSize, fLinePos, false); - if (fLinePos < 0.1f) - fLinePos = m_textParser.GetFontSize(m_pTextProvider, nullptr); - - m_pTabstopContext.reset(); - defaultSize = CFX_SizeF(m_fMaxWidth, fLinePos); - return true; -} - -bool CXFA_TextLayout::Layout(const CFX_SizeF& size, float* fHeight) { - if (size.width < 1) - return false; - - Unload(); - m_pBreak = CreateBreak(true); - if (m_pLoader) { - m_pLoader->m_iTotalLines = -1; - m_pLoader->m_iChar = 0; - } - - m_iLines = 0; - float fLinePos = 0; - Loader(size, fLinePos, true); - UpdateAlign(size.height, fLinePos); - m_pTabstopContext.reset(); - if (fHeight) - *fHeight = fLinePos; - return true; -} - -bool CXFA_TextLayout::Layout(int32_t iBlock) { - if (!m_pLoader || iBlock < 0 || iBlock >= CountBlocks()) - return false; - if (m_pLoader->m_fWidth < 1) - return false; - - m_pLoader->m_iTotalLines = -1; - m_iLines = 0; - float fLinePos = 0; - CXFA_Node* pNode = nullptr; - CFX_SizeF szText(m_pLoader->m_fWidth, m_pLoader->m_fHeight); - int32_t iCount = pdfium::CollectionSize<int32_t>(m_Blocks); - int32_t iBlocksHeightCount = - pdfium::CollectionSize<int32_t>(m_pLoader->m_BlocksHeight); - iBlocksHeightCount /= 2; - if (iBlock < iBlocksHeightCount) - return true; - if (iBlock == iBlocksHeightCount) { - Unload(); - m_pBreak = CreateBreak(true); - fLinePos = m_pLoader->m_fStartLineOffset; - for (int32_t i = 0; i < iBlocksHeightCount; i++) - fLinePos -= m_pLoader->m_BlocksHeight[i * 2 + 1]; - - m_pLoader->m_iChar = 0; - if (iCount > 1) - m_pLoader->m_iTotalLines = m_Blocks[iBlock * 2 + 1]; - - Loader(szText, fLinePos, true); - if (iCount == 0 && m_pLoader->m_fStartLineOffset < 0.1f) - UpdateAlign(szText.height, fLinePos); - } else if (m_pTextDataNode) { - iBlock *= 2; - if (iBlock < iCount - 2) - m_pLoader->m_iTotalLines = m_Blocks[iBlock + 1]; - - m_pBreak->Reset(); - if (m_bRichText) { - CFX_XMLNode* pContainerNode = GetXMLContainerNode(); - if (!pContainerNode) - return true; - - CFX_XMLNode* pXMLNode = m_pLoader->m_pXMLNode; - if (!pXMLNode) - return true; - - CFX_XMLNode* pSaveXMLNode = m_pLoader->m_pXMLNode; - for (; pXMLNode; - pXMLNode = pXMLNode->GetNodeItem(CFX_XMLNode::NextSibling)) { - if (!LoadRichText(pXMLNode, szText, fLinePos, m_pLoader->m_pParentStyle, - true, nullptr)) { - break; - } - } - while (!pXMLNode) { - pXMLNode = pSaveXMLNode->GetNodeItem(CFX_XMLNode::Parent); - if (pXMLNode == pContainerNode) - break; - if (!LoadRichText(pXMLNode, szText, fLinePos, m_pLoader->m_pParentStyle, - true, nullptr, false)) { - break; - } - pSaveXMLNode = pXMLNode; - pXMLNode = pXMLNode->GetNodeItem(CFX_XMLNode::NextSibling); - if (!pXMLNode) - continue; - for (; pXMLNode; - pXMLNode = pXMLNode->GetNodeItem(CFX_XMLNode::NextSibling)) { - if (!LoadRichText(pXMLNode, szText, fLinePos, - m_pLoader->m_pParentStyle, true, nullptr)) { - break; - } - } - } - } else { - pNode = m_pLoader->m_pNode; - if (!pNode) - return true; - LoadText(pNode, szText, fLinePos, true); - } - } - if (iBlock == iCount) { - m_pTabstopContext.reset(); - m_pLoader.reset(); - } - return true; -} - -void CXFA_TextLayout::ItemBlocks(const CFX_RectF& rtText, int32_t iBlockIndex) { - if (!m_pLoader) - return; - - int32_t iCountHeight = - pdfium::CollectionSize<int32_t>(m_pLoader->m_lineHeights); - if (iCountHeight == 0) - return; - - bool bEndItem = true; - int32_t iBlockCount = pdfium::CollectionSize<int32_t>(m_Blocks); - float fLinePos = m_pLoader->m_fStartLineOffset; - int32_t iLineIndex = 0; - if (iBlockIndex > 0) { - int32_t iBlockHeightCount = - pdfium::CollectionSize<int32_t>(m_pLoader->m_BlocksHeight); - iBlockHeightCount /= 2; - if (iBlockHeightCount >= iBlockIndex) { - for (int32_t i = 0; i < iBlockIndex; i++) - fLinePos -= m_pLoader->m_BlocksHeight[i * 2 + 1]; - } else { - fLinePos = 0; - } - iLineIndex = m_Blocks[iBlockCount - 1] + m_Blocks[iBlockCount - 2]; - } - - int32_t i = 0; - for (i = iLineIndex; i < iCountHeight; i++) { - float fLineHeight = m_pLoader->m_lineHeights[i]; - if (fLinePos + fLineHeight - rtText.height > 0.001) { - m_Blocks.push_back(iLineIndex); - m_Blocks.push_back(i - iLineIndex); - bEndItem = false; - break; - } - fLinePos += fLineHeight; - } - if (iCountHeight > 0 && (i - iLineIndex) > 0 && bEndItem) { - m_Blocks.push_back(iLineIndex); - m_Blocks.push_back(i - iLineIndex); - } -} - -bool CXFA_TextLayout::DrawString(CFX_RenderDevice* pFxDevice, - const CFX_Matrix& tmDoc2Device, - const CFX_RectF& rtClip, - int32_t iBlock) { - if (!pFxDevice) - return false; - - auto pDevice = pdfium::MakeUnique<CFDE_RenderDevice>(pFxDevice); - pDevice->SaveState(); - pDevice->SetClipRect(rtClip); - - auto pSolidBrush = pdfium::MakeUnique<CFDE_Brush>(); - auto pPen = pdfium::MakeUnique<CFDE_Pen>(); - if (m_pieceLines.empty()) { - int32_t iBlockCount = CountBlocks(); - for (int32_t i = 0; i < iBlockCount; i++) - Layout(i); - } - - FXTEXT_CHARPOS* pCharPos = nullptr; - int32_t iCharCount = 0; - int32_t iLineStart = 0; - int32_t iPieceLines = pdfium::CollectionSize<int32_t>(m_pieceLines); - int32_t iCount = pdfium::CollectionSize<int32_t>(m_Blocks); - if (iCount > 0) { - iBlock *= 2; - if (iBlock < iCount) { - iLineStart = m_Blocks[iBlock]; - iPieceLines = m_Blocks[iBlock + 1]; - } else { - iPieceLines = 0; - } - } - - for (int32_t i = 0; i < iPieceLines; i++) { - if (i + iLineStart >= pdfium::CollectionSize<int32_t>(m_pieceLines)) - break; - - CXFA_PieceLine* pPieceLine = m_pieceLines[i + iLineStart].get(); - int32_t iPieces = pdfium::CollectionSize<int32_t>(pPieceLine->m_textPieces); - int32_t j = 0; - for (j = 0; j < iPieces; j++) { - const CXFA_TextPiece* pPiece = pPieceLine->m_textPieces[j].get(); - int32_t iChars = pPiece->iChars; - if (iCharCount < iChars) { - FX_Free(pCharPos); - pCharPos = FX_Alloc(FXTEXT_CHARPOS, iChars); - iCharCount = iChars; - } - memset(pCharPos, 0, iCharCount * sizeof(FXTEXT_CHARPOS)); - RenderString(pDevice.get(), pSolidBrush.get(), pPieceLine, j, pCharPos, - tmDoc2Device); - } - for (j = 0; j < iPieces; j++) { - RenderPath(pDevice.get(), pPen.get(), pPieceLine, j, pCharPos, - tmDoc2Device); - } - } - pDevice->RestoreState(); - FX_Free(pCharPos); - return iPieceLines > 0; -} - -void CXFA_TextLayout::UpdateAlign(float fHeight, float fBottom) { - fHeight -= fBottom; - if (fHeight < 0.1f) - return; - - switch (m_textParser.GetVAlign(m_pTextProvider)) { - case XFA_ATTRIBUTEENUM_Middle: - fHeight /= 2.0f; - break; - case XFA_ATTRIBUTEENUM_Bottom: - break; - default: - return; - } - - for (const auto& pPieceLine : m_pieceLines) { - for (const auto& pPiece : pPieceLine->m_textPieces) - pPiece->rtPiece.top += fHeight; - } -} - -bool CXFA_TextLayout::Loader(const CFX_SizeF& szText, - float& fLinePos, - bool bSavePieces) { - GetTextDataNode(); - if (!m_pTextDataNode) - return true; - - if (m_bRichText) { - CFX_XMLNode* pXMLContainer = GetXMLContainerNode(); - if (pXMLContainer) { - if (!m_textParser.IsParsed()) - m_textParser.DoParse(pXMLContainer, m_pTextProvider); - - auto pRootStyle = m_textParser.CreateRootStyle(m_pTextProvider); - LoadRichText(pXMLContainer, szText, fLinePos, pRootStyle, bSavePieces, - nullptr); - } - } else { - LoadText(m_pTextDataNode, szText, fLinePos, bSavePieces); - } - return true; -} - -void CXFA_TextLayout::LoadText(CXFA_Node* pNode, - const CFX_SizeF& szText, - float& fLinePos, - bool bSavePieces) { - InitBreak(szText.width); - - CXFA_Para para = m_pTextProvider->GetParaNode(); - float fSpaceAbove = 0; - if (para) { - fSpaceAbove = para.GetSpaceAbove(); - if (fSpaceAbove < 0.1f) { - fSpaceAbove = 0; - } - int32_t verAlign = para.GetVerticalAlign(); - switch (verAlign) { - case XFA_ATTRIBUTEENUM_Top: - case XFA_ATTRIBUTEENUM_Middle: - case XFA_ATTRIBUTEENUM_Bottom: { - fLinePos += fSpaceAbove; - break; - } - } - } - - CFX_WideString wsText = pNode->GetContent(); - wsText.TrimRight(L" "); - bool bRet = AppendChar(wsText, fLinePos, fSpaceAbove, bSavePieces); - if (bRet && m_pLoader) - m_pLoader->m_pNode = pNode; - else - EndBreak(CFX_BreakType::Paragraph, fLinePos, bSavePieces); -} - -bool CXFA_TextLayout::LoadRichText( - CFX_XMLNode* pXMLNode, - const CFX_SizeF& szText, - float& fLinePos, - const CFX_RetainPtr<CFDE_CSSComputedStyle>& pParentStyle, - bool bSavePieces, - CFX_RetainPtr<CXFA_LinkUserData> pLinkData, - bool bEndBreak, - bool bIsOl, - int32_t iLiCount) { - if (!pXMLNode) - return false; - - CXFA_TextParseContext* pContext = - m_textParser.GetParseContextFromMap(pXMLNode); - FDE_CSSDisplay eDisplay = FDE_CSSDisplay::None; - bool bContentNode = false; - float fSpaceBelow = 0; - CFX_RetainPtr<CFDE_CSSComputedStyle> pStyle; - CFX_WideString wsName; - if (bEndBreak) { - bool bCurOl = false; - bool bCurLi = false; - CFX_XMLElement* pElement = nullptr; - if (pContext) { - if (m_bBlockContinue || - (m_pLoader && pXMLNode == m_pLoader->m_pXMLNode)) { - m_bBlockContinue = true; - } - if (pXMLNode->GetType() == FX_XMLNODE_Text) { - bContentNode = true; - } else if (pXMLNode->GetType() == FX_XMLNODE_Element) { - pElement = static_cast<CFX_XMLElement*>(pXMLNode); - wsName = pElement->GetLocalTagName(); - } - if (wsName == L"ol") { - bIsOl = true; - bCurOl = true; - } - if (m_bBlockContinue || bContentNode == false) { - eDisplay = pContext->GetDisplay(); - if (eDisplay != FDE_CSSDisplay::Block && - eDisplay != FDE_CSSDisplay::Inline && - eDisplay != FDE_CSSDisplay::ListItem) { - return true; - } - - pStyle = m_textParser.ComputeStyle(pXMLNode, pParentStyle.Get()); - InitBreak(bContentNode ? pParentStyle.Get() : pStyle.Get(), eDisplay, - szText.width, pXMLNode, pParentStyle.Get()); - if ((eDisplay == FDE_CSSDisplay::Block || - eDisplay == FDE_CSSDisplay::ListItem) && - pStyle && - (wsName.IsEmpty() || (wsName != L"body" && wsName != L"html" && - wsName != L"ol" && wsName != L"ul"))) { - const FDE_CSSRect* pRect = pStyle->GetMarginWidth(); - if (pRect) { - fLinePos += pRect->top.GetValue(); - fSpaceBelow = pRect->bottom.GetValue(); - } - } - - if (wsName == L"a") { - ASSERT(pElement); - CFX_WideString wsLinkContent = pElement->GetString(L"href"); - if (!wsLinkContent.IsEmpty()) { - pLinkData = pdfium::MakeRetain<CXFA_LinkUserData>( - wsLinkContent.GetBuffer(wsLinkContent.GetLength())); - wsLinkContent.ReleaseBuffer(wsLinkContent.GetLength()); - } - } - - int32_t iTabCount = m_textParser.CountTabs( - bContentNode ? pParentStyle.Get() : pStyle.Get()); - bool bSpaceRun = m_textParser.IsSpaceRun( - bContentNode ? pParentStyle.Get() : pStyle.Get()); - CFX_WideString wsText; - if (bContentNode && iTabCount == 0) { - wsText = static_cast<CFX_XMLText*>(pXMLNode)->GetText(); - } else if (wsName == L"br") { - wsText = L'\n'; - } else if (wsName == L"li") { - bCurLi = true; - if (bIsOl) - wsText.Format(L"%d. ", iLiCount); - else - wsText = 0x00B7 + CFX_WideStringC(L" ", 1); - } else if (!bContentNode) { - if (iTabCount > 0) { - while (iTabCount-- > 0) - wsText += L'\t'; - } else { - m_textParser.GetEmbbedObj(m_pTextProvider, pXMLNode, wsText); - } - } - - int32_t iLength = wsText.GetLength(); - if (iLength > 0 && bContentNode && !bSpaceRun) - ProcessText(wsText); - - if (m_pLoader) { - if (wsText.GetLength() > 0 && - (m_pLoader->m_dwFlags & XFA_LOADERCNTXTFLG_FILTERSPACE)) { - wsText.TrimLeft(0x20); - } - if (FDE_CSSDisplay::Block == eDisplay) { - m_pLoader->m_dwFlags |= XFA_LOADERCNTXTFLG_FILTERSPACE; - } else if (FDE_CSSDisplay::Inline == eDisplay && - (m_pLoader->m_dwFlags & XFA_LOADERCNTXTFLG_FILTERSPACE)) { - m_pLoader->m_dwFlags &= ~XFA_LOADERCNTXTFLG_FILTERSPACE; - } else if (wsText.GetLength() > 0 && - (0x20 == wsText.GetAt(wsText.GetLength() - 1))) { - m_pLoader->m_dwFlags |= XFA_LOADERCNTXTFLG_FILTERSPACE; - } else if (wsText.GetLength() != 0) { - m_pLoader->m_dwFlags &= ~XFA_LOADERCNTXTFLG_FILTERSPACE; - } - } - - if (wsText.GetLength() > 0) { - if (!m_pLoader || m_pLoader->m_iChar == 0) { - auto pUserData = pdfium::MakeRetain<CXFA_TextUserData>( - bContentNode ? pParentStyle : pStyle, pLinkData); - m_pBreak->SetUserData(pUserData); - } - - if (AppendChar(wsText, fLinePos, 0, bSavePieces)) { - if (m_pLoader) - m_pLoader->m_dwFlags &= ~XFA_LOADERCNTXTFLG_FILTERSPACE; - if (IsEnd(bSavePieces)) { - if (m_pLoader && m_pLoader->m_iTotalLines > -1) { - m_pLoader->m_pXMLNode = pXMLNode; - m_pLoader->m_pParentStyle = pParentStyle; - } - return false; - } - return true; - } - } - } - } - - for (CFX_XMLNode* pChildNode = - pXMLNode->GetNodeItem(CFX_XMLNode::FirstChild); - pChildNode; - pChildNode = pChildNode->GetNodeItem(CFX_XMLNode::NextSibling)) { - if (bCurOl) - iLiCount++; - - if (!LoadRichText(pChildNode, szText, fLinePos, - pContext ? pStyle : pParentStyle, bSavePieces, - pLinkData, true, bIsOl, iLiCount)) - return false; - } - - if (m_pLoader) { - if (FDE_CSSDisplay::Block == eDisplay) - m_pLoader->m_dwFlags |= XFA_LOADERCNTXTFLG_FILTERSPACE; - } - if (bCurLi) - EndBreak(CFX_BreakType::Line, fLinePos, bSavePieces); - } else { - if (pContext) - eDisplay = pContext->GetDisplay(); - } - - if (m_bBlockContinue) { - if (pContext && !bContentNode) { - CFX_BreakType dwStatus = (eDisplay == FDE_CSSDisplay::Block) - ? CFX_BreakType::Paragraph - : CFX_BreakType::Piece; - EndBreak(dwStatus, fLinePos, bSavePieces); - if (eDisplay == FDE_CSSDisplay::Block) { - fLinePos += fSpaceBelow; - if (m_pTabstopContext) - m_pTabstopContext->RemoveAll(); - } - if (IsEnd(bSavePieces)) { - if (m_pLoader && m_pLoader->m_iTotalLines > -1) { - m_pLoader->m_pXMLNode = - pXMLNode->GetNodeItem(CFX_XMLNode::NextSibling); - m_pLoader->m_pParentStyle = pParentStyle; - } - return false; - } - } - } - return true; -} - -bool CXFA_TextLayout::AppendChar(const CFX_WideString& wsText, - float& fLinePos, - float fSpaceAbove, - bool bSavePieces) { - CFX_BreakType dwStatus = CFX_BreakType::None; - int32_t iChar = 0; - if (m_pLoader) - iChar = m_pLoader->m_iChar; - - int32_t iLength = wsText.GetLength(); - for (int32_t i = iChar; i < iLength; i++) { - wchar_t wch = wsText.GetAt(i); - if (wch == 0xA0) - wch = 0x20; - - dwStatus = m_pBreak->AppendChar(wch); - if (dwStatus != CFX_BreakType::None && dwStatus != CFX_BreakType::Piece) { - AppendTextLine(dwStatus, fLinePos, bSavePieces); - if (IsEnd(bSavePieces)) { - if (m_pLoader) - m_pLoader->m_iChar = i; - return true; - } - if (dwStatus == CFX_BreakType::Paragraph && m_bRichText) - fLinePos += fSpaceAbove; - } - } - if (m_pLoader) - m_pLoader->m_iChar = 0; - - return false; -} - -bool CXFA_TextLayout::IsEnd(bool bSavePieces) { - if (!bSavePieces) - return false; - if (m_pLoader && m_pLoader->m_iTotalLines > 0) - return m_iLines >= m_pLoader->m_iTotalLines; - return false; -} - -void CXFA_TextLayout::ProcessText(CFX_WideString& wsText) { - int32_t iLen = wsText.GetLength(); - if (iLen == 0) - return; - - wchar_t* psz = wsText.GetBuffer(iLen); - int32_t iTrimLeft = 0; - wchar_t wch = 0, wPrev = 0; - for (int32_t i = 0; i < iLen; i++) { - wch = psz[i]; - if (wch < 0x20) - wch = 0x20; - if (wch == 0x20 && wPrev == 0x20) - continue; - - wPrev = wch; - psz[iTrimLeft++] = wch; - } - wsText.ReleaseBuffer(iLen); - wsText = wsText.Left(iTrimLeft); -} - -void CXFA_TextLayout::EndBreak(CFX_BreakType dwStatus, - float& fLinePos, - bool bSavePieces) { - dwStatus = m_pBreak->EndBreak(dwStatus); - if (dwStatus != CFX_BreakType::None && dwStatus != CFX_BreakType::Piece) - AppendTextLine(dwStatus, fLinePos, bSavePieces, true); -} - -void CXFA_TextLayout::DoTabstops(CFDE_CSSComputedStyle* pStyle, - CXFA_PieceLine* pPieceLine) { - if (!pStyle || !pPieceLine) - return; - - if (!m_pTabstopContext || m_pTabstopContext->m_tabstops.empty()) - return; - - int32_t iPieces = pdfium::CollectionSize<int32_t>(pPieceLine->m_textPieces); - if (iPieces == 0) - return; - - CXFA_TextPiece* pPiece = pPieceLine->m_textPieces[iPieces - 1].get(); - int32_t& iTabstopsIndex = m_pTabstopContext->m_iTabIndex; - int32_t iCount = m_textParser.CountTabs(pStyle); - if (!pdfium::IndexInBounds(m_pTabstopContext->m_tabstops, iTabstopsIndex)) - return; - - if (iCount > 0) { - iTabstopsIndex++; - m_pTabstopContext->m_bTabstops = true; - float fRight = 0; - if (iPieces > 1) { - CXFA_TextPiece* p = pPieceLine->m_textPieces[iPieces - 2].get(); - fRight = p->rtPiece.right(); - } - m_pTabstopContext->m_fTabWidth = - pPiece->rtPiece.width + pPiece->rtPiece.left - fRight; - } else if (iTabstopsIndex > -1) { - float fLeft = 0; - if (m_pTabstopContext->m_bTabstops) { - uint32_t dwAlign = m_pTabstopContext->m_tabstops[iTabstopsIndex].dwAlign; - if (dwAlign == FX_HashCode_GetW(L"center", false)) { - fLeft = pPiece->rtPiece.width / 2.0f; - } else if (dwAlign == FX_HashCode_GetW(L"right", false) || - dwAlign == FX_HashCode_GetW(L"before", false)) { - fLeft = pPiece->rtPiece.width; - } else if (dwAlign == FX_HashCode_GetW(L"decimal", false)) { - int32_t iChars = pPiece->iChars; - for (int32_t i = 0; i < iChars; i++) { - if (pPiece->szText[i] == L'.') - break; - - fLeft += pPiece->Widths[i] / 20000.0f; - } - } - m_pTabstopContext->m_fLeft = - std::min(fLeft, m_pTabstopContext->m_fTabWidth); - m_pTabstopContext->m_bTabstops = false; - m_pTabstopContext->m_fTabWidth = 0; - } - pPiece->rtPiece.left -= m_pTabstopContext->m_fLeft; - } -} - -void CXFA_TextLayout::AppendTextLine(CFX_BreakType dwStatus, - float& fLinePos, - bool bSavePieces, - bool bEndBreak) { - int32_t iPieces = m_pBreak->CountBreakPieces(); - if (iPieces < 1) - return; - - CFX_RetainPtr<CFDE_CSSComputedStyle> pStyle; - if (bSavePieces) { - auto pNew = pdfium::MakeUnique<CXFA_PieceLine>(); - CXFA_PieceLine* pPieceLine = pNew.get(); - m_pieceLines.push_back(std::move(pNew)); - if (m_pTabstopContext) - m_pTabstopContext->Reset(); - - float fLineStep = 0, fBaseLine = 0; - int32_t i = 0; - for (i = 0; i < iPieces; i++) { - const CFX_BreakPiece* pPiece = m_pBreak->GetBreakPieceUnstable(i); - CXFA_TextUserData* pUserData = pPiece->m_pUserData.Get(); - if (pUserData) - pStyle = pUserData->m_pStyle; - float fVerScale = pPiece->m_iVerticalScale / 100.0f; - - auto pTP = pdfium::MakeUnique<CXFA_TextPiece>(); - pTP->iChars = pPiece->m_iChars; - pTP->szText = pPiece->GetString(); - pTP->Widths = pPiece->GetWidths(); - pTP->iBidiLevel = pPiece->m_iBidiLevel; - pTP->iHorScale = pPiece->m_iHorizontalScale; - pTP->iVerScale = pPiece->m_iVerticalScale; - m_textParser.GetUnderline(m_pTextProvider, pStyle.Get(), pTP->iUnderline, - pTP->iPeriod); - m_textParser.GetLinethrough(m_pTextProvider, pStyle.Get(), - pTP->iLineThrough); - pTP->dwColor = m_textParser.GetColor(m_pTextProvider, pStyle.Get()); - pTP->pFont = m_textParser.GetFont(m_pTextProvider, pStyle.Get()); - pTP->fFontSize = m_textParser.GetFontSize(m_pTextProvider, pStyle.Get()); - pTP->rtPiece.left = pPiece->m_iStartPos / 20000.0f; - pTP->rtPiece.width = pPiece->m_iWidth / 20000.0f; - pTP->rtPiece.height = (float)pPiece->m_iFontSize * fVerScale / 20.0f; - float fBaseLineTemp = - m_textParser.GetBaseline(m_pTextProvider, pStyle.Get()); - pTP->rtPiece.top = fBaseLineTemp; - - float fLineHeight = m_textParser.GetLineHeight( - m_pTextProvider, pStyle.Get(), m_iLines == 0, fVerScale); - if (fBaseLineTemp > 0) { - float fLineHeightTmp = fBaseLineTemp + pTP->rtPiece.height; - if (fLineHeight < fLineHeightTmp) - fLineHeight = fLineHeightTmp; - else - fBaseLineTemp = 0; - } else if (fBaseLine < -fBaseLineTemp) { - fBaseLine = -fBaseLineTemp; - } - fLineStep = std::max(fLineStep, fLineHeight); - pTP->pLinkData = pUserData ? pUserData->m_pLinkData : nullptr; - pPieceLine->m_textPieces.push_back(std::move(pTP)); - DoTabstops(pStyle.Get(), pPieceLine); - } - for (const auto& pTP : pPieceLine->m_textPieces) { - float& fTop = pTP->rtPiece.top; - float fBaseLineTemp = fTop; - fTop = fLinePos + fLineStep - pTP->rtPiece.height - fBaseLineTemp; - fTop = std::max(0.0f, fTop); - } - fLinePos += fLineStep + fBaseLine; - } else { - float fLineStep = 0; - float fLineWidth = 0; - for (int32_t i = 0; i < iPieces; i++) { - const CFX_BreakPiece* pPiece = m_pBreak->GetBreakPieceUnstable(i); - CXFA_TextUserData* pUserData = pPiece->m_pUserData.Get(); - if (pUserData) - pStyle = pUserData->m_pStyle; - float fVerScale = pPiece->m_iVerticalScale / 100.0f; - float fBaseLine = m_textParser.GetBaseline(m_pTextProvider, pStyle.Get()); - float fLineHeight = m_textParser.GetLineHeight( - m_pTextProvider, pStyle.Get(), m_iLines == 0, fVerScale); - if (fBaseLine > 0) { - float fLineHeightTmp = - fBaseLine + (float)pPiece->m_iFontSize * fVerScale / 20.0f; - if (fLineHeight < fLineHeightTmp) { - fLineHeight = fLineHeightTmp; - } - } - fLineStep = std::max(fLineStep, fLineHeight); - fLineWidth += pPiece->m_iWidth / 20000.0f; - } - fLinePos += fLineStep; - m_fMaxWidth = std::max(m_fMaxWidth, fLineWidth); - if (m_pLoader && m_pLoader->m_bSaveLineHeight) { - float fHeight = fLinePos - m_pLoader->m_fLastPos; - m_pLoader->m_fLastPos = fLinePos; - m_pLoader->m_lineHeights.push_back(fHeight); - } - } - - m_pBreak->ClearBreakPieces(); - if (dwStatus == CFX_BreakType::Paragraph) { - m_pBreak->Reset(); - if (!pStyle && bEndBreak) { - CXFA_Para para = m_pTextProvider->GetParaNode(); - if (para) { - float fStartPos = para.GetMarginLeft(); - float fIndent = para.GetTextIndent(); - if (fIndent > 0) - fStartPos += fIndent; - - float fSpaceBelow = para.GetSpaceBelow(); - if (fSpaceBelow < 0.1f) - fSpaceBelow = 0; - - m_pBreak->SetLineStartPos(fStartPos); - fLinePos += fSpaceBelow; - } - } - } - - if (pStyle) { - float fStart = 0; - const FDE_CSSRect* pRect = pStyle->GetMarginWidth(); - if (pRect) - fStart = pRect->left.GetValue(); - - float fTextIndent = pStyle->GetTextIndent().GetValue(); - if (fTextIndent < 0) - fStart -= fTextIndent; - - m_pBreak->SetLineStartPos(fStart); - } - m_iLines++; -} - -void CXFA_TextLayout::RenderString(CFDE_RenderDevice* pDevice, - CFDE_Brush* pBrush, - CXFA_PieceLine* pPieceLine, - int32_t iPiece, - FXTEXT_CHARPOS* pCharPos, - const CFX_Matrix& tmDoc2Device) { - const CXFA_TextPiece* pPiece = pPieceLine->m_textPieces[iPiece].get(); - int32_t iCount = GetDisplayPos(pPiece, pCharPos); - if (iCount > 0) { - pBrush->SetColor(pPiece->dwColor); - pDevice->DrawString(pBrush, pPiece->pFont, pCharPos, iCount, - pPiece->fFontSize, &tmDoc2Device); - } - pPieceLine->m_charCounts.push_back(iCount); -} - -void CXFA_TextLayout::RenderPath(CFDE_RenderDevice* pDevice, - CFDE_Pen* pPen, - CXFA_PieceLine* pPieceLine, - int32_t iPiece, - FXTEXT_CHARPOS* pCharPos, - const CFX_Matrix& tmDoc2Device) { - CXFA_TextPiece* pPiece = pPieceLine->m_textPieces[iPiece].get(); - bool bNoUnderline = pPiece->iUnderline < 1 || pPiece->iUnderline > 2; - bool bNoLineThrough = pPiece->iLineThrough < 1 || pPiece->iLineThrough > 2; - if (bNoUnderline && bNoLineThrough) - return; - - pPen->SetColor(pPiece->dwColor); - auto pPath = pdfium::MakeUnique<CFDE_Path>(); - int32_t iChars = GetDisplayPos(pPiece, pCharPos); - if (iChars > 0) { - CFX_PointF pt1, pt2; - float fEndY = pCharPos[0].m_Origin.y + 1.05f; - if (pPiece->iPeriod == XFA_ATTRIBUTEENUM_Word) { - for (int32_t i = 0; i < pPiece->iUnderline; i++) { - for (int32_t j = 0; j < iChars; j++) { - pt1.x = pCharPos[j].m_Origin.x; - pt2.x = - pt1.x + pCharPos[j].m_FontCharWidth * pPiece->fFontSize / 1000.0f; - pt1.y = pt2.y = fEndY; - pPath->AddLine(pt1, pt2); - } - fEndY += 2.0f; - } - } else { - pt1.x = pCharPos[0].m_Origin.x; - pt2.x = - pCharPos[iChars - 1].m_Origin.x + - pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f; - for (int32_t i = 0; i < pPiece->iUnderline; i++) { - pt1.y = pt2.y = fEndY; - pPath->AddLine(pt1, pt2); - fEndY += 2.0f; - } - } - fEndY = pCharPos[0].m_Origin.y - pPiece->rtPiece.height * 0.25f; - pt1.x = pCharPos[0].m_Origin.x; - pt2.x = pCharPos[iChars - 1].m_Origin.x + - pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f; - for (int32_t i = 0; i < pPiece->iLineThrough; i++) { - pt1.y = pt2.y = fEndY; - pPath->AddLine(pt1, pt2); - fEndY += 2.0f; - } - } else { - if (bNoLineThrough && - (bNoUnderline || pPiece->iPeriod != XFA_ATTRIBUTEENUM_All)) { - return; - } - int32_t iCharsTmp = 0; - int32_t iPiecePrev = iPiece; - int32_t iPieceNext = iPiece; - while (iPiecePrev > 0) { - iPiecePrev--; - iCharsTmp = pPieceLine->m_charCounts[iPiecePrev]; - if (iCharsTmp > 0) - break; - } - if (iCharsTmp == 0) - return; - - iCharsTmp = 0; - int32_t iPieces = pdfium::CollectionSize<int32_t>(pPieceLine->m_textPieces); - while (iPieceNext < iPieces - 1) { - iPieceNext++; - iCharsTmp = pPieceLine->m_charCounts[iPieceNext]; - if (iCharsTmp > 0) - break; - } - if (iCharsTmp == 0) - return; - - float fOrgX = 0.0f; - float fEndX = 0.0f; - pPiece = pPieceLine->m_textPieces[iPiecePrev].get(); - iChars = GetDisplayPos(pPiece, pCharPos); - if (iChars < 1) - return; - - fOrgX = pCharPos[iChars - 1].m_Origin.x + - pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f; - pPiece = pPieceLine->m_textPieces[iPieceNext].get(); - iChars = GetDisplayPos(pPiece, pCharPos); - if (iChars < 1) - return; - - fEndX = pCharPos[0].m_Origin.x; - CFX_PointF pt1; - CFX_PointF pt2; - pt1.x = fOrgX; - pt2.x = fEndX; - float fEndY = pCharPos[0].m_Origin.y + 1.05f; - for (int32_t i = 0; i < pPiece->iUnderline; i++) { - pt1.y = fEndY; - pt2.y = fEndY; - pPath->AddLine(pt1, pt2); - fEndY += 2.0f; - } - fEndY = pCharPos[0].m_Origin.y - pPiece->rtPiece.height * 0.25f; - for (int32_t i = 0; i < pPiece->iLineThrough; i++) { - pt1.y = fEndY; - pt2.y = fEndY; - pPath->AddLine(pt1, pt2); - fEndY += 2.0f; - } - } - pDevice->DrawPath(pPen, 1, pPath.get(), &tmDoc2Device); -} - -int32_t CXFA_TextLayout::GetDisplayPos(const CXFA_TextPiece* pPiece, - FXTEXT_CHARPOS* pCharPos, - bool bCharCode) { - if (!pPiece) - return 0; - - FX_RTFTEXTOBJ tr; - if (!ToRun(pPiece, &tr)) - return 0; - return m_pBreak->GetDisplayPos(&tr, pCharPos, bCharCode); -} - -bool CXFA_TextLayout::ToRun(const CXFA_TextPiece* pPiece, FX_RTFTEXTOBJ* tr) { - int32_t iLength = pPiece->iChars; - if (iLength < 1) - return false; - - tr->pStr = pPiece->szText; - tr->pFont = pPiece->pFont; - tr->pRect = &pPiece->rtPiece; - tr->pWidths = pPiece->Widths; - tr->iLength = iLength; - tr->fFontSize = pPiece->fFontSize; - tr->iBidiLevel = pPiece->iBidiLevel; - tr->wLineBreakChar = L'\n'; - tr->iVerticalScale = pPiece->iVerScale; - tr->iHorizontalScale = pPiece->iHorScale; - return true; -} |