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