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 "core/src/fpdfapi/fpdf_page/pageint.h" 8 9 #include "core/include/fpdfapi/fpdf_module.h" 10 #include "core/include/fpdfapi/fpdf_page.h" 11 #include "core/include/fpdfapi/fpdf_serial.h" 12 13 namespace { 14 15 struct _FX_BSTR { 16 const FX_CHAR* m_Ptr; 17 int m_Size; 18 }; 19 #define _FX_BSTRC(str) \ 20 { str, sizeof(str) - 1 } 21 22 struct PDF_AbbrPairs { 23 _FX_BSTR full_name; 24 _FX_BSTR abbr; 25 }; 26 27 const PDF_AbbrPairs PDF_InlineKeyAbbr[] = { 28 {_FX_BSTRC("BitsPerComponent"), _FX_BSTRC("BPC")}, 29 {_FX_BSTRC("ColorSpace"), _FX_BSTRC("CS")}, 30 {_FX_BSTRC("Decode"), _FX_BSTRC("D")}, 31 {_FX_BSTRC("DecodeParms"), _FX_BSTRC("DP")}, 32 {_FX_BSTRC("Filter"), _FX_BSTRC("F")}, 33 {_FX_BSTRC("Height"), _FX_BSTRC("H")}, 34 {_FX_BSTRC("ImageMask"), _FX_BSTRC("IM")}, 35 {_FX_BSTRC("Interpolate"), _FX_BSTRC("I")}, 36 {_FX_BSTRC("Width"), _FX_BSTRC("W")}, 37 }; 38 39 const PDF_AbbrPairs PDF_InlineValueAbbr[] = { 40 {_FX_BSTRC("DeviceGray"), _FX_BSTRC("G")}, 41 {_FX_BSTRC("DeviceRGB"), _FX_BSTRC("RGB")}, 42 {_FX_BSTRC("DeviceCMYK"), _FX_BSTRC("CMYK")}, 43 {_FX_BSTRC("Indexed"), _FX_BSTRC("I")}, 44 {_FX_BSTRC("ASCIIHexDecode"), _FX_BSTRC("AHx")}, 45 {_FX_BSTRC("ASCII85Decode"), _FX_BSTRC("A85")}, 46 {_FX_BSTRC("LZWDecode"), _FX_BSTRC("LZW")}, 47 {_FX_BSTRC("FlateDecode"), _FX_BSTRC("Fl")}, 48 {_FX_BSTRC("RunLengthDecode"), _FX_BSTRC("RL")}, 49 {_FX_BSTRC("CCITTFaxDecode"), _FX_BSTRC("CCF")}, 50 {_FX_BSTRC("DCTDecode"), _FX_BSTRC("DCT")}, 51 }; 52 53 struct AbbrReplacementOp { 54 bool is_replace_key; 55 CFX_ByteString key; 56 CFX_ByteStringC replacement; 57 }; 58 59 CFX_ByteStringC PDF_FindFullName(const PDF_AbbrPairs* table, 60 size_t count, 61 const CFX_ByteStringC& abbr) { 62 for (size_t i = 0; i < count; ++i) { 63 if (abbr.GetLength() != table[i].abbr.m_Size) 64 continue; 65 if (memcmp(abbr.GetPtr(), table[i].abbr.m_Ptr, abbr.GetLength())) 66 continue; 67 return CFX_ByteStringC(table[i].full_name.m_Ptr, table[i].full_name.m_Size); 68 } 69 return CFX_ByteStringC(); 70 } 71 72 } // namespace 73 74 CPDF_StreamContentParser::CPDF_StreamContentParser( 75 CPDF_Document* pDocument, 76 CPDF_Dictionary* pPageResources, 77 CPDF_Dictionary* pParentResources, 78 CFX_Matrix* pmtContentToUser, 79 CPDF_PageObjects* pObjList, 80 CPDF_Dictionary* pResources, 81 CPDF_Rect* pBBox, 82 CPDF_ParseOptions* pOptions, 83 CPDF_AllStates* pStates, 84 int level) 85 : m_pDocument(pDocument), 86 m_pPageResources(pPageResources), 87 m_pParentResources(pParentResources), 88 m_pResources(pResources), 89 m_pObjectList(pObjList), 90 m_Level(level), 91 m_ParamStartPos(0), 92 m_ParamCount(0), 93 m_pCurStates(new CPDF_AllStates), 94 m_pLastTextObject(nullptr), 95 m_DefFontSize(0), 96 m_pPathPoints(nullptr), 97 m_PathPointCount(0), 98 m_PathAllocSize(0), 99 m_PathCurrentX(0.0f), 100 m_PathCurrentY(0.0f), 101 m_PathClipType(0), 102 m_pLastImage(nullptr), 103 m_pLastImageDict(nullptr), 104 m_pLastCloneImageDict(nullptr), 105 m_bReleaseLastDict(TRUE), 106 m_bColored(FALSE), 107 m_bResourceMissing(FALSE) { 108 if (pmtContentToUser) { 109 m_mtContentToUser = *pmtContentToUser; 110 } 111 if (pOptions) { 112 m_Options = *pOptions; 113 } 114 if (!m_pResources) { 115 m_pResources = m_pParentResources; 116 } 117 if (!m_pResources) { 118 m_pResources = m_pPageResources; 119 } 120 if (pBBox) { 121 m_BBox = *pBBox; 122 } 123 if (pStates) { 124 m_pCurStates->Copy(*pStates); 125 } else { 126 m_pCurStates->m_GeneralState.New(); 127 m_pCurStates->m_GraphState.New(); 128 m_pCurStates->m_TextState.New(); 129 m_pCurStates->m_ColorState.New(); 130 } 131 for (size_t i = 0; i < FX_ArraySize(m_Type3Data); ++i) { 132 m_Type3Data[i] = 0.0; 133 } 134 } 135 136 CPDF_StreamContentParser::~CPDF_StreamContentParser() { 137 ClearAllParams(); 138 FX_Free(m_pPathPoints); 139 if (m_pLastImageDict) { 140 m_pLastImageDict->Release(); 141 } 142 if (m_pLastCloneImageDict) { 143 m_pLastCloneImageDict->Release(); 144 } 145 } 146 int CPDF_StreamContentParser::GetNextParamPos() { 147 if (m_ParamCount == PARAM_BUF_SIZE) { 148 m_ParamStartPos++; 149 if (m_ParamStartPos == PARAM_BUF_SIZE) { 150 m_ParamStartPos = 0; 151 } 152 if (m_ParamBuf1[m_ParamStartPos].m_Type == 0) { 153 if (CPDF_Object* pObject = m_ParamBuf1[m_ParamStartPos].m_pObject) 154 pObject->Release(); 155 } 156 return m_ParamStartPos; 157 } 158 int index = m_ParamStartPos + m_ParamCount; 159 if (index >= PARAM_BUF_SIZE) { 160 index -= PARAM_BUF_SIZE; 161 } 162 m_ParamCount++; 163 return index; 164 } 165 void CPDF_StreamContentParser::AddNameParam(const FX_CHAR* name, int len) { 166 int index = GetNextParamPos(); 167 if (len > 32) { 168 m_ParamBuf1[index].m_Type = 0; 169 m_ParamBuf1[index].m_pObject = 170 new CPDF_Name(PDF_NameDecode(CFX_ByteStringC(name, len))); 171 } else { 172 m_ParamBuf1[index].m_Type = PDFOBJ_NAME; 173 if (!FXSYS_memchr(name, '#', len)) { 174 FXSYS_memcpy(m_ParamBuf1[index].m_Name.m_Buffer, name, len); 175 m_ParamBuf1[index].m_Name.m_Len = len; 176 } else { 177 CFX_ByteString str = PDF_NameDecode(CFX_ByteStringC(name, len)); 178 FXSYS_memcpy(m_ParamBuf1[index].m_Name.m_Buffer, str.c_str(), 179 str.GetLength()); 180 m_ParamBuf1[index].m_Name.m_Len = str.GetLength(); 181 } 182 } 183 } 184 void CPDF_StreamContentParser::AddNumberParam(const FX_CHAR* str, int len) { 185 int index = GetNextParamPos(); 186 m_ParamBuf1[index].m_Type = PDFOBJ_NUMBER; 187 FX_atonum(CFX_ByteStringC(str, len), m_ParamBuf1[index].m_Number.m_bInteger, 188 &m_ParamBuf1[index].m_Number.m_Integer); 189 } 190 void CPDF_StreamContentParser::AddObjectParam(CPDF_Object* pObj) { 191 int index = GetNextParamPos(); 192 m_ParamBuf1[index].m_Type = 0; 193 m_ParamBuf1[index].m_pObject = pObj; 194 } 195 void CPDF_StreamContentParser::ClearAllParams() { 196 FX_DWORD index = m_ParamStartPos; 197 for (FX_DWORD i = 0; i < m_ParamCount; i++) { 198 if (m_ParamBuf1[index].m_Type == 0) { 199 if (CPDF_Object* pObject = m_ParamBuf1[index].m_pObject) 200 pObject->Release(); 201 } 202 index++; 203 if (index == PARAM_BUF_SIZE) { 204 index = 0; 205 } 206 } 207 m_ParamStartPos = 0; 208 m_ParamCount = 0; 209 } 210 CPDF_Object* CPDF_StreamContentParser::GetObject(FX_DWORD index) { 211 if (index >= m_ParamCount) { 212 return NULL; 213 } 214 int real_index = m_ParamStartPos + m_ParamCount - index - 1; 215 if (real_index >= PARAM_BUF_SIZE) { 216 real_index -= PARAM_BUF_SIZE; 217 } 218 ContentParam& param = m_ParamBuf1[real_index]; 219 if (param.m_Type == PDFOBJ_NUMBER) { 220 CPDF_Number* pNumber = param.m_Number.m_bInteger 221 ? new CPDF_Number(param.m_Number.m_Integer) 222 : new CPDF_Number(param.m_Number.m_Float); 223 224 param.m_Type = 0; 225 param.m_pObject = pNumber; 226 return pNumber; 227 } 228 if (param.m_Type == PDFOBJ_NAME) { 229 CPDF_Name* pName = new CPDF_Name( 230 CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len)); 231 param.m_Type = 0; 232 param.m_pObject = pName; 233 return pName; 234 } 235 if (param.m_Type == 0) { 236 return param.m_pObject; 237 } 238 ASSERT(FALSE); 239 return NULL; 240 } 241 CFX_ByteString CPDF_StreamContentParser::GetString(FX_DWORD index) { 242 if (index >= m_ParamCount) { 243 return CFX_ByteString(); 244 } 245 int real_index = m_ParamStartPos + m_ParamCount - index - 1; 246 if (real_index >= PARAM_BUF_SIZE) { 247 real_index -= PARAM_BUF_SIZE; 248 } 249 ContentParam& param = m_ParamBuf1[real_index]; 250 if (param.m_Type == PDFOBJ_NAME) { 251 return CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len); 252 } 253 if (param.m_Type == 0 && param.m_pObject) { 254 return param.m_pObject->GetString(); 255 } 256 return CFX_ByteString(); 257 } 258 FX_FLOAT CPDF_StreamContentParser::GetNumber(FX_DWORD index) { 259 if (index >= m_ParamCount) { 260 return 0; 261 } 262 int real_index = m_ParamStartPos + m_ParamCount - index - 1; 263 if (real_index >= PARAM_BUF_SIZE) { 264 real_index -= PARAM_BUF_SIZE; 265 } 266 ContentParam& param = m_ParamBuf1[real_index]; 267 if (param.m_Type == PDFOBJ_NUMBER) { 268 return param.m_Number.m_bInteger ? (FX_FLOAT)param.m_Number.m_Integer 269 : param.m_Number.m_Float; 270 } 271 if (param.m_Type == 0 && param.m_pObject) { 272 return param.m_pObject->GetNumber(); 273 } 274 return 0; 275 } 276 FX_FLOAT CPDF_StreamContentParser::GetNumber16(FX_DWORD index) { 277 return GetNumber(index); 278 } 279 void CPDF_StreamContentParser::SetGraphicStates(CPDF_PageObject* pObj, 280 FX_BOOL bColor, 281 FX_BOOL bText, 282 FX_BOOL bGraph) { 283 pObj->m_GeneralState = m_pCurStates->m_GeneralState; 284 pObj->m_ClipPath = m_pCurStates->m_ClipPath; 285 pObj->m_ContentMark = m_CurContentMark; 286 if (bColor) { 287 pObj->m_ColorState = m_pCurStates->m_ColorState; 288 } 289 if (bGraph) { 290 pObj->m_GraphState = m_pCurStates->m_GraphState; 291 } 292 if (bText) { 293 pObj->m_TextState = m_pCurStates->m_TextState; 294 } 295 } 296 297 const CPDF_StreamContentParser::OpCode CPDF_StreamContentParser::g_OpCodes[] = { 298 {FXBSTR_ID('"', 0, 0, 0), 299 &CPDF_StreamContentParser::Handle_NextLineShowText_Space}, 300 {FXBSTR_ID('\'', 0, 0, 0), 301 &CPDF_StreamContentParser::Handle_NextLineShowText}, 302 {FXBSTR_ID('B', 0, 0, 0), &CPDF_StreamContentParser::Handle_FillStrokePath}, 303 {FXBSTR_ID('B', '*', 0, 0), 304 &CPDF_StreamContentParser::Handle_EOFillStrokePath}, 305 {FXBSTR_ID('B', 'D', 'C', 0), 306 &CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary}, 307 {FXBSTR_ID('B', 'I', 0, 0), &CPDF_StreamContentParser::Handle_BeginImage}, 308 {FXBSTR_ID('B', 'M', 'C', 0), 309 &CPDF_StreamContentParser::Handle_BeginMarkedContent}, 310 {FXBSTR_ID('B', 'T', 0, 0), &CPDF_StreamContentParser::Handle_BeginText}, 311 {FXBSTR_ID('B', 'X', 0, 0), 312 &CPDF_StreamContentParser::Handle_BeginSectionUndefined}, 313 {FXBSTR_ID('C', 'S', 0, 0), 314 &CPDF_StreamContentParser::Handle_SetColorSpace_Stroke}, 315 {FXBSTR_ID('D', 'P', 0, 0), 316 &CPDF_StreamContentParser::Handle_MarkPlace_Dictionary}, 317 {FXBSTR_ID('D', 'o', 0, 0), 318 &CPDF_StreamContentParser::Handle_ExecuteXObject}, 319 {FXBSTR_ID('E', 'I', 0, 0), &CPDF_StreamContentParser::Handle_EndImage}, 320 {FXBSTR_ID('E', 'M', 'C', 0), 321 &CPDF_StreamContentParser::Handle_EndMarkedContent}, 322 {FXBSTR_ID('E', 'T', 0, 0), &CPDF_StreamContentParser::Handle_EndText}, 323 {FXBSTR_ID('E', 'X', 0, 0), 324 &CPDF_StreamContentParser::Handle_EndSectionUndefined}, 325 {FXBSTR_ID('F', 0, 0, 0), &CPDF_StreamContentParser::Handle_FillPathOld}, 326 {FXBSTR_ID('G', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetGray_Stroke}, 327 {FXBSTR_ID('I', 'D', 0, 0), 328 &CPDF_StreamContentParser::Handle_BeginImageData}, 329 {FXBSTR_ID('J', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetLineCap}, 330 {FXBSTR_ID('K', 0, 0, 0), 331 &CPDF_StreamContentParser::Handle_SetCMYKColor_Stroke}, 332 {FXBSTR_ID('M', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetMiterLimit}, 333 {FXBSTR_ID('M', 'P', 0, 0), &CPDF_StreamContentParser::Handle_MarkPlace}, 334 {FXBSTR_ID('Q', 0, 0, 0), 335 &CPDF_StreamContentParser::Handle_RestoreGraphState}, 336 {FXBSTR_ID('R', 'G', 0, 0), 337 &CPDF_StreamContentParser::Handle_SetRGBColor_Stroke}, 338 {FXBSTR_ID('S', 0, 0, 0), &CPDF_StreamContentParser::Handle_StrokePath}, 339 {FXBSTR_ID('S', 'C', 0, 0), 340 &CPDF_StreamContentParser::Handle_SetColor_Stroke}, 341 {FXBSTR_ID('S', 'C', 'N', 0), 342 &CPDF_StreamContentParser::Handle_SetColorPS_Stroke}, 343 {FXBSTR_ID('T', '*', 0, 0), 344 &CPDF_StreamContentParser::Handle_MoveToNextLine}, 345 {FXBSTR_ID('T', 'D', 0, 0), 346 &CPDF_StreamContentParser::Handle_MoveTextPoint_SetLeading}, 347 {FXBSTR_ID('T', 'J', 0, 0), 348 &CPDF_StreamContentParser::Handle_ShowText_Positioning}, 349 {FXBSTR_ID('T', 'L', 0, 0), 350 &CPDF_StreamContentParser::Handle_SetTextLeading}, 351 {FXBSTR_ID('T', 'c', 0, 0), &CPDF_StreamContentParser::Handle_SetCharSpace}, 352 {FXBSTR_ID('T', 'd', 0, 0), 353 &CPDF_StreamContentParser::Handle_MoveTextPoint}, 354 {FXBSTR_ID('T', 'f', 0, 0), &CPDF_StreamContentParser::Handle_SetFont}, 355 {FXBSTR_ID('T', 'j', 0, 0), &CPDF_StreamContentParser::Handle_ShowText}, 356 {FXBSTR_ID('T', 'm', 0, 0), 357 &CPDF_StreamContentParser::Handle_SetTextMatrix}, 358 {FXBSTR_ID('T', 'r', 0, 0), 359 &CPDF_StreamContentParser::Handle_SetTextRenderMode}, 360 {FXBSTR_ID('T', 's', 0, 0), &CPDF_StreamContentParser::Handle_SetTextRise}, 361 {FXBSTR_ID('T', 'w', 0, 0), &CPDF_StreamContentParser::Handle_SetWordSpace}, 362 {FXBSTR_ID('T', 'z', 0, 0), &CPDF_StreamContentParser::Handle_SetHorzScale}, 363 {FXBSTR_ID('W', 0, 0, 0), &CPDF_StreamContentParser::Handle_Clip}, 364 {FXBSTR_ID('W', '*', 0, 0), &CPDF_StreamContentParser::Handle_EOClip}, 365 {FXBSTR_ID('b', 0, 0, 0), 366 &CPDF_StreamContentParser::Handle_CloseFillStrokePath}, 367 {FXBSTR_ID('b', '*', 0, 0), 368 &CPDF_StreamContentParser::Handle_CloseEOFillStrokePath}, 369 {FXBSTR_ID('c', 0, 0, 0), &CPDF_StreamContentParser::Handle_CurveTo_123}, 370 {FXBSTR_ID('c', 'm', 0, 0), &CPDF_StreamContentParser::Handle_ConcatMatrix}, 371 {FXBSTR_ID('c', 's', 0, 0), 372 &CPDF_StreamContentParser::Handle_SetColorSpace_Fill}, 373 {FXBSTR_ID('d', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetDash}, 374 {FXBSTR_ID('d', '0', 0, 0), &CPDF_StreamContentParser::Handle_SetCharWidth}, 375 {FXBSTR_ID('d', '1', 0, 0), 376 &CPDF_StreamContentParser::Handle_SetCachedDevice}, 377 {FXBSTR_ID('f', 0, 0, 0), &CPDF_StreamContentParser::Handle_FillPath}, 378 {FXBSTR_ID('f', '*', 0, 0), &CPDF_StreamContentParser::Handle_EOFillPath}, 379 {FXBSTR_ID('g', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetGray_Fill}, 380 {FXBSTR_ID('g', 's', 0, 0), 381 &CPDF_StreamContentParser::Handle_SetExtendGraphState}, 382 {FXBSTR_ID('h', 0, 0, 0), &CPDF_StreamContentParser::Handle_ClosePath}, 383 {FXBSTR_ID('i', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetFlat}, 384 {FXBSTR_ID('j', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetLineJoin}, 385 {FXBSTR_ID('k', 0, 0, 0), 386 &CPDF_StreamContentParser::Handle_SetCMYKColor_Fill}, 387 {FXBSTR_ID('l', 0, 0, 0), &CPDF_StreamContentParser::Handle_LineTo}, 388 {FXBSTR_ID('m', 0, 0, 0), &CPDF_StreamContentParser::Handle_MoveTo}, 389 {FXBSTR_ID('n', 0, 0, 0), &CPDF_StreamContentParser::Handle_EndPath}, 390 {FXBSTR_ID('q', 0, 0, 0), &CPDF_StreamContentParser::Handle_SaveGraphState}, 391 {FXBSTR_ID('r', 'e', 0, 0), &CPDF_StreamContentParser::Handle_Rectangle}, 392 {FXBSTR_ID('r', 'g', 0, 0), 393 &CPDF_StreamContentParser::Handle_SetRGBColor_Fill}, 394 {FXBSTR_ID('r', 'i', 0, 0), 395 &CPDF_StreamContentParser::Handle_SetRenderIntent}, 396 {FXBSTR_ID('s', 0, 0, 0), 397 &CPDF_StreamContentParser::Handle_CloseStrokePath}, 398 {FXBSTR_ID('s', 'c', 0, 0), 399 &CPDF_StreamContentParser::Handle_SetColor_Fill}, 400 {FXBSTR_ID('s', 'c', 'n', 0), 401 &CPDF_StreamContentParser::Handle_SetColorPS_Fill}, 402 {FXBSTR_ID('s', 'h', 0, 0), &CPDF_StreamContentParser::Handle_ShadeFill}, 403 {FXBSTR_ID('v', 0, 0, 0), &CPDF_StreamContentParser::Handle_CurveTo_23}, 404 {FXBSTR_ID('w', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetLineWidth}, 405 {FXBSTR_ID('y', 0, 0, 0), &CPDF_StreamContentParser::Handle_CurveTo_13}, 406 }; 407 FX_BOOL CPDF_StreamContentParser::OnOperator(const FX_CHAR* op) { 408 int i = 0; 409 FX_DWORD opid = 0; 410 while (i < 4 && op[i]) { 411 opid = (opid << 8) + op[i]; 412 i++; 413 } 414 while (i < 4) { 415 opid <<= 8; 416 i++; 417 } 418 int low = 0, high = sizeof g_OpCodes / sizeof(OpCode) - 1; 419 while (low <= high) { 420 int middle = (low + high) / 2; 421 int compare = opid - g_OpCodes[middle].m_OpId; 422 if (compare == 0) { 423 (this->*g_OpCodes[middle].m_OpHandler)(); 424 return TRUE; 425 } 426 if (compare < 0) { 427 high = middle - 1; 428 } else { 429 low = middle + 1; 430 } 431 } 432 return m_CompatCount != 0; 433 } 434 void CPDF_StreamContentParser::Handle_CloseFillStrokePath() { 435 if (m_Options.m_bTextOnly) { 436 return; 437 } 438 Handle_ClosePath(); 439 AddPathObject(FXFILL_WINDING, TRUE); 440 } 441 void CPDF_StreamContentParser::Handle_FillStrokePath() { 442 if (m_Options.m_bTextOnly) { 443 return; 444 } 445 AddPathObject(FXFILL_WINDING, TRUE); 446 } 447 void CPDF_StreamContentParser::Handle_CloseEOFillStrokePath() { 448 if (m_Options.m_bTextOnly) { 449 return; 450 } 451 AddPathPoint(m_PathStartX, m_PathStartY, FXPT_LINETO | FXPT_CLOSEFIGURE); 452 AddPathObject(FXFILL_ALTERNATE, TRUE); 453 } 454 void CPDF_StreamContentParser::Handle_EOFillStrokePath() { 455 if (m_Options.m_bTextOnly) { 456 return; 457 } 458 AddPathObject(FXFILL_ALTERNATE, TRUE); 459 } 460 void CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary() { 461 if (!m_Options.m_bMarkedContent) { 462 return; 463 } 464 CFX_ByteString tag = GetString(1); 465 CPDF_Object* pProperty = GetObject(0); 466 if (!pProperty) { 467 return; 468 } 469 FX_BOOL bDirect = TRUE; 470 if (pProperty->IsName()) { 471 pProperty = FindResourceObj("Properties", pProperty->GetString()); 472 if (!pProperty) 473 return; 474 bDirect = FALSE; 475 } 476 if (CPDF_Dictionary* pDict = pProperty->AsDictionary()) { 477 m_CurContentMark.GetModify()->AddMark(tag, pDict, bDirect); 478 } 479 } 480 void CPDF_StreamContentParser::Handle_BeginMarkedContent() { 481 if (!m_Options.m_bMarkedContent) { 482 return; 483 } 484 CFX_ByteString tag = GetString(0); 485 m_CurContentMark.GetModify()->AddMark(tag, NULL, FALSE); 486 } 487 488 void PDF_ReplaceAbbr(CPDF_Object* pObj) { 489 switch (pObj->GetType()) { 490 case PDFOBJ_DICTIONARY: { 491 CPDF_Dictionary* pDict = pObj->AsDictionary(); 492 std::vector<AbbrReplacementOp> replacements; 493 for (const auto& it : *pDict) { 494 CFX_ByteString key = it.first; 495 CPDF_Object* value = it.second; 496 CFX_ByteStringC fullname = PDF_FindFullName( 497 PDF_InlineKeyAbbr, FX_ArraySize(PDF_InlineKeyAbbr), key); 498 if (!fullname.IsEmpty()) { 499 AbbrReplacementOp op; 500 op.is_replace_key = true; 501 op.key = key; 502 op.replacement = fullname; 503 replacements.push_back(op); 504 key = fullname; 505 } 506 507 if (value->IsName()) { 508 CFX_ByteString name = value->GetString(); 509 fullname = PDF_FindFullName(PDF_InlineValueAbbr, 510 FX_ArraySize(PDF_InlineValueAbbr), name); 511 if (!fullname.IsEmpty()) { 512 AbbrReplacementOp op; 513 op.is_replace_key = false; 514 op.key = key; 515 op.replacement = fullname; 516 replacements.push_back(op); 517 } 518 } else { 519 PDF_ReplaceAbbr(value); 520 } 521 } 522 for (const auto& op : replacements) { 523 if (op.is_replace_key) 524 pDict->ReplaceKey(op.key, op.replacement); 525 else 526 pDict->SetAtName(op.key, op.replacement); 527 } 528 break; 529 } 530 case PDFOBJ_ARRAY: { 531 CPDF_Array* pArray = pObj->AsArray(); 532 for (FX_DWORD i = 0; i < pArray->GetCount(); i++) { 533 CPDF_Object* pElement = pArray->GetElement(i); 534 if (pElement->IsName()) { 535 CFX_ByteString name = pElement->GetString(); 536 CFX_ByteStringC fullname = PDF_FindFullName( 537 PDF_InlineValueAbbr, FX_ArraySize(PDF_InlineValueAbbr), name); 538 if (!fullname.IsEmpty()) { 539 pArray->SetAt(i, new CPDF_Name(fullname)); 540 } 541 } else { 542 PDF_ReplaceAbbr(pElement); 543 } 544 } 545 break; 546 } 547 } 548 } 549 550 void CPDF_StreamContentParser::Handle_BeginText() { 551 m_pCurStates->m_TextMatrix.Set(1.0f, 0, 0, 1.0f, 0, 0); 552 OnChangeTextMatrix(); 553 m_pCurStates->m_TextX = 0; 554 m_pCurStates->m_TextY = 0; 555 m_pCurStates->m_TextLineX = 0; 556 m_pCurStates->m_TextLineY = 0; 557 } 558 void CPDF_StreamContentParser::Handle_BeginSectionUndefined() { 559 m_CompatCount++; 560 } 561 void CPDF_StreamContentParser::Handle_CurveTo_123() { 562 if (m_Options.m_bTextOnly) { 563 return; 564 } 565 AddPathPoint(GetNumber(5), GetNumber(4), FXPT_BEZIERTO); 566 AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO); 567 AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO); 568 } 569 void CPDF_StreamContentParser::Handle_ConcatMatrix() { 570 FX_FLOAT a2 = GetNumber16(5), b2 = GetNumber16(4), c2 = GetNumber16(3), 571 d2 = GetNumber16(2); 572 FX_FLOAT e2 = GetNumber(1), f2 = GetNumber(0); 573 CFX_Matrix new_matrix(a2, b2, c2, d2, e2, f2); 574 new_matrix.Concat(m_pCurStates->m_CTM); 575 m_pCurStates->m_CTM = new_matrix; 576 OnChangeTextMatrix(); 577 } 578 void CPDF_StreamContentParser::Handle_SetColorSpace_Fill() { 579 if (m_Options.m_bTextOnly) { 580 return; 581 } 582 CFX_ByteString csname = GetString(0); 583 CPDF_ColorSpace* pCS = FindColorSpace(csname); 584 if (!pCS) { 585 return; 586 } 587 m_pCurStates->m_ColorState.GetModify()->m_FillColor.SetColorSpace(pCS); 588 } 589 void CPDF_StreamContentParser::Handle_SetColorSpace_Stroke() { 590 if (m_Options.m_bTextOnly) { 591 return; 592 } 593 CFX_ByteString csname = GetString(0); 594 CPDF_ColorSpace* pCS = FindColorSpace(csname); 595 if (!pCS) { 596 return; 597 } 598 m_pCurStates->m_ColorState.GetModify()->m_StrokeColor.SetColorSpace(pCS); 599 } 600 void CPDF_StreamContentParser::Handle_SetDash() { 601 if (m_Options.m_bTextOnly) { 602 return; 603 } 604 CPDF_Array* pArray = GetObject(1) ? GetObject(1)->GetArray() : NULL; 605 if (!pArray) { 606 return; 607 } 608 m_pCurStates->SetLineDash(pArray, GetNumber(0), 1.0f); 609 } 610 void CPDF_StreamContentParser::Handle_SetCharWidth() { 611 m_Type3Data[0] = GetNumber(1); 612 m_Type3Data[1] = GetNumber(0); 613 m_bColored = TRUE; 614 } 615 void CPDF_StreamContentParser::Handle_SetCachedDevice() { 616 for (int i = 0; i < 6; i++) { 617 m_Type3Data[i] = GetNumber(5 - i); 618 } 619 m_bColored = FALSE; 620 } 621 void CPDF_StreamContentParser::Handle_ExecuteXObject() { 622 CFX_ByteString name = GetString(0); 623 if (name == m_LastImageName && m_pLastImage && m_pLastImage->GetStream() && 624 m_pLastImage->GetStream()->GetObjNum()) { 625 AddImage(nullptr, m_pLastImage, FALSE); 626 return; 627 } 628 629 if (m_Options.m_bTextOnly) { 630 if (!m_pResources) 631 return; 632 633 CPDF_Dictionary* pList = m_pResources->GetDict("XObject"); 634 if (!pList && m_pPageResources && m_pResources != m_pPageResources) 635 pList = m_pPageResources->GetDict("XObject"); 636 if (!pList) 637 return; 638 CPDF_Reference* pRes = ToReference(pList->GetElement(name)); 639 if (!pRes) 640 return; 641 642 FX_BOOL bForm; 643 if (m_pDocument->IsFormStream(pRes->GetRefObjNum(), bForm) && !bForm) 644 return; 645 } 646 647 CPDF_Stream* pXObject = ToStream(FindResourceObj("XObject", name)); 648 if (!pXObject) { 649 m_bResourceMissing = TRUE; 650 return; 651 } 652 653 CFX_ByteStringC type = pXObject->GetDict() 654 ? pXObject->GetDict()->GetConstString("Subtype") 655 : CFX_ByteStringC(); 656 if (type == "Image") { 657 if (m_Options.m_bTextOnly) { 658 return; 659 } 660 CPDF_ImageObject* pObj = AddImage(pXObject, NULL, FALSE); 661 m_LastImageName = name; 662 m_pLastImage = pObj->m_pImage; 663 if (!m_pObjectList->m_bHasImageMask) 664 m_pObjectList->m_bHasImageMask = m_pLastImage->IsMask(); 665 } else if (type == "Form") { 666 AddForm(pXObject); 667 } else { 668 return; 669 } 670 } 671 void CPDF_StreamContentParser::AddForm(CPDF_Stream* pStream) { 672 if (!m_Options.m_bSeparateForm) { 673 CPDF_Dictionary* pResources = pStream->GetDict()->GetDict("Resources"); 674 CFX_Matrix form_matrix = pStream->GetDict()->GetMatrix("Matrix"); 675 form_matrix.Concat(m_pCurStates->m_CTM); 676 CPDF_Array* pBBox = pStream->GetDict()->GetArray("BBox"); 677 CFX_FloatRect form_bbox; 678 CPDF_Path ClipPath; 679 if (pBBox) { 680 form_bbox = pStream->GetDict()->GetRect("BBox"); 681 ClipPath.New(); 682 ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, 683 form_bbox.top); 684 ClipPath.Transform(&form_matrix); 685 form_bbox.Transform(&form_matrix); 686 } 687 CPDF_StreamContentParser parser(m_pDocument, m_pPageResources, m_pResources, 688 &m_mtContentToUser, m_pObjectList, 689 pResources, &form_bbox, &m_Options, 690 m_pCurStates.get(), m_Level + 1); 691 parser.m_pCurStates->m_CTM = form_matrix; 692 if (ClipPath.NotNull()) { 693 parser.m_pCurStates->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, 694 TRUE); 695 } 696 CPDF_StreamAcc stream; 697 stream.LoadAllData(pStream, FALSE); 698 if (stream.GetSize() == 0) { 699 return; 700 } 701 parser.Parse(stream.GetData(), stream.GetSize(), 0); 702 return; 703 } 704 CPDF_FormObject* pFormObj = new CPDF_FormObject; 705 pFormObj->m_pForm = 706 new CPDF_Form(m_pDocument, m_pPageResources, pStream, m_pResources); 707 pFormObj->m_FormMatrix = m_pCurStates->m_CTM; 708 pFormObj->m_FormMatrix.Concat(m_mtContentToUser); 709 CPDF_AllStates status; 710 status.m_GeneralState = m_pCurStates->m_GeneralState; 711 status.m_GraphState = m_pCurStates->m_GraphState; 712 status.m_ColorState = m_pCurStates->m_ColorState; 713 status.m_TextState = m_pCurStates->m_TextState; 714 pFormObj->m_pForm->ParseContent(&status, NULL, NULL, &m_Options, m_Level + 1); 715 if (!m_pObjectList->m_bBackgroundAlphaNeeded && 716 pFormObj->m_pForm->m_bBackgroundAlphaNeeded) { 717 m_pObjectList->m_bBackgroundAlphaNeeded = TRUE; 718 } 719 pFormObj->CalcBoundingBox(); 720 SetGraphicStates(pFormObj, TRUE, TRUE, TRUE); 721 m_pObjectList->m_ObjectList.AddTail(pFormObj); 722 } 723 CPDF_ImageObject* CPDF_StreamContentParser::AddImage(CPDF_Stream* pStream, 724 CPDF_Image* pImage, 725 FX_BOOL bInline) { 726 if (!pStream && !pImage) { 727 return NULL; 728 } 729 CFX_Matrix ImageMatrix; 730 ImageMatrix.Copy(m_pCurStates->m_CTM); 731 ImageMatrix.Concat(m_mtContentToUser); 732 CPDF_ImageObject* pImageObj = new CPDF_ImageObject; 733 if (pImage) { 734 pImageObj->m_pImage = 735 m_pDocument->GetPageData()->GetImage(pImage->GetStream()); 736 } else if (pStream->GetObjNum()) { 737 pImageObj->m_pImage = m_pDocument->LoadImageF(pStream); 738 } else { 739 pImageObj->m_pImage = new CPDF_Image(m_pDocument); 740 pImageObj->m_pImage->LoadImageF(pStream, bInline); 741 } 742 SetGraphicStates(pImageObj, pImageObj->m_pImage->IsMask(), FALSE, FALSE); 743 pImageObj->m_Matrix = ImageMatrix; 744 pImageObj->CalcBoundingBox(); 745 m_pObjectList->m_ObjectList.AddTail(pImageObj); 746 return pImageObj; 747 } 748 void CPDF_StreamContentParser::Handle_MarkPlace_Dictionary() {} 749 void CPDF_StreamContentParser::Handle_EndImage() {} 750 void CPDF_StreamContentParser::Handle_EndMarkedContent() { 751 if (!m_Options.m_bMarkedContent) { 752 return; 753 } 754 if (m_CurContentMark.IsNull()) { 755 return; 756 } 757 int count = m_CurContentMark.GetObject()->CountItems(); 758 if (count == 1) { 759 m_CurContentMark.SetNull(); 760 return; 761 } 762 m_CurContentMark.GetModify()->DeleteLastMark(); 763 } 764 void CPDF_StreamContentParser::Handle_EndText() { 765 int count = m_ClipTextList.GetSize(); 766 if (count == 0) { 767 return; 768 } 769 if (m_pCurStates->m_TextState.GetObject()->m_TextMode < 4) { 770 for (int i = 0; i < count; i++) { 771 delete m_ClipTextList.GetAt(i); 772 } 773 } else { 774 m_pCurStates->m_ClipPath.AppendTexts(m_ClipTextList.GetData(), count); 775 } 776 m_ClipTextList.RemoveAll(); 777 } 778 void CPDF_StreamContentParser::Handle_EndSectionUndefined() { 779 if (m_CompatCount) { 780 m_CompatCount--; 781 } 782 } 783 void CPDF_StreamContentParser::Handle_FillPath() { 784 if (m_Options.m_bTextOnly) { 785 return; 786 } 787 AddPathObject(FXFILL_WINDING, FALSE); 788 } 789 void CPDF_StreamContentParser::Handle_FillPathOld() { 790 if (m_Options.m_bTextOnly) { 791 return; 792 } 793 AddPathObject(FXFILL_WINDING, FALSE); 794 } 795 void CPDF_StreamContentParser::Handle_EOFillPath() { 796 if (m_Options.m_bTextOnly) { 797 return; 798 } 799 AddPathObject(FXFILL_ALTERNATE, FALSE); 800 } 801 void CPDF_StreamContentParser::Handle_SetGray_Fill() { 802 FX_FLOAT value = GetNumber(0); 803 CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY); 804 m_pCurStates->m_ColorState.SetFillColor(pCS, &value, 1); 805 } 806 void CPDF_StreamContentParser::Handle_SetGray_Stroke() { 807 FX_FLOAT value = GetNumber(0); 808 CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY); 809 m_pCurStates->m_ColorState.SetStrokeColor(pCS, &value, 1); 810 } 811 void CPDF_StreamContentParser::Handle_SetExtendGraphState() { 812 CFX_ByteString name = GetString(0); 813 CPDF_Dictionary* pGS = ToDictionary(FindResourceObj("ExtGState", name)); 814 if (!pGS) { 815 m_bResourceMissing = TRUE; 816 return; 817 } 818 m_pCurStates->ProcessExtGS(pGS, this); 819 } 820 void CPDF_StreamContentParser::Handle_ClosePath() { 821 if (m_Options.m_bTextOnly) { 822 return; 823 } 824 if (m_PathPointCount == 0) { 825 return; 826 } 827 if (m_PathStartX != m_PathCurrentX || m_PathStartY != m_PathCurrentY) { 828 AddPathPoint(m_PathStartX, m_PathStartY, FXPT_LINETO | FXPT_CLOSEFIGURE); 829 } else if (m_pPathPoints[m_PathPointCount - 1].m_Flag != FXPT_MOVETO) { 830 m_pPathPoints[m_PathPointCount - 1].m_Flag |= FXPT_CLOSEFIGURE; 831 } 832 } 833 void CPDF_StreamContentParser::Handle_SetFlat() { 834 m_pCurStates->m_GeneralState.GetModify()->m_Flatness = GetNumber(0); 835 } 836 void CPDF_StreamContentParser::Handle_BeginImageData() {} 837 void CPDF_StreamContentParser::Handle_SetLineJoin() { 838 m_pCurStates->m_GraphState.GetModify()->m_LineJoin = 839 (CFX_GraphStateData::LineJoin)GetInteger(0); 840 } 841 void CPDF_StreamContentParser::Handle_SetLineCap() { 842 m_pCurStates->m_GraphState.GetModify()->m_LineCap = 843 (CFX_GraphStateData::LineCap)GetInteger(0); 844 } 845 void CPDF_StreamContentParser::Handle_SetCMYKColor_Fill() { 846 if (m_ParamCount != 4) 847 return; 848 849 FX_FLOAT values[4]; 850 for (int i = 0; i < 4; i++) { 851 values[i] = GetNumber(3 - i); 852 } 853 CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); 854 m_pCurStates->m_ColorState.SetFillColor(pCS, values, 4); 855 } 856 void CPDF_StreamContentParser::Handle_SetCMYKColor_Stroke() { 857 if (m_ParamCount != 4) 858 return; 859 860 FX_FLOAT values[4]; 861 for (int i = 0; i < 4; i++) { 862 values[i] = GetNumber(3 - i); 863 } 864 CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); 865 m_pCurStates->m_ColorState.SetStrokeColor(pCS, values, 4); 866 } 867 void CPDF_StreamContentParser::Handle_LineTo() { 868 if (m_ParamCount != 2) 869 return; 870 871 if (m_Options.m_bTextOnly) { 872 return; 873 } 874 AddPathPoint(GetNumber(1), GetNumber(0), FXPT_LINETO); 875 } 876 void CPDF_StreamContentParser::Handle_MoveTo() { 877 if (m_ParamCount != 2) 878 return; 879 880 if (m_Options.m_bTextOnly) { 881 m_pSyntax->SkipPathObject(); 882 return; 883 } 884 AddPathPoint(GetNumber(1), GetNumber(0), FXPT_MOVETO); 885 ParsePathObject(); 886 } 887 void CPDF_StreamContentParser::Handle_SetMiterLimit() { 888 m_pCurStates->m_GraphState.GetModify()->m_MiterLimit = GetNumber(0); 889 } 890 void CPDF_StreamContentParser::Handle_MarkPlace() {} 891 void CPDF_StreamContentParser::Handle_EndPath() { 892 if (m_Options.m_bTextOnly) { 893 return; 894 } 895 AddPathObject(0, FALSE); 896 } 897 void CPDF_StreamContentParser::Handle_SaveGraphState() { 898 std::unique_ptr<CPDF_AllStates> pStates(new CPDF_AllStates); 899 pStates->Copy(*m_pCurStates); 900 m_StateStack.push_back(std::move(pStates)); 901 } 902 void CPDF_StreamContentParser::Handle_RestoreGraphState() { 903 if (m_StateStack.empty()) 904 return; 905 std::unique_ptr<CPDF_AllStates> pStates = std::move(m_StateStack.back()); 906 m_StateStack.pop_back(); 907 m_pCurStates->Copy(*pStates); 908 } 909 void CPDF_StreamContentParser::Handle_Rectangle() { 910 if (m_Options.m_bTextOnly) { 911 return; 912 } 913 FX_FLOAT x = GetNumber(3), y = GetNumber(2); 914 FX_FLOAT w = GetNumber(1), h = GetNumber(0); 915 AddPathRect(x, y, w, h); 916 } 917 void CPDF_StreamContentParser::AddPathRect(FX_FLOAT x, 918 FX_FLOAT y, 919 FX_FLOAT w, 920 FX_FLOAT h) { 921 AddPathPoint(x, y, FXPT_MOVETO); 922 AddPathPoint(x + w, y, FXPT_LINETO); 923 AddPathPoint(x + w, y + h, FXPT_LINETO); 924 AddPathPoint(x, y + h, FXPT_LINETO); 925 AddPathPoint(x, y, FXPT_LINETO | FXPT_CLOSEFIGURE); 926 } 927 void CPDF_StreamContentParser::Handle_SetRGBColor_Fill() { 928 if (m_ParamCount != 3) 929 return; 930 931 FX_FLOAT values[3]; 932 for (int i = 0; i < 3; i++) { 933 values[i] = GetNumber(2 - i); 934 } 935 CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); 936 m_pCurStates->m_ColorState.SetFillColor(pCS, values, 3); 937 } 938 void CPDF_StreamContentParser::Handle_SetRGBColor_Stroke() { 939 if (m_ParamCount != 3) 940 return; 941 942 FX_FLOAT values[3]; 943 for (int i = 0; i < 3; i++) { 944 values[i] = GetNumber(2 - i); 945 } 946 CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); 947 m_pCurStates->m_ColorState.SetStrokeColor(pCS, values, 3); 948 } 949 void CPDF_StreamContentParser::Handle_SetRenderIntent() {} 950 void CPDF_StreamContentParser::Handle_CloseStrokePath() { 951 if (m_Options.m_bTextOnly) { 952 return; 953 } 954 Handle_ClosePath(); 955 AddPathObject(0, TRUE); 956 } 957 void CPDF_StreamContentParser::Handle_StrokePath() { 958 if (m_Options.m_bTextOnly) { 959 return; 960 } 961 AddPathObject(0, TRUE); 962 } 963 void CPDF_StreamContentParser::Handle_SetColor_Fill() { 964 if (m_Options.m_bTextOnly) { 965 return; 966 } 967 FX_FLOAT values[4]; 968 int nargs = m_ParamCount; 969 if (nargs > 4) { 970 nargs = 4; 971 } 972 for (int i = 0; i < nargs; i++) { 973 values[i] = GetNumber(nargs - i - 1); 974 } 975 m_pCurStates->m_ColorState.SetFillColor(NULL, values, nargs); 976 } 977 void CPDF_StreamContentParser::Handle_SetColor_Stroke() { 978 if (m_Options.m_bTextOnly) { 979 return; 980 } 981 FX_FLOAT values[4]; 982 int nargs = m_ParamCount; 983 if (nargs > 4) { 984 nargs = 4; 985 } 986 for (int i = 0; i < nargs; i++) { 987 values[i] = GetNumber(nargs - i - 1); 988 } 989 m_pCurStates->m_ColorState.SetStrokeColor(NULL, values, nargs); 990 } 991 void CPDF_StreamContentParser::Handle_SetColorPS_Fill() { 992 if (m_Options.m_bTextOnly) { 993 return; 994 } 995 CPDF_Object* pLastParam = GetObject(0); 996 if (!pLastParam) { 997 return; 998 } 999 int nargs = m_ParamCount; 1000 int nvalues = nargs; 1001 if (pLastParam->IsName()) { 1002 nvalues--; 1003 } 1004 FX_FLOAT* values = NULL; 1005 if (nvalues) { 1006 values = FX_Alloc(FX_FLOAT, nvalues); 1007 for (int i = 0; i < nvalues; i++) { 1008 values[i] = GetNumber(nargs - i - 1); 1009 } 1010 } 1011 if (nvalues != nargs) { 1012 CPDF_Pattern* pPattern = FindPattern(GetString(0), FALSE); 1013 if (pPattern) { 1014 m_pCurStates->m_ColorState.SetFillPattern(pPattern, values, nvalues); 1015 } 1016 } else { 1017 m_pCurStates->m_ColorState.SetFillColor(NULL, values, nvalues); 1018 } 1019 FX_Free(values); 1020 } 1021 void CPDF_StreamContentParser::Handle_SetColorPS_Stroke() { 1022 if (m_Options.m_bTextOnly) { 1023 return; 1024 } 1025 CPDF_Object* pLastParam = GetObject(0); 1026 if (!pLastParam) { 1027 return; 1028 } 1029 int nargs = m_ParamCount; 1030 int nvalues = nargs; 1031 if (pLastParam->IsName()) 1032 nvalues--; 1033 1034 FX_FLOAT* values = NULL; 1035 if (nvalues) { 1036 values = FX_Alloc(FX_FLOAT, nvalues); 1037 for (int i = 0; i < nvalues; i++) { 1038 values[i] = GetNumber(nargs - i - 1); 1039 } 1040 } 1041 if (nvalues != nargs) { 1042 CPDF_Pattern* pPattern = FindPattern(GetString(0), FALSE); 1043 if (pPattern) { 1044 m_pCurStates->m_ColorState.SetStrokePattern(pPattern, values, nvalues); 1045 } 1046 } else { 1047 m_pCurStates->m_ColorState.SetStrokeColor(NULL, values, nvalues); 1048 } 1049 FX_Free(values); 1050 } 1051 CFX_FloatRect GetShadingBBox(CPDF_Stream* pStream, 1052 ShadingType type, 1053 const CFX_Matrix* pMatrix, 1054 CPDF_Function** pFuncs, 1055 int nFuncs, 1056 CPDF_ColorSpace* pCS); 1057 1058 void CPDF_StreamContentParser::Handle_ShadeFill() { 1059 if (m_Options.m_bTextOnly) { 1060 return; 1061 } 1062 CPDF_Pattern* pPattern = FindPattern(GetString(0), TRUE); 1063 if (!pPattern) { 1064 return; 1065 } 1066 if (pPattern->m_PatternType != CPDF_Pattern::SHADING) { 1067 return; 1068 } 1069 CPDF_ShadingPattern* pShading = static_cast<CPDF_ShadingPattern*>(pPattern); 1070 if (!pShading->m_bShadingObj) { 1071 return; 1072 } 1073 if (!pShading->Load()) { 1074 return; 1075 } 1076 CPDF_ShadingObject* pObj = new CPDF_ShadingObject; 1077 pObj->m_pShading = pShading; 1078 SetGraphicStates(pObj, FALSE, FALSE, FALSE); 1079 pObj->m_Matrix = m_pCurStates->m_CTM; 1080 pObj->m_Matrix.Concat(m_mtContentToUser); 1081 CFX_FloatRect bbox; 1082 if (!pObj->m_ClipPath.IsNull()) { 1083 bbox = pObj->m_ClipPath.GetClipBox(); 1084 } else { 1085 bbox = m_BBox; 1086 } 1087 if (pShading->IsMeshShading()) { 1088 bbox.Intersect(GetShadingBBox(ToStream(pShading->m_pShadingObj), 1089 pShading->m_ShadingType, &pObj->m_Matrix, 1090 pShading->m_pFunctions, pShading->m_nFuncs, 1091 pShading->m_pCS)); 1092 } 1093 pObj->m_Left = bbox.left; 1094 pObj->m_Right = bbox.right; 1095 pObj->m_Top = bbox.top; 1096 pObj->m_Bottom = bbox.bottom; 1097 m_pObjectList->m_ObjectList.AddTail(pObj); 1098 } 1099 void CPDF_StreamContentParser::Handle_SetCharSpace() { 1100 m_pCurStates->m_TextState.GetModify()->m_CharSpace = GetNumber(0); 1101 } 1102 void CPDF_StreamContentParser::Handle_MoveTextPoint() { 1103 m_pCurStates->m_TextLineX += GetNumber(1); 1104 m_pCurStates->m_TextLineY += GetNumber(0); 1105 m_pCurStates->m_TextX = m_pCurStates->m_TextLineX; 1106 m_pCurStates->m_TextY = m_pCurStates->m_TextLineY; 1107 } 1108 void CPDF_StreamContentParser::Handle_MoveTextPoint_SetLeading() { 1109 Handle_MoveTextPoint(); 1110 m_pCurStates->m_TextLeading = -GetNumber(0); 1111 } 1112 void CPDF_StreamContentParser::Handle_SetFont() { 1113 FX_FLOAT fs = GetNumber(0); 1114 if (fs == 0) { 1115 fs = m_DefFontSize; 1116 } 1117 m_pCurStates->m_TextState.GetModify()->m_FontSize = fs; 1118 CPDF_Font* pFont = FindFont(GetString(1)); 1119 if (pFont) { 1120 m_pCurStates->m_TextState.SetFont(pFont); 1121 } 1122 } 1123 CPDF_Object* CPDF_StreamContentParser::FindResourceObj( 1124 const CFX_ByteStringC& type, 1125 const CFX_ByteString& name) { 1126 if (!m_pResources) { 1127 return NULL; 1128 } 1129 if (m_pResources == m_pPageResources) { 1130 CPDF_Dictionary* pList = m_pResources->GetDict(type); 1131 if (!pList) { 1132 return NULL; 1133 } 1134 CPDF_Object* pRes = pList->GetElementValue(name); 1135 return pRes; 1136 } 1137 CPDF_Dictionary* pList = m_pResources->GetDict(type); 1138 if (!pList) { 1139 if (!m_pPageResources) { 1140 return NULL; 1141 } 1142 CPDF_Dictionary* pList = m_pPageResources->GetDict(type); 1143 if (!pList) { 1144 return NULL; 1145 } 1146 CPDF_Object* pRes = pList->GetElementValue(name); 1147 return pRes; 1148 } 1149 CPDF_Object* pRes = pList->GetElementValue(name); 1150 return pRes; 1151 } 1152 CPDF_Font* CPDF_StreamContentParser::FindFont(const CFX_ByteString& name) { 1153 CPDF_Dictionary* pFontDict = ToDictionary(FindResourceObj("Font", name)); 1154 if (!pFontDict) { 1155 m_bResourceMissing = TRUE; 1156 return CPDF_Font::GetStockFont(m_pDocument, "Helvetica"); 1157 } 1158 1159 CPDF_Font* pFont = m_pDocument->LoadFont(pFontDict); 1160 if (pFont && pFont->GetType3Font()) { 1161 pFont->GetType3Font()->SetPageResources(m_pResources); 1162 pFont->GetType3Font()->CheckType3FontMetrics(); 1163 } 1164 return pFont; 1165 } 1166 CPDF_ColorSpace* CPDF_StreamContentParser::FindColorSpace( 1167 const CFX_ByteString& name) { 1168 if (name == "Pattern") { 1169 return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN); 1170 } 1171 if (name == "DeviceGray" || name == "DeviceCMYK" || name == "DeviceRGB") { 1172 CFX_ByteString defname = "Default"; 1173 defname += name.Mid(7); 1174 CPDF_Object* pDefObj = FindResourceObj("ColorSpace", defname); 1175 if (!pDefObj) { 1176 if (name == "DeviceGray") { 1177 return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY); 1178 } 1179 if (name == "DeviceRGB") { 1180 return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); 1181 } 1182 return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); 1183 } 1184 return m_pDocument->LoadColorSpace(pDefObj); 1185 } 1186 CPDF_Object* pCSObj = FindResourceObj("ColorSpace", name); 1187 if (!pCSObj) { 1188 m_bResourceMissing = TRUE; 1189 return NULL; 1190 } 1191 return m_pDocument->LoadColorSpace(pCSObj); 1192 } 1193 CPDF_Pattern* CPDF_StreamContentParser::FindPattern(const CFX_ByteString& name, 1194 FX_BOOL bShading) { 1195 CPDF_Object* pPattern = 1196 FindResourceObj(bShading ? "Shading" : "Pattern", name); 1197 if (!pPattern || (!pPattern->IsDictionary() && !pPattern->IsStream())) { 1198 m_bResourceMissing = TRUE; 1199 return NULL; 1200 } 1201 return m_pDocument->LoadPattern(pPattern, bShading, 1202 &m_pCurStates->m_ParentMatrix); 1203 } 1204 void CPDF_StreamContentParser::ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y) { 1205 m_pCurStates->m_TextMatrix.Transform(x, y, x, y); 1206 ConvertUserSpace(x, y); 1207 } 1208 void CPDF_StreamContentParser::ConvertUserSpace(FX_FLOAT& x, FX_FLOAT& y) { 1209 m_pCurStates->m_CTM.Transform(x, y, x, y); 1210 m_mtContentToUser.Transform(x, y, x, y); 1211 } 1212 void CPDF_StreamContentParser::AddTextObject(CFX_ByteString* pStrs, 1213 FX_FLOAT fInitKerning, 1214 FX_FLOAT* pKerning, 1215 int nsegs) { 1216 CPDF_Font* pFont = m_pCurStates->m_TextState.GetFont(); 1217 if (!pFont) { 1218 return; 1219 } 1220 if (fInitKerning != 0) { 1221 if (!pFont->IsVertWriting()) { 1222 m_pCurStates->m_TextX -= 1223 FXSYS_Mul(fInitKerning, m_pCurStates->m_TextState.GetFontSize()) / 1224 1000; 1225 } else { 1226 m_pCurStates->m_TextY -= 1227 FXSYS_Mul(fInitKerning, m_pCurStates->m_TextState.GetFontSize()) / 1228 1000; 1229 } 1230 } 1231 if (nsegs == 0) { 1232 return; 1233 } 1234 int textmode; 1235 if (pFont->GetFontType() == PDFFONT_TYPE3) { 1236 textmode = 0; 1237 } else { 1238 textmode = m_pCurStates->m_TextState.GetObject()->m_TextMode; 1239 } 1240 CPDF_TextObject* pText = new CPDF_TextObject; 1241 m_pLastTextObject = pText; 1242 SetGraphicStates(pText, TRUE, TRUE, TRUE); 1243 if (textmode && textmode != 3 && textmode != 4 && textmode != 7) { 1244 FX_FLOAT* pCTM = pText->m_TextState.GetModify()->m_CTM; 1245 pCTM[0] = m_pCurStates->m_CTM.a; 1246 pCTM[1] = m_pCurStates->m_CTM.c; 1247 pCTM[2] = m_pCurStates->m_CTM.b; 1248 pCTM[3] = m_pCurStates->m_CTM.d; 1249 } 1250 pText->SetSegments(pStrs, pKerning, nsegs); 1251 pText->m_PosX = m_pCurStates->m_TextX; 1252 pText->m_PosY = m_pCurStates->m_TextY + m_pCurStates->m_TextRise; 1253 ConvertTextSpace(pText->m_PosX, pText->m_PosY); 1254 FX_FLOAT x_advance, y_advance; 1255 pText->CalcPositionData(&x_advance, &y_advance, m_pCurStates->m_TextHorzScale, 1256 m_Level); 1257 m_pCurStates->m_TextX += x_advance; 1258 m_pCurStates->m_TextY += y_advance; 1259 if (textmode > 3) { 1260 CPDF_TextObject* pCopy = new CPDF_TextObject; 1261 pCopy->Copy(pText); 1262 m_ClipTextList.Add(pCopy); 1263 } 1264 m_pObjectList->m_ObjectList.AddTail(pText); 1265 if (pKerning && pKerning[nsegs - 1] != 0) { 1266 if (!pFont->IsVertWriting()) { 1267 m_pCurStates->m_TextX -= 1268 FXSYS_Mul(pKerning[nsegs - 1], 1269 m_pCurStates->m_TextState.GetFontSize()) / 1270 1000; 1271 } else { 1272 m_pCurStates->m_TextY -= 1273 FXSYS_Mul(pKerning[nsegs - 1], 1274 m_pCurStates->m_TextState.GetFontSize()) / 1275 1000; 1276 } 1277 } 1278 } 1279 void CPDF_StreamContentParser::Handle_ShowText() { 1280 CFX_ByteString str = GetString(0); 1281 if (str.IsEmpty()) { 1282 return; 1283 } 1284 AddTextObject(&str, 0, NULL, 1); 1285 } 1286 void CPDF_StreamContentParser::Handle_ShowText_Positioning() { 1287 CPDF_Array* pArray = GetObject(0) ? GetObject(0)->GetArray() : NULL; 1288 if (!pArray) { 1289 return; 1290 } 1291 int n = pArray->GetCount(); 1292 int nsegs = 0; 1293 for (int i = 0; i < n; i++) { 1294 if (pArray->GetElementValue(i)->IsString()) 1295 nsegs++; 1296 } 1297 if (nsegs == 0) { 1298 for (int i = 0; i < n; i++) { 1299 m_pCurStates->m_TextX -= 1300 FXSYS_Mul(pArray->GetNumber(i), 1301 m_pCurStates->m_TextState.GetFontSize()) / 1302 1000; 1303 } 1304 return; 1305 } 1306 CFX_ByteString* pStrs = new CFX_ByteString[nsegs]; 1307 FX_FLOAT* pKerning = FX_Alloc(FX_FLOAT, nsegs); 1308 int iSegment = 0; 1309 FX_FLOAT fInitKerning = 0; 1310 for (int i = 0; i < n; i++) { 1311 CPDF_Object* pObj = pArray->GetElementValue(i); 1312 if (pObj->IsString()) { 1313 CFX_ByteString str = pObj->GetString(); 1314 if (str.IsEmpty()) { 1315 continue; 1316 } 1317 pStrs[iSegment] = str; 1318 pKerning[iSegment++] = 0; 1319 } else { 1320 FX_FLOAT num = pObj ? pObj->GetNumber() : 0; 1321 if (iSegment == 0) { 1322 fInitKerning += num; 1323 } else { 1324 pKerning[iSegment - 1] += num; 1325 } 1326 } 1327 } 1328 AddTextObject(pStrs, fInitKerning, pKerning, iSegment); 1329 delete[] pStrs; 1330 FX_Free(pKerning); 1331 } 1332 void CPDF_StreamContentParser::Handle_SetTextLeading() { 1333 m_pCurStates->m_TextLeading = GetNumber(0); 1334 } 1335 void CPDF_StreamContentParser::Handle_SetTextMatrix() { 1336 m_pCurStates->m_TextMatrix.Set(GetNumber16(5), GetNumber16(4), GetNumber16(3), 1337 GetNumber16(2), GetNumber(1), GetNumber(0)); 1338 OnChangeTextMatrix(); 1339 m_pCurStates->m_TextX = 0; 1340 m_pCurStates->m_TextY = 0; 1341 m_pCurStates->m_TextLineX = 0; 1342 m_pCurStates->m_TextLineY = 0; 1343 } 1344 void CPDF_StreamContentParser::OnChangeTextMatrix() { 1345 CFX_Matrix text_matrix(m_pCurStates->m_TextHorzScale, 0.0f, 0.0f, 1.0f, 0.0f, 1346 0.0f); 1347 text_matrix.Concat(m_pCurStates->m_TextMatrix); 1348 text_matrix.Concat(m_pCurStates->m_CTM); 1349 text_matrix.Concat(m_mtContentToUser); 1350 FX_FLOAT* pTextMatrix = m_pCurStates->m_TextState.GetModify()->m_Matrix; 1351 pTextMatrix[0] = text_matrix.a; 1352 pTextMatrix[1] = text_matrix.c; 1353 pTextMatrix[2] = text_matrix.b; 1354 pTextMatrix[3] = text_matrix.d; 1355 } 1356 void CPDF_StreamContentParser::Handle_SetTextRenderMode() { 1357 int mode = GetInteger(0); 1358 if (mode < 0 || mode > 7) { 1359 return; 1360 } 1361 m_pCurStates->m_TextState.GetModify()->m_TextMode = mode; 1362 } 1363 void CPDF_StreamContentParser::Handle_SetTextRise() { 1364 m_pCurStates->m_TextRise = GetNumber(0); 1365 } 1366 void CPDF_StreamContentParser::Handle_SetWordSpace() { 1367 m_pCurStates->m_TextState.GetModify()->m_WordSpace = GetNumber(0); 1368 } 1369 void CPDF_StreamContentParser::Handle_SetHorzScale() { 1370 if (m_ParamCount != 1) { 1371 return; 1372 } 1373 m_pCurStates->m_TextHorzScale = GetNumber(0) / 100; 1374 OnChangeTextMatrix(); 1375 } 1376 void CPDF_StreamContentParser::Handle_MoveToNextLine() { 1377 m_pCurStates->m_TextLineY -= m_pCurStates->m_TextLeading; 1378 m_pCurStates->m_TextX = m_pCurStates->m_TextLineX; 1379 m_pCurStates->m_TextY = m_pCurStates->m_TextLineY; 1380 } 1381 void CPDF_StreamContentParser::Handle_CurveTo_23() { 1382 if (m_Options.m_bTextOnly) { 1383 return; 1384 } 1385 AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_BEZIERTO); 1386 AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO); 1387 AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO); 1388 } 1389 void CPDF_StreamContentParser::Handle_SetLineWidth() { 1390 FX_FLOAT width = GetNumber(0); 1391 m_pCurStates->m_GraphState.GetModify()->m_LineWidth = width; 1392 } 1393 void CPDF_StreamContentParser::Handle_Clip() { 1394 m_PathClipType = FXFILL_WINDING; 1395 } 1396 void CPDF_StreamContentParser::Handle_EOClip() { 1397 m_PathClipType = FXFILL_ALTERNATE; 1398 } 1399 void CPDF_StreamContentParser::Handle_CurveTo_13() { 1400 if (m_Options.m_bTextOnly) { 1401 return; 1402 } 1403 AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO); 1404 AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO); 1405 AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO); 1406 } 1407 void CPDF_StreamContentParser::Handle_NextLineShowText() { 1408 Handle_MoveToNextLine(); 1409 Handle_ShowText(); 1410 } 1411 void CPDF_StreamContentParser::Handle_NextLineShowText_Space() { 1412 m_pCurStates->m_TextState.GetModify()->m_WordSpace = GetNumber(2); 1413 m_pCurStates->m_TextState.GetModify()->m_CharSpace = GetNumber(1); 1414 Handle_NextLineShowText(); 1415 } 1416 void CPDF_StreamContentParser::Handle_Invalid() {} 1417 void CPDF_StreamContentParser::AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag) { 1418 m_PathCurrentX = x; 1419 m_PathCurrentY = y; 1420 if (flag == FXPT_MOVETO) { 1421 m_PathStartX = x; 1422 m_PathStartY = y; 1423 if (m_PathPointCount && 1424 m_pPathPoints[m_PathPointCount - 1].m_Flag == FXPT_MOVETO) { 1425 m_pPathPoints[m_PathPointCount - 1].m_PointX = x; 1426 m_pPathPoints[m_PathPointCount - 1].m_PointY = y; 1427 return; 1428 } 1429 } else if (m_PathPointCount == 0) { 1430 return; 1431 } 1432 m_PathPointCount++; 1433 if (m_PathPointCount > m_PathAllocSize) { 1434 int newsize = m_PathPointCount + 256; 1435 FX_PATHPOINT* pNewPoints = FX_Alloc(FX_PATHPOINT, newsize); 1436 if (m_PathAllocSize) { 1437 FXSYS_memcpy(pNewPoints, m_pPathPoints, 1438 m_PathAllocSize * sizeof(FX_PATHPOINT)); 1439 FX_Free(m_pPathPoints); 1440 } 1441 m_pPathPoints = pNewPoints; 1442 m_PathAllocSize = newsize; 1443 } 1444 m_pPathPoints[m_PathPointCount - 1].m_Flag = flag; 1445 m_pPathPoints[m_PathPointCount - 1].m_PointX = x; 1446 m_pPathPoints[m_PathPointCount - 1].m_PointY = y; 1447 } 1448 void CPDF_StreamContentParser::AddPathObject(int FillType, FX_BOOL bStroke) { 1449 int PathPointCount = m_PathPointCount, PathClipType = m_PathClipType; 1450 m_PathPointCount = 0; 1451 m_PathClipType = 0; 1452 if (PathPointCount <= 1) { 1453 if (PathPointCount && PathClipType) { 1454 CPDF_Path path; 1455 path.New()->AppendRect(0, 0, 0, 0); 1456 m_pCurStates->m_ClipPath.AppendPath(path, FXFILL_WINDING, TRUE); 1457 } 1458 return; 1459 } 1460 if (PathPointCount && 1461 m_pPathPoints[PathPointCount - 1].m_Flag == FXPT_MOVETO) { 1462 PathPointCount--; 1463 } 1464 CPDF_Path Path; 1465 CFX_PathData* pPathData = Path.New(); 1466 pPathData->SetPointCount(PathPointCount); 1467 FXSYS_memcpy(pPathData->GetPoints(), m_pPathPoints, 1468 sizeof(FX_PATHPOINT) * PathPointCount); 1469 CFX_Matrix matrix = m_pCurStates->m_CTM; 1470 matrix.Concat(m_mtContentToUser); 1471 if (bStroke || FillType) { 1472 CPDF_PathObject* pPathObj = new CPDF_PathObject; 1473 pPathObj->m_bStroke = bStroke; 1474 pPathObj->m_FillType = FillType; 1475 pPathObj->m_Path = Path; 1476 pPathObj->m_Matrix = matrix; 1477 SetGraphicStates(pPathObj, TRUE, FALSE, TRUE); 1478 pPathObj->CalcBoundingBox(); 1479 m_pObjectList->m_ObjectList.AddTail(pPathObj); 1480 } 1481 if (PathClipType) { 1482 if (!matrix.IsIdentity()) { 1483 Path.Transform(&matrix); 1484 matrix.SetIdentity(); 1485 } 1486 m_pCurStates->m_ClipPath.AppendPath(Path, PathClipType, TRUE); 1487 } 1488 } 1489