OLD | NEW |
| (Empty) |
1 // Copyright 2014 PDFium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
6 | |
7 #include "../../../include/fpdfapi/fpdf_page.h" | |
8 #include "../../../include/fpdfapi/fpdf_module.h" | |
9 #include "pageint.h" | |
10 #if defined(_FPDFAPI_MINI_) | |
11 extern const FX_LPCSTR _PDF_CharType; | |
12 void CPDF_StreamContentParser::InputData(FX_LPCBYTE src_buf, FX_DWORD src_size) | |
13 { | |
14 if (m_Level > _FPDF_MAX_FORM_LEVEL_) { | |
15 return; | |
16 } | |
17 for (FX_DWORD i = 0; i < src_size; i ++) { | |
18 int ch = src_buf[i]; | |
19 int type = _PDF_CharType[ch]; | |
20 start: | |
21 switch (m_WordState) { | |
22 case 0: | |
23 if (type == 'W') { | |
24 } else if (type == 'N') { | |
25 m_WordState = 5; | |
26 m_pWordBuf[0] = ch; | |
27 m_WordSize = 1; | |
28 } else if (type == 'R') { | |
29 m_WordState = 4; | |
30 m_pWordBuf[0] = ch; | |
31 m_WordSize = 1; | |
32 } else switch (ch) { | |
33 case '/': | |
34 m_WordState = 2; | |
35 m_WordSize = 0; | |
36 break; | |
37 case '[': | |
38 StartArray(); | |
39 break; | |
40 case ']': | |
41 EndArray(); | |
42 break; | |
43 case '(': | |
44 m_WordState = 7; | |
45 m_StringLevel = 1; | |
46 m_StringState = 0; | |
47 m_StringBuf.Clear(); | |
48 break; | |
49 case '<': | |
50 m_WordState = 3; | |
51 break; | |
52 case '>': | |
53 m_WordState = 8; | |
54 break; | |
55 case '%': | |
56 m_WordState = 1; | |
57 break; | |
58 } | |
59 break; | |
60 case 1: | |
61 if (ch == '\n' || ch == '\r') { | |
62 m_WordState = 0; | |
63 } | |
64 break; | |
65 case 2: | |
66 if (type != 'R' && type != 'N') { | |
67 EndName(); | |
68 m_WordState = 0; | |
69 goto start; | |
70 } | |
71 if (m_WordSize < 256) { | |
72 m_pWordBuf[m_WordSize++] = ch; | |
73 } | |
74 break; | |
75 case 3: | |
76 if (ch == '<') { | |
77 StartDict(); | |
78 m_WordState = 0; | |
79 } else { | |
80 m_StringBuf.Clear(); | |
81 m_WordState = 6; | |
82 goto start; | |
83 } | |
84 break; | |
85 case 4: | |
86 if (type != 'R' && type != 'N') { | |
87 m_WordState = 0; | |
88 EndKeyword(); | |
89 if (m_bAbort) { | |
90 return; | |
91 } | |
92 goto start; | |
93 } | |
94 if (m_WordSize < 256) { | |
95 m_pWordBuf[m_WordSize++] = ch; | |
96 } | |
97 break; | |
98 case 5: | |
99 if (type != 'N') { | |
100 EndNumber(); | |
101 m_WordState = 0; | |
102 goto start; | |
103 } | |
104 if (m_WordSize < 256) { | |
105 m_pWordBuf[m_WordSize++] = ch; | |
106 } | |
107 break; | |
108 case 6: | |
109 if (ch == '>') { | |
110 EndHexString(); | |
111 m_WordState = 0; | |
112 } else { | |
113 m_StringBuf.AppendByte(ch); | |
114 } | |
115 break; | |
116 case 7: | |
117 switch (m_StringState) { | |
118 case 0: | |
119 if (ch == ')') { | |
120 m_StringLevel --; | |
121 if (m_StringLevel == 0) { | |
122 EndString(); | |
123 m_WordState = 0; | |
124 break; | |
125 } | |
126 m_StringBuf.AppendByte(')'); | |
127 } else if (ch == '(') { | |
128 m_StringLevel ++; | |
129 m_StringBuf.AppendByte('('); | |
130 } else if (ch == '\\') { | |
131 m_StringState = 1; | |
132 } else { | |
133 m_StringBuf.AppendByte((char)ch); | |
134 } | |
135 break; | |
136 case 1: | |
137 if (ch >= '0' && ch <= '7') { | |
138 m_EscCode = ch - '0'; | |
139 m_StringState = 2; | |
140 break; | |
141 } | |
142 if (ch == 'n') { | |
143 m_StringBuf.AppendByte('\n'); | |
144 } else if (ch == 'r') { | |
145 m_StringBuf.AppendByte('\r'); | |
146 } else if (ch == 't') { | |
147 m_StringBuf.AppendByte('\t'); | |
148 } else if (ch == 'b') { | |
149 m_StringBuf.AppendByte('\b'); | |
150 } else if (ch == 'f') { | |
151 m_StringBuf.AppendByte('\f'); | |
152 } else if (ch == '\\') { | |
153 m_StringBuf.AppendByte('\\'); | |
154 } else if (ch == '(') { | |
155 m_StringBuf.AppendByte('('); | |
156 } else if (ch == ')') { | |
157 m_StringBuf.AppendByte(')'); | |
158 } else if (ch == '\r') { | |
159 m_StringState = 4; | |
160 break; | |
161 } else if (ch == '\n') { | |
162 } else { | |
163 m_StringBuf.AppendByte(ch); | |
164 } | |
165 m_StringState = 0; | |
166 break; | |
167 case 2: | |
168 if (ch >= '0' && ch <= '7') { | |
169 m_EscCode = m_EscCode * 8 + ch - '0'; | |
170 m_StringState = 3; | |
171 } else { | |
172 m_StringBuf.AppendByte(m_EscCode); | |
173 m_StringState = 0; | |
174 goto start; | |
175 } | |
176 break; | |
177 case 3: | |
178 if (ch >= '0' && ch <= '7') { | |
179 m_EscCode = m_EscCode * 8 + ch - '0'; | |
180 m_StringBuf.AppendByte(m_EscCode); | |
181 m_StringState = 0; | |
182 } else { | |
183 m_StringBuf.AppendByte(m_EscCode); | |
184 m_StringState = 0; | |
185 goto start; | |
186 } | |
187 break; | |
188 case 4: | |
189 m_StringState = 0; | |
190 if (ch != '\n') { | |
191 goto start; | |
192 } | |
193 break; | |
194 } | |
195 break; | |
196 case 8: | |
197 m_WordState = 0; | |
198 if (ch == '>') { | |
199 EndDict(); | |
200 } else { | |
201 goto start; | |
202 } | |
203 break; | |
204 case 9: | |
205 switch (m_InlineImageState) { | |
206 case 0: | |
207 if (type == 'W' || type == 'D') { | |
208 m_InlineImageState = 1; | |
209 m_InlineWhiteChar = ch; | |
210 } else { | |
211 m_StringBuf.AppendByte(ch); | |
212 } | |
213 break; | |
214 case 1: | |
215 m_StringBuf.AppendByte(m_InlineWhiteChar); | |
216 if (ch == 'I') { | |
217 m_InlineImageState = 2; | |
218 } else { | |
219 m_InlineImageState = 0; | |
220 goto start; | |
221 } | |
222 break; | |
223 case 2: | |
224 if (ch == 'D') { | |
225 m_InlineImageState = 3; | |
226 } else { | |
227 m_StringBuf.AppendByte('I'); | |
228 m_InlineImageState = 0; | |
229 goto start; | |
230 } | |
231 break; | |
232 case 3: | |
233 EndImageDict(); | |
234 break; | |
235 } | |
236 break; | |
237 case 10: | |
238 switch (m_InlineImageState) { | |
239 case 0: | |
240 if (type == 'W') { | |
241 m_InlineImageState = 1; | |
242 m_InlineWhiteChar = ch; | |
243 } else { | |
244 m_ImageSrcBuf.AppendByte(ch); | |
245 } | |
246 break; | |
247 case 1: | |
248 if (ch == 'E') { | |
249 m_InlineImageState = 2; | |
250 } else { | |
251 m_ImageSrcBuf.AppendByte(m_InlineWhiteChar); | |
252 m_InlineImageState = 0; | |
253 goto start; | |
254 } | |
255 break; | |
256 case 2: | |
257 if (ch == 'I') { | |
258 m_InlineImageState = 3; | |
259 } else { | |
260 m_ImageSrcBuf.AppendByte(m_InlineWhiteChar); | |
261 m_ImageSrcBuf.AppendByte('E'); | |
262 m_InlineImageState = 0; | |
263 goto start; | |
264 } | |
265 break; | |
266 case 3: | |
267 if (type == 'W') { | |
268 EndInlineImage(); | |
269 } else { | |
270 m_ImageSrcBuf.AppendByte(m_InlineWhiteChar); | |
271 m_ImageSrcBuf.AppendByte('E'); | |
272 m_ImageSrcBuf.AppendByte('I'); | |
273 m_InlineImageState = 0; | |
274 goto start; | |
275 } | |
276 break; | |
277 } | |
278 break; | |
279 case 11: | |
280 if (m_InlineImageState < m_ImageSrcBuf.GetSize()) { | |
281 m_ImageSrcBuf.GetBuffer()[m_InlineImageState ++] = ch; | |
282 } else { | |
283 if (ch == 'I') { | |
284 EndInlineImage(); | |
285 } | |
286 } | |
287 break; | |
288 } | |
289 } | |
290 } | |
291 void CPDF_StreamContentParser::Finish() | |
292 { | |
293 switch (m_WordState) { | |
294 case 0: | |
295 break; | |
296 case 1: | |
297 break; | |
298 case 2: | |
299 EndName(); | |
300 break; | |
301 case 3: | |
302 break; | |
303 case 4: | |
304 EndKeyword(); | |
305 break; | |
306 case 5: | |
307 EndNumber(); | |
308 break; | |
309 case 6: | |
310 EndHexString(); | |
311 break; | |
312 case 7: | |
313 EndString(); | |
314 break; | |
315 case 8: | |
316 break; | |
317 case 9: | |
318 break; | |
319 case 10: | |
320 EndInlineImage(); | |
321 break; | |
322 } | |
323 m_WordState = 0; | |
324 } | |
325 void CPDF_StreamContentParser::AddContainer(CPDF_Object* pObject) | |
326 { | |
327 if (m_ObjectSize) { | |
328 m_pObjectState[m_ObjectSize] = SetToCurObj(pObject); | |
329 } | |
330 FXSYS_assert(m_ObjectSize < _FPDF_MAX_OBJECT_STACK_SIZE_); | |
331 m_pObjectStack[m_ObjectSize++] = pObject; | |
332 } | |
333 FX_BOOL CPDF_StreamContentParser::SetToCurObj(CPDF_Object* pObject) | |
334 { | |
335 if (m_ObjectSize == 0) { | |
336 AddObjectParam(pObject); | |
337 return TRUE; | |
338 } | |
339 FX_BOOL bInArrayOrDict = TRUE; | |
340 CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1]; | |
341 if (pCurObj->GetType() == PDFOBJ_ARRAY) { | |
342 ((CPDF_Array*)pCurObj)->Add(pObject, m_pDocument); | |
343 } else { | |
344 if (!m_bDictName && m_pDictName[0]) { | |
345 ((CPDF_Dictionary*)pCurObj)->SetAt((FX_LPCSTR)m_pDictName, pObject,
m_pDocument); | |
346 } else { | |
347 bInArrayOrDict = FALSE; | |
348 } | |
349 m_bDictName = TRUE; | |
350 } | |
351 return bInArrayOrDict; | |
352 } | |
353 void CPDF_StreamContentParser::StartArray() | |
354 { | |
355 if (m_ObjectSize) | |
356 if (m_pObjectStack[0]->GetType() != PDFOBJ_DICTIONARY && m_pObjectStack[
m_ObjectSize - 1]->GetType() == PDFOBJ_ARRAY) { | |
357 return; | |
358 } | |
359 CPDF_Array* pArray = FX_NEW CPDF_Array; | |
360 AddContainer(pArray); | |
361 } | |
362 void CPDF_StreamContentParser::EndArray() | |
363 { | |
364 if (m_ObjectSize == 0) { | |
365 return; | |
366 } | |
367 CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1]; | |
368 if (pCurObj->GetType() != PDFOBJ_ARRAY) { | |
369 return; | |
370 } | |
371 m_ObjectSize --; | |
372 if (m_ObjectSize == 0) { | |
373 AddObjectParam(pCurObj); | |
374 } else { | |
375 if (!m_pObjectState[m_ObjectSize]) { | |
376 pCurObj->Release(); | |
377 } | |
378 } | |
379 m_pObjectState[m_ObjectSize] = FALSE; | |
380 } | |
381 void CPDF_StreamContentParser::StartDict() | |
382 { | |
383 CPDF_Dictionary* pDict = FX_NEW CPDF_Dictionary; | |
384 AddContainer(pDict); | |
385 m_bDictName = TRUE; | |
386 } | |
387 void CPDF_StreamContentParser::EndDict() | |
388 { | |
389 if (m_ObjectSize == 0) { | |
390 return; | |
391 } | |
392 CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1]; | |
393 if (pCurObj->GetType() != PDFOBJ_DICTIONARY) { | |
394 return; | |
395 } | |
396 m_ObjectSize --; | |
397 if (m_ObjectSize == 0) { | |
398 AddObjectParam(pCurObj); | |
399 } else { | |
400 if (!m_pObjectState[m_ObjectSize]) { | |
401 pCurObj->Release(); | |
402 } | |
403 } | |
404 m_pObjectState[m_ObjectSize] = FALSE; | |
405 } | |
406 void CPDF_StreamContentParser::EndName() | |
407 { | |
408 if (m_ObjectSize == 0) { | |
409 AddNameParam((FX_LPCSTR)m_pWordBuf, m_WordSize); | |
410 return; | |
411 } | |
412 CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1]; | |
413 if (pCurObj->GetType() == PDFOBJ_ARRAY) { | |
414 ((CPDF_Array*)pCurObj)->AddName(CFX_ByteString(m_pWordBuf, m_WordSize)); | |
415 } else { | |
416 if (m_bDictName) { | |
417 FXSYS_memcpy32(m_pDictName, m_pWordBuf, m_WordSize); | |
418 m_pDictName[m_WordSize] = 0; | |
419 } else { | |
420 if (m_pDictName[0] != 0) { | |
421 ((CPDF_Dictionary*)pCurObj)->SetAtName((FX_LPCSTR)m_pDictName, C
FX_ByteString(m_pWordBuf, m_WordSize)); | |
422 } | |
423 } | |
424 m_bDictName = !m_bDictName; | |
425 } | |
426 } | |
427 void CPDF_StreamContentParser::EndNumber() | |
428 { | |
429 if (m_ObjectSize == 0) { | |
430 AddNumberParam((FX_LPCSTR)m_pWordBuf, m_WordSize); | |
431 return; | |
432 } | |
433 CPDF_Number *pObj = FX_NEW CPDF_Number(CFX_ByteStringC(m_pWordBuf, m_WordSiz
e)); | |
434 if (!SetToCurObj(pObj)) { | |
435 pObj->Release(); | |
436 } | |
437 } | |
438 extern CFX_ByteString _FPDF_ByteStringFromHex(CFX_BinaryBuf& src_buf); | |
439 void CPDF_StreamContentParser::EndHexString() | |
440 { | |
441 CPDF_String *pObj = FX_NEW CPDF_String(_FPDF_ByteStringFromHex(m_StringBuf),
TRUE); | |
442 if (!SetToCurObj(pObj)) { | |
443 pObj->Release(); | |
444 } | |
445 } | |
446 void CPDF_StreamContentParser::EndString() | |
447 { | |
448 CPDF_String *pObj = FX_NEW CPDF_String(m_StringBuf.GetByteString()); | |
449 if (!SetToCurObj(pObj)) { | |
450 pObj->Release(); | |
451 } | |
452 } | |
453 void CPDF_StreamContentParser::Handle_BeginImage(void) | |
454 { | |
455 m_WordState = 9; | |
456 m_InlineImageState = 0; | |
457 m_StringBuf.Clear(); | |
458 } | |
459 void _PDF_ReplaceAbbr(CPDF_Object* pObj); | |
460 void CPDF_StreamContentParser::EndImageDict() | |
461 { | |
462 if (m_StringBuf.GetSize() != m_LastImageDict.GetSize() || | |
463 FXSYS_memcmp32(m_StringBuf.GetBuffer(), m_LastImageDict.GetBuffer(),
m_StringBuf.GetSize())) { | |
464 m_WordState = 0; | |
465 StartDict(); | |
466 InputData(m_StringBuf.GetBuffer(), m_StringBuf.GetSize()); | |
467 Finish(); | |
468 m_bSameLastDict = FALSE; | |
469 if (m_pLastImageDict && m_bReleaseLastDict) { | |
470 m_pLastImageDict->Release(); | |
471 m_pLastImageDict = NULL; | |
472 } | |
473 if (!m_ObjectSize) { | |
474 m_InlineImageState = 0; | |
475 return; | |
476 } | |
477 m_pLastImageDict = (CPDF_Dictionary*)m_pObjectStack[--m_ObjectSize]; | |
478 m_bReleaseLastDict = !m_pObjectState[m_ObjectSize]; | |
479 m_pObjectState[m_ObjectSize] = FALSE; | |
480 _PDF_ReplaceAbbr(m_pLastImageDict); | |
481 m_LastImageDict.TakeOver(m_StringBuf); | |
482 if (m_pLastImageDict->KeyExist(FX_BSTRC("ColorSpace"))) { | |
483 CPDF_Object* pCSObj = m_pLastImageDict->GetElementValue(FX_BSTRC("Co
lorSpace")); | |
484 if (pCSObj->GetType() == PDFOBJ_NAME) { | |
485 CFX_ByteString name = pCSObj->GetString(); | |
486 if (name != FX_BSTRC("DeviceRGB") && name != FX_BSTRC("DeviceGra
y") && name != FX_BSTRC("DeviceCMYK")) { | |
487 pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name); | |
488 if (pCSObj) { | |
489 if (!pCSObj->GetObjNum()) { | |
490 pCSObj = pCSObj->Clone(); | |
491 } | |
492 m_pLastImageDict->SetAt(FX_BSTRC("ColorSpace"), pCSObj,
m_pDocument); | |
493 } | |
494 } | |
495 } | |
496 } | |
497 } else { | |
498 m_bSameLastDict = TRUE; | |
499 } | |
500 m_ImageSrcBuf.Clear(); | |
501 if (m_pLastCloneImageDict) | |
502 m_pLastCloneImageDict->Release(); | |
503 | |
504 m_pLastCloneImageDict = (CPDF_Dictionary*)m_pLastImageDict->Clone(); | |
505 if (m_pLastCloneImageDict->KeyExist(FX_BSTRC("Filter"))) { | |
506 m_WordState = 10; | |
507 m_InlineImageState = 0; | |
508 } else { | |
509 int width = m_pLastCloneImageDict->GetInteger(FX_BSTRC("Width")); | |
510 int height = m_pLastCloneImageDict->GetInteger(FX_BSTRC("Height")); | |
511 int OrigSize = 0; | |
512 CPDF_Object* pCSObj = m_pLastCloneImageDict->GetElementValue(FX_BSTRC("C
olorSpace")); | |
513 if (pCSObj != NULL) { | |
514 int bpc = m_pLastCloneImageDict->GetInteger(FX_BSTRC("BitsPerCompone
nt")); | |
515 int nComponents = 1; | |
516 CPDF_ColorSpace* pCS = m_pDocument->LoadColorSpace(pCSObj); | |
517 if (pCS == NULL) { | |
518 nComponents = 3; | |
519 } else { | |
520 nComponents = pCS->CountComponents(); | |
521 m_pDocument->GetPageData()->ReleaseColorSpace(pCSObj); | |
522 } | |
523 int pitch = (width * bpc * nComponents + 7) / 8; | |
524 OrigSize = pitch * height; | |
525 } else { | |
526 OrigSize = ((width + 7) / 8) * height; | |
527 } | |
528 m_ImageSrcBuf.AppendBlock(NULL, OrigSize); | |
529 m_WordState = 11; | |
530 m_InlineImageState = 0; | |
531 } | |
532 } | |
533 void CPDF_StreamContentParser::EndInlineImage() | |
534 { | |
535 CFX_AffineMatrix ImageMatrix; | |
536 ImageMatrix.Copy(m_pCurStates->m_CTM); | |
537 ImageMatrix.Concat(m_mtContentToUser); | |
538 m_LastImageData.CopyData(m_ImageSrcBuf.GetBuffer(), m_ImageSrcBuf.GetSize())
; | |
539 CPDF_Stream* pStream = CPDF_Stream::Create(m_ImageSrcBuf.GetBuffer(), m_Imag
eSrcBuf.GetSize(), | |
540 m_pLastCloneImageDict); | |
541 m_ImageSrcBuf.DetachBuffer(); | |
542 m_pLastCloneImageDict = NULL; | |
543 CPDF_InlineImages* pImages = FX_NEW CPDF_InlineImages; | |
544 pImages->m_pStream = pStream; | |
545 SetGraphicStates(pImages, !m_pLastCloneImageDict->KeyExist(FX_BSTRC("ColorSp
ace")), FALSE, FALSE); | |
546 pImages->AddMatrix(ImageMatrix); | |
547 m_pObjectList->m_ObjectList.AddTail(pImages); | |
548 m_WordState = 0; | |
549 } | |
550 #define FXDWORD_TRUE FXDWORD_FROM_LSBFIRST(0x65757274) | |
551 #define FXDWORD_NULL FXDWORD_FROM_LSBFIRST(0x6c6c756e) | |
552 #define FXDWORD_FALS FXDWORD_FROM_LSBFIRST(0x736c6166) | |
553 void CPDF_StreamContentParser::EndKeyword() | |
554 { | |
555 CPDF_Object *pObj = NULL; | |
556 if (m_WordSize == 4) { | |
557 if (*(FX_DWORD*)m_pWordBuf == FXDWORD_TRUE) { | |
558 pObj = CPDF_Boolean::Create(TRUE); | |
559 if (!SetToCurObj(pObj)) { | |
560 pObj->Release(); | |
561 } | |
562 return; | |
563 } else if (*(FX_DWORD*)m_pWordBuf == FXDWORD_NULL) { | |
564 pObj = CPDF_Null::Create(); | |
565 if (!SetToCurObj(pObj)) { | |
566 pObj->Release(); | |
567 } | |
568 return; | |
569 } | |
570 } else if (m_WordSize == 5) { | |
571 if (*(FX_DWORD*)m_pWordBuf == FXDWORD_FALS && m_pWordBuf[4] == 'e') { | |
572 pObj = CPDF_Boolean::Create(FALSE); | |
573 if (!SetToCurObj(pObj)) { | |
574 pObj->Release(); | |
575 } | |
576 return; | |
577 } | |
578 } | |
579 m_pWordBuf[m_WordSize] = 0; | |
580 OnOperator((char*)m_pWordBuf); | |
581 ClearAllParams(); | |
582 } | |
583 #define PAGEPARSE_STAGE_PARSE 2 | |
584 #define PAGEPARSE_STAGE_CHECKCLIP 3 | |
585 CPDF_ContentParser::CPDF_ContentParser() | |
586 { | |
587 m_pParser = NULL; | |
588 m_Status = Ready; | |
589 m_pStreamFilter = NULL; | |
590 m_pType3Char = NULL; | |
591 } | |
592 CPDF_ContentParser::~CPDF_ContentParser() | |
593 { | |
594 Clear(); | |
595 } | |
596 void CPDF_ContentParser::Clear() | |
597 { | |
598 if (m_pParser) { | |
599 delete m_pParser; | |
600 } | |
601 if (m_pStreamFilter) { | |
602 delete m_pStreamFilter; | |
603 } | |
604 m_pParser = NULL; | |
605 m_Status = Ready; | |
606 } | |
607 void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions) | |
608 { | |
609 if (m_Status != Ready || pPage == NULL || pPage->m_pDocument == NULL || pPag
e->m_pFormDict == NULL) { | |
610 m_Status = Done; | |
611 return; | |
612 } | |
613 m_pObjects = pPage; | |
614 m_bForm = FALSE; | |
615 if (pOptions) { | |
616 m_Options = *pOptions; | |
617 } | |
618 CPDF_Object* pContent = pPage->m_pFormDict->GetElementValue(FX_BSTRC("Conten
ts")); | |
619 if (pContent == NULL) { | |
620 m_Status = Done; | |
621 return; | |
622 } | |
623 if (pContent->GetType() == PDFOBJ_STREAM) { | |
624 m_nStreams = 1; | |
625 } else if (pContent->GetType() == PDFOBJ_ARRAY) { | |
626 m_nStreams = ((CPDF_Array*)pContent)->GetCount(); | |
627 } else { | |
628 m_Status = Done; | |
629 return; | |
630 } | |
631 m_Status = ToBeContinued; | |
632 m_InternalStage = PAGEPARSE_STAGE_PARSE; | |
633 m_CurrentOffset = 0; | |
634 m_pParser = FX_NEW CPDF_StreamContentParser; | |
635 m_pParser->Initialize(); | |
636 m_pParser->PrepareParse(pPage->m_pDocument, pPage->m_pResources, NULL, NULL,
pPage, | |
637 pPage->m_pResources, &pPage->m_BBox, &m_Options, NUL
L, 0); | |
638 m_pParser->m_pCurStates->m_ColorState.GetModify()->Default(); | |
639 } | |
640 void CPDF_ContentParser::Start(CPDF_Form* pForm, CPDF_AllStates* pGraphicStates,
CFX_AffineMatrix* pParentMatrix, | |
641 CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pO
ptions, int level) | |
642 { | |
643 m_pType3Char = pType3Char; | |
644 m_pObjects = pForm; | |
645 m_bForm = TRUE; | |
646 CFX_AffineMatrix form_matrix = pForm->m_pFormDict->GetMatrix(FX_BSTRC("Matri
x")); | |
647 if (pGraphicStates) { | |
648 form_matrix.Concat(pGraphicStates->m_CTM); | |
649 } | |
650 CPDF_Array* pBBox = pForm->m_pFormDict->GetArray(FX_BSTRC("BBox")); | |
651 CFX_FloatRect form_bbox; | |
652 CPDF_Path ClipPath; | |
653 if (pBBox) { | |
654 form_bbox = pBBox->GetRect(); | |
655 ClipPath.New(); | |
656 ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, f
orm_bbox.top); | |
657 ClipPath.Transform(&form_matrix); | |
658 if (pParentMatrix) { | |
659 ClipPath.Transform(pParentMatrix); | |
660 } | |
661 form_bbox.Transform(&form_matrix); | |
662 } | |
663 CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDict(FX_BSTRC("Resource
s")); | |
664 m_pParser = FX_NEW CPDF_StreamContentParser; | |
665 m_pParser->Initialize(); | |
666 m_pParser->PrepareParse(pForm->m_pDocument, pForm->m_pPageResources, pForm->
m_pResources, pParentMatrix, pForm, | |
667 pResources, &form_bbox, pOptions, pGraphicStates, le
vel); | |
668 m_pParser->m_pCurStates->m_CTM = form_matrix; | |
669 if (ClipPath.NotNull()) { | |
670 m_pParser->m_pCurStates->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING,
TRUE); | |
671 } | |
672 if (pForm->m_Transparency & PDFTRANS_GROUP) { | |
673 CPDF_GeneralStateData* pData = m_pParser->m_pCurStates->m_GeneralState.G
etModify(); | |
674 pData->m_BlendType = FXDIB_BLEND_NORMAL; | |
675 pData->m_StrokeAlpha = 1.0f; | |
676 pData->m_FillAlpha = 1.0f; | |
677 pData->m_pSoftMask = NULL; | |
678 } | |
679 m_pStreamFilter = pForm->m_pFormStream->GetStreamFilter(); | |
680 m_nStreams = 1; | |
681 m_Status = ToBeContinued; | |
682 m_InternalStage = PAGEPARSE_STAGE_PARSE; | |
683 m_CurrentOffset = 0; | |
684 } | |
685 void CPDF_ContentParser::Continue(IFX_Pause* pPause) | |
686 { | |
687 while (m_Status == ToBeContinued) { | |
688 if (m_InternalStage == PAGEPARSE_STAGE_PARSE) { | |
689 if (m_pStreamFilter == NULL) { | |
690 if (m_CurrentOffset == m_nStreams) { | |
691 m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP; | |
692 if (m_pType3Char) { | |
693 m_pType3Char->m_bColored = m_pParser->m_bColored; | |
694 m_pType3Char->m_Width = FXSYS_round(m_pParser->m_Type3Da
ta[0] * 1000); | |
695 m_pType3Char->m_BBox.left = FXSYS_round(m_pParser->m_Typ
e3Data[2] * 1000); | |
696 m_pType3Char->m_BBox.bottom = FXSYS_round(m_pParser->m_T
ype3Data[3] * 1000); | |
697 m_pType3Char->m_BBox.right = FXSYS_round(m_pParser->m_Ty
pe3Data[4] * 1000); | |
698 m_pType3Char->m_BBox.top = FXSYS_round(m_pParser->m_Type
3Data[5] * 1000); | |
699 m_pType3Char->m_bPageRequired = m_pParser->m_bResourceMi
ssing; | |
700 } | |
701 delete m_pParser; | |
702 m_pParser = NULL; | |
703 continue; | |
704 } | |
705 CPDF_Object* pContent = m_pObjects->m_pFormDict->GetElementValue
(FX_BSTRC("Contents")); | |
706 if (pContent->GetType() == PDFOBJ_STREAM) { | |
707 m_pStreamFilter = ((CPDF_Stream*)pContent)->GetStreamFilter(
); | |
708 } else { | |
709 CPDF_Stream* pStream = ((CPDF_Array*)pContent)->GetStream(m_
CurrentOffset); | |
710 if (pStream == NULL) { | |
711 m_CurrentOffset ++; | |
712 continue; | |
713 } | |
714 m_pStreamFilter = pStream->GetStreamFilter(); | |
715 } | |
716 } | |
717 FX_DWORD len = m_pStreamFilter->ReadBlock(m_pParser->m_pStreamBuf, S
TREAM_PARSE_BUFSIZE); | |
718 m_pParser->InputData(m_pParser->m_pStreamBuf, len); | |
719 if (m_pParser->m_bAbort) { | |
720 delete m_pStreamFilter; | |
721 m_pStreamFilter = NULL; | |
722 m_Status = Done; | |
723 delete m_pParser; | |
724 m_pParser = NULL; | |
725 return; | |
726 } | |
727 if (len < STREAM_PARSE_BUFSIZE) { | |
728 m_pParser->Finish(); | |
729 m_CurrentOffset ++; | |
730 delete m_pStreamFilter; | |
731 m_pStreamFilter = NULL; | |
732 } | |
733 if (pPause && pPause->NeedToPauseNow()) { | |
734 return; | |
735 } | |
736 } | |
737 if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) { | |
738 FX_POSITION pos = m_pObjects->m_ObjectList.GetHeadPosition(); | |
739 while (pos) { | |
740 CPDF_PageObject* pObj = (CPDF_PageObject*)m_pObjects->m_ObjectLi
st.GetNext(pos); | |
741 if (pObj == NULL) { | |
742 continue; | |
743 } | |
744 if (pObj->m_ClipPath.IsNull()) { | |
745 continue; | |
746 } | |
747 if (pObj->m_ClipPath.GetPathCount() != 1) { | |
748 continue; | |
749 } | |
750 if (pObj->m_ClipPath.GetTextCount()) { | |
751 continue; | |
752 } | |
753 CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0); | |
754 if (!ClipPath.IsRect() || pObj->m_Type == PDFPAGE_SHADING) { | |
755 continue; | |
756 } | |
757 CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY
(0), | |
758 ClipPath.GetPointX(2), ClipPath.GetPointY
(2)); | |
759 CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Rig
ht, pObj->m_Top); | |
760 if (old_rect.Contains(obj_rect)) { | |
761 pObj->m_ClipPath.SetNull(); | |
762 } | |
763 } | |
764 if (m_pObjects->m_ObjectList.GetCount() == 1) { | |
765 CPDF_PageObject* pObj = (CPDF_PageObject*)m_pObjects->m_ObjectLi
st.GetAt(m_pObjects->m_ObjectList.GetHeadPosition()); | |
766 if (pObj && pObj->m_Type == PDFPAGE_TEXT) { | |
767 CPDF_TextObject* pText = (CPDF_TextObject*)pObj; | |
768 } | |
769 } | |
770 m_Status = Done; | |
771 return; | |
772 } | |
773 } | |
774 } | |
775 int CPDF_ContentParser::EstimateProgress() | |
776 { | |
777 if (m_Status == Ready) { | |
778 return 0; | |
779 } | |
780 if (m_Status == Done) { | |
781 return 100; | |
782 } | |
783 if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) { | |
784 return 90; | |
785 } | |
786 if (m_pStreamFilter == NULL) { | |
787 return 90 * m_CurrentOffset / m_nStreams; | |
788 } | |
789 int total_raw_size = m_pStreamFilter->GetStream()->GetRawSize() * m_nStreams
; | |
790 int parsed_raw_size = m_pStreamFilter->GetStream()->GetRawSize() * m_Current
Offset + | |
791 m_pStreamFilter->GetSrcPos(); | |
792 return 90 * parsed_raw_size / total_raw_size; | |
793 } | |
794 CPDF_InlineImages::CPDF_InlineImages() | |
795 { | |
796 m_Type = PDFPAGE_INLINES; | |
797 m_pStream = NULL; | |
798 m_pBitmap = NULL; | |
799 } | |
800 CPDF_InlineImages::~CPDF_InlineImages() | |
801 { | |
802 if (m_pStream) { | |
803 m_pStream->Release(); | |
804 } | |
805 if (m_pBitmap) { | |
806 delete m_pBitmap; | |
807 } | |
808 } | |
809 void CPDF_InlineImages::AddMatrix(CFX_AffineMatrix& matrix) | |
810 { | |
811 m_Matrices.Add(matrix); | |
812 CFX_FloatRect rect = matrix.GetUnitRect(); | |
813 if (m_Matrices.GetSize() > 1) { | |
814 CFX_FloatRect rect1(m_Left, m_Bottom, m_Right, m_Top); | |
815 rect.Union(rect1); | |
816 } | |
817 m_Left = rect.left; | |
818 m_Right = rect.right; | |
819 m_Top = rect.top; | |
820 m_Bottom = rect.bottom; | |
821 } | |
822 #endif | |
OLD | NEW |