1 // Copyright 2017 The PDFium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #ifndef XFA_FXFA_CXFA_TEXTLAYOUT_H_ 8 #define XFA_FXFA_CXFA_TEXTLAYOUT_H_ 9 10 #include <memory> 11 #include <vector> 12 13 #include "core/fxcrt/css/cfx_css.h" 14 #include "core/fxcrt/fx_coordinates.h" 15 #include "core/fxcrt/retain_ptr.h" 16 #include "core/fxcrt/span.h" 17 #include "core/fxcrt/unowned_ptr.h" 18 #include "core/fxcrt/widestring.h" 19 #include "core/fxge/dib/fx_dib.h" 20 #include "fxjs/gc/heap.h" 21 #include "v8/include/cppgc/garbage-collected.h" 22 #include "v8/include/cppgc/member.h" 23 #include "v8/include/cppgc/visitor.h" 24 #include "xfa/fgas/layout/cfgas_char.h" 25 #include "xfa/fgas/layout/cfgas_textpiece.h" 26 #include "xfa/fxfa/fxfa_basic.h" 27 28 class CFGAS_LinkUserData; 29 class CFGAS_RTFBreak; 30 class CFX_CSSComputedStyle; 31 class CFX_RenderDevice; 32 class CFX_XMLNode; 33 class CXFA_FFDoc; 34 class CXFA_Node; 35 class CXFA_TextParser; 36 class CXFA_TextProvider; 37 class CXFA_TextTabstopsContext; 38 class TextCharPos; 39 40 class CXFA_TextLayout final : public cppgc::GarbageCollected<CXFA_TextLayout> { 41 public: 42 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; 43 ~CXFA_TextLayout(); 44 45 void Trace(cppgc::Visitor* visitor) const; 46 47 float GetLayoutHeight(); 48 float StartLayout(float fWidth); 49 float DoLayout(float fTextHeight); 50 float DoSplitLayout(size_t szBlockIndex, 51 float fCalcHeight, 52 float fTextHeight); 53 float Layout(const CFX_SizeF& size); 54 55 CFX_SizeF CalcSize(const CFX_SizeF& minSize, const CFX_SizeF& maxSize); 56 void ItemBlocks(const CFX_RectF& rtText, size_t szBlockIndex); 57 bool DrawString(CFX_RenderDevice* pFxDevice, 58 const CFX_Matrix& mtDoc2Device, 59 const CFX_RectF& rtClip, 60 size_t szBlockIndex); IsLoaded()61 bool IsLoaded() const { return !m_pieceLines.empty(); } 62 void Unload(); HasBlock()63 bool HasBlock() const { return m_bHasBlock; } ClearBlocks()64 void ClearBlocks() { m_Blocks.clear(); } ResetHasBlock()65 void ResetHasBlock() { m_bHasBlock = false; } 66 67 // Returns empty string when no link is present. 68 WideString GetLinkURLAtPoint(const CFX_PointF& point); 69 70 private: 71 class TextPiece : public CFGAS_TextPiece { 72 public: 73 TextPiece(); 74 ~TextPiece(); 75 76 int32_t iUnderline = 0; 77 int32_t iLineThrough = 0; 78 XFA_AttributeValue iPeriod = XFA_AttributeValue::All; 79 FX_ARGB dwColor = 0; 80 RetainPtr<CFGAS_LinkUserData> pLinkData; 81 }; 82 83 class PieceLine { 84 public: 85 PieceLine(); 86 ~PieceLine(); 87 88 std::vector<std::unique_ptr<TextPiece>> m_textPieces; 89 std::vector<size_t> m_charCounts; 90 }; 91 92 struct BlockData { 93 size_t szIndex; 94 size_t szLength; 95 }; 96 97 struct BlockHeight { 98 size_t szBlockIndex; 99 float fHeight; 100 }; 101 102 struct LoaderContext : public cppgc::GarbageCollected<LoaderContext> { 103 LoaderContext(); 104 ~LoaderContext(); 105 106 void Trace(cppgc::Visitor* visitor) const; 107 108 bool bSaveLineHeight = false; 109 bool bFilterSpace = false; 110 float fWidth = 0; 111 float fHeight = 0; 112 float fLastPos = 0; 113 float fStartLineOffset = 0; 114 size_t nCharIdx = 0; 115 // TODO(thestig): Make this size_t? 116 int32_t iTotalLines = -1; 117 UnownedPtr<const CFX_XMLNode> pXMLNode; 118 RetainPtr<CFX_CSSComputedStyle> pParentStyle; 119 cppgc::Member<CXFA_Node> pNode; 120 std::vector<float> lineHeights; 121 std::vector<BlockHeight> blockHeights; 122 }; 123 124 CXFA_TextLayout(CXFA_FFDoc* doc, CXFA_TextProvider* pTextProvider); 125 126 void GetTextDataNode(); 127 CFX_XMLNode* GetXMLContainerNode(); 128 std::unique_ptr<CFGAS_RTFBreak> CreateBreak(bool bDefault); 129 void InitBreak(float fLineWidth); 130 void InitBreak(CFX_CSSComputedStyle* pStyle, 131 CFX_CSSDisplay eDisplay, 132 float fLineWidth, 133 const CFX_XMLNode* pXMLNode, 134 CFX_CSSComputedStyle* pParentStyle); 135 void Loader(float textWidth, float* pLinePos, bool bSavePieces); 136 void LoadText(CXFA_Node* pNode, 137 float textWidth, 138 float* pLinePos, 139 bool bSavePieces); 140 bool LoadRichText(const CFX_XMLNode* pXMLNode, 141 float textWidth, 142 float* pLinePos, 143 RetainPtr<CFX_CSSComputedStyle> pParentStyle, 144 bool bSavePieces, 145 RetainPtr<CFGAS_LinkUserData> pLinkData, 146 bool bEndBreak, 147 bool bIsOl, 148 int32_t iLiCount); 149 bool AppendChar(const WideString& wsText, 150 float* pLinePos, 151 float fSpaceAbove, 152 bool bSavePieces); 153 void AppendTextLine(CFGAS_Char::BreakType dwStatus, 154 float* pLinePos, 155 bool bSavePieces, 156 bool bEndBreak); 157 void EndBreak(CFGAS_Char::BreakType dwStatus, float* pLinePos, bool bDefault); 158 bool IsEnd(bool bSavePieces); 159 void UpdateAlign(float fHeight, float fBottom); 160 void RenderString(CFX_RenderDevice* pDevice, 161 PieceLine* pPieceLine, 162 size_t szPiece, 163 pdfium::span<TextCharPos> pCharPos, 164 const CFX_Matrix& mtDoc2Device); 165 void RenderPath(CFX_RenderDevice* pDevice, 166 const PieceLine* pPieceLine, 167 size_t szPiece, 168 pdfium::span<TextCharPos> pCharPos, 169 const CFX_Matrix& mtDoc2Device); 170 size_t GetDisplayPos(const TextPiece* pPiece, 171 pdfium::span<TextCharPos> pCharPos); 172 void DoTabstops(CFX_CSSComputedStyle* pStyle, PieceLine* pPieceLine); 173 bool LayoutInternal(size_t szBlockIndex); 174 size_t CountBlocks() const; 175 size_t GetNextIndexFromLastBlockData() const; 176 void UpdateLoaderHeight(float fTextHeight); 177 178 bool m_bHasBlock = false; 179 bool m_bRichText = false; 180 int32_t m_iLines = 0; 181 float m_fMaxWidth = 0; 182 std::vector<BlockData> m_Blocks; 183 cppgc::Member<CXFA_FFDoc> const m_pDoc; 184 cppgc::Member<CXFA_TextProvider> const m_pTextProvider; 185 cppgc::Member<CXFA_Node> m_pTextDataNode; 186 cppgc::Member<CXFA_TextParser> m_pTextParser; 187 cppgc::Member<LoaderContext> m_pLoader; 188 std::unique_ptr<CFGAS_RTFBreak> m_pBreak; 189 std::vector<std::unique_ptr<PieceLine>> m_pieceLines; 190 std::unique_ptr<CXFA_TextTabstopsContext> m_pTabstopContext; 191 }; 192 193 #endif // XFA_FXFA_CXFA_TEXTLAYOUT_H_ 194