OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkDeflate.h" | 8 #include "SkDeflate.h" |
9 #include "SkPDFTypes.h" | 9 #include "SkPDFTypes.h" |
10 #include "SkPDFUtils.h" | 10 #include "SkPDFUtils.h" |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 fValue.emitObject(stream, objNumMap, substitutes); | 256 fValue.emitObject(stream, objNumMap, substitutes); |
257 } | 257 } |
258 void SkPDFAtom::addResources(SkPDFObjNumMap* map, | 258 void SkPDFAtom::addResources(SkPDFObjNumMap* map, |
259 const SkPDFSubstituteMap& substitutes) const { | 259 const SkPDFSubstituteMap& substitutes) const { |
260 fValue.addResources(map, substitutes); | 260 fValue.addResources(map, substitutes); |
261 } | 261 } |
262 #endif // 0 | 262 #endif // 0 |
263 | 263 |
264 //////////////////////////////////////////////////////////////////////////////// | 264 //////////////////////////////////////////////////////////////////////////////// |
265 | 265 |
266 SkPDFArray::SkPDFArray() {} | 266 SkPDFArray::SkPDFArray() { SkDEBUGCODE(fDumped = false;) } |
267 SkPDFArray::~SkPDFArray() { | 267 |
268 for (SkPDFUnion& value : fValues) { | 268 SkPDFArray::~SkPDFArray() { this->drop(); } |
269 value.~SkPDFUnion(); | 269 |
270 } | 270 void SkPDFArray::drop() { |
271 fValues.reset(); | 271 fValues.reset(); |
| 272 SkDEBUGCODE(fDumped = true;) |
272 } | 273 } |
273 | 274 |
274 int SkPDFArray::size() const { return fValues.count(); } | 275 int SkPDFArray::size() const { return fValues.count(); } |
275 | 276 |
276 void SkPDFArray::reserve(int length) { fValues.setReserve(length); } | 277 void SkPDFArray::reserve(int length) { |
| 278 // TODO(halcanary): implement SkTArray<T>::reserve() or change the |
| 279 // contstructor of SkPDFArray to take reserve size. |
| 280 } |
277 | 281 |
278 void SkPDFArray::emitObject(SkWStream* stream, | 282 void SkPDFArray::emitObject(SkWStream* stream, |
279 const SkPDFObjNumMap& objNumMap, | 283 const SkPDFObjNumMap& objNumMap, |
280 const SkPDFSubstituteMap& substitutes) const { | 284 const SkPDFSubstituteMap& substitutes) const { |
| 285 SkASSERT(!fDumped); |
281 stream->writeText("["); | 286 stream->writeText("["); |
282 for (int i = 0; i < fValues.count(); i++) { | 287 for (int i = 0; i < fValues.count(); i++) { |
283 fValues[i].emitObject(stream, objNumMap, substitutes); | 288 fValues[i].emitObject(stream, objNumMap, substitutes); |
284 if (i + 1 < fValues.count()) { | 289 if (i + 1 < fValues.count()) { |
285 stream->writeText(" "); | 290 stream->writeText(" "); |
286 } | 291 } |
287 } | 292 } |
288 stream->writeText("]"); | 293 stream->writeText("]"); |
289 } | 294 } |
290 | 295 |
291 void SkPDFArray::addResources(SkPDFObjNumMap* catalog, | 296 void SkPDFArray::addResources(SkPDFObjNumMap* catalog, |
292 const SkPDFSubstituteMap& substitutes) const { | 297 const SkPDFSubstituteMap& substitutes) const { |
| 298 SkASSERT(!fDumped); |
293 for (const SkPDFUnion& value : fValues) { | 299 for (const SkPDFUnion& value : fValues) { |
294 value.addResources(catalog, substitutes); | 300 value.addResources(catalog, substitutes); |
295 } | 301 } |
296 } | 302 } |
297 | 303 |
298 void SkPDFArray::append(SkPDFUnion&& value) { | 304 void SkPDFArray::append(SkPDFUnion&& value) { |
299 new (fValues.append()) SkPDFUnion(std::move(value)); | 305 fValues.emplace_back(std::move(value)); |
300 } | 306 } |
301 | 307 |
302 void SkPDFArray::appendInt(int32_t value) { | 308 void SkPDFArray::appendInt(int32_t value) { |
303 this->append(SkPDFUnion::Int(value)); | 309 this->append(SkPDFUnion::Int(value)); |
304 } | 310 } |
305 | 311 |
306 void SkPDFArray::appendBool(bool value) { | 312 void SkPDFArray::appendBool(bool value) { |
307 this->append(SkPDFUnion::Bool(value)); | 313 this->append(SkPDFUnion::Bool(value)); |
308 } | 314 } |
309 | 315 |
(...skipping 20 matching lines...) Expand all Loading... |
330 void SkPDFArray::appendObject(sk_sp<SkPDFObject> objSp) { | 336 void SkPDFArray::appendObject(sk_sp<SkPDFObject> objSp) { |
331 this->append(SkPDFUnion::Object(std::move(objSp))); | 337 this->append(SkPDFUnion::Object(std::move(objSp))); |
332 } | 338 } |
333 | 339 |
334 void SkPDFArray::appendObjRef(sk_sp<SkPDFObject> objSp) { | 340 void SkPDFArray::appendObjRef(sk_sp<SkPDFObject> objSp) { |
335 this->append(SkPDFUnion::ObjRef(std::move(objSp))); | 341 this->append(SkPDFUnion::ObjRef(std::move(objSp))); |
336 } | 342 } |
337 | 343 |
338 /////////////////////////////////////////////////////////////////////////////// | 344 /////////////////////////////////////////////////////////////////////////////// |
339 | 345 |
340 SkPDFDict::SkPDFDict() {} | 346 SkPDFDict::~SkPDFDict() { this->drop(); } |
341 | 347 |
342 SkPDFDict::~SkPDFDict() { this->clear(); } | 348 void SkPDFDict::drop() { |
| 349 fRecords.reset(); |
| 350 SkDEBUGCODE(fDumped = true;) |
| 351 } |
343 | 352 |
344 SkPDFDict::SkPDFDict(const char type[]) { this->insertName("Type", type); } | 353 SkPDFDict::SkPDFDict(const char type[]) { |
| 354 SkDEBUGCODE(fDumped = false;) |
| 355 if (type) { |
| 356 this->insertName("Type", type); |
| 357 } |
| 358 } |
345 | 359 |
346 void SkPDFDict::emitObject(SkWStream* stream, | 360 void SkPDFDict::emitObject(SkWStream* stream, |
347 const SkPDFObjNumMap& objNumMap, | 361 const SkPDFObjNumMap& objNumMap, |
348 const SkPDFSubstituteMap& substitutes) const { | 362 const SkPDFSubstituteMap& substitutes) const { |
349 stream->writeText("<<"); | 363 stream->writeText("<<"); |
350 this->emitAll(stream, objNumMap, substitutes); | 364 this->emitAll(stream, objNumMap, substitutes); |
351 stream->writeText(">>"); | 365 stream->writeText(">>"); |
352 } | 366 } |
353 | 367 |
354 void SkPDFDict::emitAll(SkWStream* stream, | 368 void SkPDFDict::emitAll(SkWStream* stream, |
355 const SkPDFObjNumMap& objNumMap, | 369 const SkPDFObjNumMap& objNumMap, |
356 const SkPDFSubstituteMap& substitutes) const { | 370 const SkPDFSubstituteMap& substitutes) const { |
| 371 SkASSERT(!fDumped); |
357 for (int i = 0; i < fRecords.count(); i++) { | 372 for (int i = 0; i < fRecords.count(); i++) { |
358 fRecords[i].fKey.emitObject(stream, objNumMap, substitutes); | 373 fRecords[i].fKey.emitObject(stream, objNumMap, substitutes); |
359 stream->writeText(" "); | 374 stream->writeText(" "); |
360 fRecords[i].fValue.emitObject(stream, objNumMap, substitutes); | 375 fRecords[i].fValue.emitObject(stream, objNumMap, substitutes); |
361 if (i + 1 < fRecords.count()) { | 376 if (i + 1 < fRecords.count()) { |
362 stream->writeText("\n"); | 377 stream->writeText("\n"); |
363 } | 378 } |
364 } | 379 } |
365 } | 380 } |
366 | 381 |
367 void SkPDFDict::addResources(SkPDFObjNumMap* catalog, | 382 void SkPDFDict::addResources(SkPDFObjNumMap* catalog, |
368 const SkPDFSubstituteMap& substitutes) const { | 383 const SkPDFSubstituteMap& substitutes) const { |
| 384 SkASSERT(!fDumped); |
369 for (int i = 0; i < fRecords.count(); i++) { | 385 for (int i = 0; i < fRecords.count(); i++) { |
370 fRecords[i].fKey.addResources(catalog, substitutes); | 386 fRecords[i].fKey.addResources(catalog, substitutes); |
371 fRecords[i].fValue.addResources(catalog, substitutes); | 387 fRecords[i].fValue.addResources(catalog, substitutes); |
372 } | 388 } |
373 } | 389 } |
374 | 390 |
375 void SkPDFDict::set(SkPDFUnion&& name, SkPDFUnion&& value) { | 391 SkPDFDict::Record::Record(SkPDFUnion&& k, SkPDFUnion&& v) |
376 Record* rec = fRecords.append(); | 392 : fKey(std::move(k)), fValue(std::move(v)) {} |
377 SkASSERT(name.isName()); | 393 |
378 new (&rec->fKey) SkPDFUnion(std::move(name)); | 394 SkPDFDict::Record::Record(SkPDFDict::Record&& o) |
379 new (&rec->fValue) SkPDFUnion(std::move(value)); | 395 : fKey(std::move(o.fKey)), fValue(std::move(o.fValue)) {} |
| 396 |
| 397 SkPDFDict::Record& SkPDFDict::Record::operator=(SkPDFDict::Record&& o) { |
| 398 fKey = std::move(o.fKey); |
| 399 fValue = std::move(o.fValue); |
| 400 return *this; |
380 } | 401 } |
381 | 402 |
382 int SkPDFDict::size() const { return fRecords.count(); } | 403 int SkPDFDict::size() const { return fRecords.count(); } |
383 | 404 |
384 void SkPDFDict::insertObjRef(const char key[], sk_sp<SkPDFObject> objSp) { | 405 void SkPDFDict::insertObjRef(const char key[], sk_sp<SkPDFObject> objSp) { |
385 this->set(SkPDFUnion::Name(key), SkPDFUnion::ObjRef(std::move(objSp))); | 406 fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::ObjRef(std::move(ob
jSp))); |
386 } | 407 } |
| 408 |
387 void SkPDFDict::insertObjRef(const SkString& key, sk_sp<SkPDFObject> objSp) { | 409 void SkPDFDict::insertObjRef(const SkString& key, sk_sp<SkPDFObject> objSp) { |
388 this->set(SkPDFUnion::Name(key), SkPDFUnion::ObjRef(std::move(objSp))); | 410 fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::ObjRef(std::move(ob
jSp))); |
389 } | 411 } |
390 | 412 |
391 void SkPDFDict::insertObject(const char key[], sk_sp<SkPDFObject> objSp) { | 413 void SkPDFDict::insertObject(const char key[], sk_sp<SkPDFObject> objSp) { |
392 this->set(SkPDFUnion::Name(key), SkPDFUnion::Object(std::move(objSp))); | 414 fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::Object(std::move(ob
jSp))); |
393 } | 415 } |
394 void SkPDFDict::insertObject(const SkString& key, sk_sp<SkPDFObject> objSp) { | 416 void SkPDFDict::insertObject(const SkString& key, sk_sp<SkPDFObject> objSp) { |
395 this->set(SkPDFUnion::Name(key), SkPDFUnion::Object(std::move(objSp))); | 417 fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::Object(std::move(ob
jSp))); |
396 } | 418 } |
397 | 419 |
398 void SkPDFDict::insertBool(const char key[], bool value) { | 420 void SkPDFDict::insertBool(const char key[], bool value) { |
399 this->set(SkPDFUnion::Name(key), SkPDFUnion::Bool(value)); | 421 fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::Bool(value)); |
400 } | 422 } |
401 | 423 |
402 void SkPDFDict::insertInt(const char key[], int32_t value) { | 424 void SkPDFDict::insertInt(const char key[], int32_t value) { |
403 this->set(SkPDFUnion::Name(key), SkPDFUnion::Int(value)); | 425 fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::Int(value)); |
404 } | 426 } |
405 | 427 |
406 void SkPDFDict::insertInt(const char key[], size_t value) { | 428 void SkPDFDict::insertInt(const char key[], size_t value) { |
407 this->insertInt(key, SkToS32(value)); | 429 this->insertInt(key, SkToS32(value)); |
408 } | 430 } |
409 | 431 |
410 void SkPDFDict::insertScalar(const char key[], SkScalar value) { | 432 void SkPDFDict::insertScalar(const char key[], SkScalar value) { |
411 this->set(SkPDFUnion::Name(key), SkPDFUnion::Scalar(value)); | 433 fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::Scalar(value)); |
412 } | 434 } |
413 | 435 |
414 void SkPDFDict::insertName(const char key[], const char name[]) { | 436 void SkPDFDict::insertName(const char key[], const char name[]) { |
415 this->set(SkPDFUnion::Name(key), SkPDFUnion::Name(name)); | 437 fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::Name(name)); |
416 } | 438 } |
417 | 439 |
418 void SkPDFDict::insertName(const char key[], const SkString& name) { | 440 void SkPDFDict::insertName(const char key[], const SkString& name) { |
419 this->set(SkPDFUnion::Name(key), SkPDFUnion::Name(name)); | 441 fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::Name(name)); |
420 } | 442 } |
421 | 443 |
422 void SkPDFDict::insertString(const char key[], const char value[]) { | 444 void SkPDFDict::insertString(const char key[], const char value[]) { |
423 this->set(SkPDFUnion::Name(key), SkPDFUnion::String(value)); | 445 fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::String(value)); |
424 } | 446 } |
425 | 447 |
426 void SkPDFDict::insertString(const char key[], const SkString& value) { | 448 void SkPDFDict::insertString(const char key[], const SkString& value) { |
427 this->set(SkPDFUnion::Name(key), SkPDFUnion::String(value)); | 449 fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::String(value)); |
428 } | |
429 | |
430 void SkPDFDict::clear() { | |
431 for (Record& rec : fRecords) { | |
432 rec.fKey.~SkPDFUnion(); | |
433 rec.fValue.~SkPDFUnion(); | |
434 } | |
435 fRecords.reset(); | |
436 } | 450 } |
437 | 451 |
438 //////////////////////////////////////////////////////////////////////////////// | 452 //////////////////////////////////////////////////////////////////////////////// |
439 | 453 |
| 454 SkPDFSharedStream::SkPDFSharedStream(SkStreamAsset* data) |
| 455 : fAsset(data), fDict(new SkPDFDict) { |
| 456 SkDEBUGCODE(fDumped = false;) |
| 457 SkASSERT(data); |
| 458 } |
| 459 |
| 460 SkPDFSharedStream::~SkPDFSharedStream() { this->drop(); } |
| 461 |
| 462 void SkPDFSharedStream::drop() { |
| 463 fAsset.reset(); |
| 464 fDict.reset(nullptr); |
| 465 SkDEBUGCODE(fDumped = true;) |
| 466 } |
| 467 |
440 void SkPDFSharedStream::emitObject( | 468 void SkPDFSharedStream::emitObject( |
441 SkWStream* stream, | 469 SkWStream* stream, |
442 const SkPDFObjNumMap& objNumMap, | 470 const SkPDFObjNumMap& objNumMap, |
443 const SkPDFSubstituteMap& substitutes) const { | 471 const SkPDFSubstituteMap& substitutes) const { |
| 472 SkASSERT(!fDumped); |
444 SkDynamicMemoryWStream buffer; | 473 SkDynamicMemoryWStream buffer; |
445 SkDeflateWStream deflateWStream(&buffer); | 474 SkDeflateWStream deflateWStream(&buffer); |
446 // Since emitObject is const, this function doesn't change the dictionary. | 475 // Since emitObject is const, this function doesn't change the dictionary. |
447 SkAutoTDelete<SkStreamAsset> dup(fAsset->duplicate()); // Cheap copy | 476 SkAutoTDelete<SkStreamAsset> dup(fAsset->duplicate()); // Cheap copy |
448 SkASSERT(dup); | 477 SkASSERT(dup); |
449 SkStreamCopy(&deflateWStream, dup.get()); | 478 SkStreamCopy(&deflateWStream, dup.get()); |
450 deflateWStream.finalize(); | 479 deflateWStream.finalize(); |
451 size_t length = buffer.bytesWritten(); | 480 size_t length = buffer.bytesWritten(); |
452 stream->writeText("<<"); | 481 stream->writeText("<<"); |
453 fDict->emitAll(stream, objNumMap, substitutes); | 482 fDict->emitAll(stream, objNumMap, substitutes); |
454 stream->writeText("\n"); | 483 stream->writeText("\n"); |
455 SkPDFUnion::Name("Length").emitObject(stream, objNumMap, substitutes); | 484 SkPDFUnion::Name("Length").emitObject(stream, objNumMap, substitutes); |
456 stream->writeText(" "); | 485 stream->writeText(" "); |
457 SkPDFUnion::Int(length).emitObject(stream, objNumMap, substitutes); | 486 SkPDFUnion::Int(length).emitObject(stream, objNumMap, substitutes); |
458 stream->writeText("\n"); | 487 stream->writeText("\n"); |
459 SkPDFUnion::Name("Filter").emitObject(stream, objNumMap, substitutes); | 488 SkPDFUnion::Name("Filter").emitObject(stream, objNumMap, substitutes); |
460 stream->writeText(" "); | 489 stream->writeText(" "); |
461 SkPDFUnion::Name("FlateDecode").emitObject(stream, objNumMap, substitutes); | 490 SkPDFUnion::Name("FlateDecode").emitObject(stream, objNumMap, substitutes); |
462 stream->writeText(">>"); | 491 stream->writeText(">>"); |
463 stream->writeText(" stream\n"); | 492 stream->writeText(" stream\n"); |
464 buffer.writeToStream(stream); | 493 buffer.writeToStream(stream); |
465 stream->writeText("\nendstream"); | 494 stream->writeText("\nendstream"); |
466 } | 495 } |
467 | 496 |
468 void SkPDFSharedStream::addResources( | 497 void SkPDFSharedStream::addResources( |
469 SkPDFObjNumMap* catalog, const SkPDFSubstituteMap& substitutes) const { | 498 SkPDFObjNumMap* catalog, const SkPDFSubstituteMap& substitutes) const { |
| 499 SkASSERT(!fDumped); |
470 fDict->addResources(catalog, substitutes); | 500 fDict->addResources(catalog, substitutes); |
471 } | 501 } |
472 | 502 |
473 //////////////////////////////////////////////////////////////////////////////// | 503 //////////////////////////////////////////////////////////////////////////////// |
474 | 504 |
475 SkPDFSubstituteMap::~SkPDFSubstituteMap() { | 505 SkPDFSubstituteMap::~SkPDFSubstituteMap() { |
476 fSubstituteMap.foreach( | 506 fSubstituteMap.foreach( |
477 [](SkPDFObject*, SkPDFObject** v) { (*v)->unref(); }); | 507 [](SkPDFObject*, SkPDFObject** v) { (*v)->unref(); }); |
478 } | 508 } |
479 | 509 |
480 void SkPDFSubstituteMap::setSubstitute(SkPDFObject* original, | 510 void SkPDFSubstituteMap::setSubstitute(SkPDFObject* original, |
481 SkPDFObject* substitute) { | 511 SkPDFObject* substitute) { |
482 SkASSERT(original != substitute); | 512 SkASSERT(original != substitute); |
483 SkASSERT(!fSubstituteMap.find(original)); | 513 SkASSERT(!fSubstituteMap.find(original)); |
484 fSubstituteMap.set(original, SkRef(substitute)); | 514 fSubstituteMap.set(original, SkRef(substitute)); |
485 } | 515 } |
486 | 516 |
487 SkPDFObject* SkPDFSubstituteMap::getSubstitute(SkPDFObject* object) const { | 517 SkPDFObject* SkPDFSubstituteMap::getSubstitute(SkPDFObject* object) const { |
488 SkPDFObject** found = fSubstituteMap.find(object); | 518 SkPDFObject** found = fSubstituteMap.find(object); |
489 return found ? *found : object; | 519 return found ? *found : object; |
490 } | 520 } |
491 | 521 |
492 //////////////////////////////////////////////////////////////////////////////// | 522 //////////////////////////////////////////////////////////////////////////////// |
493 | 523 |
494 bool SkPDFObjNumMap::addObject(SkPDFObject* obj) { | 524 bool SkPDFObjNumMap::addObject(SkPDFObject* obj) { |
495 if (fObjectNumbers.find(obj)) { | 525 if (fObjectNumbers.find(obj)) { |
496 return false; | 526 return false; |
497 } | 527 } |
498 fObjectNumbers.set(obj, fObjectNumbers.count() + 1); | 528 fObjectNumbers.set(obj, fObjectNumbers.count() + 1); |
499 fObjects.push(obj); | 529 fObjects.emplace_back(sk_ref_sp(obj)); |
500 return true; | 530 return true; |
501 } | 531 } |
502 | 532 |
503 void SkPDFObjNumMap::addObjectRecursively(SkPDFObject* obj, | 533 void SkPDFObjNumMap::addObjectRecursively(SkPDFObject* obj, |
504 const SkPDFSubstituteMap& subs) { | 534 const SkPDFSubstituteMap& subs) { |
505 if (obj && this->addObject(obj)) { | 535 if (obj && this->addObject(obj)) { |
506 obj->addResources(this, subs); | 536 obj->addResources(this, subs); |
507 } | 537 } |
508 } | 538 } |
509 | 539 |
(...skipping 10 matching lines...) Expand all Loading... |
520 | 550 |
521 void SkPDFImageDumpStats() { | 551 void SkPDFImageDumpStats() { |
522 SkDebugf("\ntotal PDF drawImage/drawBitmap calls: %d\n" | 552 SkDebugf("\ntotal PDF drawImage/drawBitmap calls: %d\n" |
523 "total PDF jpeg images: %d\n" | 553 "total PDF jpeg images: %d\n" |
524 "total PDF regular images: %d\n", | 554 "total PDF regular images: %d\n", |
525 gDrawImageCalls.load(), | 555 gDrawImageCalls.load(), |
526 gJpegImageObjects.load(), | 556 gJpegImageObjects.load(), |
527 gRegularImageObjects.load()); | 557 gRegularImageObjects.load()); |
528 } | 558 } |
529 #endif // SK_PDF_IMAGE_STATS | 559 #endif // SK_PDF_IMAGE_STATS |
OLD | NEW |