Line data Source code
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 0 : 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 :
63 0 : SkPixelSerializer* getPixelSerializer() const { return fPixelSerializer.get(); }
64 0 : void setPixelSerializer(sk_sp<SkPixelSerializer> ps) {
65 0 : fPixelSerializer = std::move(ps);
66 0 : }
67 :
68 : sk_sp<SkPDFStream> makeInvertFunction();
69 : sk_sp<SkPDFDict> makeNoSmaskGraphicState();
70 : sk_sp<SkPDFArray> makeRangeObject();
71 :
72 : private:
73 0 : struct ShaderRec {
74 : SkPDFShader::State fShaderState;
75 : sk_sp<SkPDFObject> fShaderObject;
76 0 : ShaderRec(SkPDFShader::State s, sk_sp<SkPDFObject> o)
77 0 : : 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 {
84 0 : explicit WrapGS(const SkPDFGraphicState* ptr = nullptr) : fPtr(ptr) {}
85 : const SkPDFGraphicState* fPtr;
86 0 : bool operator==(const WrapGS& rhs) const {
87 0 : SkASSERT(fPtr);
88 0 : SkASSERT(rhs.fPtr);
89 0 : return *fPtr == *rhs.fPtr;
90 : }
91 : struct Hash {
92 0 : uint32_t operator()(const WrapGS& w) const {
93 0 : SkASSERT(w.fPtr);
94 0 : 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
|