| 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 |