| 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 |