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_FGAS_LAYOUT_FGAS_TEXTBREAK_H_ 8 #define XFA_FGAS_LAYOUT_FGAS_TEXTBREAK_H_ 9 10 #include <deque> 11 #include <memory> 12 #include <vector> 13 14 #include "core/fxcrt/fx_ucd.h" 15 #include "core/fxge/cfx_renderdevice.h" 16 #include "third_party/base/stl_util.h" 17 #include "xfa/fgas/crt/fgas_utils.h" 18 19 class CFX_Char; 20 class CFGAS_GEFont; 21 class CFX_TxtChar; 22 class CFX_TxtPiece; 23 class IFX_TxtAccess; 24 struct FDE_TEXTEDITPIECE; 25 26 #define FX_TXTBREAKPOLICY_None 0x00 27 #define FX_TXTBREAKPOLICY_Pagination 0x01 28 #define FX_TXTBREAKPOLICY_SpaceBreak 0x02 29 #define FX_TXTBREAKPOLICY_NumberBreak 0x04 30 #define FX_TXTBREAK_None 0x00 31 #define FX_TXTBREAK_PieceBreak 0x01 32 #define FX_TXTBREAK_LineBreak 0x02 33 #define FX_TXTBREAK_ParagraphBreak 0x03 34 #define FX_TXTBREAK_PageBreak 0x04 35 #define FX_TXTBREAK_ControlChar 0x10 36 #define FX_TXTBREAK_BreakChar 0x20 37 #define FX_TXTBREAK_UnknownChar 0x40 38 #define FX_TXTBREAK_RemoveChar 0x80 39 #define FX_TXTLAYOUTSTYLE_MutipleFormat 0x0001 40 #define FX_TXTLAYOUTSTYLE_VerticalLayout 0x0002 41 #define FX_TXTLAYOUTSTYLE_VerticalChars 0x0004 42 #define FX_TXTLAYOUTSTYLE_ReverseLine 0x0008 43 #define FX_TXTLAYOUTSTYLE_ArabicContext 0x0010 44 #define FX_TXTLAYOUTSTYLE_ArabicShapes 0x0020 45 #define FX_TXTLAYOUTSTYLE_RTLReadingOrder 0x0040 46 #define FX_TXTLAYOUTSTYLE_ExpandTab 0x0100 47 #define FX_TXTLAYOUTSTYLE_SingleLine 0x0200 48 #define FX_TXTLAYOUTSTYLE_CombText 0x0400 49 #define FX_TXTCHARSTYLE_Alignment 0x000F 50 #define FX_TXTCHARSTYLE_ArabicNumber 0x0010 51 #define FX_TXTCHARSTYLE_ArabicShadda 0x0020 52 #define FX_TXTCHARSTYLE_OddBidiLevel 0x0040 53 #define FX_TXTCHARSTYLE_RTLReadingOrder 0x0080 54 #define FX_TXTCHARSTYLE_ArabicContext 0x0300 55 #define FX_TXTCHARSTYLE_ArabicIndic 0x0400 56 #define FX_TXTCHARSTYLE_ArabicComma 0x0800 57 #define FX_TXTLINEALIGNMENT_Left 0 58 #define FX_TXTLINEALIGNMENT_Center 1 59 #define FX_TXTLINEALIGNMENT_Right 2 60 #define FX_TXTLINEALIGNMENT_Justified (1 << 2) 61 #define FX_TXTLINEALIGNMENT_Distributed (2 << 2) 62 #define FX_TXTLINEALIGNMENT_JustifiedLeft \ 63 (FX_TXTLINEALIGNMENT_Left | FX_TXTLINEALIGNMENT_Justified) 64 #define FX_TXTLINEALIGNMENT_JustifiedCenter \ 65 (FX_TXTLINEALIGNMENT_Center | FX_TXTLINEALIGNMENT_Justified) 66 #define FX_TXTLINEALIGNMENT_JustifiedRight \ 67 (FX_TXTLINEALIGNMENT_Right | FX_TXTLINEALIGNMENT_Justified) 68 #define FX_TXTLINEALIGNMENT_DistributedLeft \ 69 (FX_TXTLINEALIGNMENT_Left | FX_TXTLINEALIGNMENT_Distributed) 70 #define FX_TXTLINEALIGNMENT_DistributedCenter \ 71 (FX_TXTLINEALIGNMENT_Center | FX_TXTLINEALIGNMENT_Distributed) 72 #define FX_TXTLINEALIGNMENT_DistributedRight \ 73 (FX_TXTLINEALIGNMENT_Right | FX_TXTLINEALIGNMENT_Distributed) 74 #define FX_TXTLINEALIGNMENT_LowerMask 0x03 75 #define FX_TXTLINEALIGNMENT_HigherMask 0x0C 76 #define FX_TXTBREAK_MinimumTabWidth 160000 77 78 struct FX_TPO { 79 int32_t index; 80 int32_t pos; 81 82 bool operator<(const FX_TPO& that) const { return pos < that.pos; } 83 }; 84 85 class IFX_TxtAccess { 86 public: ~IFX_TxtAccess()87 virtual ~IFX_TxtAccess() {} 88 virtual FX_WCHAR GetChar(const FDE_TEXTEDITPIECE* pIdentity, 89 int32_t index) const = 0; 90 virtual int32_t GetWidth(const FDE_TEXTEDITPIECE* pIdentity, 91 int32_t index) const = 0; 92 }; 93 94 struct FX_TXTRUN { 95 FX_TXTRUN(); 96 FX_TXTRUN(const FX_TXTRUN& other); 97 ~FX_TXTRUN(); 98 99 IFX_TxtAccess* pAccess; 100 const FDE_TEXTEDITPIECE* pIdentity; 101 CFX_WideString wsStr; 102 int32_t* pWidths; 103 int32_t iLength; 104 CFX_RetainPtr<CFGAS_GEFont> pFont; 105 FX_FLOAT fFontSize; 106 uint32_t dwStyles; 107 int32_t iHorizontalScale; 108 int32_t iVerticalScale; 109 int32_t iCharRotation; 110 uint32_t dwCharStyles; 111 const CFX_RectF* pRect; 112 FX_WCHAR wLineBreakChar; 113 bool bSkipSpace; 114 }; 115 116 class CFX_TxtPiece { 117 public: 118 CFX_TxtPiece(); 119 GetEndPos()120 int32_t GetEndPos() const { 121 return m_iWidth < 0 ? m_iStartPos : m_iStartPos + m_iWidth; 122 } GetLength()123 int32_t GetLength() const { return m_iChars; } GetEndChar()124 int32_t GetEndChar() const { return m_iStartChar + m_iChars; } GetCharPtr(int32_t index)125 CFX_TxtChar* GetCharPtr(int32_t index) const { 126 ASSERT(index > -1 && index < m_iChars && m_pChars); 127 return &(*m_pChars)[m_iStartChar + index]; 128 } GetString(FX_WCHAR * pText)129 void GetString(FX_WCHAR* pText) const { 130 ASSERT(pText); 131 int32_t iEndChar = m_iStartChar + m_iChars; 132 for (int32_t i = m_iStartChar; i < iEndChar; i++) 133 *pText++ = static_cast<FX_WCHAR>((*m_pChars)[i].m_wCharCode); 134 } GetString(CFX_WideString & wsText)135 void GetString(CFX_WideString& wsText) const { 136 FX_WCHAR* pText = wsText.GetBuffer(m_iChars); 137 GetString(pText); 138 wsText.ReleaseBuffer(m_iChars); 139 } GetWidths(int32_t * pWidths)140 void GetWidths(int32_t* pWidths) const { 141 ASSERT(pWidths); 142 int32_t iEndChar = m_iStartChar + m_iChars; 143 for (int32_t i = m_iStartChar; i < iEndChar; i++) 144 *pWidths++ = (*m_pChars)[i].m_iCharWidth; 145 } 146 147 uint32_t m_dwStatus; 148 int32_t m_iStartPos; 149 int32_t m_iWidth; 150 int32_t m_iStartChar; 151 int32_t m_iChars; 152 int32_t m_iBidiLevel; 153 int32_t m_iBidiPos; 154 int32_t m_iHorizontalScale; 155 int32_t m_iVerticalScale; 156 uint32_t m_dwCharStyles; 157 std::vector<CFX_TxtChar>* m_pChars; 158 void* m_pUserData; 159 }; 160 161 typedef CFX_BaseArrayTemplate<CFX_TxtPiece> CFX_TxtPieceArray; 162 163 class CFX_TxtLine { 164 public: 165 explicit CFX_TxtLine(int32_t iBlockSize); 166 ~CFX_TxtLine(); 167 CountChars()168 int32_t CountChars() const { 169 return pdfium::CollectionSize<int32_t>(*m_pLineChars); 170 } 171 GetCharPtr(int32_t index)172 CFX_TxtChar* GetCharPtr(int32_t index) const { 173 ASSERT(index >= 0 && 174 index < pdfium::CollectionSize<int32_t>(*m_pLineChars)); 175 return &(*m_pLineChars)[index]; 176 } 177 CountPieces()178 int32_t CountPieces() const { return m_pLinePieces->GetSize(); } GetPiecePtr(int32_t index)179 CFX_TxtPiece* GetPiecePtr(int32_t index) const { 180 ASSERT(index > -1 && index < m_pLinePieces->GetSize()); 181 return m_pLinePieces->GetPtrAt(index); 182 } 183 GetString(CFX_WideString & wsStr)184 void GetString(CFX_WideString& wsStr) const { 185 int32_t iCount = pdfium::CollectionSize<int32_t>(*m_pLineChars); 186 FX_WCHAR* pBuf = wsStr.GetBuffer(iCount); 187 for (int32_t i = 0; i < iCount; i++) 188 *pBuf++ = static_cast<FX_WCHAR>((*m_pLineChars)[i].m_wCharCode); 189 wsStr.ReleaseBuffer(iCount); 190 } 191 192 void RemoveAll(bool bLeaveMemory = false) { 193 m_pLineChars->clear(); 194 m_pLinePieces->RemoveAll(bLeaveMemory); 195 m_iWidth = 0; 196 m_iArabicChars = 0; 197 } 198 199 std::unique_ptr<std::vector<CFX_TxtChar>> m_pLineChars; 200 std::unique_ptr<CFX_TxtPieceArray> m_pLinePieces; 201 int32_t m_iStart; 202 int32_t m_iWidth; 203 int32_t m_iArabicChars; 204 }; 205 206 class CFX_TxtBreak { 207 public: 208 explicit CFX_TxtBreak(uint32_t dwPolicies); 209 ~CFX_TxtBreak(); 210 211 void SetLineWidth(FX_FLOAT fLineWidth); 212 void SetLinePos(FX_FLOAT fLinePos); GetLayoutStyles()213 uint32_t GetLayoutStyles() const { return m_dwLayoutStyles; } 214 void SetLayoutStyles(uint32_t dwLayoutStyles); 215 void SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont); 216 void SetFontSize(FX_FLOAT fFontSize); 217 void SetTabWidth(FX_FLOAT fTabWidth, bool bEquidistant); 218 void SetDefaultChar(FX_WCHAR wch); 219 void SetParagraphBreakChar(FX_WCHAR wch); 220 void SetLineBreakTolerance(FX_FLOAT fTolerance); 221 void SetHorizontalScale(int32_t iScale); 222 void SetCharRotation(int32_t iCharRotation); 223 void SetCharSpace(FX_FLOAT fCharSpace); 224 void SetAlignment(int32_t iAlignment); 225 void SetCombWidth(FX_FLOAT fCombWidth); 226 void SetUserData(void* pUserData); 227 uint32_t AppendChar(FX_WCHAR wch); 228 uint32_t EndBreak(uint32_t dwStatus = FX_TXTBREAK_PieceBreak); 229 int32_t CountBreakPieces() const; 230 const CFX_TxtPiece* GetBreakPiece(int32_t index) const; 231 void ClearBreakPieces(); 232 void Reset(); 233 int32_t GetDisplayPos(const FX_TXTRUN* pTxtRun, 234 FXTEXT_CHARPOS* pCharPos, 235 bool bCharCode = false, 236 CFX_WideString* pWSForms = nullptr) const; 237 std::vector<CFX_RectF> GetCharRects(const FX_TXTRUN* pTxtRun, 238 bool bCharBBox = false) const; 239 void AppendChar_PageLoad(CFX_TxtChar* pCurChar, uint32_t dwProps); 240 uint32_t AppendChar_Combination(CFX_TxtChar* pCurChar, int32_t iRotation); 241 uint32_t AppendChar_Tab(CFX_TxtChar* pCurChar, int32_t iRotation); 242 uint32_t AppendChar_Control(CFX_TxtChar* pCurChar, int32_t iRotation); 243 uint32_t AppendChar_Arabic(CFX_TxtChar* pCurChar, int32_t iRotation); 244 uint32_t AppendChar_Others(CFX_TxtChar* pCurChar, int32_t iRotation); 245 246 private: 247 void FontChanged(); 248 void SetBreakStatus(); 249 int32_t GetLineRotation(uint32_t dwStyles) const; 250 CFX_TxtChar* GetLastChar(int32_t index, bool bOmitChar = true) const; 251 CFX_TxtLine* GetTxtLine() const; 252 CFX_TxtPieceArray* GetTxtPieces() const; 253 FX_CHARTYPE GetUnifiedCharType(FX_CHARTYPE dwType) const; 254 void ResetArabicContext(); 255 void ResetContextCharStyles(); 256 void EndBreak_UpdateArabicShapes(); 257 bool EndBreak_SplitLine(CFX_TxtLine* pNextLine, 258 bool bAllChars, 259 uint32_t dwStatus); 260 void EndBreak_BidiLine(std::deque<FX_TPO>* tpos, uint32_t dwStatus); 261 void EndBreak_Alignment(const std::deque<FX_TPO>& tpos, 262 bool bAllChars, 263 uint32_t dwStatus); 264 int32_t GetBreakPos(std::vector<CFX_TxtChar>& ca, 265 int32_t& iEndPos, 266 bool bAllChars = false, 267 bool bOnlyBrk = false); 268 void SplitTextLine(CFX_TxtLine* pCurLine, 269 CFX_TxtLine* pNextLine, 270 bool bAllChars = false); 271 272 uint32_t m_dwPolicies; 273 bool m_bPagination; 274 int32_t m_iLineWidth; 275 uint32_t m_dwLayoutStyles; 276 bool m_bVertical; 277 bool m_bArabicContext; 278 bool m_bArabicShapes; 279 bool m_bRTL; 280 bool m_bSingleLine; 281 bool m_bCombText; 282 int32_t m_iArabicContext; 283 int32_t m_iCurArabicContext; 284 CFX_RetainPtr<CFGAS_GEFont> m_pFont; 285 int32_t m_iFontSize; 286 bool m_bEquidistant; 287 int32_t m_iTabWidth; 288 FX_WCHAR m_wDefChar; 289 FX_WCHAR m_wParagBreakChar; 290 int32_t m_iDefChar; 291 int32_t m_iLineRotation; 292 int32_t m_iCharRotation; 293 int32_t m_iRotation; 294 int32_t m_iAlignment; 295 uint32_t m_dwContextCharStyles; 296 int32_t m_iCombWidth; 297 void* m_pUserData; 298 FX_CHARTYPE m_eCharType; 299 bool m_bCurRTL; 300 int32_t m_iCurAlignment; 301 bool m_bArabicNumber; 302 bool m_bArabicComma; 303 std::unique_ptr<CFX_TxtLine> m_pTxtLine1; 304 std::unique_ptr<CFX_TxtLine> m_pTxtLine2; 305 CFX_TxtLine* m_pCurLine; 306 int32_t m_iReady; 307 int32_t m_iTolerance; 308 int32_t m_iHorScale; 309 int32_t m_iCharSpace; 310 }; 311 312 #endif // XFA_FGAS_LAYOUT_FGAS_TEXTBREAK_H_ 313