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"
DefaultStates()13 void CPDF_GraphicStates::DefaultStates()
14 {
15 m_ColorState.New()->Default();
16 }
CopyStates(const CPDF_GraphicStates & src)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 }
CPDF_ClipPathData()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 }
~CPDF_ClipPathData()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 }
CPDF_ClipPathData(const CPDF_ClipPathData & src)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 }
SetCount(int path_count,int text_count)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 }
GetClipBox() const102 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 }
AppendPath(CPDF_Path path,int type,FX_BOOL bAutoMerge)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 }
DeletePath(int index)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
AppendTexts(CPDF_TextObject ** pTexts,int count)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 }
Transform(const CPDF_Matrix & matrix)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 }
CPDF_ColorStateData(const CPDF_ColorStateData & src)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 }
Default()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 }
SetFillColor(CPDF_ColorSpace * pCS,FX_FLOAT * pValue,int nValues)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 }
SetStrokeColor(CPDF_ColorSpace * pCS,FX_FLOAT * pValue,int nValues)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 }
SetColor(CPDF_Color & color,FX_DWORD & rgb,CPDF_ColorSpace * pCS,FX_FLOAT * pValue,int nValues)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 }
SetFillPattern(CPDF_Pattern * pPattern,FX_FLOAT * pValue,int nValues)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 }
SetStrokePattern(CPDF_Pattern * pPattern,FX_FLOAT * pValue,int nValues)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 }
CPDF_TextStateData()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 }
CPDF_TextStateData(const CPDF_TextStateData & src)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 }
~CPDF_TextStateData()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 }
SetFont(CPDF_Font * pFont)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 }
GetFontSizeV() const322 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 }
GetFontSizeH() const329 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 }
GetBaselineAngle() const336 FX_FLOAT CPDF_TextState::GetBaselineAngle() const
337 {
338 FX_FLOAT* m_Matrix = GetMatrix();
339 return FXSYS_atan2(m_Matrix[2], m_Matrix[0]);
340 }
GetShearAngle() const341 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 }
CPDF_GeneralStateData()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 }
CPDF_GeneralStateData(const CPDF_GeneralStateData & src)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 }
~CPDF_GeneralStateData()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 }
GetBlendType(FX_BSTR mode)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 }
SetBlendMode(FX_BSTR blend_mode)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 }
RI_StringToId(const CFX_ByteString & ri)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 }
SetRenderIntent(const CFX_ByteString & ri)441 void CPDF_GeneralState::SetRenderIntent(const CFX_ByteString& ri)
442 {
443 GetModify()->m_RenderIntent = RI_StringToId(ri);
444 }
CPDF_AllStates()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 }
~CPDF_AllStates()452 CPDF_AllStates::~CPDF_AllStates()
453 {
454 }
Copy(const CPDF_AllStates & src)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 }
SetLineDash(CPDF_Array * pArray,FX_FLOAT phase,FX_FLOAT scale)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 }
ProcessExtGS(CPDF_Dictionary * pGS,CPDF_StreamContentParser * pParser)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 }
CPDF_ContentMarkItem()612 CPDF_ContentMarkItem::CPDF_ContentMarkItem()
613 {
614 m_ParamType = None;
615 }
CPDF_ContentMarkItem(const CPDF_ContentMarkItem & src)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 }
~CPDF_ContentMarkItem()626 CPDF_ContentMarkItem::~CPDF_ContentMarkItem()
627 {
628 if (m_ParamType == DirectDict) {
629 ((CPDF_Dictionary*)m_pParam)->Release();
630 }
631 }
HasMCID() const632 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 }
CPDF_ContentMarkData(const CPDF_ContentMarkData & src)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 }
GetMCID() const645 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 }
AddMark(const CFX_ByteString & name,CPDF_Dictionary * pDict,FX_BOOL bDirect)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 }
DeleteLastMark()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 }
HasMark(FX_BSTR mark) const677 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 }
LookupMark(FX_BSTR mark,CPDF_Dictionary * & pDict) const690 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