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 |