blob: 9ca8a261d6aee537d678eb130ed7fb18febd6c63 [file] [log] [blame]
halcanaryfb62b3d2015-01-21 09:59:14 -08001/*
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
halcanary7a14b312015-10-01 07:28:13 -070010#include "SkBitmap.h"
halcanarybe27a112015-04-01 13:31:19 -070011#include "SkPDFGraphicState.h"
halcanaryfb62b3d2015-01-21 09:59:14 -080012#include "SkPDFShader.h"
halcanary712fdf72015-12-10 08:59:43 -080013#include "SkPixelSerializer.h"
halcanaryfb62b3d2015-01-21 09:59:14 -080014#include "SkTDArray.h"
halcanarybe27a112015-04-01 13:31:19 -070015#include "SkTHash.h"
halcanaryfb62b3d2015-01-21 09:59:14 -080016
halcanaryfb62b3d2015-01-21 09:59:14 -080017class SkPDFFont;
halcanaryfb62b3d2015-01-21 09:59:14 -080018class SkPaint;
halcanary7a14b312015-10-01 07:28:13 -070019class SkImage;
20
21class SkBitmapKey {
22public:
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
30private:
31 SkIRect fSubset;
32 uint32_t fGenID;
33};
halcanaryfb62b3d2015-01-21 09:59:14 -080034
halcanary792c80f2015-02-20 07:21:05 -080035/**
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 *
halcanary2e3f9d82015-02-27 12:41:03 -080045 * 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.
halcanary792c80f2015-02-20 07:21:05 -080050 */
halcanaryfb62b3d2015-01-21 09:59:14 -080051class SkPDFCanon : SkNoncopyable {
52public:
halcanary2e3f9d82015-02-27 12:41:03 -080053 ~SkPDFCanon() { this->reset(); }
54
55 // reset to original setting, unrefs all objects.
56 void reset();
halcanaryfb62b3d2015-01-21 09:59:14 -080057
halcanary96fcdcc2015-08-27 07:41:13 -070058 // Returns exact match if there is one. If not, it returns nullptr.
halcanaryfb62b3d2015-01-21 09:59:14 -080059 // If there is no exact match, but there is a related font, we
halcanary96fcdcc2015-08-27 07:41:13 -070060 // still return nullptr, but also set *relatedFont.
halcanaryfb62b3d2015-01-21 09:59:14 -080061 SkPDFFont* findFont(uint32_t fontID,
62 uint16_t glyphID,
63 SkPDFFont** relatedFont) const;
64 void addFont(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID);
halcanaryfb62b3d2015-01-21 09:59:14 -080065
halcanary530ea8e2015-01-23 06:17:35 -080066 SkPDFFunctionShader* findFunctionShader(const SkPDFShader::State&) const;
67 void addFunctionShader(SkPDFFunctionShader*);
halcanary530ea8e2015-01-23 06:17:35 -080068
69 SkPDFAlphaFunctionShader* findAlphaShader(const SkPDFShader::State&) const;
70 void addAlphaShader(SkPDFAlphaFunctionShader*);
halcanary530ea8e2015-01-23 06:17:35 -080071
72 SkPDFImageShader* findImageShader(const SkPDFShader::State&) const;
73 void addImageShader(SkPDFImageShader*);
halcanaryfb62b3d2015-01-21 09:59:14 -080074
halcanarybe27a112015-04-01 13:31:19 -070075 const SkPDFGraphicState* findGraphicState(const SkPDFGraphicState&) const;
76 void addGraphicState(const SkPDFGraphicState*);
halcanaryfb62b3d2015-01-21 09:59:14 -080077
halcanary7a14b312015-10-01 07:28:13 -070078 SkPDFObject* findPDFBitmap(const SkImage* image) const;
79 void addPDFBitmap(uint32_t imageUniqueID, SkPDFObject*);
80 const SkImage* bitmapToImage(const SkBitmap&);
halcanarya1f1ee92015-02-20 06:17:26 -080081
halcanary66a82f32015-10-12 13:05:04 -070082 SkTHashMap<uint32_t, bool> fCanEmbedTypeface;
83
halcanaryfcad44b2016-03-06 14:47:10 -080084 SkPixelSerializer* getPixelSerializer() const { return fPixelSerializer.get(); }
85 void setPixelSerializer(SkPixelSerializer* ps) { fPixelSerializer.reset(ps); }
halcanary712fdf72015-12-10 08:59:43 -080086
halcanary1437c1e2016-03-13 18:30:24 -070087 sk_sp<SkPDFStream> makeInvertFunction();
88 sk_sp<SkPDFDict> makeNoSmaskGraphicState();
89 sk_sp<SkPDFArray> makeRangeObject();
90
halcanaryfb62b3d2015-01-21 09:59:14 -080091private:
92 struct FontRec {
93 SkPDFFont* fFont;
94 uint32_t fFontID;
95 uint16_t fGlyphID;
96 };
97 SkTDArray<FontRec> fFontRecords;
98
halcanary530ea8e2015-01-23 06:17:35 -080099 SkTDArray<SkPDFFunctionShader*> fFunctionShaderRecords;
100
101 SkTDArray<SkPDFAlphaFunctionShader*> fAlphaShaderRecords;
102
103 SkTDArray<SkPDFImageShader*> fImageShaderRecords;
halcanaryfb62b3d2015-01-21 09:59:14 -0800104
halcanarybe27a112015-04-01 13:31:19 -0700105 struct WrapGS {
halcanary96fcdcc2015-08-27 07:41:13 -0700106 explicit WrapGS(const SkPDFGraphicState* ptr = nullptr) : fPtr(ptr) {}
halcanarybe27a112015-04-01 13:31:19 -0700107 const SkPDFGraphicState* fPtr;
108 bool operator==(const WrapGS& rhs) const {
109 SkASSERT(fPtr);
110 SkASSERT(rhs.fPtr);
111 return *fPtr == *rhs.fPtr;
112 }
mtkleinc8d1dd42015-10-15 12:23:01 -0700113 struct Hash {
114 uint32_t operator()(const WrapGS& w) const {
115 SkASSERT(w.fPtr);
116 return w.fPtr->hash();
117 }
118 };
halcanarybe27a112015-04-01 13:31:19 -0700119 };
120 SkTHashSet<WrapGS, WrapGS::Hash> fGraphicStateRecords;
halcanary1b5c6042015-02-18 11:29:56 -0800121
halcanary7a14b312015-10-01 07:28:13 -0700122 SkTHashMap<SkBitmapKey, const SkImage*> fBitmapToImageMap;
123 SkTHashMap<uint32_t /*ImageUniqueID*/, SkPDFObject*> fPDFBitmapMap;
halcanaryfcad44b2016-03-06 14:47:10 -0800124
halcanary48810a02016-03-07 14:57:50 -0800125 sk_sp<SkPixelSerializer> fPixelSerializer;
halcanary1437c1e2016-03-13 18:30:24 -0700126 sk_sp<SkPDFStream> fInvertFunction;
127 sk_sp<SkPDFDict> fNoSmaskGraphicState;
128 sk_sp<SkPDFArray> fRangeObject;
halcanaryfb62b3d2015-01-21 09:59:14 -0800129};
130#endif // SkPDFCanon_DEFINED