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" |
(...skipping 27 matching lines...) Expand all Loading... |
38 void SkPDFObject::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, | 38 void SkPDFObject::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, |
39 SkTSet<SkPDFObject*>* newResourceObjects) {} | 39 SkTSet<SkPDFObject*>* newResourceObjects) {} |
40 | 40 |
41 void SkPDFObject::emitIndirectObject(SkWStream* stream, SkPDFCatalog* catalog) { | 41 void SkPDFObject::emitIndirectObject(SkWStream* stream, SkPDFCatalog* catalog) { |
42 catalog->emitObjectNumber(stream, this); | 42 catalog->emitObjectNumber(stream, this); |
43 stream->writeText(" obj\n"); | 43 stream->writeText(" obj\n"); |
44 emit(stream, catalog, false); | 44 emit(stream, catalog, false); |
45 stream->writeText("\nendobj\n"); | 45 stream->writeText("\nendobj\n"); |
46 } | 46 } |
47 | 47 |
48 size_t SkPDFObject::getIndirectOutputSize(SkPDFCatalog* catalog) { | |
49 return catalog->getObjectNumberSize(this) + strlen(" obj\n") + | |
50 this->getOutputSize(catalog, false) + strlen("\nendobj\n"); | |
51 } | |
52 | |
53 void SkPDFObject::AddResourceHelper(SkPDFObject* resource, | 48 void SkPDFObject::AddResourceHelper(SkPDFObject* resource, |
54 SkTDArray<SkPDFObject*>* list) { | 49 SkTDArray<SkPDFObject*>* list) { |
55 list->push(resource); | 50 list->push(resource); |
56 resource->ref(); | 51 resource->ref(); |
57 } | 52 } |
58 | 53 |
59 void SkPDFObject::GetResourcesHelper( | 54 void SkPDFObject::GetResourcesHelper( |
60 const SkTDArray<SkPDFObject*>* resources, | 55 const SkTDArray<SkPDFObject*>* resources, |
61 const SkTSet<SkPDFObject*>& knownResourceObjects, | 56 const SkTSet<SkPDFObject*>& knownResourceObjects, |
62 SkTSet<SkPDFObject*>* newResourceObjects) { | 57 SkTSet<SkPDFObject*>* newResourceObjects) { |
(...skipping 16 matching lines...) Expand all Loading... |
79 SkSafeRef(obj); | 74 SkSafeRef(obj); |
80 } | 75 } |
81 | 76 |
82 SkPDFObjRef::~SkPDFObjRef() {} | 77 SkPDFObjRef::~SkPDFObjRef() {} |
83 | 78 |
84 void SkPDFObjRef::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { | 79 void SkPDFObjRef::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
85 catalog->emitObjectNumber(stream, fObj.get()); | 80 catalog->emitObjectNumber(stream, fObj.get()); |
86 stream->writeText(" R"); | 81 stream->writeText(" R"); |
87 } | 82 } |
88 | 83 |
89 size_t SkPDFObjRef::getOutputSize(SkPDFCatalog* catalog, bool indirect) { | |
90 SkASSERT(!indirect); | |
91 return catalog->getObjectNumberSize(fObj.get()) + strlen(" R"); | |
92 } | |
93 | |
94 SkPDFInt::SkPDFInt(int32_t value) : fValue(value) {} | 84 SkPDFInt::SkPDFInt(int32_t value) : fValue(value) {} |
95 SkPDFInt::~SkPDFInt() {} | 85 SkPDFInt::~SkPDFInt() {} |
96 | 86 |
97 void SkPDFInt::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { | 87 void SkPDFInt::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
98 stream->writeDecAsText(fValue); | 88 stream->writeDecAsText(fValue); |
99 } | 89 } |
100 | 90 |
101 SkPDFBool::SkPDFBool(bool value) : fValue(value) {} | 91 SkPDFBool::SkPDFBool(bool value) : fValue(value) {} |
102 SkPDFBool::~SkPDFBool() {} | 92 SkPDFBool::~SkPDFBool() {} |
103 | 93 |
104 void SkPDFBool::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { | 94 void SkPDFBool::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
105 if (fValue) { | 95 if (fValue) { |
106 stream->writeText("true"); | 96 stream->writeText("true"); |
107 } else { | 97 } else { |
108 stream->writeText("false"); | 98 stream->writeText("false"); |
109 } | 99 } |
110 } | 100 } |
111 | 101 |
112 size_t SkPDFBool::getOutputSize(SkPDFCatalog* catalog, bool indirect) { | |
113 SkASSERT(!indirect); | |
114 if (fValue) { | |
115 return strlen("true"); | |
116 } | |
117 return strlen("false"); | |
118 } | |
119 | |
120 SkPDFScalar::SkPDFScalar(SkScalar value) : fValue(value) {} | 102 SkPDFScalar::SkPDFScalar(SkScalar value) : fValue(value) {} |
121 SkPDFScalar::~SkPDFScalar() {} | 103 SkPDFScalar::~SkPDFScalar() {} |
122 | 104 |
123 void SkPDFScalar::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { | 105 void SkPDFScalar::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
124 Append(fValue, stream); | 106 Append(fValue, stream); |
125 } | 107 } |
126 | 108 |
127 // static | 109 // static |
128 void SkPDFScalar::Append(SkScalar value, SkWStream* stream) { | 110 void SkPDFScalar::Append(SkScalar value, SkWStream* stream) { |
129 // The range of reals in PDF/A is the same as SkFixed: +/- 32,767 and | 111 // The range of reals in PDF/A is the same as SkFixed: +/- 32,767 and |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 SkPDFString::SkPDFString(const uint16_t* value, size_t len, bool wideChars) | 166 SkPDFString::SkPDFString(const uint16_t* value, size_t len, bool wideChars) |
185 : fValue(FormatString(value, len, wideChars)) { | 167 : fValue(FormatString(value, len, wideChars)) { |
186 } | 168 } |
187 | 169 |
188 SkPDFString::~SkPDFString() {} | 170 SkPDFString::~SkPDFString() {} |
189 | 171 |
190 void SkPDFString::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { | 172 void SkPDFString::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
191 stream->write(fValue.c_str(), fValue.size()); | 173 stream->write(fValue.c_str(), fValue.size()); |
192 } | 174 } |
193 | 175 |
194 size_t SkPDFString::getOutputSize(SkPDFCatalog* catalog, bool indirect) { | |
195 if (indirect) | |
196 return getIndirectOutputSize(catalog); | |
197 return fValue.size(); | |
198 } | |
199 | |
200 // static | 176 // static |
201 SkString SkPDFString::FormatString(const char* input, size_t len) { | 177 SkString SkPDFString::FormatString(const char* input, size_t len) { |
202 return DoFormatString(input, len, false, false); | 178 return DoFormatString(input, len, false, false); |
203 } | 179 } |
204 | 180 |
205 SkString SkPDFString::FormatString(const uint16_t* input, size_t len, | 181 SkString SkPDFString::FormatString(const uint16_t* input, size_t len, |
206 bool wideChars) { | 182 bool wideChars) { |
207 return DoFormatString(input, len, true, wideChars); | 183 return DoFormatString(input, len, true, wideChars); |
208 } | 184 } |
209 | 185 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 SkPDFName::~SkPDFName() {} | 243 SkPDFName::~SkPDFName() {} |
268 | 244 |
269 bool SkPDFName::operator==(const SkPDFName& b) const { | 245 bool SkPDFName::operator==(const SkPDFName& b) const { |
270 return fValue == b.fValue; | 246 return fValue == b.fValue; |
271 } | 247 } |
272 | 248 |
273 void SkPDFName::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { | 249 void SkPDFName::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
274 stream->write(fValue.c_str(), fValue.size()); | 250 stream->write(fValue.c_str(), fValue.size()); |
275 } | 251 } |
276 | 252 |
277 size_t SkPDFName::getOutputSize(SkPDFCatalog* catalog, bool indirect) { | |
278 SkASSERT(!indirect); | |
279 return fValue.size(); | |
280 } | |
281 | |
282 // static | 253 // static |
283 SkString SkPDFName::FormatName(const SkString& input) { | 254 SkString SkPDFName::FormatName(const SkString& input) { |
284 SkASSERT(input.size() <= kMaxLen); | 255 SkASSERT(input.size() <= kMaxLen); |
285 // TODO(vandebo) If more escaping is needed, improve the linear scan. | 256 // TODO(vandebo) If more escaping is needed, improve the linear scan. |
286 static const char escaped[] = "#/%()<>[]{}"; | 257 static const char escaped[] = "#/%()<>[]{}"; |
287 | 258 |
288 SkString result("/"); | 259 SkString result("/"); |
289 for (size_t i = 0; i < input.size(); i++) { | 260 for (size_t i = 0; i < input.size(); i++) { |
290 if (input[i] & 0x80 || input[i] < '!' || strchr(escaped, input[i])) { | 261 if (input[i] & 0x80 || input[i] < '!' || strchr(escaped, input[i])) { |
291 result.append("#"); | 262 result.append("#"); |
(...skipping 16 matching lines...) Expand all Loading... |
308 stream->writeText("["); | 279 stream->writeText("["); |
309 for (int i = 0; i < fValue.count(); i++) { | 280 for (int i = 0; i < fValue.count(); i++) { |
310 fValue[i]->emit(stream, catalog, false); | 281 fValue[i]->emit(stream, catalog, false); |
311 if (i + 1 < fValue.count()) { | 282 if (i + 1 < fValue.count()) { |
312 stream->writeText(" "); | 283 stream->writeText(" "); |
313 } | 284 } |
314 } | 285 } |
315 stream->writeText("]"); | 286 stream->writeText("]"); |
316 } | 287 } |
317 | 288 |
318 size_t SkPDFArray::getOutputSize(SkPDFCatalog* catalog, bool indirect) { | |
319 if (indirect) { | |
320 return getIndirectOutputSize(catalog); | |
321 } | |
322 | |
323 size_t result = strlen("[]"); | |
324 if (fValue.count()) { | |
325 result += fValue.count() - 1; | |
326 } | |
327 for (int i = 0; i < fValue.count(); i++) { | |
328 result += fValue[i]->getOutputSize(catalog, false); | |
329 } | |
330 return result; | |
331 } | |
332 | |
333 void SkPDFArray::reserve(int length) { | 289 void SkPDFArray::reserve(int length) { |
334 SkASSERT(length <= kMaxLen); | 290 SkASSERT(length <= kMaxLen); |
335 fValue.setReserve(length); | 291 fValue.setReserve(length); |
336 } | 292 } |
337 | 293 |
338 SkPDFObject* SkPDFArray::setAt(int offset, SkPDFObject* value) { | 294 SkPDFObject* SkPDFArray::setAt(int offset, SkPDFObject* value) { |
339 SkASSERT(offset < fValue.count()); | 295 SkASSERT(offset < fValue.count()); |
340 value->ref(); | 296 value->ref(); |
341 fValue[offset]->unref(); | 297 fValue[offset]->unref(); |
342 fValue[offset] = value; | 298 fValue[offset] = value; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 SkASSERT(fValue[i].key); | 349 SkASSERT(fValue[i].key); |
394 SkASSERT(fValue[i].value); | 350 SkASSERT(fValue[i].value); |
395 fValue[i].key->emitObject(stream, catalog); | 351 fValue[i].key->emitObject(stream, catalog); |
396 stream->writeText(" "); | 352 stream->writeText(" "); |
397 fValue[i].value->emit(stream, catalog, false); | 353 fValue[i].value->emit(stream, catalog, false); |
398 stream->writeText("\n"); | 354 stream->writeText("\n"); |
399 } | 355 } |
400 stream->writeText(">>"); | 356 stream->writeText(">>"); |
401 } | 357 } |
402 | 358 |
403 size_t SkPDFDict::getOutputSize(SkPDFCatalog* catalog, bool indirect) { | |
404 if (indirect) { | |
405 return getIndirectOutputSize(catalog); | |
406 } | |
407 | |
408 SkAutoMutexAcquire lock(fMutex); // If another thread triggers a | |
409 // resize while this thread is in | |
410 // the for-loop, we can be left | |
411 // with a bad fValue[i] reference. | |
412 size_t result = strlen("<<>>") + (fValue.count() * 2); | |
413 for (int i = 0; i < fValue.count(); i++) { | |
414 SkASSERT(fValue[i].key); | |
415 SkASSERT(fValue[i].value); | |
416 result += fValue[i].key->getOutputSize(catalog, false); | |
417 result += fValue[i].value->getOutputSize(catalog, false); | |
418 } | |
419 return result; | |
420 } | |
421 | |
422 SkPDFObject* SkPDFDict::append(SkPDFName* key, SkPDFObject* value) { | 359 SkPDFObject* SkPDFDict::append(SkPDFName* key, SkPDFObject* value) { |
423 SkASSERT(key); | 360 SkASSERT(key); |
424 SkASSERT(value); | 361 SkASSERT(value); |
425 SkAutoMutexAcquire lock(fMutex); // If the SkTDArray resizes while | 362 SkAutoMutexAcquire lock(fMutex); // If the SkTDArray resizes while |
426 // two threads access array, one | 363 // two threads access array, one |
427 // is left with a bad pointer. | 364 // is left with a bad pointer. |
428 *(fValue.append()) = Rec(key, value); | 365 *(fValue.append()) = Rec(key, value); |
429 return value; | 366 return value; |
430 } | 367 } |
431 | 368 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 void SkPDFDict::mergeFrom(const SkPDFDict& other) { | 416 void SkPDFDict::mergeFrom(const SkPDFDict& other) { |
480 SkAutoMutexAcquire lockOther(other.fMutex); | 417 SkAutoMutexAcquire lockOther(other.fMutex); |
481 SkTDArray<Rec> copy(other.fValue); | 418 SkTDArray<Rec> copy(other.fValue); |
482 lockOther.release(); // Do not hold both mutexes at once. | 419 lockOther.release(); // Do not hold both mutexes at once. |
483 | 420 |
484 SkAutoMutexAcquire lock(fMutex); | 421 SkAutoMutexAcquire lock(fMutex); |
485 for (int i = 0; i < copy.count(); i++) { | 422 for (int i = 0; i < copy.count(); i++) { |
486 *(fValue.append()) = Rec(SkRef(copy[i].key), SkRef(copy[i].value)); | 423 *(fValue.append()) = Rec(SkRef(copy[i].key), SkRef(copy[i].value)); |
487 } | 424 } |
488 } | 425 } |
OLD | NEW |