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

Side by Side Diff: experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp

Issue 19793011: (upload draf code for backup) pdfviewer: improve memory, son't allocate extra buffers, and put the … (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 5 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 | Annotate | Revision Log
OLDNEW
1 #include "SkNativeParsedPDF.h" 1 #include "SkNativeParsedPDF.h"
2 #include "SkPdfNativeTokenizer.h" 2 #include "SkPdfNativeTokenizer.h"
3 #include "SkPdfBasics.h" 3 #include "SkPdfBasics.h"
4 #include "SkPdfObject.h" 4 #include "SkPdfObject.h"
5 5
6 #include <stdio.h> 6 #include <stdio.h>
7 #include <string.h> 7 #include <string.h>
8 #include <sys/types.h> 8 #include <sys/types.h>
9 #include <sys/stat.h> 9 #include <sys/stat.h>
10 10
11 #include "SkPdfFileTrailerDictionary_autogen.h" 11 #include "SkPdfFileTrailerDictionary_autogen.h"
12 #include "SkPdfCatalogDictionary_autogen.h" 12 #include "SkPdfCatalogDictionary_autogen.h"
13 #include "SkPdfPageObjectDictionary_autogen.h" 13 #include "SkPdfPageObjectDictionary_autogen.h"
14 #include "SkPdfPageTreeNodeDictionary_autogen.h" 14 #include "SkPdfPageTreeNodeDictionary_autogen.h"
15 #include "SkPdfMapper_autogen.h" 15 #include "SkPdfMapper_autogen.h"
16 16
17 17
18 18
19 static long getFileSize(const char* filename) 19 static long getFileSize(const char* filename)
20 { 20 {
21 struct stat stat_buf; 21 struct stat stat_buf;
22 int rc = stat(filename, &stat_buf); 22 int rc = stat(filename, &stat_buf);
23 return rc == 0 ? (long)stat_buf.st_size : -1; 23 return rc == 0 ? (long)stat_buf.st_size : -1;
24 } 24 }
25 25
26 static unsigned char* lineHome(unsigned char* start, unsigned char* current) { 26 static const unsigned char* lineHome(const unsigned char* start, const unsigned char* current) {
27 while (current > start && !isPdfEOL(*(current - 1))) { 27 while (current > start && !isPdfEOL(*(current - 1))) {
28 current--; 28 current--;
29 } 29 }
30 return current; 30 return current;
31 } 31 }
32 32
33 static unsigned char* previousLineHome(unsigned char* start, unsigned char* curr ent) { 33 static const unsigned char* previousLineHome(const unsigned char* start, const u nsigned char* current) {
34 if (current > start && isPdfEOL(*(current - 1))) { 34 if (current > start && isPdfEOL(*(current - 1))) {
35 current--; 35 current--;
36 } 36 }
37 37
38 // allows CR+LF, LF+CR but not two CR+CR or LF+LF 38 // allows CR+LF, LF+CR but not two CR+CR or LF+LF
39 if (current > start && isPdfEOL(*(current - 1)) && *current != *(current - 1 )) { 39 if (current > start && isPdfEOL(*(current - 1)) && *current != *(current - 1 )) {
40 current--; 40 current--;
41 } 41 }
42 42
43 while (current > start && !isPdfEOL(*(current - 1))) { 43 while (current > start && !isPdfEOL(*(current - 1))) {
44 current--; 44 current--;
45 } 45 }
46 46
47 return current; 47 return current;
48 } 48 }
49 49
50 static unsigned char* ignoreLine(unsigned char* current, unsigned char* end) { 50 static const unsigned char* ignoreLine(const unsigned char* current, const unsig ned char* end) {
51 while (current < end && !isPdfEOL(*current)) { 51 while (current < end && !isPdfEOL(*current)) {
52 current++; 52 current++;
53 } 53 }
54 current++; 54 current++;
55 if (current < end && isPdfEOL(*current) && *current != *(current - 1)) { 55 if (current < end && isPdfEOL(*current) && *current != *(current - 1)) {
56 current++; 56 current++;
57 } 57 }
58 return current; 58 return current;
59 } 59 }
60 60
61 SkNativeParsedPDF* gDoc = NULL; 61 SkNativeParsedPDF* gDoc = NULL;
62 62
63 // TODO(edisonn): NYI 63 // TODO(edisonn): NYI
64 // TODO(edisonn): 3 constructuctors from URL, from stream, from file ... 64 // TODO(edisonn): 3 constructuctors from URL, from stream, from file ...
65 // TODO(edisonn): write one that accepts errors in the file and ignores/fixis th em 65 // TODO(edisonn): write one that accepts errors in the file and ignores/fixis th em
66 // TODO(edisonn): testing: 66 // TODO(edisonn): testing:
67 // 1) run on a lot of file 67 // 1) run on a lot of file
68 // 2) recoverable corupt file: remove endobj, endsteam, remove other keywords, u se other white spaces, insert comments randomly, ... 68 // 2) recoverable corupt file: remove endobj, endsteam, remove other keywords, u se other white spaces, insert comments randomly, ...
69 // 3) irrecoverable corrupt file 69 // 3) irrecoverable corrupt file
70 SkNativeParsedPDF::SkNativeParsedPDF(const char* path) 70 SkNativeParsedPDF::SkNativeParsedPDF(const char* path)
71 : fAllocator(new SkPdfAllocator()) 71 : fAllocator(new SkPdfAllocator())
72 , fRootCatalogRef(NULL) 72 , fRootCatalogRef(NULL)
73 , fRootCatalog(NULL) { 73 , fRootCatalog(NULL) {
74 gDoc = this; 74 gDoc = this;
75 FILE* file = fopen(path, "r"); 75 FILE* file = fopen(path, "r");
76 fContentLength = getFileSize(path); 76 fContentLength = getFileSize(path);
77 fFileContent = new unsigned char[fContentLength + 1]; 77 unsigned char* content = new unsigned char[fContentLength + 1];
78 bool ok = (0 != fread(fFileContent, fContentLength, 1, file)); 78 bool ok = (0 != fread(content, fContentLength, 1, file));
79 fFileContent[fContentLength] = '\0'; 79 content[fContentLength] = '\0';
80 fFileContent = content;
80 fclose(file); 81 fclose(file);
81 file = NULL; 82 file = NULL;
82 83
83 if (!ok) { 84 if (!ok) {
84 // TODO(edisonn): report read error 85 // TODO(edisonn): report read error
85 return; // Doc will have 0 pages 86 return; // Doc will have 0 pages
86 } 87 }
87 88
88 unsigned char* eofLine = lineHome(fFileContent, fFileContent + fContentLengt h - 1); 89 const unsigned char* eofLine = lineHome(fFileContent, fFileContent + fConten tLength - 1);
89 unsigned char* xrefByteOffsetLine = previousLineHome(fFileContent, eofLine); 90 const unsigned char* xrefByteOffsetLine = previousLineHome(fFileContent, eof Line);
90 unsigned char* xrefstartKeywordLine = previousLineHome(fFileContent, xrefByt eOffsetLine); 91 const unsigned char* xrefstartKeywordLine = previousLineHome(fFileContent, x refByteOffsetLine);
91 92
92 if (strcmp((char*)xrefstartKeywordLine, "startxref") != 0) { 93 if (strcmp((char*)xrefstartKeywordLine, "startxref") != 0) {
93 // TODO(edisonn): report/issue 94 // TODO(edisonn): report/issue
94 } 95 }
95 96
96 long xrefByteOffset = atol((const char*)xrefByteOffsetLine); 97 long xrefByteOffset = atol((const char*)xrefByteOffsetLine);
97 98
98 bool storeCatalog = true; 99 bool storeCatalog = true;
99 while (xrefByteOffset >= 0) { 100 while (xrefByteOffset >= 0) {
100 unsigned char* trailerStart = readCrossReferenceSection(fFileContent + x refByteOffset, xrefstartKeywordLine); 101 const unsigned char* trailerStart = readCrossReferenceSection(fFileConte nt + xrefByteOffset, xrefstartKeywordLine);
101 xrefByteOffset = readTrailer(trailerStart, xrefstartKeywordLine, storeCa talog); 102 xrefByteOffset = readTrailer(trailerStart, xrefstartKeywordLine, storeCa talog);
102 storeCatalog = false; 103 storeCatalog = false;
103 } 104 }
104 105
105 // TODO(edisonn): warn/error expect fObjects[fRefCatalogId].fGeneration == f RefCatalogGeneration 106 // TODO(edisonn): warn/error expect fObjects[fRefCatalogId].fGeneration == f RefCatalogGeneration
106 // TODO(edisonn): security, verify that SkPdfCatalogDictionary is indeed usi ng mapper 107 // TODO(edisonn): security, verify that SkPdfCatalogDictionary is indeed usi ng mapper
107 // load catalog 108 // load catalog
108 109
109 if (fRootCatalogRef) { 110 if (fRootCatalogRef) {
110 fRootCatalog = (SkPdfCatalogDictionary*)resolveReference(fRootCatalogRef ); 111 fRootCatalog = (SkPdfCatalogDictionary*)resolveReference(fRootCatalogRef );
(...skipping 11 matching lines...) Expand all
122 // now actually read all objects if we want, or do it lazyly 123 // now actually read all objects if we want, or do it lazyly
123 // and resolve references?... or not ... 124 // and resolve references?... or not ...
124 } 125 }
125 126
126 // TODO(edisonn): NYI 127 // TODO(edisonn): NYI
127 SkNativeParsedPDF::~SkNativeParsedPDF() { 128 SkNativeParsedPDF::~SkNativeParsedPDF() {
128 delete[] fFileContent; 129 delete[] fFileContent;
129 delete fAllocator; 130 delete fAllocator;
130 } 131 }
131 132
132 unsigned char* SkNativeParsedPDF::readCrossReferenceSection(unsigned char* xrefS tart, unsigned char* trailerEnd) { 133 const unsigned char* SkNativeParsedPDF::readCrossReferenceSection(const unsigned char* xrefStart, const unsigned char* trailerEnd) {
133 unsigned char* current = ignoreLine(xrefStart, trailerEnd); // TODO(edisonn ): verify next keyord is "xref", use nextObject here 134 const unsigned char* current = ignoreLine(xrefStart, trailerEnd); // TODO(e disonn): verify next keyord is "xref", use nextObject here
134 135
135 SkPdfObject token; 136 SkPdfObject token;
136 while (current < trailerEnd) { 137 while (current < trailerEnd) {
137 token.reset(); 138 token.reset();
138 unsigned char* previous = current; 139 const unsigned char* previous = current;
139 current = nextObject(current, trailerEnd, &token, NULL, NULL); 140 current = nextObject(0, current, trailerEnd, &token, NULL, NULL);
140 if (!token.isInteger()) { 141 if (!token.isInteger()) {
141 return previous; 142 return previous;
142 } 143 }
143 144
144 int startId = (int)token.intValue(); 145 int startId = (int)token.intValue();
145 token.reset(); 146 token.reset();
146 current = nextObject(current, trailerEnd, &token, NULL, NULL); 147 current = nextObject(0, current, trailerEnd, &token, NULL, NULL);
147 148
148 if (!token.isInteger()) { 149 if (!token.isInteger()) {
149 // TODO(edisonn): report/warning 150 // TODO(edisonn): report/warning
150 return current; 151 return current;
151 } 152 }
152 153
153 int entries = (int)token.intValue(); 154 int entries = (int)token.intValue();
154 155
155 for (int i = 0; i < entries; i++) { 156 for (int i = 0; i < entries; i++) {
156 token.reset(); 157 token.reset();
157 current = nextObject(current, trailerEnd, &token, NULL, NULL); 158 current = nextObject(0, current, trailerEnd, &token, NULL, NULL);
158 if (!token.isInteger()) { 159 if (!token.isInteger()) {
159 // TODO(edisonn): report/warning 160 // TODO(edisonn): report/warning
160 return current; 161 return current;
161 } 162 }
162 int offset = (int)token.intValue(); 163 int offset = (int)token.intValue();
163 164
164 token.reset(); 165 token.reset();
165 current = nextObject(current, trailerEnd, &token, NULL, NULL); 166 current = nextObject(0, current, trailerEnd, &token, NULL, NULL);
166 if (!token.isInteger()) { 167 if (!token.isInteger()) {
167 // TODO(edisonn): report/warning 168 // TODO(edisonn): report/warning
168 return current; 169 return current;
169 } 170 }
170 int generation = (int)token.intValue(); 171 int generation = (int)token.intValue();
171 172
172 token.reset(); 173 token.reset();
173 current = nextObject(current, trailerEnd, &token, NULL, NULL); 174 current = nextObject(0, current, trailerEnd, &token, NULL, NULL);
174 if (!token.isKeyword() || token.len() != 1 || (*token.c_str() != 'f' && *token.c_str() != 'n')) { 175 if (!token.isKeyword() || token.len() != 1 || (*token.c_str() != 'f' && *token.c_str() != 'n')) {
175 // TODO(edisonn): report/warning 176 // TODO(edisonn): report/warning
176 return current; 177 return current;
177 } 178 }
178 179
179 addCrossSectionInfo(startId + i, generation, offset, *token.c_str() == 'f'); 180 addCrossSectionInfo(startId + i, generation, offset, *token.c_str() == 'f');
180 } 181 }
181 } 182 }
182 // TODO(edisonn): it should never get here? there is no trailer? 183 // TODO(edisonn): it should never get here? there is no trailer?
183 return current; 184 return current;
184 } 185 }
185 186
186 long SkNativeParsedPDF::readTrailer(unsigned char* trailerStart, unsigned char* trailerEnd, bool storeCatalog) { 187 long SkNativeParsedPDF::readTrailer(const unsigned char* trailerStart, const uns igned char* trailerEnd, bool storeCatalog) {
187 unsigned char* current = ignoreLine(trailerStart, trailerEnd); // TODO(edis onn): verify next keyord is "trailer" use nextObject here 188 SkPdfObject trailerKeyword;
189 // TODO(edisonn): use null allocator, and let it just fail if memory
190 // needs allocated (but no crash)!
191 const unsigned char* current =
192 nextObject(0, trailerStart, trailerEnd, &trailerKeyword, fAllocator, NULL);
193
194 if (strlen("trailer") != trailerKeyword.len() &&
195 strncmp(trailerKeyword.c_str(), "trailer", strlen("trailer")) != 0) {
196 // TODO(edisonn): report warning, rebuild trailer from objects.
197 return -1;
198 }
188 199
189 SkPdfObject token; 200 SkPdfObject token;
190 current = nextObject(current, trailerEnd, &token, fAllocator, NULL); 201 current = nextObject(0, current, trailerEnd, &token, fAllocator, NULL);
191 if (!token.isDictionary()) { 202 if (!token.isDictionary()) {
192 return -1; 203 return -1;
193 } 204 }
194 SkPdfFileTrailerDictionary* trailer = (SkPdfFileTrailerDictionary*)&token; 205 SkPdfFileTrailerDictionary* trailer = (SkPdfFileTrailerDictionary*)&token;
195 if (!trailer->valid()) { 206 if (!trailer->valid()) {
196 return -1; 207 return -1;
197 } 208 }
198 209
199 if (storeCatalog) { 210 if (storeCatalog) {
200 const SkPdfObject* ref = trailer->Root(NULL); 211 const SkPdfObject* ref = trailer->Root(NULL);
(...skipping 22 matching lines...) Expand all
223 } 234 }
224 235
225 SkPdfObject* SkNativeParsedPDF::readObject(int id/*, int expectedGeneration*/) { 236 SkPdfObject* SkNativeParsedPDF::readObject(int id/*, int expectedGeneration*/) {
226 long startOffset = fObjects[id].fOffset; 237 long startOffset = fObjects[id].fOffset;
227 //long endOffset = fObjects[id].fOffsetEnd; 238 //long endOffset = fObjects[id].fOffsetEnd;
228 // TODO(edisonn): use hinted endOffset 239 // TODO(edisonn): use hinted endOffset
229 // TODO(edisonn): current implementation will result in a lot of memory usag e 240 // TODO(edisonn): current implementation will result in a lot of memory usag e
230 // to decrease memory usage, we wither need to be smart and know where objec ts end, and we will 241 // to decrease memory usage, we wither need to be smart and know where objec ts end, and we will
231 // alocate only the chancks needed, or the tokenizer will not make copies, b ut then it needs to 242 // alocate only the chancks needed, or the tokenizer will not make copies, b ut then it needs to
232 // cache the results so it does not go twice on the same buffer 243 // cache the results so it does not go twice on the same buffer
233 unsigned char* current = fFileContent + startOffset; 244 const unsigned char* current = fFileContent + startOffset;
234 unsigned char* end = fFileContent + fContentLength; 245 const unsigned char* end = fFileContent + fContentLength;
235 246
236 SkPdfNativeTokenizer tokenizer(current, end - current, fMapper, fAllocator, this); 247 SkPdfNativeTokenizer tokenizer(current, end - current, fMapper, fAllocator, this);
237 248
238 SkPdfObject idObj; 249 SkPdfObject idObj;
239 SkPdfObject generationObj; 250 SkPdfObject generationObj;
240 SkPdfObject objKeyword; 251 SkPdfObject objKeyword;
241 SkPdfObject* dict = fAllocator->allocObject(); 252 SkPdfObject* dict = fAllocator->allocObject();
242 253
243 current = nextObject(current, end, &idObj, NULL, NULL); 254 current = nextObject(0, current, end, &idObj, NULL, NULL);
244 if (current >= end) { 255 if (current >= end) {
245 // TODO(edisonn): report warning/error 256 // TODO(edisonn): report warning/error
246 return NULL; 257 return NULL;
247 } 258 }
248 259
249 current = nextObject(current, end, &generationObj, NULL, NULL); 260 current = nextObject(0, current, end, &generationObj, NULL, NULL);
250 if (current >= end) { 261 if (current >= end) {
251 // TODO(edisonn): report warning/error 262 // TODO(edisonn): report warning/error
252 return NULL; 263 return NULL;
253 } 264 }
254 265
255 current = nextObject(current, end, &objKeyword, NULL, NULL); 266 current = nextObject(0, current, end, &objKeyword, NULL, NULL);
256 if (current >= end) { 267 if (current >= end) {
257 // TODO(edisonn): report warning/error 268 // TODO(edisonn): report warning/error
258 return NULL; 269 return NULL;
259 } 270 }
260 271
261 if (!idObj.isInteger() || !generationObj.isInteger() || id != idObj.intValue ()/* || generation != generationObj.intValue()*/) { 272 if (!idObj.isInteger() || !generationObj.isInteger() || id != idObj.intValue ()/* || generation != generationObj.intValue()*/) {
262 // TODO(edisonn): report warning/error 273 // TODO(edisonn): report warning/error
263 } 274 }
264 275
265 if (!objKeyword.isKeyword() || strcmp(objKeyword.c_str(), "obj") != 0) { 276 if (!objKeyword.isKeyword() || strcmp(objKeyword.c_str(), "obj") != 0) {
266 // TODO(edisonn): report warning/error 277 // TODO(edisonn): report warning/error
267 } 278 }
268 279
269 current = nextObject(current, end, dict, fAllocator, this); 280 current = nextObject(1, current, end, dict, fAllocator, this);
270 281
271 // TODO(edisonn): report warning/error - verify last token is endobj 282 // TODO(edisonn): report warning/error - verify last token is endobj
272 283
273 return dict; 284 return dict;
274 } 285 }
275 286
276 void SkNativeParsedPDF::fillPages(SkPdfPageTreeNodeDictionary* tree) { 287 void SkNativeParsedPDF::fillPages(SkPdfPageTreeNodeDictionary* tree) {
277 const SkPdfArray* kids = tree->Kids(this); 288 const SkPdfArray* kids = tree->Kids(this);
278 if (kids == NULL) { 289 if (kids == NULL) {
279 *fPages.append() = (SkPdfPageObjectDictionary*)tree; 290 *fPages.append() = (SkPdfPageObjectDictionary*)tree;
(...skipping 26 matching lines...) Expand all
306 while (!current->has_MediaBox() && current->has_Parent()) { 317 while (!current->has_MediaBox() && current->has_Parent()) {
307 current = (SkPdfPageObjectDictionary*)current->Parent(this); 318 current = (SkPdfPageObjectDictionary*)current->Parent(this);
308 } 319 }
309 if (current) { 320 if (current) {
310 return current->MediaBox(this); 321 return current->MediaBox(this);
311 } 322 }
312 return SkRect::MakeEmpty(); 323 return SkRect::MakeEmpty();
313 } 324 }
314 325
315 // TODO(edisonn): stream or array ... ? for now only array 326 // TODO(edisonn): stream or array ... ? for now only array
316 SkPdfNativeTokenizer* SkNativeParsedPDF::tokenizerOfPage(int page) { 327 SkPdfNativeTokenizer* SkNativeParsedPDF::tokenizerOfPage(int page,
328 SkPdfAllocator* allocat or) {
317 if (fPages[page]->isContentsAStream(this)) { 329 if (fPages[page]->isContentsAStream(this)) {
318 return tokenizerOfStream(fPages[page]->getContentsAsStream(this)); 330 return tokenizerOfStream(fPages[page]->getContentsAsStream(this), alloca tor);
319 } else { 331 } else {
320 // TODO(edisonn): NYI, we need to concatenate all streams in the array o r make the tokenizer smart 332 // TODO(edisonn): NYI, we need to concatenate all streams in the array o r make the tokenizer smart
321 // so we don't allocate new memory 333 // so we don't allocate new memory
322 return NULL; 334 return NULL;
323 } 335 }
324 } 336 }
325 337
326 SkPdfNativeTokenizer* SkNativeParsedPDF::tokenizerOfStream(SkPdfObject* stream) { 338 SkPdfNativeTokenizer* SkNativeParsedPDF::tokenizerOfStream(SkPdfObject* stream,
339 SkPdfAllocator* alloc ator) {
327 if (stream == NULL) { 340 if (stream == NULL) {
328 return NULL; 341 return NULL;
329 } 342 }
330 343
331 return new SkPdfNativeTokenizer(stream, fMapper, fAllocator, this); 344 return new SkPdfNativeTokenizer(stream, fMapper, allocator, this);
332 } 345 }
333 346
334 // TODO(edisonn): NYI 347 // TODO(edisonn): NYI
335 SkPdfNativeTokenizer* SkNativeParsedPDF::tokenizerOfBuffer(unsigned char* buffer , size_t len) { 348 SkPdfNativeTokenizer* SkNativeParsedPDF::tokenizerOfBuffer(const unsigned char* buffer, size_t len,
349 SkPdfAllocator* alloc ator) {
336 // warning does not track two calls in the same buffer! the buffer is update d! 350 // warning does not track two calls in the same buffer! the buffer is update d!
337 // make a clean copy if needed! 351 // make a clean copy if needed!
338 return new SkPdfNativeTokenizer(buffer, len, fMapper, fAllocator, this); 352 return new SkPdfNativeTokenizer(buffer, len, fMapper, allocator, this);
339 } 353 }
340 354
341 size_t SkNativeParsedPDF::objects() const { 355 size_t SkNativeParsedPDF::objects() const {
342 return fObjects.count(); 356 return fObjects.count();
343 } 357 }
344 358
345 SkPdfObject* SkNativeParsedPDF::object(int i) { 359 SkPdfObject* SkNativeParsedPDF::object(int i) {
346 SkASSERT(!(i < 0 || i > fObjects.count())); 360 SkASSERT(!(i < 0 || i > fObjects.count()));
347 361
348 if (i < 0 || i > fObjects.count()) { 362 if (i < 0 || i > fObjects.count()) {
(...skipping 18 matching lines...) Expand all
367 SkPdfObject::makeReal(value, obj); 381 SkPdfObject::makeReal(value, obj);
368 return (SkPdfReal*)obj; 382 return (SkPdfReal*)obj;
369 } 383 }
370 384
371 SkPdfInteger* SkNativeParsedPDF::createInteger(int value) const { 385 SkPdfInteger* SkNativeParsedPDF::createInteger(int value) const {
372 SkPdfObject* obj = fAllocator->allocObject(); 386 SkPdfObject* obj = fAllocator->allocObject();
373 SkPdfObject::makeInteger(value, obj); 387 SkPdfObject::makeInteger(value, obj);
374 return (SkPdfInteger*)obj; 388 return (SkPdfInteger*)obj;
375 } 389 }
376 390
377 SkPdfString* SkNativeParsedPDF::createString(unsigned char* sz, size_t len) cons t { 391 SkPdfString* SkNativeParsedPDF::createString(const unsigned char* sz, size_t len ) const {
378 SkPdfObject* obj = fAllocator->allocObject(); 392 SkPdfObject* obj = fAllocator->allocObject();
379 SkPdfObject::makeString(sz, len, obj); 393 SkPdfObject::makeString(sz, len, obj);
380 return (SkPdfString*)obj; 394 return (SkPdfString*)obj;
381 } 395 }
382 396
383 SkPdfAllocator* SkNativeParsedPDF::allocator() const { 397 SkPdfAllocator* SkNativeParsedPDF::allocator() const {
384 return fAllocator; 398 return fAllocator;
385 } 399 }
386 400
387 // TODO(edisonn): fix infinite loop if ref to itself! 401 // TODO(edisonn): fix infinite loop if ref to itself!
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 return (SkPdfObject*)ref; 436 return (SkPdfObject*)ref;
423 } 437 }
424 438
425 size_t SkNativeParsedPDF::bytesUsed() const { 439 size_t SkNativeParsedPDF::bytesUsed() const {
426 return fAllocator->bytesUsed() + 440 return fAllocator->bytesUsed() +
427 fContentLength + 441 fContentLength +
428 fObjects.count() * sizeof(PublicObjectEntry) + 442 fObjects.count() * sizeof(PublicObjectEntry) +
429 fPages.count() * sizeof(SkPdfPageObjectDictionary*) + 443 fPages.count() * sizeof(SkPdfPageObjectDictionary*) +
430 sizeof(*this); 444 sizeof(*this);
431 } 445 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698