dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 1 | // Copyright 2016 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 | |
dsinclair | 1727aee | 2016-09-29 13:12:56 -0700 | [diff] [blame] | 7 | #ifndef CORE_FPDFDOC_CPDF_VARIABLETEXT_H_ |
| 8 | #define CORE_FPDFDOC_CPDF_VARIABLETEXT_H_ |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 9 | |
thestig | 821d59e | 2016-05-11 12:59:22 -0700 | [diff] [blame] | 10 | #include <memory> |
| 11 | |
dsinclair | 448c433 | 2016-08-02 12:07:35 -0700 | [diff] [blame] | 12 | #include "core/fpdfdoc/cpvt_arraytemplate.h" |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 13 | #include "core/fpdfdoc/cpvt_floatrect.h" |
dsinclair | 1727aee | 2016-09-29 13:12:56 -0700 | [diff] [blame] | 14 | #include "core/fpdfdoc/cpvt_line.h" |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 15 | #include "core/fpdfdoc/cpvt_lineinfo.h" |
dsinclair | 1727aee | 2016-09-29 13:12:56 -0700 | [diff] [blame] | 16 | #include "core/fpdfdoc/cpvt_wordplace.h" |
| 17 | #include "core/fpdfdoc/cpvt_wordrange.h" |
dsinclair | a52ab74 | 2016-09-29 13:59:29 -0700 | [diff] [blame] | 18 | #include "core/fxcrt/fx_coordinates.h" |
| 19 | #include "core/fxcrt/fx_string.h" |
| 20 | #include "core/fxcrt/fx_system.h" |
dsinclair | 74a34fc | 2016-09-29 16:41:42 -0700 | [diff] [blame] | 21 | #include "core/fxge/fx_font.h" |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 22 | |
Dan Sinclair | f528eee | 2017-02-14 11:52:07 -0500 | [diff] [blame] | 23 | class CPVT_Word; |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 24 | class CSection; |
| 25 | class IPVT_FontMap; |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 26 | struct CPVT_SecProps; |
| 27 | struct CPVT_Section; |
| 28 | struct CPVT_SectionInfo; |
Dan Sinclair | f528eee | 2017-02-14 11:52:07 -0500 | [diff] [blame] | 29 | |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 30 | struct CPVT_WordInfo; |
thestig | 2c3a16a | 2016-05-10 13:24:16 -0700 | [diff] [blame] | 31 | struct CPVT_WordProps; |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 32 | |
| 33 | #define VARIABLETEXT_HALF 0.5f |
| 34 | |
dsinclair | 448c433 | 2016-08-02 12:07:35 -0700 | [diff] [blame] | 35 | class CPDF_VariableText { |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 36 | public: |
| 37 | enum class ScriptType { Normal, Super, Sub }; |
| 38 | |
| 39 | class Iterator { |
| 40 | public: |
| 41 | explicit Iterator(CPDF_VariableText* pVT); |
| 42 | ~Iterator(); |
| 43 | |
tsepez | 12f3e4a | 2016-11-02 15:17:29 -0700 | [diff] [blame] | 44 | bool NextWord(); |
| 45 | bool PrevWord(); |
| 46 | bool NextLine(); |
| 47 | bool PrevLine(); |
| 48 | bool NextSection(); |
| 49 | bool PrevSection(); |
| 50 | bool SetWord(const CPVT_Word& word); |
| 51 | bool GetWord(CPVT_Word& word) const; |
| 52 | bool GetLine(CPVT_Line& line) const; |
| 53 | bool GetSection(CPVT_Section& section) const; |
| 54 | bool SetSection(const CPVT_Section& section); |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 55 | void SetAt(int32_t nWordIndex); |
| 56 | void SetAt(const CPVT_WordPlace& place); |
| 57 | const CPVT_WordPlace& GetAt() const { return m_CurPos; } |
| 58 | |
| 59 | private: |
| 60 | CPVT_WordPlace m_CurPos; |
| 61 | CPDF_VariableText* const m_pVT; |
| 62 | }; |
| 63 | |
| 64 | class Provider { |
| 65 | public: |
thestig | 2c3a16a | 2016-05-10 13:24:16 -0700 | [diff] [blame] | 66 | explicit Provider(IPVT_FontMap* pFontMap); |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 67 | virtual ~Provider(); |
| 68 | |
npm | 41d6bbe | 2016-09-14 11:54:44 -0700 | [diff] [blame] | 69 | virtual int32_t GetCharWidth(int32_t nFontIndex, uint16_t word); |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 70 | virtual int32_t GetTypeAscent(int32_t nFontIndex); |
| 71 | virtual int32_t GetTypeDescent(int32_t nFontIndex); |
| 72 | virtual int32_t GetWordFontIndex(uint16_t word, |
| 73 | int32_t charset, |
| 74 | int32_t nFontIndex); |
tsepez | 12f3e4a | 2016-11-02 15:17:29 -0700 | [diff] [blame] | 75 | virtual bool IsLatinWord(uint16_t word); |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 76 | virtual int32_t GetDefaultFontIndex(); |
| 77 | |
| 78 | private: |
thestig | 594b20b | 2016-05-12 21:56:43 -0700 | [diff] [blame] | 79 | IPVT_FontMap* const m_pFontMap; |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 80 | }; |
| 81 | |
| 82 | CPDF_VariableText(); |
dsinclair | 448c433 | 2016-08-02 12:07:35 -0700 | [diff] [blame] | 83 | ~CPDF_VariableText(); |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 84 | |
thestig | 2c3a16a | 2016-05-10 13:24:16 -0700 | [diff] [blame] | 85 | void SetProvider(CPDF_VariableText::Provider* pProvider); |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 86 | CPDF_VariableText::Iterator* GetIterator(); |
| 87 | |
dsinclair | 448c433 | 2016-08-02 12:07:35 -0700 | [diff] [blame] | 88 | void SetContentRect(const CPVT_FloatRect& rect); |
| 89 | CFX_FloatRect GetContentRect() const; |
| 90 | void SetPlateRect(const CFX_FloatRect& rect); |
| 91 | const CFX_FloatRect& GetPlateRect() const; |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 92 | |
dsinclair | 74a30b7 | 2016-07-18 10:18:56 -0700 | [diff] [blame] | 93 | void SetAlignment(int32_t nFormat) { m_nAlignment = nFormat; } |
| 94 | void SetPasswordChar(uint16_t wSubWord) { m_wSubWord = wSubWord; } |
| 95 | void SetLimitChar(int32_t nLimitChar) { m_nLimitChar = nLimitChar; } |
| 96 | void SetCharSpace(FX_FLOAT fCharSpace) { m_fCharSpace = fCharSpace; } |
tsepez | 12f3e4a | 2016-11-02 15:17:29 -0700 | [diff] [blame] | 97 | void SetMultiLine(bool bMultiLine) { m_bMultiLine = bMultiLine; } |
| 98 | void SetAutoReturn(bool bAuto) { m_bLimitWidth = bAuto; } |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 99 | void SetFontSize(FX_FLOAT fFontSize) { m_fFontSize = fFontSize; } |
dsinclair | 74a30b7 | 2016-07-18 10:18:56 -0700 | [diff] [blame] | 100 | void SetCharArray(int32_t nCharArray) { m_nCharArray = nCharArray; } |
tsepez | 12f3e4a | 2016-11-02 15:17:29 -0700 | [diff] [blame] | 101 | void SetAutoFontSize(bool bAuto) { m_bAutoFontSize = bAuto; } |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 102 | void Initialize(); |
weili | f4bb580 | 2016-06-14 17:21:14 -0700 | [diff] [blame] | 103 | |
tsepez | 12f3e4a | 2016-11-02 15:17:29 -0700 | [diff] [blame] | 104 | bool IsValid() const { return m_bInitial; } |
weili | f4bb580 | 2016-06-14 17:21:14 -0700 | [diff] [blame] | 105 | |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 106 | void RearrangeAll(); |
| 107 | void RearrangePart(const CPVT_WordRange& PlaceRange); |
| 108 | void ResetAll(); |
tsepez | 067990c | 2016-09-13 06:46:40 -0700 | [diff] [blame] | 109 | void SetText(const CFX_WideString& text); |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 110 | CPVT_WordPlace InsertWord(const CPVT_WordPlace& place, |
| 111 | uint16_t word, |
dsinclair | 74a30b7 | 2016-07-18 10:18:56 -0700 | [diff] [blame] | 112 | int32_t charset, |
| 113 | const CPVT_WordProps* pWordProps); |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 114 | CPVT_WordPlace InsertSection(const CPVT_WordPlace& place, |
dsinclair | 74a30b7 | 2016-07-18 10:18:56 -0700 | [diff] [blame] | 115 | const CPVT_SecProps* pSecProps, |
| 116 | const CPVT_WordProps* pWordProps); |
Dan Sinclair | 812e96c | 2017-03-13 16:43:37 -0400 | [diff] [blame^] | 117 | CPVT_WordPlace InsertText(const CPVT_WordPlace& place, const wchar_t* text); |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 118 | CPVT_WordPlace DeleteWords(const CPVT_WordRange& PlaceRange); |
| 119 | CPVT_WordPlace DeleteWord(const CPVT_WordPlace& place); |
| 120 | CPVT_WordPlace BackSpaceWord(const CPVT_WordPlace& place); |
| 121 | |
| 122 | int32_t GetTotalWords() const; |
| 123 | FX_FLOAT GetFontSize() const { return m_fFontSize; } |
| 124 | int32_t GetAlignment() const { return m_nAlignment; } |
| 125 | uint16_t GetPasswordChar() const { return GetSubWord(); } |
| 126 | int32_t GetCharArray() const { return m_nCharArray; } |
| 127 | int32_t GetLimitChar() const { return m_nLimitChar; } |
tsepez | 12f3e4a | 2016-11-02 15:17:29 -0700 | [diff] [blame] | 128 | bool IsMultiLine() const { return m_bMultiLine; } |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 129 | int32_t GetHorzScale() const { return m_nHorzScale; } |
| 130 | FX_FLOAT GetCharSpace() const { return m_fCharSpace; } |
| 131 | CPVT_WordPlace GetBeginWordPlace() const; |
| 132 | CPVT_WordPlace GetEndWordPlace() const; |
| 133 | CPVT_WordPlace GetPrevWordPlace(const CPVT_WordPlace& place) const; |
| 134 | CPVT_WordPlace GetNextWordPlace(const CPVT_WordPlace& place) const; |
Dan Sinclair | f528eee | 2017-02-14 11:52:07 -0500 | [diff] [blame] | 135 | CPVT_WordPlace SearchWordPlace(const CFX_PointF& point) const; |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 136 | CPVT_WordPlace GetUpWordPlace(const CPVT_WordPlace& place, |
Dan Sinclair | f528eee | 2017-02-14 11:52:07 -0500 | [diff] [blame] | 137 | const CFX_PointF& point) const; |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 138 | CPVT_WordPlace GetDownWordPlace(const CPVT_WordPlace& place, |
Dan Sinclair | f528eee | 2017-02-14 11:52:07 -0500 | [diff] [blame] | 139 | const CFX_PointF& point) const; |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 140 | CPVT_WordPlace GetLineBeginPlace(const CPVT_WordPlace& place) const; |
| 141 | CPVT_WordPlace GetLineEndPlace(const CPVT_WordPlace& place) const; |
| 142 | CPVT_WordPlace GetSectionBeginPlace(const CPVT_WordPlace& place) const; |
| 143 | CPVT_WordPlace GetSectionEndPlace(const CPVT_WordPlace& place) const; |
| 144 | void UpdateWordPlace(CPVT_WordPlace& place) const; |
| 145 | CPVT_WordPlace AdjustLineHeader(const CPVT_WordPlace& place, |
tsepez | 12f3e4a | 2016-11-02 15:17:29 -0700 | [diff] [blame] | 146 | bool bPrevOrNext) const; |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 147 | int32_t WordPlaceToWordIndex(const CPVT_WordPlace& place) const; |
| 148 | CPVT_WordPlace WordIndexToWordPlace(int32_t index) const; |
| 149 | |
| 150 | uint16_t GetSubWord() const { return m_wSubWord; } |
| 151 | |
dsinclair | 448c433 | 2016-08-02 12:07:35 -0700 | [diff] [blame] | 152 | FX_FLOAT GetPlateWidth() const { return m_rcPlate.right - m_rcPlate.left; } |
| 153 | FX_FLOAT GetPlateHeight() const { return m_rcPlate.top - m_rcPlate.bottom; } |
| 154 | CFX_SizeF GetPlateSize() const; |
Dan Sinclair | f528eee | 2017-02-14 11:52:07 -0500 | [diff] [blame] | 155 | CFX_PointF GetBTPoint() const; |
| 156 | CFX_PointF GetETPoint() const; |
dsinclair | 448c433 | 2016-08-02 12:07:35 -0700 | [diff] [blame] | 157 | |
Dan Sinclair | f528eee | 2017-02-14 11:52:07 -0500 | [diff] [blame] | 158 | CFX_PointF InToOut(const CFX_PointF& point) const; |
| 159 | CFX_PointF OutToIn(const CFX_PointF& point) const; |
dsinclair | 448c433 | 2016-08-02 12:07:35 -0700 | [diff] [blame] | 160 | CFX_FloatRect InToOut(const CPVT_FloatRect& rect) const; |
| 161 | CPVT_FloatRect OutToIn(const CFX_FloatRect& rect) const; |
| 162 | |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 163 | private: |
| 164 | friend class CTypeset; |
| 165 | friend class CSection; |
| 166 | |
npm | 41d6bbe | 2016-09-14 11:54:44 -0700 | [diff] [blame] | 167 | int32_t GetCharWidth(int32_t nFontIndex, uint16_t Word, uint16_t SubWord); |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 168 | int32_t GetTypeAscent(int32_t nFontIndex); |
| 169 | int32_t GetTypeDescent(int32_t nFontIndex); |
| 170 | int32_t GetWordFontIndex(uint16_t word, int32_t charset, int32_t nFontIndex); |
| 171 | int32_t GetDefaultFontIndex(); |
tsepez | 12f3e4a | 2016-11-02 15:17:29 -0700 | [diff] [blame] | 172 | bool IsLatinWord(uint16_t word); |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 173 | |
| 174 | CPVT_WordPlace AddSection(const CPVT_WordPlace& place, |
| 175 | const CPVT_SectionInfo& secinfo); |
| 176 | CPVT_WordPlace AddLine(const CPVT_WordPlace& place, |
| 177 | const CPVT_LineInfo& lineinfo); |
| 178 | CPVT_WordPlace AddWord(const CPVT_WordPlace& place, |
| 179 | const CPVT_WordInfo& wordinfo); |
tsepez | 12f3e4a | 2016-11-02 15:17:29 -0700 | [diff] [blame] | 180 | bool GetWordInfo(const CPVT_WordPlace& place, CPVT_WordInfo& wordinfo); |
| 181 | bool SetWordInfo(const CPVT_WordPlace& place, const CPVT_WordInfo& wordinfo); |
| 182 | bool GetLineInfo(const CPVT_WordPlace& place, CPVT_LineInfo& lineinfo); |
| 183 | bool GetSectionInfo(const CPVT_WordPlace& place, CPVT_SectionInfo& secinfo); |
dsinclair | 74a30b7 | 2016-07-18 10:18:56 -0700 | [diff] [blame] | 184 | FX_FLOAT GetWordFontSize(const CPVT_WordInfo& WordInfo); |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 185 | FX_FLOAT GetWordWidth(int32_t nFontIndex, |
| 186 | uint16_t Word, |
| 187 | uint16_t SubWord, |
| 188 | FX_FLOAT fCharSpace, |
| 189 | int32_t nHorzScale, |
| 190 | FX_FLOAT fFontSize, |
npm | 41d6bbe | 2016-09-14 11:54:44 -0700 | [diff] [blame] | 191 | FX_FLOAT fWordTail); |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 192 | FX_FLOAT GetWordWidth(const CPVT_WordInfo& WordInfo); |
| 193 | FX_FLOAT GetWordAscent(const CPVT_WordInfo& WordInfo, FX_FLOAT fFontSize); |
| 194 | FX_FLOAT GetWordDescent(const CPVT_WordInfo& WordInfo, FX_FLOAT fFontSize); |
dsinclair | 74a30b7 | 2016-07-18 10:18:56 -0700 | [diff] [blame] | 195 | FX_FLOAT GetWordAscent(const CPVT_WordInfo& WordInfo); |
| 196 | FX_FLOAT GetWordDescent(const CPVT_WordInfo& WordInfo); |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 197 | FX_FLOAT GetLineAscent(const CPVT_SectionInfo& SecInfo); |
| 198 | FX_FLOAT GetLineDescent(const CPVT_SectionInfo& SecInfo); |
| 199 | FX_FLOAT GetFontAscent(int32_t nFontIndex, FX_FLOAT fFontSize); |
| 200 | FX_FLOAT GetFontDescent(int32_t nFontIndex, FX_FLOAT fFontSize); |
| 201 | int32_t GetWordFontIndex(const CPVT_WordInfo& WordInfo); |
| 202 | FX_FLOAT GetCharSpace(const CPVT_WordInfo& WordInfo); |
| 203 | int32_t GetHorzScale(const CPVT_WordInfo& WordInfo); |
| 204 | FX_FLOAT GetLineLeading(const CPVT_SectionInfo& SecInfo); |
| 205 | FX_FLOAT GetLineIndent(const CPVT_SectionInfo& SecInfo); |
| 206 | int32_t GetAlignment(const CPVT_SectionInfo& SecInfo); |
| 207 | |
| 208 | void ClearSectionRightWords(const CPVT_WordPlace& place); |
| 209 | |
tsepez | 12f3e4a | 2016-11-02 15:17:29 -0700 | [diff] [blame] | 210 | bool ClearEmptySection(const CPVT_WordPlace& place); |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 211 | void ClearEmptySections(const CPVT_WordRange& PlaceRange); |
| 212 | void LinkLatterSection(const CPVT_WordPlace& place); |
| 213 | void ClearWords(const CPVT_WordRange& PlaceRange); |
| 214 | CPVT_WordPlace ClearLeftWord(const CPVT_WordPlace& place); |
| 215 | CPVT_WordPlace ClearRightWord(const CPVT_WordPlace& place); |
| 216 | |
| 217 | CPVT_FloatRect Rearrange(const CPVT_WordRange& PlaceRange); |
| 218 | FX_FLOAT GetAutoFontSize(); |
thestig | cac1571 | 2016-05-11 12:59:42 -0700 | [diff] [blame] | 219 | bool IsBigger(FX_FLOAT fFontSize) const; |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 220 | CPVT_FloatRect RearrangeSections(const CPVT_WordRange& PlaceRange); |
| 221 | |
| 222 | void ResetSectionArray(); |
| 223 | |
dsinclair | 696fc8b | 2016-05-04 07:52:55 -0700 | [diff] [blame] | 224 | CPVT_ArrayTemplate<CSection*> m_SectionArray; |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 225 | int32_t m_nLimitChar; |
| 226 | int32_t m_nCharArray; |
tsepez | 12f3e4a | 2016-11-02 15:17:29 -0700 | [diff] [blame] | 227 | bool m_bMultiLine; |
| 228 | bool m_bLimitWidth; |
| 229 | bool m_bAutoFontSize; |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 230 | int32_t m_nAlignment; |
| 231 | FX_FLOAT m_fLineLeading; |
| 232 | FX_FLOAT m_fCharSpace; |
| 233 | int32_t m_nHorzScale; |
| 234 | uint16_t m_wSubWord; |
| 235 | FX_FLOAT m_fFontSize; |
tsepez | 12f3e4a | 2016-11-02 15:17:29 -0700 | [diff] [blame] | 236 | bool m_bInitial; |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 237 | CPDF_VariableText::Provider* m_pVTProvider; |
thestig | 821d59e | 2016-05-11 12:59:22 -0700 | [diff] [blame] | 238 | std::unique_ptr<CPDF_VariableText::Iterator> m_pVTIterator; |
dsinclair | 448c433 | 2016-08-02 12:07:35 -0700 | [diff] [blame] | 239 | CFX_FloatRect m_rcPlate; |
| 240 | CPVT_FloatRect m_rcContent; |
dsinclair | c7a7349 | 2016-04-05 12:01:42 -0700 | [diff] [blame] | 241 | }; |
| 242 | |
dsinclair | 1727aee | 2016-09-29 13:12:56 -0700 | [diff] [blame] | 243 | #endif // CORE_FPDFDOC_CPDF_VARIABLETEXT_H_ |