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 #ifndef SkPDFCanon_DEFINED 8 #define SkPDFCanon_DEFINED 9 10 #include "SkPDFGraphicState.h" 11 #include "SkPDFShader.h" 12 #include "SkPixelSerializer.h" 13 #include "SkTDArray.h" 14 #include "SkTHash.h" 15 #include "SkBitmapKey.h" 16 17 class SkAdvancedTypefaceMetrics; 18 class SkPDFFont; 19 20 /** 21 * The SkPDFCanon canonicalizes objects across PDF pages 22 * (SkPDFDevices) and across draw calls. 23 * 24 * The PDF backend works correctly if: 25 * - There is no more than one SkPDFCanon for each thread. 26 * - Every SkPDFDevice is given a pointer to a SkPDFCanon on creation. 27 * - All SkPDFDevices in a document share the same SkPDFCanon. 28 * The SkPDFDocument class makes this happen by owning a single 29 * SkPDFCanon. 30 * 31 * The addFoo() methods will ref the Foo; the canon's destructor will 32 * call foo->unref() on all of these objects. 33 * 34 * The findFoo() methods do not change the ref count of the Foo 35 * objects. 36 */ 37 class SkPDFCanon : SkNoncopyable { 38 public: 39 ~SkPDFCanon(); 40 41 // reset to original setting, unrefs all objects. 42 void reset(); 43 44 sk_sp<SkPDFObject> findFunctionShader(const SkPDFShader::State&) const; 45 void addFunctionShader(sk_sp<SkPDFObject>, SkPDFShader::State); 46 47 sk_sp<SkPDFObject> findAlphaShader(const SkPDFShader::State&) const; 48 void addAlphaShader(sk_sp<SkPDFObject>, SkPDFShader::State); 49 50 sk_sp<SkPDFObject> findImageShader(const SkPDFShader::State&) const; 51 void addImageShader(sk_sp<SkPDFObject>, SkPDFShader::State); 52 53 const SkPDFGraphicState* findGraphicState(const SkPDFGraphicState&) const; 54 void addGraphicState(const SkPDFGraphicState*); 55 56 sk_sp<SkPDFObject> findPDFBitmap(SkBitmapKey key) const; 57 void addPDFBitmap(SkBitmapKey key, sk_sp<SkPDFObject>); 58 59 SkTHashMap<uint32_t, SkAdvancedTypefaceMetrics*> fTypefaceMetrics; 60 SkTHashMap<uint32_t, SkPDFDict*> fFontDescriptors; 61 SkTHashMap<uint64_t, SkPDFFont*> fFontMap; 62 getPixelSerializer()63 SkPixelSerializer* getPixelSerializer() const { return fPixelSerializer.get(); } setPixelSerializer(sk_sp<SkPixelSerializer> ps)64 void setPixelSerializer(sk_sp<SkPixelSerializer> ps) { 65 fPixelSerializer = std::move(ps); 66 } 67 68 sk_sp<SkPDFStream> makeInvertFunction(); 69 sk_sp<SkPDFDict> makeNoSmaskGraphicState(); 70 sk_sp<SkPDFArray> makeRangeObject(); 71 72 private: 73 struct ShaderRec { 74 SkPDFShader::State fShaderState; 75 sk_sp<SkPDFObject> fShaderObject; ShaderRecShaderRec76 ShaderRec(SkPDFShader::State s, sk_sp<SkPDFObject> o) 77 : fShaderState(std::move(s)), fShaderObject(std::move(o)) {} 78 }; 79 SkTArray<ShaderRec> fFunctionShaderRecords; 80 SkTArray<ShaderRec> fAlphaShaderRecords; 81 SkTArray<ShaderRec> fImageShaderRecords; 82 83 struct WrapGS { fPtrWrapGS84 explicit WrapGS(const SkPDFGraphicState* ptr = nullptr) : fPtr(ptr) {} 85 const SkPDFGraphicState* fPtr; 86 bool operator==(const WrapGS& rhs) const { 87 SkASSERT(fPtr); 88 SkASSERT(rhs.fPtr); 89 return *fPtr == *rhs.fPtr; 90 } 91 struct Hash { operatorWrapGS::Hash92 uint32_t operator()(const WrapGS& w) const { 93 SkASSERT(w.fPtr); 94 return w.fPtr->hash(); 95 } 96 }; 97 }; 98 SkTHashSet<WrapGS, WrapGS::Hash> fGraphicStateRecords; 99 100 // TODO(halcanary): make SkTHashMap<K, sk_sp<V>> work correctly. 101 SkTHashMap<SkBitmapKey, SkPDFObject*> fPDFBitmapMap; 102 103 sk_sp<SkPixelSerializer> fPixelSerializer; 104 sk_sp<SkPDFStream> fInvertFunction; 105 sk_sp<SkPDFDict> fNoSmaskGraphicState; 106 sk_sp<SkPDFArray> fRangeObject; 107 }; 108 #endif // SkPDFCanon_DEFINED 109