| 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 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 | 305 |
| 306 SkPDFDict::SkPDFDict(const char type[]) { | 306 SkPDFDict::SkPDFDict(const char type[]) { |
| 307 insertName("Type", type); | 307 insertName("Type", type); |
| 308 } | 308 } |
| 309 | 309 |
| 310 SkPDFDict::~SkPDFDict() { | 310 SkPDFDict::~SkPDFDict() { |
| 311 clear(); | 311 clear(); |
| 312 } | 312 } |
| 313 | 313 |
| 314 int SkPDFDict::size() const { | 314 int SkPDFDict::size() const { |
| 315 SkAutoMutexAcquire lock(fMutex); | |
| 316 return fValue.count(); | 315 return fValue.count(); |
| 317 } | 316 } |
| 318 | 317 |
| 319 void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { | 318 void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
| 320 SkAutoMutexAcquire lock(fMutex); // If another thread triggers a | |
| 321 // resize while this thread is in | |
| 322 // the for-loop, we can be left | |
| 323 // with a bad fValue[i] reference. | |
| 324 stream->writeText("<<"); | 319 stream->writeText("<<"); |
| 325 for (int i = 0; i < fValue.count(); i++) { | 320 for (int i = 0; i < fValue.count(); i++) { |
| 326 SkASSERT(fValue[i].key); | 321 SkASSERT(fValue[i].key); |
| 327 SkASSERT(fValue[i].value); | 322 SkASSERT(fValue[i].value); |
| 328 fValue[i].key->emitObject(stream, catalog); | 323 fValue[i].key->emitObject(stream, catalog); |
| 329 stream->writeText(" "); | 324 stream->writeText(" "); |
| 330 catalog->getSubstituteObject(fValue[i].value) | 325 catalog->getSubstituteObject(fValue[i].value) |
| 331 ->emitObject(stream, catalog); | 326 ->emitObject(stream, catalog); |
| 332 stream->writeText("\n"); | 327 stream->writeText("\n"); |
| 333 } | 328 } |
| 334 stream->writeText(">>"); | 329 stream->writeText(">>"); |
| 335 } | 330 } |
| 336 | 331 |
| 337 void SkPDFDict::addResources(SkTSet<SkPDFObject*>* resourceSet, | 332 void SkPDFDict::addResources(SkTSet<SkPDFObject*>* resourceSet, |
| 338 SkPDFCatalog* catalog) const { | 333 SkPDFCatalog* catalog) const { |
| 339 for (int i = 0; i < fValue.count(); i++) { | 334 for (int i = 0; i < fValue.count(); i++) { |
| 340 SkASSERT(fValue[i].key); | 335 SkASSERT(fValue[i].key); |
| 341 SkASSERT(fValue[i].value); | 336 SkASSERT(fValue[i].value); |
| 342 fValue[i].key->addResources(resourceSet, catalog); | 337 fValue[i].key->addResources(resourceSet, catalog); |
| 343 catalog->getSubstituteObject(fValue[i].value) | 338 catalog->getSubstituteObject(fValue[i].value) |
| 344 ->addResources(resourceSet, catalog); | 339 ->addResources(resourceSet, catalog); |
| 345 } | 340 } |
| 346 } | 341 } |
| 347 | 342 |
| 348 SkPDFObject* SkPDFDict::append(SkPDFName* key, SkPDFObject* value) { | 343 SkPDFObject* SkPDFDict::append(SkPDFName* key, SkPDFObject* value) { |
| 349 SkASSERT(key); | 344 SkASSERT(key); |
| 350 SkASSERT(value); | 345 SkASSERT(value); |
| 351 SkAutoMutexAcquire lock(fMutex); // If the SkTDArray resizes while | |
| 352 // two threads access array, one | |
| 353 // is left with a bad pointer. | |
| 354 *(fValue.append()) = Rec(key, value); | 346 *(fValue.append()) = Rec(key, value); |
| 355 return value; | 347 return value; |
| 356 } | 348 } |
| 357 | 349 |
| 358 SkPDFObject* SkPDFDict::insert(SkPDFName* key, SkPDFObject* value) { | 350 SkPDFObject* SkPDFDict::insert(SkPDFName* key, SkPDFObject* value) { |
| 359 return this->append(SkRef(key), SkRef(value)); | 351 return this->append(SkRef(key), SkRef(value)); |
| 360 } | 352 } |
| 361 | 353 |
| 362 SkPDFObject* SkPDFDict::insert(const char key[], SkPDFObject* value) { | 354 SkPDFObject* SkPDFDict::insert(const char key[], SkPDFObject* value) { |
| 363 return this->append(new SkPDFName(key), SkRef(value)); | 355 return this->append(new SkPDFName(key), SkRef(value)); |
| 364 } | 356 } |
| 365 | 357 |
| 366 void SkPDFDict::insertInt(const char key[], int32_t value) { | 358 void SkPDFDict::insertInt(const char key[], int32_t value) { |
| 367 (void)this->append(new SkPDFName(key), new SkPDFInt(value)); | 359 (void)this->append(new SkPDFName(key), new SkPDFInt(value)); |
| 368 } | 360 } |
| 369 | 361 |
| 370 void SkPDFDict::insertScalar(const char key[], SkScalar value) { | 362 void SkPDFDict::insertScalar(const char key[], SkScalar value) { |
| 371 (void)this->append(new SkPDFName(key), new SkPDFScalar(value)); | 363 (void)this->append(new SkPDFName(key), new SkPDFScalar(value)); |
| 372 } | 364 } |
| 373 | 365 |
| 374 void SkPDFDict::insertName(const char key[], const char name[]) { | 366 void SkPDFDict::insertName(const char key[], const char name[]) { |
| 375 (void)this->append(new SkPDFName(key), new SkPDFName(name)); | 367 (void)this->append(new SkPDFName(key), new SkPDFName(name)); |
| 376 } | 368 } |
| 377 | 369 |
| 378 void SkPDFDict::clear() { | 370 void SkPDFDict::clear() { |
| 379 SkAutoMutexAcquire lock(fMutex); | |
| 380 for (int i = 0; i < fValue.count(); i++) { | 371 for (int i = 0; i < fValue.count(); i++) { |
| 381 SkASSERT(fValue[i].key); | 372 SkASSERT(fValue[i].key); |
| 382 SkASSERT(fValue[i].value); | 373 SkASSERT(fValue[i].value); |
| 383 fValue[i].key->unref(); | 374 fValue[i].key->unref(); |
| 384 fValue[i].value->unref(); | 375 fValue[i].value->unref(); |
| 385 } | 376 } |
| 386 fValue.reset(); | 377 fValue.reset(); |
| 387 } | 378 } |
| 388 | 379 |
| 389 void SkPDFDict::remove(const char key[]) { | 380 void SkPDFDict::remove(const char key[]) { |
| 390 SkASSERT(key); | 381 SkASSERT(key); |
| 391 SkPDFName name(key); | 382 SkPDFName name(key); |
| 392 SkAutoMutexAcquire lock(fMutex); | |
| 393 for (int i = 0; i < fValue.count(); i++) { | 383 for (int i = 0; i < fValue.count(); i++) { |
| 394 SkASSERT(fValue[i].key); | 384 SkASSERT(fValue[i].key); |
| 395 if (*(fValue[i].key) == name) { | 385 if (*(fValue[i].key) == name) { |
| 396 fValue[i].key->unref(); | 386 fValue[i].key->unref(); |
| 397 SkASSERT(fValue[i].value); | 387 SkASSERT(fValue[i].value); |
| 398 fValue[i].value->unref(); | 388 fValue[i].value->unref(); |
| 399 fValue.removeShuffle(i); | 389 fValue.removeShuffle(i); |
| 400 return; | 390 return; |
| 401 } | 391 } |
| 402 } | 392 } |
| 403 } | 393 } |
| 404 | 394 |
| 405 void SkPDFDict::mergeFrom(const SkPDFDict& other) { | 395 void SkPDFDict::mergeFrom(const SkPDFDict& other) { |
| 406 SkAutoMutexAcquire lockOther(other.fMutex); | 396 for (int i = 0; i < other.fValue.count(); i++) { |
| 407 SkTDArray<Rec> copy(other.fValue); | 397 *(fValue.append()) = |
| 408 lockOther.release(); // Do not hold both mutexes at once. | 398 Rec(SkRef(other.fValue[i].key), SkRef(other.fValue[i].value)); |
| 409 | |
| 410 SkAutoMutexAcquire lock(fMutex); | |
| 411 for (int i = 0; i < copy.count(); i++) { | |
| 412 *(fValue.append()) = Rec(SkRef(copy[i].key), SkRef(copy[i].value)); | |
| 413 } | 399 } |
| 414 } | 400 } |
| OLD | NEW |