OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "../../../include/fpdfapi/fpdf_page.h" | 7 #include "../../../include/fpdfapi/fpdf_page.h" |
8 #include "../../../include/fpdfapi/fpdf_module.h" | 8 #include "../../../include/fpdfapi/fpdf_module.h" |
9 #include "pageint.h" | 9 #include "pageint.h" |
10 CPDF_PageObject* CPDF_PageObject::Create(int type) | 10 CPDF_PageObject* CPDF_PageObject::Create(int type) { |
11 { | 11 switch (type) { |
12 switch (type) { | 12 case PDFPAGE_TEXT: |
13 case PDFPAGE_TEXT: | 13 return new CPDF_TextObject; |
14 return new CPDF_TextObject; | 14 case PDFPAGE_IMAGE: |
15 case PDFPAGE_IMAGE: | 15 return new CPDF_ImageObject; |
16 return new CPDF_ImageObject; | 16 case PDFPAGE_PATH: |
17 case PDFPAGE_PATH: | 17 return new CPDF_PathObject; |
18 return new CPDF_PathObject; | 18 case PDFPAGE_SHADING: |
19 case PDFPAGE_SHADING: | 19 return new CPDF_ShadingObject; |
20 return new CPDF_ShadingObject; | 20 case PDFPAGE_FORM: |
21 case PDFPAGE_FORM: | 21 return new CPDF_FormObject; |
22 return new CPDF_FormObject; | 22 } |
23 } | 23 return NULL; |
24 return NULL; | |
25 } | 24 } |
26 CPDF_PageObject::~CPDF_PageObject() | 25 CPDF_PageObject::~CPDF_PageObject() {} |
27 { | 26 CPDF_PageObject* CPDF_PageObject::Clone() const { |
| 27 CPDF_PageObject* pObj = Create(m_Type); |
| 28 pObj->Copy(this); |
| 29 return pObj; |
28 } | 30 } |
29 CPDF_PageObject* CPDF_PageObject::Clone() const | 31 void CPDF_PageObject::Copy(const CPDF_PageObject* pSrc) { |
30 { | 32 if (m_Type != pSrc->m_Type) { |
31 CPDF_PageObject* pObj = Create(m_Type); | 33 return; |
32 pObj->Copy(this); | 34 } |
33 return pObj; | 35 CopyData(pSrc); |
| 36 CopyStates(*pSrc); |
| 37 m_Left = pSrc->m_Left; |
| 38 m_Right = pSrc->m_Right; |
| 39 m_Top = pSrc->m_Top; |
| 40 m_Bottom = pSrc->m_Bottom; |
34 } | 41 } |
35 void CPDF_PageObject::Copy(const CPDF_PageObject* pSrc) | 42 void CPDF_PageObject::AppendClipPath(CPDF_Path path, |
36 { | 43 int type, |
37 if (m_Type != pSrc->m_Type) { | 44 FX_BOOL bAutoMerge) { |
38 return; | 45 m_ClipPath.AppendPath(path, type, bAutoMerge); |
39 } | |
40 CopyData(pSrc); | |
41 CopyStates(*pSrc); | |
42 m_Left = pSrc->m_Left; | |
43 m_Right = pSrc->m_Right; | |
44 m_Top = pSrc->m_Top; | |
45 m_Bottom = pSrc->m_Bottom; | |
46 } | 46 } |
47 void CPDF_PageObject::AppendClipPath(CPDF_Path path, int type, FX_BOOL bAutoMerg
e) | 47 void CPDF_PageObject::CopyClipPath(CPDF_PageObject* pObj) { |
48 { | 48 m_ClipPath = pObj->m_ClipPath; |
49 m_ClipPath.AppendPath(path, type, bAutoMerge); | |
50 } | 49 } |
51 void CPDF_PageObject::CopyClipPath(CPDF_PageObject* pObj) | 50 void CPDF_PageObject::RemoveClipPath() { |
52 { | 51 m_ClipPath.SetNull(); |
53 m_ClipPath = pObj->m_ClipPath; | |
54 } | 52 } |
55 void CPDF_PageObject::RemoveClipPath() | 53 void CPDF_PageObject::RecalcBBox() { |
56 { | 54 switch (m_Type) { |
57 m_ClipPath.SetNull(); | 55 case PDFPAGE_TEXT: |
| 56 ((CPDF_TextObject*)this)->RecalcPositionData(); |
| 57 break; |
| 58 case PDFPAGE_PATH: |
| 59 ((CPDF_PathObject*)this)->CalcBoundingBox(); |
| 60 break; |
| 61 case PDFPAGE_SHADING: |
| 62 ((CPDF_ShadingObject*)this)->CalcBoundingBox(); |
| 63 break; |
| 64 } |
58 } | 65 } |
59 void CPDF_PageObject::RecalcBBox() | 66 void CPDF_PageObject::TransformClipPath(CFX_AffineMatrix& matrix) { |
60 { | 67 if (m_ClipPath.IsNull()) { |
61 switch (m_Type) { | 68 return; |
62 case PDFPAGE_TEXT: | 69 } |
63 ((CPDF_TextObject*)this)->RecalcPositionData(); | 70 m_ClipPath.GetModify(); |
64 break; | 71 m_ClipPath.Transform(matrix); |
65 case PDFPAGE_PATH: | |
66 ((CPDF_PathObject*)this)->CalcBoundingBox(); | |
67 break; | |
68 case PDFPAGE_SHADING: | |
69 ((CPDF_ShadingObject*)this)->CalcBoundingBox(); | |
70 break; | |
71 } | |
72 } | 72 } |
73 void CPDF_PageObject::TransformClipPath(CFX_AffineMatrix& matrix) | 73 void CPDF_PageObject::TransformGeneralState(CFX_AffineMatrix& matrix) { |
74 { | 74 if (m_GeneralState.IsNull()) { |
75 if (m_ClipPath.IsNull()) { | 75 return; |
76 return; | 76 } |
77 } | 77 CPDF_GeneralStateData* pGS = m_GeneralState.GetModify(); |
78 m_ClipPath.GetModify(); | 78 pGS->m_Matrix.Concat(matrix); |
79 m_ClipPath.Transform(matrix); | |
80 } | 79 } |
81 void CPDF_PageObject::TransformGeneralState(CFX_AffineMatrix& matrix) | 80 FX_RECT CPDF_PageObject::GetBBox(const CFX_AffineMatrix* pMatrix) const { |
82 { | 81 CFX_FloatRect rect(m_Left, m_Bottom, m_Right, m_Top); |
83 if(m_GeneralState.IsNull()) { | 82 if (pMatrix) { |
84 return; | 83 pMatrix->TransformRect(rect); |
85 } | 84 } |
86 CPDF_GeneralStateData* pGS = m_GeneralState.GetModify(); | 85 return rect.GetOutterRect(); |
87 pGS->m_Matrix.Concat(matrix); | |
88 } | |
89 FX_RECT CPDF_PageObject::GetBBox(const CFX_AffineMatrix* pMatrix) const | |
90 { | |
91 CFX_FloatRect rect(m_Left, m_Bottom, m_Right, m_Top); | |
92 if (pMatrix) { | |
93 pMatrix->TransformRect(rect); | |
94 } | |
95 return rect.GetOutterRect(); | |
96 } | 86 } |
97 | 87 |
98 CPDF_TextObject::CPDF_TextObject() | 88 CPDF_TextObject::CPDF_TextObject() |
99 : m_PosX(0), | 89 : m_PosX(0), |
100 m_PosY(0), | 90 m_PosY(0), |
101 m_nChars(0), | 91 m_nChars(0), |
102 m_pCharCodes(nullptr), | 92 m_pCharCodes(nullptr), |
103 m_pCharPos(nullptr) | 93 m_pCharPos(nullptr) { |
104 { | 94 m_Type = PDFPAGE_TEXT; |
105 m_Type = PDFPAGE_TEXT; | 95 } |
106 } | 96 |
107 | 97 CPDF_TextObject::~CPDF_TextObject() { |
108 CPDF_TextObject::~CPDF_TextObject() | 98 if (m_nChars > 1 && m_pCharCodes) { |
109 { | 99 FX_Free(m_pCharCodes); |
110 if (m_nChars > 1 && m_pCharCodes) { | 100 } |
111 FX_Free(m_pCharCodes); | 101 if (m_pCharPos) { |
112 } | 102 FX_Free(m_pCharPos); |
113 if (m_pCharPos) { | 103 } |
114 FX_Free(m_pCharPos); | 104 } |
115 } | 105 |
116 } | 106 void CPDF_TextObject::GetItemInfo(int index, CPDF_TextObjectItem* pInfo) const { |
117 | 107 pInfo->m_CharCode = |
118 void CPDF_TextObject::GetItemInfo(int index, CPDF_TextObjectItem* pInfo) const | 108 m_nChars == 1 ? (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[index]; |
119 { | 109 pInfo->m_OriginX = index ? m_pCharPos[index - 1] : 0; |
120 pInfo->m_CharCode = | 110 pInfo->m_OriginY = 0; |
121 m_nChars == 1 ? (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[index]; | 111 if (pInfo->m_CharCode == -1) { |
122 pInfo->m_OriginX = index ? m_pCharPos[index - 1] : 0; | 112 return; |
123 pInfo->m_OriginY = 0; | 113 } |
124 if (pInfo->m_CharCode == -1) { | 114 CPDF_Font* pFont = m_TextState.GetFont(); |
125 return; | 115 if (pFont->GetFontType() != PDFFONT_CIDFONT) { |
126 } | 116 return; |
127 CPDF_Font* pFont = m_TextState.GetFont(); | 117 } |
128 if (pFont->GetFontType() != PDFFONT_CIDFONT) { | 118 if (!((CPDF_CIDFont*)pFont)->IsVertWriting()) { |
129 return; | 119 return; |
130 } | 120 } |
131 if (!((CPDF_CIDFont*)pFont)->IsVertWriting()) { | 121 FX_WORD CID = ((CPDF_CIDFont*)pFont)->CIDFromCharCode(pInfo->m_CharCode); |
132 return; | 122 pInfo->m_OriginY = pInfo->m_OriginX; |
133 } | 123 pInfo->m_OriginX = 0; |
134 FX_WORD CID = ((CPDF_CIDFont*)pFont)->CIDFromCharCode(pInfo->m_CharCode); | 124 short vx, vy; |
135 pInfo->m_OriginY = pInfo->m_OriginX; | 125 ((CPDF_CIDFont*)pFont)->GetVertOrigin(CID, vx, vy); |
136 pInfo->m_OriginX = 0; | 126 FX_FLOAT fontsize = m_TextState.GetFontSize(); |
137 short vx, vy; | 127 pInfo->m_OriginX -= fontsize * vx / 1000; |
138 ((CPDF_CIDFont*)pFont)->GetVertOrigin(CID, vx, vy); | 128 pInfo->m_OriginY -= fontsize * vy / 1000; |
139 FX_FLOAT fontsize = m_TextState.GetFontSize(); | 129 } |
140 pInfo->m_OriginX -= fontsize * vx / 1000; | 130 |
141 pInfo->m_OriginY -= fontsize * vy / 1000; | 131 int CPDF_TextObject::CountChars() const { |
142 } | 132 if (m_nChars == 1) { |
143 | 133 return 1; |
144 int CPDF_TextObject::CountChars() const | 134 } |
145 { | 135 int count = 0; |
146 if (m_nChars == 1) { | 136 for (int i = 0; i < m_nChars; ++i) |
147 return 1; | 137 if (m_pCharCodes[i] != (FX_DWORD)-1) { |
148 } | 138 ++count; |
149 int count = 0; | 139 } |
150 for (int i = 0; i < m_nChars; ++i) | 140 return count; |
151 if (m_pCharCodes[i] != (FX_DWORD) - 1) { | |
152 ++count; | |
153 } | |
154 return count; | |
155 } | 141 } |
156 | 142 |
157 void CPDF_TextObject::GetCharInfo(int index, | 143 void CPDF_TextObject::GetCharInfo(int index, |
158 FX_DWORD& charcode, | 144 FX_DWORD& charcode, |
159 FX_FLOAT& kerning) const | 145 FX_FLOAT& kerning) const { |
160 { | 146 if (m_nChars == 1) { |
161 if (m_nChars == 1) { | 147 charcode = (FX_DWORD)(uintptr_t)m_pCharCodes; |
162 charcode = (FX_DWORD)(uintptr_t)m_pCharCodes; | 148 kerning = 0; |
163 kerning = 0; | 149 return; |
| 150 } |
| 151 int count = 0; |
| 152 for (int i = 0; i < m_nChars; ++i) { |
| 153 if (m_pCharCodes[i] != (FX_DWORD)-1) { |
| 154 if (count == index) { |
| 155 charcode = m_pCharCodes[i]; |
| 156 if (i == m_nChars - 1 || m_pCharCodes[i + 1] != (FX_DWORD)-1) { |
| 157 kerning = 0; |
| 158 } else { |
| 159 kerning = m_pCharPos[i]; |
| 160 } |
164 return; | 161 return; |
165 } | 162 } |
166 int count = 0; | 163 ++count; |
| 164 } |
| 165 } |
| 166 } |
| 167 |
| 168 void CPDF_TextObject::GetCharInfo(int index, CPDF_TextObjectItem* pInfo) const { |
| 169 if (m_nChars == 1) { |
| 170 GetItemInfo(0, pInfo); |
| 171 return; |
| 172 } |
| 173 int count = 0; |
| 174 for (int i = 0; i < m_nChars; ++i) { |
| 175 FX_DWORD charcode = m_pCharCodes[i]; |
| 176 if (charcode == (FX_DWORD)-1) { |
| 177 continue; |
| 178 } |
| 179 if (count == index) { |
| 180 GetItemInfo(i, pInfo); |
| 181 break; |
| 182 } |
| 183 ++count; |
| 184 } |
| 185 } |
| 186 |
| 187 void CPDF_TextObject::CopyData(const CPDF_PageObject* pSrc) { |
| 188 const CPDF_TextObject* pSrcObj = (const CPDF_TextObject*)pSrc; |
| 189 if (m_nChars > 1 && m_pCharCodes) { |
| 190 FX_Free(m_pCharCodes); |
| 191 m_pCharCodes = nullptr; |
| 192 } |
| 193 if (m_pCharPos) { |
| 194 FX_Free(m_pCharPos); |
| 195 m_pCharPos = nullptr; |
| 196 } |
| 197 m_nChars = pSrcObj->m_nChars; |
| 198 if (m_nChars > 1) { |
| 199 m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars); |
| 200 m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1); |
167 for (int i = 0; i < m_nChars; ++i) { | 201 for (int i = 0; i < m_nChars; ++i) { |
168 if (m_pCharCodes[i] != (FX_DWORD) - 1) { | 202 m_pCharCodes[i] = pSrcObj->m_pCharCodes[i]; |
169 if (count == index) { | 203 } |
170 charcode = m_pCharCodes[i]; | 204 for (int i = 0; i < m_nChars - 1; ++i) { |
171 if (i == m_nChars - 1 || | 205 m_pCharPos[i] = pSrcObj->m_pCharPos[i]; |
172 m_pCharCodes[i + 1] != (FX_DWORD) - 1) { | 206 } |
173 kerning = 0; | 207 } else { |
174 } else { | 208 m_pCharCodes = pSrcObj->m_pCharCodes; |
175 kerning = m_pCharPos[i]; | 209 } |
176 } | 210 m_PosX = pSrcObj->m_PosX; |
177 return; | 211 m_PosY = pSrcObj->m_PosY; |
178 } | 212 } |
179 ++count; | 213 |
180 } | 214 void CPDF_TextObject::GetTextMatrix(CFX_AffineMatrix* pMatrix) const { |
181 } | 215 FX_FLOAT* pTextMatrix = m_TextState.GetMatrix(); |
182 } | 216 pMatrix->Set(pTextMatrix[0], pTextMatrix[2], pTextMatrix[1], pTextMatrix[3], |
183 | 217 m_PosX, m_PosY); |
184 void CPDF_TextObject::GetCharInfo(int index, CPDF_TextObjectItem* pInfo) const | |
185 { | |
186 if (m_nChars == 1) { | |
187 GetItemInfo(0, pInfo); | |
188 return; | |
189 } | |
190 int count = 0; | |
191 for (int i = 0; i < m_nChars; ++i) { | |
192 FX_DWORD charcode = m_pCharCodes[i]; | |
193 if (charcode == (FX_DWORD) - 1) { | |
194 continue; | |
195 } | |
196 if (count == index) { | |
197 GetItemInfo(i, pInfo); | |
198 break; | |
199 } | |
200 ++count; | |
201 } | |
202 } | |
203 | |
204 void CPDF_TextObject::CopyData(const CPDF_PageObject* pSrc) | |
205 { | |
206 const CPDF_TextObject* pSrcObj = (const CPDF_TextObject*)pSrc; | |
207 if (m_nChars > 1 && m_pCharCodes) { | |
208 FX_Free(m_pCharCodes); | |
209 m_pCharCodes = nullptr; | |
210 } | |
211 if (m_pCharPos) { | |
212 FX_Free(m_pCharPos); | |
213 m_pCharPos = nullptr; | |
214 } | |
215 m_nChars = pSrcObj->m_nChars; | |
216 if (m_nChars > 1) { | |
217 m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars); | |
218 m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1); | |
219 for (int i = 0; i < m_nChars; ++i) { | |
220 m_pCharCodes[i] = pSrcObj->m_pCharCodes[i]; | |
221 } | |
222 for (int i = 0; i < m_nChars - 1; ++i) { | |
223 m_pCharPos[i] = pSrcObj->m_pCharPos[i]; | |
224 } | |
225 } else { | |
226 m_pCharCodes = pSrcObj->m_pCharCodes; | |
227 } | |
228 m_PosX = pSrcObj->m_PosX; | |
229 m_PosY = pSrcObj->m_PosY; | |
230 } | |
231 | |
232 void CPDF_TextObject::GetTextMatrix(CFX_AffineMatrix* pMatrix) const | |
233 { | |
234 FX_FLOAT* pTextMatrix = m_TextState.GetMatrix(); | |
235 pMatrix->Set(pTextMatrix[0], | |
236 pTextMatrix[2], | |
237 pTextMatrix[1], | |
238 pTextMatrix[3], | |
239 m_PosX, | |
240 m_PosY); | |
241 } | 218 } |
242 | 219 |
243 void CPDF_TextObject::SetSegments(const CFX_ByteString* pStrs, | 220 void CPDF_TextObject::SetSegments(const CFX_ByteString* pStrs, |
244 FX_FLOAT* pKerning, | 221 FX_FLOAT* pKerning, |
245 int nsegs) | 222 int nsegs) { |
246 { | 223 if (m_nChars > 1 && m_pCharCodes) { |
247 if (m_nChars > 1 && m_pCharCodes) { | 224 FX_Free(m_pCharCodes); |
248 FX_Free(m_pCharCodes); | 225 m_pCharCodes = nullptr; |
249 m_pCharCodes = nullptr; | 226 } |
250 } | 227 if (m_pCharPos) { |
251 if (m_pCharPos) { | 228 FX_Free(m_pCharPos); |
252 FX_Free(m_pCharPos); | 229 m_pCharPos = nullptr; |
253 m_pCharPos = nullptr; | 230 } |
254 } | 231 CPDF_Font* pFont = m_TextState.GetFont(); |
255 CPDF_Font* pFont = m_TextState.GetFont(); | 232 m_nChars = 0; |
256 m_nChars = 0; | 233 for (int i = 0; i < nsegs; ++i) { |
| 234 m_nChars += pFont->CountChar(pStrs[i], pStrs[i].GetLength()); |
| 235 } |
| 236 m_nChars += nsegs - 1; |
| 237 if (m_nChars > 1) { |
| 238 m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars); |
| 239 m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1); |
| 240 int index = 0; |
257 for (int i = 0; i < nsegs; ++i) { | 241 for (int i = 0; i < nsegs; ++i) { |
258 m_nChars += pFont->CountChar(pStrs[i], pStrs[i].GetLength()); | 242 const FX_CHAR* segment = pStrs[i]; |
259 } | 243 int offset = 0, len = pStrs[i].GetLength(); |
260 m_nChars += nsegs - 1; | 244 while (offset < len) { |
261 if (m_nChars > 1) { | 245 m_pCharCodes[index++] = pFont->GetNextChar(segment, len, offset); |
262 m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars); | 246 } |
263 m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1); | 247 if (i != nsegs - 1) { |
264 int index = 0; | 248 m_pCharPos[index - 1] = pKerning[i]; |
265 for (int i = 0; i < nsegs; ++i) { | 249 m_pCharCodes[index++] = (FX_DWORD)-1; |
266 const FX_CHAR* segment = pStrs[i]; | 250 } |
267 int offset = 0, len = pStrs[i].GetLength(); | 251 } |
268 while (offset < len) { | 252 } else { |
269 m_pCharCodes[index++] = | 253 int offset = 0; |
270 pFont->GetNextChar(segment, len, offset); | 254 m_pCharCodes = (FX_DWORD*)(uintptr_t)pFont->GetNextChar( |
271 } | 255 pStrs[0], pStrs[0].GetLength(), offset); |
272 if (i != nsegs - 1) { | 256 } |
273 m_pCharPos[index - 1] = pKerning[i]; | 257 } |
274 m_pCharCodes[index++] = (FX_DWORD) - 1; | 258 |
275 } | 259 void CPDF_TextObject::SetText(const CFX_ByteString& str) { |
276 } | 260 SetSegments(&str, nullptr, 1); |
277 } else { | 261 RecalcPositionData(); |
278 int offset = 0; | 262 } |
279 m_pCharCodes = | 263 |
280 (FX_DWORD*)(uintptr_t)pFont->GetNextChar(pStrs[0], | 264 void CPDF_TextObject::SetEmpty() { |
281 pStrs[0].GetLength(), | 265 if (m_nChars > 1 && m_pCharCodes) { |
282 offset); | 266 FX_Free(m_pCharCodes); |
283 } | 267 } |
284 } | 268 if (m_nChars > 1 && m_pCharPos) { |
285 | 269 FX_Free(m_pCharPos); |
286 void CPDF_TextObject::SetText(const CFX_ByteString& str) | 270 } |
287 { | 271 m_nChars = 0; |
288 SetSegments(&str, nullptr, 1); | 272 m_pCharCodes = nullptr; |
289 RecalcPositionData(); | 273 m_pCharPos = nullptr; |
290 } | 274 m_Left = m_Right = m_PosX; |
291 | 275 m_Top = m_Bottom = m_PosY; |
292 void CPDF_TextObject::SetEmpty() | |
293 { | |
294 if (m_nChars > 1 && m_pCharCodes) { | |
295 FX_Free(m_pCharCodes); | |
296 } | |
297 if (m_nChars > 1 && m_pCharPos) { | |
298 FX_Free(m_pCharPos); | |
299 } | |
300 m_nChars = 0; | |
301 m_pCharCodes = nullptr; | |
302 m_pCharPos = nullptr; | |
303 m_Left = m_Right = m_PosX; | |
304 m_Top = m_Bottom = m_PosY; | |
305 } | 276 } |
306 | 277 |
307 void CPDF_TextObject::SetText(CFX_ByteString* pStrs, | 278 void CPDF_TextObject::SetText(CFX_ByteString* pStrs, |
308 FX_FLOAT* pKerning, | 279 FX_FLOAT* pKerning, |
309 int nSegs) | 280 int nSegs) { |
310 { | 281 SetSegments(pStrs, pKerning, nSegs); |
311 SetSegments(pStrs, pKerning, nSegs); | 282 RecalcPositionData(); |
312 RecalcPositionData(); | |
313 } | 283 } |
314 | 284 |
315 void CPDF_TextObject::SetText(int nChars, | 285 void CPDF_TextObject::SetText(int nChars, |
316 FX_DWORD* pCharCodes, | 286 FX_DWORD* pCharCodes, |
317 FX_FLOAT* pKernings) | 287 FX_FLOAT* pKernings) { |
318 { | 288 if (m_nChars > 1 && m_pCharCodes) { |
319 if (m_nChars > 1 && m_pCharCodes) { | 289 FX_Free(m_pCharCodes); |
320 FX_Free(m_pCharCodes); | 290 m_pCharCodes = nullptr; |
321 m_pCharCodes = nullptr; | 291 } |
322 } | 292 if (m_pCharPos) { |
323 if (m_pCharPos) { | 293 FX_Free(m_pCharPos); |
324 FX_Free(m_pCharPos); | 294 m_pCharPos = nullptr; |
325 m_pCharPos = nullptr; | 295 } |
326 } | 296 int nKernings = 0; |
327 int nKernings = 0; | 297 int i; |
328 int i; | 298 for (i = 0; i < nChars - 1; ++i) { |
329 for (i = 0; i < nChars - 1; ++i) { | 299 if (pKernings[i] != 0) { |
330 if (pKernings[i] != 0) { | 300 ++nKernings; |
331 ++nKernings; | 301 } |
332 } | 302 } |
333 } | 303 m_nChars = nChars + nKernings; |
334 m_nChars = nChars + nKernings; | 304 if (m_nChars > 1) { |
335 if (m_nChars > 1) { | 305 m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars); |
336 m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars); | 306 m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1); |
337 m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1); | 307 for (int i = 0, index = 0; i < nChars; ++i) { |
338 for (int i = 0, index = 0; i < nChars; ++i) { | 308 m_pCharCodes[index++] = pCharCodes[i]; |
339 m_pCharCodes[index++] = pCharCodes[i]; | 309 if (pKernings[i] != 0 && i != nChars - 1) { |
340 if (pKernings[i] != 0 && i != nChars - 1) { | 310 m_pCharCodes[index] = (FX_DWORD)-1; |
341 m_pCharCodes[index] = (FX_DWORD) - 1; | 311 m_pCharPos[index - 1] = pKernings[i]; |
342 m_pCharPos[index - 1] = pKernings[i]; | 312 ++index; |
343 ++index; | 313 } |
344 } | 314 } |
345 } | 315 } else { |
| 316 m_pCharCodes = (FX_DWORD*)(uintptr_t)pCharCodes[0]; |
| 317 } |
| 318 RecalcPositionData(); |
| 319 } |
| 320 |
| 321 FX_FLOAT CPDF_TextObject::GetCharWidth(FX_DWORD charcode) const { |
| 322 FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000; |
| 323 CPDF_Font* pFont = m_TextState.GetFont(); |
| 324 FX_BOOL bVertWriting = FALSE; |
| 325 CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); |
| 326 if (pCIDFont) { |
| 327 bVertWriting = pCIDFont->IsVertWriting(); |
| 328 } |
| 329 if (!bVertWriting) |
| 330 return pFont->GetCharWidthF(charcode, 0) * fontsize; |
| 331 |
| 332 FX_WORD CID = pCIDFont->CIDFromCharCode(charcode); |
| 333 return pCIDFont->GetVertWidth(CID) * fontsize; |
| 334 } |
| 335 |
| 336 FX_FLOAT CPDF_TextObject::GetSpaceCharWidth() const { |
| 337 CPDF_Font* pFont = m_TextState.GetFont(); |
| 338 FX_DWORD charCode = m_TextState.GetFont()->CharCodeFromUnicode(32); |
| 339 if (charCode != (FX_DWORD)-1) { |
| 340 return GetCharWidth(charCode); |
| 341 } |
| 342 FX_FLOAT fontSize = m_TextState.GetFontSize() / 4000.0f; |
| 343 FX_BOOL bVertWriting = FALSE; |
| 344 CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); |
| 345 if (pCIDFont) { |
| 346 bVertWriting = pCIDFont->IsVertWriting(); |
| 347 } |
| 348 FX_RECT fontRect; |
| 349 pFont->GetFontBBox(fontRect); |
| 350 fontSize *= |
| 351 bVertWriting ? (FX_FLOAT)fontRect.Height() : (FX_FLOAT)fontRect.Width(); |
| 352 return fontSize; |
| 353 } |
| 354 |
| 355 void CPDF_TextObject::GetCharRect(int index, CFX_FloatRect& rect) const { |
| 356 CPDF_Font* pFont = m_TextState.GetFont(); |
| 357 FX_BOOL bVertWriting = FALSE; |
| 358 CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); |
| 359 if (pCIDFont) { |
| 360 bVertWriting = pCIDFont->IsVertWriting(); |
| 361 } |
| 362 FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000; |
| 363 int count = 0; |
| 364 for (int i = 0; i < m_nChars; ++i) { |
| 365 FX_DWORD charcode = |
| 366 m_nChars == 1 ? (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i]; |
| 367 if (charcode == (FX_DWORD)-1) { |
| 368 continue; |
| 369 } |
| 370 if (count != index) { |
| 371 ++count; |
| 372 continue; |
| 373 } |
| 374 FX_FLOAT curpos = i > 0 ? m_pCharPos[i - 1] : 0; |
| 375 FX_RECT char_rect; |
| 376 pFont->GetCharBBox(charcode, char_rect, 0); |
| 377 if (!bVertWriting) { |
| 378 rect.left = curpos + char_rect.left * fontsize; |
| 379 rect.right = curpos + char_rect.right * fontsize; |
| 380 rect.top = char_rect.top * fontsize; |
| 381 rect.bottom = char_rect.bottom * fontsize; |
346 } else { | 382 } else { |
347 m_pCharCodes = (FX_DWORD*)(uintptr_t)pCharCodes[0]; | 383 FX_WORD CID = pCIDFont->CIDFromCharCode(charcode); |
348 } | 384 short vx, vy; |
349 RecalcPositionData(); | 385 pCIDFont->GetVertOrigin(CID, vx, vy); |
350 } | 386 char_rect.left -= vx; |
351 | 387 char_rect.right -= vx; |
352 FX_FLOAT CPDF_TextObject::GetCharWidth(FX_DWORD charcode) const | 388 char_rect.top -= vy; |
353 { | 389 char_rect.bottom -= vy; |
354 FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000; | 390 rect.left = char_rect.left * fontsize; |
355 CPDF_Font* pFont = m_TextState.GetFont(); | 391 rect.right = char_rect.right * fontsize; |
356 FX_BOOL bVertWriting = FALSE; | 392 rect.top = curpos + char_rect.top * fontsize; |
357 CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); | 393 rect.bottom = curpos + char_rect.bottom * fontsize; |
358 if (pCIDFont) { | 394 } |
359 bVertWriting = pCIDFont->IsVertWriting(); | 395 return; |
360 } | 396 } |
361 if (!bVertWriting) | |
362 return pFont->GetCharWidthF(charcode, 0) * fontsize; | |
363 | |
364 FX_WORD CID = pCIDFont->CIDFromCharCode(charcode); | |
365 return pCIDFont->GetVertWidth(CID) * fontsize; | |
366 } | |
367 | |
368 FX_FLOAT CPDF_TextObject::GetSpaceCharWidth() const | |
369 { | |
370 CPDF_Font* pFont = m_TextState.GetFont(); | |
371 FX_DWORD charCode = m_TextState.GetFont()->CharCodeFromUnicode(32); | |
372 if (charCode != (FX_DWORD) - 1) { | |
373 return GetCharWidth(charCode); | |
374 } | |
375 FX_FLOAT fontSize = m_TextState.GetFontSize() / 4000.0f; | |
376 FX_BOOL bVertWriting = FALSE; | |
377 CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); | |
378 if (pCIDFont) { | |
379 bVertWriting = pCIDFont->IsVertWriting(); | |
380 } | |
381 FX_RECT fontRect; | |
382 pFont->GetFontBBox(fontRect); | |
383 fontSize *= bVertWriting ? | |
384 (FX_FLOAT)fontRect.Height() : (FX_FLOAT)fontRect.Width(); | |
385 return fontSize; | |
386 } | |
387 | |
388 void CPDF_TextObject::GetCharRect(int index, CFX_FloatRect& rect) const | |
389 { | |
390 CPDF_Font* pFont = m_TextState.GetFont(); | |
391 FX_BOOL bVertWriting = FALSE; | |
392 CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); | |
393 if (pCIDFont) { | |
394 bVertWriting = pCIDFont->IsVertWriting(); | |
395 } | |
396 FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000; | |
397 int count = 0; | |
398 for (int i = 0; i < m_nChars; ++i) { | |
399 FX_DWORD charcode = m_nChars == 1 ? | |
400 (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i]; | |
401 if (charcode == (FX_DWORD) - 1) { | |
402 continue; | |
403 } | |
404 if (count != index) { | |
405 ++count; | |
406 continue; | |
407 } | |
408 FX_FLOAT curpos = i > 0 ? m_pCharPos[i - 1] : 0; | |
409 FX_RECT char_rect; | |
410 pFont->GetCharBBox(charcode, char_rect, 0); | |
411 if (!bVertWriting) { | |
412 rect.left = curpos + char_rect.left * fontsize; | |
413 rect.right = curpos + char_rect.right * fontsize; | |
414 rect.top = char_rect.top * fontsize; | |
415 rect.bottom = char_rect.bottom * fontsize; | |
416 } else { | |
417 FX_WORD CID = pCIDFont->CIDFromCharCode(charcode); | |
418 short vx, vy; | |
419 pCIDFont->GetVertOrigin(CID, vx, vy); | |
420 char_rect.left -= vx; | |
421 char_rect.right -= vx; | |
422 char_rect.top -= vy; | |
423 char_rect.bottom -= vy; | |
424 rect.left = char_rect.left * fontsize; | |
425 rect.right = char_rect.right * fontsize; | |
426 rect.top = curpos + char_rect.top * fontsize; | |
427 rect.bottom = curpos + char_rect.bottom * fontsize; | |
428 } | |
429 return; | |
430 } | |
431 } | 397 } |
432 | 398 |
433 void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX, | 399 void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX, |
434 FX_FLOAT* pTextAdvanceY, | 400 FX_FLOAT* pTextAdvanceY, |
435 FX_FLOAT horz_scale, | 401 FX_FLOAT horz_scale, |
436 int level) | 402 int level) { |
437 { | 403 FX_FLOAT curpos = 0; |
438 FX_FLOAT curpos = 0; | 404 FX_FLOAT min_x = 10000 * 1.0f; |
439 FX_FLOAT min_x = 10000 * 1.0f; | 405 FX_FLOAT max_x = -10000 * 1.0f; |
440 FX_FLOAT max_x = -10000 * 1.0f; | 406 FX_FLOAT min_y = 10000 * 1.0f; |
441 FX_FLOAT min_y = 10000 * 1.0f; | 407 FX_FLOAT max_y = -10000 * 1.0f; |
442 FX_FLOAT max_y = -10000 * 1.0f; | 408 CPDF_Font* pFont = m_TextState.GetFont(); |
443 CPDF_Font* pFont = m_TextState.GetFont(); | 409 FX_BOOL bVertWriting = FALSE; |
444 FX_BOOL bVertWriting = FALSE; | 410 CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); |
445 CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); | 411 if (pCIDFont) { |
446 if (pCIDFont) { | 412 bVertWriting = pCIDFont->IsVertWriting(); |
447 bVertWriting = pCIDFont->IsVertWriting(); | 413 } |
448 } | 414 FX_FLOAT fontsize = m_TextState.GetFontSize(); |
449 FX_FLOAT fontsize = m_TextState.GetFontSize(); | 415 for (int i = 0; i < m_nChars; ++i) { |
450 for (int i = 0; i < m_nChars; ++i) { | 416 FX_DWORD charcode = |
451 FX_DWORD charcode = m_nChars == 1 ? | 417 m_nChars == 1 ? (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i]; |
452 (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i]; | 418 if (charcode == (FX_DWORD)-1) { |
453 if (charcode == (FX_DWORD) - 1) { | 419 curpos -= FXSYS_Mul(m_pCharPos[i - 1], fontsize) / 1000; |
454 curpos -= FXSYS_Mul(m_pCharPos[i - 1], fontsize) / 1000; | 420 continue; |
455 continue; | 421 } |
456 } | 422 if (i) { |
457 if (i) { | 423 m_pCharPos[i - 1] = curpos; |
458 m_pCharPos[i - 1] = curpos; | 424 } |
459 } | 425 FX_RECT char_rect; |
460 FX_RECT char_rect; | 426 pFont->GetCharBBox(charcode, char_rect, level); |
461 pFont->GetCharBBox(charcode, char_rect, level); | 427 FX_FLOAT charwidth; |
462 FX_FLOAT charwidth; | 428 if (!bVertWriting) { |
463 if (!bVertWriting) { | 429 if (min_y > char_rect.top) { |
464 if (min_y > char_rect.top) { | 430 min_y = (FX_FLOAT)char_rect.top; |
465 min_y = (FX_FLOAT)char_rect.top; | 431 } |
466 } | 432 if (max_y < char_rect.top) { |
467 if (max_y < char_rect.top) { | 433 max_y = (FX_FLOAT)char_rect.top; |
468 max_y = (FX_FLOAT)char_rect.top; | 434 } |
469 } | 435 if (min_y > char_rect.bottom) { |
470 if (min_y > char_rect.bottom) { | 436 min_y = (FX_FLOAT)char_rect.bottom; |
471 min_y = (FX_FLOAT)char_rect.bottom; | 437 } |
472 } | 438 if (max_y < char_rect.bottom) { |
473 if (max_y < char_rect.bottom) { | 439 max_y = (FX_FLOAT)char_rect.bottom; |
474 max_y = (FX_FLOAT)char_rect.bottom; | 440 } |
475 } | 441 FX_FLOAT char_left = curpos + char_rect.left * fontsize / 1000; |
476 FX_FLOAT char_left = curpos + char_rect.left * fontsize / 1000; | 442 FX_FLOAT char_right = curpos + char_rect.right * fontsize / 1000; |
477 FX_FLOAT char_right = curpos + char_rect.right * fontsize / 1000; | 443 if (min_x > char_left) { |
478 if (min_x > char_left) { | 444 min_x = char_left; |
479 min_x = char_left; | 445 } |
480 } | 446 if (max_x < char_left) { |
481 if (max_x < char_left) { | 447 max_x = char_left; |
482 max_x = char_left; | 448 } |
483 } | 449 if (min_x > char_right) { |
484 if (min_x > char_right) { | 450 min_x = char_right; |
485 min_x = char_right; | 451 } |
486 } | 452 if (max_x < char_right) { |
487 if (max_x < char_right) { | 453 max_x = char_right; |
488 max_x = char_right; | 454 } |
489 } | 455 charwidth = pFont->GetCharWidthF(charcode, level) * fontsize / 1000; |
490 charwidth = pFont->GetCharWidthF(charcode, level) * fontsize / 1000; | 456 } else { |
491 } else { | 457 FX_WORD CID = pCIDFont->CIDFromCharCode(charcode); |
492 FX_WORD CID = pCIDFont->CIDFromCharCode(charcode); | 458 short vx; |
493 short vx; | 459 short vy; |
494 short vy; | 460 pCIDFont->GetVertOrigin(CID, vx, vy); |
495 pCIDFont->GetVertOrigin(CID, vx, vy); | 461 char_rect.left -= vx; |
496 char_rect.left -= vx; | 462 char_rect.right -= vx; |
497 char_rect.right -= vx; | 463 char_rect.top -= vy; |
498 char_rect.top -= vy; | 464 char_rect.bottom -= vy; |
499 char_rect.bottom -= vy; | 465 if (min_x > char_rect.left) { |
500 if (min_x > char_rect.left) { | 466 min_x = (FX_FLOAT)char_rect.left; |
501 min_x = (FX_FLOAT)char_rect.left; | 467 } |
502 } | 468 if (max_x < char_rect.left) { |
503 if (max_x < char_rect.left) { | 469 max_x = (FX_FLOAT)char_rect.left; |
504 max_x = (FX_FLOAT)char_rect.left; | 470 } |
505 } | 471 if (min_x > char_rect.right) { |
506 if (min_x > char_rect.right) { | 472 min_x = (FX_FLOAT)char_rect.right; |
507 min_x = (FX_FLOAT)char_rect.right; | 473 } |
508 } | 474 if (max_x < char_rect.right) { |
509 if (max_x < char_rect.right) { | 475 max_x = (FX_FLOAT)char_rect.right; |
510 max_x = (FX_FLOAT)char_rect.right; | 476 } |
511 } | 477 FX_FLOAT char_top = curpos + char_rect.top * fontsize / 1000; |
512 FX_FLOAT char_top = curpos + char_rect.top * fontsize / 1000; | 478 FX_FLOAT char_bottom = curpos + char_rect.bottom * fontsize / 1000; |
513 FX_FLOAT char_bottom = curpos + char_rect.bottom * fontsize / 1000; | 479 if (min_y > char_top) { |
514 if (min_y > char_top) { | 480 min_y = char_top; |
515 min_y = char_top; | 481 } |
516 } | 482 if (max_y < char_top) { |
517 if (max_y < char_top) { | 483 max_y = char_top; |
518 max_y = char_top; | 484 } |
519 } | 485 if (min_y > char_bottom) { |
520 if (min_y > char_bottom) { | 486 min_y = char_bottom; |
521 min_y = char_bottom; | 487 } |
522 } | 488 if (max_y < char_bottom) { |
523 if (max_y < char_bottom) { | 489 max_y = char_bottom; |
524 max_y = char_bottom; | 490 } |
525 } | 491 charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000; |
526 charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000; | 492 } |
527 } | 493 curpos += charwidth; |
528 curpos += charwidth; | 494 if (charcode == ' ' && (!pCIDFont || pCIDFont->GetCharSize(32) == 1)) { |
529 if (charcode == ' ' && (!pCIDFont || pCIDFont->GetCharSize(32) == 1)) { | 495 curpos += m_TextState.GetObject()->m_WordSpace; |
530 curpos += m_TextState.GetObject()->m_WordSpace; | 496 } |
531 } | 497 curpos += m_TextState.GetObject()->m_CharSpace; |
532 curpos += m_TextState.GetObject()->m_CharSpace; | 498 } |
533 } | 499 if (bVertWriting) { |
| 500 if (pTextAdvanceX) { |
| 501 *pTextAdvanceX = 0; |
| 502 } |
| 503 if (pTextAdvanceY) { |
| 504 *pTextAdvanceY = curpos; |
| 505 } |
| 506 min_x = min_x * fontsize / 1000; |
| 507 max_x = max_x * fontsize / 1000; |
| 508 } else { |
| 509 if (pTextAdvanceX) { |
| 510 *pTextAdvanceX = FXSYS_Mul(curpos, horz_scale); |
| 511 } |
| 512 if (pTextAdvanceY) { |
| 513 *pTextAdvanceY = 0; |
| 514 } |
| 515 min_y = min_y * fontsize / 1000; |
| 516 max_y = max_y * fontsize / 1000; |
| 517 } |
| 518 CFX_AffineMatrix matrix; |
| 519 GetTextMatrix(&matrix); |
| 520 m_Left = min_x; |
| 521 m_Right = max_x; |
| 522 m_Bottom = min_y; |
| 523 m_Top = max_y; |
| 524 matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); |
| 525 int textmode = m_TextState.GetObject()->m_TextMode; |
| 526 if (textmode == 1 || textmode == 2 || textmode == 5 || textmode == 6) { |
| 527 FX_FLOAT half_width = m_GraphState.GetObject()->m_LineWidth / 2; |
| 528 m_Left -= half_width; |
| 529 m_Right += half_width; |
| 530 m_Top += half_width; |
| 531 m_Bottom -= half_width; |
| 532 } |
| 533 } |
| 534 |
| 535 void CPDF_TextObject::CalcCharPos(FX_FLOAT* pPosArray) const { |
| 536 CPDF_Font* pFont = m_TextState.GetFont(); |
| 537 FX_BOOL bVertWriting = FALSE; |
| 538 CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); |
| 539 if (pCIDFont) { |
| 540 bVertWriting = pCIDFont->IsVertWriting(); |
| 541 } |
| 542 FX_FLOAT fontsize = m_TextState.GetFontSize(); |
| 543 for (int i = 0, index = 0; i < m_nChars; ++i) { |
| 544 FX_DWORD charcode = |
| 545 m_nChars == 1 ? (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i]; |
| 546 if (charcode == (FX_DWORD)-1) { |
| 547 continue; |
| 548 } |
| 549 pPosArray[index++] = i ? m_pCharPos[i - 1] : 0; |
| 550 FX_FLOAT charwidth; |
534 if (bVertWriting) { | 551 if (bVertWriting) { |
535 if (pTextAdvanceX) { | 552 FX_WORD CID = pCIDFont->CIDFromCharCode(charcode); |
536 *pTextAdvanceX = 0; | 553 charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000; |
537 } | |
538 if (pTextAdvanceY) { | |
539 *pTextAdvanceY = curpos; | |
540 } | |
541 min_x = min_x * fontsize / 1000; | |
542 max_x = max_x * fontsize / 1000; | |
543 } else { | 554 } else { |
544 if (pTextAdvanceX) { | 555 charwidth = pFont->GetCharWidthF(charcode) * fontsize / 1000; |
545 *pTextAdvanceX = FXSYS_Mul(curpos, horz_scale); | 556 } |
546 } | 557 pPosArray[index] = pPosArray[index - 1] + charwidth; |
547 if (pTextAdvanceY) { | 558 index++; |
548 *pTextAdvanceY = 0; | 559 } |
549 } | 560 } |
550 min_y = min_y * fontsize / 1000; | 561 |
551 max_y = max_y * fontsize / 1000; | 562 void CPDF_TextObject::Transform(const CFX_AffineMatrix& matrix) { |
552 } | 563 m_TextState.GetModify(); |
553 CFX_AffineMatrix matrix; | 564 CFX_AffineMatrix text_matrix; |
554 GetTextMatrix(&matrix); | 565 GetTextMatrix(&text_matrix); |
555 m_Left = min_x; | 566 text_matrix.Concat(matrix); |
556 m_Right = max_x; | 567 FX_FLOAT* pTextMatrix = m_TextState.GetMatrix(); |
557 m_Bottom = min_y; | 568 pTextMatrix[0] = text_matrix.GetA(); |
558 m_Top = max_y; | 569 pTextMatrix[1] = text_matrix.GetC(); |
559 matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); | 570 pTextMatrix[2] = text_matrix.GetB(); |
560 int textmode = m_TextState.GetObject()->m_TextMode; | 571 pTextMatrix[3] = text_matrix.GetD(); |
561 if (textmode == 1 || textmode == 2 || textmode == 5 || textmode == 6) { | 572 m_PosX = text_matrix.GetE(); |
562 FX_FLOAT half_width = m_GraphState.GetObject()->m_LineWidth / 2; | 573 m_PosY = text_matrix.GetF(); |
563 m_Left -= half_width; | 574 CalcPositionData(nullptr, nullptr, 0); |
564 m_Right += half_width; | 575 } |
565 m_Top += half_width; | 576 |
566 m_Bottom -= half_width; | 577 void CPDF_TextObject::SetPosition(FX_FLOAT x, FX_FLOAT y) { |
567 } | 578 FX_FLOAT dx = x - m_PosX; |
568 } | 579 FX_FLOAT dy = y - m_PosY; |
569 | 580 m_PosX = x; |
570 void CPDF_TextObject::CalcCharPos(FX_FLOAT* pPosArray) const | 581 m_PosY = y; |
571 { | 582 m_Left += dx; |
572 CPDF_Font* pFont = m_TextState.GetFont(); | 583 m_Right += dx; |
573 FX_BOOL bVertWriting = FALSE; | 584 m_Top += dy; |
574 CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); | 585 m_Bottom += dy; |
575 if (pCIDFont) { | |
576 bVertWriting = pCIDFont->IsVertWriting(); | |
577 } | |
578 FX_FLOAT fontsize = m_TextState.GetFontSize(); | |
579 for (int i = 0, index = 0; i < m_nChars; ++i) { | |
580 FX_DWORD charcode = m_nChars == 1 ? | |
581 (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i]; | |
582 if (charcode == (FX_DWORD) - 1) { | |
583 continue; | |
584 } | |
585 pPosArray[index++] = i ? m_pCharPos[i - 1] : 0; | |
586 FX_FLOAT charwidth; | |
587 if (bVertWriting) { | |
588 FX_WORD CID = pCIDFont->CIDFromCharCode(charcode); | |
589 charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000; | |
590 } else { | |
591 charwidth = pFont->GetCharWidthF(charcode) * fontsize / 1000; | |
592 } | |
593 pPosArray[index] = pPosArray[index - 1] + charwidth; | |
594 index++; | |
595 } | |
596 } | |
597 | |
598 void CPDF_TextObject::Transform(const CFX_AffineMatrix& matrix) | |
599 { | |
600 m_TextState.GetModify(); | |
601 CFX_AffineMatrix text_matrix; | |
602 GetTextMatrix(&text_matrix); | |
603 text_matrix.Concat(matrix); | |
604 FX_FLOAT* pTextMatrix = m_TextState.GetMatrix(); | |
605 pTextMatrix[0] = text_matrix.GetA(); | |
606 pTextMatrix[1] = text_matrix.GetC(); | |
607 pTextMatrix[2] = text_matrix.GetB(); | |
608 pTextMatrix[3] = text_matrix.GetD(); | |
609 m_PosX = text_matrix.GetE(); | |
610 m_PosY = text_matrix.GetF(); | |
611 CalcPositionData(nullptr, nullptr, 0); | |
612 } | |
613 | |
614 void CPDF_TextObject::SetPosition(FX_FLOAT x, FX_FLOAT y) | |
615 { | |
616 FX_FLOAT dx = x - m_PosX; | |
617 FX_FLOAT dy = y - m_PosY; | |
618 m_PosX = x; | |
619 m_PosY = y; | |
620 m_Left += dx; | |
621 m_Right += dx; | |
622 m_Top += dy; | |
623 m_Bottom += dy; | |
624 } | 586 } |
625 | 587 |
626 void CPDF_TextObject::SetData(int nChars, | 588 void CPDF_TextObject::SetData(int nChars, |
627 FX_DWORD* pCharCodes, | 589 FX_DWORD* pCharCodes, |
628 FX_FLOAT* pCharPos, | 590 FX_FLOAT* pCharPos, |
629 FX_FLOAT x, | 591 FX_FLOAT x, |
630 FX_FLOAT y) | 592 FX_FLOAT y) { |
631 { | 593 ASSERT(m_nChars == 0); |
632 ASSERT(m_nChars == 0); | 594 m_nChars = nChars; |
633 m_nChars = nChars; | 595 m_PosX = x; |
634 m_PosX = x; | 596 m_PosY = y; |
635 m_PosY = y; | 597 if (nChars == 0) { |
636 if (nChars == 0) { | 598 return; |
637 return; | 599 } |
638 } | 600 if (nChars == 1) { |
639 if (nChars == 1) { | 601 m_pCharCodes = (FX_DWORD*)(uintptr_t)*pCharCodes; |
640 m_pCharCodes = (FX_DWORD*)(uintptr_t) * pCharCodes; | 602 } else { |
641 } else { | 603 m_pCharCodes = FX_Alloc(FX_DWORD, nChars); |
642 m_pCharCodes = FX_Alloc(FX_DWORD, nChars); | 604 FXSYS_memcpy(m_pCharCodes, pCharCodes, sizeof(FX_DWORD) * nChars); |
643 FXSYS_memcpy(m_pCharCodes, pCharCodes, sizeof(FX_DWORD)*nChars); | 605 m_pCharPos = FX_Alloc(FX_FLOAT, nChars - 1); |
644 m_pCharPos = FX_Alloc(FX_FLOAT, nChars - 1); | 606 FXSYS_memcpy(m_pCharPos, pCharPos, sizeof(FX_FLOAT) * (nChars - 1)); |
645 FXSYS_memcpy(m_pCharPos, pCharPos, sizeof(FX_FLOAT) * (nChars - 1)); | 607 } |
646 } | 608 RecalcPositionData(); |
647 RecalcPositionData(); | 609 } |
648 } | 610 |
649 | 611 void CPDF_TextObject::SetTextState(CPDF_TextState TextState) { |
650 void CPDF_TextObject::SetTextState(CPDF_TextState TextState) | 612 m_TextState = TextState; |
651 { | 613 CalcPositionData(nullptr, nullptr, 0); |
652 m_TextState = TextState; | 614 } |
653 CalcPositionData(nullptr, nullptr, 0); | 615 |
654 } | 616 CPDF_ShadingObject::CPDF_ShadingObject() { |
655 | 617 m_pShading = NULL; |
656 CPDF_ShadingObject::CPDF_ShadingObject() | 618 m_Type = PDFPAGE_SHADING; |
657 { | 619 } |
658 m_pShading = NULL; | 620 CPDF_ShadingObject::~CPDF_ShadingObject() {} |
659 m_Type = PDFPAGE_SHADING; | 621 void CPDF_ShadingObject::CopyData(const CPDF_PageObject* pSrc) { |
660 } | 622 CPDF_ShadingObject* pSrcObj = (CPDF_ShadingObject*)pSrc; |
661 CPDF_ShadingObject::~CPDF_ShadingObject() | 623 m_pShading = pSrcObj->m_pShading; |
662 { | 624 if (m_pShading && m_pShading->m_pDocument) { |
663 } | 625 CPDF_DocPageData* pDocPageData = m_pShading->m_pDocument->GetPageData(); |
664 void CPDF_ShadingObject::CopyData(const CPDF_PageObject* pSrc) | 626 m_pShading = (CPDF_ShadingPattern*)pDocPageData->GetPattern( |
665 { | 627 m_pShading->m_pShadingObj, m_pShading->m_bShadingObj, |
666 CPDF_ShadingObject* pSrcObj = (CPDF_ShadingObject*)pSrc; | 628 &m_pShading->m_ParentMatrix); |
667 m_pShading = pSrcObj->m_pShading; | 629 } |
668 if (m_pShading && m_pShading->m_pDocument) { | 630 m_Matrix = pSrcObj->m_Matrix; |
669 CPDF_DocPageData* pDocPageData = m_pShading->m_pDocument->GetPageData(); | 631 } |
670 m_pShading = (CPDF_ShadingPattern*)pDocPageData->GetPattern(m_pShading->
m_pShadingObj, m_pShading->m_bShadingObj, &m_pShading->m_ParentMatrix); | 632 void CPDF_ShadingObject::Transform(const CFX_AffineMatrix& matrix) { |
671 } | 633 if (!m_ClipPath.IsNull()) { |
672 m_Matrix = pSrcObj->m_Matrix; | 634 m_ClipPath.GetModify(); |
673 } | 635 m_ClipPath.Transform(matrix); |
674 void CPDF_ShadingObject::Transform(const CFX_AffineMatrix& matrix) | 636 } |
675 { | 637 m_Matrix.Concat(matrix); |
676 if (!m_ClipPath.IsNull()) { | 638 if (!m_ClipPath.IsNull()) { |
677 m_ClipPath.GetModify(); | |
678 m_ClipPath.Transform(matrix); | |
679 } | |
680 m_Matrix.Concat(matrix); | |
681 if (!m_ClipPath.IsNull()) { | |
682 CalcBoundingBox(); | |
683 } else { | |
684 matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); | |
685 } | |
686 } | |
687 void CPDF_ShadingObject::CalcBoundingBox() | |
688 { | |
689 if (m_ClipPath.IsNull()) { | |
690 return; | |
691 } | |
692 CFX_FloatRect rect = m_ClipPath.GetClipBox(); | |
693 m_Left = rect.left; | |
694 m_Bottom = rect.bottom; | |
695 m_Right = rect.right; | |
696 m_Top = rect.top; | |
697 } | |
698 CPDF_FormObject::~CPDF_FormObject() | |
699 { | |
700 delete m_pForm; | |
701 } | |
702 void CPDF_FormObject::Transform(const CFX_AffineMatrix& matrix) | |
703 { | |
704 m_FormMatrix.Concat(matrix); | |
705 CalcBoundingBox(); | 639 CalcBoundingBox(); |
706 } | 640 } else { |
707 void CPDF_FormObject::CopyData(const CPDF_PageObject* pSrc) | 641 matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); |
708 { | 642 } |
709 const CPDF_FormObject* pSrcObj = (const CPDF_FormObject*)pSrc; | 643 } |
710 delete m_pForm; | 644 void CPDF_ShadingObject::CalcBoundingBox() { |
711 m_pForm = pSrcObj->m_pForm->Clone(); | 645 if (m_ClipPath.IsNull()) { |
712 m_FormMatrix = pSrcObj->m_FormMatrix; | 646 return; |
713 } | 647 } |
714 void CPDF_FormObject::CalcBoundingBox() | 648 CFX_FloatRect rect = m_ClipPath.GetClipBox(); |
715 { | 649 m_Left = rect.left; |
716 CFX_FloatRect form_rect = m_pForm->CalcBoundingBox(); | 650 m_Bottom = rect.bottom; |
717 form_rect.Transform(&m_FormMatrix); | 651 m_Right = rect.right; |
718 m_Left = form_rect.left; | 652 m_Top = rect.top; |
719 m_Bottom = form_rect.bottom; | 653 } |
720 m_Right = form_rect.right; | 654 CPDF_FormObject::~CPDF_FormObject() { |
721 m_Top = form_rect.top; | 655 delete m_pForm; |
| 656 } |
| 657 void CPDF_FormObject::Transform(const CFX_AffineMatrix& matrix) { |
| 658 m_FormMatrix.Concat(matrix); |
| 659 CalcBoundingBox(); |
| 660 } |
| 661 void CPDF_FormObject::CopyData(const CPDF_PageObject* pSrc) { |
| 662 const CPDF_FormObject* pSrcObj = (const CPDF_FormObject*)pSrc; |
| 663 delete m_pForm; |
| 664 m_pForm = pSrcObj->m_pForm->Clone(); |
| 665 m_FormMatrix = pSrcObj->m_FormMatrix; |
| 666 } |
| 667 void CPDF_FormObject::CalcBoundingBox() { |
| 668 CFX_FloatRect form_rect = m_pForm->CalcBoundingBox(); |
| 669 form_rect.Transform(&m_FormMatrix); |
| 670 m_Left = form_rect.left; |
| 671 m_Bottom = form_rect.bottom; |
| 672 m_Right = form_rect.right; |
| 673 m_Top = form_rect.top; |
722 } | 674 } |
723 CPDF_PageObjects::CPDF_PageObjects(FX_BOOL bReleaseMembers) | 675 CPDF_PageObjects::CPDF_PageObjects(FX_BOOL bReleaseMembers) |
724 : m_pFormDict(nullptr), | 676 : m_pFormDict(nullptr), |
725 m_pFormStream(nullptr), | 677 m_pFormStream(nullptr), |
726 m_pDocument(nullptr), | 678 m_pDocument(nullptr), |
727 m_pPageResources(nullptr), | 679 m_pPageResources(nullptr), |
728 m_pResources(nullptr), | 680 m_pResources(nullptr), |
729 m_Transparency(0), | 681 m_Transparency(0), |
730 m_ObjectList(128), | 682 m_ObjectList(128), |
731 m_bBackgroundAlphaNeeded(FALSE), | 683 m_bBackgroundAlphaNeeded(FALSE), |
732 m_bReleaseMembers(bReleaseMembers), | 684 m_bReleaseMembers(bReleaseMembers), |
733 m_pParser(nullptr), | 685 m_pParser(nullptr), |
734 m_ParseState(CONTENT_NOT_PARSED) | 686 m_ParseState(CONTENT_NOT_PARSED) {} |
735 { | 687 CPDF_PageObjects::~CPDF_PageObjects() { |
736 } | 688 delete m_pParser; |
737 CPDF_PageObjects::~CPDF_PageObjects() | 689 if (!m_bReleaseMembers) { |
738 { | 690 return; |
| 691 } |
| 692 FX_POSITION pos = m_ObjectList.GetHeadPosition(); |
| 693 while (pos) { |
| 694 delete (CPDF_PageObject*)m_ObjectList.GetNext(pos); |
| 695 } |
| 696 } |
| 697 void CPDF_PageObjects::ContinueParse(IFX_Pause* pPause) { |
| 698 if (m_pParser == NULL) { |
| 699 return; |
| 700 } |
| 701 m_pParser->Continue(pPause); |
| 702 if (m_pParser->GetStatus() == CPDF_ContentParser::Done) { |
| 703 m_ParseState = CONTENT_PARSED; |
739 delete m_pParser; | 704 delete m_pParser; |
740 if (!m_bReleaseMembers) { | 705 m_pParser = NULL; |
741 return; | 706 } |
742 } | 707 } |
| 708 FX_POSITION CPDF_PageObjects::InsertObject(FX_POSITION posInsertAfter, |
| 709 CPDF_PageObject* pNewObject) { |
| 710 if (!posInsertAfter) { |
| 711 return m_ObjectList.AddHead(pNewObject); |
| 712 } |
| 713 return m_ObjectList.InsertAfter(posInsertAfter, pNewObject); |
| 714 } |
| 715 int CPDF_PageObjects::GetObjectIndex(CPDF_PageObject* pObj) const { |
| 716 int index = 0; |
| 717 FX_POSITION pos = m_ObjectList.GetHeadPosition(); |
| 718 while (pos) { |
| 719 CPDF_PageObject* pThisObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos); |
| 720 if (pThisObj == pObj) { |
| 721 return index; |
| 722 } |
| 723 index++; |
| 724 } |
| 725 return -1; |
| 726 } |
| 727 CPDF_PageObject* CPDF_PageObjects::GetObjectByIndex(int index) const { |
| 728 FX_POSITION pos = m_ObjectList.FindIndex(index); |
| 729 if (pos == NULL) { |
| 730 return NULL; |
| 731 } |
| 732 return (CPDF_PageObject*)m_ObjectList.GetAt(pos); |
| 733 } |
| 734 void CPDF_PageObjects::Transform(const CFX_AffineMatrix& matrix) { |
| 735 FX_POSITION pos = m_ObjectList.GetHeadPosition(); |
| 736 while (pos) { |
| 737 CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos); |
| 738 pObj->Transform(matrix); |
| 739 } |
| 740 } |
| 741 CFX_FloatRect CPDF_PageObjects::CalcBoundingBox() const { |
| 742 if (m_ObjectList.GetCount() == 0) { |
| 743 return CFX_FloatRect(0, 0, 0, 0); |
| 744 } |
| 745 FX_FLOAT left, right, top, bottom; |
| 746 left = bottom = 1000000 * 1.0f; |
| 747 right = top = -1000000 * 1.0f; |
| 748 FX_POSITION pos = m_ObjectList.GetHeadPosition(); |
| 749 while (pos) { |
| 750 CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos); |
| 751 if (left > pObj->m_Left) { |
| 752 left = pObj->m_Left; |
| 753 } |
| 754 if (right < pObj->m_Right) { |
| 755 right = pObj->m_Right; |
| 756 } |
| 757 if (top < pObj->m_Top) { |
| 758 top = pObj->m_Top; |
| 759 } |
| 760 if (bottom > pObj->m_Bottom) { |
| 761 bottom = pObj->m_Bottom; |
| 762 } |
| 763 } |
| 764 return CFX_FloatRect(left, bottom, right, top); |
| 765 } |
| 766 void CPDF_PageObjects::LoadTransInfo() { |
| 767 if (m_pFormDict == NULL) { |
| 768 return; |
| 769 } |
| 770 CPDF_Dictionary* pGroup = m_pFormDict->GetDict(FX_BSTRC("Group")); |
| 771 if (pGroup == NULL) { |
| 772 return; |
| 773 } |
| 774 if (pGroup->GetString(FX_BSTRC("S")) != FX_BSTRC("Transparency")) { |
| 775 return; |
| 776 } |
| 777 m_Transparency |= PDFTRANS_GROUP; |
| 778 if (pGroup->GetInteger(FX_BSTRC("I"))) { |
| 779 m_Transparency |= PDFTRANS_ISOLATED; |
| 780 } |
| 781 if (pGroup->GetInteger(FX_BSTRC("K"))) { |
| 782 m_Transparency |= PDFTRANS_KNOCKOUT; |
| 783 } |
| 784 } |
| 785 void CPDF_PageObjects::ClearCacheObjects() { |
| 786 m_ParseState = CONTENT_NOT_PARSED; |
| 787 delete m_pParser; |
| 788 m_pParser = NULL; |
| 789 if (m_bReleaseMembers) { |
743 FX_POSITION pos = m_ObjectList.GetHeadPosition(); | 790 FX_POSITION pos = m_ObjectList.GetHeadPosition(); |
744 while (pos) { | 791 while (pos) { |
745 delete (CPDF_PageObject*)m_ObjectList.GetNext(pos); | 792 delete (CPDF_PageObject*)m_ObjectList.GetNext(pos); |
746 } | 793 } |
747 } | 794 } |
748 void CPDF_PageObjects::ContinueParse(IFX_Pause* pPause) | 795 m_ObjectList.RemoveAll(); |
749 { | 796 } |
750 if (m_pParser == NULL) { | 797 CPDF_Page::CPDF_Page() { |
751 return; | 798 m_pPageRender = NULL; |
752 } | 799 } |
753 m_pParser->Continue(pPause); | 800 void CPDF_Page::Load(CPDF_Document* pDocument, |
754 if (m_pParser->GetStatus() == CPDF_ContentParser::Done) { | 801 CPDF_Dictionary* pPageDict, |
755 m_ParseState = CONTENT_PARSED; | 802 FX_BOOL bPageCache) { |
756 delete m_pParser; | 803 m_pDocument = (CPDF_Document*)pDocument; |
757 m_pParser = NULL; | 804 m_pFormDict = pPageDict; |
758 } | 805 if (bPageCache) { |
759 } | 806 m_pPageRender = |
760 FX_POSITION CPDF_PageObjects::InsertObject(FX_POSITION posInsertAfter, CPDF_Page
Object* pNewObject) | 807 CPDF_ModuleMgr::Get()->GetRenderModule()->CreatePageCache(this); |
761 { | 808 } |
762 if (!posInsertAfter) { | 809 if (pPageDict == NULL) { |
763 return m_ObjectList.AddHead(pNewObject); | 810 m_PageWidth = m_PageHeight = 100 * 1.0f; |
764 } | 811 m_pPageResources = m_pResources = NULL; |
765 return m_ObjectList.InsertAfter(posInsertAfter, pNewObject); | 812 return; |
766 } | 813 } |
767 int CPDF_PageObjects::GetObjectIndex(CPDF_PageObject* pObj) const | 814 CPDF_Object* pageAttr = GetPageAttr(FX_BSTRC("Resources")); |
768 { | 815 m_pResources = pageAttr ? pageAttr->GetDict() : NULL; |
769 int index = 0; | 816 m_pPageResources = m_pResources; |
770 FX_POSITION pos = m_ObjectList.GetHeadPosition(); | 817 CPDF_Object* pRotate = GetPageAttr(FX_BSTRC("Rotate")); |
771 while (pos) { | 818 int rotate = 0; |
772 CPDF_PageObject* pThisObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos); | 819 if (pRotate) { |
773 if (pThisObj == pObj) { | 820 rotate = pRotate->GetInteger() / 90 % 4; |
774 return index; | 821 } |
775 } | 822 if (rotate < 0) { |
776 index ++; | 823 rotate += 4; |
777 } | 824 } |
778 return -1; | 825 CPDF_Array *pMediaBox, *pCropBox; |
779 } | 826 pMediaBox = (CPDF_Array*)GetPageAttr(FX_BSTRC("MediaBox")); |
780 CPDF_PageObject* CPDF_PageObjects::GetObjectByIndex(int index) const | 827 CFX_FloatRect mediabox; |
781 { | 828 if (pMediaBox) { |
782 FX_POSITION pos = m_ObjectList.FindIndex(index); | 829 mediabox = pMediaBox->GetRect(); |
783 if (pos == NULL) { | 830 mediabox.Normalize(); |
784 return NULL; | 831 } |
785 } | 832 if (mediabox.IsEmpty()) { |
786 return (CPDF_PageObject*)m_ObjectList.GetAt(pos); | 833 mediabox = CFX_FloatRect(0, 0, 612, 792); |
787 } | 834 } |
788 void CPDF_PageObjects::Transform(const CFX_AffineMatrix& matrix) | 835 pCropBox = (CPDF_Array*)GetPageAttr(FX_BSTRC("CropBox")); |
789 { | 836 if (pCropBox) { |
790 FX_POSITION pos = m_ObjectList.GetHeadPosition(); | 837 m_BBox = pCropBox->GetRect(); |
791 while (pos) { | 838 m_BBox.Normalize(); |
792 CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos); | 839 } |
793 pObj->Transform(matrix); | 840 if (m_BBox.IsEmpty()) { |
794 } | 841 m_BBox = mediabox; |
795 } | 842 } else { |
796 CFX_FloatRect CPDF_PageObjects::CalcBoundingBox() const | 843 m_BBox.Intersect(mediabox); |
797 { | 844 } |
798 if (m_ObjectList.GetCount() == 0) { | 845 if (rotate % 2) { |
799 return CFX_FloatRect(0, 0, 0, 0); | 846 m_PageHeight = m_BBox.right - m_BBox.left; |
800 } | 847 m_PageWidth = m_BBox.top - m_BBox.bottom; |
801 FX_FLOAT left, right, top, bottom; | 848 } else { |
802 left = bottom = 1000000 * 1.0f; | 849 m_PageWidth = m_BBox.right - m_BBox.left; |
803 right = top = -1000000 * 1.0f; | 850 m_PageHeight = m_BBox.top - m_BBox.bottom; |
804 FX_POSITION pos = m_ObjectList.GetHeadPosition(); | 851 } |
805 while (pos) { | 852 switch (rotate) { |
806 CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos); | 853 case 0: |
807 if (left > pObj->m_Left) { | 854 m_PageMatrix.Set(1.0f, 0, 0, 1.0f, -m_BBox.left, -m_BBox.bottom); |
808 left = pObj->m_Left; | 855 break; |
809 } | 856 case 1: |
810 if (right < pObj->m_Right) { | 857 m_PageMatrix.Set(0, -1.0f, 1.0f, 0, -m_BBox.bottom, m_BBox.right); |
811 right = pObj->m_Right; | 858 break; |
812 } | 859 case 2: |
813 if (top < pObj->m_Top) { | 860 m_PageMatrix.Set(-1.0f, 0, 0, -1.0f, m_BBox.right, m_BBox.top); |
814 top = pObj->m_Top; | 861 break; |
815 } | 862 case 3: |
816 if (bottom > pObj->m_Bottom) { | 863 m_PageMatrix.Set(0, 1.0f, -1.0f, 0, m_BBox.top, -m_BBox.left); |
817 bottom = pObj->m_Bottom; | 864 break; |
818 } | 865 } |
819 } | 866 m_Transparency = PDFTRANS_ISOLATED; |
820 return CFX_FloatRect(left, bottom, right, top); | 867 LoadTransInfo(); |
821 } | 868 } |
822 void CPDF_PageObjects::LoadTransInfo() | 869 void CPDF_Page::StartParse(CPDF_ParseOptions* pOptions, FX_BOOL bReParse) { |
823 { | 870 if (bReParse) { |
824 if (m_pFormDict == NULL) { | 871 ClearCacheObjects(); |
825 return; | 872 } |
826 } | 873 if (m_ParseState == CONTENT_PARSED || m_ParseState == CONTENT_PARSING) { |
827 CPDF_Dictionary* pGroup = m_pFormDict->GetDict(FX_BSTRC("Group")); | 874 return; |
828 if (pGroup == NULL) { | 875 } |
829 return; | 876 m_pParser = new CPDF_ContentParser; |
830 } | 877 m_pParser->Start(this, pOptions); |
831 if (pGroup->GetString(FX_BSTRC("S")) != FX_BSTRC("Transparency")) { | 878 m_ParseState = CONTENT_PARSING; |
832 return; | 879 } |
833 } | 880 void CPDF_Page::ParseContent(CPDF_ParseOptions* pOptions, FX_BOOL bReParse) { |
834 m_Transparency |= PDFTRANS_GROUP; | 881 StartParse(pOptions, bReParse); |
835 if (pGroup->GetInteger(FX_BSTRC("I"))) { | 882 ContinueParse(NULL); |
836 m_Transparency |= PDFTRANS_ISOLATED; | 883 } |
837 } | 884 CPDF_Page::~CPDF_Page() { |
838 if (pGroup->GetInteger(FX_BSTRC("K"))) { | 885 if (m_pPageRender) { |
839 m_Transparency |= PDFTRANS_KNOCKOUT; | 886 IPDF_RenderModule* pModule = CPDF_ModuleMgr::Get()->GetRenderModule(); |
840 } | 887 pModule->DestroyPageCache(m_pPageRender); |
841 } | 888 } |
842 void CPDF_PageObjects::ClearCacheObjects() | 889 } |
843 { | 890 CPDF_Object* FPDFAPI_GetPageAttr(CPDF_Dictionary* pPageDict, |
844 m_ParseState = CONTENT_NOT_PARSED; | 891 const CFX_ByteStringC& name) { |
845 delete m_pParser; | 892 int level = 0; |
846 m_pParser = NULL; | 893 while (1) { |
847 if (m_bReleaseMembers) { | 894 CPDF_Object* pObj = pPageDict->GetElementValue(name); |
848 FX_POSITION pos = m_ObjectList.GetHeadPosition(); | 895 if (pObj) { |
849 while (pos) { | 896 return pObj; |
850 delete (CPDF_PageObject*)m_ObjectList.GetNext(pos); | 897 } |
851 } | 898 CPDF_Dictionary* pParent = pPageDict->GetDict(FX_BSTRC("Parent")); |
852 } | 899 if (!pParent || pParent == pPageDict) { |
853 m_ObjectList.RemoveAll(); | 900 return NULL; |
854 } | 901 } |
855 CPDF_Page::CPDF_Page() | 902 pPageDict = pParent; |
856 { | 903 level++; |
857 m_pPageRender = NULL; | 904 if (level == 1000) { |
858 } | 905 return NULL; |
859 void CPDF_Page::Load(CPDF_Document* pDocument, CPDF_Dictionary* pPageDict, FX_BO
OL bPageCache) | 906 } |
860 { | 907 } |
861 m_pDocument = (CPDF_Document*)pDocument; | 908 } |
862 m_pFormDict = pPageDict; | 909 CPDF_Object* CPDF_Page::GetPageAttr(const CFX_ByteStringC& name) const { |
863 if (bPageCache) { | 910 return FPDFAPI_GetPageAttr(m_pFormDict, name); |
864 m_pPageRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreatePageCach
e(this); | 911 } |
865 } | 912 CPDF_Form::CPDF_Form(CPDF_Document* pDoc, |
866 if (pPageDict == NULL) { | 913 CPDF_Dictionary* pPageResources, |
867 m_PageWidth = m_PageHeight = 100 * 1.0f; | 914 CPDF_Stream* pFormStream, |
868 m_pPageResources = m_pResources = NULL; | 915 CPDF_Dictionary* pParentResources) { |
869 return; | 916 m_pDocument = pDoc; |
870 } | 917 m_pFormStream = pFormStream; |
871 CPDF_Object* pageAttr = GetPageAttr(FX_BSTRC("Resources")); | 918 m_pFormDict = pFormStream ? pFormStream->GetDict() : NULL; |
872 m_pResources = pageAttr ? pageAttr->GetDict() : NULL; | 919 m_pResources = m_pFormDict->GetDict(FX_BSTRC("Resources")); |
873 m_pPageResources = m_pResources; | 920 m_pPageResources = pPageResources; |
874 CPDF_Object* pRotate = GetPageAttr(FX_BSTRC("Rotate")); | 921 if (m_pResources == NULL) { |
875 int rotate = 0; | 922 m_pResources = pParentResources; |
876 if (pRotate) { | 923 } |
877 rotate = pRotate->GetInteger() / 90 % 4; | 924 if (m_pResources == NULL) { |
878 } | 925 m_pResources = pPageResources; |
879 if (rotate < 0) { | 926 } |
880 rotate += 4; | 927 m_Transparency = 0; |
881 } | 928 LoadTransInfo(); |
882 CPDF_Array* pMediaBox, *pCropBox; | 929 } |
883 pMediaBox = (CPDF_Array*)GetPageAttr(FX_BSTRC("MediaBox")); | 930 CPDF_Form::~CPDF_Form() {} |
884 CFX_FloatRect mediabox; | 931 void CPDF_Form::StartParse(CPDF_AllStates* pGraphicStates, |
885 if (pMediaBox) { | 932 CFX_AffineMatrix* pParentMatrix, |
886 mediabox = pMediaBox->GetRect(); | 933 CPDF_Type3Char* pType3Char, |
887 mediabox.Normalize(); | 934 CPDF_ParseOptions* pOptions, |
888 } | 935 int level) { |
889 if (mediabox.IsEmpty()) { | 936 if (m_ParseState == CONTENT_PARSED || m_ParseState == CONTENT_PARSING) { |
890 mediabox = CFX_FloatRect(0, 0, 612, 792); | 937 return; |
891 } | 938 } |
892 pCropBox = (CPDF_Array*)GetPageAttr(FX_BSTRC("CropBox")); | 939 m_pParser = new CPDF_ContentParser; |
893 if (pCropBox) { | 940 m_pParser->Start(this, pGraphicStates, pParentMatrix, pType3Char, pOptions, |
894 m_BBox = pCropBox->GetRect(); | 941 level); |
895 m_BBox.Normalize(); | 942 m_ParseState = CONTENT_PARSING; |
896 } | 943 } |
897 if (m_BBox.IsEmpty()) { | 944 void CPDF_Form::ParseContent(CPDF_AllStates* pGraphicStates, |
898 m_BBox = mediabox; | 945 CFX_AffineMatrix* pParentMatrix, |
899 } else { | 946 CPDF_Type3Char* pType3Char, |
900 m_BBox.Intersect(mediabox); | 947 CPDF_ParseOptions* pOptions, |
901 } | 948 int level) { |
902 if (rotate % 2) { | 949 StartParse(pGraphicStates, pParentMatrix, pType3Char, pOptions, level); |
903 m_PageHeight = m_BBox.right - m_BBox.left; | 950 ContinueParse(NULL); |
904 m_PageWidth = m_BBox.top - m_BBox.bottom; | 951 } |
905 } else { | 952 CPDF_Form* CPDF_Form::Clone() const { |
906 m_PageWidth = m_BBox.right - m_BBox.left; | 953 CPDF_Form* pClone = |
907 m_PageHeight = m_BBox.top - m_BBox.bottom; | 954 new CPDF_Form(m_pDocument, m_pPageResources, m_pFormStream, m_pResources); |
908 } | 955 FX_POSITION pos = m_ObjectList.GetHeadPosition(); |
909 switch (rotate) { | 956 while (pos) { |
910 case 0: | 957 CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos); |
911 m_PageMatrix.Set(1.0f, 0, 0, 1.0f, -m_BBox.left, -m_BBox.bottom); | 958 pClone->m_ObjectList.AddTail(pObj->Clone()); |
912 break; | 959 } |
913 case 1: | 960 return pClone; |
914 m_PageMatrix.Set(0, -1.0f, 1.0f, 0, -m_BBox.bottom, m_BBox.right); | 961 } |
915 break; | 962 void CPDF_Page::GetDisplayMatrix(CFX_AffineMatrix& matrix, |
916 case 2: | 963 int xPos, |
917 m_PageMatrix.Set(-1.0f, 0, 0, -1.0f, m_BBox.right, m_BBox.top); | 964 int yPos, |
918 break; | 965 int xSize, |
919 case 3: | 966 int ySize, |
920 m_PageMatrix.Set(0, 1.0f, -1.0f, 0, m_BBox.top, -m_BBox.left); | 967 int iRotate) const { |
921 break; | 968 if (m_PageWidth == 0 || m_PageHeight == 0) { |
922 } | 969 return; |
923 m_Transparency = PDFTRANS_ISOLATED; | 970 } |
924 LoadTransInfo(); | 971 CFX_AffineMatrix display_matrix; |
925 } | 972 int x0, y0, x1, y1, x2, y2; |
926 void CPDF_Page::StartParse(CPDF_ParseOptions* pOptions, FX_BOOL bReParse) | 973 iRotate %= 4; |
927 { | 974 switch (iRotate) { |
928 if (bReParse) { | 975 case 0: |
929 ClearCacheObjects(); | 976 x0 = xPos; |
930 } | 977 y0 = yPos + ySize; |
931 if (m_ParseState == CONTENT_PARSED || m_ParseState == CONTENT_PARSING) { | 978 x1 = xPos; |
932 return; | 979 y1 = yPos; |
933 } | 980 x2 = xPos + xSize; |
934 m_pParser = new CPDF_ContentParser; | 981 y2 = yPos + ySize; |
935 m_pParser->Start(this, pOptions); | 982 break; |
936 m_ParseState = CONTENT_PARSING; | 983 case 1: |
937 } | 984 x0 = xPos; |
938 void CPDF_Page::ParseContent(CPDF_ParseOptions* pOptions, FX_BOOL bReParse) | 985 y0 = yPos; |
939 { | 986 x1 = xPos + xSize; |
940 StartParse(pOptions, bReParse); | 987 y1 = yPos; |
941 ContinueParse(NULL); | 988 x2 = xPos; |
942 } | 989 y2 = yPos + ySize; |
943 CPDF_Page::~CPDF_Page() | 990 break; |
944 { | 991 case 2: |
945 if (m_pPageRender) { | 992 x0 = xPos + xSize; |
946 IPDF_RenderModule* pModule = CPDF_ModuleMgr::Get()->GetRenderModule(); | 993 y0 = yPos; |
947 pModule->DestroyPageCache(m_pPageRender); | 994 x1 = xPos + xSize; |
948 } | 995 y1 = yPos + ySize; |
949 } | 996 x2 = xPos; |
950 CPDF_Object* FPDFAPI_GetPageAttr(CPDF_Dictionary* pPageDict, const CFX_ByteStrin
gC& name) | 997 y2 = yPos; |
951 { | 998 break; |
952 int level = 0; | 999 case 3: |
953 while (1) { | 1000 x0 = xPos + xSize; |
954 CPDF_Object* pObj = pPageDict->GetElementValue(name); | 1001 y0 = yPos + ySize; |
955 if (pObj) { | 1002 x1 = xPos; |
956 return pObj; | 1003 y1 = yPos + ySize; |
957 } | 1004 x2 = xPos + xSize; |
958 CPDF_Dictionary* pParent = pPageDict->GetDict(FX_BSTRC("Parent")); | 1005 y2 = yPos; |
959 if (!pParent || pParent == pPageDict) { | 1006 break; |
960 return NULL; | 1007 } |
961 } | 1008 display_matrix.Set(FXSYS_Div((FX_FLOAT)(x2 - x0), m_PageWidth), |
962 pPageDict = pParent; | 1009 FXSYS_Div((FX_FLOAT)(y2 - y0), m_PageWidth), |
963 level ++; | 1010 FXSYS_Div((FX_FLOAT)(x1 - x0), m_PageHeight), |
964 if (level == 1000) { | 1011 FXSYS_Div((FX_FLOAT)(y1 - y0), m_PageHeight), (FX_FLOAT)x0, |
965 return NULL; | 1012 (FX_FLOAT)y0); |
966 } | 1013 matrix = m_PageMatrix; |
967 } | 1014 matrix.Concat(display_matrix); |
968 } | 1015 } |
969 CPDF_Object* CPDF_Page::GetPageAttr(const CFX_ByteStringC& name) const | 1016 CPDF_ParseOptions::CPDF_ParseOptions() { |
970 { | 1017 m_bTextOnly = FALSE; |
971 return FPDFAPI_GetPageAttr(m_pFormDict, name); | 1018 m_bMarkedContent = TRUE; |
972 } | 1019 m_bSeparateForm = TRUE; |
973 CPDF_Form::CPDF_Form(CPDF_Document* pDoc, CPDF_Dictionary* pPageResources, CPDF_
Stream* pFormStream, CPDF_Dictionary* pParentResources) | 1020 m_bDecodeInlineImage = FALSE; |
974 { | 1021 } |
975 m_pDocument = pDoc; | |
976 m_pFormStream = pFormStream; | |
977 m_pFormDict = pFormStream ? pFormStream->GetDict() : NULL; | |
978 m_pResources = m_pFormDict->GetDict(FX_BSTRC("Resources")); | |
979 m_pPageResources = pPageResources; | |
980 if (m_pResources == NULL) { | |
981 m_pResources = pParentResources; | |
982 } | |
983 if (m_pResources == NULL) { | |
984 m_pResources = pPageResources; | |
985 } | |
986 m_Transparency = 0; | |
987 LoadTransInfo(); | |
988 } | |
989 CPDF_Form::~CPDF_Form() | |
990 { | |
991 } | |
992 void CPDF_Form::StartParse(CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pPa
rentMatrix, | |
993 CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptio
ns, int level) | |
994 { | |
995 if (m_ParseState == CONTENT_PARSED || m_ParseState == CONTENT_PARSING) { | |
996 return; | |
997 } | |
998 m_pParser = new CPDF_ContentParser; | |
999 m_pParser->Start(this, pGraphicStates, pParentMatrix, pType3Char, pOptions,
level); | |
1000 m_ParseState = CONTENT_PARSING; | |
1001 } | |
1002 void CPDF_Form::ParseContent(CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* p
ParentMatrix, | |
1003 CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOpt
ions, int level) | |
1004 { | |
1005 StartParse(pGraphicStates, pParentMatrix, pType3Char, pOptions, level); | |
1006 ContinueParse(NULL); | |
1007 } | |
1008 CPDF_Form* CPDF_Form::Clone() const | |
1009 { | |
1010 CPDF_Form* pClone = new CPDF_Form(m_pDocument, m_pPageResources, m_pFormStre
am, m_pResources); | |
1011 FX_POSITION pos = m_ObjectList.GetHeadPosition(); | |
1012 while (pos) { | |
1013 CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos); | |
1014 pClone->m_ObjectList.AddTail(pObj->Clone()); | |
1015 } | |
1016 return pClone; | |
1017 } | |
1018 void CPDF_Page::GetDisplayMatrix(CFX_AffineMatrix& matrix, int xPos, int yPos, | |
1019 int xSize, int ySize, int iRotate) const | |
1020 { | |
1021 if (m_PageWidth == 0 || m_PageHeight == 0) { | |
1022 return; | |
1023 } | |
1024 CFX_AffineMatrix display_matrix; | |
1025 int x0, y0, x1, y1, x2, y2; | |
1026 iRotate %= 4; | |
1027 switch (iRotate) { | |
1028 case 0: | |
1029 x0 = xPos; | |
1030 y0 = yPos + ySize; | |
1031 x1 = xPos; | |
1032 y1 = yPos; | |
1033 x2 = xPos + xSize; | |
1034 y2 = yPos + ySize; | |
1035 break; | |
1036 case 1: | |
1037 x0 = xPos; | |
1038 y0 = yPos; | |
1039 x1 = xPos + xSize; | |
1040 y1 = yPos; | |
1041 x2 = xPos; | |
1042 y2 = yPos + ySize; | |
1043 break; | |
1044 case 2: | |
1045 x0 = xPos + xSize; | |
1046 y0 = yPos; | |
1047 x1 = xPos + xSize; | |
1048 y1 = yPos + ySize; | |
1049 x2 = xPos; | |
1050 y2 = yPos; | |
1051 break; | |
1052 case 3: | |
1053 x0 = xPos + xSize; | |
1054 y0 = yPos + ySize; | |
1055 x1 = xPos; | |
1056 y1 = yPos + ySize; | |
1057 x2 = xPos + xSize; | |
1058 y2 = yPos; | |
1059 break; | |
1060 } | |
1061 display_matrix.Set(FXSYS_Div((FX_FLOAT)(x2 - x0), m_PageWidth), | |
1062 FXSYS_Div((FX_FLOAT)(y2 - y0), m_PageWidth), | |
1063 FXSYS_Div((FX_FLOAT)(x1 - x0), m_PageHeight), | |
1064 FXSYS_Div((FX_FLOAT)(y1 - y0), m_PageHeight), | |
1065 (FX_FLOAT)x0, (FX_FLOAT)y0); | |
1066 matrix = m_PageMatrix; | |
1067 matrix.Concat(display_matrix); | |
1068 } | |
1069 CPDF_ParseOptions::CPDF_ParseOptions() | |
1070 { | |
1071 m_bTextOnly = FALSE; | |
1072 m_bMarkedContent = TRUE; | |
1073 m_bSeparateForm = TRUE; | |
1074 m_bDecodeInlineImage = FALSE; | |
1075 } | |
OLD | NEW |