Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(536)

Side by Side Diff: core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp

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

Powered by Google App Engine
This is Rietveld 408576698