• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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