diff options
author | Tom Sepez <tsepez@chromium.org> | 2016-01-26 14:51:21 -0800 |
---|---|---|
committer | Tom Sepez <tsepez@chromium.org> | 2016-01-26 14:51:21 -0800 |
commit | 99ffdb0b9b488d743331646dc410f26b71e1f037 (patch) | |
tree | d9f7a4b05c8d4c46b38f9940ff8e3be9803b73e1 /xfa/src/fxfa/src/app/xfa_textlayout.cpp | |
parent | c812495631df9f059bfd332ffe37e76dd011e96c (diff) | |
download | pdfium-99ffdb0b9b488d743331646dc410f26b71e1f037.tar.xz |
Fix DOS newlines
R=thestig@chromium.org
Review URL: https://codereview.chromium.org/1636873004 .
Diffstat (limited to 'xfa/src/fxfa/src/app/xfa_textlayout.cpp')
-rw-r--r-- | xfa/src/fxfa/src/app/xfa_textlayout.cpp | 4044 |
1 files changed, 2022 insertions, 2022 deletions
diff --git a/xfa/src/fxfa/src/app/xfa_textlayout.cpp b/xfa/src/fxfa/src/app/xfa_textlayout.cpp index 4eddabc0bd..b949734fe9 100644 --- a/xfa/src/fxfa/src/app/xfa_textlayout.cpp +++ b/xfa/src/fxfa/src/app/xfa_textlayout.cpp @@ -1,2022 +1,2022 @@ -// 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 <algorithm>
-
-#include "xfa/src/foxitlib.h"
-#include "xfa/src/fxfa/src/common/xfa_common.h"
-#include "xfa_textlayout.h"
-#include "xfa_ffapp.h"
-#include "xfa_ffdoc.h"
-#include "xfa_fontmgr.h"
-CXFA_CSSTagProvider::~CXFA_CSSTagProvider() {
- FX_POSITION pos = m_Attributes.GetStartPosition();
- while (pos) {
- CFX_WideString *pName = NULL, *pValue = NULL;
- m_Attributes.GetNextAssoc(pos, (void*&)pName, (void*&)pValue);
- if (pName != NULL) {
- delete pName;
- }
- if (pValue != NULL) {
- delete pValue;
- }
- }
-}
-void CXFA_CSSTagProvider::GetNextAttribute(FX_POSITION& pos,
- CFX_WideStringC& wsAttr,
- CFX_WideStringC& wsValue) {
- if (pos == NULL) {
- return;
- }
- CFX_WideString* pName = NULL;
- CFX_WideString* pValue = NULL;
- m_Attributes.GetNextAssoc(pos, (void*&)pName, (void*&)pValue);
- wsAttr = *pName;
- wsValue = *pValue;
-}
-void CXFA_CSSTagProvider::SetAttribute(const CFX_WideString& wsAttr,
- const CFX_WideString& wsValue) {
- CFX_WideString* pName = new CFX_WideString();
- CFX_WideString* pValue = new CFX_WideString();
- *pName = wsAttr;
- *pValue = wsValue;
- m_Attributes.SetAt(pName, pValue);
-}
-void CXFA_TextParseContext::SetDecls(const IFDE_CSSDeclaration** ppDeclArray,
- int32_t iDeclCount) {
- if (iDeclCount <= 0 || ppDeclArray == NULL) {
- return;
- }
- m_dwMatchedDecls = iDeclCount;
- m_ppMatchedDecls = FX_Alloc(IFDE_CSSDeclaration*, iDeclCount);
- FX_memcpy(m_ppMatchedDecls, ppDeclArray,
- iDeclCount * sizeof(IFDE_CSSDeclaration*));
-}
-CXFA_TextParser::~CXFA_TextParser() {
- if (m_pUASheet != NULL) {
- m_pUASheet->Release();
- }
- if (m_pSelector != NULL) {
- m_pSelector->Release();
- }
- if (m_pAllocator != NULL) {
- m_pAllocator->Release();
- }
- FX_POSITION ps = m_mapXMLNodeToParseContext.GetStartPosition();
- while (ps) {
- IFDE_XMLNode* pXMLNode;
- CXFA_TextParseContext* pParseContext;
- m_mapXMLNodeToParseContext.GetNextAssoc(ps, pXMLNode, pParseContext);
- if (pParseContext != NULL) {
- FDE_DeleteWith(CXFA_TextParseContext, m_pAllocator, pParseContext);
- }
- }
- m_mapXMLNodeToParseContext.RemoveAll();
-}
-void CXFA_TextParser::Reset() {
- FX_POSITION ps = m_mapXMLNodeToParseContext.GetStartPosition();
- while (ps) {
- IFDE_XMLNode* pXMLNode;
- CXFA_TextParseContext* pParseContext;
- m_mapXMLNodeToParseContext.GetNextAssoc(ps, pXMLNode, pParseContext);
- if (pParseContext != NULL) {
- FDE_DeleteWith(CXFA_TextParseContext, m_pAllocator, pParseContext);
- }
- }
- m_mapXMLNodeToParseContext.RemoveAll();
- if (m_pAllocator != NULL) {
- m_pAllocator->Release();
- m_pAllocator = NULL;
- }
-}
-void CXFA_TextParser::InitCSSData(IXFA_TextProvider* pTextProvider) {
- if (pTextProvider == NULL) {
- return;
- }
- if (m_pSelector == NULL) {
- CXFA_FFDoc* pDoc = pTextProvider->GetDocNode();
- IFX_FontMgr* pFontMgr = pDoc->GetApp()->GetFDEFontMgr();
- FXSYS_assert(pFontMgr != NULL);
- m_pSelector = IFDE_CSSStyleSelector::Create();
- m_pSelector->SetFontMgr(pFontMgr);
- FX_FLOAT fFontSize = 10;
- CXFA_Font font = pTextProvider->GetFontNode();
- if (font.IsExistInXML()) {
- fFontSize = font.GetFontSize();
- }
- m_pSelector->SetDefFontSize(fFontSize);
- }
- if (m_pUASheet == NULL) {
- m_pUASheet = LoadDefaultSheetStyle();
- m_pSelector->SetStyleSheet(FDE_CSSSTYLESHEETGROUP_UserAgent, m_pUASheet);
- m_pSelector->UpdateStyleIndex(FDE_CSSMEDIATYPE_ALL);
- }
-}
-IFDE_CSSStyleSheet* CXFA_TextParser::LoadDefaultSheetStyle() {
- static const FX_WCHAR s_pStyle[] =
- L"html,body,ol,p,ul{display:block}"
- L"li{display:list-item}"
- L"ol,ul{padding-left:33px}ol{list-style-type:decimal}ol,ul{margin-top:0;"
- L"margin-bottom:0}ul,ol{margin:1.12em 0}"
- L"a{color:#0000ff;text-decoration:underline}b{font-weight:bolder}i{font-"
- L"style:italic}"
- L"sup{vertical-align:+15em;font-size:.66em}sub{vertical-align:-15em;font-"
- L"size:.66em}";
- return IFDE_CSSStyleSheet::LoadFromBuffer(
- CFX_WideString(), s_pStyle, FXSYS_wcslen(s_pStyle), FX_CODEPAGE_UTF8);
-}
-IFDE_CSSComputedStyle* CXFA_TextParser::CreateRootStyle(
- IXFA_TextProvider* pTextProvider) {
- CXFA_Font font = pTextProvider->GetFontNode();
- CXFA_Para para = pTextProvider->GetParaNode();
- IFDE_CSSComputedStyle* pStyle = m_pSelector->CreateComputedStyle(NULL);
- IFDE_CSSFontStyle* pFontStyle = pStyle->GetFontStyles();
- IFDE_CSSParagraphStyle* pParaStyle = pStyle->GetParagraphStyles();
- FX_FLOAT fLineHeight = 0, fFontSize = 10;
- if (para.IsExistInXML()) {
- fLineHeight = para.GetLineHeight();
- FDE_CSSLENGTH indent;
- indent.Set(FDE_CSSLENGTHUNIT_Point, para.GetTextIndent());
- pParaStyle->SetTextIndent(indent);
- FDE_CSSTEXTALIGN hAlgin = FDE_CSSTEXTALIGN_Left;
- switch (para.GetHorizontalAlign()) {
- case XFA_ATTRIBUTEENUM_Center:
- hAlgin = FDE_CSSTEXTALIGN_Center;
- break;
- case XFA_ATTRIBUTEENUM_Right:
- hAlgin = FDE_CSSTEXTALIGN_Right;
- break;
- case XFA_ATTRIBUTEENUM_Justify:
- hAlgin = FDE_CSSTEXTALIGN_Justify;
- break;
- case XFA_ATTRIBUTEENUM_JustifyAll:
- hAlgin = FDE_CSSTEXTALIGN_JustifyAll;
- break;
- }
- pParaStyle->SetTextAlign(hAlgin);
- FDE_CSSRECT rtMarginWidth;
- rtMarginWidth.left.Set(FDE_CSSLENGTHUNIT_Point, para.GetMarginLeft());
- rtMarginWidth.top.Set(FDE_CSSLENGTHUNIT_Point, para.GetSpaceAbove());
- rtMarginWidth.right.Set(FDE_CSSLENGTHUNIT_Point, para.GetMarginRight());
- rtMarginWidth.bottom.Set(FDE_CSSLENGTHUNIT_Point, para.GetSpaceBelow());
- pStyle->GetBoundaryStyles()->SetMarginWidth(rtMarginWidth);
- }
- if (font.IsExistInXML()) {
- pFontStyle->SetColor(font.GetColor());
- pFontStyle->SetFontStyle(font.IsItalic() ? FDE_CSSFONTSTYLE_Italic
- : FDE_CSSFONTSTYLE_Normal);
- pFontStyle->SetFontWeight(font.IsBold() ? FXFONT_FW_BOLD
- : FXFONT_FW_NORMAL);
- pParaStyle->SetNumberVerticalAlign(-font.GetBaselineShift());
- fFontSize = font.GetFontSize();
- FDE_CSSLENGTH letterSpacing;
- letterSpacing.Set(FDE_CSSLENGTHUNIT_Point, font.GetLetterSpacing());
- pParaStyle->SetLetterSpacing(letterSpacing);
- FX_DWORD dwDecoration = 0;
- if (font.GetLineThrough() > 0) {
- dwDecoration |= FDE_CSSTEXTDECORATION_LineThrough;
- }
- if (font.GetUnderline() > 1) {
- dwDecoration |= FDE_CSSTEXTDECORATION_Double;
- } else if (font.GetUnderline() > 0) {
- dwDecoration |= FDE_CSSTEXTDECORATION_Underline;
- }
- pParaStyle->SetTextDecoration(dwDecoration);
- }
- pParaStyle->SetLineHeight(fLineHeight);
- pFontStyle->SetFontSize(fFontSize);
- return pStyle;
-}
-IFDE_CSSComputedStyle* CXFA_TextParser::CreateStyle(
- IFDE_CSSComputedStyle* pParentStyle) {
- IFDE_CSSComputedStyle* pNewStyle =
- m_pSelector->CreateComputedStyle(pParentStyle);
- FXSYS_assert(pNewStyle != NULL);
- if (pParentStyle) {
- IFDE_CSSParagraphStyle* pParaStyle = pParentStyle->GetParagraphStyles();
- FX_DWORD dwDecoration = pParaStyle->GetTextDecoration();
- FX_FLOAT fBaseLine = 0;
- if (pParaStyle->GetVerticalAlign() == FDE_CSSVERTICALALIGN_Number) {
- fBaseLine = pParaStyle->GetNumberVerticalAlign();
- }
- pParaStyle = pNewStyle->GetParagraphStyles();
- pParaStyle->SetTextDecoration(dwDecoration);
- pParaStyle->SetNumberVerticalAlign(fBaseLine);
- IFDE_CSSBoundaryStyle* pBoundarytyle = pParentStyle->GetBoundaryStyles();
- const FDE_CSSRECT* pRect = pBoundarytyle->GetMarginWidth();
- if (pRect != NULL) {
- pBoundarytyle = pNewStyle->GetBoundaryStyles();
- pBoundarytyle->SetMarginWidth(*pRect);
- }
- }
- return pNewStyle;
-}
-IFDE_CSSComputedStyle* CXFA_TextParser::ComputeStyle(
- IFDE_XMLNode* pXMLNode,
- IFDE_CSSComputedStyle* pParentStyle) {
- CXFA_TextParseContext* pContext = static_cast<CXFA_TextParseContext*>(
- m_mapXMLNodeToParseContext.GetValueAt(pXMLNode));
- if (!pContext)
- return nullptr;
- pContext->m_pParentStyle = pParentStyle;
- pParentStyle->AddRef();
- CXFA_CSSTagProvider tagProvider;
- ParseTagInfo(pXMLNode, tagProvider);
- if (tagProvider.m_bContent)
- return nullptr;
- IFDE_CSSComputedStyle* pStyle = CreateStyle(pParentStyle);
- IFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator();
- pCSSAccel->OnEnterTag(&tagProvider);
- m_pSelector->ComputeStyle(&tagProvider, pContext->GetDecls(),
- pContext->CountDecls(), pStyle);
- pCSSAccel->OnLeaveTag(&tagProvider);
- return pStyle;
-}
-void CXFA_TextParser::DoParse(IFDE_XMLNode* pXMLContainer,
- IXFA_TextProvider* pTextProvider) {
- if (pXMLContainer == NULL || pTextProvider == NULL || m_pAllocator != NULL) {
- return;
- }
- m_pAllocator =
- FX_CreateAllocator(FX_ALLOCTYPE_Fixed, 32, sizeof(CXFA_CSSTagProvider));
- InitCSSData(pTextProvider);
- IFDE_CSSComputedStyle* pRootStyle = CreateRootStyle(pTextProvider);
- ParseRichText(pXMLContainer, pRootStyle);
- pRootStyle->Release();
-}
-void CXFA_TextParser::ParseRichText(IFDE_XMLNode* pXMLNode,
- IFDE_CSSComputedStyle* pParentStyle) {
- if (pXMLNode == NULL) {
- return;
- }
- CXFA_CSSTagProvider tagProvider;
- ParseTagInfo(pXMLNode, tagProvider);
- if (!tagProvider.m_bTagAviliable) {
- return;
- }
- IFDE_CSSComputedStyle* pNewStyle = NULL;
- if ((tagProvider.GetTagName() != FX_WSTRC(L"body")) ||
- (tagProvider.GetTagName() != FX_WSTRC(L"html"))) {
- CXFA_TextParseContext* pTextContext =
- FDE_NewWith(m_pAllocator) CXFA_TextParseContext;
- FDE_CSSDISPLAY eDisplay = FDE_CSSDISPLAY_Inline;
- if (!tagProvider.m_bContent) {
- pNewStyle = CreateStyle(pParentStyle);
- IFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator();
- pCSSAccel->OnEnterTag(&tagProvider);
- CFDE_CSSDeclarationArray DeclArray;
- int32_t iMatchedDecls =
- m_pSelector->MatchDeclarations(&tagProvider, DeclArray);
- const IFDE_CSSDeclaration** ppMatchDecls =
- (const IFDE_CSSDeclaration**)DeclArray.GetData();
- m_pSelector->ComputeStyle(&tagProvider, ppMatchDecls, iMatchedDecls,
- pNewStyle);
- pCSSAccel->OnLeaveTag(&tagProvider);
- if (iMatchedDecls > 0) {
- pTextContext->SetDecls(ppMatchDecls, iMatchedDecls);
- }
- eDisplay = pNewStyle->GetPositionStyles()->GetDisplay();
- }
- pTextContext->SetDisplay(eDisplay);
- m_mapXMLNodeToParseContext.SetAt(pXMLNode, pTextContext);
- }
- for (IFDE_XMLNode* pXMLChild =
- pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
- pXMLChild;
- pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
- ParseRichText(pXMLChild, pNewStyle);
- }
- if (pNewStyle != NULL) {
- pNewStyle->Release();
- }
-}
-void CXFA_TextParser::ParseTagInfo(IFDE_XMLNode* pXMLNode,
- CXFA_CSSTagProvider& tagProvider) {
- static const FX_DWORD s_XFATagName[] = {
- 0x61, 0x62, 0x69, 0x70, 0x0001f714,
- 0x00022a55, 0x000239bb, 0x00025881, 0x0bd37faa, 0x0bd37fb8,
- 0xa73e3af2, 0xb182eaae, 0xdb8ac455,
- };
- CFX_WideString wsName;
- if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
- IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLNode;
- pXMLElement->GetLocalTagName(wsName);
- tagProvider.SetTagNameObj(wsName);
- FX_DWORD dwHashCode =
- FX_HashCode_String_GetW(wsName, wsName.GetLength(), TRUE);
- static const int32_t s_iCount = sizeof(s_XFATagName) / sizeof(FX_DWORD);
- CFX_DSPATemplate<FX_DWORD> lookup;
- tagProvider.m_bTagAviliable =
- lookup.Lookup(dwHashCode, s_XFATagName, s_iCount) > -1;
- CFX_WideString wsValue;
- pXMLElement->GetString(FX_WSTRC(L"style").GetPtr(), wsValue);
- if (!wsValue.IsEmpty()) {
- tagProvider.SetAttribute(FX_WSTRC(L"style"), wsValue);
- }
- } else if (pXMLNode->GetType() == FDE_XMLNODE_Text) {
- tagProvider.m_bTagAviliable = TRUE;
- tagProvider.m_bContent = TRUE;
- }
-}
-int32_t CXFA_TextParser::GetVAlgin(IXFA_TextProvider* pTextProvider) const {
- int32_t iAlign = XFA_ATTRIBUTEENUM_Top;
- CXFA_Para para = pTextProvider->GetParaNode();
- if (para.IsExistInXML()) {
- iAlign = para.GetVerticalAlign();
- }
- return iAlign;
-}
-FX_FLOAT CXFA_TextParser::GetTabInterval(IFDE_CSSComputedStyle* pStyle) const {
- CFX_WideString wsValue;
- if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"tab-interval"), wsValue)) {
- CXFA_Measurement ms(wsValue);
- return ms.ToUnit(XFA_UNIT_Pt);
- }
- return 36;
-}
-int32_t CXFA_TextParser::CountTabs(IFDE_CSSComputedStyle* pStyle) const {
- CFX_WideString wsValue;
- if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"xfa-tab-count"), wsValue)) {
- return wsValue.GetInteger();
- }
- return 0;
-}
-FX_BOOL CXFA_TextParser::IsSpaceRun(IFDE_CSSComputedStyle* pStyle) const {
- CFX_WideString wsValue;
- if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"xfa-spacerun"), wsValue)) {
- wsValue.MakeLower();
- return wsValue == FX_WSTRC(L"yes");
- }
- return FALSE;
-}
-IFX_Font* CXFA_TextParser::GetFont(IXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle) const {
- CFX_WideStringC wsFamily = FX_WSTRC(L"Courier");
- FX_DWORD dwStyle = 0;
- CXFA_Font font = pTextProvider->GetFontNode();
- if (font.IsExistInXML()) {
- font.GetTypeface(wsFamily);
- if (font.IsBold()) {
- dwStyle |= FX_FONTSTYLE_Bold;
- }
- if (font.IsItalic()) {
- dwStyle |= FX_FONTSTYLE_Italic;
- }
- }
- if (pStyle) {
- IFDE_CSSFontStyle* pFontStyle = pStyle->GetFontStyles();
- int32_t iCount = pFontStyle->CountFontFamilies();
- if (iCount > 0) {
- wsFamily = pFontStyle->GetFontFamily(iCount - 1);
- }
- dwStyle = 0;
- if (pFontStyle->GetFontWeight() > FXFONT_FW_NORMAL) {
- dwStyle |= FX_FONTSTYLE_Bold;
- }
- if (pFontStyle->GetFontStyle() == FDE_CSSFONTSTYLE_Italic) {
- dwStyle |= FX_FONTSTYLE_Italic;
- }
- }
- CXFA_FFDoc* pDoc = pTextProvider->GetDocNode();
- FXSYS_assert(pDoc != NULL);
- CXFA_FontMgr* pFontMgr = pDoc->GetApp()->GetXFAFontMgr();
- return pFontMgr->GetFont(pDoc, wsFamily, dwStyle);
-}
-FX_FLOAT CXFA_TextParser::GetFontSize(IXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle) const {
- if (pStyle != NULL) {
- return pStyle->GetFontStyles()->GetFontSize();
- }
- CXFA_Font font = pTextProvider->GetFontNode();
- if (font.IsExistInXML()) {
- return font.GetFontSize();
- }
- return 10;
-}
-int32_t CXFA_TextParser::GetHorScale(IXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle,
- IFDE_XMLNode* pXMLNode) const {
- if (pStyle) {
- CFX_WideString wsValue;
- if (pStyle->GetCustomStyle(FX_WSTRC(L"xfa-font-horizontal-scale"),
- wsValue)) {
- return wsValue.GetInteger();
- }
- while (pXMLNode) {
- CXFA_TextParseContext* pContext = static_cast<CXFA_TextParseContext*>(
- m_mapXMLNodeToParseContext.GetValueAt(pXMLNode));
- if (pContext && pContext->m_pParentStyle &&
- pContext->m_pParentStyle->GetCustomStyle(
- FX_WSTRC(L"xfa-font-horizontal-scale"), wsValue)) {
- return wsValue.GetInteger();
- }
- pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::Parent);
- }
- }
- if (CXFA_Font font = pTextProvider->GetFontNode()) {
- return static_cast<int32_t>(font.GetHorizontalScale());
- }
- return 100;
-}
-int32_t CXFA_TextParser::GetVerScale(IXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle) const {
- if (pStyle != NULL) {
- CFX_WideString wsValue;
- if (pStyle->GetCustomStyle(FX_WSTRC(L"xfa-font-vertical-scale"), wsValue)) {
- return wsValue.GetInteger();
- }
- }
- if (CXFA_Font font = pTextProvider->GetFontNode()) {
- return (int32_t)font.GetVerticalScale();
- }
- return 100;
-}
-void CXFA_TextParser::GetUnderline(IXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle,
- int32_t& iUnderline,
- int32_t& iPeriod) const {
- iUnderline = 0;
- iPeriod = XFA_ATTRIBUTEENUM_All;
- if (pStyle) {
- FX_DWORD dwDecoration = pStyle->GetParagraphStyles()->GetTextDecoration();
- if (dwDecoration & FDE_CSSTEXTDECORATION_Double) {
- iUnderline = 2;
- } else if (dwDecoration & FDE_CSSTEXTDECORATION_Underline) {
- iUnderline = 1;
- }
- CFX_WideString wsValue;
- if (pStyle->GetCustomStyle(FX_WSTRC(L"underlinePeriod"), wsValue)) {
- if (wsValue == FX_WSTRC(L"word")) {
- iPeriod = XFA_ATTRIBUTEENUM_Word;
- }
- } else if (CXFA_Font font = pTextProvider->GetFontNode()) {
- iPeriod = font.GetUnderlinePeriod();
- }
- } else {
- CXFA_Font font = pTextProvider->GetFontNode();
- if (font.IsExistInXML()) {
- iUnderline = font.GetUnderline();
- iPeriod = font.GetUnderlinePeriod();
- }
- }
-}
-void CXFA_TextParser::GetLinethrough(IXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle,
- int32_t& iLinethrough) const {
- if (pStyle) {
- FX_DWORD dwDecoration = pStyle->GetParagraphStyles()->GetTextDecoration();
- iLinethrough = (dwDecoration & FDE_CSSTEXTDECORATION_LineThrough) ? 1 : 0;
- } else {
- CXFA_Font font = pTextProvider->GetFontNode();
- if (font.IsExistInXML()) {
- iLinethrough = font.GetLineThrough();
- }
- }
-}
-FX_ARGB CXFA_TextParser::GetColor(IXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle) const {
- if (pStyle != NULL) {
- return pStyle->GetFontStyles()->GetColor();
- }
- if (CXFA_Font font = pTextProvider->GetFontNode()) {
- return font.GetColor();
- }
- return 0xFF000000;
-}
-FX_FLOAT CXFA_TextParser::GetBaseline(IXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle) const {
- if (pStyle != NULL) {
- IFDE_CSSParagraphStyle* pParaStyle = pStyle->GetParagraphStyles();
- if (pParaStyle->GetVerticalAlign() == FDE_CSSVERTICALALIGN_Number) {
- return pParaStyle->GetNumberVerticalAlign();
- }
- } else if (CXFA_Font font = pTextProvider->GetFontNode()) {
- return font.GetBaselineShift();
- }
- return 0;
-}
-FX_FLOAT CXFA_TextParser::GetLineHeight(IXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle,
- FX_BOOL bFirst,
- FX_FLOAT fVerScale) const {
- FX_FLOAT fLineHeight = 0;
- if (pStyle != NULL) {
- fLineHeight = pStyle->GetParagraphStyles()->GetLineHeight();
- } else if (CXFA_Para para = pTextProvider->GetParaNode()) {
- fLineHeight = para.GetLineHeight();
- }
- if (bFirst) {
- FX_FLOAT fFontSize = GetFontSize(pTextProvider, pStyle);
- if (fLineHeight < 0.1f) {
- fLineHeight = fFontSize;
- } else {
- fLineHeight = std::min(fLineHeight, fFontSize);
- }
- } else if (fLineHeight < 0.1f) {
- fLineHeight = GetFontSize(pTextProvider, pStyle) * 1.2f;
- }
- fLineHeight *= fVerScale;
- return fLineHeight;
-}
-FX_BOOL CXFA_TextParser::GetEmbbedObj(IXFA_TextProvider* pTextProvider,
- IFDE_XMLNode* pXMLNode,
- CFX_WideString& wsValue) {
- wsValue.Empty();
- if (pXMLNode == NULL) {
- return FALSE;
- }
- FX_BOOL bRet = FALSE;
- if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
- IFDE_XMLElement* pElement = (IFDE_XMLElement*)pXMLNode;
- CFX_WideString wsAttr;
- pElement->GetString(FX_WSTRC(L"xfa:embed").GetPtr(), wsAttr);
- if (wsAttr.IsEmpty()) {
- return FALSE;
- }
- if (wsAttr.GetAt(0) == L'#') {
- wsAttr.Delete(0);
- }
- CFX_WideString ws;
- pElement->GetString(FX_WSTRC(L"xfa:embedType").GetPtr(), ws);
- if (ws.IsEmpty()) {
- ws = L"som";
- } else {
- ws.MakeLower();
- }
- FX_BOOL bURI = (ws == FX_WSTRC(L"uri"));
- if (!bURI && ws != FX_WSTRC(L"som")) {
- return FALSE;
- }
- ws.Empty();
- pElement->GetString(FX_WSTRC(L"xfa:embedMode").GetPtr(), ws);
- if (ws.IsEmpty()) {
- ws = L"formatted";
- } else {
- ws.MakeLower();
- }
- FX_BOOL bRaw = (ws == FX_WSTRC(L"raw"));
- if (!bRaw && ws != FX_WSTRC(L"formatted")) {
- return FALSE;
- }
- bRet = pTextProvider->GetEmbbedObj(bURI, bRaw, wsAttr, wsValue);
- }
- return bRet;
-}
-CXFA_TextParseContext* CXFA_TextParser::GetParseContextFromMap(
- IFDE_XMLNode* pXMLNode) {
- return (CXFA_TextParseContext*)m_mapXMLNodeToParseContext.GetValueAt(
- pXMLNode);
-}
-enum XFA_TABSTOPSSTATUS {
- XFA_TABSTOPSSTATUS_Error,
- XFA_TABSTOPSSTATUS_EOS,
- XFA_TABSTOPSSTATUS_None,
- XFA_TABSTOPSSTATUS_Alignment,
- XFA_TABSTOPSSTATUS_StartLeader,
- XFA_TABSTOPSSTATUS_Leader,
- XFA_TABSTOPSSTATUS_Location,
-};
-FX_BOOL CXFA_TextParser::GetTabstops(
- IFDE_CSSComputedStyle* pStyle,
- CXFA_TextTabstopsContext* pTabstopContext) {
- if (pStyle == NULL || pTabstopContext == NULL) {
- return FALSE;
- }
- CFX_WideString wsValue;
- if (!pStyle->GetCustomStyle(FX_WSTRC(L"xfa-tab-stops"), wsValue) &&
- !pStyle->GetCustomStyle(FX_WSTRC(L"tab-stops"), wsValue)) {
- return FALSE;
- }
- int32_t iLength = wsValue.GetLength();
- const FX_WCHAR* pTabStops = wsValue;
- int32_t iCur = 0;
- int32_t iLast = 0;
- CFX_WideString wsAlign;
- XFA_TABSTOPSSTATUS eStatus = XFA_TABSTOPSSTATUS_None;
- FX_WCHAR ch;
- while (iCur < iLength) {
- ch = pTabStops[iCur];
- switch (eStatus) {
- case XFA_TABSTOPSSTATUS_None:
- if (ch <= ' ') {
- iCur++;
- } else {
- eStatus = XFA_TABSTOPSSTATUS_Alignment;
- iLast = iCur;
- }
- break;
- case XFA_TABSTOPSSTATUS_Alignment:
- if (ch == ' ') {
- wsAlign = CFX_WideStringC(pTabStops + iLast, iCur - iLast);
- eStatus = XFA_TABSTOPSSTATUS_StartLeader;
- iCur++;
- while (iCur < iLength && pTabStops[iCur] <= ' ') {
- iCur++;
- }
- iLast = iCur;
- } else {
- iCur++;
- }
- break;
- case XFA_TABSTOPSSTATUS_StartLeader:
- if (ch != 'l') {
- eStatus = XFA_TABSTOPSSTATUS_Location;
- } else {
- int32_t iCount = 0;
- while (iCur < iLength) {
- ch = pTabStops[iCur];
- iCur++;
- if (ch == '(') {
- iCount++;
- } else if (ch == ')') {
- iCount--;
- if (iCount == 0) {
- break;
- }
- }
- }
- while (iCur < iLength && pTabStops[iCur] <= ' ') {
- iCur++;
- }
- iLast = iCur;
- eStatus = XFA_TABSTOPSSTATUS_Location;
- }
- break;
- case XFA_TABSTOPSSTATUS_Location:
- if (ch == ' ') {
- FX_DWORD dwHashCode =
- FX_HashCode_String_GetW(wsAlign, wsAlign.GetLength(), TRUE);
- CXFA_Measurement ms(CFX_WideStringC(pTabStops + iLast, iCur - iLast));
- FX_FLOAT fPos = ms.ToUnit(XFA_UNIT_Pt);
- pTabstopContext->Append(dwHashCode, fPos);
- wsAlign.Empty();
- eStatus = XFA_TABSTOPSSTATUS_None;
- }
- iCur++;
- break;
- default:
- break;
- }
- }
- if (!wsAlign.IsEmpty()) {
- FX_DWORD dwHashCode =
- FX_HashCode_String_GetW(wsAlign, wsAlign.GetLength(), TRUE);
- CXFA_Measurement ms(CFX_WideStringC(pTabStops + iLast, iCur - iLast));
- FX_FLOAT fPos = ms.ToUnit(XFA_UNIT_Pt);
- pTabstopContext->Append(dwHashCode, fPos);
- }
- return TRUE;
-}
-CXFA_TextLayout::CXFA_TextLayout(IXFA_TextProvider* pTextProvider)
- : m_bHasBlock(FALSE),
- m_pTextProvider(pTextProvider),
- m_pTextDataNode(nullptr),
- m_bRichText(FALSE),
- m_pAllocator(nullptr),
- m_pBreak(nullptr),
- m_pLoader(nullptr),
- m_iLines(0),
- m_fMaxWidth(0),
- m_pTabstopContext(nullptr),
- m_bBlockContinue(TRUE) {
- FXSYS_assert(m_pTextProvider);
-}
-CXFA_TextLayout::~CXFA_TextLayout() {
- m_textParser.Reset();
- delete m_pLoader;
- delete m_pTabstopContext;
- Unload();
-}
-void CXFA_TextLayout::Unload() {
- int32_t iCount = m_pieceLines.GetSize();
- for (int32_t i = 0; i < iCount; i++) {
- CXFA_PieceLine* pLine = m_pieceLines.GetAt(i);
- FDE_DeleteWith(CXFA_PieceLine, m_pAllocator, pLine);
- }
- m_pieceLines.RemoveAll();
- if (m_pBreak != NULL) {
- m_pBreak->Release();
- m_pBreak = NULL;
- }
- if (m_pAllocator != NULL) {
- m_pAllocator->Release();
- m_pAllocator = NULL;
- }
-}
-const CXFA_PieceLineArray* CXFA_TextLayout::GetPieceLines() {
- return &m_pieceLines;
-}
-void CXFA_TextLayout::GetTextDataNode() {
- if (m_pTextProvider == NULL) {
- return;
- }
- CXFA_Node* pNode = m_pTextProvider->GetTextNode(m_bRichText);
- if (pNode && m_bRichText) {
- m_textParser.Reset();
- }
- m_pTextDataNode = pNode;
-}
-IFDE_XMLNode* CXFA_TextLayout::GetXMLContainerNode() {
- IFDE_XMLNode* pXMLContainer = NULL;
- if (m_bRichText) {
- IFDE_XMLNode* pXMLRoot = m_pTextDataNode->GetXMLMappingNode();
- if (!pXMLRoot) {
- return pXMLContainer;
- }
- for (IFDE_XMLNode* pXMLChild =
- pXMLRoot->GetNodeItem(IFDE_XMLNode::FirstChild);
- pXMLChild;
- pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
- if (pXMLChild->GetType() == FDE_XMLNODE_Element) {
- IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLChild;
- CFX_WideString wsTag;
- pXMLElement->GetLocalTagName(wsTag);
- if (wsTag.Equal(FX_WSTRC(L"body")) || wsTag.Equal(FX_WSTRC(L"html"))) {
- pXMLContainer = pXMLChild;
- break;
- }
- }
- }
- }
- return pXMLContainer;
-}
-IFX_RTFBreak* CXFA_TextLayout::CreateBreak(FX_BOOL bDefault) {
- FX_DWORD dwStyle = FX_RTFLAYOUTSTYLE_ExpandTab;
- if (!bDefault) {
- dwStyle |= FX_RTFLAYOUTSTYLE_Pagination;
- }
- IFX_RTFBreak* pBreak = IFX_RTFBreak::Create(0);
- pBreak->SetLayoutStyles(dwStyle);
- pBreak->SetLineBreakChar(L'\n');
- pBreak->SetLineBreakTolerance(1);
- pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, NULL));
- pBreak->SetFontSize(m_textParser.GetFontSize(m_pTextProvider, NULL));
- return pBreak;
-}
-void CXFA_TextLayout::InitBreak(FX_FLOAT fLineWidth) {
- CXFA_Font font = m_pTextProvider->GetFontNode();
- CXFA_Para para = m_pTextProvider->GetParaNode();
- FX_FLOAT fStart = 0;
- FX_FLOAT fStartPos = 0;
- if (para.IsExistInXML()) {
- int32_t iAlign = FX_RTFLINEALIGNMENT_Left;
- switch (para.GetHorizontalAlign()) {
- case XFA_ATTRIBUTEENUM_Center:
- iAlign = FX_RTFLINEALIGNMENT_Center;
- break;
- case XFA_ATTRIBUTEENUM_Right:
- iAlign = FX_RTFLINEALIGNMENT_Right;
- break;
- case XFA_ATTRIBUTEENUM_Justify:
- iAlign = FX_RTFLINEALIGNMENT_Justified;
- break;
- case XFA_ATTRIBUTEENUM_JustifyAll:
- iAlign = FX_RTFLINEALIGNMENT_Distributed;
- break;
- }
- m_pBreak->SetAlignment(iAlign);
- fStart = para.GetMarginLeft();
- if (m_pTextProvider->IsCheckButtonAndAutoWidth()) {
- if (iAlign != FX_RTFLINEALIGNMENT_Left) {
- fLineWidth -= para.GetMarginRight();
- }
- } else {
- fLineWidth -= para.GetMarginRight();
- }
- if (fLineWidth < 0) {
- fLineWidth = fStart;
- }
- fStartPos = fStart;
- FX_FLOAT fIndent = para.GetTextIndent();
- if (fIndent > 0) {
- fStartPos += fIndent;
- }
- }
- m_pBreak->SetLineBoundary(fStart, fLineWidth);
- m_pBreak->SetLineStartPos(fStartPos);
- if (font.IsExistInXML()) {
- m_pBreak->SetHorizontalScale((int32_t)font.GetHorizontalScale());
- m_pBreak->SetVerticalScale((int32_t)font.GetVerticalScale());
- m_pBreak->SetCharSpace(font.GetLetterSpacing());
- }
- FX_FLOAT fFontSize = m_textParser.GetFontSize(m_pTextProvider, NULL);
- m_pBreak->SetFontSize(fFontSize);
- m_pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, NULL));
- m_pBreak->SetLineBreakTolerance(fFontSize * 0.2f);
-}
-void CXFA_TextLayout::InitBreak(IFDE_CSSComputedStyle* pStyle,
- FDE_CSSDISPLAY eDisplay,
- FX_FLOAT fLineWidth,
- IFDE_XMLNode* pXMLNode,
- IFDE_CSSComputedStyle* pParentStyle) {
- if (pStyle == NULL) {
- InitBreak(fLineWidth);
- return;
- }
- IFDE_CSSParagraphStyle* pParaStyle = pStyle->GetParagraphStyles();
- if (eDisplay == FDE_CSSDISPLAY_Block || eDisplay == FDE_CSSDISPLAY_ListItem) {
- int32_t iAlign = FX_RTFLINEALIGNMENT_Left;
- switch (pParaStyle->GetTextAlign()) {
- case FDE_CSSTEXTALIGN_Right:
- iAlign = FX_RTFLINEALIGNMENT_Right;
- break;
- case FDE_CSSTEXTALIGN_Center:
- iAlign = FX_RTFLINEALIGNMENT_Center;
- break;
- case FDE_CSSTEXTALIGN_Justify:
- iAlign = FX_RTFLINEALIGNMENT_Justified;
- break;
- case FDE_CSSTEXTALIGN_JustifyAll:
- iAlign = FX_RTFLINEALIGNMENT_Distributed;
- break;
- default:
- break;
- }
- m_pBreak->SetAlignment(iAlign);
- FX_FLOAT fStart = 0;
- const FDE_CSSRECT* pRect = pStyle->GetBoundaryStyles()->GetMarginWidth();
- const FDE_CSSRECT* pPaddingRect =
- pStyle->GetBoundaryStyles()->GetPaddingWidth();
- if (pRect != NULL) {
- fStart = pRect->left.GetValue();
- fLineWidth -= pRect->right.GetValue();
- if (pPaddingRect != NULL) {
- fStart += pPaddingRect->left.GetValue();
- fLineWidth -= pPaddingRect->right.GetValue();
- }
- if (eDisplay == FDE_CSSDISPLAY_ListItem) {
- const FDE_CSSRECT* pParRect =
- pParentStyle->GetBoundaryStyles()->GetMarginWidth();
- const FDE_CSSRECT* pParPaddingRect =
- pParentStyle->GetBoundaryStyles()->GetPaddingWidth();
- if (pParRect != NULL) {
- fStart += pParRect->left.GetValue();
- fLineWidth -= pParRect->right.GetValue();
- if (pParPaddingRect != NULL) {
- 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->GetBoundaryStyles()->SetMarginWidth(pNewRect);
- }
- }
- m_pBreak->SetLineBoundary(fStart, fLineWidth);
- FX_FLOAT fIndent = pParaStyle->GetTextIndent().GetValue();
- if (fIndent > 0) {
- fStart += fIndent;
- }
- m_pBreak->SetLineStartPos(fStart);
- m_pBreak->SetTabWidth(m_textParser.GetTabInterval(pStyle));
- if (m_pTabstopContext == NULL) {
- m_pTabstopContext = new CXFA_TextTabstopsContext;
- }
- m_textParser.GetTabstops(pStyle, m_pTabstopContext);
- for (int32_t i = 0; i < m_pTabstopContext->m_iTabCount; i++) {
- XFA_TABSTOPS* pTab = m_pTabstopContext->m_tabstops.GetDataPtr(i);
- m_pBreak->AddPositionedTab(pTab->fTabstops);
- }
- }
- FX_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(pParaStyle->GetLetterSpacing().GetValue());
-}
-int32_t CXFA_TextLayout::GetText(CFX_WideString& wsText) {
- GetTextDataNode();
- wsText.Empty();
- if (m_bRichText) {
- } else {
- wsText = m_pTextDataNode->GetContent();
- }
- return wsText.GetLength();
-}
-FX_FLOAT CXFA_TextLayout::GetLayoutHeight() {
- if (m_pLoader == NULL) {
- return 0;
- }
- int32_t iCount = m_pLoader->m_lineHeights.GetSize();
- if (iCount == 0 && m_pLoader->m_fWidth > 0) {
- CFX_SizeF szMax, szDef;
- szMax.Set(m_pLoader->m_fWidth, m_pLoader->m_fHeight);
- szDef.Set(0, 0);
- m_pLoader->m_bSaveLineHeight = TRUE;
- m_pLoader->m_fLastPos = 0;
- CalcSize(szMax, szMax, szDef);
- m_pLoader->m_bSaveLineHeight = FALSE;
- return szDef.y;
- }
- FX_FLOAT fHeight = m_pLoader->m_fHeight;
- if (fHeight < 0.1f) {
- fHeight = 0;
- for (int32_t i = 0; i < iCount; i++) {
- fHeight += m_pLoader->m_lineHeights.ElementAt(i);
- }
- }
- return fHeight;
-}
-FX_FLOAT CXFA_TextLayout::StartLayout(FX_FLOAT fWidth) {
- if (m_pLoader == NULL) {
- m_pLoader = new CXFA_LoaderContext;
- }
- if (fWidth < 0 || (m_pLoader->m_fWidth > -1 &&
- FXSYS_fabs(fWidth - m_pLoader->m_fWidth) > 0)) {
- m_pLoader->m_lineHeights.RemoveAll();
- m_Blocks.RemoveAll();
- Unload();
- m_pLoader->m_fStartLineOffset = 0;
- }
- m_pLoader->m_fWidth = fWidth;
- if (fWidth < 0) {
- CFX_SizeF szMax, szDef;
- szMax.Set(0, 0);
- szDef.Set(0, 0);
- m_pLoader->m_bSaveLineHeight = TRUE;
- m_pLoader->m_fLastPos = 0;
- CalcSize(szMax, szMax, szDef);
- m_pLoader->m_bSaveLineHeight = FALSE;
- fWidth = szDef.x;
- }
- return fWidth;
-}
-FX_BOOL CXFA_TextLayout::DoLayout(int32_t iBlockIndex,
- FX_FLOAT& fCalcHeight,
- FX_FLOAT fContentAreaHeight,
- FX_FLOAT fTextHeight) {
- if (m_pLoader == NULL) {
- return FALSE;
- }
- int32_t iBlockCount = m_Blocks.GetSize();
- FX_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.GetVAlgin(m_pTextProvider);
- if (iAlign == XFA_ATTRIBUTEENUM_Middle) {
- fHeight /= 2.0f;
- } else if (iAlign != XFA_ATTRIBUTEENUM_Bottom) {
- fHeight = 0;
- }
- m_pLoader->m_fStartLineOffset = fHeight;
- }
- }
- FX_FLOAT fLinePos = m_pLoader->m_fStartLineOffset;
- int32_t iLineIndex = 0;
- if (iBlockCount > 1) {
- if (iBlockCount >= (iBlockIndex + 1) * 2) {
- iLineIndex = m_Blocks.ElementAt(iBlockIndex * 2);
- } else {
- iLineIndex = m_Blocks.ElementAt(iBlockCount - 1) +
- m_Blocks.ElementAt(iBlockCount - 2);
- }
- if (m_pLoader->m_BlocksHeight.GetSize() > 0) {
- for (int32_t i = 0; i < iBlockIndex; i++) {
- fLinePos -= m_pLoader->m_BlocksHeight.ElementAt(i * 2 + 1);
- }
- }
- }
- int32_t iCount = m_pLoader->m_lineHeights.GetSize();
- int32_t i = 0;
- for (i = iLineIndex; i < iCount; i++) {
- FX_FLOAT fLineHeight = m_pLoader->m_lineHeights.ElementAt(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.SetAt(iBlockIndex * 2, iLineIndex);
- m_Blocks.SetAt(iBlockIndex * 2 + 1, i - iLineIndex);
- } else {
- m_Blocks.Add(iLineIndex);
- m_Blocks.Add(i - iLineIndex);
- }
- if (i == iLineIndex) {
- if (fCalcHeight <= fLinePos) {
- if (m_pLoader->m_BlocksHeight.GetSize() > iBlockIndex * 2 &&
- (m_pLoader->m_BlocksHeight.GetAt(iBlockIndex * 2) ==
- iBlockIndex)) {
- m_pLoader->m_BlocksHeight.SetAt(iBlockIndex * 2 + 1, fCalcHeight);
- } else {
- m_pLoader->m_BlocksHeight.Add((FX_FLOAT)iBlockIndex);
- m_pLoader->m_BlocksHeight.Add(fCalcHeight);
- }
- }
- return TRUE;
- }
- fCalcHeight = fLinePos;
- return TRUE;
- }
- fLinePos += fLineHeight;
- }
- return FALSE;
-}
-int32_t CXFA_TextLayout::CountBlocks() const {
- int32_t iCount = m_Blocks.GetSize() / 2;
- return iCount > 0 ? iCount : 1;
-}
-FX_BOOL CXFA_TextLayout::CalcSize(const CFX_SizeF& minSize,
- const CFX_SizeF& maxSize,
- CFX_SizeF& defaultSize) {
- defaultSize.x = maxSize.x;
- if (defaultSize.x < 1) {
- defaultSize.x = 0xFFFF;
- }
- if (m_pBreak != NULL) {
- m_pBreak->Release();
- }
- m_pBreak = CreateBreak(FALSE);
- FX_FLOAT fLinePos = 0;
- m_iLines = 0;
- m_fMaxWidth = 0;
- Loader(defaultSize, fLinePos, FALSE);
- if (fLinePos < 0.1f) {
- fLinePos = m_textParser.GetFontSize(m_pTextProvider, NULL);
- }
- if (m_pTabstopContext) {
- delete m_pTabstopContext;
- m_pTabstopContext = NULL;
- }
- defaultSize.Set(m_fMaxWidth, fLinePos);
- return TRUE;
-}
-FX_BOOL CXFA_TextLayout::Layout(const CFX_SizeF& size, FX_FLOAT* fHeight) {
- if (size.x < 1) {
- return FALSE;
- }
- Unload();
- m_pBreak = CreateBreak(TRUE);
- if (m_pLoader != NULL) {
- m_pLoader->m_iTotalLines = -1;
- m_pLoader->m_iChar = 0;
- }
- m_iLines = 0;
- FX_FLOAT fLinePos = 0;
- Loader(size, fLinePos, TRUE);
- UpdateAlign(size.y, fLinePos);
- if (m_pTabstopContext) {
- delete m_pTabstopContext;
- m_pTabstopContext = NULL;
- }
- if (fHeight) {
- *fHeight = fLinePos;
- }
- return TRUE;
-}
-FX_BOOL CXFA_TextLayout::Layout(int32_t iBlock) {
- if (m_pLoader == NULL || iBlock < 0 || iBlock >= CountBlocks()) {
- return FALSE;
- }
- if (m_pLoader->m_fWidth < 1) {
- return FALSE;
- }
- m_pLoader->m_iTotalLines = -1;
- m_iLines = 0;
- FX_FLOAT fLinePos = 0;
- CXFA_Node* pNode = NULL;
- CFX_SizeF szText;
- szText.Set(m_pLoader->m_fWidth, m_pLoader->m_fHeight);
- int32_t iCount = m_Blocks.GetSize();
- int32_t iBlocksHeightCount = m_pLoader->m_BlocksHeight.GetSize();
- 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.ElementAt(i * 2 + 1);
- }
- m_pLoader->m_iChar = 0;
- if (iCount > 1) {
- m_pLoader->m_iTotalLines = m_Blocks.ElementAt(iBlock * 2 + 1);
- }
- Loader(szText, fLinePos, TRUE);
- if (iCount == 0 && m_pLoader->m_fStartLineOffset < 0.1f) {
- UpdateAlign(szText.y, fLinePos);
- }
- } else if (m_pTextDataNode != NULL) {
- iBlock *= 2;
- if (iBlock < iCount - 2) {
- m_pLoader->m_iTotalLines = m_Blocks.ElementAt(iBlock + 1);
- }
- m_pBreak->Reset();
- if (m_bRichText) {
- IFDE_XMLNode* pContainerNode = GetXMLContainerNode();
- if (!pContainerNode) {
- return TRUE;
- }
- IFDE_XMLNode* pXMLNode = m_pLoader->m_pXMLNode;
- if (pXMLNode == NULL) {
- return TRUE;
- }
- IFDE_XMLNode* pSaveXMLNode = m_pLoader->m_pXMLNode;
- for (; pXMLNode;
- pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
- FX_BOOL bFlag = LoadRichText(pXMLNode, szText, fLinePos,
- m_pLoader->m_pParentStyle, TRUE);
- if (!bFlag) {
- break;
- }
- }
- while (pXMLNode == NULL) {
- pXMLNode = pSaveXMLNode->GetNodeItem(IFDE_XMLNode::Parent);
- if (pXMLNode == pContainerNode) {
- break;
- }
- FX_BOOL bFlag =
- LoadRichText(pXMLNode, szText, fLinePos, m_pLoader->m_pParentStyle,
- TRUE, NULL, FALSE);
- if (!bFlag) {
- break;
- }
- pSaveXMLNode = pXMLNode;
- pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling);
- if (!pXMLNode) {
- continue;
- }
- for (; pXMLNode;
- pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
- FX_BOOL bFlag = LoadRichText(pXMLNode, szText, fLinePos,
- m_pLoader->m_pParentStyle, TRUE);
- if (!bFlag) {
- break;
- }
- }
- }
- } else {
- pNode = m_pLoader->m_pNode;
- if (pNode == NULL) {
- return TRUE;
- }
- LoadText(pNode, szText, fLinePos, TRUE);
- }
- }
- if (iBlock == iCount) {
- if (m_pTabstopContext != NULL) {
- delete m_pTabstopContext;
- m_pTabstopContext = NULL;
- }
- if (m_pLoader != NULL) {
- delete m_pLoader;
- m_pLoader = NULL;
- }
- }
- return TRUE;
-}
-void CXFA_TextLayout::ItemBlocks(const CFX_RectF& rtText, int32_t iBlockIndex) {
- if (!m_pLoader) {
- return;
- }
- int32_t iCountHeight = m_pLoader->m_lineHeights.GetSize();
- if (iCountHeight == 0) {
- return;
- }
- FX_BOOL bEndItem = TRUE;
- int32_t iBlockCount = m_Blocks.GetSize();
- FX_FLOAT fLinePos = m_pLoader->m_fStartLineOffset;
- int32_t iLineIndex = 0;
- if (iBlockIndex > 0) {
- int32_t iBlockHeightCount = m_pLoader->m_BlocksHeight.GetSize();
- iBlockHeightCount /= 2;
- if (iBlockHeightCount >= iBlockIndex) {
- for (int32_t i = 0; i < iBlockIndex; i++) {
- fLinePos -= m_pLoader->m_BlocksHeight.ElementAt(i * 2 + 1);
- }
- } else {
- fLinePos = 0;
- }
- iLineIndex = m_Blocks.ElementAt(iBlockCount - 1) +
- m_Blocks.ElementAt(iBlockCount - 2);
- }
- int32_t i = 0;
- for (i = iLineIndex; i < iCountHeight; i++) {
- FX_FLOAT fLineHeight = m_pLoader->m_lineHeights.ElementAt(i);
- if (fLinePos + fLineHeight - rtText.height > 0.001) {
- m_Blocks.Add(iLineIndex);
- m_Blocks.Add(i - iLineIndex);
- bEndItem = FALSE;
- break;
- }
- fLinePos += fLineHeight;
- }
- if (iCountHeight > 0 && (i - iLineIndex) > 0 && bEndItem) {
- m_Blocks.Add(iLineIndex);
- m_Blocks.Add(i - iLineIndex);
- }
-}
-FX_BOOL CXFA_TextLayout::DrawString(CFX_RenderDevice* pFxDevice,
- const CFX_Matrix& tmDoc2Device,
- const CFX_RectF& rtClip,
- int32_t iBlock) {
- IFDE_RenderDevice* pDevice = IFDE_RenderDevice::Create(pFxDevice);
- if (pDevice == NULL) {
- return FALSE;
- }
- FDE_HDEVICESTATE state = pDevice->SaveState();
- pDevice->SetClipRect(rtClip);
- IFDE_SolidBrush* pSolidBrush =
- (IFDE_SolidBrush*)IFDE_Brush::Create(FDE_BRUSHTYPE_Solid);
- IFDE_Pen* pPen = IFDE_Pen::Create();
- FXSYS_assert(pDevice != NULL && pSolidBrush != NULL && pPen != NULL);
- if (m_pieceLines.GetSize() == 0) {
- int32_t iBlockCount = CountBlocks();
- for (int32_t i = 0; i < iBlockCount; i++) {
- Layout(i);
- }
- }
- FXTEXT_CHARPOS* pCharPos = NULL;
- int32_t iCharCount = 0;
- int32_t iLineStart = 0;
- int32_t iPieceLines = m_pieceLines.GetSize();
- int32_t iCount = m_Blocks.GetSize();
- if (iCount > 0) {
- iBlock *= 2;
- if (iBlock < iCount) {
- iLineStart = m_Blocks.ElementAt(iBlock);
- iPieceLines = m_Blocks.ElementAt(iBlock + 1);
- } else {
- iPieceLines = 0;
- }
- }
- for (int32_t i = 0; i < iPieceLines; i++) {
- if (i + iLineStart >= m_pieceLines.GetSize()) {
- break;
- }
- CXFA_PieceLine* pPieceLine = m_pieceLines.GetAt(i + iLineStart);
- int32_t iPieces = pPieceLine->m_textPieces.GetSize();
- int32_t j = 0;
- for (j = 0; j < iPieces; j++) {
- XFA_LPCTEXTPIECE pPiece = pPieceLine->m_textPieces.GetAt(j);
- int32_t iChars = pPiece->iChars;
- if (iCharCount < iChars) {
- FX_Free(pCharPos);
- pCharPos = FX_Alloc(FXTEXT_CHARPOS, iChars);
- iCharCount = iChars;
- }
- FXSYS_memset(pCharPos, 0, iCharCount * sizeof(FXTEXT_CHARPOS));
- RenderString(pDevice, pSolidBrush, pPieceLine, j, pCharPos, tmDoc2Device);
- }
- for (j = 0; j < iPieces; j++) {
- RenderPath(pDevice, pPen, pPieceLine, j, pCharPos, tmDoc2Device);
- }
- }
- pDevice->RestoreState(state);
- FX_Free(pCharPos);
- pSolidBrush->Release();
- pPen->Release();
- pDevice->Release();
- return iPieceLines;
-}
-void CXFA_TextLayout::UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom) {
- fHeight -= fBottom;
- if (fHeight < 0.1f) {
- return;
- }
- switch (m_textParser.GetVAlgin(m_pTextProvider)) {
- case XFA_ATTRIBUTEENUM_Middle:
- fHeight /= 2.0f;
- break;
- case XFA_ATTRIBUTEENUM_Bottom:
- break;
- default:
- return;
- }
- int32_t iCount = m_pieceLines.GetSize();
- for (int32_t i = 0; i < iCount; i++) {
- CXFA_PieceLine* pPieceLine = m_pieceLines.GetAt(i);
- int32_t iPieces = pPieceLine->m_textPieces.GetSize();
- for (int32_t j = 0; j < iPieces; j++) {
- XFA_LPTEXTPIECE pPiece = pPieceLine->m_textPieces.GetAt(j);
- CFX_RectF& rect = pPiece->rtPiece;
- rect.top += fHeight;
- }
- }
-}
-FX_BOOL CXFA_TextLayout::Loader(const CFX_SizeF& szText,
- FX_FLOAT& fLinePos,
- FX_BOOL bSavePieces) {
- if (m_pAllocator == NULL) {
- m_pAllocator = FX_CreateAllocator(FX_ALLOCTYPE_Static, 256, 0);
- }
- GetTextDataNode();
- if (m_pTextDataNode == NULL) {
- return TRUE;
- }
- if (m_bRichText) {
- IFDE_XMLNode* pXMLContainer = GetXMLContainerNode();
- if (pXMLContainer) {
- if (!m_textParser.IsParsed()) {
- m_textParser.DoParse(pXMLContainer, m_pTextProvider);
- }
- IFDE_CSSComputedStyle* pRootStyle =
- m_textParser.CreateRootStyle(m_pTextProvider);
- LoadRichText(pXMLContainer, szText, fLinePos, pRootStyle, bSavePieces);
- pRootStyle->Release();
- }
- } else {
- LoadText(m_pTextDataNode, szText, fLinePos, bSavePieces);
- }
- return TRUE;
-}
-void CXFA_TextLayout::LoadText(CXFA_Node* pNode,
- const CFX_SizeF& szText,
- FX_FLOAT& fLinePos,
- FX_BOOL bSavePieces) {
- InitBreak(szText.x);
- CXFA_Para para = m_pTextProvider->GetParaNode();
- FX_FLOAT fSpaceAbove = 0;
- if (para.IsExistInXML()) {
- 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" ");
- FX_BOOL bRet = AppendChar(wsText, fLinePos, fSpaceAbove, bSavePieces);
- if (bRet && m_pLoader != NULL) {
- m_pLoader->m_pNode = pNode;
- } else {
- EndBreak(FX_RTFBREAK_ParagraphBreak, fLinePos, bSavePieces);
- }
-}
-FX_BOOL CXFA_TextLayout::LoadRichText(IFDE_XMLNode* pXMLNode,
- const CFX_SizeF& szText,
- FX_FLOAT& fLinePos,
- IFDE_CSSComputedStyle* pParentStyle,
- FX_BOOL bSavePieces,
- CXFA_LinkUserData* pLinkData,
- FX_BOOL bEndBreak,
- FX_BOOL bIsOl,
- int32_t iLiCount) {
- if (pXMLNode == NULL) {
- return FALSE;
- }
- CXFA_TextParseContext* pContext =
- m_textParser.GetParseContextFromMap(pXMLNode);
- FDE_CSSDISPLAY eDisplay = FDE_CSSDISPLAY_None;
- FX_BOOL bContentNode = FALSE;
- FX_FLOAT fSpaceBelow = 0;
- IFDE_CSSComputedStyle* pStyle = NULL;
- CFX_WideString wsName;
- if (bEndBreak) {
- FX_BOOL bCurOl = FALSE;
- FX_BOOL bCurLi = FALSE;
- IFDE_XMLElement* pElement = NULL;
- if (pContext != NULL) {
- if (m_bBlockContinue ||
- (m_pLoader && pXMLNode == m_pLoader->m_pXMLNode)) {
- m_bBlockContinue = TRUE;
- }
- if (pXMLNode->GetType() == FDE_XMLNODE_Text) {
- bContentNode = TRUE;
- } else if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
- pElement = (IFDE_XMLElement*)pXMLNode;
- pElement->GetLocalTagName(wsName);
- }
- if (wsName == FX_WSTRC(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);
- InitBreak(bContentNode ? pParentStyle : pStyle, eDisplay, szText.x,
- pXMLNode, pParentStyle);
- if ((eDisplay == FDE_CSSDISPLAY_Block ||
- eDisplay == FDE_CSSDISPLAY_ListItem) &&
- (pStyle != NULL) &&
- (wsName.IsEmpty() ||
- (wsName != FX_WSTRC(L"body") && wsName != FX_WSTRC(L"html") &&
- wsName != FX_WSTRC(L"ol") && wsName != FX_WSTRC(L"ul")))) {
- const FDE_CSSRECT* pRect =
- pStyle->GetBoundaryStyles()->GetMarginWidth();
- if (pRect) {
- fLinePos += pRect->top.GetValue();
- fSpaceBelow = pRect->bottom.GetValue();
- }
- }
- if (wsName == FX_WSTRC(L"a")) {
- CFX_WideString wsLinkContent;
- FXSYS_assert(pElement);
- pElement->GetString(FX_WSTRC(L"href").GetPtr(), wsLinkContent);
- if (!wsLinkContent.IsEmpty()) {
- pLinkData = FDE_NewWith(m_pAllocator) CXFA_LinkUserData(
- m_pAllocator,
- wsLinkContent.GetBuffer(wsLinkContent.GetLength()));
- wsLinkContent.ReleaseBuffer(wsLinkContent.GetLength());
- }
- }
- int32_t iTabCount =
- m_textParser.CountTabs(bContentNode ? pParentStyle : pStyle);
- FX_BOOL bSpaceRun =
- m_textParser.IsSpaceRun(bContentNode ? pParentStyle : pStyle);
- CFX_WideString wsText;
- if (bContentNode && iTabCount == 0) {
- ((IFDE_XMLText*)pXMLNode)->GetText(wsText);
- } else if (wsName == FX_WSTRC(L"br")) {
- wsText = L'\n';
- } else if (wsName == FX_WSTRC(L"li")) {
- bCurLi = TRUE;
- if (bIsOl) {
- wsText.Format(L"%d. ", iLiCount);
- } else {
- wsText = 0x00B7 + FX_WSTRC(L" ");
- }
- } 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)
- ;
- else {
- m_pLoader->m_dwFlags &= ~XFA_LOADERCNTXTFLG_FILTERSPACE;
- }
- }
- if (wsText.GetLength() > 0) {
- if (m_pLoader == NULL || m_pLoader->m_iChar == 0) {
- if (pLinkData) {
- pLinkData->AddRef();
- }
- CXFA_TextUserData* pUserData = FDE_NewWith(m_pAllocator)
- CXFA_TextUserData(m_pAllocator,
- 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;
- }
- if (pStyle != NULL) {
- pStyle->Release();
- }
- return FALSE;
- }
- return TRUE;
- }
- }
- }
- }
- FX_BOOL ret = TRUE;
- for (IFDE_XMLNode* pChildNode =
- pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
- pChildNode;
- pChildNode = pChildNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
- if (bCurOl) {
- iLiCount++;
- }
- ret = LoadRichText(pChildNode, szText, fLinePos,
- pContext ? pStyle : pParentStyle, bSavePieces,
- pLinkData, TRUE, bIsOl, iLiCount);
- if (ret == FALSE) {
- return FALSE;
- }
- }
- if (m_pLoader) {
- if (FDE_CSSDISPLAY_Block == eDisplay) {
- m_pLoader->m_dwFlags |= XFA_LOADERCNTXTFLG_FILTERSPACE;
- }
- }
- if (bCurLi) {
- EndBreak(FX_RTFBREAK_LineBreak, fLinePos, bSavePieces);
- }
- } else {
- if (pContext != NULL) {
- eDisplay = pContext->GetDisplay();
- }
- }
- if (m_bBlockContinue) {
- if (pContext != NULL && !bContentNode) {
- FX_DWORD dwStatus = (eDisplay == FDE_CSSDISPLAY_Block)
- ? FX_RTFBREAK_ParagraphBreak
- : FX_RTFBREAK_PieceBreak;
- EndBreak(dwStatus, fLinePos, bSavePieces);
- if (eDisplay == FDE_CSSDISPLAY_Block) {
- fLinePos += fSpaceBelow;
- if (m_pTabstopContext) {
- m_pTabstopContext->RemoveAll();
- }
- }
- if (wsName == FX_WSTRC(L"a")) {
- if (pLinkData) {
- pLinkData->Release();
- pLinkData = nullptr;
- }
- }
- if (IsEnd(bSavePieces)) {
- if (pStyle) {
- pStyle->Release();
- }
- if (m_pLoader && m_pLoader->m_iTotalLines > -1) {
- m_pLoader->m_pXMLNode =
- pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling);
- m_pLoader->m_pParentStyle = pParentStyle;
- }
- return FALSE;
- }
- }
- }
- if (pStyle != NULL) {
- pStyle->Release();
- }
- return TRUE;
-}
-FX_BOOL CXFA_TextLayout::AppendChar(const CFX_WideString& wsText,
- FX_FLOAT& fLinePos,
- FX_FLOAT fSpaceAbove,
- FX_BOOL bSavePieces) {
- FX_DWORD dwStatus = 0;
- 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++) {
- FX_WCHAR wch = wsText.GetAt(i);
- if (wch == 0xA0) {
- wch = 0x20;
- }
- if ((dwStatus = m_pBreak->AppendChar(wch)) > FX_RTFBREAK_PieceBreak) {
- AppendTextLine(dwStatus, fLinePos, bSavePieces);
- if (IsEnd(bSavePieces)) {
- if (m_pLoader != NULL) {
- m_pLoader->m_iChar = i;
- }
- return TRUE;
- }
- if (dwStatus == FX_RTFBREAK_ParagraphBreak && m_bRichText) {
- fLinePos += fSpaceAbove;
- }
- }
- }
- if (m_pLoader) {
- m_pLoader->m_iChar = 0;
- }
- return FALSE;
-}
-FX_BOOL CXFA_TextLayout::IsEnd(FX_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;
- }
- FX_WCHAR* psz = wsText.GetBuffer(iLen);
- int32_t iTrimLeft = 0;
- FX_WCHAR 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(FX_DWORD dwStatus,
- FX_FLOAT& fLinePos,
- FX_BOOL bSavePieces) {
- dwStatus = m_pBreak->EndBreak(dwStatus);
- if (dwStatus > FX_RTFBREAK_PieceBreak) {
- AppendTextLine(dwStatus, fLinePos, bSavePieces, TRUE);
- }
-}
-void CXFA_TextLayout::DoTabstops(IFDE_CSSComputedStyle* pStyle,
- CXFA_PieceLine* pPieceLine) {
- if (m_pTabstopContext == NULL || m_pTabstopContext->m_iTabCount == 0) {
- return;
- }
- if (pStyle == NULL || pPieceLine == NULL) {
- return;
- }
- int32_t iPieces = pPieceLine->m_textPieces.GetSize();
- if (iPieces == 0) {
- return;
- }
- XFA_LPTEXTPIECE pPiece = pPieceLine->m_textPieces.GetAt(iPieces - 1);
- int32_t& iTabstopsIndex = m_pTabstopContext->m_iTabIndex;
- int32_t iCount = m_textParser.CountTabs(pStyle);
- if (iTabstopsIndex > m_pTabstopContext->m_iTabCount - 1) {
- return;
- }
- if (iCount > 0) {
- iTabstopsIndex++;
- m_pTabstopContext->m_bTabstops = TRUE;
- FX_FLOAT fRight = 0;
- if (iPieces > 1) {
- XFA_LPTEXTPIECE p = pPieceLine->m_textPieces.GetAt(iPieces - 2);
- fRight = p->rtPiece.right();
- }
- m_pTabstopContext->m_fTabWidth =
- pPiece->rtPiece.width + pPiece->rtPiece.left - fRight;
- } else if (iTabstopsIndex > -1) {
- FX_FLOAT fLeft = 0;
- if (m_pTabstopContext->m_bTabstops) {
- XFA_TABSTOPS* pTabstops =
- m_pTabstopContext->m_tabstops.GetDataPtr(iTabstopsIndex);
- FX_DWORD dwAlgin = pTabstops->dwAlign;
- if (dwAlgin == FX_HashCode_String_GetW(L"center", 6)) {
- fLeft = pPiece->rtPiece.width / 2.0f;
- } else if (dwAlgin == FX_HashCode_String_GetW(L"right", 5) ||
- dwAlgin == FX_HashCode_String_GetW(L"before", 6)) {
- fLeft = pPiece->rtPiece.width;
- } else if (dwAlgin == FX_HashCode_String_GetW(L"decimal", 7)) {
- int32_t iChars = pPiece->iChars;
- for (int32_t i = 0; i < iChars; i++) {
- if (pPiece->pszText[i] == L'.') {
- break;
- }
- fLeft += pPiece->pWidths[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(FX_DWORD dwStatus,
- FX_FLOAT& fLinePos,
- FX_BOOL bSavePieces,
- FX_BOOL bEndBreak) {
- int32_t iPieces = m_pBreak->CountBreakPieces();
- if (iPieces < 1) {
- return;
- }
- IFDE_CSSComputedStyle* pStyle = NULL;
- if (bSavePieces) {
- CXFA_PieceLine* pPieceLine = FDE_NewWith(m_pAllocator) CXFA_PieceLine;
- m_pieceLines.Add(pPieceLine);
- if (m_pTabstopContext) {
- m_pTabstopContext->Reset();
- }
- FX_FLOAT fLineStep = 0, fBaseLine = 0;
- int32_t i = 0;
- for (i = 0; i < iPieces; i++) {
- const CFX_RTFPiece* pPiece = m_pBreak->GetBreakPiece(i);
- CXFA_TextUserData* pUserData = (CXFA_TextUserData*)pPiece->m_pUserData;
- if (pUserData != NULL) {
- pStyle = pUserData->m_pStyle;
- }
- FX_FLOAT fVerScale = pPiece->m_iVerticalScale / 100.0f;
- XFA_LPTEXTPIECE pTP =
- (XFA_LPTEXTPIECE)m_pAllocator->Alloc(sizeof(XFA_TEXTPIECE));
- pTP->pszText =
- (FX_WCHAR*)m_pAllocator->Alloc(pPiece->m_iChars * sizeof(FX_WCHAR));
- pTP->pWidths =
- (int32_t*)m_pAllocator->Alloc(pPiece->m_iChars * sizeof(int32_t));
- pTP->iChars = pPiece->m_iChars;
- pPiece->GetString(pTP->pszText);
- pPiece->GetWidths(pTP->pWidths);
- pTP->iBidiLevel = pPiece->m_iBidiLevel;
- pTP->iHorScale = pPiece->m_iHorizontalScale;
- pTP->iVerScale = pPiece->m_iVerticalScale;
- m_textParser.GetUnderline(m_pTextProvider, pStyle, pTP->iUnderline,
- pTP->iPeriod);
- m_textParser.GetLinethrough(m_pTextProvider, pStyle, pTP->iLineThrough);
- pTP->dwColor = m_textParser.GetColor(m_pTextProvider, pStyle);
- pTP->pFont = m_textParser.GetFont(m_pTextProvider, pStyle);
- pTP->fFontSize = m_textParser.GetFontSize(m_pTextProvider, pStyle);
- pTP->rtPiece.left = pPiece->m_iStartPos / 20000.0f;
- pTP->rtPiece.width = pPiece->m_iWidth / 20000.0f;
- pTP->rtPiece.height = (FX_FLOAT)pPiece->m_iFontSize * fVerScale / 20.0f;
- FX_FLOAT fBaseLineTemp =
- m_textParser.GetBaseline(m_pTextProvider, pStyle);
- pTP->rtPiece.top = fBaseLineTemp;
- pPieceLine->m_textPieces.Add(pTP);
- FX_FLOAT fLineHeight = m_textParser.GetLineHeight(
- m_pTextProvider, pStyle, m_iLines == 0, fVerScale);
- if (fBaseLineTemp > 0) {
- FX_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);
- if (pUserData != NULL && pUserData->m_pLinkData != NULL) {
- pUserData->m_pLinkData->AddRef();
- pTP->pLinkData = pUserData->m_pLinkData;
- } else {
- pTP->pLinkData = NULL;
- }
- DoTabstops(pStyle, pPieceLine);
- }
- for (i = 0; i < iPieces; i++) {
- XFA_LPTEXTPIECE pTP = pPieceLine->m_textPieces.GetAt(i);
- FX_FLOAT& fTop = pTP->rtPiece.top;
- FX_FLOAT fBaseLineTemp = fTop;
- fTop = fLinePos + fLineStep - pTP->rtPiece.height - fBaseLineTemp;
- fTop = std::max(0.0f, fTop);
- }
- fLinePos += fLineStep + fBaseLine;
- } else {
- FX_FLOAT fLineStep = 0;
- FX_FLOAT fLineWidth = 0;
- for (int32_t i = 0; i < iPieces; i++) {
- const CFX_RTFPiece* pPiece = m_pBreak->GetBreakPiece(i);
- CXFA_TextUserData* pUserData = (CXFA_TextUserData*)pPiece->m_pUserData;
- if (pUserData != NULL) {
- pStyle = pUserData->m_pStyle;
- }
- FX_FLOAT fVerScale = pPiece->m_iVerticalScale / 100.0f;
- FX_FLOAT fBaseLine = m_textParser.GetBaseline(m_pTextProvider, pStyle);
- FX_FLOAT fLineHeight = m_textParser.GetLineHeight(
- m_pTextProvider, pStyle, m_iLines == 0, fVerScale);
- if (fBaseLine > 0) {
- FX_FLOAT fLineHeightTmp =
- fBaseLine + (FX_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) {
- FX_FLOAT fHeight = fLinePos - m_pLoader->m_fLastPos;
- m_pLoader->m_fLastPos = fLinePos;
- m_pLoader->m_lineHeights.Add(fHeight);
- }
- }
- if (pStyle) {
- pStyle->AddRef();
- }
- m_pBreak->ClearBreakPieces();
- if (dwStatus == FX_RTFBREAK_ParagraphBreak) {
- m_pBreak->Reset();
- if (!pStyle && bEndBreak) {
- CXFA_Para para = m_pTextProvider->GetParaNode();
- if (para.IsExistInXML()) {
- FX_FLOAT fStartPos = para.GetMarginLeft();
- FX_FLOAT fIndent = para.GetTextIndent();
- if (fIndent > 0) {
- fStartPos += fIndent;
- }
- FX_FLOAT fSpaceBelow = para.GetSpaceBelow();
- if (fSpaceBelow < 0.1f) {
- fSpaceBelow = 0;
- }
- m_pBreak->SetLineStartPos(fStartPos);
- fLinePos += fSpaceBelow;
- }
- }
- }
- if (pStyle) {
- FX_FLOAT fStart = 0;
- const FDE_CSSRECT* pRect = pStyle->GetBoundaryStyles()->GetMarginWidth();
- if (pRect) {
- fStart = pRect->left.GetValue();
- }
- FX_FLOAT fTextIndent =
- pStyle->GetParagraphStyles()->GetTextIndent().GetValue();
- if (fTextIndent < 0) {
- fStart -= fTextIndent;
- }
- m_pBreak->SetLineStartPos(fStart);
- pStyle->Release();
- }
- m_iLines++;
-}
-void CXFA_TextLayout::RenderString(IFDE_RenderDevice* pDevice,
- IFDE_SolidBrush* pBrush,
- CXFA_PieceLine* pPieceLine,
- int32_t iPiece,
- FXTEXT_CHARPOS* pCharPos,
- const CFX_Matrix& tmDoc2Device) {
- XFA_LPCTEXTPIECE pPiece = pPieceLine->m_textPieces.GetAt(iPiece);
- 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.Add(iCount);
-}
-void CXFA_TextLayout::RenderPath(IFDE_RenderDevice* pDevice,
- IFDE_Pen* pPen,
- CXFA_PieceLine* pPieceLine,
- int32_t iPiece,
- FXTEXT_CHARPOS* pCharPos,
- const CFX_Matrix& tmDoc2Device) {
- XFA_TEXTPIECE* pPiece = pPieceLine->m_textPieces.GetAt(iPiece);
- FX_BOOL bNoUnderline = pPiece->iUnderline < 1 || pPiece->iUnderline > 2;
- FX_BOOL bNoLineThrough = pPiece->iLineThrough < 1 || pPiece->iLineThrough > 2;
- if (bNoUnderline && bNoLineThrough) {
- return;
- }
- pPen->SetColor(pPiece->dwColor);
- IFDE_Path* pPath = IFDE_Path::Create();
- int32_t iChars = GetDisplayPos(pPiece, pCharPos);
- if (iChars > 0) {
- CFX_PointF pt1, pt2;
- FX_FLOAT fEndY = pCharPos[0].m_OriginY + 1.05f;
- int32_t i = 0;
- 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_OriginX;
- 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_OriginX;
- pt2.x =
- pCharPos[iChars - 1].m_OriginX +
- 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_OriginY - pPiece->rtPiece.height * 0.25f;
- pt1.x = pCharPos[0].m_OriginX;
- pt2.x = pCharPos[iChars - 1].m_OriginX +
- pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
- for (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)) {
- goto XFA_RenderPathRet;
- }
- int32_t iCharsTmp = 0;
- int32_t iPiecePrev = iPiece, iPieceNext = iPiece;
- while (iPiecePrev > 0) {
- iPiecePrev--;
- iCharsTmp = pPieceLine->m_charCounts.GetAt(iPiecePrev);
- if (iCharsTmp > 0) {
- break;
- }
- }
- if (iCharsTmp == 0) {
- goto XFA_RenderPathRet;
- }
- iCharsTmp = 0;
- int32_t iPieces = pPieceLine->m_textPieces.GetSize();
- while (iPieceNext < iPieces - 1) {
- iPieceNext++;
- iCharsTmp = pPieceLine->m_charCounts.GetAt(iPieceNext);
- if (iCharsTmp > 0) {
- break;
- }
- }
- if (iCharsTmp == 0) {
- goto XFA_RenderPathRet;
- }
- FX_FLOAT fOrgX = 0.0f, fEndX = 0.0f;
- pPiece = pPieceLine->m_textPieces.GetAt(iPiecePrev);
- iChars = GetDisplayPos(pPiece, pCharPos);
- if (iChars < 1) {
- goto XFA_RenderPathRet;
- }
- fOrgX = pCharPos[iChars - 1].m_OriginX +
- pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
- pPiece = pPieceLine->m_textPieces.GetAt(iPieceNext);
- iChars = GetDisplayPos(pPiece, pCharPos);
- if (iChars < 1) {
- goto XFA_RenderPathRet;
- }
- fEndX = pCharPos[0].m_OriginX;
- CFX_PointF pt1, pt2;
- pt1.x = fOrgX, pt2.x = fEndX;
- FX_FLOAT fEndY = pCharPos[0].m_OriginY + 1.05f;
- int32_t i = 0;
- for (i = 0; i < pPiece->iUnderline; i++) {
- pt1.y = pt2.y = fEndY;
- pPath->AddLine(pt1, pt2);
- fEndY += 2.0f;
- }
- fEndY = pCharPos[0].m_OriginY - pPiece->rtPiece.height * 0.25f;
- for (i = 0; i < pPiece->iLineThrough; i++) {
- pt1.y = pt2.y = fEndY;
- pPath->AddLine(pt1, pt2);
- fEndY += 2.0f;
- }
- }
- pDevice->DrawPath(pPen, 1, pPath, &tmDoc2Device);
-XFA_RenderPathRet:
- pPath->Release();
-}
-int32_t CXFA_TextLayout::GetDisplayPos(XFA_LPCTEXTPIECE pPiece,
- FXTEXT_CHARPOS* pCharPos,
- FX_BOOL bCharCode) {
- if (pPiece == NULL) {
- return 0;
- }
- FX_RTFTEXTOBJ tr;
- if (!ToRun(pPiece, tr)) {
- return 0;
- }
- return m_pBreak->GetDisplayPos(&tr, pCharPos, bCharCode);
-}
-FX_BOOL CXFA_TextLayout::ToRun(XFA_LPCTEXTPIECE pPiece, FX_RTFTEXTOBJ& tr) {
- int32_t iLength = pPiece->iChars;
- if (iLength < 1) {
- return FALSE;
- }
- tr.pStr = pPiece->pszText;
- tr.pFont = pPiece->pFont;
- tr.pRect = &pPiece->rtPiece;
- tr.pWidths = pPiece->pWidths;
- tr.iLength = iLength;
- tr.fFontSize = pPiece->fFontSize;
- tr.iBidiLevel = pPiece->iBidiLevel;
- tr.iCharRotation = 0;
- tr.wLineBreakChar = L'\n';
- tr.iVerticalScale = pPiece->iVerScale;
- tr.dwLayoutStyles = FX_RTFLAYOUTSTYLE_ExpandTab;
- tr.iHorizontalScale = pPiece->iHorScale;
- return TRUE;
-}
+// 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 <algorithm> + +#include "xfa/src/foxitlib.h" +#include "xfa/src/fxfa/src/common/xfa_common.h" +#include "xfa_textlayout.h" +#include "xfa_ffapp.h" +#include "xfa_ffdoc.h" +#include "xfa_fontmgr.h" +CXFA_CSSTagProvider::~CXFA_CSSTagProvider() { + FX_POSITION pos = m_Attributes.GetStartPosition(); + while (pos) { + CFX_WideString *pName = NULL, *pValue = NULL; + m_Attributes.GetNextAssoc(pos, (void*&)pName, (void*&)pValue); + if (pName != NULL) { + delete pName; + } + if (pValue != NULL) { + delete pValue; + } + } +} +void CXFA_CSSTagProvider::GetNextAttribute(FX_POSITION& pos, + CFX_WideStringC& wsAttr, + CFX_WideStringC& wsValue) { + if (pos == NULL) { + return; + } + CFX_WideString* pName = NULL; + CFX_WideString* pValue = NULL; + m_Attributes.GetNextAssoc(pos, (void*&)pName, (void*&)pValue); + wsAttr = *pName; + wsValue = *pValue; +} +void CXFA_CSSTagProvider::SetAttribute(const CFX_WideString& wsAttr, + const CFX_WideString& wsValue) { + CFX_WideString* pName = new CFX_WideString(); + CFX_WideString* pValue = new CFX_WideString(); + *pName = wsAttr; + *pValue = wsValue; + m_Attributes.SetAt(pName, pValue); +} +void CXFA_TextParseContext::SetDecls(const IFDE_CSSDeclaration** ppDeclArray, + int32_t iDeclCount) { + if (iDeclCount <= 0 || ppDeclArray == NULL) { + return; + } + m_dwMatchedDecls = iDeclCount; + m_ppMatchedDecls = FX_Alloc(IFDE_CSSDeclaration*, iDeclCount); + FX_memcpy(m_ppMatchedDecls, ppDeclArray, + iDeclCount * sizeof(IFDE_CSSDeclaration*)); +} +CXFA_TextParser::~CXFA_TextParser() { + if (m_pUASheet != NULL) { + m_pUASheet->Release(); + } + if (m_pSelector != NULL) { + m_pSelector->Release(); + } + if (m_pAllocator != NULL) { + m_pAllocator->Release(); + } + FX_POSITION ps = m_mapXMLNodeToParseContext.GetStartPosition(); + while (ps) { + IFDE_XMLNode* pXMLNode; + CXFA_TextParseContext* pParseContext; + m_mapXMLNodeToParseContext.GetNextAssoc(ps, pXMLNode, pParseContext); + if (pParseContext != NULL) { + FDE_DeleteWith(CXFA_TextParseContext, m_pAllocator, pParseContext); + } + } + m_mapXMLNodeToParseContext.RemoveAll(); +} +void CXFA_TextParser::Reset() { + FX_POSITION ps = m_mapXMLNodeToParseContext.GetStartPosition(); + while (ps) { + IFDE_XMLNode* pXMLNode; + CXFA_TextParseContext* pParseContext; + m_mapXMLNodeToParseContext.GetNextAssoc(ps, pXMLNode, pParseContext); + if (pParseContext != NULL) { + FDE_DeleteWith(CXFA_TextParseContext, m_pAllocator, pParseContext); + } + } + m_mapXMLNodeToParseContext.RemoveAll(); + if (m_pAllocator != NULL) { + m_pAllocator->Release(); + m_pAllocator = NULL; + } +} +void CXFA_TextParser::InitCSSData(IXFA_TextProvider* pTextProvider) { + if (pTextProvider == NULL) { + return; + } + if (m_pSelector == NULL) { + CXFA_FFDoc* pDoc = pTextProvider->GetDocNode(); + IFX_FontMgr* pFontMgr = pDoc->GetApp()->GetFDEFontMgr(); + FXSYS_assert(pFontMgr != NULL); + m_pSelector = IFDE_CSSStyleSelector::Create(); + m_pSelector->SetFontMgr(pFontMgr); + FX_FLOAT fFontSize = 10; + CXFA_Font font = pTextProvider->GetFontNode(); + if (font.IsExistInXML()) { + fFontSize = font.GetFontSize(); + } + m_pSelector->SetDefFontSize(fFontSize); + } + if (m_pUASheet == NULL) { + m_pUASheet = LoadDefaultSheetStyle(); + m_pSelector->SetStyleSheet(FDE_CSSSTYLESHEETGROUP_UserAgent, m_pUASheet); + m_pSelector->UpdateStyleIndex(FDE_CSSMEDIATYPE_ALL); + } +} +IFDE_CSSStyleSheet* CXFA_TextParser::LoadDefaultSheetStyle() { + static const FX_WCHAR s_pStyle[] = + L"html,body,ol,p,ul{display:block}" + L"li{display:list-item}" + L"ol,ul{padding-left:33px}ol{list-style-type:decimal}ol,ul{margin-top:0;" + L"margin-bottom:0}ul,ol{margin:1.12em 0}" + L"a{color:#0000ff;text-decoration:underline}b{font-weight:bolder}i{font-" + L"style:italic}" + L"sup{vertical-align:+15em;font-size:.66em}sub{vertical-align:-15em;font-" + L"size:.66em}"; + return IFDE_CSSStyleSheet::LoadFromBuffer( + CFX_WideString(), s_pStyle, FXSYS_wcslen(s_pStyle), FX_CODEPAGE_UTF8); +} +IFDE_CSSComputedStyle* CXFA_TextParser::CreateRootStyle( + IXFA_TextProvider* pTextProvider) { + CXFA_Font font = pTextProvider->GetFontNode(); + CXFA_Para para = pTextProvider->GetParaNode(); + IFDE_CSSComputedStyle* pStyle = m_pSelector->CreateComputedStyle(NULL); + IFDE_CSSFontStyle* pFontStyle = pStyle->GetFontStyles(); + IFDE_CSSParagraphStyle* pParaStyle = pStyle->GetParagraphStyles(); + FX_FLOAT fLineHeight = 0, fFontSize = 10; + if (para.IsExistInXML()) { + fLineHeight = para.GetLineHeight(); + FDE_CSSLENGTH indent; + indent.Set(FDE_CSSLENGTHUNIT_Point, para.GetTextIndent()); + pParaStyle->SetTextIndent(indent); + FDE_CSSTEXTALIGN hAlgin = FDE_CSSTEXTALIGN_Left; + switch (para.GetHorizontalAlign()) { + case XFA_ATTRIBUTEENUM_Center: + hAlgin = FDE_CSSTEXTALIGN_Center; + break; + case XFA_ATTRIBUTEENUM_Right: + hAlgin = FDE_CSSTEXTALIGN_Right; + break; + case XFA_ATTRIBUTEENUM_Justify: + hAlgin = FDE_CSSTEXTALIGN_Justify; + break; + case XFA_ATTRIBUTEENUM_JustifyAll: + hAlgin = FDE_CSSTEXTALIGN_JustifyAll; + break; + } + pParaStyle->SetTextAlign(hAlgin); + FDE_CSSRECT rtMarginWidth; + rtMarginWidth.left.Set(FDE_CSSLENGTHUNIT_Point, para.GetMarginLeft()); + rtMarginWidth.top.Set(FDE_CSSLENGTHUNIT_Point, para.GetSpaceAbove()); + rtMarginWidth.right.Set(FDE_CSSLENGTHUNIT_Point, para.GetMarginRight()); + rtMarginWidth.bottom.Set(FDE_CSSLENGTHUNIT_Point, para.GetSpaceBelow()); + pStyle->GetBoundaryStyles()->SetMarginWidth(rtMarginWidth); + } + if (font.IsExistInXML()) { + pFontStyle->SetColor(font.GetColor()); + pFontStyle->SetFontStyle(font.IsItalic() ? FDE_CSSFONTSTYLE_Italic + : FDE_CSSFONTSTYLE_Normal); + pFontStyle->SetFontWeight(font.IsBold() ? FXFONT_FW_BOLD + : FXFONT_FW_NORMAL); + pParaStyle->SetNumberVerticalAlign(-font.GetBaselineShift()); + fFontSize = font.GetFontSize(); + FDE_CSSLENGTH letterSpacing; + letterSpacing.Set(FDE_CSSLENGTHUNIT_Point, font.GetLetterSpacing()); + pParaStyle->SetLetterSpacing(letterSpacing); + FX_DWORD dwDecoration = 0; + if (font.GetLineThrough() > 0) { + dwDecoration |= FDE_CSSTEXTDECORATION_LineThrough; + } + if (font.GetUnderline() > 1) { + dwDecoration |= FDE_CSSTEXTDECORATION_Double; + } else if (font.GetUnderline() > 0) { + dwDecoration |= FDE_CSSTEXTDECORATION_Underline; + } + pParaStyle->SetTextDecoration(dwDecoration); + } + pParaStyle->SetLineHeight(fLineHeight); + pFontStyle->SetFontSize(fFontSize); + return pStyle; +} +IFDE_CSSComputedStyle* CXFA_TextParser::CreateStyle( + IFDE_CSSComputedStyle* pParentStyle) { + IFDE_CSSComputedStyle* pNewStyle = + m_pSelector->CreateComputedStyle(pParentStyle); + FXSYS_assert(pNewStyle != NULL); + if (pParentStyle) { + IFDE_CSSParagraphStyle* pParaStyle = pParentStyle->GetParagraphStyles(); + FX_DWORD dwDecoration = pParaStyle->GetTextDecoration(); + FX_FLOAT fBaseLine = 0; + if (pParaStyle->GetVerticalAlign() == FDE_CSSVERTICALALIGN_Number) { + fBaseLine = pParaStyle->GetNumberVerticalAlign(); + } + pParaStyle = pNewStyle->GetParagraphStyles(); + pParaStyle->SetTextDecoration(dwDecoration); + pParaStyle->SetNumberVerticalAlign(fBaseLine); + IFDE_CSSBoundaryStyle* pBoundarytyle = pParentStyle->GetBoundaryStyles(); + const FDE_CSSRECT* pRect = pBoundarytyle->GetMarginWidth(); + if (pRect != NULL) { + pBoundarytyle = pNewStyle->GetBoundaryStyles(); + pBoundarytyle->SetMarginWidth(*pRect); + } + } + return pNewStyle; +} +IFDE_CSSComputedStyle* CXFA_TextParser::ComputeStyle( + IFDE_XMLNode* pXMLNode, + IFDE_CSSComputedStyle* pParentStyle) { + CXFA_TextParseContext* pContext = static_cast<CXFA_TextParseContext*>( + m_mapXMLNodeToParseContext.GetValueAt(pXMLNode)); + if (!pContext) + return nullptr; + pContext->m_pParentStyle = pParentStyle; + pParentStyle->AddRef(); + CXFA_CSSTagProvider tagProvider; + ParseTagInfo(pXMLNode, tagProvider); + if (tagProvider.m_bContent) + return nullptr; + IFDE_CSSComputedStyle* pStyle = CreateStyle(pParentStyle); + IFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator(); + pCSSAccel->OnEnterTag(&tagProvider); + m_pSelector->ComputeStyle(&tagProvider, pContext->GetDecls(), + pContext->CountDecls(), pStyle); + pCSSAccel->OnLeaveTag(&tagProvider); + return pStyle; +} +void CXFA_TextParser::DoParse(IFDE_XMLNode* pXMLContainer, + IXFA_TextProvider* pTextProvider) { + if (pXMLContainer == NULL || pTextProvider == NULL || m_pAllocator != NULL) { + return; + } + m_pAllocator = + FX_CreateAllocator(FX_ALLOCTYPE_Fixed, 32, sizeof(CXFA_CSSTagProvider)); + InitCSSData(pTextProvider); + IFDE_CSSComputedStyle* pRootStyle = CreateRootStyle(pTextProvider); + ParseRichText(pXMLContainer, pRootStyle); + pRootStyle->Release(); +} +void CXFA_TextParser::ParseRichText(IFDE_XMLNode* pXMLNode, + IFDE_CSSComputedStyle* pParentStyle) { + if (pXMLNode == NULL) { + return; + } + CXFA_CSSTagProvider tagProvider; + ParseTagInfo(pXMLNode, tagProvider); + if (!tagProvider.m_bTagAviliable) { + return; + } + IFDE_CSSComputedStyle* pNewStyle = NULL; + if ((tagProvider.GetTagName() != FX_WSTRC(L"body")) || + (tagProvider.GetTagName() != FX_WSTRC(L"html"))) { + CXFA_TextParseContext* pTextContext = + FDE_NewWith(m_pAllocator) CXFA_TextParseContext; + FDE_CSSDISPLAY eDisplay = FDE_CSSDISPLAY_Inline; + if (!tagProvider.m_bContent) { + pNewStyle = CreateStyle(pParentStyle); + IFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator(); + pCSSAccel->OnEnterTag(&tagProvider); + CFDE_CSSDeclarationArray DeclArray; + int32_t iMatchedDecls = + m_pSelector->MatchDeclarations(&tagProvider, DeclArray); + const IFDE_CSSDeclaration** ppMatchDecls = + (const IFDE_CSSDeclaration**)DeclArray.GetData(); + m_pSelector->ComputeStyle(&tagProvider, ppMatchDecls, iMatchedDecls, + pNewStyle); + pCSSAccel->OnLeaveTag(&tagProvider); + if (iMatchedDecls > 0) { + pTextContext->SetDecls(ppMatchDecls, iMatchedDecls); + } + eDisplay = pNewStyle->GetPositionStyles()->GetDisplay(); + } + pTextContext->SetDisplay(eDisplay); + m_mapXMLNodeToParseContext.SetAt(pXMLNode, pTextContext); + } + for (IFDE_XMLNode* pXMLChild = + pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild); + pXMLChild; + pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) { + ParseRichText(pXMLChild, pNewStyle); + } + if (pNewStyle != NULL) { + pNewStyle->Release(); + } +} +void CXFA_TextParser::ParseTagInfo(IFDE_XMLNode* pXMLNode, + CXFA_CSSTagProvider& tagProvider) { + static const FX_DWORD s_XFATagName[] = { + 0x61, 0x62, 0x69, 0x70, 0x0001f714, + 0x00022a55, 0x000239bb, 0x00025881, 0x0bd37faa, 0x0bd37fb8, + 0xa73e3af2, 0xb182eaae, 0xdb8ac455, + }; + CFX_WideString wsName; + if (pXMLNode->GetType() == FDE_XMLNODE_Element) { + IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLNode; + pXMLElement->GetLocalTagName(wsName); + tagProvider.SetTagNameObj(wsName); + FX_DWORD dwHashCode = + FX_HashCode_String_GetW(wsName, wsName.GetLength(), TRUE); + static const int32_t s_iCount = sizeof(s_XFATagName) / sizeof(FX_DWORD); + CFX_DSPATemplate<FX_DWORD> lookup; + tagProvider.m_bTagAviliable = + lookup.Lookup(dwHashCode, s_XFATagName, s_iCount) > -1; + CFX_WideString wsValue; + pXMLElement->GetString(FX_WSTRC(L"style").GetPtr(), wsValue); + if (!wsValue.IsEmpty()) { + tagProvider.SetAttribute(FX_WSTRC(L"style"), wsValue); + } + } else if (pXMLNode->GetType() == FDE_XMLNODE_Text) { + tagProvider.m_bTagAviliable = TRUE; + tagProvider.m_bContent = TRUE; + } +} +int32_t CXFA_TextParser::GetVAlgin(IXFA_TextProvider* pTextProvider) const { + int32_t iAlign = XFA_ATTRIBUTEENUM_Top; + CXFA_Para para = pTextProvider->GetParaNode(); + if (para.IsExistInXML()) { + iAlign = para.GetVerticalAlign(); + } + return iAlign; +} +FX_FLOAT CXFA_TextParser::GetTabInterval(IFDE_CSSComputedStyle* pStyle) const { + CFX_WideString wsValue; + if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"tab-interval"), wsValue)) { + CXFA_Measurement ms(wsValue); + return ms.ToUnit(XFA_UNIT_Pt); + } + return 36; +} +int32_t CXFA_TextParser::CountTabs(IFDE_CSSComputedStyle* pStyle) const { + CFX_WideString wsValue; + if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"xfa-tab-count"), wsValue)) { + return wsValue.GetInteger(); + } + return 0; +} +FX_BOOL CXFA_TextParser::IsSpaceRun(IFDE_CSSComputedStyle* pStyle) const { + CFX_WideString wsValue; + if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"xfa-spacerun"), wsValue)) { + wsValue.MakeLower(); + return wsValue == FX_WSTRC(L"yes"); + } + return FALSE; +} +IFX_Font* CXFA_TextParser::GetFont(IXFA_TextProvider* pTextProvider, + IFDE_CSSComputedStyle* pStyle) const { + CFX_WideStringC wsFamily = FX_WSTRC(L"Courier"); + FX_DWORD dwStyle = 0; + CXFA_Font font = pTextProvider->GetFontNode(); + if (font.IsExistInXML()) { + font.GetTypeface(wsFamily); + if (font.IsBold()) { + dwStyle |= FX_FONTSTYLE_Bold; + } + if (font.IsItalic()) { + dwStyle |= FX_FONTSTYLE_Italic; + } + } + if (pStyle) { + IFDE_CSSFontStyle* pFontStyle = pStyle->GetFontStyles(); + int32_t iCount = pFontStyle->CountFontFamilies(); + if (iCount > 0) { + wsFamily = pFontStyle->GetFontFamily(iCount - 1); + } + dwStyle = 0; + if (pFontStyle->GetFontWeight() > FXFONT_FW_NORMAL) { + dwStyle |= FX_FONTSTYLE_Bold; + } + if (pFontStyle->GetFontStyle() == FDE_CSSFONTSTYLE_Italic) { + dwStyle |= FX_FONTSTYLE_Italic; + } + } + CXFA_FFDoc* pDoc = pTextProvider->GetDocNode(); + FXSYS_assert(pDoc != NULL); + CXFA_FontMgr* pFontMgr = pDoc->GetApp()->GetXFAFontMgr(); + return pFontMgr->GetFont(pDoc, wsFamily, dwStyle); +} +FX_FLOAT CXFA_TextParser::GetFontSize(IXFA_TextProvider* pTextProvider, + IFDE_CSSComputedStyle* pStyle) const { + if (pStyle != NULL) { + return pStyle->GetFontStyles()->GetFontSize(); + } + CXFA_Font font = pTextProvider->GetFontNode(); + if (font.IsExistInXML()) { + return font.GetFontSize(); + } + return 10; +} +int32_t CXFA_TextParser::GetHorScale(IXFA_TextProvider* pTextProvider, + IFDE_CSSComputedStyle* pStyle, + IFDE_XMLNode* pXMLNode) const { + if (pStyle) { + CFX_WideString wsValue; + if (pStyle->GetCustomStyle(FX_WSTRC(L"xfa-font-horizontal-scale"), + wsValue)) { + return wsValue.GetInteger(); + } + while (pXMLNode) { + CXFA_TextParseContext* pContext = static_cast<CXFA_TextParseContext*>( + m_mapXMLNodeToParseContext.GetValueAt(pXMLNode)); + if (pContext && pContext->m_pParentStyle && + pContext->m_pParentStyle->GetCustomStyle( + FX_WSTRC(L"xfa-font-horizontal-scale"), wsValue)) { + return wsValue.GetInteger(); + } + pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::Parent); + } + } + if (CXFA_Font font = pTextProvider->GetFontNode()) { + return static_cast<int32_t>(font.GetHorizontalScale()); + } + return 100; +} +int32_t CXFA_TextParser::GetVerScale(IXFA_TextProvider* pTextProvider, + IFDE_CSSComputedStyle* pStyle) const { + if (pStyle != NULL) { + CFX_WideString wsValue; + if (pStyle->GetCustomStyle(FX_WSTRC(L"xfa-font-vertical-scale"), wsValue)) { + return wsValue.GetInteger(); + } + } + if (CXFA_Font font = pTextProvider->GetFontNode()) { + return (int32_t)font.GetVerticalScale(); + } + return 100; +} +void CXFA_TextParser::GetUnderline(IXFA_TextProvider* pTextProvider, + IFDE_CSSComputedStyle* pStyle, + int32_t& iUnderline, + int32_t& iPeriod) const { + iUnderline = 0; + iPeriod = XFA_ATTRIBUTEENUM_All; + if (pStyle) { + FX_DWORD dwDecoration = pStyle->GetParagraphStyles()->GetTextDecoration(); + if (dwDecoration & FDE_CSSTEXTDECORATION_Double) { + iUnderline = 2; + } else if (dwDecoration & FDE_CSSTEXTDECORATION_Underline) { + iUnderline = 1; + } + CFX_WideString wsValue; + if (pStyle->GetCustomStyle(FX_WSTRC(L"underlinePeriod"), wsValue)) { + if (wsValue == FX_WSTRC(L"word")) { + iPeriod = XFA_ATTRIBUTEENUM_Word; + } + } else if (CXFA_Font font = pTextProvider->GetFontNode()) { + iPeriod = font.GetUnderlinePeriod(); + } + } else { + CXFA_Font font = pTextProvider->GetFontNode(); + if (font.IsExistInXML()) { + iUnderline = font.GetUnderline(); + iPeriod = font.GetUnderlinePeriod(); + } + } +} +void CXFA_TextParser::GetLinethrough(IXFA_TextProvider* pTextProvider, + IFDE_CSSComputedStyle* pStyle, + int32_t& iLinethrough) const { + if (pStyle) { + FX_DWORD dwDecoration = pStyle->GetParagraphStyles()->GetTextDecoration(); + iLinethrough = (dwDecoration & FDE_CSSTEXTDECORATION_LineThrough) ? 1 : 0; + } else { + CXFA_Font font = pTextProvider->GetFontNode(); + if (font.IsExistInXML()) { + iLinethrough = font.GetLineThrough(); + } + } +} +FX_ARGB CXFA_TextParser::GetColor(IXFA_TextProvider* pTextProvider, + IFDE_CSSComputedStyle* pStyle) const { + if (pStyle != NULL) { + return pStyle->GetFontStyles()->GetColor(); + } + if (CXFA_Font font = pTextProvider->GetFontNode()) { + return font.GetColor(); + } + return 0xFF000000; +} +FX_FLOAT CXFA_TextParser::GetBaseline(IXFA_TextProvider* pTextProvider, + IFDE_CSSComputedStyle* pStyle) const { + if (pStyle != NULL) { + IFDE_CSSParagraphStyle* pParaStyle = pStyle->GetParagraphStyles(); + if (pParaStyle->GetVerticalAlign() == FDE_CSSVERTICALALIGN_Number) { + return pParaStyle->GetNumberVerticalAlign(); + } + } else if (CXFA_Font font = pTextProvider->GetFontNode()) { + return font.GetBaselineShift(); + } + return 0; +} +FX_FLOAT CXFA_TextParser::GetLineHeight(IXFA_TextProvider* pTextProvider, + IFDE_CSSComputedStyle* pStyle, + FX_BOOL bFirst, + FX_FLOAT fVerScale) const { + FX_FLOAT fLineHeight = 0; + if (pStyle != NULL) { + fLineHeight = pStyle->GetParagraphStyles()->GetLineHeight(); + } else if (CXFA_Para para = pTextProvider->GetParaNode()) { + fLineHeight = para.GetLineHeight(); + } + if (bFirst) { + FX_FLOAT fFontSize = GetFontSize(pTextProvider, pStyle); + if (fLineHeight < 0.1f) { + fLineHeight = fFontSize; + } else { + fLineHeight = std::min(fLineHeight, fFontSize); + } + } else if (fLineHeight < 0.1f) { + fLineHeight = GetFontSize(pTextProvider, pStyle) * 1.2f; + } + fLineHeight *= fVerScale; + return fLineHeight; +} +FX_BOOL CXFA_TextParser::GetEmbbedObj(IXFA_TextProvider* pTextProvider, + IFDE_XMLNode* pXMLNode, + CFX_WideString& wsValue) { + wsValue.Empty(); + if (pXMLNode == NULL) { + return FALSE; + } + FX_BOOL bRet = FALSE; + if (pXMLNode->GetType() == FDE_XMLNODE_Element) { + IFDE_XMLElement* pElement = (IFDE_XMLElement*)pXMLNode; + CFX_WideString wsAttr; + pElement->GetString(FX_WSTRC(L"xfa:embed").GetPtr(), wsAttr); + if (wsAttr.IsEmpty()) { + return FALSE; + } + if (wsAttr.GetAt(0) == L'#') { + wsAttr.Delete(0); + } + CFX_WideString ws; + pElement->GetString(FX_WSTRC(L"xfa:embedType").GetPtr(), ws); + if (ws.IsEmpty()) { + ws = L"som"; + } else { + ws.MakeLower(); + } + FX_BOOL bURI = (ws == FX_WSTRC(L"uri")); + if (!bURI && ws != FX_WSTRC(L"som")) { + return FALSE; + } + ws.Empty(); + pElement->GetString(FX_WSTRC(L"xfa:embedMode").GetPtr(), ws); + if (ws.IsEmpty()) { + ws = L"formatted"; + } else { + ws.MakeLower(); + } + FX_BOOL bRaw = (ws == FX_WSTRC(L"raw")); + if (!bRaw && ws != FX_WSTRC(L"formatted")) { + return FALSE; + } + bRet = pTextProvider->GetEmbbedObj(bURI, bRaw, wsAttr, wsValue); + } + return bRet; +} +CXFA_TextParseContext* CXFA_TextParser::GetParseContextFromMap( + IFDE_XMLNode* pXMLNode) { + return (CXFA_TextParseContext*)m_mapXMLNodeToParseContext.GetValueAt( + pXMLNode); +} +enum XFA_TABSTOPSSTATUS { + XFA_TABSTOPSSTATUS_Error, + XFA_TABSTOPSSTATUS_EOS, + XFA_TABSTOPSSTATUS_None, + XFA_TABSTOPSSTATUS_Alignment, + XFA_TABSTOPSSTATUS_StartLeader, + XFA_TABSTOPSSTATUS_Leader, + XFA_TABSTOPSSTATUS_Location, +}; +FX_BOOL CXFA_TextParser::GetTabstops( + IFDE_CSSComputedStyle* pStyle, + CXFA_TextTabstopsContext* pTabstopContext) { + if (pStyle == NULL || pTabstopContext == NULL) { + return FALSE; + } + CFX_WideString wsValue; + if (!pStyle->GetCustomStyle(FX_WSTRC(L"xfa-tab-stops"), wsValue) && + !pStyle->GetCustomStyle(FX_WSTRC(L"tab-stops"), wsValue)) { + return FALSE; + } + int32_t iLength = wsValue.GetLength(); + const FX_WCHAR* pTabStops = wsValue; + int32_t iCur = 0; + int32_t iLast = 0; + CFX_WideString wsAlign; + XFA_TABSTOPSSTATUS eStatus = XFA_TABSTOPSSTATUS_None; + FX_WCHAR ch; + while (iCur < iLength) { + ch = pTabStops[iCur]; + switch (eStatus) { + case XFA_TABSTOPSSTATUS_None: + if (ch <= ' ') { + iCur++; + } else { + eStatus = XFA_TABSTOPSSTATUS_Alignment; + iLast = iCur; + } + break; + case XFA_TABSTOPSSTATUS_Alignment: + if (ch == ' ') { + wsAlign = CFX_WideStringC(pTabStops + iLast, iCur - iLast); + eStatus = XFA_TABSTOPSSTATUS_StartLeader; + iCur++; + while (iCur < iLength && pTabStops[iCur] <= ' ') { + iCur++; + } + iLast = iCur; + } else { + iCur++; + } + break; + case XFA_TABSTOPSSTATUS_StartLeader: + if (ch != 'l') { + eStatus = XFA_TABSTOPSSTATUS_Location; + } else { + int32_t iCount = 0; + while (iCur < iLength) { + ch = pTabStops[iCur]; + iCur++; + if (ch == '(') { + iCount++; + } else if (ch == ')') { + iCount--; + if (iCount == 0) { + break; + } + } + } + while (iCur < iLength && pTabStops[iCur] <= ' ') { + iCur++; + } + iLast = iCur; + eStatus = XFA_TABSTOPSSTATUS_Location; + } + break; + case XFA_TABSTOPSSTATUS_Location: + if (ch == ' ') { + FX_DWORD dwHashCode = + FX_HashCode_String_GetW(wsAlign, wsAlign.GetLength(), TRUE); + CXFA_Measurement ms(CFX_WideStringC(pTabStops + iLast, iCur - iLast)); + FX_FLOAT fPos = ms.ToUnit(XFA_UNIT_Pt); + pTabstopContext->Append(dwHashCode, fPos); + wsAlign.Empty(); + eStatus = XFA_TABSTOPSSTATUS_None; + } + iCur++; + break; + default: + break; + } + } + if (!wsAlign.IsEmpty()) { + FX_DWORD dwHashCode = + FX_HashCode_String_GetW(wsAlign, wsAlign.GetLength(), TRUE); + CXFA_Measurement ms(CFX_WideStringC(pTabStops + iLast, iCur - iLast)); + FX_FLOAT fPos = ms.ToUnit(XFA_UNIT_Pt); + pTabstopContext->Append(dwHashCode, fPos); + } + return TRUE; +} +CXFA_TextLayout::CXFA_TextLayout(IXFA_TextProvider* pTextProvider) + : m_bHasBlock(FALSE), + m_pTextProvider(pTextProvider), + m_pTextDataNode(nullptr), + m_bRichText(FALSE), + m_pAllocator(nullptr), + m_pBreak(nullptr), + m_pLoader(nullptr), + m_iLines(0), + m_fMaxWidth(0), + m_pTabstopContext(nullptr), + m_bBlockContinue(TRUE) { + FXSYS_assert(m_pTextProvider); +} +CXFA_TextLayout::~CXFA_TextLayout() { + m_textParser.Reset(); + delete m_pLoader; + delete m_pTabstopContext; + Unload(); +} +void CXFA_TextLayout::Unload() { + int32_t iCount = m_pieceLines.GetSize(); + for (int32_t i = 0; i < iCount; i++) { + CXFA_PieceLine* pLine = m_pieceLines.GetAt(i); + FDE_DeleteWith(CXFA_PieceLine, m_pAllocator, pLine); + } + m_pieceLines.RemoveAll(); + if (m_pBreak != NULL) { + m_pBreak->Release(); + m_pBreak = NULL; + } + if (m_pAllocator != NULL) { + m_pAllocator->Release(); + m_pAllocator = NULL; + } +} +const CXFA_PieceLineArray* CXFA_TextLayout::GetPieceLines() { + return &m_pieceLines; +} +void CXFA_TextLayout::GetTextDataNode() { + if (m_pTextProvider == NULL) { + return; + } + CXFA_Node* pNode = m_pTextProvider->GetTextNode(m_bRichText); + if (pNode && m_bRichText) { + m_textParser.Reset(); + } + m_pTextDataNode = pNode; +} +IFDE_XMLNode* CXFA_TextLayout::GetXMLContainerNode() { + IFDE_XMLNode* pXMLContainer = NULL; + if (m_bRichText) { + IFDE_XMLNode* pXMLRoot = m_pTextDataNode->GetXMLMappingNode(); + if (!pXMLRoot) { + return pXMLContainer; + } + for (IFDE_XMLNode* pXMLChild = + pXMLRoot->GetNodeItem(IFDE_XMLNode::FirstChild); + pXMLChild; + pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) { + if (pXMLChild->GetType() == FDE_XMLNODE_Element) { + IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLChild; + CFX_WideString wsTag; + pXMLElement->GetLocalTagName(wsTag); + if (wsTag.Equal(FX_WSTRC(L"body")) || wsTag.Equal(FX_WSTRC(L"html"))) { + pXMLContainer = pXMLChild; + break; + } + } + } + } + return pXMLContainer; +} +IFX_RTFBreak* CXFA_TextLayout::CreateBreak(FX_BOOL bDefault) { + FX_DWORD dwStyle = FX_RTFLAYOUTSTYLE_ExpandTab; + if (!bDefault) { + dwStyle |= FX_RTFLAYOUTSTYLE_Pagination; + } + IFX_RTFBreak* pBreak = IFX_RTFBreak::Create(0); + pBreak->SetLayoutStyles(dwStyle); + pBreak->SetLineBreakChar(L'\n'); + pBreak->SetLineBreakTolerance(1); + pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, NULL)); + pBreak->SetFontSize(m_textParser.GetFontSize(m_pTextProvider, NULL)); + return pBreak; +} +void CXFA_TextLayout::InitBreak(FX_FLOAT fLineWidth) { + CXFA_Font font = m_pTextProvider->GetFontNode(); + CXFA_Para para = m_pTextProvider->GetParaNode(); + FX_FLOAT fStart = 0; + FX_FLOAT fStartPos = 0; + if (para.IsExistInXML()) { + int32_t iAlign = FX_RTFLINEALIGNMENT_Left; + switch (para.GetHorizontalAlign()) { + case XFA_ATTRIBUTEENUM_Center: + iAlign = FX_RTFLINEALIGNMENT_Center; + break; + case XFA_ATTRIBUTEENUM_Right: + iAlign = FX_RTFLINEALIGNMENT_Right; + break; + case XFA_ATTRIBUTEENUM_Justify: + iAlign = FX_RTFLINEALIGNMENT_Justified; + break; + case XFA_ATTRIBUTEENUM_JustifyAll: + iAlign = FX_RTFLINEALIGNMENT_Distributed; + break; + } + m_pBreak->SetAlignment(iAlign); + fStart = para.GetMarginLeft(); + if (m_pTextProvider->IsCheckButtonAndAutoWidth()) { + if (iAlign != FX_RTFLINEALIGNMENT_Left) { + fLineWidth -= para.GetMarginRight(); + } + } else { + fLineWidth -= para.GetMarginRight(); + } + if (fLineWidth < 0) { + fLineWidth = fStart; + } + fStartPos = fStart; + FX_FLOAT fIndent = para.GetTextIndent(); + if (fIndent > 0) { + fStartPos += fIndent; + } + } + m_pBreak->SetLineBoundary(fStart, fLineWidth); + m_pBreak->SetLineStartPos(fStartPos); + if (font.IsExistInXML()) { + m_pBreak->SetHorizontalScale((int32_t)font.GetHorizontalScale()); + m_pBreak->SetVerticalScale((int32_t)font.GetVerticalScale()); + m_pBreak->SetCharSpace(font.GetLetterSpacing()); + } + FX_FLOAT fFontSize = m_textParser.GetFontSize(m_pTextProvider, NULL); + m_pBreak->SetFontSize(fFontSize); + m_pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, NULL)); + m_pBreak->SetLineBreakTolerance(fFontSize * 0.2f); +} +void CXFA_TextLayout::InitBreak(IFDE_CSSComputedStyle* pStyle, + FDE_CSSDISPLAY eDisplay, + FX_FLOAT fLineWidth, + IFDE_XMLNode* pXMLNode, + IFDE_CSSComputedStyle* pParentStyle) { + if (pStyle == NULL) { + InitBreak(fLineWidth); + return; + } + IFDE_CSSParagraphStyle* pParaStyle = pStyle->GetParagraphStyles(); + if (eDisplay == FDE_CSSDISPLAY_Block || eDisplay == FDE_CSSDISPLAY_ListItem) { + int32_t iAlign = FX_RTFLINEALIGNMENT_Left; + switch (pParaStyle->GetTextAlign()) { + case FDE_CSSTEXTALIGN_Right: + iAlign = FX_RTFLINEALIGNMENT_Right; + break; + case FDE_CSSTEXTALIGN_Center: + iAlign = FX_RTFLINEALIGNMENT_Center; + break; + case FDE_CSSTEXTALIGN_Justify: + iAlign = FX_RTFLINEALIGNMENT_Justified; + break; + case FDE_CSSTEXTALIGN_JustifyAll: + iAlign = FX_RTFLINEALIGNMENT_Distributed; + break; + default: + break; + } + m_pBreak->SetAlignment(iAlign); + FX_FLOAT fStart = 0; + const FDE_CSSRECT* pRect = pStyle->GetBoundaryStyles()->GetMarginWidth(); + const FDE_CSSRECT* pPaddingRect = + pStyle->GetBoundaryStyles()->GetPaddingWidth(); + if (pRect != NULL) { + fStart = pRect->left.GetValue(); + fLineWidth -= pRect->right.GetValue(); + if (pPaddingRect != NULL) { + fStart += pPaddingRect->left.GetValue(); + fLineWidth -= pPaddingRect->right.GetValue(); + } + if (eDisplay == FDE_CSSDISPLAY_ListItem) { + const FDE_CSSRECT* pParRect = + pParentStyle->GetBoundaryStyles()->GetMarginWidth(); + const FDE_CSSRECT* pParPaddingRect = + pParentStyle->GetBoundaryStyles()->GetPaddingWidth(); + if (pParRect != NULL) { + fStart += pParRect->left.GetValue(); + fLineWidth -= pParRect->right.GetValue(); + if (pParPaddingRect != NULL) { + 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->GetBoundaryStyles()->SetMarginWidth(pNewRect); + } + } + m_pBreak->SetLineBoundary(fStart, fLineWidth); + FX_FLOAT fIndent = pParaStyle->GetTextIndent().GetValue(); + if (fIndent > 0) { + fStart += fIndent; + } + m_pBreak->SetLineStartPos(fStart); + m_pBreak->SetTabWidth(m_textParser.GetTabInterval(pStyle)); + if (m_pTabstopContext == NULL) { + m_pTabstopContext = new CXFA_TextTabstopsContext; + } + m_textParser.GetTabstops(pStyle, m_pTabstopContext); + for (int32_t i = 0; i < m_pTabstopContext->m_iTabCount; i++) { + XFA_TABSTOPS* pTab = m_pTabstopContext->m_tabstops.GetDataPtr(i); + m_pBreak->AddPositionedTab(pTab->fTabstops); + } + } + FX_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(pParaStyle->GetLetterSpacing().GetValue()); +} +int32_t CXFA_TextLayout::GetText(CFX_WideString& wsText) { + GetTextDataNode(); + wsText.Empty(); + if (m_bRichText) { + } else { + wsText = m_pTextDataNode->GetContent(); + } + return wsText.GetLength(); +} +FX_FLOAT CXFA_TextLayout::GetLayoutHeight() { + if (m_pLoader == NULL) { + return 0; + } + int32_t iCount = m_pLoader->m_lineHeights.GetSize(); + if (iCount == 0 && m_pLoader->m_fWidth > 0) { + CFX_SizeF szMax, szDef; + szMax.Set(m_pLoader->m_fWidth, m_pLoader->m_fHeight); + szDef.Set(0, 0); + m_pLoader->m_bSaveLineHeight = TRUE; + m_pLoader->m_fLastPos = 0; + CalcSize(szMax, szMax, szDef); + m_pLoader->m_bSaveLineHeight = FALSE; + return szDef.y; + } + FX_FLOAT fHeight = m_pLoader->m_fHeight; + if (fHeight < 0.1f) { + fHeight = 0; + for (int32_t i = 0; i < iCount; i++) { + fHeight += m_pLoader->m_lineHeights.ElementAt(i); + } + } + return fHeight; +} +FX_FLOAT CXFA_TextLayout::StartLayout(FX_FLOAT fWidth) { + if (m_pLoader == NULL) { + m_pLoader = new CXFA_LoaderContext; + } + if (fWidth < 0 || (m_pLoader->m_fWidth > -1 && + FXSYS_fabs(fWidth - m_pLoader->m_fWidth) > 0)) { + m_pLoader->m_lineHeights.RemoveAll(); + m_Blocks.RemoveAll(); + Unload(); + m_pLoader->m_fStartLineOffset = 0; + } + m_pLoader->m_fWidth = fWidth; + if (fWidth < 0) { + CFX_SizeF szMax, szDef; + szMax.Set(0, 0); + szDef.Set(0, 0); + m_pLoader->m_bSaveLineHeight = TRUE; + m_pLoader->m_fLastPos = 0; + CalcSize(szMax, szMax, szDef); + m_pLoader->m_bSaveLineHeight = FALSE; + fWidth = szDef.x; + } + return fWidth; +} +FX_BOOL CXFA_TextLayout::DoLayout(int32_t iBlockIndex, + FX_FLOAT& fCalcHeight, + FX_FLOAT fContentAreaHeight, + FX_FLOAT fTextHeight) { + if (m_pLoader == NULL) { + return FALSE; + } + int32_t iBlockCount = m_Blocks.GetSize(); + FX_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.GetVAlgin(m_pTextProvider); + if (iAlign == XFA_ATTRIBUTEENUM_Middle) { + fHeight /= 2.0f; + } else if (iAlign != XFA_ATTRIBUTEENUM_Bottom) { + fHeight = 0; + } + m_pLoader->m_fStartLineOffset = fHeight; + } + } + FX_FLOAT fLinePos = m_pLoader->m_fStartLineOffset; + int32_t iLineIndex = 0; + if (iBlockCount > 1) { + if (iBlockCount >= (iBlockIndex + 1) * 2) { + iLineIndex = m_Blocks.ElementAt(iBlockIndex * 2); + } else { + iLineIndex = m_Blocks.ElementAt(iBlockCount - 1) + + m_Blocks.ElementAt(iBlockCount - 2); + } + if (m_pLoader->m_BlocksHeight.GetSize() > 0) { + for (int32_t i = 0; i < iBlockIndex; i++) { + fLinePos -= m_pLoader->m_BlocksHeight.ElementAt(i * 2 + 1); + } + } + } + int32_t iCount = m_pLoader->m_lineHeights.GetSize(); + int32_t i = 0; + for (i = iLineIndex; i < iCount; i++) { + FX_FLOAT fLineHeight = m_pLoader->m_lineHeights.ElementAt(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.SetAt(iBlockIndex * 2, iLineIndex); + m_Blocks.SetAt(iBlockIndex * 2 + 1, i - iLineIndex); + } else { + m_Blocks.Add(iLineIndex); + m_Blocks.Add(i - iLineIndex); + } + if (i == iLineIndex) { + if (fCalcHeight <= fLinePos) { + if (m_pLoader->m_BlocksHeight.GetSize() > iBlockIndex * 2 && + (m_pLoader->m_BlocksHeight.GetAt(iBlockIndex * 2) == + iBlockIndex)) { + m_pLoader->m_BlocksHeight.SetAt(iBlockIndex * 2 + 1, fCalcHeight); + } else { + m_pLoader->m_BlocksHeight.Add((FX_FLOAT)iBlockIndex); + m_pLoader->m_BlocksHeight.Add(fCalcHeight); + } + } + return TRUE; + } + fCalcHeight = fLinePos; + return TRUE; + } + fLinePos += fLineHeight; + } + return FALSE; +} +int32_t CXFA_TextLayout::CountBlocks() const { + int32_t iCount = m_Blocks.GetSize() / 2; + return iCount > 0 ? iCount : 1; +} +FX_BOOL CXFA_TextLayout::CalcSize(const CFX_SizeF& minSize, + const CFX_SizeF& maxSize, + CFX_SizeF& defaultSize) { + defaultSize.x = maxSize.x; + if (defaultSize.x < 1) { + defaultSize.x = 0xFFFF; + } + if (m_pBreak != NULL) { + m_pBreak->Release(); + } + m_pBreak = CreateBreak(FALSE); + FX_FLOAT fLinePos = 0; + m_iLines = 0; + m_fMaxWidth = 0; + Loader(defaultSize, fLinePos, FALSE); + if (fLinePos < 0.1f) { + fLinePos = m_textParser.GetFontSize(m_pTextProvider, NULL); + } + if (m_pTabstopContext) { + delete m_pTabstopContext; + m_pTabstopContext = NULL; + } + defaultSize.Set(m_fMaxWidth, fLinePos); + return TRUE; +} +FX_BOOL CXFA_TextLayout::Layout(const CFX_SizeF& size, FX_FLOAT* fHeight) { + if (size.x < 1) { + return FALSE; + } + Unload(); + m_pBreak = CreateBreak(TRUE); + if (m_pLoader != NULL) { + m_pLoader->m_iTotalLines = -1; + m_pLoader->m_iChar = 0; + } + m_iLines = 0; + FX_FLOAT fLinePos = 0; + Loader(size, fLinePos, TRUE); + UpdateAlign(size.y, fLinePos); + if (m_pTabstopContext) { + delete m_pTabstopContext; + m_pTabstopContext = NULL; + } + if (fHeight) { + *fHeight = fLinePos; + } + return TRUE; +} +FX_BOOL CXFA_TextLayout::Layout(int32_t iBlock) { + if (m_pLoader == NULL || iBlock < 0 || iBlock >= CountBlocks()) { + return FALSE; + } + if (m_pLoader->m_fWidth < 1) { + return FALSE; + } + m_pLoader->m_iTotalLines = -1; + m_iLines = 0; + FX_FLOAT fLinePos = 0; + CXFA_Node* pNode = NULL; + CFX_SizeF szText; + szText.Set(m_pLoader->m_fWidth, m_pLoader->m_fHeight); + int32_t iCount = m_Blocks.GetSize(); + int32_t iBlocksHeightCount = m_pLoader->m_BlocksHeight.GetSize(); + 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.ElementAt(i * 2 + 1); + } + m_pLoader->m_iChar = 0; + if (iCount > 1) { + m_pLoader->m_iTotalLines = m_Blocks.ElementAt(iBlock * 2 + 1); + } + Loader(szText, fLinePos, TRUE); + if (iCount == 0 && m_pLoader->m_fStartLineOffset < 0.1f) { + UpdateAlign(szText.y, fLinePos); + } + } else if (m_pTextDataNode != NULL) { + iBlock *= 2; + if (iBlock < iCount - 2) { + m_pLoader->m_iTotalLines = m_Blocks.ElementAt(iBlock + 1); + } + m_pBreak->Reset(); + if (m_bRichText) { + IFDE_XMLNode* pContainerNode = GetXMLContainerNode(); + if (!pContainerNode) { + return TRUE; + } + IFDE_XMLNode* pXMLNode = m_pLoader->m_pXMLNode; + if (pXMLNode == NULL) { + return TRUE; + } + IFDE_XMLNode* pSaveXMLNode = m_pLoader->m_pXMLNode; + for (; pXMLNode; + pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling)) { + FX_BOOL bFlag = LoadRichText(pXMLNode, szText, fLinePos, + m_pLoader->m_pParentStyle, TRUE); + if (!bFlag) { + break; + } + } + while (pXMLNode == NULL) { + pXMLNode = pSaveXMLNode->GetNodeItem(IFDE_XMLNode::Parent); + if (pXMLNode == pContainerNode) { + break; + } + FX_BOOL bFlag = + LoadRichText(pXMLNode, szText, fLinePos, m_pLoader->m_pParentStyle, + TRUE, NULL, FALSE); + if (!bFlag) { + break; + } + pSaveXMLNode = pXMLNode; + pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling); + if (!pXMLNode) { + continue; + } + for (; pXMLNode; + pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling)) { + FX_BOOL bFlag = LoadRichText(pXMLNode, szText, fLinePos, + m_pLoader->m_pParentStyle, TRUE); + if (!bFlag) { + break; + } + } + } + } else { + pNode = m_pLoader->m_pNode; + if (pNode == NULL) { + return TRUE; + } + LoadText(pNode, szText, fLinePos, TRUE); + } + } + if (iBlock == iCount) { + if (m_pTabstopContext != NULL) { + delete m_pTabstopContext; + m_pTabstopContext = NULL; + } + if (m_pLoader != NULL) { + delete m_pLoader; + m_pLoader = NULL; + } + } + return TRUE; +} +void CXFA_TextLayout::ItemBlocks(const CFX_RectF& rtText, int32_t iBlockIndex) { + if (!m_pLoader) { + return; + } + int32_t iCountHeight = m_pLoader->m_lineHeights.GetSize(); + if (iCountHeight == 0) { + return; + } + FX_BOOL bEndItem = TRUE; + int32_t iBlockCount = m_Blocks.GetSize(); + FX_FLOAT fLinePos = m_pLoader->m_fStartLineOffset; + int32_t iLineIndex = 0; + if (iBlockIndex > 0) { + int32_t iBlockHeightCount = m_pLoader->m_BlocksHeight.GetSize(); + iBlockHeightCount /= 2; + if (iBlockHeightCount >= iBlockIndex) { + for (int32_t i = 0; i < iBlockIndex; i++) { + fLinePos -= m_pLoader->m_BlocksHeight.ElementAt(i * 2 + 1); + } + } else { + fLinePos = 0; + } + iLineIndex = m_Blocks.ElementAt(iBlockCount - 1) + + m_Blocks.ElementAt(iBlockCount - 2); + } + int32_t i = 0; + for (i = iLineIndex; i < iCountHeight; i++) { + FX_FLOAT fLineHeight = m_pLoader->m_lineHeights.ElementAt(i); + if (fLinePos + fLineHeight - rtText.height > 0.001) { + m_Blocks.Add(iLineIndex); + m_Blocks.Add(i - iLineIndex); + bEndItem = FALSE; + break; + } + fLinePos += fLineHeight; + } + if (iCountHeight > 0 && (i - iLineIndex) > 0 && bEndItem) { + m_Blocks.Add(iLineIndex); + m_Blocks.Add(i - iLineIndex); + } +} +FX_BOOL CXFA_TextLayout::DrawString(CFX_RenderDevice* pFxDevice, + const CFX_Matrix& tmDoc2Device, + const CFX_RectF& rtClip, + int32_t iBlock) { + IFDE_RenderDevice* pDevice = IFDE_RenderDevice::Create(pFxDevice); + if (pDevice == NULL) { + return FALSE; + } + FDE_HDEVICESTATE state = pDevice->SaveState(); + pDevice->SetClipRect(rtClip); + IFDE_SolidBrush* pSolidBrush = + (IFDE_SolidBrush*)IFDE_Brush::Create(FDE_BRUSHTYPE_Solid); + IFDE_Pen* pPen = IFDE_Pen::Create(); + FXSYS_assert(pDevice != NULL && pSolidBrush != NULL && pPen != NULL); + if (m_pieceLines.GetSize() == 0) { + int32_t iBlockCount = CountBlocks(); + for (int32_t i = 0; i < iBlockCount; i++) { + Layout(i); + } + } + FXTEXT_CHARPOS* pCharPos = NULL; + int32_t iCharCount = 0; + int32_t iLineStart = 0; + int32_t iPieceLines = m_pieceLines.GetSize(); + int32_t iCount = m_Blocks.GetSize(); + if (iCount > 0) { + iBlock *= 2; + if (iBlock < iCount) { + iLineStart = m_Blocks.ElementAt(iBlock); + iPieceLines = m_Blocks.ElementAt(iBlock + 1); + } else { + iPieceLines = 0; + } + } + for (int32_t i = 0; i < iPieceLines; i++) { + if (i + iLineStart >= m_pieceLines.GetSize()) { + break; + } + CXFA_PieceLine* pPieceLine = m_pieceLines.GetAt(i + iLineStart); + int32_t iPieces = pPieceLine->m_textPieces.GetSize(); + int32_t j = 0; + for (j = 0; j < iPieces; j++) { + XFA_LPCTEXTPIECE pPiece = pPieceLine->m_textPieces.GetAt(j); + int32_t iChars = pPiece->iChars; + if (iCharCount < iChars) { + FX_Free(pCharPos); + pCharPos = FX_Alloc(FXTEXT_CHARPOS, iChars); + iCharCount = iChars; + } + FXSYS_memset(pCharPos, 0, iCharCount * sizeof(FXTEXT_CHARPOS)); + RenderString(pDevice, pSolidBrush, pPieceLine, j, pCharPos, tmDoc2Device); + } + for (j = 0; j < iPieces; j++) { + RenderPath(pDevice, pPen, pPieceLine, j, pCharPos, tmDoc2Device); + } + } + pDevice->RestoreState(state); + FX_Free(pCharPos); + pSolidBrush->Release(); + pPen->Release(); + pDevice->Release(); + return iPieceLines; +} +void CXFA_TextLayout::UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom) { + fHeight -= fBottom; + if (fHeight < 0.1f) { + return; + } + switch (m_textParser.GetVAlgin(m_pTextProvider)) { + case XFA_ATTRIBUTEENUM_Middle: + fHeight /= 2.0f; + break; + case XFA_ATTRIBUTEENUM_Bottom: + break; + default: + return; + } + int32_t iCount = m_pieceLines.GetSize(); + for (int32_t i = 0; i < iCount; i++) { + CXFA_PieceLine* pPieceLine = m_pieceLines.GetAt(i); + int32_t iPieces = pPieceLine->m_textPieces.GetSize(); + for (int32_t j = 0; j < iPieces; j++) { + XFA_LPTEXTPIECE pPiece = pPieceLine->m_textPieces.GetAt(j); + CFX_RectF& rect = pPiece->rtPiece; + rect.top += fHeight; + } + } +} +FX_BOOL CXFA_TextLayout::Loader(const CFX_SizeF& szText, + FX_FLOAT& fLinePos, + FX_BOOL bSavePieces) { + if (m_pAllocator == NULL) { + m_pAllocator = FX_CreateAllocator(FX_ALLOCTYPE_Static, 256, 0); + } + GetTextDataNode(); + if (m_pTextDataNode == NULL) { + return TRUE; + } + if (m_bRichText) { + IFDE_XMLNode* pXMLContainer = GetXMLContainerNode(); + if (pXMLContainer) { + if (!m_textParser.IsParsed()) { + m_textParser.DoParse(pXMLContainer, m_pTextProvider); + } + IFDE_CSSComputedStyle* pRootStyle = + m_textParser.CreateRootStyle(m_pTextProvider); + LoadRichText(pXMLContainer, szText, fLinePos, pRootStyle, bSavePieces); + pRootStyle->Release(); + } + } else { + LoadText(m_pTextDataNode, szText, fLinePos, bSavePieces); + } + return TRUE; +} +void CXFA_TextLayout::LoadText(CXFA_Node* pNode, + const CFX_SizeF& szText, + FX_FLOAT& fLinePos, + FX_BOOL bSavePieces) { + InitBreak(szText.x); + CXFA_Para para = m_pTextProvider->GetParaNode(); + FX_FLOAT fSpaceAbove = 0; + if (para.IsExistInXML()) { + 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" "); + FX_BOOL bRet = AppendChar(wsText, fLinePos, fSpaceAbove, bSavePieces); + if (bRet && m_pLoader != NULL) { + m_pLoader->m_pNode = pNode; + } else { + EndBreak(FX_RTFBREAK_ParagraphBreak, fLinePos, bSavePieces); + } +} +FX_BOOL CXFA_TextLayout::LoadRichText(IFDE_XMLNode* pXMLNode, + const CFX_SizeF& szText, + FX_FLOAT& fLinePos, + IFDE_CSSComputedStyle* pParentStyle, + FX_BOOL bSavePieces, + CXFA_LinkUserData* pLinkData, + FX_BOOL bEndBreak, + FX_BOOL bIsOl, + int32_t iLiCount) { + if (pXMLNode == NULL) { + return FALSE; + } + CXFA_TextParseContext* pContext = + m_textParser.GetParseContextFromMap(pXMLNode); + FDE_CSSDISPLAY eDisplay = FDE_CSSDISPLAY_None; + FX_BOOL bContentNode = FALSE; + FX_FLOAT fSpaceBelow = 0; + IFDE_CSSComputedStyle* pStyle = NULL; + CFX_WideString wsName; + if (bEndBreak) { + FX_BOOL bCurOl = FALSE; + FX_BOOL bCurLi = FALSE; + IFDE_XMLElement* pElement = NULL; + if (pContext != NULL) { + if (m_bBlockContinue || + (m_pLoader && pXMLNode == m_pLoader->m_pXMLNode)) { + m_bBlockContinue = TRUE; + } + if (pXMLNode->GetType() == FDE_XMLNODE_Text) { + bContentNode = TRUE; + } else if (pXMLNode->GetType() == FDE_XMLNODE_Element) { + pElement = (IFDE_XMLElement*)pXMLNode; + pElement->GetLocalTagName(wsName); + } + if (wsName == FX_WSTRC(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); + InitBreak(bContentNode ? pParentStyle : pStyle, eDisplay, szText.x, + pXMLNode, pParentStyle); + if ((eDisplay == FDE_CSSDISPLAY_Block || + eDisplay == FDE_CSSDISPLAY_ListItem) && + (pStyle != NULL) && + (wsName.IsEmpty() || + (wsName != FX_WSTRC(L"body") && wsName != FX_WSTRC(L"html") && + wsName != FX_WSTRC(L"ol") && wsName != FX_WSTRC(L"ul")))) { + const FDE_CSSRECT* pRect = + pStyle->GetBoundaryStyles()->GetMarginWidth(); + if (pRect) { + fLinePos += pRect->top.GetValue(); + fSpaceBelow = pRect->bottom.GetValue(); + } + } + if (wsName == FX_WSTRC(L"a")) { + CFX_WideString wsLinkContent; + FXSYS_assert(pElement); + pElement->GetString(FX_WSTRC(L"href").GetPtr(), wsLinkContent); + if (!wsLinkContent.IsEmpty()) { + pLinkData = FDE_NewWith(m_pAllocator) CXFA_LinkUserData( + m_pAllocator, + wsLinkContent.GetBuffer(wsLinkContent.GetLength())); + wsLinkContent.ReleaseBuffer(wsLinkContent.GetLength()); + } + } + int32_t iTabCount = + m_textParser.CountTabs(bContentNode ? pParentStyle : pStyle); + FX_BOOL bSpaceRun = + m_textParser.IsSpaceRun(bContentNode ? pParentStyle : pStyle); + CFX_WideString wsText; + if (bContentNode && iTabCount == 0) { + ((IFDE_XMLText*)pXMLNode)->GetText(wsText); + } else if (wsName == FX_WSTRC(L"br")) { + wsText = L'\n'; + } else if (wsName == FX_WSTRC(L"li")) { + bCurLi = TRUE; + if (bIsOl) { + wsText.Format(L"%d. ", iLiCount); + } else { + wsText = 0x00B7 + FX_WSTRC(L" "); + } + } 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) + ; + else { + m_pLoader->m_dwFlags &= ~XFA_LOADERCNTXTFLG_FILTERSPACE; + } + } + if (wsText.GetLength() > 0) { + if (m_pLoader == NULL || m_pLoader->m_iChar == 0) { + if (pLinkData) { + pLinkData->AddRef(); + } + CXFA_TextUserData* pUserData = FDE_NewWith(m_pAllocator) + CXFA_TextUserData(m_pAllocator, + 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; + } + if (pStyle != NULL) { + pStyle->Release(); + } + return FALSE; + } + return TRUE; + } + } + } + } + FX_BOOL ret = TRUE; + for (IFDE_XMLNode* pChildNode = + pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild); + pChildNode; + pChildNode = pChildNode->GetNodeItem(IFDE_XMLNode::NextSibling)) { + if (bCurOl) { + iLiCount++; + } + ret = LoadRichText(pChildNode, szText, fLinePos, + pContext ? pStyle : pParentStyle, bSavePieces, + pLinkData, TRUE, bIsOl, iLiCount); + if (ret == FALSE) { + return FALSE; + } + } + if (m_pLoader) { + if (FDE_CSSDISPLAY_Block == eDisplay) { + m_pLoader->m_dwFlags |= XFA_LOADERCNTXTFLG_FILTERSPACE; + } + } + if (bCurLi) { + EndBreak(FX_RTFBREAK_LineBreak, fLinePos, bSavePieces); + } + } else { + if (pContext != NULL) { + eDisplay = pContext->GetDisplay(); + } + } + if (m_bBlockContinue) { + if (pContext != NULL && !bContentNode) { + FX_DWORD dwStatus = (eDisplay == FDE_CSSDISPLAY_Block) + ? FX_RTFBREAK_ParagraphBreak + : FX_RTFBREAK_PieceBreak; + EndBreak(dwStatus, fLinePos, bSavePieces); + if (eDisplay == FDE_CSSDISPLAY_Block) { + fLinePos += fSpaceBelow; + if (m_pTabstopContext) { + m_pTabstopContext->RemoveAll(); + } + } + if (wsName == FX_WSTRC(L"a")) { + if (pLinkData) { + pLinkData->Release(); + pLinkData = nullptr; + } + } + if (IsEnd(bSavePieces)) { + if (pStyle) { + pStyle->Release(); + } + if (m_pLoader && m_pLoader->m_iTotalLines > -1) { + m_pLoader->m_pXMLNode = + pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling); + m_pLoader->m_pParentStyle = pParentStyle; + } + return FALSE; + } + } + } + if (pStyle != NULL) { + pStyle->Release(); + } + return TRUE; +} +FX_BOOL CXFA_TextLayout::AppendChar(const CFX_WideString& wsText, + FX_FLOAT& fLinePos, + FX_FLOAT fSpaceAbove, + FX_BOOL bSavePieces) { + FX_DWORD dwStatus = 0; + 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++) { + FX_WCHAR wch = wsText.GetAt(i); + if (wch == 0xA0) { + wch = 0x20; + } + if ((dwStatus = m_pBreak->AppendChar(wch)) > FX_RTFBREAK_PieceBreak) { + AppendTextLine(dwStatus, fLinePos, bSavePieces); + if (IsEnd(bSavePieces)) { + if (m_pLoader != NULL) { + m_pLoader->m_iChar = i; + } + return TRUE; + } + if (dwStatus == FX_RTFBREAK_ParagraphBreak && m_bRichText) { + fLinePos += fSpaceAbove; + } + } + } + if (m_pLoader) { + m_pLoader->m_iChar = 0; + } + return FALSE; +} +FX_BOOL CXFA_TextLayout::IsEnd(FX_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; + } + FX_WCHAR* psz = wsText.GetBuffer(iLen); + int32_t iTrimLeft = 0; + FX_WCHAR 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(FX_DWORD dwStatus, + FX_FLOAT& fLinePos, + FX_BOOL bSavePieces) { + dwStatus = m_pBreak->EndBreak(dwStatus); + if (dwStatus > FX_RTFBREAK_PieceBreak) { + AppendTextLine(dwStatus, fLinePos, bSavePieces, TRUE); + } +} +void CXFA_TextLayout::DoTabstops(IFDE_CSSComputedStyle* pStyle, + CXFA_PieceLine* pPieceLine) { + if (m_pTabstopContext == NULL || m_pTabstopContext->m_iTabCount == 0) { + return; + } + if (pStyle == NULL || pPieceLine == NULL) { + return; + } + int32_t iPieces = pPieceLine->m_textPieces.GetSize(); + if (iPieces == 0) { + return; + } + XFA_LPTEXTPIECE pPiece = pPieceLine->m_textPieces.GetAt(iPieces - 1); + int32_t& iTabstopsIndex = m_pTabstopContext->m_iTabIndex; + int32_t iCount = m_textParser.CountTabs(pStyle); + if (iTabstopsIndex > m_pTabstopContext->m_iTabCount - 1) { + return; + } + if (iCount > 0) { + iTabstopsIndex++; + m_pTabstopContext->m_bTabstops = TRUE; + FX_FLOAT fRight = 0; + if (iPieces > 1) { + XFA_LPTEXTPIECE p = pPieceLine->m_textPieces.GetAt(iPieces - 2); + fRight = p->rtPiece.right(); + } + m_pTabstopContext->m_fTabWidth = + pPiece->rtPiece.width + pPiece->rtPiece.left - fRight; + } else if (iTabstopsIndex > -1) { + FX_FLOAT fLeft = 0; + if (m_pTabstopContext->m_bTabstops) { + XFA_TABSTOPS* pTabstops = + m_pTabstopContext->m_tabstops.GetDataPtr(iTabstopsIndex); + FX_DWORD dwAlgin = pTabstops->dwAlign; + if (dwAlgin == FX_HashCode_String_GetW(L"center", 6)) { + fLeft = pPiece->rtPiece.width / 2.0f; + } else if (dwAlgin == FX_HashCode_String_GetW(L"right", 5) || + dwAlgin == FX_HashCode_String_GetW(L"before", 6)) { + fLeft = pPiece->rtPiece.width; + } else if (dwAlgin == FX_HashCode_String_GetW(L"decimal", 7)) { + int32_t iChars = pPiece->iChars; + for (int32_t i = 0; i < iChars; i++) { + if (pPiece->pszText[i] == L'.') { + break; + } + fLeft += pPiece->pWidths[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(FX_DWORD dwStatus, + FX_FLOAT& fLinePos, + FX_BOOL bSavePieces, + FX_BOOL bEndBreak) { + int32_t iPieces = m_pBreak->CountBreakPieces(); + if (iPieces < 1) { + return; + } + IFDE_CSSComputedStyle* pStyle = NULL; + if (bSavePieces) { + CXFA_PieceLine* pPieceLine = FDE_NewWith(m_pAllocator) CXFA_PieceLine; + m_pieceLines.Add(pPieceLine); + if (m_pTabstopContext) { + m_pTabstopContext->Reset(); + } + FX_FLOAT fLineStep = 0, fBaseLine = 0; + int32_t i = 0; + for (i = 0; i < iPieces; i++) { + const CFX_RTFPiece* pPiece = m_pBreak->GetBreakPiece(i); + CXFA_TextUserData* pUserData = (CXFA_TextUserData*)pPiece->m_pUserData; + if (pUserData != NULL) { + pStyle = pUserData->m_pStyle; + } + FX_FLOAT fVerScale = pPiece->m_iVerticalScale / 100.0f; + XFA_LPTEXTPIECE pTP = + (XFA_LPTEXTPIECE)m_pAllocator->Alloc(sizeof(XFA_TEXTPIECE)); + pTP->pszText = + (FX_WCHAR*)m_pAllocator->Alloc(pPiece->m_iChars * sizeof(FX_WCHAR)); + pTP->pWidths = + (int32_t*)m_pAllocator->Alloc(pPiece->m_iChars * sizeof(int32_t)); + pTP->iChars = pPiece->m_iChars; + pPiece->GetString(pTP->pszText); + pPiece->GetWidths(pTP->pWidths); + pTP->iBidiLevel = pPiece->m_iBidiLevel; + pTP->iHorScale = pPiece->m_iHorizontalScale; + pTP->iVerScale = pPiece->m_iVerticalScale; + m_textParser.GetUnderline(m_pTextProvider, pStyle, pTP->iUnderline, + pTP->iPeriod); + m_textParser.GetLinethrough(m_pTextProvider, pStyle, pTP->iLineThrough); + pTP->dwColor = m_textParser.GetColor(m_pTextProvider, pStyle); + pTP->pFont = m_textParser.GetFont(m_pTextProvider, pStyle); + pTP->fFontSize = m_textParser.GetFontSize(m_pTextProvider, pStyle); + pTP->rtPiece.left = pPiece->m_iStartPos / 20000.0f; + pTP->rtPiece.width = pPiece->m_iWidth / 20000.0f; + pTP->rtPiece.height = (FX_FLOAT)pPiece->m_iFontSize * fVerScale / 20.0f; + FX_FLOAT fBaseLineTemp = + m_textParser.GetBaseline(m_pTextProvider, pStyle); + pTP->rtPiece.top = fBaseLineTemp; + pPieceLine->m_textPieces.Add(pTP); + FX_FLOAT fLineHeight = m_textParser.GetLineHeight( + m_pTextProvider, pStyle, m_iLines == 0, fVerScale); + if (fBaseLineTemp > 0) { + FX_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); + if (pUserData != NULL && pUserData->m_pLinkData != NULL) { + pUserData->m_pLinkData->AddRef(); + pTP->pLinkData = pUserData->m_pLinkData; + } else { + pTP->pLinkData = NULL; + } + DoTabstops(pStyle, pPieceLine); + } + for (i = 0; i < iPieces; i++) { + XFA_LPTEXTPIECE pTP = pPieceLine->m_textPieces.GetAt(i); + FX_FLOAT& fTop = pTP->rtPiece.top; + FX_FLOAT fBaseLineTemp = fTop; + fTop = fLinePos + fLineStep - pTP->rtPiece.height - fBaseLineTemp; + fTop = std::max(0.0f, fTop); + } + fLinePos += fLineStep + fBaseLine; + } else { + FX_FLOAT fLineStep = 0; + FX_FLOAT fLineWidth = 0; + for (int32_t i = 0; i < iPieces; i++) { + const CFX_RTFPiece* pPiece = m_pBreak->GetBreakPiece(i); + CXFA_TextUserData* pUserData = (CXFA_TextUserData*)pPiece->m_pUserData; + if (pUserData != NULL) { + pStyle = pUserData->m_pStyle; + } + FX_FLOAT fVerScale = pPiece->m_iVerticalScale / 100.0f; + FX_FLOAT fBaseLine = m_textParser.GetBaseline(m_pTextProvider, pStyle); + FX_FLOAT fLineHeight = m_textParser.GetLineHeight( + m_pTextProvider, pStyle, m_iLines == 0, fVerScale); + if (fBaseLine > 0) { + FX_FLOAT fLineHeightTmp = + fBaseLine + (FX_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) { + FX_FLOAT fHeight = fLinePos - m_pLoader->m_fLastPos; + m_pLoader->m_fLastPos = fLinePos; + m_pLoader->m_lineHeights.Add(fHeight); + } + } + if (pStyle) { + pStyle->AddRef(); + } + m_pBreak->ClearBreakPieces(); + if (dwStatus == FX_RTFBREAK_ParagraphBreak) { + m_pBreak->Reset(); + if (!pStyle && bEndBreak) { + CXFA_Para para = m_pTextProvider->GetParaNode(); + if (para.IsExistInXML()) { + FX_FLOAT fStartPos = para.GetMarginLeft(); + FX_FLOAT fIndent = para.GetTextIndent(); + if (fIndent > 0) { + fStartPos += fIndent; + } + FX_FLOAT fSpaceBelow = para.GetSpaceBelow(); + if (fSpaceBelow < 0.1f) { + fSpaceBelow = 0; + } + m_pBreak->SetLineStartPos(fStartPos); + fLinePos += fSpaceBelow; + } + } + } + if (pStyle) { + FX_FLOAT fStart = 0; + const FDE_CSSRECT* pRect = pStyle->GetBoundaryStyles()->GetMarginWidth(); + if (pRect) { + fStart = pRect->left.GetValue(); + } + FX_FLOAT fTextIndent = + pStyle->GetParagraphStyles()->GetTextIndent().GetValue(); + if (fTextIndent < 0) { + fStart -= fTextIndent; + } + m_pBreak->SetLineStartPos(fStart); + pStyle->Release(); + } + m_iLines++; +} +void CXFA_TextLayout::RenderString(IFDE_RenderDevice* pDevice, + IFDE_SolidBrush* pBrush, + CXFA_PieceLine* pPieceLine, + int32_t iPiece, + FXTEXT_CHARPOS* pCharPos, + const CFX_Matrix& tmDoc2Device) { + XFA_LPCTEXTPIECE pPiece = pPieceLine->m_textPieces.GetAt(iPiece); + 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.Add(iCount); +} +void CXFA_TextLayout::RenderPath(IFDE_RenderDevice* pDevice, + IFDE_Pen* pPen, + CXFA_PieceLine* pPieceLine, + int32_t iPiece, + FXTEXT_CHARPOS* pCharPos, + const CFX_Matrix& tmDoc2Device) { + XFA_TEXTPIECE* pPiece = pPieceLine->m_textPieces.GetAt(iPiece); + FX_BOOL bNoUnderline = pPiece->iUnderline < 1 || pPiece->iUnderline > 2; + FX_BOOL bNoLineThrough = pPiece->iLineThrough < 1 || pPiece->iLineThrough > 2; + if (bNoUnderline && bNoLineThrough) { + return; + } + pPen->SetColor(pPiece->dwColor); + IFDE_Path* pPath = IFDE_Path::Create(); + int32_t iChars = GetDisplayPos(pPiece, pCharPos); + if (iChars > 0) { + CFX_PointF pt1, pt2; + FX_FLOAT fEndY = pCharPos[0].m_OriginY + 1.05f; + int32_t i = 0; + 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_OriginX; + 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_OriginX; + pt2.x = + pCharPos[iChars - 1].m_OriginX + + 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_OriginY - pPiece->rtPiece.height * 0.25f; + pt1.x = pCharPos[0].m_OriginX; + pt2.x = pCharPos[iChars - 1].m_OriginX + + pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f; + for (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)) { + goto XFA_RenderPathRet; + } + int32_t iCharsTmp = 0; + int32_t iPiecePrev = iPiece, iPieceNext = iPiece; + while (iPiecePrev > 0) { + iPiecePrev--; + iCharsTmp = pPieceLine->m_charCounts.GetAt(iPiecePrev); + if (iCharsTmp > 0) { + break; + } + } + if (iCharsTmp == 0) { + goto XFA_RenderPathRet; + } + iCharsTmp = 0; + int32_t iPieces = pPieceLine->m_textPieces.GetSize(); + while (iPieceNext < iPieces - 1) { + iPieceNext++; + iCharsTmp = pPieceLine->m_charCounts.GetAt(iPieceNext); + if (iCharsTmp > 0) { + break; + } + } + if (iCharsTmp == 0) { + goto XFA_RenderPathRet; + } + FX_FLOAT fOrgX = 0.0f, fEndX = 0.0f; + pPiece = pPieceLine->m_textPieces.GetAt(iPiecePrev); + iChars = GetDisplayPos(pPiece, pCharPos); + if (iChars < 1) { + goto XFA_RenderPathRet; + } + fOrgX = pCharPos[iChars - 1].m_OriginX + + pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f; + pPiece = pPieceLine->m_textPieces.GetAt(iPieceNext); + iChars = GetDisplayPos(pPiece, pCharPos); + if (iChars < 1) { + goto XFA_RenderPathRet; + } + fEndX = pCharPos[0].m_OriginX; + CFX_PointF pt1, pt2; + pt1.x = fOrgX, pt2.x = fEndX; + FX_FLOAT fEndY = pCharPos[0].m_OriginY + 1.05f; + int32_t i = 0; + for (i = 0; i < pPiece->iUnderline; i++) { + pt1.y = pt2.y = fEndY; + pPath->AddLine(pt1, pt2); + fEndY += 2.0f; + } + fEndY = pCharPos[0].m_OriginY - pPiece->rtPiece.height * 0.25f; + for (i = 0; i < pPiece->iLineThrough; i++) { + pt1.y = pt2.y = fEndY; + pPath->AddLine(pt1, pt2); + fEndY += 2.0f; + } + } + pDevice->DrawPath(pPen, 1, pPath, &tmDoc2Device); +XFA_RenderPathRet: + pPath->Release(); +} +int32_t CXFA_TextLayout::GetDisplayPos(XFA_LPCTEXTPIECE pPiece, + FXTEXT_CHARPOS* pCharPos, + FX_BOOL bCharCode) { + if (pPiece == NULL) { + return 0; + } + FX_RTFTEXTOBJ tr; + if (!ToRun(pPiece, tr)) { + return 0; + } + return m_pBreak->GetDisplayPos(&tr, pCharPos, bCharCode); +} +FX_BOOL CXFA_TextLayout::ToRun(XFA_LPCTEXTPIECE pPiece, FX_RTFTEXTOBJ& tr) { + int32_t iLength = pPiece->iChars; + if (iLength < 1) { + return FALSE; + } + tr.pStr = pPiece->pszText; + tr.pFont = pPiece->pFont; + tr.pRect = &pPiece->rtPiece; + tr.pWidths = pPiece->pWidths; + tr.iLength = iLength; + tr.fFontSize = pPiece->fFontSize; + tr.iBidiLevel = pPiece->iBidiLevel; + tr.iCharRotation = 0; + tr.wLineBreakChar = L'\n'; + tr.iVerticalScale = pPiece->iVerScale; + tr.dwLayoutStyles = FX_RTFLAYOUTSTYLE_ExpandTab; + tr.iHorizontalScale = pPiece->iHorScale; + return TRUE; +} |