summaryrefslogtreecommitdiff
path: root/xfa/fxfa/app
diff options
context:
space:
mode:
authorDan Sinclair <dsinclair@chromium.org>2017-01-10 16:37:32 -0500
committerChromium commit bot <commit-bot@chromium.org>2017-01-10 21:52:30 +0000
commit1f5d4988dcdac125e3e822d37c9086a5e4a3e224 (patch)
tree41fe47f62e1a76117022ed3774040608f1f00c7b /xfa/fxfa/app
parent0e6438e40a95702edb8327286c8253aa269c9826 (diff)
downloadpdfium-1f5d4988dcdac125e3e822d37c9086a5e4a3e224.tar.xz
Split xfa_textlayout apart.
This CL splits the xfa_texlayout.{cpp|h} files into individual class files. Minor reformatting was done in the new clasess. Change-Id: Id79ffcb8dca3fcf287a2e6dec78fd2b1f990a542 Reviewed-on: https://pdfium-review.googlesource.com/2162 Commit-Queue: dsinclair <dsinclair@chromium.org> Reviewed-by: Tom Sepez <tsepez@chromium.org>
Diffstat (limited to 'xfa/fxfa/app')
-rw-r--r--xfa/fxfa/app/cxfa_csstagprovider.cpp12
-rw-r--r--xfa/fxfa/app/cxfa_csstagprovider.h42
-rw-r--r--xfa/fxfa/app/cxfa_linkuserdata.cpp28
-rw-r--r--xfa/fxfa/app/cxfa_linkuserdata.h34
-rw-r--r--xfa/fxfa/app/cxfa_loadercontext.cpp22
-rw-r--r--xfa/fxfa/app/cxfa_loadercontext.h40
-rw-r--r--xfa/fxfa/app/cxfa_pieceline.cpp11
-rw-r--r--xfa/fxfa/app/cxfa_pieceline.h24
-rw-r--r--xfa/fxfa/app/cxfa_textlayout.cpp (renamed from xfa/fxfa/app/xfa_textlayout.cpp)1167
-rw-r--r--xfa/fxfa/app/cxfa_textlayout.h135
-rw-r--r--xfa/fxfa/app/cxfa_textparsecontext.cpp32
-rw-r--r--xfa/fxfa/app/cxfa_textparsecontext.h38
-rw-r--r--xfa/fxfa/app/cxfa_textparser.cpp659
-rw-r--r--xfa/fxfa/app/cxfa_textparser.h101
-rw-r--r--xfa/fxfa/app/cxfa_textparser_unittest.cpp (renamed from xfa/fxfa/app/xfa_textlayout_unittest.cpp)2
-rw-r--r--xfa/fxfa/app/cxfa_texttabstopscontext.cpp44
-rw-r--r--xfa/fxfa/app/cxfa_texttabstopscontext.h34
-rw-r--r--xfa/fxfa/app/cxfa_textuserdata.cpp51
-rw-r--r--xfa/fxfa/app/cxfa_textuserdata.h38
-rw-r--r--xfa/fxfa/app/xfa_ffdocview.cpp1
-rw-r--r--xfa/fxfa/app/xfa_fffield.cpp2
-rw-r--r--xfa/fxfa/app/xfa_ffnotify.cpp2
-rw-r--r--xfa/fxfa/app/xfa_ffpushbutton.cpp2
-rw-r--r--xfa/fxfa/app/xfa_fftext.cpp8
-rw-r--r--xfa/fxfa/app/xfa_fftextedit.cpp1
-rw-r--r--xfa/fxfa/app/xfa_ffwidget.cpp2
-rw-r--r--xfa/fxfa/app/xfa_ffwidgetacc.cpp1
-rw-r--r--xfa/fxfa/app/xfa_ffwidgetacc.h9
-rw-r--r--xfa/fxfa/app/xfa_textlayout.h354
-rw-r--r--xfa/fxfa/app/xfa_textpiece.cpp17
-rw-r--r--xfa/fxfa/app/xfa_textpiece.h39
31 files changed, 1633 insertions, 1319 deletions
diff --git a/xfa/fxfa/app/cxfa_csstagprovider.cpp b/xfa/fxfa/app/cxfa_csstagprovider.cpp
new file mode 100644
index 0000000000..ef5133e104
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_csstagprovider.cpp
@@ -0,0 +1,12 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/cxfa_csstagprovider.h"
+
+CXFA_CSSTagProvider::CXFA_CSSTagProvider()
+ : m_bTagAvailable(false), m_bContent(false) {}
+
+CXFA_CSSTagProvider::~CXFA_CSSTagProvider() {}
diff --git a/xfa/fxfa/app/cxfa_csstagprovider.h b/xfa/fxfa/app/cxfa_csstagprovider.h
new file mode 100644
index 0000000000..3c23784403
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_csstagprovider.h
@@ -0,0 +1,42 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_CXFA_CSSTAGPROVIDER_H_
+#define XFA_FXFA_APP_CXFA_CSSTAGPROVIDER_H_
+
+#include <map>
+
+#include "core/fxcrt/fx_string.h"
+
+class CXFA_CSSTagProvider {
+ public:
+ using AttributeMap = std::map<CFX_WideString, CFX_WideString>;
+
+ CXFA_CSSTagProvider();
+ ~CXFA_CSSTagProvider();
+
+ CFX_WideString GetTagName() { return m_wsTagName; }
+
+ AttributeMap::iterator begin() { return m_Attributes.begin(); }
+ AttributeMap::iterator end() { return m_Attributes.end(); }
+
+ bool empty() const { return m_Attributes.empty(); }
+
+ void SetTagNameObj(const CFX_WideString& wsName) { m_wsTagName = wsName; }
+ void SetAttribute(const CFX_WideString& wsAttr,
+ const CFX_WideString& wsValue) {
+ m_Attributes.insert({wsAttr, wsValue});
+ }
+
+ bool m_bTagAvailable;
+ bool m_bContent;
+
+ protected:
+ CFX_WideString m_wsTagName;
+ AttributeMap m_Attributes;
+};
+
+#endif // XFA_FXFA_APP_CXFA_CSSTAGPROVIDER_H_
diff --git a/xfa/fxfa/app/cxfa_linkuserdata.cpp b/xfa/fxfa/app/cxfa_linkuserdata.cpp
new file mode 100644
index 0000000000..62a2938d95
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_linkuserdata.cpp
@@ -0,0 +1,28 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/cxfa_linkuserdata.h"
+
+CXFA_LinkUserData::CXFA_LinkUserData(IFX_MemoryAllocator* pAllocator,
+ FX_WCHAR* pszText)
+ : m_pAllocator(pAllocator), m_dwRefCount(1), m_wsURLContent(pszText) {}
+
+CXFA_LinkUserData::~CXFA_LinkUserData() {}
+
+uint32_t CXFA_LinkUserData::Retain() {
+ return ++m_dwRefCount;
+}
+
+uint32_t CXFA_LinkUserData::Release() {
+ uint32_t dwRefCount = --m_dwRefCount;
+ if (dwRefCount <= 0)
+ FXTARGET_DeleteWith(CXFA_LinkUserData, m_pAllocator, this);
+ return dwRefCount;
+}
+
+const FX_WCHAR* CXFA_LinkUserData::GetLinkURL() {
+ return m_wsURLContent.c_str();
+}
diff --git a/xfa/fxfa/app/cxfa_linkuserdata.h b/xfa/fxfa/app/cxfa_linkuserdata.h
new file mode 100644
index 0000000000..d5ec14e17e
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_linkuserdata.h
@@ -0,0 +1,34 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_CXFA_LINKUSERDATA_H_
+#define XFA_FXFA_APP_CXFA_LINKUSERDATA_H_
+
+#include "core/fxcrt/fx_basic.h"
+#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/fx_system.h"
+#include "xfa/fgas/crt/fgas_memory.h"
+
+class IFX_MemoryAllocator;
+
+class CXFA_LinkUserData : public IFX_Retainable, public CFX_Target {
+ public:
+ CXFA_LinkUserData(IFX_MemoryAllocator* pAllocator, FX_WCHAR* pszText);
+ ~CXFA_LinkUserData() override;
+
+ // IFX_Retainable:
+ uint32_t Retain() override;
+ uint32_t Release() override;
+
+ const FX_WCHAR* GetLinkURL();
+
+ protected:
+ IFX_MemoryAllocator* m_pAllocator;
+ uint32_t m_dwRefCount;
+ CFX_WideString m_wsURLContent;
+};
+
+#endif // XFA_FXFA_APP_CXFA_LINKUSERDATA_H_
diff --git a/xfa/fxfa/app/cxfa_loadercontext.cpp b/xfa/fxfa/app/cxfa_loadercontext.cpp
new file mode 100644
index 0000000000..56ac71bfb4
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_loadercontext.cpp
@@ -0,0 +1,22 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/cxfa_loadercontext.h"
+
+CXFA_LoaderContext::CXFA_LoaderContext()
+ : m_bSaveLineHeight(false),
+ m_fWidth(0),
+ m_fHeight(0),
+ m_fLastPos(0),
+ m_fStartLineOffset(0),
+ m_iChar(0),
+ m_iTotalLines(-1),
+ m_pXMLNode(nullptr),
+ m_pNode(nullptr),
+ m_pParentStyle(nullptr),
+ m_dwFlags(0) {}
+
+CXFA_LoaderContext::~CXFA_LoaderContext() {}
diff --git a/xfa/fxfa/app/cxfa_loadercontext.h b/xfa/fxfa/app/cxfa_loadercontext.h
new file mode 100644
index 0000000000..39d2adc74d
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_loadercontext.h
@@ -0,0 +1,40 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_CXFA_LOADERCONTEXT_H_
+#define XFA_FXFA_APP_CXFA_LOADERCONTEXT_H_
+
+#include <vector>
+
+#include "core/fxcrt/fx_basic.h"
+#include "core/fxcrt/fx_system.h"
+
+class CFDE_XMLNode;
+class CXFA_Node;
+class IFDE_CSSComputedStyle;
+
+class CXFA_LoaderContext {
+ public:
+ CXFA_LoaderContext();
+ ~CXFA_LoaderContext();
+
+ bool m_bSaveLineHeight;
+ FX_FLOAT m_fWidth;
+ FX_FLOAT m_fHeight;
+ FX_FLOAT m_fLastPos;
+ FX_FLOAT m_fStartLineOffset;
+ int32_t m_iChar;
+ int32_t m_iLines;
+ int32_t m_iTotalLines;
+ CFDE_XMLNode* m_pXMLNode;
+ CXFA_Node* m_pNode;
+ IFDE_CSSComputedStyle* m_pParentStyle;
+ CFX_ArrayTemplate<FX_FLOAT> m_lineHeights;
+ uint32_t m_dwFlags;
+ std::vector<FX_FLOAT> m_BlocksHeight;
+};
+
+#endif // XFA_FXFA_APP_CXFA_LOADERCONTEXT_H_
diff --git a/xfa/fxfa/app/cxfa_pieceline.cpp b/xfa/fxfa/app/cxfa_pieceline.cpp
new file mode 100644
index 0000000000..465896fd18
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_pieceline.cpp
@@ -0,0 +1,11 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/cxfa_pieceline.h"
+
+CXFA_PieceLine::CXFA_PieceLine() {}
+
+CXFA_PieceLine::~CXFA_PieceLine() {}
diff --git a/xfa/fxfa/app/cxfa_pieceline.h b/xfa/fxfa/app/cxfa_pieceline.h
new file mode 100644
index 0000000000..88642d38bc
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_pieceline.h
@@ -0,0 +1,24 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_CXFA_PIECELINE_H_
+#define XFA_FXFA_APP_CXFA_PIECELINE_H_
+
+#include "core/fxcrt/fx_basic.h"
+#include "xfa/fgas/crt/fgas_memory.h"
+
+class XFA_TextPiece;
+
+class CXFA_PieceLine : public CFX_Target {
+ public:
+ CXFA_PieceLine();
+ ~CXFA_PieceLine() override;
+
+ CFX_ArrayTemplate<XFA_TextPiece*> m_textPieces;
+ CFX_ArrayTemplate<int32_t> m_charCounts;
+};
+
+#endif // XFA_FXFA_APP_CXFA_PIECELINE_H_
diff --git a/xfa/fxfa/app/xfa_textlayout.cpp b/xfa/fxfa/app/cxfa_textlayout.cpp
index 826fefcfbc..c4c2712386 100644
--- a/xfa/fxfa/app/xfa_textlayout.cpp
+++ b/xfa/fxfa/app/cxfa_textlayout.cpp
@@ -1,700 +1,32 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2017 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-#include "xfa/fxfa/app/xfa_textlayout.h"
+#include "xfa/fxfa/app/cxfa_textlayout.h"
#include <algorithm>
-#include "core/fxcrt/fx_ext.h"
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"
#include "xfa/fde/cfde_path.h"
-#include "xfa/fde/css/fde_csscache.h"
-#include "xfa/fde/css/fde_cssstyleselector.h"
#include "xfa/fde/fde_gedevice.h"
#include "xfa/fde/fde_object.h"
#include "xfa/fde/xml/fde_xml_imp.h"
-#include "xfa/fgas/crt/fgas_codepage.h"
+#include "xfa/fxfa/app/cxfa_linkuserdata.h"
+#include "xfa/fxfa/app/cxfa_loadercontext.h"
+#include "xfa/fxfa/app/cxfa_pieceline.h"
+#include "xfa/fxfa/app/cxfa_textparsecontext.h"
+#include "xfa/fxfa/app/cxfa_texttabstopscontext.h"
+#include "xfa/fxfa/app/cxfa_textuserdata.h"
#include "xfa/fxfa/app/xfa_ffwidgetacc.h"
-#include "xfa/fxfa/parser/cxfa_measurement.h"
-#include "xfa/fxfa/xfa_ffapp.h"
-#include "xfa/fxfa/xfa_ffdoc.h"
-#include "xfa/fxfa/xfa_fontmgr.h"
+#include "xfa/fxfa/app/xfa_textpiece.h"
+#include "xfa/fxfa/parser/cxfa_font.h"
+#include "xfa/fxfa/parser/cxfa_para.h"
+#include "xfa/fxfa/parser/xfa_object.h"
-CXFA_CSSTagProvider::CXFA_CSSTagProvider()
- : m_bTagAvailable(false), m_bContent(false) {}
-
-CXFA_CSSTagProvider::~CXFA_CSSTagProvider() {}
-
-XFA_TextPiece::XFA_TextPiece()
- : pszText(nullptr), pFont(nullptr), pLinkData(nullptr) {}
-
-XFA_TextPiece::~XFA_TextPiece() {
- if (pLinkData)
- pLinkData->Release();
-}
-
-CXFA_TextParseContext::CXFA_TextParseContext()
- : m_pParentStyle(nullptr),
- m_ppMatchedDecls(nullptr),
- m_dwMatchedDecls(0),
- m_eDisplay(FDE_CSSDISPLAY_None) {}
-
-CXFA_TextParseContext::~CXFA_TextParseContext() {
- if (m_pParentStyle)
- m_pParentStyle->Release();
- FX_Free(m_ppMatchedDecls);
-}
-
-void CXFA_TextParseContext::SetDecls(const CFDE_CSSDeclaration** ppDeclArray,
- int32_t iDeclCount) {
- if (iDeclCount <= 0 || !ppDeclArray)
- return;
-
- m_dwMatchedDecls = iDeclCount;
- m_ppMatchedDecls = FX_Alloc(CFDE_CSSDeclaration*, iDeclCount);
- FXSYS_memcpy(m_ppMatchedDecls, ppDeclArray,
- iDeclCount * sizeof(CFDE_CSSDeclaration*));
-}
-
-CXFA_TextParser::CXFA_TextParser() : m_pUASheet(nullptr) {}
-
-CXFA_TextParser::~CXFA_TextParser() {
- if (m_pUASheet)
- m_pUASheet->Release();
-
- for (auto& pair : m_mapXMLNodeToParseContext) {
- if (pair.second) {
- FXTARGET_DeleteWith(CXFA_TextParseContext, m_pAllocator.get(),
- pair.second);
- }
- }
-}
-
-void CXFA_TextParser::Reset() {
- for (auto& pair : m_mapXMLNodeToParseContext) {
- if (pair.second) {
- FXTARGET_DeleteWith(CXFA_TextParseContext, m_pAllocator.get(),
- pair.second);
- }
- }
- m_mapXMLNodeToParseContext.clear();
- m_pAllocator.reset();
-}
-void CXFA_TextParser::InitCSSData(CXFA_TextProvider* pTextProvider) {
- if (!pTextProvider)
- return;
-
- if (!m_pSelector) {
- CXFA_FFDoc* pDoc = pTextProvider->GetDocNode();
- CFGAS_FontMgr* pFontMgr = pDoc->GetApp()->GetFDEFontMgr();
- ASSERT(pFontMgr);
- m_pSelector = pdfium::MakeUnique<CFDE_CSSStyleSelector>(pFontMgr);
- FX_FLOAT fFontSize = 10;
- CXFA_Font font = pTextProvider->GetFontNode();
- if (font) {
- fFontSize = font.GetFontSize();
- }
- m_pSelector->SetDefFontSize(fFontSize);
- }
- if (!m_pUASheet) {
- m_pUASheet = LoadDefaultSheetStyle();
- m_pSelector->SetStyleSheet(FDE_CSSSTYLESHEETGROUP_UserAgent, m_pUASheet);
- m_pSelector->UpdateStyleIndex(FDE_CSSMEDIATYPE_ALL);
- }
-}
-
-CXFA_LoaderContext::CXFA_LoaderContext()
- : m_bSaveLineHeight(false),
- m_fWidth(0),
- m_fHeight(0),
- m_fLastPos(0),
- m_fStartLineOffset(0),
- m_iChar(0),
- m_iTotalLines(-1),
- m_pXMLNode(nullptr),
- m_pNode(nullptr),
- m_pParentStyle(nullptr),
- m_dwFlags(0) {}
-
-CXFA_LoaderContext::~CXFA_LoaderContext() {}
-
-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(
- CXFA_TextProvider* pTextProvider) {
- CXFA_Font font = pTextProvider->GetFontNode();
- CXFA_Para para = pTextProvider->GetParaNode();
- IFDE_CSSComputedStyle* pStyle = m_pSelector->CreateComputedStyle(nullptr);
- IFDE_CSSFontStyle* pFontStyle = pStyle->GetFontStyles();
- IFDE_CSSParagraphStyle* pParaStyle = pStyle->GetParagraphStyles();
- FX_FLOAT fLineHeight = 0, fFontSize = 10;
- if (para) {
- fLineHeight = para.GetLineHeight();
- FDE_CSSLENGTH indent;
- indent.Set(FDE_CSSLENGTHUNIT_Point, para.GetTextIndent());
- pParaStyle->SetTextIndent(indent);
- FDE_CSSTEXTALIGN hAlign = FDE_CSSTEXTALIGN_Left;
- switch (para.GetHorizontalAlign()) {
- case XFA_ATTRIBUTEENUM_Center:
- hAlign = FDE_CSSTEXTALIGN_Center;
- break;
- case XFA_ATTRIBUTEENUM_Right:
- hAlign = FDE_CSSTEXTALIGN_Right;
- break;
- case XFA_ATTRIBUTEENUM_Justify:
- hAlign = FDE_CSSTEXTALIGN_Justify;
- break;
- case XFA_ATTRIBUTEENUM_JustifyAll:
- hAlign = FDE_CSSTEXTALIGN_JustifyAll;
- break;
- }
- pParaStyle->SetTextAlign(hAlign);
- 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) {
- 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);
- uint32_t 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);
- ASSERT(pNewStyle);
- if (pParentStyle) {
- IFDE_CSSParagraphStyle* pParaStyle = pParentStyle->GetParagraphStyles();
- uint32_t 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) {
- pBoundarytyle = pNewStyle->GetBoundaryStyles();
- pBoundarytyle->SetMarginWidth(*pRect);
- }
- }
- return pNewStyle;
-}
-
-IFDE_CSSComputedStyle* CXFA_TextParser::ComputeStyle(
- CFDE_XMLNode* pXMLNode,
- IFDE_CSSComputedStyle* pParentStyle) {
- auto it = m_mapXMLNodeToParseContext.find(pXMLNode);
- if (it == m_mapXMLNodeToParseContext.end())
- return nullptr;
-
- CXFA_TextParseContext* pContext = it->second;
- if (!pContext)
- return nullptr;
-
- pContext->m_pParentStyle = pParentStyle;
- pParentStyle->Retain();
-
- CXFA_CSSTagProvider tagProvider;
- ParseTagInfo(pXMLNode, tagProvider);
- if (tagProvider.m_bContent)
- return nullptr;
-
- IFDE_CSSComputedStyle* pStyle = CreateStyle(pParentStyle);
- CFDE_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(CFDE_XMLNode* pXMLContainer,
- CXFA_TextProvider* pTextProvider) {
- if (!pXMLContainer || !pTextProvider || m_pAllocator) {
- return;
- }
- m_pAllocator = IFX_MemoryAllocator::Create(FX_ALLOCTYPE_Fixed, 32,
- sizeof(CXFA_CSSTagProvider));
- InitCSSData(pTextProvider);
- IFDE_CSSComputedStyle* pRootStyle = CreateRootStyle(pTextProvider);
- ParseRichText(pXMLContainer, pRootStyle);
- pRootStyle->Release();
-}
-void CXFA_TextParser::ParseRichText(CFDE_XMLNode* pXMLNode,
- IFDE_CSSComputedStyle* pParentStyle) {
- if (!pXMLNode)
- return;
-
- CXFA_CSSTagProvider tagProvider;
- ParseTagInfo(pXMLNode, tagProvider);
- if (!tagProvider.m_bTagAvailable)
- return;
-
- IFDE_CSSComputedStyle* pNewStyle = nullptr;
- if ((tagProvider.GetTagName() != FX_WSTRC(L"body")) ||
- (tagProvider.GetTagName() != FX_WSTRC(L"html"))) {
- CXFA_TextParseContext* pTextContext =
- FXTARGET_NewWith(m_pAllocator.get()) CXFA_TextParseContext;
- FDE_CSSDISPLAY eDisplay = FDE_CSSDISPLAY_Inline;
- if (!tagProvider.m_bContent) {
- pNewStyle = CreateStyle(pParentStyle);
- CFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator();
- pCSSAccel->OnEnterTag(&tagProvider);
- CFDE_CSSDeclarationArray DeclArray;
- int32_t iMatchedDecls =
- m_pSelector->MatchDeclarations(&tagProvider, DeclArray);
- const CFDE_CSSDeclaration** ppMatchDecls =
- const_cast<const CFDE_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[pXMLNode] = pTextContext;
- }
- for (CFDE_XMLNode* pXMLChild =
- pXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild);
- pXMLChild;
- pXMLChild = pXMLChild->GetNodeItem(CFDE_XMLNode::NextSibling)) {
- ParseRichText(pXMLChild, pNewStyle);
- }
- if (pNewStyle)
- pNewStyle->Release();
-}
-
-bool CXFA_TextParser::TagValidate(const CFX_WideString& wsName) const {
- static const uint32_t s_XFATagName[] = {
- 0x61, // a
- 0x62, // b
- 0x69, // i
- 0x70, // p
- 0x0001f714, // br
- 0x00022a55, // li
- 0x000239bb, // ol
- 0x00025881, // ul
- 0x0bd37faa, // sub
- 0x0bd37fb8, // sup
- 0xa73e3af2, // span
- 0xb182eaae, // body
- 0xdb8ac455, // html
- };
- static const int32_t s_iCount = FX_ArraySize(s_XFATagName);
-
- return std::binary_search(s_XFATagName, s_XFATagName + s_iCount,
- FX_HashCode_GetW(wsName.AsStringC(), true));
-}
-
-void CXFA_TextParser::ParseTagInfo(CFDE_XMLNode* pXMLNode,
- CXFA_CSSTagProvider& tagProvider) {
- CFX_WideString wsName;
- if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
- CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode);
- pXMLElement->GetLocalTagName(wsName);
- tagProvider.SetTagNameObj(wsName);
- tagProvider.m_bTagAvailable = TagValidate(wsName);
-
- CFX_WideString wsValue;
- pXMLElement->GetString(L"style", wsValue);
- if (!wsValue.IsEmpty()) {
- tagProvider.SetAttribute(L"style", wsValue);
- }
- } else if (pXMLNode->GetType() == FDE_XMLNODE_Text) {
- tagProvider.m_bTagAvailable = true;
- tagProvider.m_bContent = true;
- }
-}
-
-int32_t CXFA_TextParser::GetVAlign(CXFA_TextProvider* pTextProvider) const {
- CXFA_Para para = pTextProvider->GetParaNode();
- return para ? para.GetVerticalAlign() : XFA_ATTRIBUTEENUM_Top;
-}
-
-FX_FLOAT CXFA_TextParser::GetTabInterval(IFDE_CSSComputedStyle* pStyle) const {
- CFX_WideString wsValue;
- if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"tab-interval"), wsValue))
- return CXFA_Measurement(wsValue.AsStringC()).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;
-}
-
-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;
-}
-
-CFX_RetainPtr<CFGAS_GEFont> CXFA_TextParser::GetFont(
- CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle) const {
- CFX_WideStringC wsFamily = FX_WSTRC(L"Courier");
- uint32_t dwStyle = 0;
- CXFA_Font font = pTextProvider->GetFontNode();
- if (font) {
- 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();
- CXFA_FontMgr* pFontMgr = pDoc->GetApp()->GetXFAFontMgr();
- return pFontMgr->GetFont(pDoc, wsFamily, dwStyle);
-}
-FX_FLOAT CXFA_TextParser::GetFontSize(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle) const {
- if (pStyle)
- return pStyle->GetFontStyles()->GetFontSize();
-
- CXFA_Font font = pTextProvider->GetFontNode();
- if (font) {
- return font.GetFontSize();
- }
- return 10;
-}
-int32_t CXFA_TextParser::GetHorScale(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle,
- CFDE_XMLNode* pXMLNode) const {
- if (pStyle) {
- CFX_WideString wsValue;
- if (pStyle->GetCustomStyle(L"xfa-font-horizontal-scale", wsValue)) {
- return wsValue.GetInteger();
- }
- while (pXMLNode) {
- auto it = m_mapXMLNodeToParseContext.find(pXMLNode);
- if (it != m_mapXMLNodeToParseContext.end()) {
- CXFA_TextParseContext* pContext = it->second;
- if (pContext && pContext->m_pParentStyle &&
- pContext->m_pParentStyle->GetCustomStyle(
- L"xfa-font-horizontal-scale", wsValue)) {
- return wsValue.GetInteger();
- }
- }
- pXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::Parent);
- }
- }
- if (CXFA_Font font = pTextProvider->GetFontNode()) {
- return static_cast<int32_t>(font.GetHorizontalScale());
- }
- return 100;
-}
-int32_t CXFA_TextParser::GetVerScale(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle) const {
- if (pStyle) {
- 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(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle,
- int32_t& iUnderline,
- int32_t& iPeriod) const {
- iUnderline = 0;
- iPeriod = XFA_ATTRIBUTEENUM_All;
- if (pStyle) {
- uint32_t 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) {
- iUnderline = font.GetUnderline();
- iPeriod = font.GetUnderlinePeriod();
- }
- }
-}
-void CXFA_TextParser::GetLinethrough(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle,
- int32_t& iLinethrough) const {
- if (pStyle) {
- uint32_t dwDecoration = pStyle->GetParagraphStyles()->GetTextDecoration();
- iLinethrough = (dwDecoration & FDE_CSSTEXTDECORATION_LineThrough) ? 1 : 0;
- } else {
- CXFA_Font font = pTextProvider->GetFontNode();
- if (font) {
- iLinethrough = font.GetLineThrough();
- }
- }
-}
-FX_ARGB CXFA_TextParser::GetColor(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle) const {
- if (pStyle)
- return pStyle->GetFontStyles()->GetColor();
-
- if (CXFA_Font font = pTextProvider->GetFontNode())
- return font.GetColor();
-
- return 0xFF000000;
-}
-FX_FLOAT CXFA_TextParser::GetBaseline(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle) const {
- if (pStyle) {
- 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(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle,
- bool bFirst,
- FX_FLOAT fVerScale) const {
- FX_FLOAT fLineHeight = 0;
- if (pStyle) {
- 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;
-}
-bool CXFA_TextParser::GetEmbbedObj(CXFA_TextProvider* pTextProvider,
- CFDE_XMLNode* pXMLNode,
- CFX_WideString& wsValue) {
- wsValue.clear();
- if (!pXMLNode) {
- return false;
- }
- bool bRet = false;
- if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
- CFDE_XMLElement* pElement = static_cast<CFDE_XMLElement*>(pXMLNode);
- CFX_WideString wsAttr;
- pElement->GetString(L"xfa:embed", wsAttr);
- if (wsAttr.IsEmpty()) {
- return false;
- }
- if (wsAttr.GetAt(0) == L'#') {
- wsAttr.Delete(0);
- }
- CFX_WideString ws;
- pElement->GetString(L"xfa:embedType", ws);
- if (ws.IsEmpty()) {
- ws = L"som";
- } else {
- ws.MakeLower();
- }
- bool bURI = (ws == FX_WSTRC(L"uri"));
- if (!bURI && ws != FX_WSTRC(L"som")) {
- return false;
- }
- ws.clear();
- pElement->GetString(L"xfa:embedMode", ws);
- if (ws.IsEmpty()) {
- ws = L"formatted";
- } else {
- ws.MakeLower();
- }
- 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(
- CFDE_XMLNode* pXMLNode) {
- auto it = m_mapXMLNodeToParseContext.find(pXMLNode);
- return it != m_mapXMLNodeToParseContext.end() ? it->second : nullptr;
-}
-
-enum XFA_TABSTOPSSTATUS {
- XFA_TABSTOPSSTATUS_Error,
- XFA_TABSTOPSSTATUS_EOS,
- XFA_TABSTOPSSTATUS_None,
- XFA_TABSTOPSSTATUS_Alignment,
- XFA_TABSTOPSSTATUS_StartLeader,
- XFA_TABSTOPSSTATUS_Leader,
- XFA_TABSTOPSSTATUS_Location,
-};
-bool CXFA_TextParser::GetTabstops(IFDE_CSSComputedStyle* pStyle,
- CXFA_TextTabstopsContext* pTabstopContext) {
- if (!pStyle || !pTabstopContext) {
- 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.c_str();
- 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 == ' ') {
- uint32_t dwHashCode = FX_HashCode_GetW(wsAlign.AsStringC(), true);
- CXFA_Measurement ms(CFX_WideStringC(pTabStops + iLast, iCur - iLast));
- FX_FLOAT fPos = ms.ToUnit(XFA_UNIT_Pt);
- pTabstopContext->Append(dwHashCode, fPos);
- wsAlign.clear();
- eStatus = XFA_TABSTOPSSTATUS_None;
- }
- iCur++;
- break;
- default:
- break;
- }
- }
- if (!wsAlign.IsEmpty()) {
- uint32_t dwHashCode = FX_HashCode_GetW(wsAlign.AsStringC(), true);
- CXFA_Measurement ms(CFX_WideStringC(pTabStops + iLast, iCur - iLast));
- FX_FLOAT fPos = ms.ToUnit(XFA_UNIT_Pt);
- pTabstopContext->Append(dwHashCode, fPos);
- }
- return true;
-}
+#define XFA_LOADERCNTXTFLG_FILTERSPACE 0x001
CXFA_TextLayout::CXFA_TextLayout(CXFA_TextProvider* pTextProvider)
: m_bHasBlock(false),
@@ -732,49 +64,52 @@ void CXFA_TextLayout::Unload() {
m_pAllocator.reset();
}
-const CXFA_PieceLineArray* CXFA_TextLayout::GetPieceLines() {
+const CFX_ArrayTemplate<CXFA_PieceLine*>* CXFA_TextLayout::GetPieceLines() {
return &m_pieceLines;
}
void CXFA_TextLayout::GetTextDataNode() {
- if (!m_pTextProvider) {
+ if (!m_pTextProvider)
return;
- }
+
CXFA_Node* pNode = m_pTextProvider->GetTextNode(m_bRichText);
- if (pNode && m_bRichText) {
+ if (pNode && m_bRichText)
m_textParser.Reset();
- }
+
m_pTextDataNode = pNode;
}
+
CFDE_XMLNode* CXFA_TextLayout::GetXMLContainerNode() {
+ if (!m_bRichText)
+ return nullptr;
+
+ CFDE_XMLNode* pXMLRoot = m_pTextDataNode->GetXMLMappingNode();
+ if (!pXMLRoot)
+ return nullptr;
+
CFDE_XMLNode* pXMLContainer = nullptr;
- if (m_bRichText) {
- CFDE_XMLNode* pXMLRoot = m_pTextDataNode->GetXMLMappingNode();
- if (!pXMLRoot) {
- return pXMLContainer;
- }
- for (CFDE_XMLNode* pXMLChild =
- pXMLRoot->GetNodeItem(CFDE_XMLNode::FirstChild);
- pXMLChild;
- pXMLChild = pXMLChild->GetNodeItem(CFDE_XMLNode::NextSibling)) {
- if (pXMLChild->GetType() == FDE_XMLNODE_Element) {
- CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLChild);
- CFX_WideString wsTag;
- pXMLElement->GetLocalTagName(wsTag);
- if (wsTag == FX_WSTRC(L"body") || wsTag == FX_WSTRC(L"html")) {
- pXMLContainer = pXMLChild;
- break;
- }
+ for (CFDE_XMLNode* pXMLChild =
+ pXMLRoot->GetNodeItem(CFDE_XMLNode::FirstChild);
+ pXMLChild;
+ pXMLChild = pXMLChild->GetNodeItem(CFDE_XMLNode::NextSibling)) {
+ if (pXMLChild->GetType() == FDE_XMLNODE_Element) {
+ CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLChild);
+ CFX_WideString wsTag;
+ pXMLElement->GetLocalTagName(wsTag);
+ if (wsTag == FX_WSTRC(L"body") || wsTag == FX_WSTRC(L"html")) {
+ pXMLContainer = pXMLChild;
+ break;
}
}
}
return pXMLContainer;
}
+
CFX_RTFBreak* CXFA_TextLayout::CreateBreak(bool bDefault) {
uint32_t dwStyle = FX_RTFLAYOUTSTYLE_ExpandTab;
- if (!bDefault) {
+ if (!bDefault)
dwStyle |= FX_RTFLAYOUTSTYLE_Pagination;
- }
+
CFX_RTFBreak* pBreak = new CFX_RTFBreak(0);
pBreak->SetLayoutStyles(dwStyle);
pBreak->SetLineBreakChar(L'\n');
@@ -783,6 +118,7 @@ CFX_RTFBreak* CXFA_TextLayout::CreateBreak(bool bDefault) {
pBreak->SetFontSize(m_textParser.GetFontSize(m_pTextProvider, nullptr));
return pBreak;
}
+
void CXFA_TextLayout::InitBreak(FX_FLOAT fLineWidth) {
CXFA_Font font = m_pTextProvider->GetFontNode();
CXFA_Para para = m_pTextProvider->GetParaNode();
@@ -805,23 +141,23 @@ void CXFA_TextLayout::InitBreak(FX_FLOAT fLineWidth) {
break;
}
m_pBreak->SetAlignment(iAlign);
+
fStart = para.GetMarginLeft();
if (m_pTextProvider->IsCheckButtonAndAutoWidth()) {
- if (iAlign != FX_RTFLINEALIGNMENT_Left) {
+ if (iAlign != FX_RTFLINEALIGNMENT_Left)
fLineWidth -= para.GetMarginRight();
- }
} else {
fLineWidth -= para.GetMarginRight();
}
- if (fLineWidth < 0) {
+ if (fLineWidth < 0)
fLineWidth = fStart;
- }
+
fStartPos = fStart;
FX_FLOAT fIndent = para.GetTextIndent();
- if (fIndent > 0) {
+ if (fIndent > 0)
fStartPos += fIndent;
- }
}
+
m_pBreak->SetLineBoundary(fStart, fLineWidth);
m_pBreak->SetLineStartPos(fStartPos);
if (font) {
@@ -829,11 +165,13 @@ void CXFA_TextLayout::InitBreak(FX_FLOAT fLineWidth) {
m_pBreak->SetVerticalScale((int32_t)font.GetVerticalScale());
m_pBreak->SetCharSpace(font.GetLetterSpacing());
}
+
FX_FLOAT fFontSize = m_textParser.GetFontSize(m_pTextProvider, nullptr);
m_pBreak->SetFontSize(fFontSize);
m_pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, nullptr));
m_pBreak->SetLineBreakTolerance(fFontSize * 0.2f);
}
+
void CXFA_TextLayout::InitBreak(IFDE_CSSComputedStyle* pStyle,
FDE_CSSDISPLAY eDisplay,
FX_FLOAT fLineWidth,
@@ -843,6 +181,7 @@ void CXFA_TextLayout::InitBreak(IFDE_CSSComputedStyle* pStyle,
InitBreak(fLineWidth);
return;
}
+
IFDE_CSSParagraphStyle* pParaStyle = pStyle->GetParagraphStyles();
if (eDisplay == FDE_CSSDISPLAY_Block || eDisplay == FDE_CSSDISPLAY_ListItem) {
int32_t iAlign = FX_RTFLINEALIGNMENT_Left;
@@ -897,9 +236,9 @@ void CXFA_TextLayout::InitBreak(IFDE_CSSComputedStyle* pStyle,
}
m_pBreak->SetLineBoundary(fStart, fLineWidth);
FX_FLOAT fIndent = pParaStyle->GetTextIndent().GetValue();
- if (fIndent > 0) {
+ if (fIndent > 0)
fStart += fIndent;
- }
+
m_pBreak->SetLineStartPos(fStart);
m_pBreak->SetTabWidth(m_textParser.GetTabInterval(pStyle));
if (!m_pTabstopContext)
@@ -910,6 +249,7 @@ void CXFA_TextLayout::InitBreak(IFDE_CSSComputedStyle* pStyle,
m_pBreak->AddPositionedTab(pTab->fTabstops);
}
}
+
FX_FLOAT fFontSize = m_textParser.GetFontSize(m_pTextProvider, pStyle);
m_pBreak->SetFontSize(fFontSize);
m_pBreak->SetLineBreakTolerance(fFontSize * 0.2f);
@@ -919,19 +259,19 @@ void CXFA_TextLayout::InitBreak(IFDE_CSSComputedStyle* pStyle,
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.clear();
- if (m_bRichText) {
- } else {
+ if (!m_bRichText)
wsText = m_pTextDataNode->GetContent();
- }
return wsText.GetLength();
}
+
FX_FLOAT CXFA_TextLayout::GetLayoutHeight() {
- if (!m_pLoader) {
+ if (!m_pLoader)
return 0;
- }
+
int32_t iCount = m_pLoader->m_lineHeights.GetSize();
if (iCount == 0 && m_pLoader->m_fWidth > 0) {
CFX_SizeF szMax(m_pLoader->m_fWidth, m_pLoader->m_fHeight);
@@ -942,15 +282,16 @@ FX_FLOAT CXFA_TextLayout::GetLayoutHeight() {
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++) {
+ 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)
m_pLoader = pdfium::MakeUnique<CXFA_LoaderContext>();
@@ -963,6 +304,7 @@ FX_FLOAT CXFA_TextLayout::StartLayout(FX_FLOAT fWidth) {
m_pLoader->m_fStartLineOffset = 0;
}
m_pLoader->m_fWidth = fWidth;
+
if (fWidth < 0) {
CFX_SizeF szMax;
CFX_SizeF szDef;
@@ -974,35 +316,36 @@ FX_FLOAT CXFA_TextLayout::StartLayout(FX_FLOAT fWidth) {
}
return fWidth;
}
+
bool CXFA_TextLayout::DoLayout(int32_t iBlockIndex,
FX_FLOAT& fCalcHeight,
FX_FLOAT fContentAreaHeight,
FX_FLOAT fTextHeight) {
- if (!m_pLoader) {
+ if (!m_pLoader)
return false;
- }
+
int32_t iBlockCount = m_Blocks.GetSize();
FX_FLOAT fHeight = fTextHeight;
- if (fHeight < 0) {
+ if (fHeight < 0)
fHeight = GetLayoutHeight();
- }
+
m_pLoader->m_fHeight = fHeight;
- if (fContentAreaHeight < 0) {
+ if (fContentAreaHeight < 0)
return false;
- }
+
m_bHasBlock = true;
if (iBlockCount == 0 && fHeight > 0) {
fHeight = fTextHeight - GetLayoutHeight();
if (fHeight > 0) {
int32_t iAlign = m_textParser.GetVAlign(m_pTextProvider);
- if (iAlign == XFA_ATTRIBUTEENUM_Middle) {
+ if (iAlign == XFA_ATTRIBUTEENUM_Middle)
fHeight /= 2.0f;
- } else if (iAlign != XFA_ATTRIBUTEENUM_Bottom) {
+ 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) {
@@ -1017,6 +360,7 @@ bool CXFA_TextLayout::DoLayout(int32_t iBlockIndex,
fLinePos -= m_pLoader->m_BlocksHeight[i * 2 + 1];
}
}
+
int32_t iCount = m_pLoader->m_lineHeights.GetSize();
int32_t i = 0;
for (i = iLineIndex; i < iCount; i++) {
@@ -1046,6 +390,7 @@ bool CXFA_TextLayout::DoLayout(int32_t iBlockIndex,
}
return true;
}
+
fCalcHeight = fLinePos;
return true;
}
@@ -1053,6 +398,7 @@ bool CXFA_TextLayout::DoLayout(int32_t iBlockIndex,
}
return false;
}
+
int32_t CXFA_TextLayout::CountBlocks() const {
int32_t iCount = m_Blocks.GetSize() / 2;
return iCount > 0 ? iCount : 1;
@@ -1088,6 +434,7 @@ bool CXFA_TextLayout::Layout(const CFX_SizeF& size, FX_FLOAT* fHeight) {
m_pLoader->m_iTotalLines = -1;
m_pLoader->m_iChar = 0;
}
+
m_iLines = 0;
FX_FLOAT fLinePos = 0;
Loader(size, fLinePos, true);
@@ -1119,12 +466,13 @@ bool CXFA_TextLayout::Layout(int32_t iBlock) {
Unload();
m_pBreak.reset(CreateBreak(true));
fLinePos = m_pLoader->m_fStartLineOffset;
- for (int32_t i = 0; i < iBlocksHeightCount; i++) {
+ for (int32_t i = 0; i < iBlocksHeightCount; i++)
fLinePos -= m_pLoader->m_BlocksHeight[i * 2 + 1];
- }
+
m_pLoader->m_iChar = 0;
if (iCount > 1)
m_pLoader->m_iTotalLines = m_Blocks.ElementAt(iBlock * 2 + 1);
+
Loader(szText, fLinePos, true);
if (iCount == 0 && m_pLoader->m_fStartLineOffset < 0.1f)
UpdateAlign(szText.y, fLinePos);
@@ -1132,15 +480,17 @@ bool CXFA_TextLayout::Layout(int32_t iBlock) {
iBlock *= 2;
if (iBlock < iCount - 2)
m_pLoader->m_iTotalLines = m_Blocks.ElementAt(iBlock + 1);
+
m_pBreak->Reset();
if (m_bRichText) {
CFDE_XMLNode* pContainerNode = GetXMLContainerNode();
- if (!pContainerNode) {
+ if (!pContainerNode)
return true;
- }
+
CFDE_XMLNode* pXMLNode = m_pLoader->m_pXMLNode;
if (!pXMLNode)
return true;
+
CFDE_XMLNode* pSaveXMLNode = m_pLoader->m_pXMLNode;
for (; pXMLNode;
pXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::NextSibling)) {
@@ -1182,14 +532,15 @@ bool CXFA_TextLayout::Layout(int32_t iBlock) {
}
return true;
}
+
void CXFA_TextLayout::ItemBlocks(const CFX_RectF& rtText, int32_t iBlockIndex) {
- if (!m_pLoader) {
+ if (!m_pLoader)
return;
- }
+
int32_t iCountHeight = m_pLoader->m_lineHeights.GetSize();
- if (iCountHeight == 0) {
+ if (iCountHeight == 0)
return;
- }
+
bool bEndItem = true;
int32_t iBlockCount = m_Blocks.GetSize();
FX_FLOAT fLinePos = m_pLoader->m_fStartLineOffset;
@@ -1199,14 +550,14 @@ void CXFA_TextLayout::ItemBlocks(const CFX_RectF& rtText, int32_t iBlockIndex) {
pdfium::CollectionSize<int32_t>(m_pLoader->m_BlocksHeight);
iBlockHeightCount /= 2;
if (iBlockHeightCount >= iBlockIndex) {
- for (int32_t i = 0; i < iBlockIndex; i++) {
+ for (int32_t i = 0; i < iBlockIndex; i++)
fLinePos -= m_pLoader->m_BlocksHeight[i * 2 + 1];
- }
} else {
fLinePos = 0;
}
iLineIndex = m_Blocks[iBlockCount - 1] + m_Blocks[iBlockCount - 2];
}
+
int32_t i = 0;
for (i = iLineIndex; i < iCountHeight; i++) {
FX_FLOAT fLineHeight = m_pLoader->m_lineHeights.ElementAt(i);
@@ -1223,6 +574,7 @@ void CXFA_TextLayout::ItemBlocks(const CFX_RectF& rtText, int32_t iBlockIndex) {
m_Blocks.Add(i - iLineIndex);
}
}
+
bool CXFA_TextLayout::DrawString(CFX_RenderDevice* pFxDevice,
const CFX_Matrix& tmDoc2Device,
const CFX_RectF& rtClip,
@@ -1235,14 +587,14 @@ bool CXFA_TextLayout::DrawString(CFX_RenderDevice* pFxDevice,
pDevice->SaveState();
pDevice->SetClipRect(rtClip);
- std::unique_ptr<CFDE_Brush> pSolidBrush(new CFDE_Brush);
- std::unique_ptr<CFDE_Pen> pPen(new CFDE_Pen);
+ auto pSolidBrush = pdfium::MakeUnique<CFDE_Brush>();
+ auto pPen = pdfium::MakeUnique<CFDE_Pen>();
if (m_pieceLines.GetSize() == 0) {
int32_t iBlockCount = CountBlocks();
- for (int32_t i = 0; i < iBlockCount; i++) {
+ for (int32_t i = 0; i < iBlockCount; i++)
Layout(i);
- }
}
+
FXTEXT_CHARPOS* pCharPos = nullptr;
int32_t iCharCount = 0;
int32_t iLineStart = 0;
@@ -1257,10 +609,11 @@ bool CXFA_TextLayout::DrawString(CFX_RenderDevice* pFxDevice,
iPieceLines = 0;
}
}
+
for (int32_t i = 0; i < iPieceLines; i++) {
- if (i + iLineStart >= m_pieceLines.GetSize()) {
+ 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;
@@ -1285,11 +638,12 @@ bool CXFA_TextLayout::DrawString(CFX_RenderDevice* pFxDevice,
FX_Free(pCharPos);
return iPieceLines > 0;
}
+
void CXFA_TextLayout::UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom) {
fHeight -= fBottom;
- if (fHeight < 0.1f) {
+ if (fHeight < 0.1f)
return;
- }
+
switch (m_textParser.GetVAlign(m_pTextProvider)) {
case XFA_ATTRIBUTEENUM_Middle:
fHeight /= 2.0f;
@@ -1299,6 +653,7 @@ void CXFA_TextLayout::UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom) {
default:
return;
}
+
int32_t iCount = m_pieceLines.GetSize();
for (int32_t i = 0; i < iCount; i++) {
CXFA_PieceLine* pPieceLine = m_pieceLines.GetAt(i);
@@ -1310,12 +665,13 @@ void CXFA_TextLayout::UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom) {
}
}
}
+
bool CXFA_TextLayout::Loader(const CFX_SizeF& szText,
FX_FLOAT& fLinePos,
bool bSavePieces) {
- if (!m_pAllocator) {
+ if (!m_pAllocator)
m_pAllocator = IFX_MemoryAllocator::Create(FX_ALLOCTYPE_Static, 256, 0);
- }
+
GetTextDataNode();
if (!m_pTextDataNode)
return true;
@@ -1323,9 +679,9 @@ bool CXFA_TextLayout::Loader(const CFX_SizeF& szText,
if (m_bRichText) {
CFDE_XMLNode* pXMLContainer = GetXMLContainerNode();
if (pXMLContainer) {
- if (!m_textParser.IsParsed()) {
+ if (!m_textParser.IsParsed())
m_textParser.DoParse(pXMLContainer, m_pTextProvider);
- }
+
IFDE_CSSComputedStyle* pRootStyle =
m_textParser.CreateRootStyle(m_pTextProvider);
LoadRichText(pXMLContainer, szText, fLinePos, pRootStyle, bSavePieces);
@@ -1336,11 +692,13 @@ bool CXFA_TextLayout::Loader(const CFX_SizeF& szText,
}
return true;
}
+
void CXFA_TextLayout::LoadText(CXFA_Node* pNode,
const CFX_SizeF& szText,
FX_FLOAT& fLinePos,
bool bSavePieces) {
InitBreak(szText.x);
+
CXFA_Para para = m_pTextProvider->GetParaNode();
FX_FLOAT fSpaceAbove = 0;
if (para) {
@@ -1358,15 +716,16 @@ void CXFA_TextLayout::LoadText(CXFA_Node* pNode,
}
}
}
+
CFX_WideString wsText = pNode->GetContent();
wsText.TrimRight(L" ");
bool bRet = AppendChar(wsText, fLinePos, fSpaceAbove, bSavePieces);
- if (bRet && m_pLoader) {
+ if (bRet && m_pLoader)
m_pLoader->m_pNode = pNode;
- } else {
+ else
EndBreak(FX_RTFBREAK_ParagraphBreak, fLinePos, bSavePieces);
- }
}
+
bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode,
const CFX_SizeF& szText,
FX_FLOAT& fLinePos,
@@ -1376,9 +735,9 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode,
bool bEndBreak,
bool bIsOl,
int32_t iLiCount) {
- if (!pXMLNode) {
+ if (!pXMLNode)
return false;
- }
+
CXFA_TextParseContext* pContext =
m_textParser.GetParseContextFromMap(pXMLNode);
FDE_CSSDISPLAY eDisplay = FDE_CSSDISPLAY_None;
@@ -1412,6 +771,7 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode,
eDisplay != FDE_CSSDISPLAY_ListItem) {
return true;
}
+
pStyle = m_textParser.ComputeStyle(pXMLNode, pParentStyle);
InitBreak(bContentNode ? pParentStyle : pStyle, eDisplay, szText.x,
pXMLNode, pParentStyle);
@@ -1428,6 +788,7 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode,
fSpaceBelow = pRect->bottom.GetValue();
}
}
+
if (wsName == FX_WSTRC(L"a")) {
CFX_WideString wsLinkContent;
ASSERT(pElement);
@@ -1439,6 +800,7 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode,
wsLinkContent.ReleaseBuffer(wsLinkContent.GetLength());
}
}
+
int32_t iTabCount =
m_textParser.CountTabs(bContentNode ? pParentStyle : pStyle);
bool bSpaceRun =
@@ -1450,11 +812,10 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode,
wsText = L'\n';
} else if (wsName == FX_WSTRC(L"li")) {
bCurLi = true;
- if (bIsOl) {
+ if (bIsOl)
wsText.Format(L"%d. ", iLiCount);
- } else {
+ else
wsText = 0x00B7 + FX_WSTRC(L" ");
- }
} else if (!bContentNode) {
if (iTabCount > 0) {
while (iTabCount-- > 0)
@@ -1463,10 +824,11 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode,
m_textParser.GetEmbbedObj(m_pTextProvider, pXMLNode, wsText);
}
}
+
int32_t iLength = wsText.GetLength();
- if (iLength > 0 && bContentNode && !bSpaceRun) {
+ if (iLength > 0 && bContentNode && !bSpaceRun)
ProcessText(wsText);
- }
+
if (m_pLoader) {
if (wsText.GetLength() > 0 &&
(m_pLoader->m_dwFlags & XFA_LOADERCNTXTFLG_FILTERSPACE)) {
@@ -1484,21 +846,22 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode,
m_pLoader->m_dwFlags &= ~XFA_LOADERCNTXTFLG_FILTERSPACE;
}
}
+
if (wsText.GetLength() > 0) {
if (!m_pLoader || m_pLoader->m_iChar == 0) {
- if (pLinkData) {
+ if (pLinkData)
pLinkData->Retain();
- }
+
CXFA_TextUserData* pUserData = FXTARGET_NewWith(m_pAllocator.get())
CXFA_TextUserData(m_pAllocator.get(),
bContentNode ? pParentStyle : pStyle,
pLinkData);
m_pBreak->SetUserData(pUserData);
}
+
if (AppendChar(wsText, fLinePos, 0, bSavePieces)) {
- if (m_pLoader) {
+ 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;
@@ -1513,34 +876,31 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode,
}
}
}
- bool ret = true;
+
for (CFDE_XMLNode* pChildNode =
pXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild);
pChildNode;
pChildNode = pChildNode->GetNodeItem(CFDE_XMLNode::NextSibling)) {
- if (bCurOl) {
+ if (bCurOl)
iLiCount++;
- }
- ret = LoadRichText(pChildNode, szText, fLinePos,
- pContext ? pStyle : pParentStyle, bSavePieces,
- pLinkData, true, bIsOl, iLiCount);
- if (ret == false) {
+
+ if (!LoadRichText(pChildNode, szText, fLinePos,
+ pContext ? pStyle : pParentStyle, bSavePieces,
+ pLinkData, true, bIsOl, iLiCount))
return false;
- }
}
+
if (m_pLoader) {
- if (FDE_CSSDISPLAY_Block == eDisplay) {
+ if (FDE_CSSDISPLAY_Block == eDisplay)
m_pLoader->m_dwFlags |= XFA_LOADERCNTXTFLG_FILTERSPACE;
- }
}
- if (bCurLi) {
+ if (bCurLi)
EndBreak(FX_RTFBREAK_LineBreak, fLinePos, bSavePieces);
- }
} else {
- if (pContext) {
+ if (pContext)
eDisplay = pContext->GetDisplay();
- }
}
+
if (m_bBlockContinue) {
if (pContext && !bContentNode) {
uint32_t dwStatus = (eDisplay == FDE_CSSDISPLAY_Block)
@@ -1549,9 +909,8 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode,
EndBreak(dwStatus, fLinePos, bSavePieces);
if (eDisplay == FDE_CSSDISPLAY_Block) {
fLinePos += fSpaceBelow;
- if (m_pTabstopContext) {
+ if (m_pTabstopContext)
m_pTabstopContext->RemoveAll();
- }
}
if (wsName == FX_WSTRC(L"a")) {
if (pLinkData) {
@@ -1560,9 +919,9 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode,
}
}
if (IsEnd(bSavePieces)) {
- if (pStyle) {
+ if (pStyle)
pStyle->Release();
- }
+
if (m_pLoader && m_pLoader->m_iTotalLines > -1) {
m_pLoader->m_pXMLNode =
pXMLNode->GetNodeItem(CFDE_XMLNode::NextSibling);
@@ -1574,23 +933,25 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode,
}
if (pStyle)
pStyle->Release();
+
return true;
}
+
bool CXFA_TextLayout::AppendChar(const CFX_WideString& wsText,
FX_FLOAT& fLinePos,
FX_FLOAT fSpaceAbove,
bool bSavePieces) {
uint32_t dwStatus = 0;
int32_t iChar = 0;
- if (m_pLoader) {
+ 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) {
+ if (wch == 0xA0)
wch = 0x20;
- }
+
if ((dwStatus = m_pBreak->AppendChar(wch)) > FX_RTFBREAK_PieceBreak) {
AppendTextLine(dwStatus, fLinePos, bSavePieces);
if (IsEnd(bSavePieces)) {
@@ -1598,73 +959,71 @@ bool CXFA_TextLayout::AppendChar(const CFX_WideString& wsText,
m_pLoader->m_iChar = i;
return true;
}
- if (dwStatus == FX_RTFBREAK_ParagraphBreak && m_bRichText) {
+ if (dwStatus == FX_RTFBREAK_ParagraphBreak && m_bRichText)
fLinePos += fSpaceAbove;
- }
}
}
- if (m_pLoader) {
+ if (m_pLoader)
m_pLoader->m_iChar = 0;
- }
+
return false;
}
+
bool CXFA_TextLayout::IsEnd(bool bSavePieces) {
- if (!bSavePieces) {
+ if (!bSavePieces)
return false;
- }
- if (m_pLoader && m_pLoader->m_iTotalLines > 0) {
+ 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) {
+ 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) {
+ if (wch < 0x20)
wch = 0x20;
- }
- if (wch == 0x20 && wPrev == 0x20) {
+ if (wch == 0x20 && wPrev == 0x20)
continue;
- }
+
wPrev = wch;
psz[iTrimLeft++] = wch;
}
wsText.ReleaseBuffer(iLen);
wsText = wsText.Left(iTrimLeft);
}
+
void CXFA_TextLayout::EndBreak(uint32_t dwStatus,
FX_FLOAT& fLinePos,
bool bSavePieces) {
dwStatus = m_pBreak->EndBreak(dwStatus);
- if (dwStatus > FX_RTFBREAK_PieceBreak) {
+ if (dwStatus > FX_RTFBREAK_PieceBreak)
AppendTextLine(dwStatus, fLinePos, bSavePieces, true);
- }
}
+
void CXFA_TextLayout::DoTabstops(IFDE_CSSComputedStyle* pStyle,
CXFA_PieceLine* pPieceLine) {
- if (!m_pTabstopContext || m_pTabstopContext->m_iTabCount == 0) {
+ if (!m_pTabstopContext || m_pTabstopContext->m_iTabCount == 0)
return;
- }
- if (!pStyle || !pPieceLine) {
+ if (!pStyle || !pPieceLine)
return;
- }
+
int32_t iPieces = pPieceLine->m_textPieces.GetSize();
- if (iPieces == 0) {
+ if (iPieces == 0)
return;
- }
+
XFA_TextPiece* 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) {
+ if (iTabstopsIndex > m_pTabstopContext->m_iTabCount - 1)
return;
- }
+
if (iCount > 0) {
iTabstopsIndex++;
m_pTabstopContext->m_bTabstops = true;
@@ -1689,9 +1048,9 @@ void CXFA_TextLayout::DoTabstops(IFDE_CSSComputedStyle* pStyle,
} else if (dwAlign == FX_HashCode_GetW(L"decimal", false)) {
int32_t iChars = pPiece->iChars;
for (int32_t i = 0; i < iChars; i++) {
- if (pPiece->pszText[i] == L'.') {
+ if (pPiece->pszText[i] == L'.')
break;
- }
+
fLeft += pPiece->pWidths[i] / 20000.0f;
}
}
@@ -1703,22 +1062,23 @@ void CXFA_TextLayout::DoTabstops(IFDE_CSSComputedStyle* pStyle,
pPiece->rtPiece.left -= m_pTabstopContext->m_fLeft;
}
}
+
void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus,
FX_FLOAT& fLinePos,
bool bSavePieces,
bool bEndBreak) {
int32_t iPieces = m_pBreak->CountBreakPieces();
- if (iPieces < 1) {
+ if (iPieces < 1)
return;
- }
+
IFDE_CSSComputedStyle* pStyle = nullptr;
if (bSavePieces) {
CXFA_PieceLine* pPieceLine =
FXTARGET_NewWith(m_pAllocator.get()) CXFA_PieceLine;
m_pieceLines.Add(pPieceLine);
- if (m_pTabstopContext) {
+ if (m_pTabstopContext)
m_pTabstopContext->Reset();
- }
+
FX_FLOAT fLineStep = 0, fBaseLine = 0;
int32_t i = 0;
for (i = 0; i < iPieces; i++) {
@@ -1727,6 +1087,7 @@ void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus,
if (pUserData)
pStyle = pUserData->m_pStyle;
FX_FLOAT fVerScale = pPiece->m_iVerticalScale / 100.0f;
+
XFA_TextPiece* pTP = FXTARGET_NewWith(m_pAllocator.get()) XFA_TextPiece();
pTP->pszText =
(FX_WCHAR*)m_pAllocator->Alloc(pPiece->m_iChars * sizeof(FX_WCHAR));
@@ -1751,15 +1112,15 @@ void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus,
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) {
+ if (fLineHeight < fLineHeightTmp)
fLineHeight = fLineHeightTmp;
- } else {
+ else
fBaseLineTemp = 0;
- }
} else if (fBaseLine < -fBaseLineTemp) {
fBaseLine = -fBaseLineTemp;
}
@@ -1810,9 +1171,9 @@ void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus,
m_pLoader->m_lineHeights.Add(fHeight);
}
}
- if (pStyle) {
+ if (pStyle)
pStyle->Retain();
- }
+
m_pBreak->ClearBreakPieces();
if (dwStatus == FX_RTFBREAK_ParagraphBreak) {
m_pBreak->Reset();
@@ -1821,34 +1182,36 @@ void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus,
if (para) {
FX_FLOAT fStartPos = para.GetMarginLeft();
FX_FLOAT fIndent = para.GetTextIndent();
- if (fIndent > 0) {
+ if (fIndent > 0)
fStartPos += fIndent;
- }
+
FX_FLOAT fSpaceBelow = para.GetSpaceBelow();
- if (fSpaceBelow < 0.1f) {
+ 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) {
+ if (pRect)
fStart = pRect->left.GetValue();
- }
+
FX_FLOAT fTextIndent =
pStyle->GetParagraphStyles()->GetTextIndent().GetValue();
- if (fTextIndent < 0) {
+ if (fTextIndent < 0)
fStart -= fTextIndent;
- }
+
m_pBreak->SetLineStartPos(fStart);
pStyle->Release();
}
m_iLines++;
}
+
void CXFA_TextLayout::RenderString(CFDE_RenderDevice* pDevice,
CFDE_Brush* pBrush,
CXFA_PieceLine* pPieceLine,
@@ -1874,9 +1237,9 @@ void CXFA_TextLayout::RenderPath(CFDE_RenderDevice* pDevice,
XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(iPiece);
bool bNoUnderline = pPiece->iUnderline < 1 || pPiece->iUnderline > 2;
bool bNoLineThrough = pPiece->iLineThrough < 1 || pPiece->iLineThrough > 2;
- if (bNoUnderline && bNoLineThrough) {
+ if (bNoUnderline && bNoLineThrough)
return;
- }
+
pPen->SetColor(pPiece->dwColor);
std::unique_ptr<CFDE_Path> pPath(new CFDE_Path);
int32_t iChars = GetDisplayPos(pPiece, pCharPos);
@@ -1924,38 +1287,37 @@ void CXFA_TextLayout::RenderPath(CFDE_RenderDevice* pDevice,
while (iPiecePrev > 0) {
iPiecePrev--;
iCharsTmp = pPieceLine->m_charCounts.GetAt(iPiecePrev);
- if (iCharsTmp > 0) {
+ if (iCharsTmp > 0)
break;
- }
}
- if (iCharsTmp == 0) {
+ if (iCharsTmp == 0)
return;
- }
+
iCharsTmp = 0;
int32_t iPieces = pPieceLine->m_textPieces.GetSize();
while (iPieceNext < iPieces - 1) {
iPieceNext++;
iCharsTmp = pPieceLine->m_charCounts.GetAt(iPieceNext);
- if (iCharsTmp > 0) {
+ if (iCharsTmp > 0)
break;
- }
}
- if (iCharsTmp == 0) {
+ if (iCharsTmp == 0)
return;
- }
- FX_FLOAT fOrgX = 0.0f, fEndX = 0.0f;
+
+ FX_FLOAT fOrgX = 0.0f;
+ FX_FLOAT fEndX = 0.0f;
pPiece = pPieceLine->m_textPieces.GetAt(iPiecePrev);
iChars = GetDisplayPos(pPiece, pCharPos);
- if (iChars < 1) {
+ if (iChars < 1)
return;
- }
+
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) {
+ if (iChars < 1)
return;
- }
+
fEndX = pCharPos[0].m_OriginX;
CFX_PointF pt1, pt2;
pt1.x = fOrgX, pt2.x = fEndX;
@@ -1978,20 +1340,20 @@ void CXFA_TextLayout::RenderPath(CFDE_RenderDevice* pDevice,
int32_t CXFA_TextLayout::GetDisplayPos(const XFA_TextPiece* pPiece,
FXTEXT_CHARPOS* pCharPos,
bool bCharCode) {
- if (!pPiece) {
+ if (!pPiece)
return 0;
- }
+
FX_RTFTEXTOBJ tr;
- if (!ToRun(pPiece, tr)) {
+ if (!ToRun(pPiece, tr))
return 0;
- }
return m_pBreak->GetDisplayPos(&tr, pCharPos, bCharCode);
}
+
bool CXFA_TextLayout::ToRun(const XFA_TextPiece* pPiece, FX_RTFTEXTOBJ& tr) {
int32_t iLength = pPiece->iChars;
- if (iLength < 1) {
+ if (iLength < 1)
return false;
- }
+
tr.pStr = pPiece->pszText;
tr.pFont = pPiece->pFont;
tr.pRect = &pPiece->rtPiece;
@@ -2006,106 +1368,3 @@ bool CXFA_TextLayout::ToRun(const XFA_TextPiece* pPiece, FX_RTFTEXTOBJ& tr) {
tr.iHorizontalScale = pPiece->iHorScale;
return true;
}
-
-CXFA_LinkUserData::CXFA_LinkUserData(IFX_MemoryAllocator* pAllocator,
- FX_WCHAR* pszText)
- : m_pAllocator(pAllocator), m_dwRefCount(1), m_wsURLContent(pszText) {}
-
-CXFA_LinkUserData::~CXFA_LinkUserData() {}
-
-uint32_t CXFA_LinkUserData::Retain() {
- return ++m_dwRefCount;
-}
-
-uint32_t CXFA_LinkUserData::Release() {
- uint32_t dwRefCount = --m_dwRefCount;
- if (dwRefCount <= 0)
- FXTARGET_DeleteWith(CXFA_LinkUserData, m_pAllocator, this);
- return dwRefCount;
-}
-
-const FX_WCHAR* CXFA_LinkUserData::GetLinkURL() {
- return m_wsURLContent.c_str();
-}
-
-CXFA_TextUserData::CXFA_TextUserData(IFX_MemoryAllocator* pAllocator,
- IFDE_CSSComputedStyle* pStyle)
- : m_pStyle(pStyle),
- m_pLinkData(nullptr),
- m_pAllocator(pAllocator),
- m_dwRefCount(0) {
- ASSERT(m_pAllocator);
- if (m_pStyle)
- m_pStyle->Retain();
-}
-
-CXFA_TextUserData::CXFA_TextUserData(IFX_MemoryAllocator* pAllocator,
- IFDE_CSSComputedStyle* pStyle,
- CXFA_LinkUserData* pLinkData)
- : m_pStyle(pStyle),
- m_pLinkData(pLinkData),
- m_pAllocator(pAllocator),
- m_dwRefCount(0) {
- ASSERT(m_pAllocator);
- if (m_pStyle)
- m_pStyle->Retain();
-}
-
-CXFA_TextUserData::~CXFA_TextUserData() {
- if (m_pStyle)
- m_pStyle->Release();
- if (m_pLinkData)
- m_pLinkData->Release();
-}
-
-uint32_t CXFA_TextUserData::Retain() {
- return ++m_dwRefCount;
-}
-
-uint32_t CXFA_TextUserData::Release() {
- uint32_t dwRefCount = --m_dwRefCount;
- if (dwRefCount == 0)
- FXTARGET_DeleteWith(CXFA_TextUserData, m_pAllocator, this);
- return dwRefCount;
-}
-
-CXFA_PieceLine::CXFA_PieceLine() {}
-
-CXFA_PieceLine::~CXFA_PieceLine() {}
-
-CXFA_TextTabstopsContext::CXFA_TextTabstopsContext()
- : m_iTabCount(0),
- m_iTabIndex(-1),
- m_bTabstops(false),
- m_fTabWidth(0),
- m_fLeft(0) {}
-
-CXFA_TextTabstopsContext::~CXFA_TextTabstopsContext() {}
-
-void CXFA_TextTabstopsContext::Append(uint32_t dwAlign, FX_FLOAT fTabstops) {
- int32_t i = 0;
- for (i = 0; i < m_iTabCount; i++) {
- XFA_TABSTOPS* pTabstop = m_tabstops.GetDataPtr(i);
- if (fTabstops < pTabstop->fTabstops) {
- break;
- }
- }
- m_tabstops.InsertSpaceAt(i, 1);
- XFA_TABSTOPS tabstop;
- tabstop.dwAlign = dwAlign;
- tabstop.fTabstops = fTabstops;
- m_tabstops.SetAt(i, tabstop);
- m_iTabCount++;
-}
-
-void CXFA_TextTabstopsContext::RemoveAll() {
- m_tabstops.RemoveAll();
- m_iTabCount = 0;
-}
-
-void CXFA_TextTabstopsContext::Reset() {
- m_iTabIndex = -1;
- m_bTabstops = false;
- m_fTabWidth = 0;
- m_fLeft = 0;
-}
diff --git a/xfa/fxfa/app/cxfa_textlayout.h b/xfa/fxfa/app/cxfa_textlayout.h
new file mode 100644
index 0000000000..e21a5de424
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_textlayout.h
@@ -0,0 +1,135 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_CXFA_TEXTLAYOUT_H_
+#define XFA_FXFA_APP_CXFA_TEXTLAYOUT_H_
+
+#include <memory>
+
+#include "core/fxcrt/fx_basic.h"
+#include "core/fxcrt/fx_coordinates.h"
+#include "core/fxcrt/fx_string.h"
+#include "xfa/fde/css/fde_css.h"
+#include "xfa/fgas/layout/fgas_rtfbreak.h"
+#include "xfa/fxfa/app/cxfa_textparser.h"
+
+class CFDE_Brush;
+class CFDE_Pen;
+class CFDE_RenderDevice;
+class CFDE_XMLNode;
+class CFX_RTFBreak;
+class CXFA_LoaderContext;
+class CXFA_LinkUserData;
+class CXFA_Node;
+class CXFA_PieceLine;
+class CXFA_TextProvider;
+class CXFA_TextTabstopsContext;
+class IFDE_CSSComputedStyle;
+class IFX_MemoryAllocator;
+class XFA_TextPiece;
+
+class CXFA_TextLayout {
+ public:
+ explicit CXFA_TextLayout(CXFA_TextProvider* pTextProvider);
+ ~CXFA_TextLayout();
+
+ int32_t GetText(CFX_WideString& wsText);
+ FX_FLOAT GetLayoutHeight();
+ FX_FLOAT StartLayout(FX_FLOAT fWidth = -1);
+ bool DoLayout(int32_t iBlockIndex,
+ FX_FLOAT& fCalcHeight,
+ FX_FLOAT fContentAreaHeight = -1,
+ FX_FLOAT fTextHeight = -1);
+
+ bool CalcSize(const CFX_SizeF& minSize,
+ const CFX_SizeF& maxSize,
+ CFX_SizeF& defaultSize);
+ bool Layout(const CFX_SizeF& size, FX_FLOAT* fHeight = nullptr);
+ void ItemBlocks(const CFX_RectF& rtText, int32_t iBlockIndex);
+ bool DrawString(CFX_RenderDevice* pFxDevice,
+ const CFX_Matrix& tmDoc2Device,
+ const CFX_RectF& rtClip,
+ int32_t iBlock = 0);
+ bool IsLoaded() const { return m_pieceLines.GetSize() > 0; }
+ void Unload();
+ const CFX_ArrayTemplate<CXFA_PieceLine*>* GetPieceLines();
+
+ bool m_bHasBlock;
+ CFX_Int32Array m_Blocks;
+
+ private:
+ void GetTextDataNode();
+ CFDE_XMLNode* GetXMLContainerNode();
+ CFX_RTFBreak* CreateBreak(bool bDefault);
+ void InitBreak(FX_FLOAT fLineWidth);
+ void InitBreak(IFDE_CSSComputedStyle* pStyle,
+ FDE_CSSDISPLAY eDisplay,
+ FX_FLOAT fLineWidth,
+ CFDE_XMLNode* pXMLNode,
+ IFDE_CSSComputedStyle* pParentStyle = nullptr);
+ bool Loader(const CFX_SizeF& szText,
+ FX_FLOAT& fLinePos,
+ bool bSavePieces = true);
+ void LoadText(CXFA_Node* pNode,
+ const CFX_SizeF& szText,
+ FX_FLOAT& fLinePos,
+ bool bSavePieces);
+ bool LoadRichText(CFDE_XMLNode* pXMLNode,
+ const CFX_SizeF& szText,
+ FX_FLOAT& fLinePos,
+ IFDE_CSSComputedStyle* pParentStyle,
+ bool bSavePieces,
+ CXFA_LinkUserData* pLinkData = nullptr,
+ bool bEndBreak = true,
+ bool bIsOl = false,
+ int32_t iLiCount = 0);
+ bool AppendChar(const CFX_WideString& wsText,
+ FX_FLOAT& fLinePos,
+ FX_FLOAT fSpaceAbove,
+ bool bSavePieces);
+ void AppendTextLine(uint32_t dwStatus,
+ FX_FLOAT& fLinePos,
+ bool bSavePieces,
+ bool bEndBreak = false);
+ void EndBreak(uint32_t dwStatus, FX_FLOAT& fLinePos, bool bDefault);
+ bool IsEnd(bool bSavePieces);
+ void ProcessText(CFX_WideString& wsText);
+ void UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom);
+ void RenderString(CFDE_RenderDevice* pDevice,
+ CFDE_Brush* pBrush,
+ CXFA_PieceLine* pPieceLine,
+ int32_t iPiece,
+ FXTEXT_CHARPOS* pCharPos,
+ const CFX_Matrix& tmDoc2Device);
+ void RenderPath(CFDE_RenderDevice* pDevice,
+ CFDE_Pen* pPen,
+ CXFA_PieceLine* pPieceLine,
+ int32_t iPiece,
+ FXTEXT_CHARPOS* pCharPos,
+ const CFX_Matrix& tmDoc2Device);
+ int32_t GetDisplayPos(const XFA_TextPiece* pPiece,
+ FXTEXT_CHARPOS* pCharPos,
+ bool bCharCode = false);
+ bool ToRun(const XFA_TextPiece* pPiece, FX_RTFTEXTOBJ& tr);
+ void DoTabstops(IFDE_CSSComputedStyle* pStyle, CXFA_PieceLine* pPieceLine);
+ bool Layout(int32_t iBlock);
+ int32_t CountBlocks() const;
+
+ CXFA_TextProvider* m_pTextProvider;
+ CXFA_Node* m_pTextDataNode;
+ bool m_bRichText;
+ std::unique_ptr<IFX_MemoryAllocator> m_pAllocator;
+ std::unique_ptr<CFX_RTFBreak> m_pBreak;
+ std::unique_ptr<CXFA_LoaderContext> m_pLoader;
+ int32_t m_iLines;
+ FX_FLOAT m_fMaxWidth;
+ CXFA_TextParser m_textParser;
+ CFX_ArrayTemplate<CXFA_PieceLine*> m_pieceLines;
+ std::unique_ptr<CXFA_TextTabstopsContext> m_pTabstopContext;
+ bool m_bBlockContinue;
+};
+
+#endif // XFA_FXFA_APP_CXFA_TEXTLAYOUT_H_
diff --git a/xfa/fxfa/app/cxfa_textparsecontext.cpp b/xfa/fxfa/app/cxfa_textparsecontext.cpp
new file mode 100644
index 0000000000..b0dc655f00
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_textparsecontext.cpp
@@ -0,0 +1,32 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/cxfa_textparsecontext.h"
+
+#include "xfa/fde/css/fde_cssdeclaration.h"
+
+CXFA_TextParseContext::CXFA_TextParseContext()
+ : m_pParentStyle(nullptr),
+ m_ppMatchedDecls(nullptr),
+ m_dwMatchedDecls(0),
+ m_eDisplay(FDE_CSSDISPLAY_None) {}
+
+CXFA_TextParseContext::~CXFA_TextParseContext() {
+ if (m_pParentStyle)
+ m_pParentStyle->Release();
+ FX_Free(m_ppMatchedDecls);
+}
+
+void CXFA_TextParseContext::SetDecls(const CFDE_CSSDeclaration** ppDeclArray,
+ int32_t iDeclCount) {
+ if (iDeclCount <= 0 || !ppDeclArray)
+ return;
+
+ m_dwMatchedDecls = iDeclCount;
+ m_ppMatchedDecls = FX_Alloc(CFDE_CSSDeclaration*, iDeclCount);
+ FXSYS_memcpy(m_ppMatchedDecls, ppDeclArray,
+ iDeclCount * sizeof(CFDE_CSSDeclaration*));
+}
diff --git a/xfa/fxfa/app/cxfa_textparsecontext.h b/xfa/fxfa/app/cxfa_textparsecontext.h
new file mode 100644
index 0000000000..2eafacc8fe
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_textparsecontext.h
@@ -0,0 +1,38 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_CXFA_TEXTPARSECONTEXT_H_
+#define XFA_FXFA_APP_CXFA_TEXTPARSECONTEXT_H_
+
+#include "xfa/fde/css/fde_css.h"
+#include "xfa/fgas/crt/fgas_memory.h"
+
+class CFDE_CSSDeclaration;
+class IFDE_CSSComputedStyle;
+
+class CXFA_TextParseContext : public CFX_Target {
+ public:
+ CXFA_TextParseContext();
+ ~CXFA_TextParseContext() override;
+
+ void SetDisplay(FDE_CSSDISPLAY eDisplay) { m_eDisplay = eDisplay; }
+ FDE_CSSDISPLAY GetDisplay() const { return m_eDisplay; }
+
+ void SetDecls(const CFDE_CSSDeclaration** ppDeclArray, int32_t iDeclCount);
+ const CFDE_CSSDeclaration** GetDecls() {
+ return const_cast<const CFDE_CSSDeclaration**>(m_ppMatchedDecls);
+ }
+ uint32_t CountDecls() const { return m_dwMatchedDecls; }
+
+ IFDE_CSSComputedStyle* m_pParentStyle;
+
+ protected:
+ CFDE_CSSDeclaration** m_ppMatchedDecls;
+ uint32_t m_dwMatchedDecls;
+ FDE_CSSDISPLAY m_eDisplay;
+};
+
+#endif // XFA_FXFA_APP_CXFA_TEXTPARSECONTEXT_H_
diff --git a/xfa/fxfa/app/cxfa_textparser.cpp b/xfa/fxfa/app/cxfa_textparser.cpp
new file mode 100644
index 0000000000..b865e5e576
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_textparser.cpp
@@ -0,0 +1,659 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/cxfa_textparser.h"
+
+#include <algorithm>
+
+#include "third_party/base/ptr_util.h"
+#include "xfa/fde/css/fde_css.h"
+#include "xfa/fde/css/fde_cssstyleselector.h"
+#include "xfa/fgas/crt/fgas_codepage.h"
+#include "xfa/fgas/font/cfgas_fontmgr.h"
+#include "xfa/fxfa/app/cxfa_csstagprovider.h"
+#include "xfa/fxfa/app/cxfa_textparsecontext.h"
+#include "xfa/fxfa/app/cxfa_texttabstopscontext.h"
+#include "xfa/fxfa/app/xfa_ffwidgetacc.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
+#include "xfa/fxfa/xfa_ffapp.h"
+#include "xfa/fxfa/xfa_ffdoc.h"
+#include "xfa/fxfa/xfa_fontmgr.h"
+
+namespace {
+
+enum class TabStopStatus {
+ Error,
+ EOS,
+ None,
+ Alignment,
+ StartLeader,
+ Leader,
+ Location,
+};
+
+} // namespace
+
+CXFA_TextParser::CXFA_TextParser() : m_pUASheet(nullptr) {}
+
+CXFA_TextParser::~CXFA_TextParser() {
+ if (m_pUASheet)
+ m_pUASheet->Release();
+
+ for (auto& pair : m_mapXMLNodeToParseContext) {
+ if (pair.second) {
+ FXTARGET_DeleteWith(CXFA_TextParseContext, m_pAllocator.get(),
+ pair.second);
+ }
+ }
+}
+
+void CXFA_TextParser::Reset() {
+ for (auto& pair : m_mapXMLNodeToParseContext) {
+ if (pair.second) {
+ FXTARGET_DeleteWith(CXFA_TextParseContext, m_pAllocator.get(),
+ pair.second);
+ }
+ }
+ m_mapXMLNodeToParseContext.clear();
+ m_pAllocator.reset();
+}
+void CXFA_TextParser::InitCSSData(CXFA_TextProvider* pTextProvider) {
+ if (!pTextProvider)
+ return;
+
+ if (!m_pSelector) {
+ CXFA_FFDoc* pDoc = pTextProvider->GetDocNode();
+ CFGAS_FontMgr* pFontMgr = pDoc->GetApp()->GetFDEFontMgr();
+ ASSERT(pFontMgr);
+ m_pSelector = pdfium::MakeUnique<CFDE_CSSStyleSelector>(pFontMgr);
+ FX_FLOAT fFontSize = 10;
+ CXFA_Font font = pTextProvider->GetFontNode();
+ if (font) {
+ fFontSize = font.GetFontSize();
+ }
+ m_pSelector->SetDefFontSize(fFontSize);
+ }
+
+ if (!m_pUASheet) {
+ 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(
+ CXFA_TextProvider* pTextProvider) {
+ CXFA_Font font = pTextProvider->GetFontNode();
+ CXFA_Para para = pTextProvider->GetParaNode();
+ IFDE_CSSComputedStyle* pStyle = m_pSelector->CreateComputedStyle(nullptr);
+ IFDE_CSSFontStyle* pFontStyle = pStyle->GetFontStyles();
+ IFDE_CSSParagraphStyle* pParaStyle = pStyle->GetParagraphStyles();
+ FX_FLOAT fLineHeight = 0;
+ FX_FLOAT fFontSize = 10;
+
+ if (para) {
+ fLineHeight = para.GetLineHeight();
+ FDE_CSSLENGTH indent;
+ indent.Set(FDE_CSSLENGTHUNIT_Point, para.GetTextIndent());
+ pParaStyle->SetTextIndent(indent);
+ FDE_CSSTEXTALIGN hAlign = FDE_CSSTEXTALIGN_Left;
+ switch (para.GetHorizontalAlign()) {
+ case XFA_ATTRIBUTEENUM_Center:
+ hAlign = FDE_CSSTEXTALIGN_Center;
+ break;
+ case XFA_ATTRIBUTEENUM_Right:
+ hAlign = FDE_CSSTEXTALIGN_Right;
+ break;
+ case XFA_ATTRIBUTEENUM_Justify:
+ hAlign = FDE_CSSTEXTALIGN_Justify;
+ break;
+ case XFA_ATTRIBUTEENUM_JustifyAll:
+ hAlign = FDE_CSSTEXTALIGN_JustifyAll;
+ break;
+ }
+ pParaStyle->SetTextAlign(hAlign);
+ 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) {
+ 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);
+ uint32_t 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);
+ ASSERT(pNewStyle);
+ if (!pParentStyle)
+ return pNewStyle;
+
+ IFDE_CSSParagraphStyle* pParaStyle = pParentStyle->GetParagraphStyles();
+ uint32_t 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) {
+ pBoundarytyle = pNewStyle->GetBoundaryStyles();
+ pBoundarytyle->SetMarginWidth(*pRect);
+ }
+ return pNewStyle;
+}
+
+IFDE_CSSComputedStyle* CXFA_TextParser::ComputeStyle(
+ CFDE_XMLNode* pXMLNode,
+ IFDE_CSSComputedStyle* pParentStyle) {
+ auto it = m_mapXMLNodeToParseContext.find(pXMLNode);
+ if (it == m_mapXMLNodeToParseContext.end())
+ return nullptr;
+
+ CXFA_TextParseContext* pContext = it->second;
+ if (!pContext)
+ return nullptr;
+
+ pContext->m_pParentStyle = pParentStyle;
+ pParentStyle->Retain();
+
+ CXFA_CSSTagProvider tagProvider;
+ ParseTagInfo(pXMLNode, tagProvider);
+ if (tagProvider.m_bContent)
+ return nullptr;
+
+ IFDE_CSSComputedStyle* pStyle = CreateStyle(pParentStyle);
+ CFDE_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(CFDE_XMLNode* pXMLContainer,
+ CXFA_TextProvider* pTextProvider) {
+ if (!pXMLContainer || !pTextProvider || m_pAllocator)
+ return;
+
+ m_pAllocator = IFX_MemoryAllocator::Create(FX_ALLOCTYPE_Fixed, 32,
+ sizeof(CXFA_CSSTagProvider));
+ InitCSSData(pTextProvider);
+ IFDE_CSSComputedStyle* pRootStyle = CreateRootStyle(pTextProvider);
+ ParseRichText(pXMLContainer, pRootStyle);
+ pRootStyle->Release();
+}
+
+void CXFA_TextParser::ParseRichText(CFDE_XMLNode* pXMLNode,
+ IFDE_CSSComputedStyle* pParentStyle) {
+ if (!pXMLNode)
+ return;
+
+ CXFA_CSSTagProvider tagProvider;
+ ParseTagInfo(pXMLNode, tagProvider);
+ if (!tagProvider.m_bTagAvailable)
+ return;
+
+ IFDE_CSSComputedStyle* pNewStyle = nullptr;
+ if ((tagProvider.GetTagName() != FX_WSTRC(L"body")) ||
+ (tagProvider.GetTagName() != FX_WSTRC(L"html"))) {
+ CXFA_TextParseContext* pTextContext =
+ FXTARGET_NewWith(m_pAllocator.get()) CXFA_TextParseContext;
+ FDE_CSSDISPLAY eDisplay = FDE_CSSDISPLAY_Inline;
+ if (!tagProvider.m_bContent) {
+ pNewStyle = CreateStyle(pParentStyle);
+ CFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator();
+ pCSSAccel->OnEnterTag(&tagProvider);
+ CFDE_CSSDeclarationArray DeclArray;
+ int32_t iMatchedDecls =
+ m_pSelector->MatchDeclarations(&tagProvider, DeclArray);
+ const CFDE_CSSDeclaration** ppMatchDecls =
+ const_cast<const CFDE_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[pXMLNode] = pTextContext;
+ }
+
+ for (CFDE_XMLNode* pXMLChild =
+ pXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild);
+ pXMLChild;
+ pXMLChild = pXMLChild->GetNodeItem(CFDE_XMLNode::NextSibling)) {
+ ParseRichText(pXMLChild, pNewStyle);
+ }
+ if (pNewStyle)
+ pNewStyle->Release();
+}
+
+bool CXFA_TextParser::TagValidate(const CFX_WideString& wsName) const {
+ static const uint32_t s_XFATagName[] = {
+ 0x61, // a
+ 0x62, // b
+ 0x69, // i
+ 0x70, // p
+ 0x0001f714, // br
+ 0x00022a55, // li
+ 0x000239bb, // ol
+ 0x00025881, // ul
+ 0x0bd37faa, // sub
+ 0x0bd37fb8, // sup
+ 0xa73e3af2, // span
+ 0xb182eaae, // body
+ 0xdb8ac455, // html
+ };
+ static const int32_t s_iCount = FX_ArraySize(s_XFATagName);
+
+ return std::binary_search(s_XFATagName, s_XFATagName + s_iCount,
+ FX_HashCode_GetW(wsName.AsStringC(), true));
+}
+
+void CXFA_TextParser::ParseTagInfo(CFDE_XMLNode* pXMLNode,
+ CXFA_CSSTagProvider& tagProvider) {
+ CFX_WideString wsName;
+ if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
+ CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode);
+ pXMLElement->GetLocalTagName(wsName);
+ tagProvider.SetTagNameObj(wsName);
+ tagProvider.m_bTagAvailable = TagValidate(wsName);
+
+ CFX_WideString wsValue;
+ pXMLElement->GetString(L"style", wsValue);
+ if (!wsValue.IsEmpty())
+ tagProvider.SetAttribute(L"style", wsValue);
+ } else if (pXMLNode->GetType() == FDE_XMLNODE_Text) {
+ tagProvider.m_bTagAvailable = true;
+ tagProvider.m_bContent = true;
+ }
+}
+
+int32_t CXFA_TextParser::GetVAlign(CXFA_TextProvider* pTextProvider) const {
+ CXFA_Para para = pTextProvider->GetParaNode();
+ return para ? para.GetVerticalAlign() : XFA_ATTRIBUTEENUM_Top;
+}
+
+FX_FLOAT CXFA_TextParser::GetTabInterval(IFDE_CSSComputedStyle* pStyle) const {
+ CFX_WideString wsValue;
+ if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"tab-interval"), wsValue))
+ return CXFA_Measurement(wsValue.AsStringC()).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;
+}
+
+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;
+}
+
+CFX_RetainPtr<CFGAS_GEFont> CXFA_TextParser::GetFont(
+ CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle) const {
+ CFX_WideStringC wsFamily = FX_WSTRC(L"Courier");
+ uint32_t dwStyle = 0;
+ CXFA_Font font = pTextProvider->GetFontNode();
+ if (font) {
+ 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();
+ CXFA_FontMgr* pFontMgr = pDoc->GetApp()->GetXFAFontMgr();
+ return pFontMgr->GetFont(pDoc, wsFamily, dwStyle);
+}
+
+FX_FLOAT CXFA_TextParser::GetFontSize(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle) const {
+ if (pStyle)
+ return pStyle->GetFontStyles()->GetFontSize();
+
+ CXFA_Font font = pTextProvider->GetFontNode();
+ if (font)
+ return font.GetFontSize();
+ return 10;
+}
+
+int32_t CXFA_TextParser::GetHorScale(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle,
+ CFDE_XMLNode* pXMLNode) const {
+ if (pStyle) {
+ CFX_WideString wsValue;
+ if (pStyle->GetCustomStyle(L"xfa-font-horizontal-scale", wsValue))
+ return wsValue.GetInteger();
+
+ while (pXMLNode) {
+ auto it = m_mapXMLNodeToParseContext.find(pXMLNode);
+ if (it != m_mapXMLNodeToParseContext.end()) {
+ CXFA_TextParseContext* pContext = it->second;
+ if (pContext && pContext->m_pParentStyle &&
+ pContext->m_pParentStyle->GetCustomStyle(
+ L"xfa-font-horizontal-scale", wsValue)) {
+ return wsValue.GetInteger();
+ }
+ }
+ pXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::Parent);
+ }
+ }
+
+ if (CXFA_Font font = pTextProvider->GetFontNode())
+ return static_cast<int32_t>(font.GetHorizontalScale());
+ return 100;
+}
+
+int32_t CXFA_TextParser::GetVerScale(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle) const {
+ if (pStyle) {
+ 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(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle,
+ int32_t& iUnderline,
+ int32_t& iPeriod) const {
+ iUnderline = 0;
+ iPeriod = XFA_ATTRIBUTEENUM_All;
+ if (!pStyle) {
+ CXFA_Font font = pTextProvider->GetFontNode();
+ if (font) {
+ iUnderline = font.GetUnderline();
+ iPeriod = font.GetUnderlinePeriod();
+ }
+ return;
+ }
+
+ uint32_t 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();
+ }
+}
+
+void CXFA_TextParser::GetLinethrough(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle,
+ int32_t& iLinethrough) const {
+ if (pStyle) {
+ uint32_t dwDecoration = pStyle->GetParagraphStyles()->GetTextDecoration();
+ iLinethrough = (dwDecoration & FDE_CSSTEXTDECORATION_LineThrough) ? 1 : 0;
+ return;
+ }
+
+ CXFA_Font font = pTextProvider->GetFontNode();
+ if (font)
+ iLinethrough = font.GetLineThrough();
+}
+
+FX_ARGB CXFA_TextParser::GetColor(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle) const {
+ if (pStyle)
+ return pStyle->GetFontStyles()->GetColor();
+ if (CXFA_Font font = pTextProvider->GetFontNode())
+ return font.GetColor();
+
+ return 0xFF000000;
+}
+
+FX_FLOAT CXFA_TextParser::GetBaseline(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle) const {
+ if (pStyle) {
+ 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(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle,
+ bool bFirst,
+ FX_FLOAT fVerScale) const {
+ FX_FLOAT fLineHeight = 0;
+ if (pStyle)
+ 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;
+}
+
+bool CXFA_TextParser::GetEmbbedObj(CXFA_TextProvider* pTextProvider,
+ CFDE_XMLNode* pXMLNode,
+ CFX_WideString& wsValue) {
+ wsValue.clear();
+ if (!pXMLNode)
+ return false;
+
+ bool bRet = false;
+ if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
+ CFDE_XMLElement* pElement = static_cast<CFDE_XMLElement*>(pXMLNode);
+ CFX_WideString wsAttr;
+ pElement->GetString(L"xfa:embed", wsAttr);
+ if (wsAttr.IsEmpty())
+ return false;
+ if (wsAttr.GetAt(0) == L'#')
+ wsAttr.Delete(0);
+
+ CFX_WideString ws;
+ pElement->GetString(L"xfa:embedType", ws);
+ if (ws.IsEmpty())
+ ws = L"som";
+ else
+ ws.MakeLower();
+
+ bool bURI = (ws == FX_WSTRC(L"uri"));
+ if (!bURI && ws != FX_WSTRC(L"som"))
+ return false;
+
+ ws.clear();
+ pElement->GetString(L"xfa:embedMode", ws);
+ if (ws.IsEmpty())
+ ws = L"formatted";
+ else
+ ws.MakeLower();
+
+ 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(
+ CFDE_XMLNode* pXMLNode) {
+ auto it = m_mapXMLNodeToParseContext.find(pXMLNode);
+ return it != m_mapXMLNodeToParseContext.end() ? it->second : nullptr;
+}
+
+bool CXFA_TextParser::GetTabstops(IFDE_CSSComputedStyle* pStyle,
+ CXFA_TextTabstopsContext* pTabstopContext) {
+ if (!pStyle || !pTabstopContext)
+ 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.c_str();
+ int32_t iCur = 0;
+ int32_t iLast = 0;
+ CFX_WideString wsAlign;
+ TabStopStatus eStatus = TabStopStatus::None;
+ FX_WCHAR ch;
+ while (iCur < iLength) {
+ ch = pTabStops[iCur];
+ switch (eStatus) {
+ case TabStopStatus::None:
+ if (ch <= ' ') {
+ iCur++;
+ } else {
+ eStatus = TabStopStatus::Alignment;
+ iLast = iCur;
+ }
+ break;
+ case TabStopStatus::Alignment:
+ if (ch == ' ') {
+ wsAlign = CFX_WideStringC(pTabStops + iLast, iCur - iLast);
+ eStatus = TabStopStatus::StartLeader;
+ iCur++;
+ while (iCur < iLength && pTabStops[iCur] <= ' ')
+ iCur++;
+ iLast = iCur;
+ } else {
+ iCur++;
+ }
+ break;
+ case TabStopStatus::StartLeader:
+ if (ch != 'l') {
+ eStatus = TabStopStatus::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 = TabStopStatus::Location;
+ }
+ break;
+ case TabStopStatus::Location:
+ if (ch == ' ') {
+ uint32_t dwHashCode = FX_HashCode_GetW(wsAlign.AsStringC(), true);
+ CXFA_Measurement ms(CFX_WideStringC(pTabStops + iLast, iCur - iLast));
+ FX_FLOAT fPos = ms.ToUnit(XFA_UNIT_Pt);
+ pTabstopContext->Append(dwHashCode, fPos);
+ wsAlign.clear();
+ eStatus = TabStopStatus::None;
+ }
+ iCur++;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!wsAlign.IsEmpty()) {
+ uint32_t dwHashCode = FX_HashCode_GetW(wsAlign.AsStringC(), true);
+ CXFA_Measurement ms(CFX_WideStringC(pTabStops + iLast, iCur - iLast));
+ FX_FLOAT fPos = ms.ToUnit(XFA_UNIT_Pt);
+ pTabstopContext->Append(dwHashCode, fPos);
+ }
+ return true;
+}
diff --git a/xfa/fxfa/app/cxfa_textparser.h b/xfa/fxfa/app/cxfa_textparser.h
new file mode 100644
index 0000000000..e793c0c9fe
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_textparser.h
@@ -0,0 +1,101 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_CXFA_TEXTPARSER_H_
+#define XFA_FXFA_APP_CXFA_TEXTPARSER_H_
+
+#include <map>
+#include <memory>
+
+#include "core/fxcrt/cfx_retain_ptr.h"
+#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/fx_system.h"
+#include "core/fxge/fx_dib.h"
+#include "xfa/fgas/font/cfgas_gefont.h"
+
+class CFDE_CSSStyleSelector;
+class CFDE_XMLNode;
+class CXFA_CSSTagProvider;
+class CXFA_TextParseContext;
+class CXFA_TextProvider;
+class CXFA_TextTabstopsContext;
+class IFDE_CSSComputedStyle;
+class IFDE_CSSStyleSheet;
+class IFX_MemoryAllocator;
+
+class CXFA_TextParser {
+ public:
+ CXFA_TextParser();
+ virtual ~CXFA_TextParser();
+
+ void Reset();
+ void DoParse(CFDE_XMLNode* pXMLContainer, CXFA_TextProvider* pTextProvider);
+
+ IFDE_CSSComputedStyle* CreateRootStyle(CXFA_TextProvider* pTextProvider);
+ IFDE_CSSComputedStyle* ComputeStyle(CFDE_XMLNode* pXMLNode,
+ IFDE_CSSComputedStyle* pParentStyle);
+
+ bool IsParsed() const { return !!m_pAllocator; }
+
+ int32_t GetVAlign(CXFA_TextProvider* pTextProvider) const;
+
+ FX_FLOAT GetTabInterval(IFDE_CSSComputedStyle* pStyle) const;
+ int32_t CountTabs(IFDE_CSSComputedStyle* pStyle) const;
+
+ bool IsSpaceRun(IFDE_CSSComputedStyle* pStyle) const;
+ bool GetTabstops(IFDE_CSSComputedStyle* pStyle,
+ CXFA_TextTabstopsContext* pTabstopContext);
+
+ CFX_RetainPtr<CFGAS_GEFont> GetFont(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle) const;
+ FX_FLOAT GetFontSize(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle) const;
+
+ int32_t GetHorScale(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle,
+ CFDE_XMLNode* pXMLNode) const;
+ int32_t GetVerScale(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle) const;
+
+ void GetUnderline(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle,
+ int32_t& iUnderline,
+ int32_t& iPeriod) const;
+ void GetLinethrough(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle,
+ int32_t& iLinethrough) const;
+ FX_ARGB GetColor(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle) const;
+ FX_FLOAT GetBaseline(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle) const;
+ FX_FLOAT GetLineHeight(CXFA_TextProvider* pTextProvider,
+ IFDE_CSSComputedStyle* pStyle,
+ bool bFirst,
+ FX_FLOAT fVerScale) const;
+
+ bool GetEmbbedObj(CXFA_TextProvider* pTextProvider,
+ CFDE_XMLNode* pXMLNode,
+ CFX_WideString& wsValue);
+ CXFA_TextParseContext* GetParseContextFromMap(CFDE_XMLNode* pXMLNode);
+
+ protected:
+ bool TagValidate(const CFX_WideString& str) const;
+
+ private:
+ void InitCSSData(CXFA_TextProvider* pTextProvider);
+ void ParseRichText(CFDE_XMLNode* pXMLNode,
+ IFDE_CSSComputedStyle* pParentStyle);
+ void ParseTagInfo(CFDE_XMLNode* pXMLNode, CXFA_CSSTagProvider& tagProvider);
+ IFDE_CSSStyleSheet* LoadDefaultSheetStyle();
+ IFDE_CSSComputedStyle* CreateStyle(IFDE_CSSComputedStyle* pParentStyle);
+
+ std::unique_ptr<IFX_MemoryAllocator> m_pAllocator;
+ std::unique_ptr<CFDE_CSSStyleSelector> m_pSelector;
+ IFDE_CSSStyleSheet* m_pUASheet;
+ std::map<CFDE_XMLNode*, CXFA_TextParseContext*> m_mapXMLNodeToParseContext;
+};
+
+#endif // XFA_FXFA_APP_CXFA_TEXTPARSER_H_
diff --git a/xfa/fxfa/app/xfa_textlayout_unittest.cpp b/xfa/fxfa/app/cxfa_textparser_unittest.cpp
index 7354631dbb..82a0110468 100644
--- a/xfa/fxfa/app/xfa_textlayout_unittest.cpp
+++ b/xfa/fxfa/app/cxfa_textparser_unittest.cpp
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "xfa/fxfa/app/xfa_textlayout.h"
+#include "xfa/fxfa/app/cxfa_textparser.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/xfa/fxfa/app/cxfa_texttabstopscontext.cpp b/xfa/fxfa/app/cxfa_texttabstopscontext.cpp
new file mode 100644
index 0000000000..3209603af3
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_texttabstopscontext.cpp
@@ -0,0 +1,44 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/cxfa_texttabstopscontext.h"
+
+CXFA_TextTabstopsContext::CXFA_TextTabstopsContext()
+ : m_iTabCount(0),
+ m_iTabIndex(-1),
+ m_bTabstops(false),
+ m_fTabWidth(0),
+ m_fLeft(0) {}
+
+CXFA_TextTabstopsContext::~CXFA_TextTabstopsContext() {}
+
+void CXFA_TextTabstopsContext::Append(uint32_t dwAlign, FX_FLOAT fTabstops) {
+ int32_t i = 0;
+ for (i = 0; i < m_iTabCount; i++) {
+ XFA_TABSTOPS* pTabstop = m_tabstops.GetDataPtr(i);
+ if (fTabstops < pTabstop->fTabstops) {
+ break;
+ }
+ }
+ m_tabstops.InsertSpaceAt(i, 1);
+ XFA_TABSTOPS tabstop;
+ tabstop.dwAlign = dwAlign;
+ tabstop.fTabstops = fTabstops;
+ m_tabstops.SetAt(i, tabstop);
+ m_iTabCount++;
+}
+
+void CXFA_TextTabstopsContext::RemoveAll() {
+ m_tabstops.RemoveAll();
+ m_iTabCount = 0;
+}
+
+void CXFA_TextTabstopsContext::Reset() {
+ m_iTabIndex = -1;
+ m_bTabstops = false;
+ m_fTabWidth = 0;
+ m_fLeft = 0;
+}
diff --git a/xfa/fxfa/app/cxfa_texttabstopscontext.h b/xfa/fxfa/app/cxfa_texttabstopscontext.h
new file mode 100644
index 0000000000..8fe0e6273f
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_texttabstopscontext.h
@@ -0,0 +1,34 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_CXFA_TEXTTABSTOPSCONTEXT_H_
+#define XFA_FXFA_APP_CXFA_TEXTTABSTOPSCONTEXT_H_
+
+#include "core/fxcrt/fx_basic.h"
+
+struct XFA_TABSTOPS {
+ uint32_t dwAlign;
+ FX_FLOAT fTabstops;
+};
+
+class CXFA_TextTabstopsContext {
+ public:
+ CXFA_TextTabstopsContext();
+ ~CXFA_TextTabstopsContext();
+
+ void Append(uint32_t dwAlign, FX_FLOAT fTabstops);
+ void RemoveAll();
+ void Reset();
+
+ CFX_ArrayTemplate<XFA_TABSTOPS> m_tabstops;
+ int32_t m_iTabCount;
+ int32_t m_iTabIndex;
+ bool m_bTabstops;
+ FX_FLOAT m_fTabWidth;
+ FX_FLOAT m_fLeft;
+};
+
+#endif // XFA_FXFA_APP_CXFA_TEXTTABSTOPSCONTEXT_H_
diff --git a/xfa/fxfa/app/cxfa_textuserdata.cpp b/xfa/fxfa/app/cxfa_textuserdata.cpp
new file mode 100644
index 0000000000..209e4f2c21
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_textuserdata.cpp
@@ -0,0 +1,51 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/cxfa_textuserdata.h"
+
+#include "xfa/fde/css/fde_css.h"
+#include "xfa/fxfa/app/cxfa_linkuserdata.h"
+
+CXFA_TextUserData::CXFA_TextUserData(IFX_MemoryAllocator* pAllocator,
+ IFDE_CSSComputedStyle* pStyle)
+ : m_pStyle(pStyle),
+ m_pLinkData(nullptr),
+ m_pAllocator(pAllocator),
+ m_dwRefCount(0) {
+ ASSERT(m_pAllocator);
+ if (m_pStyle)
+ m_pStyle->Retain();
+}
+
+CXFA_TextUserData::CXFA_TextUserData(IFX_MemoryAllocator* pAllocator,
+ IFDE_CSSComputedStyle* pStyle,
+ CXFA_LinkUserData* pLinkData)
+ : m_pStyle(pStyle),
+ m_pLinkData(pLinkData),
+ m_pAllocator(pAllocator),
+ m_dwRefCount(0) {
+ ASSERT(m_pAllocator);
+ if (m_pStyle)
+ m_pStyle->Retain();
+}
+
+CXFA_TextUserData::~CXFA_TextUserData() {
+ if (m_pStyle)
+ m_pStyle->Release();
+ if (m_pLinkData)
+ m_pLinkData->Release();
+}
+
+uint32_t CXFA_TextUserData::Retain() {
+ return ++m_dwRefCount;
+}
+
+uint32_t CXFA_TextUserData::Release() {
+ uint32_t dwRefCount = --m_dwRefCount;
+ if (dwRefCount == 0)
+ FXTARGET_DeleteWith(CXFA_TextUserData, m_pAllocator, this);
+ return dwRefCount;
+}
diff --git a/xfa/fxfa/app/cxfa_textuserdata.h b/xfa/fxfa/app/cxfa_textuserdata.h
new file mode 100644
index 0000000000..f9e76f94d8
--- /dev/null
+++ b/xfa/fxfa/app/cxfa_textuserdata.h
@@ -0,0 +1,38 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_CXFA_TEXTUSERDATA_H_
+#define XFA_FXFA_APP_CXFA_TEXTUSERDATA_H_
+
+#include "core/fxcrt/fx_basic.h"
+#include "xfa/fgas/crt/fgas_memory.h"
+
+class CXFA_LinkUserData;
+class IFDE_CSSComputedStyle;
+class IFX_MemoryAllocator;
+
+class CXFA_TextUserData : public IFX_Retainable, public CFX_Target {
+ public:
+ CXFA_TextUserData(IFX_MemoryAllocator* pAllocator,
+ IFDE_CSSComputedStyle* pStyle);
+ CXFA_TextUserData(IFX_MemoryAllocator* pAllocator,
+ IFDE_CSSComputedStyle* pStyle,
+ CXFA_LinkUserData* pLinkData);
+ ~CXFA_TextUserData() override;
+
+ // IFX_Retainable:
+ uint32_t Retain() override;
+ uint32_t Release() override;
+
+ IFDE_CSSComputedStyle* m_pStyle;
+ CXFA_LinkUserData* m_pLinkData;
+
+ protected:
+ IFX_MemoryAllocator* m_pAllocator;
+ uint32_t m_dwRefCount;
+};
+
+#endif // XFA_FXFA_APP_CXFA_TEXTUSERDATA_H_
diff --git a/xfa/fxfa/app/xfa_ffdocview.cpp b/xfa/fxfa/app/xfa_ffdocview.cpp
index 4a3465bd9d..bf91baf082 100644
--- a/xfa/fxfa/app/xfa_ffdocview.cpp
+++ b/xfa/fxfa/app/xfa_ffdocview.cpp
@@ -25,7 +25,6 @@
#include "xfa/fxfa/app/xfa_fftextedit.h"
#include "xfa/fxfa/app/xfa_ffwidgetacc.h"
#include "xfa/fxfa/app/xfa_fwladapter.h"
-#include "xfa/fxfa/app/xfa_textlayout.h"
#include "xfa/fxfa/parser/cxfa_binditems.h"
#include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
#include "xfa/fxfa/parser/cxfa_scriptcontext.h"
diff --git a/xfa/fxfa/app/xfa_fffield.cpp b/xfa/fxfa/app/xfa_fffield.cpp
index 0bd6160944..aa8abbde86 100644
--- a/xfa/fxfa/app/xfa_fffield.cpp
+++ b/xfa/fxfa/app/xfa_fffield.cpp
@@ -15,8 +15,8 @@
#include "xfa/fwl/cfwl_messagesetfocus.h"
#include "xfa/fwl/cfwl_picturebox.h"
#include "xfa/fwl/cfwl_widgetmgr.h"
+#include "xfa/fxfa/app/cxfa_textlayout.h"
#include "xfa/fxfa/app/xfa_fwltheme.h"
-#include "xfa/fxfa/app/xfa_textlayout.h"
#include "xfa/fxfa/xfa_ffapp.h"
#include "xfa/fxfa/xfa_ffdoc.h"
#include "xfa/fxfa/xfa_ffdocview.h"
diff --git a/xfa/fxfa/app/xfa_ffnotify.cpp b/xfa/fxfa/app/xfa_ffnotify.cpp
index cb1964cb45..3aef5fcbfd 100644
--- a/xfa/fxfa/app/xfa_ffnotify.cpp
+++ b/xfa/fxfa/app/xfa_ffnotify.cpp
@@ -7,6 +7,7 @@
#include "xfa/fxfa/app/xfa_ffnotify.h"
#include "fxjs/cfxjse_value.h"
+#include "xfa/fxfa/app/cxfa_textlayout.h"
#include "xfa/fxfa/app/xfa_ffbarcode.h"
#include "xfa/fxfa/app/xfa_ffcheckbutton.h"
#include "xfa/fxfa/app/xfa_ffchoicelist.h"
@@ -23,7 +24,6 @@
#include "xfa/fxfa/app/xfa_fftextedit.h"
#include "xfa/fxfa/app/xfa_ffwidgetacc.h"
#include "xfa/fxfa/app/xfa_fwladapter.h"
-#include "xfa/fxfa/app/xfa_textlayout.h"
#include "xfa/fxfa/xfa_ffapp.h"
#include "xfa/fxfa/xfa_ffdoc.h"
#include "xfa/fxfa/xfa_ffdocview.h"
diff --git a/xfa/fxfa/app/xfa_ffpushbutton.cpp b/xfa/fxfa/app/xfa_ffpushbutton.cpp
index c12aa48d1a..4d4d1aad2d 100644
--- a/xfa/fxfa/app/xfa_ffpushbutton.cpp
+++ b/xfa/fxfa/app/xfa_ffpushbutton.cpp
@@ -9,9 +9,9 @@
#include "xfa/fwl/cfwl_notedriver.h"
#include "xfa/fwl/cfwl_pushbutton.h"
#include "xfa/fwl/cfwl_widgetmgr.h"
+#include "xfa/fxfa/app/cxfa_textlayout.h"
#include "xfa/fxfa/app/xfa_fffield.h"
#include "xfa/fxfa/app/xfa_ffwidgetacc.h"
-#include "xfa/fxfa/app/xfa_textlayout.h"
#include "xfa/fxfa/xfa_ffapp.h"
#include "xfa/fxfa/xfa_ffpageview.h"
#include "xfa/fxfa/xfa_ffwidget.h"
diff --git a/xfa/fxfa/app/xfa_fftext.cpp b/xfa/fxfa/app/xfa_fftext.cpp
index cc7b65cabc..2307ea0dc4 100644
--- a/xfa/fxfa/app/xfa_fftext.cpp
+++ b/xfa/fxfa/app/xfa_fftext.cpp
@@ -8,8 +8,11 @@
#include "xfa/fwl/fwl_widgetdef.h"
#include "xfa/fwl/fwl_widgethit.h"
+#include "xfa/fxfa/app/cxfa_linkuserdata.h"
+#include "xfa/fxfa/app/cxfa_pieceline.h"
+#include "xfa/fxfa/app/cxfa_textlayout.h"
#include "xfa/fxfa/app/xfa_ffdraw.h"
-#include "xfa/fxfa/app/xfa_textlayout.h"
+#include "xfa/fxfa/app/xfa_textpiece.h"
#include "xfa/fxfa/xfa_ffapp.h"
#include "xfa/fxfa/xfa_ffdoc.h"
#include "xfa/fxfa/xfa_ffpageview.h"
@@ -155,7 +158,8 @@ const FX_WCHAR* CXFA_FFText::GetLinkURLAtPoint(FX_FLOAT fx, FX_FLOAT fy) {
}
FX_FLOAT x(fx), y(fy);
FWLToClient(x, y);
- const CXFA_PieceLineArray* pPieceLines = pTextLayout->GetPieceLines();
+ const CFX_ArrayTemplate<CXFA_PieceLine*>* pPieceLines =
+ pTextLayout->GetPieceLines();
int32_t iCount = pPieceLines->GetSize();
for (int32_t i = 0; i < iCount; i++) {
CXFA_PieceLine* pPieceLine = pPieceLines->GetAt(i);
diff --git a/xfa/fxfa/app/xfa_fftextedit.cpp b/xfa/fxfa/app/xfa_fftextedit.cpp
index 26e3512c40..1088afdb6a 100644
--- a/xfa/fxfa/app/xfa_fftextedit.cpp
+++ b/xfa/fxfa/app/xfa_fftextedit.cpp
@@ -20,7 +20,6 @@
#include "xfa/fwl/cfwl_notedriver.h"
#include "xfa/fxfa/app/xfa_fffield.h"
#include "xfa/fxfa/app/xfa_fwladapter.h"
-#include "xfa/fxfa/app/xfa_textlayout.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/parser/xfa_localevalue.h"
#include "xfa/fxfa/xfa_ffapp.h"
diff --git a/xfa/fxfa/app/xfa_ffwidget.cpp b/xfa/fxfa/app/xfa_ffwidget.cpp
index f46c6a0381..64aed4f328 100644
--- a/xfa/fxfa/app/xfa_ffwidget.cpp
+++ b/xfa/fxfa/app/xfa_ffwidget.cpp
@@ -18,7 +18,7 @@
#include "core/fxge/cfx_pathdata.h"
#include "core/fxge/cfx_renderdevice.h"
#include "xfa/fwl/fwl_widgethit.h"
-#include "xfa/fxfa/app/xfa_textlayout.h"
+#include "xfa/fxfa/app/cxfa_textlayout.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/fxfa_widget.h"
#include "xfa/fxfa/parser/cxfa_corner.h"
diff --git a/xfa/fxfa/app/xfa_ffwidgetacc.cpp b/xfa/fxfa/app/xfa_ffwidgetacc.cpp
index e62ebca302..d4d9949c3e 100644
--- a/xfa/fxfa/app/xfa_ffwidgetacc.cpp
+++ b/xfa/fxfa/app/xfa_ffwidgetacc.cpp
@@ -19,7 +19,6 @@
#include "xfa/fxfa/app/xfa_ffchoicelist.h"
#include "xfa/fxfa/app/xfa_fffield.h"
#include "xfa/fxfa/app/xfa_fwladapter.h"
-#include "xfa/fxfa/app/xfa_textlayout.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
#include "xfa/fxfa/parser/cxfa_scriptcontext.h"
diff --git a/xfa/fxfa/app/xfa_ffwidgetacc.h b/xfa/fxfa/app/xfa_ffwidgetacc.h
index 092254b2d8..2daa35e6cd 100644
--- a/xfa/fxfa/app/xfa_ffwidgetacc.h
+++ b/xfa/fxfa/app/xfa_ffwidgetacc.h
@@ -7,7 +7,14 @@
#ifndef XFA_FXFA_APP_XFA_FFWIDGETACC_H_
#define XFA_FXFA_APP_XFA_FFWIDGETACC_H_
-#include "xfa/fxfa/app/xfa_textlayout.h"
+#include "core/fxcrt/fx_string.h"
+#include "xfa/fxfa/app/cxfa_textlayout.h"
+#include "xfa/fxfa/fxfa_widget.h"
+#include "xfa/fxfa/parser/cxfa_font.h"
+#include "xfa/fxfa/parser/cxfa_para.h"
+
+class CXFA_FFDoc;
+class CXFA_Node;
enum XFA_TEXTPROVIDERTYPE {
XFA_TEXTPROVIDERTYPE_Text,
diff --git a/xfa/fxfa/app/xfa_textlayout.h b/xfa/fxfa/app/xfa_textlayout.h
deleted file mode 100644
index fa0ca668ca..0000000000
--- a/xfa/fxfa/app/xfa_textlayout.h
+++ /dev/null
@@ -1,354 +0,0 @@
-// 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
-
-#ifndef XFA_FXFA_APP_XFA_TEXTLAYOUT_H_
-#define XFA_FXFA_APP_XFA_TEXTLAYOUT_H_
-
-#include <map>
-#include <memory>
-#include <vector>
-
-#include "xfa/fde/css/fde_css.h"
-#include "xfa/fde/fde_gedevice.h"
-#include "xfa/fgas/layout/fgas_rtfbreak.h"
-#include "xfa/fxfa/parser/xfa_object.h"
-#include "xfa/fxfa/xfa_ffdoc.h"
-
-#define XFA_LOADERCNTXTFLG_FILTERSPACE 0x001
-
-class CFDE_CSSStyleSelector;
-class CXFA_Para;
-class CXFA_Font;
-class CXFA_TextProvider;
-class CXFA_TextTabstopsContext;
-
-class CXFA_CSSTagProvider {
- public:
- using AttributeMap = std::map<CFX_WideString, CFX_WideString>;
-
- CXFA_CSSTagProvider();
- ~CXFA_CSSTagProvider();
-
- CFX_WideString GetTagName() { return m_wsTagName; }
-
- AttributeMap::iterator begin() { return m_Attributes.begin(); }
- AttributeMap::iterator end() { return m_Attributes.end(); }
-
- bool empty() const { return m_Attributes.empty(); }
-
- void SetTagNameObj(const CFX_WideString& wsName) { m_wsTagName = wsName; }
- void SetAttribute(const CFX_WideString& wsAttr,
- const CFX_WideString& wsValue) {
- m_Attributes.insert({wsAttr, wsValue});
- }
-
- bool m_bTagAvailable;
- bool m_bContent;
-
- protected:
- CFX_WideString m_wsTagName;
- AttributeMap m_Attributes;
-};
-
-class CXFA_TextParseContext : public CFX_Target {
- public:
- CXFA_TextParseContext();
- ~CXFA_TextParseContext() override;
-
- void SetDisplay(FDE_CSSDISPLAY eDisplay) { m_eDisplay = eDisplay; }
- FDE_CSSDISPLAY GetDisplay() const { return m_eDisplay; }
- void SetDecls(const CFDE_CSSDeclaration** ppDeclArray, int32_t iDeclCount);
- const CFDE_CSSDeclaration** GetDecls() {
- return const_cast<const CFDE_CSSDeclaration**>(m_ppMatchedDecls);
- }
- uint32_t CountDecls() const { return m_dwMatchedDecls; }
-
- IFDE_CSSComputedStyle* m_pParentStyle;
-
- protected:
- CFDE_CSSDeclaration** m_ppMatchedDecls;
- uint32_t m_dwMatchedDecls;
- FDE_CSSDISPLAY m_eDisplay;
-};
-
-class CXFA_TextParser {
- public:
- CXFA_TextParser();
- virtual ~CXFA_TextParser();
-
- void Reset();
- void DoParse(CFDE_XMLNode* pXMLContainer, CXFA_TextProvider* pTextProvider);
- IFDE_CSSComputedStyle* CreateRootStyle(CXFA_TextProvider* pTextProvider);
- IFDE_CSSComputedStyle* ComputeStyle(CFDE_XMLNode* pXMLNode,
- IFDE_CSSComputedStyle* pParentStyle);
- bool IsParsed() const { return !!m_pAllocator; }
-
- int32_t GetVAlign(CXFA_TextProvider* pTextProvider) const;
- FX_FLOAT GetTabInterval(IFDE_CSSComputedStyle* pStyle) const;
- int32_t CountTabs(IFDE_CSSComputedStyle* pStyle) const;
- bool IsSpaceRun(IFDE_CSSComputedStyle* pStyle) const;
- bool GetTabstops(IFDE_CSSComputedStyle* pStyle,
- CXFA_TextTabstopsContext* pTabstopContext);
- CFX_RetainPtr<CFGAS_GEFont> GetFont(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle) const;
- FX_FLOAT GetFontSize(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle) const;
- int32_t GetHorScale(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle,
- CFDE_XMLNode* pXMLNode) const;
- int32_t GetVerScale(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle) const;
- void GetUnderline(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle,
- int32_t& iUnderline,
- int32_t& iPeriod) const;
- void GetLinethrough(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle,
- int32_t& iLinethrough) const;
- FX_ARGB GetColor(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle) const;
- FX_FLOAT GetBaseline(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle) const;
- FX_FLOAT GetLineHeight(CXFA_TextProvider* pTextProvider,
- IFDE_CSSComputedStyle* pStyle,
- bool bFirst,
- FX_FLOAT fVerScale) const;
- bool GetEmbbedObj(CXFA_TextProvider* pTextProvider,
- CFDE_XMLNode* pXMLNode,
- CFX_WideString& wsValue);
- CXFA_TextParseContext* GetParseContextFromMap(CFDE_XMLNode* pXMLNode);
-
- protected:
- bool TagValidate(const CFX_WideString& str) const;
-
- private:
- void InitCSSData(CXFA_TextProvider* pTextProvider);
- void ParseRichText(CFDE_XMLNode* pXMLNode,
- IFDE_CSSComputedStyle* pParentStyle);
- void ParseTagInfo(CFDE_XMLNode* pXMLNode, CXFA_CSSTagProvider& tagProvider);
- IFDE_CSSStyleSheet* LoadDefaultSheetStyle();
- IFDE_CSSComputedStyle* CreateStyle(IFDE_CSSComputedStyle* pParentStyle);
- std::unique_ptr<IFX_MemoryAllocator> m_pAllocator;
- std::unique_ptr<CFDE_CSSStyleSelector> m_pSelector;
- IFDE_CSSStyleSheet* m_pUASheet;
- std::map<CFDE_XMLNode*, CXFA_TextParseContext*> m_mapXMLNodeToParseContext;
-};
-
-class CXFA_LoaderContext {
- public:
- CXFA_LoaderContext();
- ~CXFA_LoaderContext();
-
- bool m_bSaveLineHeight;
- FX_FLOAT m_fWidth;
- FX_FLOAT m_fHeight;
- FX_FLOAT m_fLastPos;
- FX_FLOAT m_fStartLineOffset;
- int32_t m_iChar;
- int32_t m_iLines;
- int32_t m_iTotalLines;
- CFDE_XMLNode* m_pXMLNode;
- CXFA_Node* m_pNode;
- IFDE_CSSComputedStyle* m_pParentStyle;
- CFX_ArrayTemplate<FX_FLOAT> m_lineHeights;
- uint32_t m_dwFlags;
- std::vector<FX_FLOAT> m_BlocksHeight;
-};
-
-class CXFA_LinkUserData : public IFX_Retainable, public CFX_Target {
- public:
- CXFA_LinkUserData(IFX_MemoryAllocator* pAllocator, FX_WCHAR* pszText);
- ~CXFA_LinkUserData() override;
-
- // IFX_Retainable:
- uint32_t Retain() override;
- uint32_t Release() override;
-
- const FX_WCHAR* GetLinkURL();
-
- protected:
- IFX_MemoryAllocator* m_pAllocator;
- uint32_t m_dwRefCount;
- CFX_WideString m_wsURLContent;
-};
-
-class CXFA_TextUserData : public IFX_Retainable, public CFX_Target {
- public:
- CXFA_TextUserData(IFX_MemoryAllocator* pAllocator,
- IFDE_CSSComputedStyle* pStyle);
- CXFA_TextUserData(IFX_MemoryAllocator* pAllocator,
- IFDE_CSSComputedStyle* pStyle,
- CXFA_LinkUserData* pLinkData);
- ~CXFA_TextUserData() override;
-
- // IFX_Retainable:
- uint32_t Retain() override;
- uint32_t Release() override;
-
- IFDE_CSSComputedStyle* m_pStyle;
- CXFA_LinkUserData* m_pLinkData;
-
- protected:
- IFX_MemoryAllocator* m_pAllocator;
- uint32_t m_dwRefCount;
-};
-
-class XFA_TextPiece : public CFX_Target {
- public:
- XFA_TextPiece();
- ~XFA_TextPiece() override;
-
- FX_WCHAR* pszText;
- int32_t iChars;
- int32_t* pWidths;
- int32_t iHorScale;
- int32_t iVerScale;
- int32_t iBidiLevel;
- int32_t iUnderline;
- int32_t iPeriod;
- int32_t iLineThrough;
- CFX_RetainPtr<CFGAS_GEFont> pFont;
- FX_ARGB dwColor;
- FX_FLOAT fFontSize;
- CFX_RectF rtPiece;
- CXFA_LinkUserData* pLinkData;
-};
-typedef CFX_ArrayTemplate<XFA_TextPiece*> CXFA_PieceArray;
-
-class CXFA_PieceLine : public CFX_Target {
- public:
- CXFA_PieceLine();
- ~CXFA_PieceLine() override;
-
- CXFA_PieceArray m_textPieces;
- CFX_Int32Array m_charCounts;
-};
-typedef CFX_ArrayTemplate<CXFA_PieceLine*> CXFA_PieceLineArray;
-
-struct XFA_TABSTOPS {
- uint32_t dwAlign;
- FX_FLOAT fTabstops;
-};
-
-class CXFA_TextTabstopsContext {
- public:
- CXFA_TextTabstopsContext();
- ~CXFA_TextTabstopsContext();
-
- void Append(uint32_t dwAlign, FX_FLOAT fTabstops);
- void RemoveAll();
- void Reset();
-
- CFX_ArrayTemplate<XFA_TABSTOPS> m_tabstops;
- int32_t m_iTabCount;
- int32_t m_iTabIndex;
- bool m_bTabstops;
- FX_FLOAT m_fTabWidth;
- FX_FLOAT m_fLeft;
-};
-
-class CXFA_TextLayout {
- public:
- explicit CXFA_TextLayout(CXFA_TextProvider* pTextProvider);
- ~CXFA_TextLayout();
-
- int32_t GetText(CFX_WideString& wsText);
- FX_FLOAT GetLayoutHeight();
- FX_FLOAT StartLayout(FX_FLOAT fWidth = -1);
- bool DoLayout(int32_t iBlockIndex,
- FX_FLOAT& fCalcHeight,
- FX_FLOAT fContentAreaHeight = -1,
- FX_FLOAT fTextHeight = -1);
-
- bool CalcSize(const CFX_SizeF& minSize,
- const CFX_SizeF& maxSize,
- CFX_SizeF& defaultSize);
- bool Layout(const CFX_SizeF& size, FX_FLOAT* fHeight = nullptr);
- void ItemBlocks(const CFX_RectF& rtText, int32_t iBlockIndex);
- bool DrawString(CFX_RenderDevice* pFxDevice,
- const CFX_Matrix& tmDoc2Device,
- const CFX_RectF& rtClip,
- int32_t iBlock = 0);
- bool IsLoaded() const { return m_pieceLines.GetSize() > 0; }
- void Unload();
- const CXFA_PieceLineArray* GetPieceLines();
-
- bool m_bHasBlock;
- CFX_Int32Array m_Blocks;
-
- private:
- void GetTextDataNode();
- CFDE_XMLNode* GetXMLContainerNode();
- CFX_RTFBreak* CreateBreak(bool bDefault);
- void InitBreak(FX_FLOAT fLineWidth);
- void InitBreak(IFDE_CSSComputedStyle* pStyle,
- FDE_CSSDISPLAY eDisplay,
- FX_FLOAT fLineWidth,
- CFDE_XMLNode* pXMLNode,
- IFDE_CSSComputedStyle* pParentStyle = nullptr);
- bool Loader(const CFX_SizeF& szText,
- FX_FLOAT& fLinePos,
- bool bSavePieces = true);
- void LoadText(CXFA_Node* pNode,
- const CFX_SizeF& szText,
- FX_FLOAT& fLinePos,
- bool bSavePieces);
- bool LoadRichText(CFDE_XMLNode* pXMLNode,
- const CFX_SizeF& szText,
- FX_FLOAT& fLinePos,
- IFDE_CSSComputedStyle* pParentStyle,
- bool bSavePieces,
- CXFA_LinkUserData* pLinkData = nullptr,
- bool bEndBreak = true,
- bool bIsOl = false,
- int32_t iLiCount = 0);
- bool AppendChar(const CFX_WideString& wsText,
- FX_FLOAT& fLinePos,
- FX_FLOAT fSpaceAbove,
- bool bSavePieces);
- void AppendTextLine(uint32_t dwStatus,
- FX_FLOAT& fLinePos,
- bool bSavePieces,
- bool bEndBreak = false);
- void EndBreak(uint32_t dwStatus, FX_FLOAT& fLinePos, bool bDefault);
- bool IsEnd(bool bSavePieces);
- void ProcessText(CFX_WideString& wsText);
- void UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom);
- void RenderString(CFDE_RenderDevice* pDevice,
- CFDE_Brush* pBrush,
- CXFA_PieceLine* pPieceLine,
- int32_t iPiece,
- FXTEXT_CHARPOS* pCharPos,
- const CFX_Matrix& tmDoc2Device);
- void RenderPath(CFDE_RenderDevice* pDevice,
- CFDE_Pen* pPen,
- CXFA_PieceLine* pPieceLine,
- int32_t iPiece,
- FXTEXT_CHARPOS* pCharPos,
- const CFX_Matrix& tmDoc2Device);
- int32_t GetDisplayPos(const XFA_TextPiece* pPiece,
- FXTEXT_CHARPOS* pCharPos,
- bool bCharCode = false);
- bool ToRun(const XFA_TextPiece* pPiece, FX_RTFTEXTOBJ& tr);
- void DoTabstops(IFDE_CSSComputedStyle* pStyle, CXFA_PieceLine* pPieceLine);
- bool Layout(int32_t iBlock);
- int32_t CountBlocks() const;
-
- CXFA_TextProvider* m_pTextProvider;
- CXFA_Node* m_pTextDataNode;
- bool m_bRichText;
- std::unique_ptr<IFX_MemoryAllocator> m_pAllocator;
- std::unique_ptr<CFX_RTFBreak> m_pBreak;
- std::unique_ptr<CXFA_LoaderContext> m_pLoader;
- int32_t m_iLines;
- FX_FLOAT m_fMaxWidth;
- CXFA_TextParser m_textParser;
- CXFA_PieceLineArray m_pieceLines;
- std::unique_ptr<CXFA_TextTabstopsContext> m_pTabstopContext;
- bool m_bBlockContinue;
-};
-
-#endif // XFA_FXFA_APP_XFA_TEXTLAYOUT_H_
diff --git a/xfa/fxfa/app/xfa_textpiece.cpp b/xfa/fxfa/app/xfa_textpiece.cpp
new file mode 100644
index 0000000000..4b57aa82d9
--- /dev/null
+++ b/xfa/fxfa/app/xfa_textpiece.cpp
@@ -0,0 +1,17 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_textpiece.h"
+
+#include "xfa/fxfa/app/cxfa_linkuserdata.h"
+
+XFA_TextPiece::XFA_TextPiece()
+ : pszText(nullptr), pFont(nullptr), pLinkData(nullptr) {}
+
+XFA_TextPiece::~XFA_TextPiece() {
+ if (pLinkData)
+ pLinkData->Release();
+}
diff --git a/xfa/fxfa/app/xfa_textpiece.h b/xfa/fxfa/app/xfa_textpiece.h
new file mode 100644
index 0000000000..4047cd2d7f
--- /dev/null
+++ b/xfa/fxfa/app/xfa_textpiece.h
@@ -0,0 +1,39 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_TEXTPIECE_H_
+#define XFA_FXFA_APP_XFA_TEXTPIECE_H_
+
+#include "core/fxcrt/fx_basic.h"
+#include "core/fxcrt/fx_coordinates.h"
+#include "core/fxcrt/fx_string.h"
+#include "core/fxge/fx_dib.h"
+#include "xfa/fgas/font/cfgas_gefont.h"
+
+class CXFA_LinkUserData;
+
+class XFA_TextPiece : public CFX_Target {
+ public:
+ XFA_TextPiece();
+ ~XFA_TextPiece() override;
+
+ FX_WCHAR* pszText;
+ int32_t iChars;
+ int32_t* pWidths;
+ int32_t iHorScale;
+ int32_t iVerScale;
+ int32_t iBidiLevel;
+ int32_t iUnderline;
+ int32_t iPeriod;
+ int32_t iLineThrough;
+ CFX_RetainPtr<CFGAS_GEFont> pFont;
+ FX_ARGB dwColor;
+ FX_FLOAT fFontSize;
+ CFX_RectF rtPiece;
+ CXFA_LinkUserData* pLinkData;
+};
+
+#endif // XFA_FXFA_APP_XFA_TEXTPIECE_H_