halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 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 | |
halcanary | 7a14b31 | 2015-10-01 07:28:13 -0700 | [diff] [blame] | 10 | #include "SkBitmap.h" |
halcanary | be27a11 | 2015-04-01 13:31:19 -0700 | [diff] [blame] | 11 | #include "SkPDFGraphicState.h" |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 12 | #include "SkPDFShader.h" |
halcanary | 712fdf7 | 2015-12-10 08:59:43 -0800 | [diff] [blame] | 13 | #include "SkPixelSerializer.h" |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 14 | #include "SkTDArray.h" |
halcanary | be27a11 | 2015-04-01 13:31:19 -0700 | [diff] [blame] | 15 | #include "SkTHash.h" |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 16 | |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 17 | class SkPDFFont; |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 18 | class SkPaint; |
halcanary | 7a14b31 | 2015-10-01 07:28:13 -0700 | [diff] [blame] | 19 | class SkImage; |
| 20 | |
| 21 | class SkBitmapKey { |
| 22 | public: |
| 23 | SkBitmapKey() : fSubset(SkIRect::MakeEmpty()), fGenID(0) {} |
| 24 | explicit SkBitmapKey(const SkBitmap& bm) |
| 25 | : fSubset(bm.getSubset()), fGenID(bm.getGenerationID()) {} |
| 26 | bool operator==(const SkBitmapKey& rhs) const { |
| 27 | return fGenID == rhs.fGenID && fSubset == rhs.fSubset; |
| 28 | } |
| 29 | |
| 30 | private: |
| 31 | SkIRect fSubset; |
| 32 | uint32_t fGenID; |
| 33 | }; |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 34 | |
halcanary | 792c80f | 2015-02-20 07:21:05 -0800 | [diff] [blame] | 35 | /** |
| 36 | * The SkPDFCanon canonicalizes objects across PDF pages(SkPDFDevices). |
| 37 | * |
| 38 | * The PDF backend works correctly if: |
| 39 | * - There is no more than one SkPDFCanon for each thread. |
| 40 | * - Every SkPDFDevice is given a pointer to a SkPDFCanon on creation. |
| 41 | * - All SkPDFDevices in a document share the same SkPDFCanon. |
| 42 | * The SkDocument_PDF class makes this happen by owning a single |
| 43 | * SkPDFCanon. |
| 44 | * |
halcanary | 2e3f9d8 | 2015-02-27 12:41:03 -0800 | [diff] [blame] | 45 | * The addFoo() methods will ref the Foo; the canon's destructor will |
| 46 | * call foo->unref() on all of these objects. |
| 47 | * |
| 48 | * The findFoo() methods do not change the ref count of the Foo |
| 49 | * objects. |
halcanary | 792c80f | 2015-02-20 07:21:05 -0800 | [diff] [blame] | 50 | */ |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 51 | class SkPDFCanon : SkNoncopyable { |
| 52 | public: |
halcanary | 2e3f9d8 | 2015-02-27 12:41:03 -0800 | [diff] [blame] | 53 | ~SkPDFCanon() { this->reset(); } |
| 54 | |
| 55 | // reset to original setting, unrefs all objects. |
| 56 | void reset(); |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 57 | |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 58 | // Returns exact match if there is one. If not, it returns nullptr. |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 59 | // If there is no exact match, but there is a related font, we |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 60 | // still return nullptr, but also set *relatedFont. |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 61 | SkPDFFont* findFont(uint32_t fontID, |
| 62 | uint16_t glyphID, |
| 63 | SkPDFFont** relatedFont) const; |
| 64 | void addFont(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID); |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 65 | |
halcanary | 530ea8e | 2015-01-23 06:17:35 -0800 | [diff] [blame] | 66 | SkPDFFunctionShader* findFunctionShader(const SkPDFShader::State&) const; |
| 67 | void addFunctionShader(SkPDFFunctionShader*); |
halcanary | 530ea8e | 2015-01-23 06:17:35 -0800 | [diff] [blame] | 68 | |
| 69 | SkPDFAlphaFunctionShader* findAlphaShader(const SkPDFShader::State&) const; |
| 70 | void addAlphaShader(SkPDFAlphaFunctionShader*); |
halcanary | 530ea8e | 2015-01-23 06:17:35 -0800 | [diff] [blame] | 71 | |
| 72 | SkPDFImageShader* findImageShader(const SkPDFShader::State&) const; |
| 73 | void addImageShader(SkPDFImageShader*); |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 74 | |
halcanary | be27a11 | 2015-04-01 13:31:19 -0700 | [diff] [blame] | 75 | const SkPDFGraphicState* findGraphicState(const SkPDFGraphicState&) const; |
| 76 | void addGraphicState(const SkPDFGraphicState*); |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 77 | |
halcanary | 7a14b31 | 2015-10-01 07:28:13 -0700 | [diff] [blame] | 78 | SkPDFObject* findPDFBitmap(const SkImage* image) const; |
| 79 | void addPDFBitmap(uint32_t imageUniqueID, SkPDFObject*); |
| 80 | const SkImage* bitmapToImage(const SkBitmap&); |
halcanary | a1f1ee9 | 2015-02-20 06:17:26 -0800 | [diff] [blame] | 81 | |
halcanary | 66a82f3 | 2015-10-12 13:05:04 -0700 | [diff] [blame] | 82 | SkTHashMap<uint32_t, bool> fCanEmbedTypeface; |
| 83 | |
halcanary | fcad44b | 2016-03-06 14:47:10 -0800 | [diff] [blame] | 84 | SkPixelSerializer* getPixelSerializer() const { return fPixelSerializer.get(); } |
| 85 | void setPixelSerializer(SkPixelSerializer* ps) { fPixelSerializer.reset(ps); } |
halcanary | 712fdf7 | 2015-12-10 08:59:43 -0800 | [diff] [blame] | 86 | |
halcanary | 1437c1e | 2016-03-13 18:30:24 -0700 | [diff] [blame] | 87 | sk_sp<SkPDFStream> makeInvertFunction(); |
| 88 | sk_sp<SkPDFDict> makeNoSmaskGraphicState(); |
| 89 | sk_sp<SkPDFArray> makeRangeObject(); |
| 90 | |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 91 | private: |
| 92 | struct FontRec { |
| 93 | SkPDFFont* fFont; |
| 94 | uint32_t fFontID; |
| 95 | uint16_t fGlyphID; |
| 96 | }; |
| 97 | SkTDArray<FontRec> fFontRecords; |
| 98 | |
halcanary | 530ea8e | 2015-01-23 06:17:35 -0800 | [diff] [blame] | 99 | SkTDArray<SkPDFFunctionShader*> fFunctionShaderRecords; |
| 100 | |
| 101 | SkTDArray<SkPDFAlphaFunctionShader*> fAlphaShaderRecords; |
| 102 | |
| 103 | SkTDArray<SkPDFImageShader*> fImageShaderRecords; |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 104 | |
halcanary | be27a11 | 2015-04-01 13:31:19 -0700 | [diff] [blame] | 105 | struct WrapGS { |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 106 | explicit WrapGS(const SkPDFGraphicState* ptr = nullptr) : fPtr(ptr) {} |
halcanary | be27a11 | 2015-04-01 13:31:19 -0700 | [diff] [blame] | 107 | const SkPDFGraphicState* fPtr; |
| 108 | bool operator==(const WrapGS& rhs) const { |
| 109 | SkASSERT(fPtr); |
| 110 | SkASSERT(rhs.fPtr); |
| 111 | return *fPtr == *rhs.fPtr; |
| 112 | } |
mtklein | c8d1dd4 | 2015-10-15 12:23:01 -0700 | [diff] [blame] | 113 | struct Hash { |
| 114 | uint32_t operator()(const WrapGS& w) const { |
| 115 | SkASSERT(w.fPtr); |
| 116 | return w.fPtr->hash(); |
| 117 | } |
| 118 | }; |
halcanary | be27a11 | 2015-04-01 13:31:19 -0700 | [diff] [blame] | 119 | }; |
| 120 | SkTHashSet<WrapGS, WrapGS::Hash> fGraphicStateRecords; |
halcanary | 1b5c604 | 2015-02-18 11:29:56 -0800 | [diff] [blame] | 121 | |
halcanary | 7a14b31 | 2015-10-01 07:28:13 -0700 | [diff] [blame] | 122 | SkTHashMap<SkBitmapKey, const SkImage*> fBitmapToImageMap; |
| 123 | SkTHashMap<uint32_t /*ImageUniqueID*/, SkPDFObject*> fPDFBitmapMap; |
halcanary | fcad44b | 2016-03-06 14:47:10 -0800 | [diff] [blame] | 124 | |
halcanary | 48810a0 | 2016-03-07 14:57:50 -0800 | [diff] [blame] | 125 | sk_sp<SkPixelSerializer> fPixelSerializer; |
halcanary | 1437c1e | 2016-03-13 18:30:24 -0700 | [diff] [blame] | 126 | sk_sp<SkPDFStream> fInvertFunction; |
| 127 | sk_sp<SkPDFDict> fNoSmaskGraphicState; |
| 128 | sk_sp<SkPDFArray> fRangeObject; |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 129 | }; |
| 130 | #endif // SkPDFCanon_DEFINED |