OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "../../../include/fpdfapi/fpdf_page.h" | 7 #include "../../../include/fpdfapi/fpdf_page.h" |
8 #include "../../../include/fpdfapi/fpdf_module.h" | 8 #include "../../../include/fpdfapi/fpdf_module.h" |
9 #include "../../../include/fxcodec/fx_codec.h" | 9 #include "../../../include/fxcodec/fx_codec.h" |
10 #include "pageint.h" | 10 #include "pageint.h" |
11 #include <limits.h> | 11 #include <limits.h> |
12 const FX_CHAR* const _PDF_OpCharType = | 12 const FX_CHAR* const _PDF_OpCharType = |
13 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" | 13 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" |
14 "IIVIIIIVIIVIIIIIVVIIIIIIIIIIIIII" | 14 "IIVIIIIVIIVIIIIIVVIIIIIIIIIIIIII" |
15 "IIVVVVVVIVVVVVVIVVVVVIIVVIIIIIII" | 15 "IIVVVVVVIVVVVVVIVVVVVIIVVIIIIIII" |
16 "IIVVVVVVVVVVVVVVIVVVIIVVIVVIIIII" | 16 "IIVVVVVVVVVVVVVVIVVVIIVVIVVIIIII" |
17 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" | 17 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" |
18 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" | 18 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" |
19 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" | 19 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" |
20 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII"; | 20 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII"; |
21 FX_BOOL _PDF_HasInvalidOpChar(const FX_CHAR* op) | 21 FX_BOOL _PDF_HasInvalidOpChar(const FX_CHAR* op) { |
22 { | 22 if (!op) { |
23 if(!op) { | |
24 return FALSE; | |
25 } | |
26 uint8_t ch; | |
27 while((ch = *op++)) { | |
28 if(_PDF_OpCharType[ch] == 'I') { | |
29 return TRUE; | |
30 } | |
31 } | |
32 return FALSE; | 23 return FALSE; |
| 24 } |
| 25 uint8_t ch; |
| 26 while ((ch = *op++)) { |
| 27 if (_PDF_OpCharType[ch] == 'I') { |
| 28 return TRUE; |
| 29 } |
| 30 } |
| 31 return FALSE; |
33 } | 32 } |
34 class CPDF_StreamParserAutoClearer { | 33 class CPDF_StreamParserAutoClearer { |
35 public: | 34 public: |
36 CPDF_StreamParserAutoClearer(CPDF_StreamParser** scoped_variable, CPDF_Strea
mParser* new_parser) | 35 CPDF_StreamParserAutoClearer(CPDF_StreamParser** scoped_variable, |
37 : scoped_variable_(scoped_variable) { | 36 CPDF_StreamParser* new_parser) |
38 *scoped_variable_ = new_parser; | 37 : scoped_variable_(scoped_variable) { |
39 } | 38 *scoped_variable_ = new_parser; |
40 ~CPDF_StreamParserAutoClearer() { *scoped_variable_ = NULL; } | 39 } |
41 private: | 40 ~CPDF_StreamParserAutoClearer() { *scoped_variable_ = NULL; } |
42 CPDF_StreamParser** scoped_variable_; | 41 |
| 42 private: |
| 43 CPDF_StreamParser** scoped_variable_; |
43 }; | 44 }; |
44 FX_DWORD CPDF_StreamContentParser::Parse(const uint8_t* pData, FX_DWORD dwSize,
FX_DWORD max_cost) | 45 FX_DWORD CPDF_StreamContentParser::Parse(const uint8_t* pData, |
45 { | 46 FX_DWORD dwSize, |
46 if (m_Level > _FPDF_MAX_FORM_LEVEL_) { | 47 FX_DWORD max_cost) { |
47 return dwSize; | 48 if (m_Level > _FPDF_MAX_FORM_LEVEL_) { |
48 } | 49 return dwSize; |
49 FX_DWORD InitObjCount = m_pObjectList->CountObjects(); | 50 } |
50 CPDF_StreamParser syntax(pData, dwSize); | 51 FX_DWORD InitObjCount = m_pObjectList->CountObjects(); |
51 CPDF_StreamParserAutoClearer auto_clearer(&m_pSyntax, &syntax); | 52 CPDF_StreamParser syntax(pData, dwSize); |
52 m_CompatCount = 0; | 53 CPDF_StreamParserAutoClearer auto_clearer(&m_pSyntax, &syntax); |
53 while (1) { | 54 m_CompatCount = 0; |
54 FX_DWORD cost = m_pObjectList->CountObjects() - InitObjCount; | 55 while (1) { |
55 if (max_cost && cost >= max_cost) { | 56 FX_DWORD cost = m_pObjectList->CountObjects() - InitObjCount; |
56 break; | 57 if (max_cost && cost >= max_cost) { |
57 } | 58 break; |
58 switch (syntax.ParseNextElement()) { | 59 } |
59 case CPDF_StreamParser::EndOfData: | 60 switch (syntax.ParseNextElement()) { |
60 return m_pSyntax->GetPos(); | 61 case CPDF_StreamParser::EndOfData: |
61 case CPDF_StreamParser::Keyword: | 62 return m_pSyntax->GetPos(); |
62 if(!OnOperator((char*)syntax.GetWordBuf()) && _PDF_HasInvalidOpC
har((char*)syntax.GetWordBuf())) { | 63 case CPDF_StreamParser::Keyword: |
63 m_bAbort = TRUE; | 64 if (!OnOperator((char*)syntax.GetWordBuf()) && |
64 } | 65 _PDF_HasInvalidOpChar((char*)syntax.GetWordBuf())) { |
65 if (m_bAbort) { | 66 m_bAbort = TRUE; |
66 return m_pSyntax->GetPos(); | 67 } |
67 } | 68 if (m_bAbort) { |
68 ClearAllParams(); | 69 return m_pSyntax->GetPos(); |
69 break; | 70 } |
70 case CPDF_StreamParser::Number: | 71 ClearAllParams(); |
71 AddNumberParam((char*)syntax.GetWordBuf(), syntax.GetWordSize())
; | 72 break; |
72 break; | 73 case CPDF_StreamParser::Number: |
73 case CPDF_StreamParser::Name: | 74 AddNumberParam((char*)syntax.GetWordBuf(), syntax.GetWordSize()); |
74 AddNameParam((const FX_CHAR*)syntax.GetWordBuf() + 1, syntax.Get
WordSize() - 1); | 75 break; |
75 break; | 76 case CPDF_StreamParser::Name: |
| 77 AddNameParam((const FX_CHAR*)syntax.GetWordBuf() + 1, |
| 78 syntax.GetWordSize() - 1); |
| 79 break; |
| 80 default: |
| 81 AddObjectParam(syntax.GetObject()); |
| 82 } |
| 83 } |
| 84 return m_pSyntax->GetPos(); |
| 85 } |
| 86 void _PDF_ReplaceAbbr(CPDF_Object* pObj); |
| 87 void CPDF_StreamContentParser::Handle_BeginImage() { |
| 88 FX_FILESIZE savePos = m_pSyntax->GetPos(); |
| 89 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); |
| 90 while (1) { |
| 91 CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); |
| 92 if (type == CPDF_StreamParser::Keyword) { |
| 93 CFX_ByteString bsKeyword(m_pSyntax->GetWordBuf(), |
| 94 m_pSyntax->GetWordSize()); |
| 95 if (bsKeyword != FX_BSTRC("ID")) { |
| 96 m_pSyntax->SetPos(savePos); |
| 97 pDict->Release(); |
| 98 return; |
| 99 } |
| 100 } |
| 101 if (type != CPDF_StreamParser::Name) { |
| 102 break; |
| 103 } |
| 104 CFX_ByteString key((const FX_CHAR*)m_pSyntax->GetWordBuf() + 1, |
| 105 m_pSyntax->GetWordSize() - 1); |
| 106 CPDF_Object* pObj = m_pSyntax->ReadNextObject(); |
| 107 if (!key.IsEmpty()) { |
| 108 pDict->SetAt(key, pObj, m_pDocument); |
| 109 } else if (pObj) { |
| 110 pObj->Release(); |
| 111 } |
| 112 } |
| 113 _PDF_ReplaceAbbr(pDict); |
| 114 CPDF_Object* pCSObj = NULL; |
| 115 if (pDict->KeyExist(FX_BSTRC("ColorSpace"))) { |
| 116 pCSObj = pDict->GetElementValue(FX_BSTRC("ColorSpace")); |
| 117 if (pCSObj->GetType() == PDFOBJ_NAME) { |
| 118 CFX_ByteString name = pCSObj->GetString(); |
| 119 if (name != FX_BSTRC("DeviceRGB") && name != FX_BSTRC("DeviceGray") && |
| 120 name != FX_BSTRC("DeviceCMYK")) { |
| 121 pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name); |
| 122 if (pCSObj && !pCSObj->GetObjNum()) { |
| 123 pCSObj = pCSObj->Clone(); |
| 124 pDict->SetAt(FX_BSTRC("ColorSpace"), pCSObj, m_pDocument); |
| 125 } |
| 126 } |
| 127 } |
| 128 } |
| 129 CPDF_Stream* pStream = m_pSyntax->ReadInlineStream( |
| 130 m_pDocument, pDict, pCSObj, m_Options.m_bDecodeInlineImage); |
| 131 while (1) { |
| 132 CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); |
| 133 if (type == CPDF_StreamParser::EndOfData) { |
| 134 break; |
| 135 } |
| 136 if (type != CPDF_StreamParser::Keyword) { |
| 137 continue; |
| 138 } |
| 139 if (m_pSyntax->GetWordSize() == 2 && m_pSyntax->GetWordBuf()[0] == 'E' && |
| 140 m_pSyntax->GetWordBuf()[1] == 'I') { |
| 141 break; |
| 142 } |
| 143 } |
| 144 if (m_Options.m_bTextOnly) { |
| 145 if (pStream) { |
| 146 pStream->Release(); |
| 147 } else { |
| 148 pDict->Release(); |
| 149 } |
| 150 return; |
| 151 } |
| 152 pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Image")); |
| 153 CPDF_ImageObject* pImgObj = AddImage(pStream, NULL, TRUE); |
| 154 if (!pImgObj) { |
| 155 if (pStream) { |
| 156 pStream->Release(); |
| 157 } else { |
| 158 pDict->Release(); |
| 159 } |
| 160 } |
| 161 } |
| 162 void CPDF_StreamContentParser::ParsePathObject() { |
| 163 FX_FLOAT params[6] = {}; |
| 164 int nParams = 0; |
| 165 int last_pos = m_pSyntax->GetPos(); |
| 166 while (1) { |
| 167 CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); |
| 168 FX_BOOL bProcessed = TRUE; |
| 169 switch (type) { |
| 170 case CPDF_StreamParser::EndOfData: |
| 171 return; |
| 172 case CPDF_StreamParser::Keyword: { |
| 173 int len = m_pSyntax->GetWordSize(); |
| 174 if (len == 1) { |
| 175 switch (m_pSyntax->GetWordBuf()[0]) { |
| 176 case 'm': |
| 177 AddPathPoint(params[0], params[1], FXPT_MOVETO); |
| 178 nParams = 0; |
| 179 break; |
| 180 case 'l': |
| 181 AddPathPoint(params[0], params[1], FXPT_LINETO); |
| 182 nParams = 0; |
| 183 break; |
| 184 case 'c': |
| 185 AddPathPoint(params[0], params[1], FXPT_BEZIERTO); |
| 186 AddPathPoint(params[2], params[3], FXPT_BEZIERTO); |
| 187 AddPathPoint(params[4], params[5], FXPT_BEZIERTO); |
| 188 nParams = 0; |
| 189 break; |
| 190 case 'v': |
| 191 AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_BEZIERTO); |
| 192 AddPathPoint(params[0], params[1], FXPT_BEZIERTO); |
| 193 AddPathPoint(params[2], params[3], FXPT_BEZIERTO); |
| 194 nParams = 0; |
| 195 break; |
| 196 case 'y': |
| 197 AddPathPoint(params[0], params[1], FXPT_BEZIERTO); |
| 198 AddPathPoint(params[2], params[3], FXPT_BEZIERTO); |
| 199 AddPathPoint(params[2], params[3], FXPT_BEZIERTO); |
| 200 nParams = 0; |
| 201 break; |
| 202 case 'h': |
| 203 Handle_ClosePath(); |
| 204 nParams = 0; |
| 205 break; |
76 default: | 206 default: |
77 AddObjectParam(syntax.GetObject()); | 207 bProcessed = FALSE; |
78 } | 208 break; |
79 } | 209 } |
80 return m_pSyntax->GetPos(); | 210 } else if (len == 2) { |
81 } | 211 if (m_pSyntax->GetWordBuf()[0] == 'r' && |
82 void _PDF_ReplaceAbbr(CPDF_Object* pObj); | 212 m_pSyntax->GetWordBuf()[1] == 'e') { |
83 void CPDF_StreamContentParser::Handle_BeginImage() | 213 AddPathRect(params[0], params[1], params[2], params[3]); |
84 { | 214 nParams = 0; |
85 FX_FILESIZE savePos = m_pSyntax->GetPos(); | 215 } else { |
86 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); | 216 bProcessed = FALSE; |
87 while (1) { | 217 } |
88 CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); | |
89 if (type == CPDF_StreamParser::Keyword) { | |
90 CFX_ByteString bsKeyword(m_pSyntax->GetWordBuf(), m_pSyntax->GetWord
Size()); | |
91 if (bsKeyword != FX_BSTRC("ID")) { | |
92 m_pSyntax->SetPos(savePos); | |
93 pDict->Release(); | |
94 return; | |
95 } | |
96 } | |
97 if (type != CPDF_StreamParser::Name) { | |
98 break; | |
99 } | |
100 CFX_ByteString key((const FX_CHAR*)m_pSyntax->GetWordBuf() + 1, m_pSynta
x->GetWordSize() - 1); | |
101 CPDF_Object* pObj = m_pSyntax->ReadNextObject(); | |
102 if (!key.IsEmpty()) { | |
103 pDict->SetAt(key, pObj, m_pDocument); | |
104 } else if (pObj) { | |
105 pObj->Release(); | |
106 } | |
107 } | |
108 _PDF_ReplaceAbbr(pDict); | |
109 CPDF_Object* pCSObj = NULL; | |
110 if (pDict->KeyExist(FX_BSTRC("ColorSpace"))) { | |
111 pCSObj = pDict->GetElementValue(FX_BSTRC("ColorSpace")); | |
112 if (pCSObj->GetType() == PDFOBJ_NAME) { | |
113 CFX_ByteString name = pCSObj->GetString(); | |
114 if (name != FX_BSTRC("DeviceRGB") && name != FX_BSTRC("DeviceGray")
&& name != FX_BSTRC("DeviceCMYK")) { | |
115 pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name); | |
116 if (pCSObj && !pCSObj->GetObjNum()) { | |
117 pCSObj = pCSObj->Clone(); | |
118 pDict->SetAt(FX_BSTRC("ColorSpace"), pCSObj, m_pDocument); | |
119 } | |
120 } | |
121 } | |
122 } | |
123 CPDF_Stream* pStream = m_pSyntax->ReadInlineStream(m_pDocument, pDict, pCSOb
j, m_Options.m_bDecodeInlineImage); | |
124 while (1) { | |
125 CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); | |
126 if (type == CPDF_StreamParser::EndOfData) { | |
127 break; | |
128 } | |
129 if (type != CPDF_StreamParser::Keyword) { | |
130 continue; | |
131 } | |
132 if (m_pSyntax->GetWordSize() == 2 && m_pSyntax->GetWordBuf()[0] == 'E' &
& | |
133 m_pSyntax->GetWordBuf()[1] == 'I') { | |
134 break; | |
135 } | |
136 } | |
137 if (m_Options.m_bTextOnly) { | |
138 if (pStream) { | |
139 pStream->Release(); | |
140 } else { | 218 } else { |
141 pDict->Release(); | 219 bProcessed = FALSE; |
142 } | 220 } |
143 return; | 221 if (bProcessed) { |
144 } | 222 last_pos = m_pSyntax->GetPos(); |
145 pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Image")); | 223 } |
146 CPDF_ImageObject *pImgObj = AddImage(pStream, NULL, TRUE); | 224 break; |
147 if (!pImgObj) { | 225 } |
148 if (pStream) { | 226 case CPDF_StreamParser::Number: { |
149 pStream->Release(); | 227 if (nParams == 6) { |
150 } else { | 228 break; |
151 pDict->Release(); | 229 } |
152 } | 230 FX_BOOL bInteger; |
153 } | 231 int value; |
154 } | 232 FX_atonum( |
155 void CPDF_StreamContentParser::ParsePathObject() | 233 CFX_ByteStringC(m_pSyntax->GetWordBuf(), m_pSyntax->GetWordSize()), |
156 { | 234 bInteger, &value); |
157 FX_FLOAT params[6] = {}; | 235 params[nParams++] = bInteger ? (FX_FLOAT)value : *(FX_FLOAT*)&value; |
158 int nParams = 0; | 236 break; |
159 int last_pos = m_pSyntax->GetPos(); | 237 } |
160 while (1) { | 238 default: |
161 CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); | 239 bProcessed = FALSE; |
162 FX_BOOL bProcessed = TRUE; | 240 } |
163 switch (type) { | 241 if (!bProcessed) { |
164 case CPDF_StreamParser::EndOfData: | 242 m_pSyntax->SetPos(last_pos); |
165 return; | 243 return; |
166 case CPDF_StreamParser::Keyword: { | 244 } |
167 int len = m_pSyntax->GetWordSize(); | 245 } |
168 if (len == 1) { | 246 } |
169 switch (m_pSyntax->GetWordBuf()[0]) { | 247 CPDF_StreamParser::CPDF_StreamParser(const uint8_t* pData, FX_DWORD dwSize) { |
170 case 'm': | 248 m_pBuf = pData; |
171 AddPathPoint(params[0], params[1], FXPT_MOVETO); | 249 m_Size = dwSize; |
172 nParams = 0; | 250 m_Pos = 0; |
173 break; | 251 m_pLastObj = NULL; |
174 case 'l': | 252 } |
175 AddPathPoint(params[0], params[1], FXPT_LINETO); | 253 CPDF_StreamParser::~CPDF_StreamParser() { |
176 nParams = 0; | 254 if (m_pLastObj) { |
177 break; | 255 m_pLastObj->Release(); |
178 case 'c': | 256 } |
179 AddPathPoint(params[0], params[1], FXPT_BEZIERTO
); | 257 } |
180 AddPathPoint(params[2], params[3], FXPT_BEZIERTO
); | 258 FX_DWORD _DecodeAllScanlines(ICodec_ScanlineDecoder* pDecoder, |
181 AddPathPoint(params[4], params[5], FXPT_BEZIERTO
); | 259 uint8_t*& dest_buf, |
182 nParams = 0; | 260 FX_DWORD& dest_size) { |
183 break; | 261 if (pDecoder == NULL) { |
184 case 'v': | 262 return (FX_DWORD)-1; |
185 AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXP
T_BEZIERTO); | 263 } |
186 AddPathPoint(params[0], params[1], FXPT_BEZIERTO
); | 264 int ncomps = pDecoder->CountComps(); |
187 AddPathPoint(params[2], params[3], FXPT_BEZIERTO
); | 265 int bpc = pDecoder->GetBPC(); |
188 nParams = 0; | 266 int width = pDecoder->GetWidth(); |
189 break; | 267 int height = pDecoder->GetHeight(); |
190 case 'y': | 268 int pitch = (width * ncomps * bpc + 7) / 8; |
191 AddPathPoint(params[0], params[1], FXPT_BEZIERTO
); | 269 if (height == 0 || pitch > (1 << 30) / height) { |
192 AddPathPoint(params[2], params[3], FXPT_BEZIERTO
); | |
193 AddPathPoint(params[2], params[3], FXPT_BEZIERTO
); | |
194 nParams = 0; | |
195 break; | |
196 case 'h': | |
197 Handle_ClosePath(); | |
198 nParams = 0; | |
199 break; | |
200 default: | |
201 bProcessed = FALSE; | |
202 break; | |
203 } | |
204 } else if (len == 2) { | |
205 if (m_pSyntax->GetWordBuf()[0] == 'r' && m_pSyntax->GetW
ordBuf()[1] == 'e') { | |
206 AddPathRect(params[0], params[1], params[2], params[
3]); | |
207 nParams = 0; | |
208 } else { | |
209 bProcessed = FALSE; | |
210 } | |
211 } else { | |
212 bProcessed = FALSE; | |
213 } | |
214 if (bProcessed) { | |
215 last_pos = m_pSyntax->GetPos(); | |
216 } | |
217 break; | |
218 } | |
219 case CPDF_StreamParser::Number: { | |
220 if (nParams == 6) { | |
221 break; | |
222 } | |
223 FX_BOOL bInteger; | |
224 int value; | |
225 FX_atonum(CFX_ByteStringC(m_pSyntax->GetWordBuf(), m_pSyntax
->GetWordSize()), bInteger, &value); | |
226 params[nParams++] = bInteger ? (FX_FLOAT)value : *(FX_FLOAT*
)&value; | |
227 break; | |
228 } | |
229 default: | |
230 bProcessed = FALSE; | |
231 } | |
232 if (!bProcessed) { | |
233 m_pSyntax->SetPos(last_pos); | |
234 return; | |
235 } | |
236 } | |
237 } | |
238 CPDF_StreamParser::CPDF_StreamParser(const uint8_t* pData, FX_DWORD dwSize) | |
239 { | |
240 m_pBuf = pData; | |
241 m_Size = dwSize; | |
242 m_Pos = 0; | |
243 m_pLastObj = NULL; | |
244 } | |
245 CPDF_StreamParser::~CPDF_StreamParser() | |
246 { | |
247 if (m_pLastObj) { | |
248 m_pLastObj->Release(); | |
249 } | |
250 } | |
251 FX_DWORD _DecodeAllScanlines(ICodec_ScanlineDecoder* pDecoder, uint8_t*& dest_bu
f, FX_DWORD& dest_size) | |
252 { | |
253 if (pDecoder == NULL) { | |
254 return (FX_DWORD) - 1; | |
255 } | |
256 int ncomps = pDecoder->CountComps(); | |
257 int bpc = pDecoder->GetBPC(); | |
258 int width = pDecoder->GetWidth(); | |
259 int height = pDecoder->GetHeight(); | |
260 int pitch = (width * ncomps * bpc + 7) / 8; | |
261 if (height == 0 || pitch > (1 << 30) / height) { | |
262 delete pDecoder; | |
263 return -1; | |
264 } | |
265 dest_buf = FX_Alloc2D(uint8_t, pitch, height); | |
266 dest_size = pitch * height; // Safe since checked alloc returned. | |
267 for (int row = 0; row < height; row ++) { | |
268 uint8_t* pLine = pDecoder->GetScanline(row); | |
269 if (pLine == NULL) { | |
270 break; | |
271 } | |
272 FXSYS_memcpy(dest_buf + row * pitch, pLine, pitch); | |
273 } | |
274 FX_DWORD srcoff = pDecoder->GetSrcOffset(); | |
275 delete pDecoder; | 270 delete pDecoder; |
276 return srcoff; | 271 return -1; |
277 } | 272 } |
278 ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder(const uint8_t* src_buf, FX_DWOR
D src_size, int width, int height, | 273 dest_buf = FX_Alloc2D(uint8_t, pitch, height); |
279 const CPDF_Dictionary* pParams); | 274 dest_size = pitch * height; // Safe since checked alloc returned. |
280 FX_DWORD _A85Decode(const uint8_t* src_buf, FX_DWORD src_size, uint8_t*& dest_bu
f, FX_DWORD& dest_size); | 275 for (int row = 0; row < height; row++) { |
281 FX_DWORD _HexDecode(const uint8_t* src_buf, FX_DWORD src_size, uint8_t*& dest_bu
f, FX_DWORD& dest_size); | 276 uint8_t* pLine = pDecoder->GetScanline(row); |
282 FX_DWORD FPDFAPI_FlateOrLZWDecode(FX_BOOL bLZW, const uint8_t* src_buf, FX_DWORD
src_size, CPDF_Dictionary* pParams, | 277 if (pLine == NULL) { |
283 FX_DWORD estimated_size, uint8_t*& dest_buf, F
X_DWORD& dest_size); | 278 break; |
284 FX_DWORD PDF_DecodeInlineStream(const uint8_t* src_buf, FX_DWORD limit, | 279 } |
285 int width, int height, CFX_ByteString& decoder, | 280 FXSYS_memcpy(dest_buf + row * pitch, pLine, pitch); |
286 CPDF_Dictionary* pParam, uint8_t*& dest_buf, FX_
DWORD& dest_size) | 281 } |
287 { | 282 FX_DWORD srcoff = pDecoder->GetSrcOffset(); |
288 if (decoder == FX_BSTRC("CCITTFaxDecode") || decoder == FX_BSTRC("CCF")) { | 283 delete pDecoder; |
289 ICodec_ScanlineDecoder* pDecoder = FPDFAPI_CreateFaxDecoder(src_buf, lim
it, width, height, pParam); | 284 return srcoff; |
290 return _DecodeAllScanlines(pDecoder, dest_buf, dest_size); | 285 } |
291 } | 286 ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder( |
292 if (decoder == FX_BSTRC("ASCII85Decode") || decoder == FX_BSTRC("A85")) { | 287 const uint8_t* src_buf, |
293 return _A85Decode(src_buf, limit, dest_buf, dest_size); | 288 FX_DWORD src_size, |
294 } | 289 int width, |
295 if (decoder == FX_BSTRC("ASCIIHexDecode") || decoder == FX_BSTRC("AHx")) { | 290 int height, |
296 return _HexDecode(src_buf, limit, dest_buf, dest_size); | 291 const CPDF_Dictionary* pParams); |
297 } | 292 FX_DWORD _A85Decode(const uint8_t* src_buf, |
298 if (decoder == FX_BSTRC("FlateDecode") || decoder == FX_BSTRC("Fl")) { | 293 FX_DWORD src_size, |
299 return FPDFAPI_FlateOrLZWDecode(FALSE, src_buf, limit, pParam, dest_size
, dest_buf, dest_size); | 294 uint8_t*& dest_buf, |
300 } | 295 FX_DWORD& dest_size); |
301 if (decoder == FX_BSTRC("LZWDecode") || decoder == FX_BSTRC("LZW")) { | 296 FX_DWORD _HexDecode(const uint8_t* src_buf, |
302 return FPDFAPI_FlateOrLZWDecode(TRUE, src_buf, limit, pParam, 0, dest_bu
f, dest_size); | 297 FX_DWORD src_size, |
303 } | 298 uint8_t*& dest_buf, |
304 if (decoder == FX_BSTRC("DCTDecode") || decoder == FX_BSTRC("DCT")) { | 299 FX_DWORD& dest_size); |
305 ICodec_ScanlineDecoder* pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule(
)->CreateDecoder( | 300 FX_DWORD FPDFAPI_FlateOrLZWDecode(FX_BOOL bLZW, |
306 src_buf, limit, width, height, 0, pParam ? pParam->GetInteger(FX_BST
RC("ColorTransform"), 1) : 1); | 301 const uint8_t* src_buf, |
307 return _DecodeAllScanlines(pDecoder, dest_buf, dest_size); | 302 FX_DWORD src_size, |
308 } | 303 CPDF_Dictionary* pParams, |
309 if (decoder == FX_BSTRC("RunLengthDecode") || decoder == FX_BSTRC("RL")) { | 304 FX_DWORD estimated_size, |
310 return RunLengthDecode(src_buf, limit, dest_buf, dest_size); | 305 uint8_t*& dest_buf, |
311 } | 306 FX_DWORD& dest_size); |
312 dest_size = 0; | 307 FX_DWORD PDF_DecodeInlineStream(const uint8_t* src_buf, |
313 dest_buf = 0; | 308 FX_DWORD limit, |
314 return (FX_DWORD) - 1; | 309 int width, |
315 } | 310 int height, |
316 CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc, CPDF_Dicti
onary* pDict, CPDF_Object* pCSObj, FX_BOOL bDecode) | 311 CFX_ByteString& decoder, |
317 { | 312 CPDF_Dictionary* pParam, |
318 if (m_Pos == m_Size) { | 313 uint8_t*& dest_buf, |
319 return NULL; | 314 FX_DWORD& dest_size) { |
320 } | 315 if (decoder == FX_BSTRC("CCITTFaxDecode") || decoder == FX_BSTRC("CCF")) { |
321 if (PDF_CharType[m_pBuf[m_Pos]] == 'W') { | 316 ICodec_ScanlineDecoder* pDecoder = |
322 m_Pos ++; | 317 FPDFAPI_CreateFaxDecoder(src_buf, limit, width, height, pParam); |
323 } | 318 return _DecodeAllScanlines(pDecoder, dest_buf, dest_size); |
324 CFX_ByteString Decoder; | 319 } |
325 CPDF_Dictionary* pParam = NULL; | 320 if (decoder == FX_BSTRC("ASCII85Decode") || decoder == FX_BSTRC("A85")) { |
326 CPDF_Object* pFilter = pDict->GetElementValue(FX_BSTRC("Filter")); | 321 return _A85Decode(src_buf, limit, dest_buf, dest_size); |
327 if (pFilter == NULL) { | 322 } |
328 } else if (pFilter->GetType() == PDFOBJ_ARRAY) { | 323 if (decoder == FX_BSTRC("ASCIIHexDecode") || decoder == FX_BSTRC("AHx")) { |
329 Decoder = ((CPDF_Array*)pFilter)->GetString(0); | 324 return _HexDecode(src_buf, limit, dest_buf, dest_size); |
| 325 } |
| 326 if (decoder == FX_BSTRC("FlateDecode") || decoder == FX_BSTRC("Fl")) { |
| 327 return FPDFAPI_FlateOrLZWDecode(FALSE, src_buf, limit, pParam, dest_size, |
| 328 dest_buf, dest_size); |
| 329 } |
| 330 if (decoder == FX_BSTRC("LZWDecode") || decoder == FX_BSTRC("LZW")) { |
| 331 return FPDFAPI_FlateOrLZWDecode(TRUE, src_buf, limit, pParam, 0, dest_buf, |
| 332 dest_size); |
| 333 } |
| 334 if (decoder == FX_BSTRC("DCTDecode") || decoder == FX_BSTRC("DCT")) { |
| 335 ICodec_ScanlineDecoder* pDecoder = |
| 336 CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder( |
| 337 src_buf, limit, width, height, 0, |
| 338 pParam ? pParam->GetInteger(FX_BSTRC("ColorTransform"), 1) : 1); |
| 339 return _DecodeAllScanlines(pDecoder, dest_buf, dest_size); |
| 340 } |
| 341 if (decoder == FX_BSTRC("RunLengthDecode") || decoder == FX_BSTRC("RL")) { |
| 342 return RunLengthDecode(src_buf, limit, dest_buf, dest_size); |
| 343 } |
| 344 dest_size = 0; |
| 345 dest_buf = 0; |
| 346 return (FX_DWORD)-1; |
| 347 } |
| 348 CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc, |
| 349 CPDF_Dictionary* pDict, |
| 350 CPDF_Object* pCSObj, |
| 351 FX_BOOL bDecode) { |
| 352 if (m_Pos == m_Size) { |
| 353 return NULL; |
| 354 } |
| 355 if (PDF_CharType[m_pBuf[m_Pos]] == 'W') { |
| 356 m_Pos++; |
| 357 } |
| 358 CFX_ByteString Decoder; |
| 359 CPDF_Dictionary* pParam = NULL; |
| 360 CPDF_Object* pFilter = pDict->GetElementValue(FX_BSTRC("Filter")); |
| 361 if (pFilter == NULL) { |
| 362 } else if (pFilter->GetType() == PDFOBJ_ARRAY) { |
| 363 Decoder = ((CPDF_Array*)pFilter)->GetString(0); |
| 364 CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms")); |
| 365 if (pParams) { |
| 366 pParam = pParams->GetDict(0); |
| 367 } |
| 368 } else { |
| 369 Decoder = pFilter->GetString(); |
| 370 pParam = pDict->GetDict(FX_BSTRC("DecodeParms")); |
| 371 } |
| 372 FX_DWORD width = pDict->GetInteger(FX_BSTRC("Width")); |
| 373 FX_DWORD height = pDict->GetInteger(FX_BSTRC("Height")); |
| 374 FX_DWORD OrigSize = 0; |
| 375 if (pCSObj != NULL) { |
| 376 FX_DWORD bpc = pDict->GetInteger(FX_BSTRC("BitsPerComponent")); |
| 377 FX_DWORD nComponents = 1; |
| 378 CPDF_ColorSpace* pCS = pDoc->LoadColorSpace(pCSObj); |
| 379 if (pCS == NULL) { |
| 380 nComponents = 3; |
| 381 } else { |
| 382 nComponents = pCS->CountComponents(); |
| 383 pDoc->GetPageData()->ReleaseColorSpace(pCSObj); |
| 384 } |
| 385 FX_DWORD pitch = width; |
| 386 if (bpc && pitch > INT_MAX / bpc) { |
| 387 return NULL; |
| 388 } |
| 389 pitch *= bpc; |
| 390 if (nComponents && pitch > INT_MAX / nComponents) { |
| 391 return NULL; |
| 392 } |
| 393 pitch *= nComponents; |
| 394 if (pitch > INT_MAX - 7) { |
| 395 return NULL; |
| 396 } |
| 397 pitch += 7; |
| 398 pitch /= 8; |
| 399 OrigSize = pitch; |
| 400 } else { |
| 401 if (width > INT_MAX - 7) { |
| 402 return NULL; |
| 403 } |
| 404 OrigSize = ((width + 7) / 8); |
| 405 } |
| 406 if (height && OrigSize > INT_MAX / height) { |
| 407 return NULL; |
| 408 } |
| 409 OrigSize *= height; |
| 410 uint8_t* pData = NULL; |
| 411 FX_DWORD dwStreamSize; |
| 412 if (Decoder.IsEmpty()) { |
| 413 if (OrigSize > m_Size - m_Pos) { |
| 414 OrigSize = m_Size - m_Pos; |
| 415 } |
| 416 pData = FX_Alloc(uint8_t, OrigSize); |
| 417 FXSYS_memcpy(pData, m_pBuf + m_Pos, OrigSize); |
| 418 dwStreamSize = OrigSize; |
| 419 m_Pos += OrigSize; |
| 420 } else { |
| 421 FX_DWORD dwDestSize = OrigSize; |
| 422 dwStreamSize = |
| 423 PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, width, height, |
| 424 Decoder, pParam, pData, dwDestSize); |
| 425 if ((int)dwStreamSize < 0) { |
| 426 return NULL; |
| 427 } |
| 428 if (bDecode) { |
| 429 m_Pos += dwStreamSize; |
| 430 dwStreamSize = dwDestSize; |
| 431 if (pFilter->GetType() == PDFOBJ_ARRAY) { |
| 432 ((CPDF_Array*)pFilter)->RemoveAt(0); |
330 CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms")); | 433 CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms")); |
331 if (pParams) { | 434 if (pParams) { |
332 pParam = pParams->GetDict(0); | 435 pParams->RemoveAt(0); |
333 } | 436 } |
| 437 } else { |
| 438 pDict->RemoveAt(FX_BSTRC("Filter")); |
| 439 pDict->RemoveAt(FX_BSTRC("DecodeParms")); |
| 440 } |
334 } else { | 441 } else { |
335 Decoder = pFilter->GetString(); | 442 if (pData) { |
336 pParam = pDict->GetDict(FX_BSTRC("DecodeParms")); | 443 FX_Free(pData); |
337 } | 444 } |
338 FX_DWORD width = pDict->GetInteger(FX_BSTRC("Width")); | 445 FX_DWORD dwSavePos = m_Pos; |
339 FX_DWORD height = pDict->GetInteger(FX_BSTRC("Height")); | 446 m_Pos += dwStreamSize; |
340 FX_DWORD OrigSize = 0; | 447 while (1) { |
341 if (pCSObj != NULL) { | 448 FX_DWORD dwPrevPos = m_Pos; |
342 FX_DWORD bpc = pDict->GetInteger(FX_BSTRC("BitsPerComponent")); | 449 CPDF_StreamParser::SyntaxType type = ParseNextElement(); |
343 FX_DWORD nComponents = 1; | 450 if (type == CPDF_StreamParser::EndOfData) { |
344 CPDF_ColorSpace* pCS = pDoc->LoadColorSpace(pCSObj); | 451 break; |
345 if (pCS == NULL) { | 452 } |
346 nComponents = 3; | 453 if (type != CPDF_StreamParser::Keyword) { |
347 } else { | 454 dwStreamSize += m_Pos - dwPrevPos; |
348 nComponents = pCS->CountComponents(); | 455 continue; |
349 pDoc->GetPageData()->ReleaseColorSpace(pCSObj); | 456 } |
350 } | 457 if (GetWordSize() == 2 && GetWordBuf()[0] == 'E' && |
351 FX_DWORD pitch = width; | 458 GetWordBuf()[1] == 'I') { |
352 if (bpc && pitch > INT_MAX / bpc) { | 459 m_Pos = dwPrevPos; |
353 return NULL; | 460 break; |
354 } | 461 } |
355 pitch *= bpc; | 462 dwStreamSize += m_Pos - dwPrevPos; |
356 if (nComponents && pitch > INT_MAX / nComponents) { | 463 } |
357 return NULL; | 464 m_Pos = dwSavePos; |
358 } | 465 pData = FX_Alloc(uint8_t, dwStreamSize); |
359 pitch *= nComponents; | 466 FXSYS_memcpy(pData, m_pBuf + m_Pos, dwStreamSize); |
360 if (pitch > INT_MAX - 7) { | 467 m_Pos += dwStreamSize; |
361 return NULL; | 468 } |
362 } | 469 } |
363 pitch += 7; | 470 pDict->SetAtInteger(FX_BSTRC("Length"), (int)dwStreamSize); |
364 pitch /= 8; | 471 return CPDF_Stream::Create(pData, dwStreamSize, pDict); |
365 OrigSize = pitch; | |
366 } else { | |
367 if (width > INT_MAX - 7) { | |
368 return NULL; | |
369 } | |
370 OrigSize = ((width + 7) / 8); | |
371 } | |
372 if (height && OrigSize > INT_MAX / height) { | |
373 return NULL; | |
374 } | |
375 OrigSize *= height; | |
376 uint8_t* pData = NULL; | |
377 FX_DWORD dwStreamSize; | |
378 if (Decoder.IsEmpty()) { | |
379 if (OrigSize > m_Size - m_Pos) { | |
380 OrigSize = m_Size - m_Pos; | |
381 } | |
382 pData = FX_Alloc(uint8_t, OrigSize); | |
383 FXSYS_memcpy(pData, m_pBuf + m_Pos, OrigSize); | |
384 dwStreamSize = OrigSize; | |
385 m_Pos += OrigSize; | |
386 } else { | |
387 FX_DWORD dwDestSize = OrigSize; | |
388 dwStreamSize = PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, wi
dth, height, Decoder, pParam, | |
389 pData, dwDestSize); | |
390 if ((int)dwStreamSize < 0) { | |
391 return NULL; | |
392 } | |
393 if (bDecode) { | |
394 m_Pos += dwStreamSize; | |
395 dwStreamSize = dwDestSize; | |
396 if (pFilter->GetType() == PDFOBJ_ARRAY) { | |
397 ((CPDF_Array*)pFilter)->RemoveAt(0); | |
398 CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms")); | |
399 if (pParams) { | |
400 pParams->RemoveAt(0); | |
401 } | |
402 } else { | |
403 pDict->RemoveAt(FX_BSTRC("Filter")); | |
404 pDict->RemoveAt(FX_BSTRC("DecodeParms")); | |
405 } | |
406 } else { | |
407 if (pData) { | |
408 FX_Free(pData); | |
409 } | |
410 FX_DWORD dwSavePos = m_Pos; | |
411 m_Pos += dwStreamSize; | |
412 while (1) { | |
413 FX_DWORD dwPrevPos = m_Pos; | |
414 CPDF_StreamParser::SyntaxType type = ParseNextElement(); | |
415 if (type == CPDF_StreamParser::EndOfData) { | |
416 break; | |
417 } | |
418 if (type != CPDF_StreamParser::Keyword) { | |
419 dwStreamSize += m_Pos - dwPrevPos; | |
420 continue; | |
421 } | |
422 if (GetWordSize() == 2 && GetWordBuf()[0] == 'E' && | |
423 GetWordBuf()[1] == 'I') { | |
424 m_Pos = dwPrevPos; | |
425 break; | |
426 } | |
427 dwStreamSize += m_Pos - dwPrevPos; | |
428 } | |
429 m_Pos = dwSavePos; | |
430 pData = FX_Alloc(uint8_t, dwStreamSize); | |
431 FXSYS_memcpy(pData, m_pBuf + m_Pos, dwStreamSize); | |
432 m_Pos += dwStreamSize; | |
433 } | |
434 } | |
435 pDict->SetAtInteger(FX_BSTRC("Length"), (int)dwStreamSize); | |
436 return CPDF_Stream::Create(pData, dwStreamSize, pDict); | |
437 } | 472 } |
438 #define MAX_WORD_BUFFER 256 | 473 #define MAX_WORD_BUFFER 256 |
439 #define MAX_STRING_LENGTH» 32767 | 474 #define MAX_STRING_LENGTH 32767 |
440 #define FXDWORD_TRUE FXDWORD_FROM_LSBFIRST(0x65757274) | 475 #define FXDWORD_TRUE FXDWORD_FROM_LSBFIRST(0x65757274) |
441 #define FXDWORD_NULL FXDWORD_FROM_LSBFIRST(0x6c6c756e) | 476 #define FXDWORD_NULL FXDWORD_FROM_LSBFIRST(0x6c6c756e) |
442 #define FXDWORD_FALS FXDWORD_FROM_LSBFIRST(0x736c6166) | 477 #define FXDWORD_FALS FXDWORD_FROM_LSBFIRST(0x736c6166) |
443 CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() | 478 CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() { |
444 { | 479 if (m_pLastObj) { |
445 if (m_pLastObj) { | 480 m_pLastObj->Release(); |
446 m_pLastObj->Release(); | 481 m_pLastObj = NULL; |
447 m_pLastObj = NULL; | 482 } |
448 } | 483 m_WordSize = 0; |
449 m_WordSize = 0; | 484 FX_BOOL bIsNumber = TRUE; |
450 FX_BOOL bIsNumber = TRUE; | 485 if (m_Pos >= m_Size) { |
451 if (m_Pos >= m_Size) { | 486 return EndOfData; |
| 487 } |
| 488 int ch = m_pBuf[m_Pos++]; |
| 489 int type = PDF_CharType[ch]; |
| 490 while (1) { |
| 491 while (type == 'W') { |
| 492 if (m_Size <= m_Pos) { |
452 return EndOfData; | 493 return EndOfData; |
453 } | 494 } |
454 int ch = m_pBuf[m_Pos++]; | 495 ch = m_pBuf[m_Pos++]; |
455 int type = PDF_CharType[ch]; | 496 type = PDF_CharType[ch]; |
| 497 } |
| 498 if (ch != '%') { |
| 499 break; |
| 500 } |
456 while (1) { | 501 while (1) { |
457 while (type == 'W') { | 502 if (m_Size <= m_Pos) { |
458 if (m_Size <= m_Pos) { | 503 return EndOfData; |
459 return EndOfData; | 504 } |
460 } | 505 ch = m_pBuf[m_Pos++]; |
461 ch = m_pBuf[m_Pos++]; | 506 if (ch == '\r' || ch == '\n') { |
462 type = PDF_CharType[ch]; | 507 break; |
463 } | 508 } |
464 if (ch != '%') { | 509 } |
465 break; | 510 type = PDF_CharType[ch]; |
466 } | 511 } |
467 while (1) { | 512 if (type == 'D' && ch != '/') { |
468 if (m_Size <= m_Pos) { | 513 m_Pos--; |
469 return EndOfData; | 514 m_pLastObj = ReadNextObject(); |
470 } | 515 return Others; |
471 ch = m_pBuf[m_Pos++]; | 516 } |
472 if (ch == '\r' || ch == '\n') { | 517 while (1) { |
473 break; | 518 if (m_WordSize < MAX_WORD_BUFFER) { |
474 } | 519 m_WordBuffer[m_WordSize++] = ch; |
475 } | 520 } |
476 type = PDF_CharType[ch]; | 521 if (type != 'N') { |
477 } | 522 bIsNumber = FALSE; |
478 if (type == 'D' && ch != '/') { | 523 } |
479 m_Pos --; | 524 if (m_Size <= m_Pos) { |
480 m_pLastObj = ReadNextObject(); | 525 break; |
481 return Others; | 526 } |
| 527 ch = m_pBuf[m_Pos++]; |
| 528 type = PDF_CharType[ch]; |
| 529 if (type == 'D' || type == 'W') { |
| 530 m_Pos--; |
| 531 break; |
| 532 } |
| 533 } |
| 534 m_WordBuffer[m_WordSize] = 0; |
| 535 if (bIsNumber) { |
| 536 return Number; |
| 537 } |
| 538 if (m_WordBuffer[0] == '/') { |
| 539 return Name; |
| 540 } |
| 541 if (m_WordSize == 4) { |
| 542 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) { |
| 543 m_pLastObj = CPDF_Boolean::Create(TRUE); |
| 544 return Others; |
| 545 } |
| 546 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) { |
| 547 m_pLastObj = CPDF_Null::Create(); |
| 548 return Others; |
| 549 } |
| 550 } else if (m_WordSize == 5) { |
| 551 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e') { |
| 552 m_pLastObj = CPDF_Boolean::Create(FALSE); |
| 553 return Others; |
| 554 } |
| 555 } |
| 556 return Keyword; |
| 557 } |
| 558 void CPDF_StreamParser::SkipPathObject() { |
| 559 FX_DWORD command_startpos = m_Pos; |
| 560 if (m_Pos >= m_Size) { |
| 561 return; |
| 562 } |
| 563 int ch = m_pBuf[m_Pos++]; |
| 564 int type = PDF_CharType[ch]; |
| 565 while (1) { |
| 566 while (type == 'W') { |
| 567 if (m_Pos >= m_Size) { |
| 568 return; |
| 569 } |
| 570 ch = m_pBuf[m_Pos++]; |
| 571 type = PDF_CharType[ch]; |
| 572 } |
| 573 if (type != 'N') { |
| 574 m_Pos = command_startpos; |
| 575 return; |
482 } | 576 } |
483 while (1) { | 577 while (1) { |
484 if (m_WordSize < MAX_WORD_BUFFER) { | 578 while (type != 'W') { |
485 m_WordBuffer[m_WordSize++] = ch; | 579 if (m_Pos >= m_Size) { |
486 } | 580 return; |
487 if (type != 'N') { | |
488 bIsNumber = FALSE; | |
489 } | |
490 if (m_Size <= m_Pos) { | |
491 break; | |
492 } | 581 } |
493 ch = m_pBuf[m_Pos++]; | 582 ch = m_pBuf[m_Pos++]; |
494 type = PDF_CharType[ch]; | 583 type = PDF_CharType[ch]; |
495 if (type == 'D' || type == 'W') { | 584 } |
496 m_Pos --; | 585 while (type == 'W') { |
497 break; | 586 if (m_Pos >= m_Size) { |
498 } | 587 return; |
499 } | |
500 m_WordBuffer[m_WordSize] = 0; | |
501 if (bIsNumber) { | |
502 return Number; | |
503 } | |
504 if (m_WordBuffer[0] == '/') { | |
505 return Name; | |
506 } | |
507 if (m_WordSize == 4) { | |
508 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) { | |
509 m_pLastObj = CPDF_Boolean::Create(TRUE); | |
510 return Others; | |
511 } | |
512 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) { | |
513 m_pLastObj = CPDF_Null::Create(); | |
514 return Others; | |
515 } | |
516 } else if (m_WordSize == 5) { | |
517 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e')
{ | |
518 m_pLastObj = CPDF_Boolean::Create(FALSE); | |
519 return Others; | |
520 } | |
521 } | |
522 return Keyword; | |
523 } | |
524 void CPDF_StreamParser::SkipPathObject() | |
525 { | |
526 FX_DWORD command_startpos = m_Pos; | |
527 if (m_Pos >= m_Size) { | |
528 return; | |
529 } | |
530 int ch = m_pBuf[m_Pos++]; | |
531 int type = PDF_CharType[ch]; | |
532 while (1) { | |
533 while (type == 'W') { | |
534 if (m_Pos >= m_Size) { | |
535 return; | |
536 } | |
537 ch = m_pBuf[m_Pos++]; | |
538 type = PDF_CharType[ch]; | |
539 } | |
540 if (type != 'N') { | |
541 m_Pos = command_startpos; | |
542 return; | |
543 } | |
544 while (1) { | |
545 while (type != 'W') { | |
546 if (m_Pos >= m_Size) { | |
547 return; | |
548 } | |
549 ch = m_pBuf[m_Pos++]; | |
550 type = PDF_CharType[ch]; | |
551 } | |
552 while (type == 'W') { | |
553 if (m_Pos >= m_Size) { | |
554 return; | |
555 } | |
556 ch = m_pBuf[m_Pos++]; | |
557 type = PDF_CharType[ch]; | |
558 } | |
559 if (type == 'N') { | |
560 continue; | |
561 } | |
562 FX_DWORD op_startpos = m_Pos - 1; | |
563 while (type != 'W' && type != 'D') { | |
564 if (m_Pos >= m_Size) { | |
565 return; | |
566 } | |
567 ch = m_pBuf[m_Pos++]; | |
568 type = PDF_CharType[ch]; | |
569 } | |
570 if (m_Pos - op_startpos == 2) { | |
571 int op = m_pBuf[op_startpos]; | |
572 if (op == 'm' || op == 'l' || op == 'c' || op == 'v' || op == 'y
') { | |
573 command_startpos = m_Pos; | |
574 break; | |
575 } | |
576 } else if (m_Pos - op_startpos == 3) { | |
577 if (m_pBuf[op_startpos] == 'r' && m_pBuf[op_startpos + 1] == 'e'
) { | |
578 command_startpos = m_Pos; | |
579 break; | |
580 } | |
581 } | |
582 m_Pos = command_startpos; | |
583 return; | |
584 } | |
585 } | |
586 } | |
587 CPDF_Object* CPDF_StreamParser::ReadNextObject(FX_BOOL bAllowNestedArray, FX_BOO
L bInArray) | |
588 { | |
589 FX_BOOL bIsNumber; | |
590 GetNextWord(bIsNumber); | |
591 if (m_WordSize == 0) { | |
592 return NULL; | |
593 } | |
594 if (bIsNumber) { | |
595 m_WordBuffer[m_WordSize] = 0; | |
596 return CPDF_Number::Create(CFX_ByteStringC(m_WordBuffer, m_WordSize)); | |
597 } | |
598 int first_char = m_WordBuffer[0]; | |
599 if (first_char == '/') { | |
600 return CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1
, m_WordSize - 1))); | |
601 } | |
602 if (first_char == '(') { | |
603 return CPDF_String::Create(ReadString()); | |
604 } | |
605 if (first_char == '<') { | |
606 if (m_WordSize == 1) { | |
607 return CPDF_String::Create(ReadHexString(), TRUE); | |
608 } | |
609 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); | |
610 while (1) { | |
611 GetNextWord(bIsNumber); | |
612 if (m_WordSize == 0) { | |
613 pDict->Release(); | |
614 return NULL; | |
615 } | |
616 if (m_WordSize == 2 && m_WordBuffer[0] == '>') { | |
617 break; | |
618 } | |
619 if (m_WordBuffer[0] != '/') { | |
620 pDict->Release(); | |
621 return NULL; | |
622 } | |
623 CFX_ByteString key = PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1
, m_WordSize - 1)); | |
624 CPDF_Object* pObj = ReadNextObject(TRUE); | |
625 if (pObj == NULL) { | |
626 if (pDict) { | |
627 pDict->Release(); | |
628 } | |
629 return NULL; | |
630 } | |
631 if (!key.IsEmpty()) { | |
632 pDict->SetAt(key, pObj); | |
633 } else { | |
634 pObj->Release(); | |
635 } | |
636 } | |
637 return pDict; | |
638 } | |
639 if (first_char == '[') { | |
640 if (!bAllowNestedArray && bInArray) { | |
641 return NULL; | |
642 } | |
643 CPDF_Array* pArray = CPDF_Array::Create(); | |
644 while (1) { | |
645 CPDF_Object* pObj = ReadNextObject(bAllowNestedArray, TRUE); | |
646 if (pObj == NULL) { | |
647 if (m_WordSize == 0 || m_WordBuffer[0] == ']') { | |
648 return pArray; | |
649 } | |
650 if (m_WordBuffer[0] == '[') { | |
651 continue; | |
652 } | |
653 } else { | |
654 pArray->Add(pObj); | |
655 } | |
656 } | |
657 } | |
658 if (m_WordSize == 4) { | |
659 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) { | |
660 return CPDF_Boolean::Create(TRUE); | |
661 } | |
662 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) { | |
663 return CPDF_Null::Create(); | |
664 } | |
665 } else if (m_WordSize == 5) { | |
666 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e')
{ | |
667 return CPDF_Boolean::Create(FALSE); | |
668 } | |
669 } | |
670 return NULL; | |
671 } | |
672 void CPDF_StreamParser::GetNextWord(FX_BOOL& bIsNumber) | |
673 { | |
674 m_WordSize = 0; | |
675 bIsNumber = TRUE; | |
676 if (m_Size <= m_Pos) { | |
677 return; | |
678 } | |
679 int ch = m_pBuf[m_Pos++]; | |
680 int type = PDF_CharType[ch]; | |
681 while (1) { | |
682 while (type == 'W') { | |
683 if (m_Size <= m_Pos) { | |
684 return; | |
685 } | |
686 ch = m_pBuf[m_Pos++]; | |
687 type = PDF_CharType[ch]; | |
688 } | |
689 if (ch != '%') { | |
690 break; | |
691 } | |
692 while (1) { | |
693 if (m_Size <= m_Pos) { | |
694 return; | |
695 } | |
696 ch = m_pBuf[m_Pos++]; | |
697 if (ch == '\r' || ch == '\n') { | |
698 break; | |
699 } | |
700 } | |
701 type = PDF_CharType[ch]; | |
702 } | |
703 if (type == 'D') { | |
704 bIsNumber = FALSE; | |
705 m_WordBuffer[m_WordSize++] = ch; | |
706 if (ch == '/') { | |
707 while (1) { | |
708 if (m_Size <= m_Pos) { | |
709 return; | |
710 } | |
711 ch = m_pBuf[m_Pos++]; | |
712 type = PDF_CharType[ch]; | |
713 if (type != 'R' && type != 'N') { | |
714 m_Pos --; | |
715 return; | |
716 } | |
717 if (m_WordSize < MAX_WORD_BUFFER) { | |
718 m_WordBuffer[m_WordSize++] = ch; | |
719 } | |
720 } | |
721 } else if (ch == '<') { | |
722 if (m_Size <= m_Pos) { | |
723 return; | |
724 } | |
725 ch = m_pBuf[m_Pos++]; | |
726 if (ch == '<') { | |
727 m_WordBuffer[m_WordSize++] = ch; | |
728 } else { | |
729 m_Pos --; | |
730 } | |
731 } else if (ch == '>') { | |
732 if (m_Size <= m_Pos) { | |
733 return; | |
734 } | |
735 ch = m_pBuf[m_Pos++]; | |
736 if (ch == '>') { | |
737 m_WordBuffer[m_WordSize++] = ch; | |
738 } else { | |
739 m_Pos --; | |
740 } | |
741 } | |
742 return; | |
743 } | |
744 while (1) { | |
745 if (m_WordSize < MAX_WORD_BUFFER) { | |
746 m_WordBuffer[m_WordSize++] = ch; | |
747 } | |
748 if (type != 'N') { | |
749 bIsNumber = FALSE; | |
750 } | |
751 if (m_Size <= m_Pos) { | |
752 return; | |
753 } | 588 } |
754 ch = m_pBuf[m_Pos++]; | 589 ch = m_pBuf[m_Pos++]; |
755 type = PDF_CharType[ch]; | 590 type = PDF_CharType[ch]; |
756 if (type == 'D' || type == 'W') { | 591 } |
757 m_Pos --; | 592 if (type == 'N') { |
758 break; | 593 continue; |
759 } | 594 } |
760 } | 595 FX_DWORD op_startpos = m_Pos - 1; |
761 } | 596 while (type != 'W' && type != 'D') { |
762 CFX_ByteString CPDF_StreamParser::ReadString() | 597 if (m_Pos >= m_Size) { |
763 { | 598 return; |
| 599 } |
| 600 ch = m_pBuf[m_Pos++]; |
| 601 type = PDF_CharType[ch]; |
| 602 } |
| 603 if (m_Pos - op_startpos == 2) { |
| 604 int op = m_pBuf[op_startpos]; |
| 605 if (op == 'm' || op == 'l' || op == 'c' || op == 'v' || op == 'y') { |
| 606 command_startpos = m_Pos; |
| 607 break; |
| 608 } |
| 609 } else if (m_Pos - op_startpos == 3) { |
| 610 if (m_pBuf[op_startpos] == 'r' && m_pBuf[op_startpos + 1] == 'e') { |
| 611 command_startpos = m_Pos; |
| 612 break; |
| 613 } |
| 614 } |
| 615 m_Pos = command_startpos; |
| 616 return; |
| 617 } |
| 618 } |
| 619 } |
| 620 CPDF_Object* CPDF_StreamParser::ReadNextObject(FX_BOOL bAllowNestedArray, |
| 621 FX_BOOL bInArray) { |
| 622 FX_BOOL bIsNumber; |
| 623 GetNextWord(bIsNumber); |
| 624 if (m_WordSize == 0) { |
| 625 return NULL; |
| 626 } |
| 627 if (bIsNumber) { |
| 628 m_WordBuffer[m_WordSize] = 0; |
| 629 return CPDF_Number::Create(CFX_ByteStringC(m_WordBuffer, m_WordSize)); |
| 630 } |
| 631 int first_char = m_WordBuffer[0]; |
| 632 if (first_char == '/') { |
| 633 return CPDF_Name::Create( |
| 634 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); |
| 635 } |
| 636 if (first_char == '(') { |
| 637 return CPDF_String::Create(ReadString()); |
| 638 } |
| 639 if (first_char == '<') { |
| 640 if (m_WordSize == 1) { |
| 641 return CPDF_String::Create(ReadHexString(), TRUE); |
| 642 } |
| 643 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); |
| 644 while (1) { |
| 645 GetNextWord(bIsNumber); |
| 646 if (m_WordSize == 0) { |
| 647 pDict->Release(); |
| 648 return NULL; |
| 649 } |
| 650 if (m_WordSize == 2 && m_WordBuffer[0] == '>') { |
| 651 break; |
| 652 } |
| 653 if (m_WordBuffer[0] != '/') { |
| 654 pDict->Release(); |
| 655 return NULL; |
| 656 } |
| 657 CFX_ByteString key = |
| 658 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)); |
| 659 CPDF_Object* pObj = ReadNextObject(TRUE); |
| 660 if (pObj == NULL) { |
| 661 if (pDict) { |
| 662 pDict->Release(); |
| 663 } |
| 664 return NULL; |
| 665 } |
| 666 if (!key.IsEmpty()) { |
| 667 pDict->SetAt(key, pObj); |
| 668 } else { |
| 669 pObj->Release(); |
| 670 } |
| 671 } |
| 672 return pDict; |
| 673 } |
| 674 if (first_char == '[') { |
| 675 if (!bAllowNestedArray && bInArray) { |
| 676 return NULL; |
| 677 } |
| 678 CPDF_Array* pArray = CPDF_Array::Create(); |
| 679 while (1) { |
| 680 CPDF_Object* pObj = ReadNextObject(bAllowNestedArray, TRUE); |
| 681 if (pObj == NULL) { |
| 682 if (m_WordSize == 0 || m_WordBuffer[0] == ']') { |
| 683 return pArray; |
| 684 } |
| 685 if (m_WordBuffer[0] == '[') { |
| 686 continue; |
| 687 } |
| 688 } else { |
| 689 pArray->Add(pObj); |
| 690 } |
| 691 } |
| 692 } |
| 693 if (m_WordSize == 4) { |
| 694 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) { |
| 695 return CPDF_Boolean::Create(TRUE); |
| 696 } |
| 697 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) { |
| 698 return CPDF_Null::Create(); |
| 699 } |
| 700 } else if (m_WordSize == 5) { |
| 701 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e') { |
| 702 return CPDF_Boolean::Create(FALSE); |
| 703 } |
| 704 } |
| 705 return NULL; |
| 706 } |
| 707 void CPDF_StreamParser::GetNextWord(FX_BOOL& bIsNumber) { |
| 708 m_WordSize = 0; |
| 709 bIsNumber = TRUE; |
| 710 if (m_Size <= m_Pos) { |
| 711 return; |
| 712 } |
| 713 int ch = m_pBuf[m_Pos++]; |
| 714 int type = PDF_CharType[ch]; |
| 715 while (1) { |
| 716 while (type == 'W') { |
| 717 if (m_Size <= m_Pos) { |
| 718 return; |
| 719 } |
| 720 ch = m_pBuf[m_Pos++]; |
| 721 type = PDF_CharType[ch]; |
| 722 } |
| 723 if (ch != '%') { |
| 724 break; |
| 725 } |
| 726 while (1) { |
| 727 if (m_Size <= m_Pos) { |
| 728 return; |
| 729 } |
| 730 ch = m_pBuf[m_Pos++]; |
| 731 if (ch == '\r' || ch == '\n') { |
| 732 break; |
| 733 } |
| 734 } |
| 735 type = PDF_CharType[ch]; |
| 736 } |
| 737 if (type == 'D') { |
| 738 bIsNumber = FALSE; |
| 739 m_WordBuffer[m_WordSize++] = ch; |
| 740 if (ch == '/') { |
| 741 while (1) { |
| 742 if (m_Size <= m_Pos) { |
| 743 return; |
| 744 } |
| 745 ch = m_pBuf[m_Pos++]; |
| 746 type = PDF_CharType[ch]; |
| 747 if (type != 'R' && type != 'N') { |
| 748 m_Pos--; |
| 749 return; |
| 750 } |
| 751 if (m_WordSize < MAX_WORD_BUFFER) { |
| 752 m_WordBuffer[m_WordSize++] = ch; |
| 753 } |
| 754 } |
| 755 } else if (ch == '<') { |
| 756 if (m_Size <= m_Pos) { |
| 757 return; |
| 758 } |
| 759 ch = m_pBuf[m_Pos++]; |
| 760 if (ch == '<') { |
| 761 m_WordBuffer[m_WordSize++] = ch; |
| 762 } else { |
| 763 m_Pos--; |
| 764 } |
| 765 } else if (ch == '>') { |
| 766 if (m_Size <= m_Pos) { |
| 767 return; |
| 768 } |
| 769 ch = m_pBuf[m_Pos++]; |
| 770 if (ch == '>') { |
| 771 m_WordBuffer[m_WordSize++] = ch; |
| 772 } else { |
| 773 m_Pos--; |
| 774 } |
| 775 } |
| 776 return; |
| 777 } |
| 778 while (1) { |
| 779 if (m_WordSize < MAX_WORD_BUFFER) { |
| 780 m_WordBuffer[m_WordSize++] = ch; |
| 781 } |
| 782 if (type != 'N') { |
| 783 bIsNumber = FALSE; |
| 784 } |
764 if (m_Size <= m_Pos) { | 785 if (m_Size <= m_Pos) { |
765 return CFX_ByteString(); | 786 return; |
766 } | 787 } |
767 int ch = m_pBuf[m_Pos++]; | 788 ch = m_pBuf[m_Pos++]; |
768 CFX_ByteTextBuf buf; | 789 type = PDF_CharType[ch]; |
769 int parlevel = 0; | 790 if (type == 'D' || type == 'W') { |
770 int status = 0, iEscCode = 0; | 791 m_Pos--; |
771 while (1) { | 792 break; |
772 switch (status) { | 793 } |
773 case 0: | 794 } |
774 if (ch == ')') { | 795 } |
775 if (parlevel == 0) { | 796 CFX_ByteString CPDF_StreamParser::ReadString() { |
776 if (buf.GetLength() > MAX_STRING_LENGTH) { | 797 if (m_Size <= m_Pos) { |
777 return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LE
NGTH); | 798 return CFX_ByteString(); |
778 } | 799 } |
779 return buf.GetByteString(); | 800 int ch = m_pBuf[m_Pos++]; |
780 } | 801 CFX_ByteTextBuf buf; |
781 parlevel --; | 802 int parlevel = 0; |
782 buf.AppendChar(')'); | 803 int status = 0, iEscCode = 0; |
783 } else if (ch == '(') { | 804 while (1) { |
784 parlevel ++; | 805 switch (status) { |
785 buf.AppendChar('('); | 806 case 0: |
786 } else if (ch == '\\') { | 807 if (ch == ')') { |
787 status = 1; | 808 if (parlevel == 0) { |
788 } else { | 809 if (buf.GetLength() > MAX_STRING_LENGTH) { |
789 buf.AppendChar((char)ch); | 810 return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH); |
790 } | 811 } |
791 break; | 812 return buf.GetByteString(); |
792 case 1: | 813 } |
793 if (ch >= '0' && ch <= '7') { | 814 parlevel--; |
794 iEscCode = ch - '0'; | 815 buf.AppendChar(')'); |
795 status = 2; | 816 } else if (ch == '(') { |
796 break; | 817 parlevel++; |
797 } | 818 buf.AppendChar('('); |
798 if (ch == 'n') { | 819 } else if (ch == '\\') { |
799 buf.AppendChar('\n'); | 820 status = 1; |
800 } else if (ch == 'r') { | 821 } else { |
801 buf.AppendChar('\r'); | 822 buf.AppendChar((char)ch); |
802 } else if (ch == 't') { | 823 } |
803 buf.AppendChar('\t'); | 824 break; |
804 } else if (ch == 'b') { | 825 case 1: |
805 buf.AppendChar('\b'); | 826 if (ch >= '0' && ch <= '7') { |
806 } else if (ch == 'f') { | 827 iEscCode = ch - '0'; |
807 buf.AppendChar('\f'); | 828 status = 2; |
808 } else if (ch == '\r') { | 829 break; |
809 status = 4; | 830 } |
810 break; | 831 if (ch == 'n') { |
811 } else if (ch == '\n') { | 832 buf.AppendChar('\n'); |
812 } else { | 833 } else if (ch == 'r') { |
813 buf.AppendChar(ch); | 834 buf.AppendChar('\r'); |
814 } | 835 } else if (ch == 't') { |
815 status = 0; | 836 buf.AppendChar('\t'); |
816 break; | 837 } else if (ch == 'b') { |
817 case 2: | 838 buf.AppendChar('\b'); |
818 if (ch >= '0' && ch <= '7') { | 839 } else if (ch == 'f') { |
819 iEscCode = iEscCode * 8 + ch - '0'; | 840 buf.AppendChar('\f'); |
820 status = 3; | 841 } else if (ch == '\r') { |
821 } else { | 842 status = 4; |
822 buf.AppendChar(iEscCode); | 843 break; |
823 status = 0; | 844 } else if (ch == '\n') { |
824 continue; | 845 } else { |
825 } | 846 buf.AppendChar(ch); |
826 break; | 847 } |
827 case 3: | 848 status = 0; |
828 if (ch >= '0' && ch <= '7') { | 849 break; |
829 iEscCode = iEscCode * 8 + ch - '0'; | 850 case 2: |
830 buf.AppendChar(iEscCode); | 851 if (ch >= '0' && ch <= '7') { |
831 status = 0; | 852 iEscCode = iEscCode * 8 + ch - '0'; |
832 } else { | 853 status = 3; |
833 buf.AppendChar(iEscCode); | 854 } else { |
834 status = 0; | 855 buf.AppendChar(iEscCode); |
835 continue; | 856 status = 0; |
836 } | 857 continue; |
837 break; | 858 } |
838 case 4: | 859 break; |
839 status = 0; | 860 case 3: |
840 if (ch != '\n') { | 861 if (ch >= '0' && ch <= '7') { |
841 continue; | 862 iEscCode = iEscCode * 8 + ch - '0'; |
842 } | 863 buf.AppendChar(iEscCode); |
843 break; | 864 status = 0; |
844 } | 865 } else { |
845 if (m_Size <= m_Pos) { | 866 buf.AppendChar(iEscCode); |
846 break; | 867 status = 0; |
847 } | 868 continue; |
848 ch = m_pBuf[m_Pos++]; | 869 } |
849 } | 870 break; |
850 if (m_Size > m_Pos) { | 871 case 4: |
851 ch = m_pBuf[m_Pos++]; | 872 status = 0; |
852 } | 873 if (ch != '\n') { |
853 if (buf.GetLength() > MAX_STRING_LENGTH) { | 874 continue; |
854 return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH); | 875 } |
855 } | 876 break; |
856 return buf.GetByteString(); | 877 } |
857 } | |
858 CFX_ByteString CPDF_StreamParser::ReadHexString() | |
859 { | |
860 if (m_Size <= m_Pos) { | 878 if (m_Size <= m_Pos) { |
861 return CFX_ByteString(); | 879 break; |
862 } | 880 } |
863 int ch = m_pBuf[m_Pos++]; | 881 ch = m_pBuf[m_Pos++]; |
864 CFX_ByteTextBuf buf; | 882 } |
865 FX_BOOL bFirst = TRUE; | 883 if (m_Size > m_Pos) { |
866 int code = 0; | 884 ch = m_pBuf[m_Pos++]; |
867 while (1) { | 885 } |
868 if (ch == '>') { | 886 if (buf.GetLength() > MAX_STRING_LENGTH) { |
869 break; | 887 return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH); |
870 } | 888 } |
871 if (ch >= '0' && ch <= '9') { | 889 return buf.GetByteString(); |
872 if (bFirst) { | 890 } |
873 code = (ch - '0') * 16; | 891 CFX_ByteString CPDF_StreamParser::ReadHexString() { |
874 } else { | 892 if (m_Size <= m_Pos) { |
875 code += ch - '0'; | 893 return CFX_ByteString(); |
876 buf.AppendChar((char)code); | 894 } |
877 } | 895 int ch = m_pBuf[m_Pos++]; |
878 bFirst = !bFirst; | 896 CFX_ByteTextBuf buf; |
879 } else if (ch >= 'A' && ch <= 'F') { | 897 FX_BOOL bFirst = TRUE; |
880 if (bFirst) { | 898 int code = 0; |
881 code = (ch - 'A' + 10) * 16; | 899 while (1) { |
882 } else { | 900 if (ch == '>') { |
883 code += ch - 'A' + 10; | 901 break; |
884 buf.AppendChar((char)code); | 902 } |
885 } | 903 if (ch >= '0' && ch <= '9') { |
886 bFirst = !bFirst; | 904 if (bFirst) { |
887 } else if (ch >= 'a' && ch <= 'f') { | 905 code = (ch - '0') * 16; |
888 if (bFirst) { | 906 } else { |
889 code = (ch - 'a' + 10) * 16; | 907 code += ch - '0'; |
890 } else { | |
891 code += ch - 'a' + 10; | |
892 buf.AppendChar((char)code); | |
893 } | |
894 bFirst = !bFirst; | |
895 } | |
896 if (m_Size <= m_Pos) { | |
897 break; | |
898 } | |
899 ch = m_pBuf[m_Pos++]; | |
900 } | |
901 if (!bFirst) { | |
902 buf.AppendChar((char)code); | 908 buf.AppendChar((char)code); |
903 } | 909 } |
904 if (buf.GetLength() > MAX_STRING_LENGTH) { | 910 bFirst = !bFirst; |
905 return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH); | 911 } else if (ch >= 'A' && ch <= 'F') { |
906 } | 912 if (bFirst) { |
907 return buf.GetByteString(); | 913 code = (ch - 'A' + 10) * 16; |
908 } | 914 } else { |
909 #define PAGEPARSE_STAGE_GETCONTENT» » 1 | 915 code += ch - 'A' + 10; |
910 #define PAGEPARSE_STAGE_PARSE» » » 2 | 916 buf.AppendChar((char)code); |
911 #define PAGEPARSE_STAGE_CHECKCLIP» » 3 | 917 } |
912 CPDF_ContentParser::CPDF_ContentParser() | 918 bFirst = !bFirst; |
913 { | 919 } else if (ch >= 'a' && ch <= 'f') { |
914 m_pParser = NULL; | 920 if (bFirst) { |
915 m_pStreamArray = NULL; | 921 code = (ch - 'a' + 10) * 16; |
916 m_pSingleStream = NULL; | 922 } else { |
917 m_pData = NULL; | 923 code += ch - 'a' + 10; |
918 m_Status = Ready; | 924 buf.AppendChar((char)code); |
919 m_pType3Char = NULL; | 925 } |
920 } | 926 bFirst = !bFirst; |
921 CPDF_ContentParser::~CPDF_ContentParser() | 927 } |
922 { | 928 if (m_Size <= m_Pos) { |
923 Clear(); | 929 break; |
924 } | 930 } |
925 void CPDF_ContentParser::Clear() | 931 ch = m_pBuf[m_Pos++]; |
926 { | 932 } |
927 delete m_pParser; | 933 if (!bFirst) { |
928 delete m_pSingleStream; | 934 buf.AppendChar((char)code); |
929 if (m_pStreamArray) { | 935 } |
930 for (FX_DWORD i = 0; i < m_nStreams; i ++) | 936 if (buf.GetLength() > MAX_STRING_LENGTH) { |
931 delete m_pStreamArray[i]; | 937 return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH); |
932 FX_Free(m_pStreamArray); | 938 } |
933 } | 939 return buf.GetByteString(); |
934 if (m_pData && m_pSingleStream == NULL) { | 940 } |
935 FX_Free((void*)m_pData); | 941 #define PAGEPARSE_STAGE_GETCONTENT 1 |
936 } | 942 #define PAGEPARSE_STAGE_PARSE 2 |
937 m_pParser = NULL; | 943 #define PAGEPARSE_STAGE_CHECKCLIP 3 |
938 m_pStreamArray = NULL; | 944 CPDF_ContentParser::CPDF_ContentParser() { |
939 m_pSingleStream = NULL; | 945 m_pParser = NULL; |
940 m_pData = NULL; | 946 m_pStreamArray = NULL; |
941 m_Status = Ready; | 947 m_pSingleStream = NULL; |
942 } | 948 m_pData = NULL; |
943 void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions) | 949 m_Status = Ready; |
944 { | 950 m_pType3Char = NULL; |
945 if (m_Status != Ready || pPage == NULL || pPage->m_pDocument == NULL || pPag
e->m_pFormDict == NULL) { | 951 } |
946 m_Status = Done; | 952 CPDF_ContentParser::~CPDF_ContentParser() { |
947 return; | 953 Clear(); |
948 } | 954 } |
949 m_pObjects = pPage; | 955 void CPDF_ContentParser::Clear() { |
950 m_bForm = FALSE; | 956 delete m_pParser; |
951 if (pOptions) { | 957 delete m_pSingleStream; |
952 m_Options = *pOptions; | 958 if (m_pStreamArray) { |
953 } | 959 for (FX_DWORD i = 0; i < m_nStreams; i++) |
954 m_Status = ToBeContinued; | 960 delete m_pStreamArray[i]; |
955 m_InternalStage = PAGEPARSE_STAGE_GETCONTENT; | 961 FX_Free(m_pStreamArray); |
956 m_CurrentOffset = 0; | 962 } |
957 CPDF_Object* pContent = pPage->m_pFormDict->GetElementValue(FX_BSTRC("Conten
ts")); | 963 if (m_pData && m_pSingleStream == NULL) { |
958 if (pContent == NULL) { | 964 FX_Free((void*)m_pData); |
959 m_Status = Done; | 965 } |
960 return; | 966 m_pParser = NULL; |
961 } | 967 m_pStreamArray = NULL; |
962 if (pContent->GetType() == PDFOBJ_STREAM) { | 968 m_pSingleStream = NULL; |
963 m_nStreams = 0; | 969 m_pData = NULL; |
964 m_pSingleStream = new CPDF_StreamAcc; | 970 m_Status = Ready; |
965 m_pSingleStream->LoadAllData((CPDF_Stream*)pContent, FALSE); | 971 } |
966 } else if (pContent->GetType() == PDFOBJ_ARRAY) { | 972 void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions) { |
967 CPDF_Array* pArray = (CPDF_Array*)pContent; | 973 if (m_Status != Ready || pPage == NULL || pPage->m_pDocument == NULL || |
968 m_nStreams = pArray->GetCount(); | 974 pPage->m_pFormDict == NULL) { |
969 if (m_nStreams == 0) { | 975 m_Status = Done; |
970 m_Status = Done; | 976 return; |
971 return; | 977 } |
972 } | 978 m_pObjects = pPage; |
973 m_pStreamArray = FX_Alloc(CPDF_StreamAcc*, m_nStreams); | 979 m_bForm = FALSE; |
974 } else { | 980 if (pOptions) { |
975 m_Status = Done; | 981 m_Options = *pOptions; |
976 return; | 982 } |
977 } | 983 m_Status = ToBeContinued; |
978 } | 984 m_InternalStage = PAGEPARSE_STAGE_GETCONTENT; |
979 void CPDF_ContentParser::Start(CPDF_Form* pForm, CPDF_AllStates* pGraphicStates, | 985 m_CurrentOffset = 0; |
980 CFX_AffineMatrix* pParentMatrix, CPDF_Type3Char*
pType3Char, CPDF_ParseOptions* pOptions, int level) | 986 CPDF_Object* pContent = |
981 { | 987 pPage->m_pFormDict->GetElementValue(FX_BSTRC("Contents")); |
982 m_pType3Char = pType3Char; | 988 if (pContent == NULL) { |
983 m_pObjects = pForm; | 989 m_Status = Done; |
984 m_bForm = TRUE; | 990 return; |
985 CFX_AffineMatrix form_matrix = pForm->m_pFormDict->GetMatrix(FX_BSTRC("Matri
x")); | 991 } |
986 if (pGraphicStates) { | 992 if (pContent->GetType() == PDFOBJ_STREAM) { |
987 form_matrix.Concat(pGraphicStates->m_CTM); | |
988 } | |
989 CPDF_Array* pBBox = pForm->m_pFormDict->GetArray(FX_BSTRC("BBox")); | |
990 CFX_FloatRect form_bbox; | |
991 CPDF_Path ClipPath; | |
992 if (pBBox) { | |
993 form_bbox = pBBox->GetRect(); | |
994 ClipPath.New(); | |
995 ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, f
orm_bbox.top); | |
996 ClipPath.Transform(&form_matrix); | |
997 if (pParentMatrix) { | |
998 ClipPath.Transform(pParentMatrix); | |
999 } | |
1000 form_bbox.Transform(&form_matrix); | |
1001 if (pParentMatrix) { | |
1002 form_bbox.Transform(pParentMatrix); | |
1003 } | |
1004 } | |
1005 CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDict(FX_BSTRC("Resource
s")); | |
1006 m_pParser = new CPDF_StreamContentParser( | |
1007 pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources, | |
1008 pParentMatrix, pForm, pResources, &form_bbox, pOptions, pGraphicStates, | |
1009 level); | |
1010 | |
1011 m_pParser->GetCurStates()->m_CTM = form_matrix; | |
1012 m_pParser->GetCurStates()->m_ParentMatrix = form_matrix; | |
1013 if (ClipPath.NotNull()) { | |
1014 m_pParser->GetCurStates()->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDIN
G, TRUE); | |
1015 } | |
1016 if (pForm->m_Transparency & PDFTRANS_GROUP) { | |
1017 CPDF_GeneralStateData* pData = m_pParser->GetCurStates()->m_GeneralState
.GetModify(); | |
1018 pData->m_BlendType = FXDIB_BLEND_NORMAL; | |
1019 pData->m_StrokeAlpha = 1.0f; | |
1020 pData->m_FillAlpha = 1.0f; | |
1021 pData->m_pSoftMask = NULL; | |
1022 } | |
1023 m_nStreams = 0; | 993 m_nStreams = 0; |
1024 m_pSingleStream = new CPDF_StreamAcc; | 994 m_pSingleStream = new CPDF_StreamAcc; |
1025 if (pForm->m_pDocument) { | 995 m_pSingleStream->LoadAllData((CPDF_Stream*)pContent, FALSE); |
1026 m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE); | 996 } else if (pContent->GetType() == PDFOBJ_ARRAY) { |
1027 } else { | 997 CPDF_Array* pArray = (CPDF_Array*)pContent; |
1028 m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE); | 998 m_nStreams = pArray->GetCount(); |
1029 } | 999 if (m_nStreams == 0) { |
1030 m_pData = (uint8_t*)m_pSingleStream->GetData(); | 1000 m_Status = Done; |
1031 m_Size = m_pSingleStream->GetSize(); | 1001 return; |
1032 m_Status = ToBeContinued; | 1002 } |
1033 m_InternalStage = PAGEPARSE_STAGE_PARSE; | 1003 m_pStreamArray = FX_Alloc(CPDF_StreamAcc*, m_nStreams); |
1034 m_CurrentOffset = 0; | 1004 } else { |
1035 } | 1005 m_Status = Done; |
1036 void CPDF_ContentParser::Continue(IFX_Pause* pPause) | 1006 return; |
1037 { | 1007 } |
1038 int steps = 0; | 1008 } |
1039 while (m_Status == ToBeContinued) { | 1009 void CPDF_ContentParser::Start(CPDF_Form* pForm, |
1040 if (m_InternalStage == PAGEPARSE_STAGE_GETCONTENT) { | 1010 CPDF_AllStates* pGraphicStates, |
1041 if (m_CurrentOffset == m_nStreams) { | 1011 CFX_AffineMatrix* pParentMatrix, |
1042 if (m_pStreamArray) { | 1012 CPDF_Type3Char* pType3Char, |
1043 m_Size = 0; | 1013 CPDF_ParseOptions* pOptions, |
1044 FX_DWORD i; | 1014 int level) { |
1045 for (i = 0; i < m_nStreams; i ++) { | 1015 m_pType3Char = pType3Char; |
1046 FX_DWORD size = m_pStreamArray[i]->GetSize(); | 1016 m_pObjects = pForm; |
1047 if (m_Size + size + 1 <= m_Size) { | 1017 m_bForm = TRUE; |
1048 m_Status = Done; | 1018 CFX_AffineMatrix form_matrix = |
1049 return; | 1019 pForm->m_pFormDict->GetMatrix(FX_BSTRC("Matrix")); |
1050 } | 1020 if (pGraphicStates) { |
1051 m_Size += size + 1; | 1021 form_matrix.Concat(pGraphicStates->m_CTM); |
1052 } | 1022 } |
1053 m_pData = FX_Alloc(uint8_t, m_Size); | 1023 CPDF_Array* pBBox = pForm->m_pFormDict->GetArray(FX_BSTRC("BBox")); |
1054 FX_DWORD pos = 0; | 1024 CFX_FloatRect form_bbox; |
1055 for (i = 0; i < m_nStreams; i ++) { | 1025 CPDF_Path ClipPath; |
1056 FXSYS_memcpy(m_pData + pos, m_pStreamArray[i]->GetData()
, m_pStreamArray[i]->GetSize()); | 1026 if (pBBox) { |
1057 pos += m_pStreamArray[i]->GetSize() + 1; | 1027 form_bbox = pBBox->GetRect(); |
1058 m_pData[pos - 1] = ' '; | 1028 ClipPath.New(); |
1059 delete m_pStreamArray[i]; | 1029 ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, |
1060 } | 1030 form_bbox.top); |
1061 FX_Free(m_pStreamArray); | 1031 ClipPath.Transform(&form_matrix); |
1062 m_pStreamArray = NULL; | 1032 if (pParentMatrix) { |
1063 } else { | 1033 ClipPath.Transform(pParentMatrix); |
1064 m_pData = (uint8_t*)m_pSingleStream->GetData(); | 1034 } |
1065 m_Size = m_pSingleStream->GetSize(); | 1035 form_bbox.Transform(&form_matrix); |
1066 } | 1036 if (pParentMatrix) { |
1067 m_InternalStage = PAGEPARSE_STAGE_PARSE; | 1037 form_bbox.Transform(pParentMatrix); |
1068 m_CurrentOffset = 0; | 1038 } |
1069 } else { | 1039 } |
1070 CPDF_Array* pContent = m_pObjects->m_pFormDict->GetArray(FX_BSTR
C("Contents")); | 1040 CPDF_Dictionary* pResources = |
1071 m_pStreamArray[m_CurrentOffset] = new CPDF_StreamAcc; | 1041 pForm->m_pFormDict->GetDict(FX_BSTRC("Resources")); |
1072 CPDF_Stream* pStreamObj = (CPDF_Stream*)(pContent ? pContent->Ge
tElementValue(m_CurrentOffset) : NULL); | 1042 m_pParser = new CPDF_StreamContentParser( |
1073 m_pStreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, FALSE); | 1043 pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources, |
1074 m_CurrentOffset ++; | 1044 pParentMatrix, pForm, pResources, &form_bbox, pOptions, pGraphicStates, |
| 1045 level); |
| 1046 |
| 1047 m_pParser->GetCurStates()->m_CTM = form_matrix; |
| 1048 m_pParser->GetCurStates()->m_ParentMatrix = form_matrix; |
| 1049 if (ClipPath.NotNull()) { |
| 1050 m_pParser->GetCurStates()->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, |
| 1051 TRUE); |
| 1052 } |
| 1053 if (pForm->m_Transparency & PDFTRANS_GROUP) { |
| 1054 CPDF_GeneralStateData* pData = |
| 1055 m_pParser->GetCurStates()->m_GeneralState.GetModify(); |
| 1056 pData->m_BlendType = FXDIB_BLEND_NORMAL; |
| 1057 pData->m_StrokeAlpha = 1.0f; |
| 1058 pData->m_FillAlpha = 1.0f; |
| 1059 pData->m_pSoftMask = NULL; |
| 1060 } |
| 1061 m_nStreams = 0; |
| 1062 m_pSingleStream = new CPDF_StreamAcc; |
| 1063 if (pForm->m_pDocument) { |
| 1064 m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE); |
| 1065 } else { |
| 1066 m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE); |
| 1067 } |
| 1068 m_pData = (uint8_t*)m_pSingleStream->GetData(); |
| 1069 m_Size = m_pSingleStream->GetSize(); |
| 1070 m_Status = ToBeContinued; |
| 1071 m_InternalStage = PAGEPARSE_STAGE_PARSE; |
| 1072 m_CurrentOffset = 0; |
| 1073 } |
| 1074 void CPDF_ContentParser::Continue(IFX_Pause* pPause) { |
| 1075 int steps = 0; |
| 1076 while (m_Status == ToBeContinued) { |
| 1077 if (m_InternalStage == PAGEPARSE_STAGE_GETCONTENT) { |
| 1078 if (m_CurrentOffset == m_nStreams) { |
| 1079 if (m_pStreamArray) { |
| 1080 m_Size = 0; |
| 1081 FX_DWORD i; |
| 1082 for (i = 0; i < m_nStreams; i++) { |
| 1083 FX_DWORD size = m_pStreamArray[i]->GetSize(); |
| 1084 if (m_Size + size + 1 <= m_Size) { |
| 1085 m_Status = Done; |
| 1086 return; |
1075 } | 1087 } |
1076 } | 1088 m_Size += size + 1; |
1077 if (m_InternalStage == PAGEPARSE_STAGE_PARSE) { | 1089 } |
1078 if (!m_pParser) { | 1090 m_pData = FX_Alloc(uint8_t, m_Size); |
1079 m_pParser = new CPDF_StreamContentParser( | 1091 FX_DWORD pos = 0; |
1080 m_pObjects->m_pDocument, m_pObjects->m_pPageResources, | 1092 for (i = 0; i < m_nStreams; i++) { |
1081 nullptr, nullptr, m_pObjects, m_pObjects->m_pResources, | 1093 FXSYS_memcpy(m_pData + pos, m_pStreamArray[i]->GetData(), |
1082 &m_pObjects->m_BBox, &m_Options, nullptr, 0); | 1094 m_pStreamArray[i]->GetSize()); |
1083 m_pParser->GetCurStates()->m_ColorState.GetModify()->Default(); | 1095 pos += m_pStreamArray[i]->GetSize() + 1; |
1084 } | 1096 m_pData[pos - 1] = ' '; |
1085 if (m_CurrentOffset >= m_Size) { | 1097 delete m_pStreamArray[i]; |
1086 m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP; | 1098 } |
1087 } else { | 1099 FX_Free(m_pStreamArray); |
1088 m_CurrentOffset += m_pParser->Parse(m_pData + m_CurrentOffset, m
_Size - m_CurrentOffset, PARSE_STEP_LIMIT); | 1100 m_pStreamArray = NULL; |
1089 if (m_pParser->ShouldAbort()) { | 1101 } else { |
1090 m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP; | 1102 m_pData = (uint8_t*)m_pSingleStream->GetData(); |
1091 continue; | 1103 m_Size = m_pSingleStream->GetSize(); |
1092 } | 1104 } |
1093 } | 1105 m_InternalStage = PAGEPARSE_STAGE_PARSE; |
1094 } | 1106 m_CurrentOffset = 0; |
1095 if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) { | 1107 } else { |
1096 if (m_pType3Char) { | 1108 CPDF_Array* pContent = |
1097 m_pType3Char->m_bColored = m_pParser->IsColored(); | 1109 m_pObjects->m_pFormDict->GetArray(FX_BSTRC("Contents")); |
1098 m_pType3Char->m_Width = FXSYS_round(m_pParser->GetType3Data()[0]
* 1000); | 1110 m_pStreamArray[m_CurrentOffset] = new CPDF_StreamAcc; |
1099 m_pType3Char->m_BBox.left = FXSYS_round(m_pParser->GetType3Data(
)[2] * 1000); | 1111 CPDF_Stream* pStreamObj = |
1100 m_pType3Char->m_BBox.bottom = FXSYS_round(m_pParser->GetType3Dat
a()[3] * 1000); | 1112 (CPDF_Stream*)(pContent ? pContent->GetElementValue(m_CurrentOffset) |
1101 m_pType3Char->m_BBox.right = FXSYS_round(m_pParser->GetType3Data
()[4] * 1000); | 1113 : NULL); |
1102 m_pType3Char->m_BBox.top = FXSYS_round(m_pParser->GetType3Data()
[5] * 1000); | 1114 m_pStreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, FALSE); |
1103 } | 1115 m_CurrentOffset++; |
1104 FX_POSITION pos = m_pObjects->m_ObjectList.GetHeadPosition(); | 1116 } |
1105 while (pos) { | 1117 } |
1106 CPDF_PageObject* pObj = (CPDF_PageObject*)m_pObjects->m_ObjectLi
st.GetNext(pos); | 1118 if (m_InternalStage == PAGEPARSE_STAGE_PARSE) { |
1107 if (pObj->m_ClipPath.IsNull()) { | 1119 if (!m_pParser) { |
1108 continue; | 1120 m_pParser = new CPDF_StreamContentParser( |
1109 } | 1121 m_pObjects->m_pDocument, m_pObjects->m_pPageResources, nullptr, |
1110 if (pObj->m_ClipPath.GetPathCount() != 1) { | 1122 nullptr, m_pObjects, m_pObjects->m_pResources, &m_pObjects->m_BBox, |
1111 continue; | 1123 &m_Options, nullptr, 0); |
1112 } | 1124 m_pParser->GetCurStates()->m_ColorState.GetModify()->Default(); |
1113 if (pObj->m_ClipPath.GetTextCount()) { | 1125 } |
1114 continue; | 1126 if (m_CurrentOffset >= m_Size) { |
1115 } | 1127 m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP; |
1116 CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0); | 1128 } else { |
1117 if (!ClipPath.IsRect() || pObj->m_Type == PDFPAGE_SHADING) { | 1129 m_CurrentOffset += |
1118 continue; | 1130 m_pParser->Parse(m_pData + m_CurrentOffset, |
1119 } | 1131 m_Size - m_CurrentOffset, PARSE_STEP_LIMIT); |
1120 CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY
(0), | 1132 if (m_pParser->ShouldAbort()) { |
1121 ClipPath.GetPointX(2), ClipPath.GetPointY
(2)); | 1133 m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP; |
1122 CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Rig
ht, pObj->m_Top); | 1134 continue; |
1123 if (old_rect.Contains(obj_rect)) { | 1135 } |
1124 pObj->m_ClipPath.SetNull(); | 1136 } |
1125 } | 1137 } |
1126 } | 1138 if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) { |
1127 m_Status = Done; | 1139 if (m_pType3Char) { |
1128 return; | 1140 m_pType3Char->m_bColored = m_pParser->IsColored(); |
1129 } | 1141 m_pType3Char->m_Width = |
1130 steps ++; | 1142 FXSYS_round(m_pParser->GetType3Data()[0] * 1000); |
1131 if (pPause && pPause->NeedToPauseNow()) { | 1143 m_pType3Char->m_BBox.left = |
1132 break; | 1144 FXSYS_round(m_pParser->GetType3Data()[2] * 1000); |
1133 } | 1145 m_pType3Char->m_BBox.bottom = |
1134 } | 1146 FXSYS_round(m_pParser->GetType3Data()[3] * 1000); |
1135 } | 1147 m_pType3Char->m_BBox.right = |
| 1148 FXSYS_round(m_pParser->GetType3Data()[4] * 1000); |
| 1149 m_pType3Char->m_BBox.top = |
| 1150 FXSYS_round(m_pParser->GetType3Data()[5] * 1000); |
| 1151 } |
| 1152 FX_POSITION pos = m_pObjects->m_ObjectList.GetHeadPosition(); |
| 1153 while (pos) { |
| 1154 CPDF_PageObject* pObj = |
| 1155 (CPDF_PageObject*)m_pObjects->m_ObjectList.GetNext(pos); |
| 1156 if (pObj->m_ClipPath.IsNull()) { |
| 1157 continue; |
| 1158 } |
| 1159 if (pObj->m_ClipPath.GetPathCount() != 1) { |
| 1160 continue; |
| 1161 } |
| 1162 if (pObj->m_ClipPath.GetTextCount()) { |
| 1163 continue; |
| 1164 } |
| 1165 CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0); |
| 1166 if (!ClipPath.IsRect() || pObj->m_Type == PDFPAGE_SHADING) { |
| 1167 continue; |
| 1168 } |
| 1169 CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY(0), |
| 1170 ClipPath.GetPointX(2), ClipPath.GetPointY(2)); |
| 1171 CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, |
| 1172 pObj->m_Top); |
| 1173 if (old_rect.Contains(obj_rect)) { |
| 1174 pObj->m_ClipPath.SetNull(); |
| 1175 } |
| 1176 } |
| 1177 m_Status = Done; |
| 1178 return; |
| 1179 } |
| 1180 steps++; |
| 1181 if (pPause && pPause->NeedToPauseNow()) { |
| 1182 break; |
| 1183 } |
| 1184 } |
| 1185 } |
OLD | NEW |