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