OLD | NEW |
| (Empty) |
1 // Copyright 2014 PDFium Authors. All rights reserved. | |
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_SRC_FXFA_APP_XFA_TEXTLAYOUT_H_ | |
8 #define XFA_SRC_FXFA_APP_XFA_TEXTLAYOUT_H_ | |
9 | |
10 #include "xfa/src/fde/css/fde_css.h" | |
11 #include "xfa/src/fde/fde_brush.h" | |
12 #include "xfa/src/fde/fde_renderdevice.h" | |
13 #include "xfa/src/fgas/layout/fgas_rtfbreak.h" | |
14 #include "xfa/src/fxfa/app/xfa_ffdoc.h" | |
15 #include "xfa/src/fxfa/parser/xfa_object.h" | |
16 | |
17 #define XFA_LOADERCNTXTFLG_FILTERSPACE 0x001 | |
18 | |
19 class CXFA_Para; | |
20 class CXFA_Font; | |
21 class CXFA_TextTabstopsContext; | |
22 | |
23 class IXFA_TextProvider { | |
24 public: | |
25 virtual ~IXFA_TextProvider() {} | |
26 virtual CXFA_Node* GetTextNode(FX_BOOL& bRichText) = 0; | |
27 virtual CXFA_Para GetParaNode() = 0; | |
28 virtual CXFA_Font GetFontNode() = 0; | |
29 virtual FX_BOOL IsCheckButtonAndAutoWidth() = 0; | |
30 virtual CXFA_FFDoc* GetDocNode() = 0; | |
31 virtual FX_BOOL GetEmbbedObj(FX_BOOL bURI, | |
32 FX_BOOL bRaw, | |
33 const CFX_WideString& wsAttr, | |
34 CFX_WideString& wsValue) = 0; | |
35 }; | |
36 | |
37 class CXFA_CSSTagProvider : public IFDE_CSSTagProvider { | |
38 public: | |
39 CXFA_CSSTagProvider() : m_bTagAviliable(FALSE), m_bContent(FALSE) {} | |
40 virtual ~CXFA_CSSTagProvider(); | |
41 virtual CFX_WideStringC GetTagName() { return m_wsTagName; } | |
42 virtual FX_POSITION GetFirstAttribute() { | |
43 return m_Attributes.GetStartPosition(); | |
44 } | |
45 virtual void GetNextAttribute(FX_POSITION& pos, | |
46 CFX_WideStringC& wsAttr, | |
47 CFX_WideStringC& wsValue); | |
48 void SetTagNameObj(const CFX_WideString& wsName) { m_wsTagName = wsName; } | |
49 void SetAttribute(const CFX_WideString& wsAttr, | |
50 const CFX_WideString& wsValue); | |
51 FX_BOOL m_bTagAviliable; | |
52 FX_BOOL m_bContent; | |
53 | |
54 protected: | |
55 CFX_WideString m_wsTagName; | |
56 CFX_MapPtrToPtr m_Attributes; | |
57 }; | |
58 | |
59 class CXFA_TextParseContext : public CFX_Target { | |
60 public: | |
61 CXFA_TextParseContext() | |
62 : m_pParentStyle(nullptr), | |
63 m_ppMatchedDecls(nullptr), | |
64 m_dwMatchedDecls(0), | |
65 m_eDisplay(FDE_CSSDISPLAY_None) {} | |
66 ~CXFA_TextParseContext() { | |
67 if (m_pParentStyle) | |
68 m_pParentStyle->Release(); | |
69 FX_Free(m_ppMatchedDecls); | |
70 } | |
71 void SetDisplay(FDE_CSSDISPLAY eDisplay) { m_eDisplay = eDisplay; } | |
72 FDE_CSSDISPLAY GetDisplay() const { return m_eDisplay; } | |
73 void SetDecls(const IFDE_CSSDeclaration** ppDeclArray, int32_t iDeclCount); | |
74 const IFDE_CSSDeclaration** GetDecls() { | |
75 return (const IFDE_CSSDeclaration**)m_ppMatchedDecls; | |
76 } | |
77 FX_DWORD CountDecls() const { return m_dwMatchedDecls; } | |
78 IFDE_CSSComputedStyle* m_pParentStyle; | |
79 | |
80 protected: | |
81 IFDE_CSSDeclaration** m_ppMatchedDecls; | |
82 FX_DWORD m_dwMatchedDecls; | |
83 FDE_CSSDISPLAY m_eDisplay; | |
84 }; | |
85 | |
86 class CXFA_TextParser { | |
87 public: | |
88 CXFA_TextParser() : m_pAllocator(NULL), m_pSelector(NULL), m_pUASheet(NULL) {} | |
89 virtual ~CXFA_TextParser(); | |
90 void Reset(); | |
91 void DoParse(IFDE_XMLNode* pXMLContainer, IXFA_TextProvider* pTextProvider); | |
92 IFDE_CSSComputedStyle* CreateRootStyle(IXFA_TextProvider* pTextProvider); | |
93 IFDE_CSSComputedStyle* ComputeStyle(IFDE_XMLNode* pXMLNode, | |
94 IFDE_CSSComputedStyle* pParentStyle); | |
95 FX_BOOL IsParsed() const { return m_pAllocator != NULL; } | |
96 | |
97 int32_t GetVAlgin(IXFA_TextProvider* pTextProvider) const; | |
98 FX_FLOAT GetTabInterval(IFDE_CSSComputedStyle* pStyle) const; | |
99 int32_t CountTabs(IFDE_CSSComputedStyle* pStyle) const; | |
100 FX_BOOL IsSpaceRun(IFDE_CSSComputedStyle* pStyle) const; | |
101 FX_BOOL GetTabstops(IFDE_CSSComputedStyle* pStyle, | |
102 CXFA_TextTabstopsContext* pTabstopContext); | |
103 IFX_Font* GetFont(IXFA_TextProvider* pTextProvider, | |
104 IFDE_CSSComputedStyle* pStyle) const; | |
105 FX_FLOAT GetFontSize(IXFA_TextProvider* pTextProvider, | |
106 IFDE_CSSComputedStyle* pStyle) const; | |
107 int32_t GetHorScale(IXFA_TextProvider* pTextProvider, | |
108 IFDE_CSSComputedStyle* pStyle, | |
109 IFDE_XMLNode* pXMLNode) const; | |
110 int32_t GetVerScale(IXFA_TextProvider* pTextProvider, | |
111 IFDE_CSSComputedStyle* pStyle) const; | |
112 void GetUnderline(IXFA_TextProvider* pTextProvider, | |
113 IFDE_CSSComputedStyle* pStyle, | |
114 int32_t& iUnderline, | |
115 int32_t& iPeriod) const; | |
116 void GetLinethrough(IXFA_TextProvider* pTextProvider, | |
117 IFDE_CSSComputedStyle* pStyle, | |
118 int32_t& iLinethrough) const; | |
119 FX_ARGB GetColor(IXFA_TextProvider* pTextProvider, | |
120 IFDE_CSSComputedStyle* pStyle) const; | |
121 FX_FLOAT GetBaseline(IXFA_TextProvider* pTextProvider, | |
122 IFDE_CSSComputedStyle* pStyle) const; | |
123 FX_FLOAT GetLineHeight(IXFA_TextProvider* pTextProvider, | |
124 IFDE_CSSComputedStyle* pStyle, | |
125 FX_BOOL bFirst, | |
126 FX_FLOAT fVerScale) const; | |
127 FX_BOOL GetEmbbedObj(IXFA_TextProvider* pTextProvider, | |
128 IFDE_XMLNode* pXMLNode, | |
129 CFX_WideString& wsValue); | |
130 CXFA_TextParseContext* GetParseContextFromMap(IFDE_XMLNode* pXMLNode); | |
131 | |
132 private: | |
133 void InitCSSData(IXFA_TextProvider* pTextProvider); | |
134 void ParseRichText(IFDE_XMLNode* pXMLNode, | |
135 IFDE_CSSComputedStyle* pParentStyle); | |
136 void ParseTagInfo(IFDE_XMLNode* pXMLNode, CXFA_CSSTagProvider& tagProvider); | |
137 IFDE_CSSStyleSheet* LoadDefaultSheetStyle(); | |
138 IFDE_CSSComputedStyle* CreateStyle(IFDE_CSSComputedStyle* pParentStyle); | |
139 IFX_MEMAllocator* m_pAllocator; | |
140 IFDE_CSSStyleSelector* m_pSelector; | |
141 IFDE_CSSStyleSheet* m_pUASheet; | |
142 CFX_MapPtrTemplate<IFDE_XMLNode*, CXFA_TextParseContext*> | |
143 m_mapXMLNodeToParseContext; | |
144 }; | |
145 | |
146 class CXFA_LoaderContext { | |
147 public: | |
148 CXFA_LoaderContext() | |
149 : m_bSaveLineHeight(FALSE), | |
150 m_fWidth(0), | |
151 m_fHeight(0), | |
152 m_fLastPos(0), | |
153 m_fStartLineOffset(0), | |
154 m_iChar(0), | |
155 m_iTotalLines(-1), | |
156 m_pXMLNode(NULL), | |
157 m_pNode(NULL), | |
158 m_pParentStyle(NULL), | |
159 m_dwFlags(0) {} | |
160 FX_BOOL m_bSaveLineHeight; | |
161 FX_FLOAT m_fWidth; | |
162 FX_FLOAT m_fHeight; | |
163 FX_FLOAT m_fLastPos; | |
164 FX_FLOAT m_fStartLineOffset; | |
165 int32_t m_iChar; | |
166 int32_t m_iLines; | |
167 int32_t m_iTotalLines; | |
168 IFDE_XMLNode* m_pXMLNode; | |
169 CXFA_Node* m_pNode; | |
170 IFDE_CSSComputedStyle* m_pParentStyle; | |
171 CFX_ArrayTemplate<FX_FLOAT> m_lineHeights; | |
172 FX_DWORD m_dwFlags; | |
173 CFX_FloatArray m_BlocksHeight; | |
174 }; | |
175 | |
176 class CXFA_LinkUserData : public IFX_Unknown, public CFX_Target { | |
177 public: | |
178 CXFA_LinkUserData(IFX_MEMAllocator* pAllocator, FX_WCHAR* pszText) | |
179 : m_pAllocator(pAllocator), m_dwRefCount(1) { | |
180 m_pszURLContent = pszText; | |
181 } | |
182 ~CXFA_LinkUserData() {} | |
183 virtual FX_DWORD Release() { | |
184 FX_DWORD dwRefCount = --m_dwRefCount; | |
185 if (dwRefCount <= 0) { | |
186 FXTARGET_DeleteWith(CXFA_LinkUserData, m_pAllocator, this); | |
187 } | |
188 return dwRefCount; | |
189 } | |
190 virtual FX_DWORD AddRef() { return ++m_dwRefCount; } | |
191 | |
192 public: | |
193 const FX_WCHAR* GetLinkURL() { return m_pszURLContent; } | |
194 | |
195 protected: | |
196 IFX_MEMAllocator* m_pAllocator; | |
197 FX_DWORD m_dwRefCount; | |
198 CFX_WideString m_pszURLContent; | |
199 }; | |
200 | |
201 class CXFA_TextUserData : public IFX_Unknown, public CFX_Target { | |
202 public: | |
203 CXFA_TextUserData(IFX_MEMAllocator* pAllocator, IFDE_CSSComputedStyle* pStyle) | |
204 : m_pStyle(pStyle), | |
205 m_pLinkData(nullptr), | |
206 m_pAllocator(pAllocator), | |
207 m_dwRefCount(0) { | |
208 FXSYS_assert(m_pAllocator); | |
209 if (m_pStyle) | |
210 m_pStyle->AddRef(); | |
211 } | |
212 CXFA_TextUserData(IFX_MEMAllocator* pAllocator, | |
213 IFDE_CSSComputedStyle* pStyle, | |
214 CXFA_LinkUserData* pLinkData) | |
215 : m_pStyle(pStyle), | |
216 m_pLinkData(pLinkData), | |
217 m_pAllocator(pAllocator), | |
218 m_dwRefCount(0) { | |
219 FXSYS_assert(m_pAllocator); | |
220 if (m_pStyle) | |
221 m_pStyle->AddRef(); | |
222 } | |
223 ~CXFA_TextUserData() { | |
224 if (m_pStyle) | |
225 m_pStyle->Release(); | |
226 if (m_pLinkData) | |
227 m_pLinkData->Release(); | |
228 } | |
229 virtual FX_DWORD Release() { | |
230 FX_DWORD dwRefCount = --m_dwRefCount; | |
231 if (dwRefCount == 0) { | |
232 FXTARGET_DeleteWith(CXFA_TextUserData, m_pAllocator, this); | |
233 } | |
234 return dwRefCount; | |
235 } | |
236 virtual FX_DWORD AddRef() { return ++m_dwRefCount; } | |
237 | |
238 IFDE_CSSComputedStyle* m_pStyle; | |
239 CXFA_LinkUserData* m_pLinkData; | |
240 | |
241 protected: | |
242 IFX_MEMAllocator* m_pAllocator; | |
243 FX_DWORD m_dwRefCount; | |
244 }; | |
245 | |
246 class XFA_TextPiece : public CFX_Target { | |
247 public: | |
248 XFA_TextPiece() : pszText(nullptr), pFont(nullptr), pLinkData(nullptr) {} | |
249 ~XFA_TextPiece() { | |
250 if (pLinkData) | |
251 pLinkData->Release(); | |
252 } | |
253 | |
254 FX_WCHAR* pszText; | |
255 int32_t iChars; | |
256 int32_t* pWidths; | |
257 int32_t iHorScale; | |
258 int32_t iVerScale; | |
259 int32_t iBidiLevel; | |
260 int32_t iUnderline; | |
261 int32_t iPeriod; | |
262 int32_t iLineThrough; | |
263 IFX_Font* pFont; | |
264 FX_ARGB dwColor; | |
265 FX_FLOAT fFontSize; | |
266 CFX_RectF rtPiece; | |
267 CXFA_LinkUserData* pLinkData; | |
268 }; | |
269 typedef CFX_ArrayTemplate<XFA_TextPiece*> CXFA_PieceArray; | |
270 | |
271 class CXFA_PieceLine : public CFX_Target { | |
272 public: | |
273 CXFA_PieceLine() {} | |
274 CXFA_PieceArray m_textPieces; | |
275 CFX_Int32Array m_charCounts; | |
276 }; | |
277 typedef CFX_ArrayTemplate<CXFA_PieceLine*> CXFA_PieceLineArray; | |
278 | |
279 struct XFA_TABSTOPS { | |
280 FX_DWORD dwAlign; | |
281 FX_FLOAT fTabstops; | |
282 }; | |
283 | |
284 class CXFA_TextTabstopsContext { | |
285 public: | |
286 CXFA_TextTabstopsContext() | |
287 : m_iTabCount(0), | |
288 m_iTabIndex(-1), | |
289 m_bTabstops(FALSE), | |
290 m_fTabWidth(0), | |
291 m_fLeft(0) {} | |
292 void Append(FX_DWORD dwAlign, FX_FLOAT fTabstops) { | |
293 int32_t i = 0; | |
294 for (i = 0; i < m_iTabCount; i++) { | |
295 XFA_TABSTOPS* pTabstop = m_tabstops.GetDataPtr(i); | |
296 if (fTabstops < pTabstop->fTabstops) { | |
297 break; | |
298 } | |
299 } | |
300 m_tabstops.InsertSpaceAt(i, 1); | |
301 XFA_TABSTOPS tabstop; | |
302 tabstop.dwAlign = dwAlign; | |
303 tabstop.fTabstops = fTabstops; | |
304 m_tabstops.SetAt(i, tabstop); | |
305 m_iTabCount++; | |
306 } | |
307 void RemoveAll() { | |
308 m_tabstops.RemoveAll(); | |
309 m_iTabCount = 0; | |
310 } | |
311 void Reset() { | |
312 m_iTabIndex = -1; | |
313 m_bTabstops = FALSE; | |
314 m_fTabWidth = 0; | |
315 m_fLeft = 0; | |
316 } | |
317 CFX_ArrayTemplate<XFA_TABSTOPS> m_tabstops; | |
318 int32_t m_iTabCount; | |
319 int32_t m_iTabIndex; | |
320 FX_BOOL m_bTabstops; | |
321 FX_FLOAT m_fTabWidth; | |
322 FX_FLOAT m_fLeft; | |
323 }; | |
324 | |
325 class CXFA_TextLayout { | |
326 public: | |
327 CXFA_TextLayout(IXFA_TextProvider* pTextProvider); | |
328 virtual ~CXFA_TextLayout(); | |
329 int32_t GetText(CFX_WideString& wsText); | |
330 FX_FLOAT GetLayoutHeight(); | |
331 FX_FLOAT StartLayout(FX_FLOAT fWidth = -1); | |
332 FX_BOOL DoLayout(int32_t iBlockIndex, | |
333 FX_FLOAT& fCalcHeight, | |
334 FX_FLOAT fContentAreaHeight = -1, | |
335 FX_FLOAT fTextHeight = -1); | |
336 | |
337 FX_BOOL CalcSize(const CFX_SizeF& minSize, | |
338 const CFX_SizeF& maxSize, | |
339 CFX_SizeF& defaultSize); | |
340 FX_BOOL Layout(const CFX_SizeF& size, FX_FLOAT* fHeight = NULL); | |
341 void ItemBlocks(const CFX_RectF& rtText, int32_t iBlockIndex); | |
342 FX_BOOL DrawString(CFX_RenderDevice* pFxDevice, | |
343 const CFX_Matrix& tmDoc2Device, | |
344 const CFX_RectF& rtClip, | |
345 int32_t iBlock = 0); | |
346 FX_BOOL IsLoaded() const { return m_pieceLines.GetSize() > 0; } | |
347 void Unload(); | |
348 const CXFA_PieceLineArray* GetPieceLines(); | |
349 | |
350 FX_BOOL m_bHasBlock; | |
351 CFX_Int32Array m_Blocks; | |
352 | |
353 private: | |
354 void GetTextDataNode(); | |
355 IFDE_XMLNode* GetXMLContainerNode(); | |
356 IFX_RTFBreak* CreateBreak(FX_BOOL bDefault); | |
357 void InitBreak(FX_FLOAT fLineWidth); | |
358 void InitBreak(IFDE_CSSComputedStyle* pStyle, | |
359 FDE_CSSDISPLAY eDisplay, | |
360 FX_FLOAT fLineWidth, | |
361 IFDE_XMLNode* pXMLNode, | |
362 IFDE_CSSComputedStyle* pParentStyle = NULL); | |
363 FX_BOOL Loader(const CFX_SizeF& szText, | |
364 FX_FLOAT& fLinePos, | |
365 FX_BOOL bSavePieces = TRUE); | |
366 void LoadText(CXFA_Node* pNode, | |
367 const CFX_SizeF& szText, | |
368 FX_FLOAT& fLinePos, | |
369 FX_BOOL bSavePieces); | |
370 FX_BOOL LoadRichText(IFDE_XMLNode* pXMLNode, | |
371 const CFX_SizeF& szText, | |
372 FX_FLOAT& fLinePos, | |
373 IFDE_CSSComputedStyle* pParentStyle, | |
374 FX_BOOL bSavePieces, | |
375 CXFA_LinkUserData* pLinkData = NULL, | |
376 FX_BOOL bEndBreak = TRUE, | |
377 FX_BOOL bIsOl = FALSE, | |
378 int32_t iLiCount = 0); | |
379 FX_BOOL AppendChar(const CFX_WideString& wsText, | |
380 FX_FLOAT& fLinePos, | |
381 FX_FLOAT fSpaceAbove, | |
382 FX_BOOL bSavePieces); | |
383 void AppendTextLine(FX_DWORD dwStatus, | |
384 FX_FLOAT& fLinePos, | |
385 FX_BOOL bSavePieces, | |
386 FX_BOOL bEndBreak = FALSE); | |
387 void EndBreak(FX_DWORD dwStatus, FX_FLOAT& fLinePos, FX_BOOL bDefault); | |
388 FX_BOOL IsEnd(FX_BOOL bSavePieces); | |
389 void ProcessText(CFX_WideString& wsText); | |
390 void UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom); | |
391 void RenderString(IFDE_RenderDevice* pDevice, | |
392 IFDE_SolidBrush* pBrush, | |
393 CXFA_PieceLine* pPieceLine, | |
394 int32_t iPiece, | |
395 FXTEXT_CHARPOS* pCharPos, | |
396 const CFX_Matrix& tmDoc2Device); | |
397 void RenderPath(IFDE_RenderDevice* pDevice, | |
398 IFDE_Pen* pPen, | |
399 CXFA_PieceLine* pPieceLine, | |
400 int32_t iPiece, | |
401 FXTEXT_CHARPOS* pCharPos, | |
402 const CFX_Matrix& tmDoc2Device); | |
403 int32_t GetDisplayPos(const XFA_TextPiece* pPiece, | |
404 FXTEXT_CHARPOS* pCharPos, | |
405 FX_BOOL bCharCode = FALSE); | |
406 FX_BOOL ToRun(const XFA_TextPiece* pPiece, FX_RTFTEXTOBJ& tr); | |
407 void DoTabstops(IFDE_CSSComputedStyle* pStyle, CXFA_PieceLine* pPieceLine); | |
408 FX_BOOL Layout(int32_t iBlock); | |
409 int32_t CountBlocks() const; | |
410 | |
411 IXFA_TextProvider* m_pTextProvider; | |
412 CXFA_Node* m_pTextDataNode; | |
413 FX_BOOL m_bRichText; | |
414 IFX_MEMAllocator* m_pAllocator; | |
415 IFX_RTFBreak* m_pBreak; | |
416 CXFA_LoaderContext* m_pLoader; | |
417 int32_t m_iLines; | |
418 FX_FLOAT m_fMaxWidth; | |
419 CXFA_TextParser m_textParser; | |
420 CXFA_PieceLineArray m_pieceLines; | |
421 CXFA_TextTabstopsContext* m_pTabstopContext; | |
422 FX_BOOL m_bBlockContinue; | |
423 }; | |
424 | |
425 #endif // XFA_SRC_FXFA_APP_XFA_TEXTLAYOUT_H_ | |
OLD | NEW |