| /* |
| * Copyright 2015 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| #ifndef SkPDFCanon_DEFINED |
| #define SkPDFCanon_DEFINED |
| |
| #include "SkPDFGraphicState.h" |
| #include "SkPDFShader.h" |
| #include "SkPixelSerializer.h" |
| #include "SkTDArray.h" |
| #include "SkTHash.h" |
| #include "SkBitmapKey.h" |
| |
| class SkAdvancedTypefaceMetrics; |
| class SkPDFFont; |
| |
| /** |
| * The SkPDFCanon canonicalizes objects across PDF pages |
| * (SkPDFDevices) and across draw calls. |
| * |
| * The PDF backend works correctly if: |
| * - There is no more than one SkPDFCanon for each thread. |
| * - Every SkPDFDevice is given a pointer to a SkPDFCanon on creation. |
| * - All SkPDFDevices in a document share the same SkPDFCanon. |
| * The SkPDFDocument class makes this happen by owning a single |
| * SkPDFCanon. |
| * |
| * The addFoo() methods will ref the Foo; the canon's destructor will |
| * call foo->unref() on all of these objects. |
| * |
| * The findFoo() methods do not change the ref count of the Foo |
| * objects. |
| */ |
| class SkPDFCanon : SkNoncopyable { |
| public: |
| ~SkPDFCanon(); |
| |
| // reset to original setting, unrefs all objects. |
| void reset(); |
| |
| sk_sp<SkPDFObject> findFunctionShader(const SkPDFShader::State&) const; |
| void addFunctionShader(sk_sp<SkPDFObject>, SkPDFShader::State); |
| |
| sk_sp<SkPDFObject> findAlphaShader(const SkPDFShader::State&) const; |
| void addAlphaShader(sk_sp<SkPDFObject>, SkPDFShader::State); |
| |
| sk_sp<SkPDFObject> findImageShader(const SkPDFShader::State&) const; |
| void addImageShader(sk_sp<SkPDFObject>, SkPDFShader::State); |
| |
| const SkPDFGraphicState* findGraphicState(const SkPDFGraphicState&) const; |
| void addGraphicState(const SkPDFGraphicState*); |
| |
| sk_sp<SkPDFObject> findPDFBitmap(SkBitmapKey key) const; |
| void addPDFBitmap(SkBitmapKey key, sk_sp<SkPDFObject>); |
| |
| SkTHashMap<uint32_t, SkAdvancedTypefaceMetrics*> fTypefaceMetrics; |
| SkTHashMap<uint32_t, SkPDFDict*> fFontDescriptors; |
| SkTHashMap<uint64_t, SkPDFFont*> fFontMap; |
| |
| SkPixelSerializer* getPixelSerializer() const { return fPixelSerializer.get(); } |
| void setPixelSerializer(sk_sp<SkPixelSerializer> ps) { |
| fPixelSerializer = std::move(ps); |
| } |
| |
| sk_sp<SkPDFStream> makeInvertFunction(); |
| sk_sp<SkPDFDict> makeNoSmaskGraphicState(); |
| sk_sp<SkPDFArray> makeRangeObject(); |
| |
| private: |
| struct ShaderRec { |
| SkPDFShader::State fShaderState; |
| sk_sp<SkPDFObject> fShaderObject; |
| ShaderRec(SkPDFShader::State s, sk_sp<SkPDFObject> o) |
| : fShaderState(std::move(s)), fShaderObject(std::move(o)) {} |
| }; |
| SkTArray<ShaderRec> fFunctionShaderRecords; |
| SkTArray<ShaderRec> fAlphaShaderRecords; |
| SkTArray<ShaderRec> fImageShaderRecords; |
| |
| struct WrapGS { |
| explicit WrapGS(const SkPDFGraphicState* ptr = nullptr) : fPtr(ptr) {} |
| const SkPDFGraphicState* fPtr; |
| bool operator==(const WrapGS& rhs) const { |
| SkASSERT(fPtr); |
| SkASSERT(rhs.fPtr); |
| return *fPtr == *rhs.fPtr; |
| } |
| struct Hash { |
| uint32_t operator()(const WrapGS& w) const { |
| SkASSERT(w.fPtr); |
| return w.fPtr->hash(); |
| } |
| }; |
| }; |
| SkTHashSet<WrapGS, WrapGS::Hash> fGraphicStateRecords; |
| |
| // TODO(halcanary): make SkTHashMap<K, sk_sp<V>> work correctly. |
| SkTHashMap<SkBitmapKey, SkPDFObject*> fPDFBitmapMap; |
| |
| sk_sp<SkPixelSerializer> fPixelSerializer; |
| sk_sp<SkPDFStream> fInvertFunction; |
| sk_sp<SkPDFDict> fNoSmaskGraphicState; |
| sk_sp<SkPDFArray> fRangeObject; |
| }; |
| #endif // SkPDFCanon_DEFINED |