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_pageobj.h" 9 #include "../../../include/fpdfapi/fpdf_module.h" 10 #include "../../../include/fpdfapi/fpdf_render.h" 11 #include "pageint.h" 12 #include "../fpdf_render/render_int.h" 13 void CPDF_GraphicStates::DefaultStates() 14 { 15 m_ColorState.New()->Default(); 16 } 17 void CPDF_GraphicStates::CopyStates(const CPDF_GraphicStates& src) 18 { 19 m_ClipPath = src.m_ClipPath; 20 m_GraphState = src.m_GraphState; 21 m_ColorState = src.m_ColorState; 22 m_TextState = src.m_TextState; 23 m_GeneralState = src.m_GeneralState; 24 } 25 CPDF_ClipPathData::CPDF_ClipPathData() 26 { 27 m_PathCount = 0; 28 m_pPathList = NULL; 29 m_pTypeList = NULL; 30 m_TextCount = 0; 31 m_pTextList = NULL; 32 } 33 CPDF_ClipPathData::~CPDF_ClipPathData() 34 { 35 int i; 36 if (m_pPathList) { 37 FX_DELETE_VECTOR(m_pPathList, CPDF_Path, m_PathCount); 38 } 39 if (m_pTypeList) { 40 FX_Free(m_pTypeList); 41 } 42 for (i = m_TextCount - 1; i > -1; i --) 43 if (m_pTextList[i]) { 44 delete m_pTextList[i]; 45 } 46 if (m_pTextList) { 47 FX_Free(m_pTextList); 48 } 49 } 50 CPDF_ClipPathData::CPDF_ClipPathData(const CPDF_ClipPathData& src) 51 { 52 m_pPathList = NULL; 53 m_pPathList = NULL; 54 m_pTextList = NULL; 55 m_PathCount = src.m_PathCount; 56 if (m_PathCount) { 57 int alloc_size = m_PathCount; 58 if (alloc_size % 8) { 59 alloc_size += 8 - (alloc_size % 8); 60 } 61 FX_NEW_VECTOR(m_pPathList, CPDF_Path, alloc_size); 62 for (int i = 0; i < m_PathCount; i ++) { 63 m_pPathList[i] = src.m_pPathList[i]; 64 } 65 m_pTypeList = FX_Alloc(FX_BYTE, alloc_size); 66 FXSYS_memcpy32(m_pTypeList, src.m_pTypeList, m_PathCount); 67 } else { 68 m_pPathList = NULL; 69 m_pTypeList = NULL; 70 } 71 m_TextCount = src.m_TextCount; 72 if (m_TextCount) { 73 m_pTextList = FX_Alloc(CPDF_TextObject*, m_TextCount); 74 FXSYS_memset32(m_pTextList, 0, sizeof(CPDF_TextObject*) * m_TextCount); 75 for (int i = 0; i < m_TextCount; i ++) { 76 if (src.m_pTextList[i]) { 77 m_pTextList[i] = FX_NEW CPDF_TextObject; 78 m_pTextList[i]->Copy(src.m_pTextList[i]); 79 } else { 80 m_pTextList[i] = NULL; 81 } 82 } 83 } else { 84 m_pTextList = NULL; 85 } 86 } 87 void CPDF_ClipPathData::SetCount(int path_count, int text_count) 88 { 89 ASSERT(m_TextCount == 0 && m_PathCount == 0); 90 if (path_count) { 91 m_PathCount = path_count; 92 int alloc_size = (path_count + 7) / 8 * 8; 93 FX_NEW_VECTOR(m_pPathList, CPDF_Path, alloc_size); 94 m_pTypeList = FX_Alloc(FX_BYTE, alloc_size); 95 } 96 if (text_count) { 97 m_TextCount = text_count; 98 m_pTextList = FX_Alloc(CPDF_TextObject*, text_count); 99 FXSYS_memset32(m_pTextList, 0, sizeof(void*) * text_count); 100 } 101 } 102 CPDF_Rect CPDF_ClipPath::GetClipBox() const 103 { 104 CPDF_Rect rect; 105 FX_BOOL bStarted = FALSE; 106 int count = GetPathCount(); 107 if (count) { 108 rect = GetPath(0).GetBoundingBox(); 109 for (int i = 1; i < count; i ++) { 110 CPDF_Rect path_rect = GetPath(i).GetBoundingBox(); 111 rect.Intersect(path_rect); 112 } 113 bStarted = TRUE; 114 } 115 count = GetTextCount(); 116 if (count) { 117 CPDF_Rect layer_rect; 118 FX_BOOL bLayerStarted = FALSE; 119 for (int i = 0; i < count; i ++) { 120 CPDF_TextObject* pTextObj = GetText(i); 121 if (pTextObj == NULL) { 122 if (!bStarted) { 123 rect = layer_rect; 124 bStarted = TRUE; 125 } else { 126 rect.Intersect(layer_rect); 127 } 128 bLayerStarted = FALSE; 129 } else { 130 if (!bLayerStarted) { 131 layer_rect = pTextObj->GetBBox(NULL); 132 bLayerStarted = TRUE; 133 } else { 134 layer_rect.Union(pTextObj->GetBBox(NULL)); 135 } 136 } 137 } 138 } 139 return rect; 140 } 141 void CPDF_ClipPath::AppendPath(CPDF_Path path, int type, FX_BOOL bAutoMerge) 142 { 143 CPDF_ClipPathData* pData = GetModify(); 144 if (pData->m_PathCount && bAutoMerge) { 145 CPDF_Path old_path = pData->m_pPathList[pData->m_PathCount - 1]; 146 if (old_path.IsRect()) { 147 CPDF_Rect old_rect(old_path.GetPointX(0), old_path.GetPointY(0), 148 old_path.GetPointX(2), old_path.GetPointY(2)); 149 CPDF_Rect new_rect = path.GetBoundingBox(); 150 if (old_rect.Contains(new_rect)) { 151 pData->m_PathCount --; 152 pData->m_pPathList[pData->m_PathCount].SetNull(); 153 } 154 } 155 } 156 if (pData->m_PathCount % 8 == 0) { 157 CPDF_Path* pNewPath; 158 FX_NEW_VECTOR(pNewPath, CPDF_Path, pData->m_PathCount + 8); 159 for (int i = 0; i < pData->m_PathCount; i ++) { 160 pNewPath[i] = pData->m_pPathList[i]; 161 } 162 if (pData->m_pPathList) { 163 FX_DELETE_VECTOR(pData->m_pPathList, CPDF_Path, pData->m_PathCount); 164 } 165 FX_BYTE* pNewType = FX_Alloc(FX_BYTE, pData->m_PathCount + 8); 166 FXSYS_memcpy32(pNewType, pData->m_pTypeList, pData->m_PathCount); 167 if (pData->m_pTypeList) { 168 FX_Free(pData->m_pTypeList); 169 } 170 pData->m_pPathList = pNewPath; 171 pData->m_pTypeList = pNewType; 172 } 173 pData->m_pPathList[pData->m_PathCount] = path; 174 pData->m_pTypeList[pData->m_PathCount] = (FX_BYTE)type; 175 pData->m_PathCount ++; 176 } 177 void CPDF_ClipPath::DeletePath(int index) 178 { 179 CPDF_ClipPathData* pData = GetModify(); 180 if (index >= pData->m_PathCount) { 181 return; 182 } 183 pData->m_pPathList[index].SetNull(); 184 for (int i = index; i < pData->m_PathCount - 1; i ++) { 185 pData->m_pPathList[i] = pData->m_pPathList[i + 1]; 186 } 187 pData->m_pPathList[pData->m_PathCount - 1].SetNull(); 188 FXSYS_memmove32(pData->m_pTypeList + index, pData->m_pTypeList + index + 1, pData->m_PathCount - index - 1); 189 pData->m_PathCount --; 190 } 191 #define FPDF_CLIPPATH_MAX_TEXTS 1024 192 void CPDF_ClipPath::AppendTexts(CPDF_TextObject** pTexts, int count) 193 { 194 CPDF_ClipPathData* pData = GetModify(); 195 if (pData->m_TextCount + count > FPDF_CLIPPATH_MAX_TEXTS) { 196 for (int i = 0; i < count; i ++) { 197 pTexts[i]->Release(); 198 } 199 return; 200 } 201 CPDF_TextObject** pNewList = FX_Alloc(CPDF_TextObject*, pData->m_TextCount + count + 1); 202 if (pData->m_pTextList) { 203 FXSYS_memcpy32(pNewList, pData->m_pTextList, pData->m_TextCount * sizeof(CPDF_TextObject*)); 204 FX_Free(pData->m_pTextList); 205 } 206 pData->m_pTextList = pNewList; 207 for (int i = 0; i < count; i ++) { 208 pData->m_pTextList[pData->m_TextCount + i] = pTexts[i]; 209 } 210 pData->m_pTextList[pData->m_TextCount + count] = NULL; 211 pData->m_TextCount += count + 1; 212 } 213 void CPDF_ClipPath::Transform(const CPDF_Matrix& matrix) 214 { 215 CPDF_ClipPathData* pData = GetModify(); 216 int i; 217 for (i = 0; i < pData->m_PathCount; i ++) { 218 pData->m_pPathList[i].Transform(&matrix); 219 } 220 for (i = 0; i < pData->m_TextCount; i ++) 221 if (pData->m_pTextList[i]) { 222 pData->m_pTextList[i]->Transform(matrix); 223 } 224 } 225 CPDF_ColorStateData::CPDF_ColorStateData(const CPDF_ColorStateData& src) 226 { 227 m_FillColor.Copy(&src.m_FillColor); 228 m_FillRGB = src.m_FillRGB; 229 m_StrokeColor.Copy(&src.m_StrokeColor); 230 m_StrokeRGB = src.m_StrokeRGB; 231 } 232 void CPDF_ColorStateData::Default() 233 { 234 m_FillRGB = m_StrokeRGB = 0; 235 m_FillColor.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY)); 236 m_StrokeColor.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY)); 237 } 238 void CPDF_ColorState::SetFillColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues) 239 { 240 CPDF_ColorStateData* pData = GetModify(); 241 SetColor(pData->m_FillColor, pData->m_FillRGB, pCS, pValue, nValues); 242 } 243 void CPDF_ColorState::SetStrokeColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues) 244 { 245 CPDF_ColorStateData* pData = GetModify(); 246 SetColor(pData->m_StrokeColor, pData->m_StrokeRGB, pCS, pValue, nValues); 247 } 248 void CPDF_ColorState::SetColor(CPDF_Color& color, FX_DWORD& rgb, CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues) 249 { 250 if (pCS) { 251 color.SetColorSpace(pCS); 252 } else if (color.IsNull()) { 253 color.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY)); 254 } 255 if (color.m_pCS->CountComponents() > nValues) { 256 return; 257 } 258 color.SetValue(pValue); 259 int R, G, B; 260 rgb = color.GetRGB(R, G, B) ? FXSYS_RGB(R, G, B) : (FX_DWORD) - 1; 261 } 262 void CPDF_ColorState::SetFillPattern(CPDF_Pattern* pPattern, FX_FLOAT* pValue, int nValues) 263 { 264 CPDF_ColorStateData* pData = GetModify(); 265 pData->m_FillColor.SetValue(pPattern, pValue, nValues); 266 int R, G, B; 267 FX_BOOL ret = pData->m_FillColor.GetRGB(R, G, B); 268 if (pPattern->m_PatternType == 1 && ((CPDF_TilingPattern*)pPattern)->m_bColored && !ret) { 269 pData->m_FillRGB = 0x00BFBFBF; 270 return; 271 } 272 pData->m_FillRGB = ret ? FXSYS_RGB(R, G, B) : (FX_DWORD) - 1; 273 } 274 void CPDF_ColorState::SetStrokePattern(CPDF_Pattern* pPattern, FX_FLOAT* pValue, int nValues) 275 { 276 CPDF_ColorStateData* pData = GetModify(); 277 pData->m_StrokeColor.SetValue(pPattern, pValue, nValues); 278 int R, G, B; 279 FX_BOOL ret = pData->m_StrokeColor.GetRGB(R, G, B); 280 if (pPattern->m_PatternType == 1 && ((CPDF_TilingPattern*)pPattern)->m_bColored && !ret) { 281 pData->m_StrokeRGB = 0x00BFBFBF; 282 return; 283 } 284 pData->m_StrokeRGB = pData->m_StrokeColor.GetRGB(R, G, B) ? FXSYS_RGB(R, G, B) : (FX_DWORD) - 1; 285 } 286 CPDF_TextStateData::CPDF_TextStateData() 287 { 288 m_pFont = NULL; 289 m_FontSize = 1.0f; 290 m_WordSpace = 0; 291 m_CharSpace = 0; 292 m_TextMode = 0; 293 m_Matrix[0] = m_Matrix[3] = 1.0f; 294 m_Matrix[1] = m_Matrix[2] = 0; 295 m_CTM[0] = m_CTM[3] = 1.0f; 296 m_CTM[1] = m_CTM[2] = 0; 297 } 298 CPDF_TextStateData::CPDF_TextStateData(const CPDF_TextStateData& src) 299 { 300 FXSYS_memcpy32(this, &src, sizeof(CPDF_TextStateData)); 301 if (m_pFont && m_pFont->m_pDocument) { 302 m_pFont = m_pFont->m_pDocument->GetPageData()->GetFont(m_pFont->GetFontDict(), FALSE); 303 } 304 } 305 CPDF_TextStateData::~CPDF_TextStateData() 306 { 307 CPDF_Font* pFont = m_pFont; 308 if (pFont && pFont->m_pDocument) { 309 pFont->m_pDocument->GetPageData()->ReleaseFont(pFont->GetFontDict()); 310 } 311 } 312 void CPDF_TextState::SetFont(CPDF_Font* pFont) 313 { 314 CPDF_Font*& pStateFont = GetModify()->m_pFont; 315 CPDF_DocPageData* pDocPageData = NULL; 316 if (pStateFont && pStateFont->m_pDocument) { 317 pDocPageData = pStateFont->m_pDocument->GetPageData(); 318 pDocPageData->ReleaseFont(pStateFont->GetFontDict()); 319 } 320 pStateFont = pFont; 321 } 322 FX_FLOAT CPDF_TextState::GetFontSizeV() const 323 { 324 FX_FLOAT* pMatrix = GetMatrix(); 325 FX_FLOAT unit = FXSYS_sqrt2(pMatrix[1], pMatrix[3]); 326 FX_FLOAT size = FXSYS_Mul(unit, GetFontSize()); 327 return (FX_FLOAT)FXSYS_fabs(size); 328 } 329 FX_FLOAT CPDF_TextState::GetFontSizeH() const 330 { 331 FX_FLOAT* pMatrix = GetMatrix(); 332 FX_FLOAT unit = FXSYS_sqrt2(pMatrix[0], pMatrix[2]); 333 FX_FLOAT size = FXSYS_Mul(unit, GetFontSize()); 334 return (FX_FLOAT)FXSYS_fabs(size); 335 } 336 FX_FLOAT CPDF_TextState::GetBaselineAngle() const 337 { 338 FX_FLOAT* m_Matrix = GetMatrix(); 339 return FXSYS_atan2(m_Matrix[2], m_Matrix[0]); 340 } 341 FX_FLOAT CPDF_TextState::GetShearAngle() const 342 { 343 FX_FLOAT* m_Matrix = GetMatrix(); 344 FX_FLOAT shear_angle = FXSYS_atan2(m_Matrix[1], m_Matrix[3]); 345 return GetBaselineAngle() + shear_angle; 346 } 347 CPDF_GeneralStateData::CPDF_GeneralStateData() 348 { 349 FXSYS_memset32(this, 0, sizeof(CPDF_GeneralStateData)); 350 FXSYS_strcpy((FX_LPSTR)m_BlendMode, (FX_LPCSTR)"Normal"); 351 m_StrokeAlpha = 1.0f; 352 m_FillAlpha = 1.0f; 353 m_Flatness = 1.0f; 354 m_Matrix.SetIdentity(); 355 } 356 CPDF_GeneralStateData::CPDF_GeneralStateData(const CPDF_GeneralStateData& src) 357 { 358 FXSYS_memcpy32(this, &src, sizeof(CPDF_GeneralStateData)); 359 if (src.m_pTransferFunc && src.m_pTransferFunc->m_pPDFDoc) { 360 CPDF_DocRenderData* pDocCache = src.m_pTransferFunc->m_pPDFDoc->GetRenderData(); 361 if (!pDocCache) { 362 return; 363 } 364 m_pTransferFunc = pDocCache->GetTransferFunc(m_pTR); 365 } 366 } 367 CPDF_GeneralStateData::~CPDF_GeneralStateData() 368 { 369 if (m_pTransferFunc && m_pTransferFunc->m_pPDFDoc) { 370 CPDF_DocRenderData* pDocCache = m_pTransferFunc->m_pPDFDoc->GetRenderData(); 371 if (!pDocCache) { 372 return; 373 } 374 pDocCache->ReleaseTransferFunc(m_pTR); 375 } 376 } 377 static int GetBlendType(FX_BSTR mode) 378 { 379 switch (mode.GetID()) { 380 case FXBSTR_ID('N', 'o', 'r', 'm'): 381 case FXBSTR_ID('C', 'o', 'm', 'p'): 382 return FXDIB_BLEND_NORMAL; 383 case FXBSTR_ID('M', 'u', 'l', 't'): 384 return FXDIB_BLEND_MULTIPLY; 385 case FXBSTR_ID('S', 'c', 'r', 'e'): 386 return FXDIB_BLEND_SCREEN; 387 case FXBSTR_ID('O', 'v', 'e', 'r'): 388 return FXDIB_BLEND_OVERLAY; 389 case FXBSTR_ID('D', 'a', 'r', 'k'): 390 return FXDIB_BLEND_DARKEN; 391 case FXBSTR_ID('L', 'i', 'g', 'h'): 392 return FXDIB_BLEND_LIGHTEN; 393 case FXBSTR_ID('C', 'o', 'l', 'o'): 394 if (mode.GetLength() == 10) { 395 return FXDIB_BLEND_COLORDODGE; 396 } 397 if (mode.GetLength() == 9) { 398 return FXDIB_BLEND_COLORBURN; 399 } 400 return FXDIB_BLEND_COLOR; 401 case FXBSTR_ID('H', 'a', 'r', 'd'): 402 return FXDIB_BLEND_HARDLIGHT; 403 case FXBSTR_ID('S', 'o', 'f', 't'): 404 return FXDIB_BLEND_SOFTLIGHT; 405 case FXBSTR_ID('D', 'i', 'f', 'f'): 406 return FXDIB_BLEND_DIFFERENCE; 407 case FXBSTR_ID('E', 'x', 'c', 'l'): 408 return FXDIB_BLEND_EXCLUSION; 409 case FXBSTR_ID('H', 'u', 'e', 0): 410 return FXDIB_BLEND_HUE; 411 case FXBSTR_ID('S', 'a', 't', 'u'): 412 return FXDIB_BLEND_SATURATION; 413 case FXBSTR_ID('L', 'u', 'm', 'i'): 414 return FXDIB_BLEND_LUMINOSITY; 415 } 416 return FXDIB_BLEND_NORMAL; 417 } 418 void CPDF_GeneralStateData::SetBlendMode(FX_BSTR blend_mode) 419 { 420 if (blend_mode.GetLength() > 15) { 421 return; 422 } 423 FXSYS_memcpy32(m_BlendMode, (FX_LPCBYTE)blend_mode, blend_mode.GetLength()); 424 m_BlendMode[blend_mode.GetLength()] = 0; 425 m_BlendType = ::GetBlendType(blend_mode); 426 } 427 int RI_StringToId(const CFX_ByteString& ri) 428 { 429 FX_DWORD id = ri.GetID(); 430 if (id == FXBSTR_ID('A', 'b', 's', 'o')) { 431 return 1; 432 } 433 if (id == FXBSTR_ID('S', 'a', 't', 'u')) { 434 return 2; 435 } 436 if (id == FXBSTR_ID('P', 'e', 'r', 'c')) { 437 return 3; 438 } 439 return 0; 440 } 441 void CPDF_GeneralState::SetRenderIntent(const CFX_ByteString& ri) 442 { 443 GetModify()->m_RenderIntent = RI_StringToId(ri); 444 } 445 CPDF_AllStates::CPDF_AllStates() 446 { 447 m_TextX = m_TextY = m_TextLineX = m_TextLineY = 0; 448 m_TextLeading = 0; 449 m_TextRise = 0; 450 m_TextHorzScale = 1.0f; 451 } 452 CPDF_AllStates::~CPDF_AllStates() 453 { 454 } 455 void CPDF_AllStates::Copy(const CPDF_AllStates& src) 456 { 457 CopyStates(src); 458 m_TextMatrix.Copy(src.m_TextMatrix); 459 m_ParentMatrix.Copy(src.m_ParentMatrix); 460 m_CTM.Copy(src.m_CTM); 461 m_TextX = src.m_TextX; 462 m_TextY = src.m_TextY; 463 m_TextLineX = src.m_TextLineX; 464 m_TextLineY = src.m_TextLineY; 465 m_TextLeading = src.m_TextLeading; 466 m_TextRise = src.m_TextRise; 467 m_TextHorzScale = src.m_TextHorzScale; 468 } 469 void CPDF_AllStates::SetLineDash(CPDF_Array* pArray, FX_FLOAT phase, FX_FLOAT scale) 470 { 471 CFX_GraphStateData* pData = m_GraphState.GetModify(); 472 pData->m_DashPhase = FXSYS_Mul(phase, scale); 473 pData->SetDashCount(pArray->GetCount()); 474 for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) { 475 pData->m_DashArray[i] = FXSYS_Mul(pArray->GetNumber(i), scale); 476 } 477 } 478 void CPDF_AllStates::ProcessExtGS(CPDF_Dictionary* pGS, CPDF_StreamContentParser* pParser) 479 { 480 CPDF_GeneralStateData* pGeneralState = m_GeneralState.GetModify(); 481 FX_POSITION pos = pGS->GetStartPos(); 482 while (pos) { 483 CFX_ByteString key_str; 484 CPDF_Object* pObject = pGS->GetNextElement(pos, key_str)->GetDirect(); 485 if (pObject == NULL) { 486 continue; 487 } 488 FX_DWORD key = key_str.GetID(); 489 switch (key) { 490 case FXBSTR_ID('L', 'W', 0, 0): 491 m_GraphState.GetModify()->m_LineWidth = pObject->GetNumber(); 492 break; 493 case FXBSTR_ID('L', 'C', 0, 0): 494 m_GraphState.GetModify()->m_LineCap = (CFX_GraphStateData::LineCap)pObject->GetInteger(); 495 break; 496 case FXBSTR_ID('L', 'J', 0, 0): 497 m_GraphState.GetModify()->m_LineJoin = (CFX_GraphStateData::LineJoin)pObject->GetInteger(); 498 break; 499 case FXBSTR_ID('M', 'L', 0, 0): 500 m_GraphState.GetModify()->m_MiterLimit = pObject->GetNumber(); 501 break; 502 case FXBSTR_ID('D', 0, 0, 0): { 503 if (pObject->GetType() != PDFOBJ_ARRAY) { 504 break; 505 } 506 CPDF_Array* pDash = (CPDF_Array*)pObject; 507 CPDF_Array* pArray = pDash->GetArray(0); 508 if (pArray == NULL) { 509 break; 510 } 511 SetLineDash(pArray, pDash->GetNumber(1), 1.0f); 512 break; 513 } 514 case FXBSTR_ID('R', 'I', 0, 0): 515 m_GeneralState.SetRenderIntent(pObject->GetString()); 516 break; 517 case FXBSTR_ID('F', 'o', 'n', 't'): { 518 if (pObject->GetType() != PDFOBJ_ARRAY) { 519 break; 520 } 521 CPDF_Array* pFont = (CPDF_Array*)pObject; 522 m_TextState.GetModify()->m_FontSize = pFont->GetNumber(1); 523 m_TextState.SetFont(pParser->FindFont(pFont->GetString(0))); 524 break; 525 } 526 case FXBSTR_ID('T', 'R', 0, 0): 527 if (pGS->KeyExist(FX_BSTRC("TR2"))) { 528 continue; 529 } 530 case FXBSTR_ID('T', 'R', '2', 0): 531 if (pObject && pObject->GetType() != PDFOBJ_NAME) { 532 pGeneralState->m_pTR = pObject; 533 } else { 534 pGeneralState->m_pTR = NULL; 535 } 536 break; 537 case FXBSTR_ID('B', 'M', 0, 0): { 538 CFX_ByteString mode; 539 if (pObject->GetType() == PDFOBJ_ARRAY) { 540 mode = ((CPDF_Array*)pObject)->GetString(0); 541 } else { 542 mode = pObject->GetString(); 543 } 544 pGeneralState->SetBlendMode(mode); 545 if (pGeneralState->m_BlendType > FXDIB_BLEND_MULTIPLY) { 546 pParser->m_pObjectList->m_bBackgroundAlphaNeeded = TRUE; 547 } 548 break; 549 } 550 case FXBSTR_ID('S', 'M', 'a', 's'): 551 if (pObject && pObject->GetType() == PDFOBJ_DICTIONARY) { 552 pGeneralState->m_pSoftMask = pObject; 553 FXSYS_memcpy32(pGeneralState->m_SMaskMatrix, &pParser->m_pCurStates->m_CTM, sizeof(CPDF_Matrix)); 554 } else { 555 pGeneralState->m_pSoftMask = NULL; 556 } 557 break; 558 case FXBSTR_ID('C', 'A', 0, 0): 559 pGeneralState->m_StrokeAlpha = PDF_ClipFloat(pObject->GetNumber()); 560 break; 561 case FXBSTR_ID('c', 'a', 0, 0): 562 pGeneralState->m_FillAlpha = PDF_ClipFloat(pObject->GetNumber()); 563 break; 564 case FXBSTR_ID('O', 'P', 0, 0): 565 pGeneralState->m_StrokeOP = pObject->GetInteger(); 566 if (!pGS->KeyExist(FX_BSTRC("op"))) { 567 pGeneralState->m_FillOP = pObject->GetInteger(); 568 } 569 break; 570 case FXBSTR_ID('o', 'p', 0, 0): 571 pGeneralState->m_FillOP = pObject->GetInteger(); 572 break; 573 case FXBSTR_ID('O', 'P', 'M', 0): 574 pGeneralState->m_OPMode = pObject->GetInteger(); 575 break; 576 case FXBSTR_ID('B', 'G', 0, 0): 577 if (pGS->KeyExist(FX_BSTRC("BG2"))) { 578 continue; 579 } 580 case FXBSTR_ID('B', 'G', '2', 0): 581 pGeneralState->m_pBG = pObject; 582 break; 583 case FXBSTR_ID('U', 'C', 'R', 0): 584 if (pGS->KeyExist(FX_BSTRC("UCR2"))) { 585 continue; 586 } 587 case FXBSTR_ID('U', 'C', 'R', '2'): 588 pGeneralState->m_pUCR = pObject; 589 break; 590 case FXBSTR_ID('H', 'T', 0, 0): 591 pGeneralState->m_pHT = pObject; 592 break; 593 case FXBSTR_ID('F', 'L', 0, 0): 594 pGeneralState->m_Flatness = pObject->GetNumber(); 595 break; 596 case FXBSTR_ID('S', 'M', 0, 0): 597 pGeneralState->m_Smoothness = pObject->GetNumber(); 598 break; 599 case FXBSTR_ID('S', 'A', 0, 0): 600 pGeneralState->m_StrokeAdjust = pObject->GetInteger(); 601 break; 602 case FXBSTR_ID('A', 'I', 'S', 0): 603 pGeneralState->m_AlphaSource = pObject->GetInteger(); 604 break; 605 case FXBSTR_ID('T', 'K', 0, 0): 606 pGeneralState->m_TextKnockout = pObject->GetInteger(); 607 break; 608 } 609 } 610 pGeneralState->m_Matrix = m_CTM; 611 } 612 CPDF_ContentMarkItem::CPDF_ContentMarkItem() 613 { 614 m_ParamType = None; 615 } 616 CPDF_ContentMarkItem::CPDF_ContentMarkItem(const CPDF_ContentMarkItem& src) 617 { 618 m_MarkName = src.m_MarkName; 619 m_ParamType = src.m_ParamType; 620 if (m_ParamType == DirectDict) { 621 m_pParam = ((CPDF_Dictionary*)src.m_pParam)->Clone(); 622 } else { 623 m_pParam = src.m_pParam; 624 } 625 } 626 CPDF_ContentMarkItem::~CPDF_ContentMarkItem() 627 { 628 if (m_ParamType == DirectDict) { 629 ((CPDF_Dictionary*)m_pParam)->Release(); 630 } 631 } 632 FX_BOOL CPDF_ContentMarkItem::HasMCID() const 633 { 634 if (m_pParam && (m_ParamType == DirectDict || m_ParamType == PropertiesDict)) { 635 return ((CPDF_Dictionary *)m_pParam)->KeyExist(FX_BSTRC("MCID")); 636 } 637 return FALSE; 638 } 639 CPDF_ContentMarkData::CPDF_ContentMarkData(const CPDF_ContentMarkData& src) 640 { 641 for (int i = 0; i < src.m_Marks.GetSize(); i ++) { 642 m_Marks.Add(src.m_Marks[i]); 643 } 644 } 645 int CPDF_ContentMarkData::GetMCID() const 646 { 647 CPDF_ContentMarkItem::ParamType type = CPDF_ContentMarkItem::None; 648 for (int i = 0; i < m_Marks.GetSize(); i ++) { 649 type = m_Marks[i].GetParamType(); 650 if (type == CPDF_ContentMarkItem::PropertiesDict || type == CPDF_ContentMarkItem::DirectDict) { 651 CPDF_Dictionary *pDict = (CPDF_Dictionary *)m_Marks[i].GetParam(); 652 if (pDict->KeyExist(FX_BSTRC("MCID"))) { 653 return pDict->GetInteger(FX_BSTRC("MCID")); 654 } 655 } 656 } 657 return -1; 658 } 659 void CPDF_ContentMarkData::AddMark(const CFX_ByteString& name, CPDF_Dictionary* pDict, FX_BOOL bDirect) 660 { 661 CPDF_ContentMarkItem& item = m_Marks.Add(); 662 item.SetName(name); 663 if (pDict == NULL) { 664 return; 665 } 666 item.SetParam(bDirect ? CPDF_ContentMarkItem::DirectDict : CPDF_ContentMarkItem::PropertiesDict, 667 bDirect ? pDict->Clone() : pDict); 668 } 669 void CPDF_ContentMarkData::DeleteLastMark() 670 { 671 int size = m_Marks.GetSize(); 672 if (size == 0) { 673 return; 674 } 675 m_Marks.RemoveAt(size - 1); 676 } 677 FX_BOOL CPDF_ContentMark::HasMark(FX_BSTR mark) const 678 { 679 if (m_pObject == NULL) { 680 return FALSE; 681 } 682 for (int i = 0; i < m_pObject->CountItems(); i ++) { 683 CPDF_ContentMarkItem& item = m_pObject->GetItem(i); 684 if (item.GetName() == mark) { 685 return TRUE; 686 } 687 } 688 return FALSE; 689 } 690 FX_BOOL CPDF_ContentMark::LookupMark(FX_BSTR mark, CPDF_Dictionary*& pDict) const 691 { 692 if (m_pObject == NULL) { 693 return FALSE; 694 } 695 for (int i = 0; i < m_pObject->CountItems(); i ++) { 696 CPDF_ContentMarkItem& item = m_pObject->GetItem(i); 697 if (item.GetName() == mark) { 698 pDict = NULL; 699 if (item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict || 700 item.GetParamType() == CPDF_ContentMarkItem::DirectDict) { 701 pDict = (CPDF_Dictionary*)item.GetParam(); 702 } 703 return TRUE; 704 } 705 } 706 return FALSE; 707 } 708