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;
InputData(FX_LPCBYTE src_buf,FX_DWORD src_size)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 }
Finish()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 }
AddContainer(CPDF_Object * pObject)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 }
SetToCurObj(CPDF_Object * pObject)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 }
StartArray()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 }
EndArray()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 }
StartDict()381 void CPDF_StreamContentParser::StartDict()
382 {
383 CPDF_Dictionary* pDict = FX_NEW CPDF_Dictionary;
384 AddContainer(pDict);
385 m_bDictName = TRUE;
386 }
EndDict()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 }
EndName()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, CFX_ByteString(m_pWordBuf, m_WordSize));
422 }
423 }
424 m_bDictName = !m_bDictName;
425 }
426 }
EndNumber()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_WordSize));
434 if (!SetToCurObj(pObj)) {
435 pObj->Release();
436 }
437 }
438 extern CFX_ByteString _FPDF_ByteStringFromHex(CFX_BinaryBuf& src_buf);
EndHexString()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 }
EndString()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 }
Handle_BeginImage(void)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);
EndImageDict()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("ColorSpace"));
484 if (pCSObj->GetType() == PDFOBJ_NAME) {
485 CFX_ByteString name = pCSObj->GetString();
486 if (name != FX_BSTRC("DeviceRGB") && name != FX_BSTRC("DeviceGray") && 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("ColorSpace"));
513 if (pCSObj != NULL) {
514 int bpc = m_pLastCloneImageDict->GetInteger(FX_BSTRC("BitsPerComponent"));
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 }
EndInlineImage()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_ImageSrcBuf.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("ColorSpace")), 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)
EndKeyword()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
CPDF_ContentParser()585 CPDF_ContentParser::CPDF_ContentParser()
586 {
587 m_pParser = NULL;
588 m_Status = Ready;
589 m_pStreamFilter = NULL;
590 m_pType3Char = NULL;
591 }
~CPDF_ContentParser()592 CPDF_ContentParser::~CPDF_ContentParser()
593 {
594 Clear();
595 }
Clear()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 }
Start(CPDF_Page * pPage,CPDF_ParseOptions * pOptions)607 void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions)
608 {
609 if (m_Status != Ready || pPage == NULL || pPage->m_pDocument == NULL || pPage->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("Contents"));
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, NULL, 0);
638 m_pParser->m_pCurStates->m_ColorState.GetModify()->Default();
639 }
Start(CPDF_Form * pForm,CPDF_AllStates * pGraphicStates,CFX_AffineMatrix * pParentMatrix,CPDF_Type3Char * pType3Char,CPDF_ParseOptions * pOptions,int level)640 void CPDF_ContentParser::Start(CPDF_Form* pForm, CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pParentMatrix,
641 CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, 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("Matrix"));
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, form_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("Resources"));
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, level);
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.GetModify();
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 }
Continue(IFX_Pause * pPause)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_Type3Data[0] * 1000);
695 m_pType3Char->m_BBox.left = FXSYS_round(m_pParser->m_Type3Data[2] * 1000);
696 m_pType3Char->m_BBox.bottom = FXSYS_round(m_pParser->m_Type3Data[3] * 1000);
697 m_pType3Char->m_BBox.right = FXSYS_round(m_pParser->m_Type3Data[4] * 1000);
698 m_pType3Char->m_BBox.top = FXSYS_round(m_pParser->m_Type3Data[5] * 1000);
699 m_pType3Char->m_bPageRequired = m_pParser->m_bResourceMissing;
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, STREAM_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_ObjectList.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_Right, 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_ObjectList.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 }
EstimateProgress()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_CurrentOffset +
791 m_pStreamFilter->GetSrcPos();
792 return 90 * parsed_raw_size / total_raw_size;
793 }
CPDF_InlineImages()794 CPDF_InlineImages::CPDF_InlineImages()
795 {
796 m_Type = PDFPAGE_INLINES;
797 m_pStream = NULL;
798 m_pBitmap = NULL;
799 }
~CPDF_InlineImages()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 }
AddMatrix(CFX_AffineMatrix & matrix)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
823