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