| 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, | |
| 23 bool indirect) { | |
| 24 SkPDFObject* realObject = catalog->getSubstituteObject(this); | |
| 25 if (indirect) { | |
| 26 realObject->emitIndirectObject(stream, catalog); | |
| 27 } else { | |
| 28 realObject->emitObject(stream, catalog); | |
| 29 } | |
| 30 } | |
| 31 | |
| 32 size_t SkPDFObject::getOutputSize(SkPDFCatalog* catalog, bool indirect) { | |
| 33 SkDynamicMemoryWStream buffer; | |
| 34 emit(&buffer, catalog, indirect); | |
| 35 return buffer.getOffset(); | |
| 36 } | |
| 37 | |
| 38 void SkPDFObject::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, | 22 void SkPDFObject::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, |
| 39 SkTSet<SkPDFObject*>* newResourceObjects) {} | 23 SkTSet<SkPDFObject*>* newResourceObjects) {} |
| 40 | 24 |
| 41 void SkPDFObject::emitIndirectObject(SkWStream* stream, SkPDFCatalog* catalog) { | |
| 42 catalog->emitObjectNumber(stream, this); | |
| 43 stream->writeText(" obj\n"); | |
| 44 emit(stream, catalog, false); | |
| 45 stream->writeText("\nendobj\n"); | |
| 46 } | |
| 47 | |
| 48 void SkPDFObject::AddResourceHelper(SkPDFObject* resource, | 25 void SkPDFObject::AddResourceHelper(SkPDFObject* resource, |
| 49 SkTDArray<SkPDFObject*>* list) { | 26 SkTDArray<SkPDFObject*>* list) { |
| 50 list->push(resource); | 27 list->push(resource); |
| 51 resource->ref(); | 28 resource->ref(); |
| 52 } | 29 } |
| 53 | 30 |
| 54 void SkPDFObject::GetResourcesHelper( | 31 void SkPDFObject::GetResourcesHelper( |
| 55 const SkTDArray<SkPDFObject*>* resources, | 32 const SkTDArray<SkPDFObject*>* resources, |
| 56 const SkTSet<SkPDFObject*>& knownResourceObjects, | 33 const SkTSet<SkPDFObject*>& knownResourceObjects, |
| 57 SkTSet<SkPDFObject*>* newResourceObjects) { | 34 SkTSet<SkPDFObject*>* newResourceObjects) { |
| 58 if (resources->count()) { | 35 if (resources->count()) { |
| 59 newResourceObjects->setReserve( | 36 newResourceObjects->setReserve( |
| 60 newResourceObjects->count() + resources->count()); | 37 newResourceObjects->count() + resources->count()); |
| 61 for (int i = 0; i < resources->count(); i++) { | 38 for (int i = 0; i < resources->count(); i++) { |
| 62 if (!knownResourceObjects.contains((*resources)[i]) && | 39 if (!knownResourceObjects.contains((*resources)[i]) && |
| 63 !newResourceObjects->contains((*resources)[i])) { | 40 !newResourceObjects->contains((*resources)[i])) { |
| 64 newResourceObjects->add((*resources)[i]); | 41 newResourceObjects->add((*resources)[i]); |
| 65 (*resources)[i]->ref(); | 42 (*resources)[i]->ref(); |
| 66 (*resources)[i]->getResources(knownResourceObjects, | 43 (*resources)[i]->getResources(knownResourceObjects, |
| 67 newResourceObjects); | 44 newResourceObjects); |
| 68 } | 45 } |
| 69 } | 46 } |
| 70 } | 47 } |
| 71 } | 48 } |
| 72 | 49 |
| 50 //////////////////////////////////////////////////////////////////////////////// |
| 51 |
| 73 SkPDFObjRef::SkPDFObjRef(SkPDFObject* obj) : fObj(obj) { | 52 SkPDFObjRef::SkPDFObjRef(SkPDFObject* obj) : fObj(obj) { |
| 74 SkSafeRef(obj); | 53 SkSafeRef(obj); |
| 75 } | 54 } |
| 76 | 55 |
| 77 SkPDFObjRef::~SkPDFObjRef() {} | 56 SkPDFObjRef::~SkPDFObjRef() {} |
| 78 | 57 |
| 79 void SkPDFObjRef::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { | 58 void SkPDFObjRef::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
| 80 catalog->emitObjectNumber(stream, fObj.get()); | 59 catalog->emitObjectNumber(stream, fObj.get()); |
| 81 stream->writeText(" R"); | 60 stream->writeText(" R"); |
| 82 } | 61 } |
| 83 | 62 |
| 63 //////////////////////////////////////////////////////////////////////////////// |
| 64 |
| 84 SkPDFInt::SkPDFInt(int32_t value) : fValue(value) {} | 65 SkPDFInt::SkPDFInt(int32_t value) : fValue(value) {} |
| 85 SkPDFInt::~SkPDFInt() {} | 66 SkPDFInt::~SkPDFInt() {} |
| 86 | 67 |
| 87 void SkPDFInt::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { | 68 void SkPDFInt::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
| 88 stream->writeDecAsText(fValue); | 69 stream->writeDecAsText(fValue); |
| 89 } | 70 } |
| 90 | 71 |
| 72 //////////////////////////////////////////////////////////////////////////////// |
| 73 |
| 91 SkPDFBool::SkPDFBool(bool value) : fValue(value) {} | 74 SkPDFBool::SkPDFBool(bool value) : fValue(value) {} |
| 92 SkPDFBool::~SkPDFBool() {} | 75 SkPDFBool::~SkPDFBool() {} |
| 93 | 76 |
| 94 void SkPDFBool::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { | 77 void SkPDFBool::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
| 95 if (fValue) { | 78 if (fValue) { |
| 96 stream->writeText("true"); | 79 stream->writeText("true"); |
| 97 } else { | 80 } else { |
| 98 stream->writeText("false"); | 81 stream->writeText("false"); |
| 99 } | 82 } |
| 100 } | 83 } |
| 101 | 84 |
| 85 //////////////////////////////////////////////////////////////////////////////// |
| 86 |
| 102 SkPDFScalar::SkPDFScalar(SkScalar value) : fValue(value) {} | 87 SkPDFScalar::SkPDFScalar(SkScalar value) : fValue(value) {} |
| 103 SkPDFScalar::~SkPDFScalar() {} | 88 SkPDFScalar::~SkPDFScalar() {} |
| 104 | 89 |
| 105 void SkPDFScalar::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { | 90 void SkPDFScalar::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
| 106 Append(fValue, stream); | 91 Append(fValue, stream); |
| 107 } | 92 } |
| 108 | 93 |
| 109 // static | 94 // static |
| 110 void SkPDFScalar::Append(SkScalar value, SkWStream* stream) { | 95 void SkPDFScalar::Append(SkScalar value, SkWStream* stream) { |
| 111 // The range of reals in PDF/A is the same as SkFixed: +/- 32,767 and | 96 // The range of reals in PDF/A is the same as SkFixed: +/- 32,767 and |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 buffer[len - 1] = '\0'; | 133 buffer[len - 1] = '\0'; |
| 149 } | 134 } |
| 150 if (buffer[len - 1] == '.') { | 135 if (buffer[len - 1] == '.') { |
| 151 buffer[len - 1] = '\0'; | 136 buffer[len - 1] = '\0'; |
| 152 } | 137 } |
| 153 stream->writeText(buffer); | 138 stream->writeText(buffer); |
| 154 return; | 139 return; |
| 155 #endif // SK_ALLOW_LARGE_PDF_SCALARS | 140 #endif // SK_ALLOW_LARGE_PDF_SCALARS |
| 156 } | 141 } |
| 157 | 142 |
| 143 //////////////////////////////////////////////////////////////////////////////// |
| 144 |
| 158 SkPDFString::SkPDFString(const char value[]) | 145 SkPDFString::SkPDFString(const char value[]) |
| 159 : fValue(FormatString(value, strlen(value))) { | 146 : fValue(FormatString(value, strlen(value))) { |
| 160 } | 147 } |
| 161 | 148 |
| 162 SkPDFString::SkPDFString(const SkString& value) | 149 SkPDFString::SkPDFString(const SkString& value) |
| 163 : fValue(FormatString(value.c_str(), value.size())) { | 150 : fValue(FormatString(value.c_str(), value.size())) { |
| 164 } | 151 } |
| 165 | 152 |
| 166 SkPDFString::SkPDFString(const uint16_t* value, size_t len, bool wideChars) | 153 SkPDFString::SkPDFString(const uint16_t* value, size_t len, bool wideChars) |
| 167 : fValue(FormatString(value, len, wideChars)) { | 154 : fValue(FormatString(value, len, wideChars)) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 SkASSERT(!wideInput || !(win[i] & ~0xFF)); | 218 SkASSERT(!wideInput || !(win[i] & ~0xFF)); |
| 232 unsigned char val = wideInput ? win[i] : cin[i]; | 219 unsigned char val = wideInput ? win[i] : cin[i]; |
| 233 result.appendHex(val, 2); | 220 result.appendHex(val, 2); |
| 234 } | 221 } |
| 235 result.append(">"); | 222 result.append(">"); |
| 236 } | 223 } |
| 237 | 224 |
| 238 return result; | 225 return result; |
| 239 } | 226 } |
| 240 | 227 |
| 228 //////////////////////////////////////////////////////////////////////////////// |
| 229 |
| 241 SkPDFName::SkPDFName(const char name[]) : fValue(FormatName(SkString(name))) {} | 230 SkPDFName::SkPDFName(const char name[]) : fValue(FormatName(SkString(name))) {} |
| 242 SkPDFName::SkPDFName(const SkString& name) : fValue(FormatName(name)) {} | 231 SkPDFName::SkPDFName(const SkString& name) : fValue(FormatName(name)) {} |
| 243 SkPDFName::~SkPDFName() {} | 232 SkPDFName::~SkPDFName() {} |
| 244 | 233 |
| 245 bool SkPDFName::operator==(const SkPDFName& b) const { | 234 bool SkPDFName::operator==(const SkPDFName& b) const { |
| 246 return fValue == b.fValue; | 235 return fValue == b.fValue; |
| 247 } | 236 } |
| 248 | 237 |
| 249 void SkPDFName::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { | 238 void SkPDFName::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
| 250 stream->write(fValue.c_str(), fValue.size()); | 239 stream->write(fValue.c_str(), fValue.size()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 263 // Mask with 0xFF to avoid sign extension. i.e. #FFFFFF81 | 252 // Mask with 0xFF to avoid sign extension. i.e. #FFFFFF81 |
| 264 result.appendHex(input[i] & 0xFF, 2); | 253 result.appendHex(input[i] & 0xFF, 2); |
| 265 } else { | 254 } else { |
| 266 result.append(input.c_str() + i, 1); | 255 result.append(input.c_str() + i, 1); |
| 267 } | 256 } |
| 268 } | 257 } |
| 269 | 258 |
| 270 return result; | 259 return result; |
| 271 } | 260 } |
| 272 | 261 |
| 262 //////////////////////////////////////////////////////////////////////////////// |
| 263 |
| 273 SkPDFArray::SkPDFArray() {} | 264 SkPDFArray::SkPDFArray() {} |
| 274 SkPDFArray::~SkPDFArray() { | 265 SkPDFArray::~SkPDFArray() { |
| 275 fValue.unrefAll(); | 266 fValue.unrefAll(); |
| 276 } | 267 } |
| 277 | 268 |
| 278 void SkPDFArray::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { | 269 void SkPDFArray::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
| 279 stream->writeText("["); | 270 stream->writeText("["); |
| 280 for (int i = 0; i < fValue.count(); i++) { | 271 for (int i = 0; i < fValue.count(); i++) { |
| 281 fValue[i]->emit(stream, catalog, false); | 272 catalog->getSubstituteObject(fValue[i])->emitObject(stream, catalog); |
| 282 if (i + 1 < fValue.count()) { | 273 if (i + 1 < fValue.count()) { |
| 283 stream->writeText(" "); | 274 stream->writeText(" "); |
| 284 } | 275 } |
| 285 } | 276 } |
| 286 stream->writeText("]"); | 277 stream->writeText("]"); |
| 287 } | 278 } |
| 288 | 279 |
| 289 void SkPDFArray::reserve(int length) { | 280 void SkPDFArray::reserve(int length) { |
| 290 SkASSERT(length <= kMaxLen); | 281 SkASSERT(length <= kMaxLen); |
| 291 fValue.setReserve(length); | 282 fValue.setReserve(length); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 | 322 |
| 332 SkPDFDict::~SkPDFDict() { | 323 SkPDFDict::~SkPDFDict() { |
| 333 clear(); | 324 clear(); |
| 334 } | 325 } |
| 335 | 326 |
| 336 int SkPDFDict::size() const { | 327 int SkPDFDict::size() const { |
| 337 SkAutoMutexAcquire lock(fMutex); | 328 SkAutoMutexAcquire lock(fMutex); |
| 338 return fValue.count(); | 329 return fValue.count(); |
| 339 } | 330 } |
| 340 | 331 |
| 341 | |
| 342 void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { | 332 void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
| 343 SkAutoMutexAcquire lock(fMutex); // If another thread triggers a | 333 SkAutoMutexAcquire lock(fMutex); // If another thread triggers a |
| 344 // resize while this thread is in | 334 // resize while this thread is in |
| 345 // the for-loop, we can be left | 335 // the for-loop, we can be left |
| 346 // with a bad fValue[i] reference. | 336 // with a bad fValue[i] reference. |
| 347 stream->writeText("<<"); | 337 stream->writeText("<<"); |
| 348 for (int i = 0; i < fValue.count(); i++) { | 338 for (int i = 0; i < fValue.count(); i++) { |
| 349 SkASSERT(fValue[i].key); | 339 SkASSERT(fValue[i].key); |
| 350 SkASSERT(fValue[i].value); | 340 SkASSERT(fValue[i].value); |
| 351 fValue[i].key->emitObject(stream, catalog); | 341 fValue[i].key->emitObject(stream, catalog); |
| 352 stream->writeText(" "); | 342 stream->writeText(" "); |
| 353 fValue[i].value->emit(stream, catalog, false); | 343 catalog->getSubstituteObject(fValue[i].value) |
| 344 ->emitObject(stream, catalog); |
| 354 stream->writeText("\n"); | 345 stream->writeText("\n"); |
| 355 } | 346 } |
| 356 stream->writeText(">>"); | 347 stream->writeText(">>"); |
| 357 } | 348 } |
| 358 | 349 |
| 359 SkPDFObject* SkPDFDict::append(SkPDFName* key, SkPDFObject* value) { | 350 SkPDFObject* SkPDFDict::append(SkPDFName* key, SkPDFObject* value) { |
| 360 SkASSERT(key); | 351 SkASSERT(key); |
| 361 SkASSERT(value); | 352 SkASSERT(value); |
| 362 SkAutoMutexAcquire lock(fMutex); // If the SkTDArray resizes while | 353 SkAutoMutexAcquire lock(fMutex); // If the SkTDArray resizes while |
| 363 // two threads access array, one | 354 // two threads access array, one |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 void SkPDFDict::mergeFrom(const SkPDFDict& other) { | 407 void SkPDFDict::mergeFrom(const SkPDFDict& other) { |
| 417 SkAutoMutexAcquire lockOther(other.fMutex); | 408 SkAutoMutexAcquire lockOther(other.fMutex); |
| 418 SkTDArray<Rec> copy(other.fValue); | 409 SkTDArray<Rec> copy(other.fValue); |
| 419 lockOther.release(); // Do not hold both mutexes at once. | 410 lockOther.release(); // Do not hold both mutexes at once. |
| 420 | 411 |
| 421 SkAutoMutexAcquire lock(fMutex); | 412 SkAutoMutexAcquire lock(fMutex); |
| 422 for (int i = 0; i < copy.count(); i++) { | 413 for (int i = 0; i < copy.count(); i++) { |
| 423 *(fValue.append()) = Rec(SkRef(copy[i].key), SkRef(copy[i].value)); | 414 *(fValue.append()) = Rec(SkRef(copy[i].key), SkRef(copy[i].value)); |
| 424 } | 415 } |
| 425 } | 416 } |
| OLD | NEW |