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