blob: cd1c51e2fa28fc4f5331517803abb2a7454588ea [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2011 Google Inc.
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000010#include "SkPDFCatalog.h"
11#include "SkPDFTypes.h"
12#include "SkStream.h"
13
vandebo@chromium.org094316b2011-03-04 03:15:13 +000014#ifdef SK_BUILD_FOR_WIN
15 #define SNPRINTF _snprintf
16#else
17 #define SNPRINTF snprintf
18#endif
19
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +000020SkPDFObject::SkPDFObject() {}
21SkPDFObject::~SkPDFObject() {}
22
vandebo@chromium.org2ef12d42011-07-06 23:31:24 +000023void SkPDFObject::emit(SkWStream* stream, SkPDFCatalog* catalog,
24 bool indirect) {
25 SkPDFObject* realObject = catalog->getSubstituteObject(this);
26 return realObject->emitObject(stream, catalog, indirect);
27}
28
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000029size_t SkPDFObject::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
30 SkDynamicMemoryWStream buffer;
vandebo@chromium.org2ef12d42011-07-06 23:31:24 +000031 emit(&buffer, catalog, indirect);
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000032 return buffer.getOffset();
33}
34
vandebo@chromium.orga5180862010-10-26 19:48:49 +000035void SkPDFObject::getResources(SkTDArray<SkPDFObject*>* resourceList) {}
36
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000037void SkPDFObject::emitIndirectObject(SkWStream* stream, SkPDFCatalog* catalog) {
38 catalog->emitObjectNumber(stream, this);
39 stream->writeText(" obj\n");
vandebo@chromium.org2ef12d42011-07-06 23:31:24 +000040 emit(stream, catalog, false);
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000041 stream->writeText("\nendobj\n");
42}
43
44size_t SkPDFObject::getIndirectOutputSize(SkPDFCatalog* catalog) {
45 return catalog->getObjectNumberSize(this) + strlen(" obj\n") +
46 this->getOutputSize(catalog, false) + strlen("\nendobj\n");
47}
48
vandebo@chromium.org421d6442011-07-20 17:39:01 +000049void SkPDFObject::AddResourceHelper(SkPDFObject* resource,
50 SkTDArray<SkPDFObject*>* list) {
51 list->push(resource);
52 resource->ref();
53}
54
55void SkPDFObject::GetResourcesHelper(SkTDArray<SkPDFObject*>* resources,
56 SkTDArray<SkPDFObject*>* result) {
57 if (resources->count()) {
58 result->setReserve(result->count() + resources->count());
59 for (int i = 0; i < resources->count(); i++) {
60 result->push((*resources)[i]);
61 (*resources)[i]->ref();
62 (*resources)[i]->getResources(result);
63 }
64 }
65}
66
67SkPDFObjRef::SkPDFObjRef(SkPDFObject* obj) : fObj(obj) {}
68SkPDFObjRef::~SkPDFObjRef() {}
69
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000070void SkPDFObjRef::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
71 bool indirect) {
72 SkASSERT(!indirect);
73 catalog->emitObjectNumber(stream, fObj.get());
74 stream->writeText(" R");
75}
76
77size_t SkPDFObjRef::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
78 SkASSERT(!indirect);
79 return catalog->getObjectNumberSize(fObj.get()) + strlen(" R");
80}
81
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +000082SkPDFInt::SkPDFInt(int32_t value) : fValue(value) {}
83SkPDFInt::~SkPDFInt() {}
84
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000085void SkPDFInt::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
86 bool indirect) {
87 if (indirect)
88 return emitIndirectObject(stream, catalog);
89 stream->writeDecAsText(fValue);
90}
91
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000092SkPDFBool::SkPDFBool(bool value) : fValue(value) {}
93SkPDFBool::~SkPDFBool() {}
94
95void SkPDFBool::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
96 bool indirect) {
97 SkASSERT(!indirect);
98 if (fValue) {
99 stream->writeText("true");
100 } else {
101 stream->writeText("false");
102 }
103}
104
105size_t SkPDFBool::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
106 SkASSERT(!indirect);
107 if (fValue)
108 return strlen("true");
109 return strlen("false");
110}
111
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +0000112SkPDFScalar::SkPDFScalar(SkScalar value) : fValue(value) {}
113SkPDFScalar::~SkPDFScalar() {}
114
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000115void SkPDFScalar::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
116 bool indirect) {
117 if (indirect)
118 return emitIndirectObject(stream, catalog);
vandebo@chromium.org094316b2011-03-04 03:15:13 +0000119
vandebo@chromium.orgcae5fba2011-03-28 19:03:50 +0000120 Append(fValue, stream);
vandebo@chromium.org094316b2011-03-04 03:15:13 +0000121}
122
123// static
vandebo@chromium.orgcae5fba2011-03-28 19:03:50 +0000124void SkPDFScalar::Append(SkScalar value, SkWStream* stream) {
vandebo@chromium.org094316b2011-03-04 03:15:13 +0000125 // The range of reals in PDF/A is the same as SkFixed: +/- 32,767 and
126 // +/- 1/65,536 (though integers can range from 2^31 - 1 to -2^31).
127 // When using floats that are outside the whole value range, we can use
128 // integers instead.
129
vandebo@chromium.orgcae5fba2011-03-28 19:03:50 +0000130
vandebo@chromium.org094316b2011-03-04 03:15:13 +0000131#if defined(SK_SCALAR_IS_FIXED)
epoger@google.com2047f002011-05-17 17:36:59 +0000132 stream->writeScalarAsText(value);
vandebo@chromium.org094316b2011-03-04 03:15:13 +0000133 return;
134#endif // SK_SCALAR_IS_FIXED
135
136#if !defined(SK_ALLOW_LARGE_PDF_SCALARS)
137 if (value > 32767 || value < -32767) {
vandebo@chromium.orgcae5fba2011-03-28 19:03:50 +0000138 stream->writeDecAsText(SkScalarRound(value));
vandebo@chromium.org094316b2011-03-04 03:15:13 +0000139 return;
140 }
141
142 char buffer[SkStrAppendScalar_MaxSize];
143 char* end = SkStrAppendFixed(buffer, SkScalarToFixed(value));
vandebo@chromium.orgcae5fba2011-03-28 19:03:50 +0000144 stream->write(buffer, end - buffer);
vandebo@chromium.org094316b2011-03-04 03:15:13 +0000145 return;
146#endif // !SK_ALLOW_LARGE_PDF_SCALARS
147
148#if defined(SK_SCALAR_IS_FLOAT) && defined(SK_ALLOW_LARGE_PDF_SCALARS)
149 // Floats have 24bits of significance, so anything outside that range is
150 // no more precise than an int. (Plus PDF doesn't support scientific
151 // notation, so this clamps to SK_Max/MinS32).
152 if (value > (1 << 24) || value < -(1 << 24)) {
vandebo@chromium.orgcae5fba2011-03-28 19:03:50 +0000153 stream->writeDecAsText(value);
vandebo@chromium.org094316b2011-03-04 03:15:13 +0000154 return;
155 }
156 // Continue to enforce the PDF limits for small floats.
157 if (value < 1.0f/65536 && value > -1.0f/65536) {
vandebo@chromium.orgcae5fba2011-03-28 19:03:50 +0000158 stream->writeDecAsText(0);
vandebo@chromium.org094316b2011-03-04 03:15:13 +0000159 return;
160 }
161 // SkStrAppendFloat might still use scientific notation, so use snprintf
162 // directly..
163 static const int kFloat_MaxSize = 19;
164 char buffer[kFloat_MaxSize];
165 int len = SNPRINTF(buffer, kFloat_MaxSize, "%#.8f", value);
166 // %f always prints trailing 0s, so strip them.
167 for (; buffer[len - 1] == '0' && len > 0; len--) {
168 buffer[len - 1] = '\0';
169 }
170 if (buffer[len - 1] == '.') {
171 buffer[len - 1] = '\0';
172 }
vandebo@chromium.orgcae5fba2011-03-28 19:03:50 +0000173 stream->writeText(buffer);
vandebo@chromium.org094316b2011-03-04 03:15:13 +0000174 return;
175#endif // SK_SCALAR_IS_FLOAT && SK_ALLOW_LARGE_PDF_SCALARS
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000176}
177
178SkPDFString::SkPDFString(const char value[])
reed@google.comf6c3ebd2011-07-20 17:20:28 +0000179 : fValue(FormatString(value, strlen(value))) {
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000180}
181
182SkPDFString::SkPDFString(const SkString& value)
reed@google.comf6c3ebd2011-07-20 17:20:28 +0000183 : fValue(FormatString(value.c_str(), value.size())) {
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000184}
185
186SkPDFString::SkPDFString(const uint16_t* value, size_t len, bool wideChars)
reed@google.comf6c3ebd2011-07-20 17:20:28 +0000187 : fValue(FormatString(value, len, wideChars)) {
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000188}
189
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +0000190SkPDFString::~SkPDFString() {}
191
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000192void SkPDFString::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
193 bool indirect) {
194 if (indirect)
195 return emitIndirectObject(stream, catalog);
196 stream->write(fValue.c_str(), fValue.size());
197}
198
199size_t SkPDFString::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
200 if (indirect)
201 return getIndirectOutputSize(catalog);
202 return fValue.size();
203}
204
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000205// static
reed@google.comf6c3ebd2011-07-20 17:20:28 +0000206SkString SkPDFString::FormatString(const char* input, size_t len) {
207 return DoFormatString(input, len, false, false);
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000208}
209
reed@google.comf6c3ebd2011-07-20 17:20:28 +0000210SkString SkPDFString::FormatString(const uint16_t* input, size_t len,
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000211 bool wideChars) {
reed@google.comf6c3ebd2011-07-20 17:20:28 +0000212 return DoFormatString(input, len, true, wideChars);
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000213}
214
215// static
reed@google.comf6c3ebd2011-07-20 17:20:28 +0000216SkString SkPDFString::DoFormatString(const void* input, size_t len,
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000217 bool wideInput, bool wideOutput) {
218 SkASSERT(len <= kMaxLen);
219 const uint16_t* win = (const uint16_t*) input;
220 const char* cin = (const char*) input;
221
222 if (wideOutput) {
223 SkASSERT(wideInput);
224 SkString result;
225 result.append("<");
226 for (size_t i = 0; i < len; i++)
227 result.appendHex(win[i], 4);
228 result.append(">");
229 return result;
230 }
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000231
232 // 7-bit clean is a heuristic to decide what string format to use;
233 // a 7-bit clean string should require little escaping.
234 bool sevenBitClean = true;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000235 for (size_t i = 0; i < len; i++) {
236 SkASSERT(!wideInput || !(win[i] & ~0xFF));
237 char val = wideInput ? win[i] : cin[i];
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000238 if (val > '~' || val < ' ') {
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000239 sevenBitClean = false;
240 break;
241 }
242 }
243
244 SkString result;
245 if (sevenBitClean) {
246 result.append("(");
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000247 for (size_t i = 0; i < len; i++) {
248 SkASSERT(!wideInput || !(win[i] & ~0xFF));
249 char val = wideInput ? win[i] : cin[i];
250 if (val == '\\' || val == '(' || val == ')')
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000251 result.append("\\");
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000252 result.append(&val, 1);
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000253 }
254 result.append(")");
255 } else {
256 result.append("<");
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000257 for (size_t i = 0; i < len; i++) {
258 SkASSERT(!wideInput || !(win[i] & ~0xFF));
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000259 unsigned char val = wideInput ? win[i] : cin[i];
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000260 result.appendHex(val, 2);
261 }
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000262 result.append(">");
263 }
264
265 return result;
266}
267
reed@google.comf6c3ebd2011-07-20 17:20:28 +0000268SkPDFName::SkPDFName(const char name[]) : fValue(FormatName(SkString(name))) {}
269SkPDFName::SkPDFName(const SkString& name) : fValue(FormatName(name)) {}
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +0000270SkPDFName::~SkPDFName() {}
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000271
vandebo@chromium.org421d6442011-07-20 17:39:01 +0000272bool SkPDFName::operator==(const SkPDFName& b) const {
273 return fValue == b.fValue;
274}
275
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000276void SkPDFName::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
277 bool indirect) {
278 SkASSERT(!indirect);
279 stream->write(fValue.c_str(), fValue.size());
280}
281
282size_t SkPDFName::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
283 SkASSERT(!indirect);
284 return fValue.size();
285}
286
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +0000287// static
reed@google.comf6c3ebd2011-07-20 17:20:28 +0000288SkString SkPDFName::FormatName(const SkString& input) {
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000289 SkASSERT(input.size() <= kMaxLen);
290
291 SkString result("/");
292 for (size_t i = 0; i < input.size(); i++) {
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +0000293 if (input[i] & 0x80 || input[i] < '!' || input[i] == '#') {
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000294 result.append("#");
295 result.appendHex(input[i], 2);
296 } else {
297 result.append(input.c_str() + i, 1);
298 }
299 }
300
301 return result;
302}
303
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +0000304SkPDFArray::SkPDFArray() {}
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000305SkPDFArray::~SkPDFArray() {
reed@google.com2812b802011-07-19 15:46:40 +0000306 fValue.unrefAll();
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000307}
308
309void SkPDFArray::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
310 bool indirect) {
311 if (indirect)
312 return emitIndirectObject(stream, catalog);
313
314 stream->writeText("[");
315 for (int i = 0; i < fValue.count(); i++) {
vandebo@chromium.org2ef12d42011-07-06 23:31:24 +0000316 fValue[i]->emit(stream, catalog, false);
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000317 if (i + 1 < fValue.count())
318 stream->writeText(" ");
319 }
320 stream->writeText("]");
321}
322
323size_t SkPDFArray::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
324 if (indirect)
325 return getIndirectOutputSize(catalog);
326
327 size_t result = strlen("[]");
328 if (fValue.count())
329 result += fValue.count() - 1;
330 for (int i = 0; i < fValue.count(); i++)
331 result += fValue[i]->getOutputSize(catalog, false);
332 return result;
333}
334
335void SkPDFArray::reserve(int length) {
336 SkASSERT(length <= kMaxLen);
337 fValue.setReserve(length);
338}
339
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000340SkPDFObject* SkPDFArray::setAt(int offset, SkPDFObject* value) {
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000341 SkASSERT(offset < fValue.count());
reed@google.com2812b802011-07-19 15:46:40 +0000342 value->ref();
343 fValue[offset]->unref();
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000344 fValue[offset] = value;
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000345 return value;
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000346}
347
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000348SkPDFObject* SkPDFArray::append(SkPDFObject* value) {
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000349 SkASSERT(fValue.count() < kMaxLen);
reed@google.com2812b802011-07-19 15:46:40 +0000350 value->ref();
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000351 fValue.push(value);
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000352 return value;
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000353}
354
reed@google.comc789cf12011-07-20 12:14:33 +0000355void SkPDFArray::appendInt(int32_t value) {
356 SkASSERT(fValue.count() < kMaxLen);
357 fValue.push(new SkPDFInt(value));
358}
359
360void SkPDFArray::appendScalar(SkScalar value) {
361 SkASSERT(fValue.count() < kMaxLen);
362 fValue.push(new SkPDFScalar(value));
363}
364
365void SkPDFArray::appendName(const char name[]) {
366 SkASSERT(fValue.count() < kMaxLen);
367 fValue.push(new SkPDFName(name));
368}
369
370///////////////////////////////////////////////////////////////////////////////
371
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +0000372SkPDFDict::SkPDFDict() {}
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +0000373
374SkPDFDict::SkPDFDict(const char type[]) {
vandebo@chromium.org06f7f402011-07-20 18:39:20 +0000375 insertName("Type", type);
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +0000376}
377
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000378SkPDFDict::~SkPDFDict() {
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +0000379 clear();
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000380}
381
382void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
383 bool indirect) {
384 if (indirect)
385 return emitIndirectObject(stream, catalog);
386
387 stream->writeText("<<");
388 for (int i = 0; i < fValue.count(); i++) {
389 fValue[i].key->emitObject(stream, catalog, false);
390 stream->writeText(" ");
vandebo@chromium.org2ef12d42011-07-06 23:31:24 +0000391 fValue[i].value->emit(stream, catalog, false);
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000392 stream->writeText("\n");
393 }
394 stream->writeText(">>");
395}
396
397size_t SkPDFDict::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
398 if (indirect)
399 return getIndirectOutputSize(catalog);
400
401 size_t result = strlen("<<>>") + (fValue.count() * 2);
402 for (int i = 0; i < fValue.count(); i++) {
403 result += fValue[i].key->getOutputSize(catalog, false);
404 result += fValue[i].value->getOutputSize(catalog, false);
405 }
406 return result;
407}
408
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000409SkPDFObject* SkPDFDict::insert(SkPDFName* key, SkPDFObject* value) {
reed@google.com2812b802011-07-19 15:46:40 +0000410 key->ref();
411 value->ref();
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000412 struct Rec* newEntry = fValue.append();
413 newEntry->key = key;
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000414 newEntry->value = value;
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000415 return value;
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000416}
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +0000417
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000418SkPDFObject* SkPDFDict::insert(const char key[], SkPDFObject* value) {
reed@google.com2812b802011-07-19 15:46:40 +0000419 value->ref();
420 struct Rec* newEntry = fValue.append();
421 newEntry->key = new SkPDFName(key);
422 newEntry->value = value;
423 return value;
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +0000424}
425
reed@google.comc789cf12011-07-20 12:14:33 +0000426void SkPDFDict::insertInt(const char key[], int32_t value) {
427 struct Rec* newEntry = fValue.append();
428 newEntry->key = new SkPDFName(key);
429 newEntry->value = new SkPDFInt(value);
430}
431
432void SkPDFDict::insertScalar(const char key[], SkScalar value) {
433 struct Rec* newEntry = fValue.append();
434 newEntry->key = new SkPDFName(key);
435 newEntry->value = new SkPDFScalar(value);
436}
437
438void SkPDFDict::insertName(const char key[], const char name[]) {
439 struct Rec* newEntry = fValue.append();
440 newEntry->key = new SkPDFName(key);
441 newEntry->value = new SkPDFName(name);
442}
443
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +0000444void SkPDFDict::clear() {
445 for (int i = 0; i < fValue.count(); i++) {
reed@google.com2812b802011-07-19 15:46:40 +0000446 fValue[i].key->unref();
447 fValue[i].value->unref();
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +0000448 }
449 fValue.reset();
450}
vandebo@chromium.org421d6442011-07-20 17:39:01 +0000451
452SkPDFDict::Iter::Iter(const SkPDFDict& dict)
453 : fIter(dict.fValue.begin()),
454 fStop(dict.fValue.end()) {
455}
456
457SkPDFName* SkPDFDict::Iter::next(SkPDFObject** value) {
458 if (fIter != fStop) {
459 Rec* cur = fIter;
460 fIter++;
461 *value = cur->value;
462 return cur->key;
463 }
464 *value = NULL;
465 return NULL;
466}