OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkPDFCatalog.h" | 10 #include "SkPDFCatalog.h" |
11 #include "SkPDFTypes.h" | 11 #include "SkPDFTypes.h" |
12 #include "SkStream.h" | 12 #include "SkStream.h" |
13 | 13 |
14 #ifdef SK_BUILD_FOR_WIN | 14 #ifdef SK_BUILD_FOR_WIN |
15 #define SNPRINTF _snprintf | 15 #define SNPRINTF _snprintf |
16 #else | 16 #else |
17 #define SNPRINTF snprintf | 17 #define SNPRINTF snprintf |
18 #endif | 18 #endif |
19 | 19 |
20 /////////////////////////////////////////////////////////////////////////////// | 20 /////////////////////////////////////////////////////////////////////////////// |
21 | 21 |
22 void SkPDFObject::emit(SkWStream* stream, SkPDFCatalog* catalog, | 22 void SkPDFObject::emit(SkWStream* stream, SkPDFCatalog* catalog, |
23 bool indirect) { | 23 bool indirect) { |
24 SkPDFObject* realObject = catalog->getSubstituteObject(this); | 24 SkPDFObject* realObject = catalog->getSubstituteObject(this); |
25 return realObject->emitObject(stream, catalog, indirect); | 25 if (indirect) { |
| 26 realObject->emitIndirectObject(stream, catalog); |
| 27 } else { |
| 28 realObject->emitObject(stream, catalog); |
| 29 } |
26 } | 30 } |
27 | 31 |
28 size_t SkPDFObject::getOutputSize(SkPDFCatalog* catalog, bool indirect) { | 32 size_t SkPDFObject::getOutputSize(SkPDFCatalog* catalog, bool indirect) { |
29 SkDynamicMemoryWStream buffer; | 33 SkDynamicMemoryWStream buffer; |
30 emit(&buffer, catalog, indirect); | 34 emit(&buffer, catalog, indirect); |
31 return buffer.getOffset(); | 35 return buffer.getOffset(); |
32 } | 36 } |
33 | 37 |
34 void SkPDFObject::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, | 38 void SkPDFObject::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, |
35 SkTSet<SkPDFObject*>* newResourceObjects) {} | 39 SkTSet<SkPDFObject*>* newResourceObjects) {} |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 } | 74 } |
71 } | 75 } |
72 } | 76 } |
73 | 77 |
74 SkPDFObjRef::SkPDFObjRef(SkPDFObject* obj) : fObj(obj) { | 78 SkPDFObjRef::SkPDFObjRef(SkPDFObject* obj) : fObj(obj) { |
75 SkSafeRef(obj); | 79 SkSafeRef(obj); |
76 } | 80 } |
77 | 81 |
78 SkPDFObjRef::~SkPDFObjRef() {} | 82 SkPDFObjRef::~SkPDFObjRef() {} |
79 | 83 |
80 void SkPDFObjRef::emitObject(SkWStream* stream, SkPDFCatalog* catalog, | 84 void SkPDFObjRef::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
81 bool indirect) { | |
82 SkASSERT(!indirect); | |
83 catalog->emitObjectNumber(stream, fObj.get()); | 85 catalog->emitObjectNumber(stream, fObj.get()); |
84 stream->writeText(" R"); | 86 stream->writeText(" R"); |
85 } | 87 } |
86 | 88 |
87 size_t SkPDFObjRef::getOutputSize(SkPDFCatalog* catalog, bool indirect) { | 89 size_t SkPDFObjRef::getOutputSize(SkPDFCatalog* catalog, bool indirect) { |
88 SkASSERT(!indirect); | 90 SkASSERT(!indirect); |
89 return catalog->getObjectNumberSize(fObj.get()) + strlen(" R"); | 91 return catalog->getObjectNumberSize(fObj.get()) + strlen(" R"); |
90 } | 92 } |
91 | 93 |
92 SkPDFInt::SkPDFInt(int32_t value) : fValue(value) {} | 94 SkPDFInt::SkPDFInt(int32_t value) : fValue(value) {} |
93 SkPDFInt::~SkPDFInt() {} | 95 SkPDFInt::~SkPDFInt() {} |
94 | 96 |
95 void SkPDFInt::emitObject(SkWStream* stream, SkPDFCatalog* catalog, | 97 void SkPDFInt::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
96 bool indirect) { | |
97 if (indirect) { | |
98 return emitIndirectObject(stream, catalog); | |
99 } | |
100 stream->writeDecAsText(fValue); | 98 stream->writeDecAsText(fValue); |
101 } | 99 } |
102 | 100 |
103 SkPDFBool::SkPDFBool(bool value) : fValue(value) {} | 101 SkPDFBool::SkPDFBool(bool value) : fValue(value) {} |
104 SkPDFBool::~SkPDFBool() {} | 102 SkPDFBool::~SkPDFBool() {} |
105 | 103 |
106 void SkPDFBool::emitObject(SkWStream* stream, SkPDFCatalog* catalog, | 104 void SkPDFBool::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
107 bool indirect) { | |
108 SkASSERT(!indirect); | |
109 if (fValue) { | 105 if (fValue) { |
110 stream->writeText("true"); | 106 stream->writeText("true"); |
111 } else { | 107 } else { |
112 stream->writeText("false"); | 108 stream->writeText("false"); |
113 } | 109 } |
114 } | 110 } |
115 | 111 |
116 size_t SkPDFBool::getOutputSize(SkPDFCatalog* catalog, bool indirect) { | 112 size_t SkPDFBool::getOutputSize(SkPDFCatalog* catalog, bool indirect) { |
117 SkASSERT(!indirect); | 113 SkASSERT(!indirect); |
118 if (fValue) { | 114 if (fValue) { |
119 return strlen("true"); | 115 return strlen("true"); |
120 } | 116 } |
121 return strlen("false"); | 117 return strlen("false"); |
122 } | 118 } |
123 | 119 |
124 SkPDFScalar::SkPDFScalar(SkScalar value) : fValue(value) {} | 120 SkPDFScalar::SkPDFScalar(SkScalar value) : fValue(value) {} |
125 SkPDFScalar::~SkPDFScalar() {} | 121 SkPDFScalar::~SkPDFScalar() {} |
126 | 122 |
127 void SkPDFScalar::emitObject(SkWStream* stream, SkPDFCatalog* catalog, | 123 void SkPDFScalar::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
128 bool indirect) { | |
129 if (indirect) { | |
130 return emitIndirectObject(stream, catalog); | |
131 } | |
132 | |
133 Append(fValue, stream); | 124 Append(fValue, stream); |
134 } | 125 } |
135 | 126 |
136 // static | 127 // static |
137 void SkPDFScalar::Append(SkScalar value, SkWStream* stream) { | 128 void SkPDFScalar::Append(SkScalar value, SkWStream* stream) { |
138 // The range of reals in PDF/A is the same as SkFixed: +/- 32,767 and | 129 // The range of reals in PDF/A is the same as SkFixed: +/- 32,767 and |
139 // +/- 1/65,536 (though integers can range from 2^31 - 1 to -2^31). | 130 // +/- 1/65,536 (though integers can range from 2^31 - 1 to -2^31). |
140 // When using floats that are outside the whole value range, we can use | 131 // When using floats that are outside the whole value range, we can use |
141 // integers instead. | 132 // integers instead. |
142 | 133 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 SkPDFString::SkPDFString(const SkString& value) | 180 SkPDFString::SkPDFString(const SkString& value) |
190 : fValue(FormatString(value.c_str(), value.size())) { | 181 : fValue(FormatString(value.c_str(), value.size())) { |
191 } | 182 } |
192 | 183 |
193 SkPDFString::SkPDFString(const uint16_t* value, size_t len, bool wideChars) | 184 SkPDFString::SkPDFString(const uint16_t* value, size_t len, bool wideChars) |
194 : fValue(FormatString(value, len, wideChars)) { | 185 : fValue(FormatString(value, len, wideChars)) { |
195 } | 186 } |
196 | 187 |
197 SkPDFString::~SkPDFString() {} | 188 SkPDFString::~SkPDFString() {} |
198 | 189 |
199 void SkPDFString::emitObject(SkWStream* stream, SkPDFCatalog* catalog, | 190 void SkPDFString::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
200 bool indirect) { | |
201 if (indirect) | |
202 return emitIndirectObject(stream, catalog); | |
203 stream->write(fValue.c_str(), fValue.size()); | 191 stream->write(fValue.c_str(), fValue.size()); |
204 } | 192 } |
205 | 193 |
206 size_t SkPDFString::getOutputSize(SkPDFCatalog* catalog, bool indirect) { | 194 size_t SkPDFString::getOutputSize(SkPDFCatalog* catalog, bool indirect) { |
207 if (indirect) | 195 if (indirect) |
208 return getIndirectOutputSize(catalog); | 196 return getIndirectOutputSize(catalog); |
209 return fValue.size(); | 197 return fValue.size(); |
210 } | 198 } |
211 | 199 |
212 // static | 200 // static |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 } | 263 } |
276 | 264 |
277 SkPDFName::SkPDFName(const char name[]) : fValue(FormatName(SkString(name))) {} | 265 SkPDFName::SkPDFName(const char name[]) : fValue(FormatName(SkString(name))) {} |
278 SkPDFName::SkPDFName(const SkString& name) : fValue(FormatName(name)) {} | 266 SkPDFName::SkPDFName(const SkString& name) : fValue(FormatName(name)) {} |
279 SkPDFName::~SkPDFName() {} | 267 SkPDFName::~SkPDFName() {} |
280 | 268 |
281 bool SkPDFName::operator==(const SkPDFName& b) const { | 269 bool SkPDFName::operator==(const SkPDFName& b) const { |
282 return fValue == b.fValue; | 270 return fValue == b.fValue; |
283 } | 271 } |
284 | 272 |
285 void SkPDFName::emitObject(SkWStream* stream, SkPDFCatalog* catalog, | 273 void SkPDFName::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
286 bool indirect) { | |
287 SkASSERT(!indirect); | |
288 stream->write(fValue.c_str(), fValue.size()); | 274 stream->write(fValue.c_str(), fValue.size()); |
289 } | 275 } |
290 | 276 |
291 size_t SkPDFName::getOutputSize(SkPDFCatalog* catalog, bool indirect) { | 277 size_t SkPDFName::getOutputSize(SkPDFCatalog* catalog, bool indirect) { |
292 SkASSERT(!indirect); | 278 SkASSERT(!indirect); |
293 return fValue.size(); | 279 return fValue.size(); |
294 } | 280 } |
295 | 281 |
296 // static | 282 // static |
297 SkString SkPDFName::FormatName(const SkString& input) { | 283 SkString SkPDFName::FormatName(const SkString& input) { |
(...skipping 13 matching lines...) Expand all Loading... |
311 } | 297 } |
312 | 298 |
313 return result; | 299 return result; |
314 } | 300 } |
315 | 301 |
316 SkPDFArray::SkPDFArray() {} | 302 SkPDFArray::SkPDFArray() {} |
317 SkPDFArray::~SkPDFArray() { | 303 SkPDFArray::~SkPDFArray() { |
318 fValue.unrefAll(); | 304 fValue.unrefAll(); |
319 } | 305 } |
320 | 306 |
321 void SkPDFArray::emitObject(SkWStream* stream, SkPDFCatalog* catalog, | 307 void SkPDFArray::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
322 bool indirect) { | |
323 if (indirect) { | |
324 return emitIndirectObject(stream, catalog); | |
325 } | |
326 | |
327 stream->writeText("["); | 308 stream->writeText("["); |
328 for (int i = 0; i < fValue.count(); i++) { | 309 for (int i = 0; i < fValue.count(); i++) { |
329 fValue[i]->emit(stream, catalog, false); | 310 fValue[i]->emit(stream, catalog, false); |
330 if (i + 1 < fValue.count()) { | 311 if (i + 1 < fValue.count()) { |
331 stream->writeText(" "); | 312 stream->writeText(" "); |
332 } | 313 } |
333 } | 314 } |
334 stream->writeText("]"); | 315 stream->writeText("]"); |
335 } | 316 } |
336 | 317 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 SkPDFDict::~SkPDFDict() { | 376 SkPDFDict::~SkPDFDict() { |
396 clear(); | 377 clear(); |
397 } | 378 } |
398 | 379 |
399 int SkPDFDict::size() const { | 380 int SkPDFDict::size() const { |
400 SkAutoMutexAcquire lock(fMutex); | 381 SkAutoMutexAcquire lock(fMutex); |
401 return fValue.count(); | 382 return fValue.count(); |
402 } | 383 } |
403 | 384 |
404 | 385 |
405 void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog, | 386 void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
406 bool indirect) { | |
407 if (indirect) { | |
408 return emitIndirectObject(stream, catalog); | |
409 } | |
410 | |
411 SkAutoMutexAcquire lock(fMutex); // If another thread triggers a | 387 SkAutoMutexAcquire lock(fMutex); // If another thread triggers a |
412 // resize while this thread is in | 388 // resize while this thread is in |
413 // the for-loop, we can be left | 389 // the for-loop, we can be left |
414 // with a bad fValue[i] reference. | 390 // with a bad fValue[i] reference. |
415 stream->writeText("<<"); | 391 stream->writeText("<<"); |
416 for (int i = 0; i < fValue.count(); i++) { | 392 for (int i = 0; i < fValue.count(); i++) { |
417 SkASSERT(fValue[i].key); | 393 SkASSERT(fValue[i].key); |
418 SkASSERT(fValue[i].value); | 394 SkASSERT(fValue[i].value); |
419 fValue[i].key->emitObject(stream, catalog, false); | 395 fValue[i].key->emitObject(stream, catalog); |
420 stream->writeText(" "); | 396 stream->writeText(" "); |
421 fValue[i].value->emit(stream, catalog, false); | 397 fValue[i].value->emit(stream, catalog, false); |
422 stream->writeText("\n"); | 398 stream->writeText("\n"); |
423 } | 399 } |
424 stream->writeText(">>"); | 400 stream->writeText(">>"); |
425 } | 401 } |
426 | 402 |
427 size_t SkPDFDict::getOutputSize(SkPDFCatalog* catalog, bool indirect) { | 403 size_t SkPDFDict::getOutputSize(SkPDFCatalog* catalog, bool indirect) { |
428 if (indirect) { | 404 if (indirect) { |
429 return getIndirectOutputSize(catalog); | 405 return getIndirectOutputSize(catalog); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 void SkPDFDict::mergeFrom(const SkPDFDict& other) { | 479 void SkPDFDict::mergeFrom(const SkPDFDict& other) { |
504 SkAutoMutexAcquire lockOther(other.fMutex); | 480 SkAutoMutexAcquire lockOther(other.fMutex); |
505 SkTDArray<Rec> copy(other.fValue); | 481 SkTDArray<Rec> copy(other.fValue); |
506 lockOther.release(); // Do not hold both mutexes at once. | 482 lockOther.release(); // Do not hold both mutexes at once. |
507 | 483 |
508 SkAutoMutexAcquire lock(fMutex); | 484 SkAutoMutexAcquire lock(fMutex); |
509 for (int i = 0; i < copy.count(); i++) { | 485 for (int i = 0; i < copy.count(); i++) { |
510 *(fValue.append()) = Rec(SkRef(copy[i].key), SkRef(copy[i].value)); | 486 *(fValue.append()) = Rec(SkRef(copy[i].key), SkRef(copy[i].value)); |
511 } | 487 } |
512 } | 488 } |
OLD | NEW |