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.
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
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"
12 #include "../fpdf_render/render_int.h"
13 void CPDF_GraphicStates::DefaultStates()
15 m_ColorState.New()->Default();
17 void CPDF_GraphicStates::CopyStates(const CPDF_GraphicStates& src)
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;
25 CPDF_ClipPathData::CPDF_ClipPathData()
33 CPDF_ClipPathData::~CPDF_ClipPathData()
37 FX_DELETE_VECTOR(m_pPathList, CPDF_Path, m_PathCount);
42 for (i = m_TextCount - 1; i > -1; i --)
44 delete m_pTextList[i];
50 CPDF_ClipPathData::CPDF_ClipPathData(const CPDF_ClipPathData& src)
55 m_PathCount = src.m_PathCount;
57 int alloc_size = m_PathCount;
59 alloc_size += 8 - (alloc_size % 8);
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];
65 m_pTypeList = FX_Alloc(FX_BYTE, alloc_size);
66 FXSYS_memcpy32(m_pTypeList, src.m_pTypeList, m_PathCount);
71 m_TextCount = src.m_TextCount;
73 m_pTextList = FX_Alloc(CPDF_TextObject*, m_TextCount);
74 for (int i = 0; i < m_TextCount; i ++) {
75 if (src.m_pTextList[i]) {
76 m_pTextList[i] = FX_NEW CPDF_TextObject;
77 m_pTextList[i]->Copy(src.m_pTextList[i]);
79 m_pTextList[i] = NULL;
86 void CPDF_ClipPathData::SetCount(int path_count, int text_count)
88 ASSERT(m_TextCount == 0 && m_PathCount == 0);
90 m_PathCount = path_count;
91 int alloc_size = (path_count + 7) / 8 * 8;
92 FX_NEW_VECTOR(m_pPathList, CPDF_Path, alloc_size);
93 m_pTypeList = FX_Alloc(FX_BYTE, alloc_size);
96 m_TextCount = text_count;
97 m_pTextList = FX_Alloc(CPDF_TextObject*, text_count);
100 CPDF_Rect CPDF_ClipPath::GetClipBox() const
103 FX_BOOL bStarted = FALSE;
104 int count = GetPathCount();
106 rect = GetPath(0).GetBoundingBox();
107 for (int i = 1; i < count; i ++) {
108 CPDF_Rect path_rect = GetPath(i).GetBoundingBox();
109 rect.Intersect(path_rect);
113 count = GetTextCount();
115 CPDF_Rect layer_rect;
116 FX_BOOL bLayerStarted = FALSE;
117 for (int i = 0; i < count; i ++) {
118 CPDF_TextObject* pTextObj = GetText(i);
119 if (pTextObj == NULL) {
124 rect.Intersect(layer_rect);
126 bLayerStarted = FALSE;
128 if (!bLayerStarted) {
129 layer_rect = pTextObj->GetBBox(NULL);
130 bLayerStarted = TRUE;
132 layer_rect.Union(pTextObj->GetBBox(NULL));
139 void CPDF_ClipPath::AppendPath(CPDF_Path path, int type, FX_BOOL bAutoMerge)
141 CPDF_ClipPathData* pData = GetModify();
142 if (pData->m_PathCount && bAutoMerge) {
143 CPDF_Path old_path = pData->m_pPathList[pData->m_PathCount - 1];
144 if (old_path.IsRect()) {
145 CPDF_Rect old_rect(old_path.GetPointX(0), old_path.GetPointY(0),
146 old_path.GetPointX(2), old_path.GetPointY(2));
147 CPDF_Rect new_rect = path.GetBoundingBox();
148 if (old_rect.Contains(new_rect)) {
149 pData->m_PathCount --;
150 pData->m_pPathList[pData->m_PathCount].SetNull();
154 if (pData->m_PathCount % 8 == 0) {
156 FX_NEW_VECTOR(pNewPath, CPDF_Path, pData->m_PathCount + 8);
157 for (int i = 0; i < pData->m_PathCount; i ++) {
158 pNewPath[i] = pData->m_pPathList[i];
160 if (pData->m_pPathList) {
161 FX_DELETE_VECTOR(pData->m_pPathList, CPDF_Path, pData->m_PathCount);
163 FX_BYTE* pNewType = FX_Alloc(FX_BYTE, pData->m_PathCount + 8);
164 FXSYS_memcpy32(pNewType, pData->m_pTypeList, pData->m_PathCount);
165 if (pData->m_pTypeList) {
166 FX_Free(pData->m_pTypeList);
168 pData->m_pPathList = pNewPath;
169 pData->m_pTypeList = pNewType;
171 pData->m_pPathList[pData->m_PathCount] = path;
172 pData->m_pTypeList[pData->m_PathCount] = (FX_BYTE)type;
173 pData->m_PathCount ++;
175 void CPDF_ClipPath::DeletePath(int index)
177 CPDF_ClipPathData* pData = GetModify();
178 if (index >= pData->m_PathCount) {
181 pData->m_pPathList[index].SetNull();
182 for (int i = index; i < pData->m_PathCount - 1; i ++) {
183 pData->m_pPathList[i] = pData->m_pPathList[i + 1];
185 pData->m_pPathList[pData->m_PathCount - 1].SetNull();
186 FXSYS_memmove32(pData->m_pTypeList + index, pData->m_pTypeList + index + 1, pData->m_PathCount - index - 1);
187 pData->m_PathCount --;
189 #define FPDF_CLIPPATH_MAX_TEXTS 1024
190 void CPDF_ClipPath::AppendTexts(CPDF_TextObject** pTexts, int count)
192 CPDF_ClipPathData* pData = GetModify();
193 if (pData->m_TextCount + count > FPDF_CLIPPATH_MAX_TEXTS) {
194 for (int i = 0; i < count; i ++) {
196 pTexts[i]->Release();
200 CPDF_TextObject** pNewList = FX_Alloc(CPDF_TextObject*, pData->m_TextCount + count + 1);
201 if (pData->m_pTextList) {
202 FXSYS_memcpy32(pNewList, pData->m_pTextList, pData->m_TextCount * sizeof(CPDF_TextObject*));
203 FX_Free(pData->m_pTextList);
205 pData->m_pTextList = pNewList;
206 for (int i = 0; i < count; i ++) {
207 pData->m_pTextList[pData->m_TextCount + i] = pTexts[i];
209 pData->m_pTextList[pData->m_TextCount + count] = NULL;
210 pData->m_TextCount += count + 1;
212 void CPDF_ClipPath::Transform(const CPDF_Matrix& matrix)
214 CPDF_ClipPathData* pData = GetModify();
216 for (i = 0; i < pData->m_PathCount; i ++) {
217 pData->m_pPathList[i].Transform(&matrix);
219 for (i = 0; i < pData->m_TextCount; i ++)
220 if (pData->m_pTextList[i]) {
221 pData->m_pTextList[i]->Transform(matrix);
224 CPDF_ColorStateData::CPDF_ColorStateData(const CPDF_ColorStateData& src)
226 m_FillColor.Copy(&src.m_FillColor);
227 m_FillRGB = src.m_FillRGB;
228 m_StrokeColor.Copy(&src.m_StrokeColor);
229 m_StrokeRGB = src.m_StrokeRGB;
231 void CPDF_ColorStateData::Default()
233 m_FillRGB = m_StrokeRGB = 0;
234 m_FillColor.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY));
235 m_StrokeColor.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY));
237 void CPDF_ColorState::SetFillColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues)
239 CPDF_ColorStateData* pData = GetModify();
240 SetColor(pData->m_FillColor, pData->m_FillRGB, pCS, pValue, nValues);
242 void CPDF_ColorState::SetStrokeColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues)
244 CPDF_ColorStateData* pData = GetModify();
245 SetColor(pData->m_StrokeColor, pData->m_StrokeRGB, pCS, pValue, nValues);
247 void CPDF_ColorState::SetColor(CPDF_Color& color, FX_DWORD& rgb, CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues)
250 color.SetColorSpace(pCS);
251 } else if (color.IsNull()) {
252 color.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY));
254 if (color.m_pCS->CountComponents() > nValues) {
257 color.SetValue(pValue);
259 rgb = color.GetRGB(R, G, B) ? FXSYS_RGB(R, G, B) : (FX_DWORD) - 1;
261 void CPDF_ColorState::SetFillPattern(CPDF_Pattern* pPattern, FX_FLOAT* pValue, int nValues)
263 CPDF_ColorStateData* pData = GetModify();
264 pData->m_FillColor.SetValue(pPattern, pValue, nValues);
266 FX_BOOL ret = pData->m_FillColor.GetRGB(R, G, B);
267 if (pPattern->m_PatternType == 1 && ((CPDF_TilingPattern*)pPattern)->m_bColored && !ret) {
268 pData->m_FillRGB = 0x00BFBFBF;
271 pData->m_FillRGB = ret ? FXSYS_RGB(R, G, B) : (FX_DWORD) - 1;
273 void CPDF_ColorState::SetStrokePattern(CPDF_Pattern* pPattern, FX_FLOAT* pValue, int nValues)
275 CPDF_ColorStateData* pData = GetModify();
276 pData->m_StrokeColor.SetValue(pPattern, pValue, nValues);
278 FX_BOOL ret = pData->m_StrokeColor.GetRGB(R, G, B);
279 if (pPattern->m_PatternType == 1 && ((CPDF_TilingPattern*)pPattern)->m_bColored && !ret) {
280 pData->m_StrokeRGB = 0x00BFBFBF;
283 pData->m_StrokeRGB = pData->m_StrokeColor.GetRGB(R, G, B) ? FXSYS_RGB(R, G, B) : (FX_DWORD) - 1;
285 CPDF_TextStateData::CPDF_TextStateData()
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;
298 CPDF_TextStateData::CPDF_TextStateData(const CPDF_TextStateData& src)
303 FXSYS_memcpy32(this, &src, sizeof(CPDF_TextStateData));
304 if (m_pDocument && m_pFont) {
305 m_pFont = m_pDocument->GetPageData()->GetFont(m_pFont->GetFontDict(), FALSE);
308 CPDF_TextStateData::~CPDF_TextStateData()
310 if (m_pDocument && m_pFont) {
311 CPDF_DocPageData *pPageData = m_pDocument->GetPageData();
312 if (pPageData && !pPageData->IsForceClear()) {
313 pPageData->ReleaseFont(m_pFont->GetFontDict());
317 void CPDF_TextState::SetFont(CPDF_Font* pFont)
319 CPDF_TextStateData* pStateData = GetModify();
321 CPDF_Document* pDoc = pStateData->m_pDocument;
322 CPDF_DocPageData *pPageData = pDoc ? pDoc->GetPageData() : NULL;
323 if (pPageData && pStateData->m_pFont && !pPageData->IsForceClear()) {
324 pPageData->ReleaseFont(pStateData->m_pFont->GetFontDict());
326 pStateData->m_pDocument = pFont ? pFont->m_pDocument : NULL;
327 pStateData->m_pFont = pFont;
330 FX_FLOAT CPDF_TextState::GetFontSizeV() const
332 FX_FLOAT* pMatrix = GetMatrix();
333 FX_FLOAT unit = FXSYS_sqrt2(pMatrix[1], pMatrix[3]);
334 FX_FLOAT size = FXSYS_Mul(unit, GetFontSize());
335 return (FX_FLOAT)FXSYS_fabs(size);
337 FX_FLOAT CPDF_TextState::GetFontSizeH() const
339 FX_FLOAT* pMatrix = GetMatrix();
340 FX_FLOAT unit = FXSYS_sqrt2(pMatrix[0], pMatrix[2]);
341 FX_FLOAT size = FXSYS_Mul(unit, GetFontSize());
342 return (FX_FLOAT)FXSYS_fabs(size);
344 FX_FLOAT CPDF_TextState::GetBaselineAngle() const
346 FX_FLOAT* m_Matrix = GetMatrix();
347 return FXSYS_atan2(m_Matrix[2], m_Matrix[0]);
349 FX_FLOAT CPDF_TextState::GetShearAngle() const
351 FX_FLOAT* m_Matrix = GetMatrix();
352 FX_FLOAT shear_angle = FXSYS_atan2(m_Matrix[1], m_Matrix[3]);
353 return GetBaselineAngle() + shear_angle;
355 CPDF_GeneralStateData::CPDF_GeneralStateData()
357 FXSYS_memset32(this, 0, sizeof(CPDF_GeneralStateData));
358 FXSYS_strcpy((FX_LPSTR)m_BlendMode, (FX_LPCSTR)"Normal");
359 m_StrokeAlpha = 1.0f;
362 m_Matrix.SetIdentity();
364 CPDF_GeneralStateData::CPDF_GeneralStateData(const CPDF_GeneralStateData& src)
366 FXSYS_memcpy32(this, &src, sizeof(CPDF_GeneralStateData));
367 if (src.m_pTransferFunc && src.m_pTransferFunc->m_pPDFDoc) {
368 CPDF_DocRenderData* pDocCache = src.m_pTransferFunc->m_pPDFDoc->GetRenderData();
372 m_pTransferFunc = pDocCache->GetTransferFunc(m_pTR);
375 CPDF_GeneralStateData::~CPDF_GeneralStateData()
377 if (m_pTransferFunc && m_pTransferFunc->m_pPDFDoc) {
378 CPDF_DocRenderData* pDocCache = m_pTransferFunc->m_pPDFDoc->GetRenderData();
382 pDocCache->ReleaseTransferFunc(m_pTR);
385 static int GetBlendType(FX_BSTR mode)
387 switch (mode.GetID()) {
388 case FXBSTR_ID('N', 'o', 'r', 'm'):
389 case FXBSTR_ID('C', 'o', 'm', 'p'):
390 return FXDIB_BLEND_NORMAL;
391 case FXBSTR_ID('M', 'u', 'l', 't'):
392 return FXDIB_BLEND_MULTIPLY;
393 case FXBSTR_ID('S', 'c', 'r', 'e'):
394 return FXDIB_BLEND_SCREEN;
395 case FXBSTR_ID('O', 'v', 'e', 'r'):
396 return FXDIB_BLEND_OVERLAY;
397 case FXBSTR_ID('D', 'a', 'r', 'k'):
398 return FXDIB_BLEND_DARKEN;
399 case FXBSTR_ID('L', 'i', 'g', 'h'):
400 return FXDIB_BLEND_LIGHTEN;
401 case FXBSTR_ID('C', 'o', 'l', 'o'):
402 if (mode.GetLength() == 10) {
403 return FXDIB_BLEND_COLORDODGE;
405 if (mode.GetLength() == 9) {
406 return FXDIB_BLEND_COLORBURN;
408 return FXDIB_BLEND_COLOR;
409 case FXBSTR_ID('H', 'a', 'r', 'd'):
410 return FXDIB_BLEND_HARDLIGHT;
411 case FXBSTR_ID('S', 'o', 'f', 't'):
412 return FXDIB_BLEND_SOFTLIGHT;
413 case FXBSTR_ID('D', 'i', 'f', 'f'):
414 return FXDIB_BLEND_DIFFERENCE;
415 case FXBSTR_ID('E', 'x', 'c', 'l'):
416 return FXDIB_BLEND_EXCLUSION;
417 case FXBSTR_ID('H', 'u', 'e', 0):
418 return FXDIB_BLEND_HUE;
419 case FXBSTR_ID('S', 'a', 't', 'u'):
420 return FXDIB_BLEND_SATURATION;
421 case FXBSTR_ID('L', 'u', 'm', 'i'):
422 return FXDIB_BLEND_LUMINOSITY;
424 return FXDIB_BLEND_NORMAL;
426 void CPDF_GeneralStateData::SetBlendMode(FX_BSTR blend_mode)
428 if (blend_mode.GetLength() > 15) {
431 FXSYS_memcpy32(m_BlendMode, (FX_LPCBYTE)blend_mode, blend_mode.GetLength());
432 m_BlendMode[blend_mode.GetLength()] = 0;
433 m_BlendType = ::GetBlendType(blend_mode);
435 int RI_StringToId(const CFX_ByteString& ri)
437 FX_DWORD id = ri.GetID();
438 if (id == FXBSTR_ID('A', 'b', 's', 'o')) {
441 if (id == FXBSTR_ID('S', 'a', 't', 'u')) {
444 if (id == FXBSTR_ID('P', 'e', 'r', 'c')) {
449 void CPDF_GeneralState::SetRenderIntent(const CFX_ByteString& ri)
451 GetModify()->m_RenderIntent = RI_StringToId(ri);
453 CPDF_AllStates::CPDF_AllStates()
455 m_TextX = m_TextY = m_TextLineX = m_TextLineY = 0;
458 m_TextHorzScale = 1.0f;
460 CPDF_AllStates::~CPDF_AllStates()
463 void CPDF_AllStates::Copy(const CPDF_AllStates& src)
466 m_TextMatrix.Copy(src.m_TextMatrix);
467 m_ParentMatrix.Copy(src.m_ParentMatrix);
468 m_CTM.Copy(src.m_CTM);
469 m_TextX = src.m_TextX;
470 m_TextY = src.m_TextY;
471 m_TextLineX = src.m_TextLineX;
472 m_TextLineY = src.m_TextLineY;
473 m_TextLeading = src.m_TextLeading;
474 m_TextRise = src.m_TextRise;
475 m_TextHorzScale = src.m_TextHorzScale;
477 void CPDF_AllStates::SetLineDash(CPDF_Array* pArray, FX_FLOAT phase, FX_FLOAT scale)
479 CFX_GraphStateData* pData = m_GraphState.GetModify();
480 pData->m_DashPhase = FXSYS_Mul(phase, scale);
481 pData->SetDashCount(pArray->GetCount());
482 for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {
483 pData->m_DashArray[i] = FXSYS_Mul(pArray->GetNumber(i), scale);
486 void CPDF_AllStates::ProcessExtGS(CPDF_Dictionary* pGS, CPDF_StreamContentParser* pParser)
488 CPDF_GeneralStateData* pGeneralState = m_GeneralState.GetModify();
489 FX_POSITION pos = pGS->GetStartPos();
491 CFX_ByteString key_str;
492 CPDF_Object* pElement = pGS->GetNextElement(pos, key_str);
493 CPDF_Object* pObject = pElement ? pElement->GetDirect() : NULL;
494 if (pObject == NULL) {
497 FX_DWORD key = key_str.GetID();
499 case FXBSTR_ID('L', 'W', 0, 0):
500 m_GraphState.GetModify()->m_LineWidth = pObject->GetNumber();
502 case FXBSTR_ID('L', 'C', 0, 0):
503 m_GraphState.GetModify()->m_LineCap = (CFX_GraphStateData::LineCap)pObject->GetInteger();
505 case FXBSTR_ID('L', 'J', 0, 0):
506 m_GraphState.GetModify()->m_LineJoin = (CFX_GraphStateData::LineJoin)pObject->GetInteger();
508 case FXBSTR_ID('M', 'L', 0, 0):
509 m_GraphState.GetModify()->m_MiterLimit = pObject->GetNumber();
511 case FXBSTR_ID('D', 0, 0, 0): {
512 if (pObject->GetType() != PDFOBJ_ARRAY) {
515 CPDF_Array* pDash = (CPDF_Array*)pObject;
516 CPDF_Array* pArray = pDash->GetArray(0);
517 if (pArray == NULL) {
520 SetLineDash(pArray, pDash->GetNumber(1), 1.0f);
523 case FXBSTR_ID('R', 'I', 0, 0):
524 m_GeneralState.SetRenderIntent(pObject->GetString());
526 case FXBSTR_ID('F', 'o', 'n', 't'): {
527 if (pObject->GetType() != PDFOBJ_ARRAY) {
530 CPDF_Array* pFont = (CPDF_Array*)pObject;
531 m_TextState.GetModify()->m_FontSize = pFont->GetNumber(1);
532 m_TextState.SetFont(pParser->FindFont(pFont->GetString(0)));
535 case FXBSTR_ID('T', 'R', 0, 0):
536 if (pGS->KeyExist(FX_BSTRC("TR2"))) {
539 case FXBSTR_ID('T', 'R', '2', 0):
540 if (pObject && pObject->GetType() != PDFOBJ_NAME) {
541 pGeneralState->m_pTR = pObject;
543 pGeneralState->m_pTR = NULL;
546 case FXBSTR_ID('B', 'M', 0, 0): {
548 if (pObject->GetType() == PDFOBJ_ARRAY) {
549 mode = ((CPDF_Array*)pObject)->GetString(0);
551 mode = pObject->GetString();
553 pGeneralState->SetBlendMode(mode);
554 if (pGeneralState->m_BlendType > FXDIB_BLEND_MULTIPLY) {
555 pParser->m_pObjectList->m_bBackgroundAlphaNeeded = TRUE;
559 case FXBSTR_ID('S', 'M', 'a', 's'):
560 if (pObject && pObject->GetType() == PDFOBJ_DICTIONARY) {
561 pGeneralState->m_pSoftMask = pObject;
562 FXSYS_memcpy32(pGeneralState->m_SMaskMatrix, &pParser->m_pCurStates->m_CTM, sizeof(CPDF_Matrix));
564 pGeneralState->m_pSoftMask = NULL;
567 case FXBSTR_ID('C', 'A', 0, 0):
568 pGeneralState->m_StrokeAlpha = PDF_ClipFloat(pObject->GetNumber());
570 case FXBSTR_ID('c', 'a', 0, 0):
571 pGeneralState->m_FillAlpha = PDF_ClipFloat(pObject->GetNumber());
573 case FXBSTR_ID('O', 'P', 0, 0):
574 pGeneralState->m_StrokeOP = pObject->GetInteger();
575 if (!pGS->KeyExist(FX_BSTRC("op"))) {
576 pGeneralState->m_FillOP = pObject->GetInteger();
579 case FXBSTR_ID('o', 'p', 0, 0):
580 pGeneralState->m_FillOP = pObject->GetInteger();
582 case FXBSTR_ID('O', 'P', 'M', 0):
583 pGeneralState->m_OPMode = pObject->GetInteger();
585 case FXBSTR_ID('B', 'G', 0, 0):
586 if (pGS->KeyExist(FX_BSTRC("BG2"))) {
589 case FXBSTR_ID('B', 'G', '2', 0):
590 pGeneralState->m_pBG = pObject;
592 case FXBSTR_ID('U', 'C', 'R', 0):
593 if (pGS->KeyExist(FX_BSTRC("UCR2"))) {
596 case FXBSTR_ID('U', 'C', 'R', '2'):
597 pGeneralState->m_pUCR = pObject;
599 case FXBSTR_ID('H', 'T', 0, 0):
600 pGeneralState->m_pHT = pObject;
602 case FXBSTR_ID('F', 'L', 0, 0):
603 pGeneralState->m_Flatness = pObject->GetNumber();
605 case FXBSTR_ID('S', 'M', 0, 0):
606 pGeneralState->m_Smoothness = pObject->GetNumber();
608 case FXBSTR_ID('S', 'A', 0, 0):
609 pGeneralState->m_StrokeAdjust = pObject->GetInteger();
611 case FXBSTR_ID('A', 'I', 'S', 0):
612 pGeneralState->m_AlphaSource = pObject->GetInteger();
614 case FXBSTR_ID('T', 'K', 0, 0):
615 pGeneralState->m_TextKnockout = pObject->GetInteger();
619 pGeneralState->m_Matrix = m_CTM;
621 CPDF_ContentMarkItem::CPDF_ContentMarkItem()
625 CPDF_ContentMarkItem::CPDF_ContentMarkItem(const CPDF_ContentMarkItem& src)
627 m_MarkName = src.m_MarkName;
628 m_ParamType = src.m_ParamType;
629 if (m_ParamType == DirectDict) {
630 m_pParam = ((CPDF_Dictionary*)src.m_pParam)->Clone();
632 m_pParam = src.m_pParam;
635 CPDF_ContentMarkItem::~CPDF_ContentMarkItem()
637 if (m_ParamType == DirectDict && m_pParam) {
638 ((CPDF_Dictionary*)m_pParam)->Release();
641 FX_BOOL CPDF_ContentMarkItem::HasMCID() const
643 if (m_pParam && (m_ParamType == DirectDict || m_ParamType == PropertiesDict)) {
644 return ((CPDF_Dictionary *)m_pParam)->KeyExist(FX_BSTRC("MCID"));
648 CPDF_ContentMarkData::CPDF_ContentMarkData(const CPDF_ContentMarkData& src)
650 for (int i = 0; i < src.m_Marks.GetSize(); i ++) {
651 m_Marks.Add(src.m_Marks[i]);
654 int CPDF_ContentMarkData::GetMCID() const
656 CPDF_ContentMarkItem::ParamType type = CPDF_ContentMarkItem::None;
657 for (int i = 0; i < m_Marks.GetSize(); i ++) {
658 type = m_Marks[i].GetParamType();
659 if (type == CPDF_ContentMarkItem::PropertiesDict || type == CPDF_ContentMarkItem::DirectDict) {
660 CPDF_Dictionary *pDict = (CPDF_Dictionary *)m_Marks[i].GetParam();
661 if (pDict->KeyExist(FX_BSTRC("MCID"))) {
662 return pDict->GetInteger(FX_BSTRC("MCID"));
668 void CPDF_ContentMarkData::AddMark(const CFX_ByteString& name, CPDF_Dictionary* pDict, FX_BOOL bDirect)
670 CPDF_ContentMarkItem& item = m_Marks.Add();
675 item.SetParam(bDirect ? CPDF_ContentMarkItem::DirectDict : CPDF_ContentMarkItem::PropertiesDict,
676 bDirect ? pDict->Clone() : pDict);
678 void CPDF_ContentMarkData::DeleteLastMark()
680 int size = m_Marks.GetSize();
684 m_Marks.RemoveAt(size - 1);
686 FX_BOOL CPDF_ContentMark::HasMark(FX_BSTR mark) const
688 if (m_pObject == NULL) {
691 for (int i = 0; i < m_pObject->CountItems(); i ++) {
692 CPDF_ContentMarkItem& item = m_pObject->GetItem(i);
693 if (item.GetName() == mark) {
699 FX_BOOL CPDF_ContentMark::LookupMark(FX_BSTR mark, CPDF_Dictionary*& pDict) const
701 if (m_pObject == NULL) {
704 for (int i = 0; i < m_pObject->CountItems(); i ++) {
705 CPDF_ContentMarkItem& item = m_pObject->GetItem(i);
706 if (item.GetName() == mark) {
708 if (item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict ||
709 item.GetParamType() == CPDF_ContentMarkItem::DirectDict) {
710 pDict = (CPDF_Dictionary*)item.GetParam();