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