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, CFX_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_WordSize)); 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("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 } 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) 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 || 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 } 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 } 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 } 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 } 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 823