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