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

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

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

Powered by Google App Engine
This is Rietveld 408576698