1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkImage.h" 9 #include "SkPDFBitmap.h" 10 #include "SkPDFCanon.h" 11 #include "SkPDFFont.h" 12 13 //////////////////////////////////////////////////////////////////////////////// 14 15 namespace { 16 template <typename K, typename V> struct UnrefValue { 17 void operator()(K, V** v) { SkSafeUnref(*v); } 18 }; 19 } 20 21 SkPDFCanon::~SkPDFCanon() { 22 // TODO(halcanary): make SkTHashSet work nicely with sk_sp<>, 23 // or use std::unordered_set<> 24 fGraphicStateRecords.foreach ([](WrapGS w) { w.fPtr->unref(); }); 25 fPDFBitmapMap.foreach(UnrefValue<SkBitmapKey, SkPDFObject>()); 26 fTypefaceMetrics.foreach(UnrefValue<uint32_t, SkAdvancedTypefaceMetrics>()); 27 fFontDescriptors.foreach(UnrefValue<uint32_t, SkPDFDict>()); 28 fFontMap.foreach(UnrefValue<uint64_t, SkPDFFont>()); 29 } 30 31 void SkPDFCanon::reset() { 32 this->~SkPDFCanon(); 33 new (this)SkPDFCanon; 34 } 35 36 //////////////////////////////////////////////////////////////////////////////// 37 38 template <typename T> 39 sk_sp<SkPDFObject> find_shader(const SkTArray<T>& records, 40 const SkPDFShader::State& state) { 41 for (const T& record : records) { 42 if (record.fShaderState == state) { 43 return record.fShaderObject; 44 } 45 } 46 return nullptr; 47 } 48 49 sk_sp<SkPDFObject> SkPDFCanon::findFunctionShader( 50 const SkPDFShader::State& state) const { 51 return find_shader(fFunctionShaderRecords, state); 52 } 53 void SkPDFCanon::addFunctionShader(sk_sp<SkPDFObject> pdfShader, 54 SkPDFShader::State state) { 55 fFunctionShaderRecords.emplace_back(std::move(state), std::move(pdfShader)); 56 } 57 58 sk_sp<SkPDFObject> SkPDFCanon::findAlphaShader( 59 const SkPDFShader::State& state) const { 60 return find_shader(fAlphaShaderRecords, state); 61 } 62 void SkPDFCanon::addAlphaShader(sk_sp<SkPDFObject> pdfShader, 63 SkPDFShader::State state) { 64 fAlphaShaderRecords.emplace_back(std::move(state), std::move(pdfShader)); 65 } 66 67 sk_sp<SkPDFObject> SkPDFCanon::findImageShader( 68 const SkPDFShader::State& state) const { 69 return find_shader(fImageShaderRecords, state); 70 } 71 72 void SkPDFCanon::addImageShader(sk_sp<SkPDFObject> pdfShader, 73 SkPDFShader::State state) { 74 fImageShaderRecords.emplace_back(std::move(state), std::move(pdfShader)); 75 } 76 77 //////////////////////////////////////////////////////////////////////////////// 78 79 const SkPDFGraphicState* SkPDFCanon::findGraphicState( 80 const SkPDFGraphicState& key) const { 81 const WrapGS* ptr = fGraphicStateRecords.find(WrapGS(&key)); 82 return ptr ? ptr->fPtr : nullptr; 83 } 84 85 void SkPDFCanon::addGraphicState(const SkPDFGraphicState* state) { 86 SkASSERT(state); 87 WrapGS w(SkRef(state)); 88 SkASSERT(!fGraphicStateRecords.contains(w)); 89 fGraphicStateRecords.add(w); 90 } 91 92 //////////////////////////////////////////////////////////////////////////////// 93 94 sk_sp<SkPDFObject> SkPDFCanon::findPDFBitmap(SkBitmapKey key) const { 95 SkPDFObject** ptr = fPDFBitmapMap.find(key); 96 return ptr ? sk_ref_sp(*ptr) : sk_sp<SkPDFObject>(); 97 } 98 99 void SkPDFCanon::addPDFBitmap(SkBitmapKey key, sk_sp<SkPDFObject> pdfBitmap) { 100 fPDFBitmapMap.set(key, pdfBitmap.release()); 101 } 102 103 //////////////////////////////////////////////////////////////////////////////// 104 105 sk_sp<SkPDFStream> SkPDFCanon::makeInvertFunction() { 106 if (fInvertFunction) { 107 return fInvertFunction; 108 } 109 fInvertFunction = SkPDFGraphicState::MakeInvertFunction(); 110 return fInvertFunction; 111 } 112 sk_sp<SkPDFDict> SkPDFCanon::makeNoSmaskGraphicState() { 113 if (fNoSmaskGraphicState) { 114 return fNoSmaskGraphicState; 115 } 116 fNoSmaskGraphicState = SkPDFGraphicState::MakeNoSmaskGraphicState(); 117 return fNoSmaskGraphicState; 118 } 119 sk_sp<SkPDFArray> SkPDFCanon::makeRangeObject() { 120 if (fRangeObject) { 121 return fRangeObject; 122 } 123 fRangeObject = SkPDFShader::MakeRangeObject(); 124 return fRangeObject; 125 } 126