| 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 |