vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 1 | /* |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 2 | * Copyright 2010 The Android Open Source Project |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 3 | * |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 6 | */ |
| 7 | |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 8 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 9 | #ifndef SkPDFTypes_DEFINED |
| 10 | #define SkPDFTypes_DEFINED |
| 11 | |
| 12 | #include "SkRefCnt.h" |
| 13 | #include "SkScalar.h" |
halcanary | 37c46ca | 2015-03-31 12:30:20 -0700 | [diff] [blame] | 14 | #include "SkTHash.h" |
vandebo@chromium.org | 28be72b | 2010-11-11 21:37:00 +0000 | [diff] [blame] | 15 | #include "SkTypes.h" |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 16 | |
halcanary | fa25106 | 2016-07-29 10:13:18 -0700 | [diff] [blame] | 17 | class SkData; |
halcanary | 37c46ca | 2015-03-31 12:30:20 -0700 | [diff] [blame] | 18 | class SkPDFObjNumMap; |
halcanary | bf799cd | 2015-02-10 13:32:09 -0800 | [diff] [blame] | 19 | class SkPDFObject; |
martina.kollarova | b8d6af1 | 2016-06-29 05:12:31 -0700 | [diff] [blame] | 20 | class SkStreamAsset; |
| 21 | class SkString; |
| 22 | class SkWStream; |
halcanary | bf799cd | 2015-02-10 13:32:09 -0800 | [diff] [blame] | 23 | |
halcanary | 7a14b31 | 2015-10-01 07:28:13 -0700 | [diff] [blame] | 24 | #ifdef SK_PDF_IMAGE_STATS |
| 25 | #include "SkAtomics.h" |
| 26 | #endif |
| 27 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 28 | /** \class SkPDFObject |
| 29 | |
| 30 | A PDF Object is the base class for primitive elements in a PDF file. A |
| 31 | common subtype is used to ease the use of indirect object references, |
| 32 | which are common in the PDF format. |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 33 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 34 | */ |
| 35 | class SkPDFObject : public SkRefCnt { |
| 36 | public: |
halcanary | 6a14434 | 2015-01-23 11:45:10 -0800 | [diff] [blame] | 37 | /** Subclasses must implement this method to print the object to the |
| 38 | * PDF file. |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 39 | * @param catalog The object catalog to use. |
halcanary | 6a14434 | 2015-01-23 11:45:10 -0800 | [diff] [blame] | 40 | * @param stream The writable output stream to send the output to. |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 41 | */ |
halcanary | 37c46ca | 2015-03-31 12:30:20 -0700 | [diff] [blame] | 42 | virtual void emitObject(SkWStream* stream, |
halcanary | 530032a | 2016-08-18 14:22:52 -0700 | [diff] [blame] | 43 | const SkPDFObjNumMap& objNumMap) const = 0; |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 44 | |
halcanary | bf799cd | 2015-02-10 13:32:09 -0800 | [diff] [blame] | 45 | /** |
halcanary | d4714af | 2015-03-25 13:23:13 -0700 | [diff] [blame] | 46 | * Adds all transitive dependencies of this object to the |
| 47 | * catalog. Implementations should respect the catalog's object |
| 48 | * substitution map. |
vandebo@chromium.org | a518086 | 2010-10-26 19:48:49 +0000 | [diff] [blame] | 49 | */ |
halcanary | 530032a | 2016-08-18 14:22:52 -0700 | [diff] [blame] | 50 | virtual void addResources(SkPDFObjNumMap* catalog) const {} |
vandebo@chromium.org | 421d644 | 2011-07-20 17:39:01 +0000 | [diff] [blame] | 51 | |
halcanary | bae235e | 2016-03-21 10:05:23 -0700 | [diff] [blame] | 52 | /** |
| 53 | * Release all resources associated with this SkPDFObject. It is |
| 54 | * an error to call emitObject() or addResources() after calling |
| 55 | * drop(). |
| 56 | */ |
| 57 | virtual void drop() {} |
| 58 | |
| 59 | virtual ~SkPDFObject() {} |
halcanary | 6a14434 | 2015-01-23 11:45:10 -0800 | [diff] [blame] | 60 | private: |
halcanary | 4fc48af | 2015-01-12 10:07:50 -0800 | [diff] [blame] | 61 | typedef SkRefCnt INHERITED; |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 62 | }; |
| 63 | |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 64 | //////////////////////////////////////////////////////////////////////////////// |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 65 | |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 66 | /** |
| 67 | A SkPDFUnion is a non-virtualized implementation of the |
| 68 | non-compound, non-specialized PDF Object types: Name, String, |
| 69 | Number, Boolean. |
| 70 | */ |
| 71 | class SkPDFUnion { |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 72 | public: |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 73 | // Move contstructor and assignemnt operator destroy the argument |
| 74 | // and steal their references (if needed). |
| 75 | SkPDFUnion(SkPDFUnion&& other); |
| 76 | SkPDFUnion& operator=(SkPDFUnion&& other); |
reed@google.com | 3b42998 | 2012-06-26 15:30:08 +0000 | [diff] [blame] | 77 | |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 78 | ~SkPDFUnion(); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 79 | |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 80 | /** The following nine functions are the standard way of creating |
| 81 | SkPDFUnion objects. */ |
| 82 | |
| 83 | static SkPDFUnion Int(int32_t); |
| 84 | |
halcanary | 725c620 | 2015-08-20 08:09:37 -0700 | [diff] [blame] | 85 | static SkPDFUnion Int(size_t v) { return SkPDFUnion::Int(SkToS32(v)); } |
halcanary | f7a169e | 2015-05-01 07:35:45 -0700 | [diff] [blame] | 86 | |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 87 | static SkPDFUnion Bool(bool); |
| 88 | |
| 89 | static SkPDFUnion Scalar(SkScalar); |
| 90 | |
halcanary | eb92cb3 | 2016-07-15 13:41:27 -0700 | [diff] [blame] | 91 | static SkPDFUnion ColorComponent(uint8_t); |
| 92 | |
halcanary | 8103a34 | 2016-03-08 15:10:16 -0800 | [diff] [blame] | 93 | /** These two functions do NOT take ownership of char*, and do NOT |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 94 | copy the string. Suitable for passing in static const |
| 95 | strings. For example: |
| 96 | SkPDFUnion n = SkPDFUnion::Name("Length"); |
| 97 | SkPDFUnion u = SkPDFUnion::String("Identity"); */ |
| 98 | |
| 99 | /** SkPDFUnion::Name(const char*) assumes that the passed string |
| 100 | is already a valid name (that is: it has no control or |
| 101 | whitespace characters). This will not copy the name. */ |
| 102 | static SkPDFUnion Name(const char*); |
| 103 | |
| 104 | /** SkPDFUnion::String will encode the passed string. This will |
| 105 | not copy the name. */ |
| 106 | static SkPDFUnion String(const char*); |
| 107 | |
| 108 | /** SkPDFUnion::Name(const SkString&) does not assume that the |
| 109 | passed string is already a valid name and it will escape the |
| 110 | string. */ |
| 111 | static SkPDFUnion Name(const SkString&); |
| 112 | |
| 113 | /** SkPDFUnion::String will encode the passed string. */ |
| 114 | static SkPDFUnion String(const SkString&); |
| 115 | |
halcanary | 8103a34 | 2016-03-08 15:10:16 -0800 | [diff] [blame] | 116 | static SkPDFUnion Object(sk_sp<SkPDFObject>); |
| 117 | static SkPDFUnion ObjRef(sk_sp<SkPDFObject>); |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 118 | |
| 119 | /** These two non-virtual methods mirror SkPDFObject's |
| 120 | corresponding virtuals. */ |
halcanary | 530032a | 2016-08-18 14:22:52 -0700 | [diff] [blame] | 121 | void emitObject(SkWStream*, const SkPDFObjNumMap&) const; |
| 122 | void addResources(SkPDFObjNumMap*) const; |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 123 | |
| 124 | bool isName() const; |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 125 | |
| 126 | private: |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 127 | union { |
| 128 | int32_t fIntValue; |
| 129 | bool fBoolValue; |
| 130 | SkScalar fScalarValue; |
| 131 | const char* fStaticString; |
| 132 | char fSkString[sizeof(SkString)]; |
| 133 | SkPDFObject* fObject; |
| 134 | }; |
| 135 | enum class Type : char { |
| 136 | /** It is an error to call emitObject() or addResources() on an |
| 137 | kDestroyed object. */ |
| 138 | kDestroyed = 0, |
| 139 | kInt, |
halcanary | eb92cb3 | 2016-07-15 13:41:27 -0700 | [diff] [blame] | 140 | kColorComponent, |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 141 | kBool, |
| 142 | kScalar, |
| 143 | kName, |
| 144 | kString, |
| 145 | kNameSkS, |
| 146 | kStringSkS, |
| 147 | kObjRef, |
| 148 | kObject, |
| 149 | }; |
| 150 | Type fType; |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 151 | |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 152 | SkPDFUnion(Type); |
| 153 | // We do not now need copy constructor and copy assignment, so we |
| 154 | // will disable this functionality. |
| 155 | SkPDFUnion& operator=(const SkPDFUnion&) = delete; |
| 156 | SkPDFUnion(const SkPDFUnion&) = delete; |
| 157 | }; |
bungeman | 99fe822 | 2015-08-20 07:57:51 -0700 | [diff] [blame] | 158 | static_assert(sizeof(SkString) == sizeof(void*), "SkString_size"); |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 159 | |
| 160 | //////////////////////////////////////////////////////////////////////////////// |
| 161 | |
halcanary | 002653e | 2015-05-05 11:28:55 -0700 | [diff] [blame] | 162 | #if 0 // Enable if needed. |
| 163 | /** This class is a SkPDFUnion with SkPDFObject virtuals attached. |
| 164 | The only use case of this is when a non-compound PDF object is |
| 165 | referenced indirectly. */ |
halcanary | 70d1554 | 2015-11-22 12:55:04 -0800 | [diff] [blame] | 166 | class SkPDFAtom final : public SkPDFObject { |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 167 | public: |
| 168 | void emitObject(SkWStream* stream, |
halcanary | 530032a | 2016-08-18 14:22:52 -0700 | [diff] [blame] | 169 | const SkPDFObjNumMap& objNumMap) final; |
| 170 | void addResources(SkPDFObjNumMap* const final; |
halcanary | 8103a34 | 2016-03-08 15:10:16 -0800 | [diff] [blame] | 171 | SkPDFAtom(SkPDFUnion&& v) : fValue(std::move(v) {} |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 172 | |
| 173 | private: |
| 174 | const SkPDFUnion fValue; |
reed@google.com | 3b42998 | 2012-06-26 15:30:08 +0000 | [diff] [blame] | 175 | typedef SkPDFObject INHERITED; |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 176 | }; |
halcanary | 002653e | 2015-05-05 11:28:55 -0700 | [diff] [blame] | 177 | #endif // 0 |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 178 | |
halcanary | bc4696b | 2015-05-06 10:56:04 -0700 | [diff] [blame] | 179 | //////////////////////////////////////////////////////////////////////////////// |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 180 | |
| 181 | /** \class SkPDFArray |
| 182 | |
| 183 | An array object in a PDF. |
| 184 | */ |
halcanary | 70d1554 | 2015-11-22 12:55:04 -0800 | [diff] [blame] | 185 | class SkPDFArray final : public SkPDFObject { |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 186 | public: |
| 187 | /** Create a PDF array. Maximum length is 8191. |
| 188 | */ |
vandebo@chromium.org | f66025d | 2010-10-01 23:26:55 +0000 | [diff] [blame] | 189 | SkPDFArray(); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 190 | virtual ~SkPDFArray(); |
| 191 | |
| 192 | // The SkPDFObject interface. |
tfarina | f4219dd | 2015-04-27 17:18:28 -0700 | [diff] [blame] | 193 | void emitObject(SkWStream* stream, |
halcanary | 530032a | 2016-08-18 14:22:52 -0700 | [diff] [blame] | 194 | const SkPDFObjNumMap& objNumMap) const override; |
| 195 | void addResources(SkPDFObjNumMap*) const override; |
halcanary | bae235e | 2016-03-21 10:05:23 -0700 | [diff] [blame] | 196 | void drop() override; |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 197 | |
| 198 | /** The size of the array. |
| 199 | */ |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 200 | int size() const; |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 201 | |
| 202 | /** Preallocate space for the given number of entries. |
| 203 | * @param length The number of array slots to preallocate. |
| 204 | */ |
| 205 | void reserve(int length); |
| 206 | |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 207 | /** Appends a value to the end of the array. |
reed@google.com | c789cf1 | 2011-07-20 12:14:33 +0000 | [diff] [blame] | 208 | * @param value The value to add to the array. |
| 209 | */ |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 210 | void appendInt(int32_t); |
halcanary | eb92cb3 | 2016-07-15 13:41:27 -0700 | [diff] [blame] | 211 | void appendColorComponent(uint8_t); |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 212 | void appendBool(bool); |
| 213 | void appendScalar(SkScalar); |
| 214 | void appendName(const char[]); |
| 215 | void appendName(const SkString&); |
| 216 | void appendString(const char[]); |
| 217 | void appendString(const SkString&); |
halcanary | 8103a34 | 2016-03-08 15:10:16 -0800 | [diff] [blame] | 218 | void appendObject(sk_sp<SkPDFObject>); |
| 219 | void appendObjRef(sk_sp<SkPDFObject>); |
ctguil@chromium.org | a5c7234 | 2011-08-15 23:55:03 +0000 | [diff] [blame] | 220 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 221 | private: |
halcanary | bae235e | 2016-03-21 10:05:23 -0700 | [diff] [blame] | 222 | SkTArray<SkPDFUnion> fValues; |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 223 | void append(SkPDFUnion&& value); |
halcanary | bae235e | 2016-03-21 10:05:23 -0700 | [diff] [blame] | 224 | SkDEBUGCODE(bool fDumped;) |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 225 | }; |
| 226 | |
| 227 | /** \class SkPDFDict |
| 228 | |
| 229 | A dictionary object in a PDF. |
| 230 | */ |
| 231 | class SkPDFDict : public SkPDFObject { |
| 232 | public: |
halcanary | bae235e | 2016-03-21 10:05:23 -0700 | [diff] [blame] | 233 | /** Create a PDF dictionary. |
| 234 | * @param type The value of the Type entry, nullptr for no type. |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 235 | */ |
halcanary | bae235e | 2016-03-21 10:05:23 -0700 | [diff] [blame] | 236 | explicit SkPDFDict(const char type[] = nullptr); |
vandebo@chromium.org | d877fdb | 2010-10-12 23:08:13 +0000 | [diff] [blame] | 237 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 238 | virtual ~SkPDFDict(); |
| 239 | |
| 240 | // The SkPDFObject interface. |
tfarina | f4219dd | 2015-04-27 17:18:28 -0700 | [diff] [blame] | 241 | void emitObject(SkWStream* stream, |
halcanary | 530032a | 2016-08-18 14:22:52 -0700 | [diff] [blame] | 242 | const SkPDFObjNumMap& objNumMap) const override; |
| 243 | void addResources(SkPDFObjNumMap*) const override; |
halcanary | bae235e | 2016-03-21 10:05:23 -0700 | [diff] [blame] | 244 | void drop() override; |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 245 | |
| 246 | /** The size of the dictionary. |
| 247 | */ |
halcanary | 1f8ed02 | 2014-06-27 10:37:27 -0700 | [diff] [blame] | 248 | int size() const; |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 249 | |
halcanary | 8103a34 | 2016-03-08 15:10:16 -0800 | [diff] [blame] | 250 | /** Add the value to the dictionary with the given key. |
reed@google.com | c789cf1 | 2011-07-20 12:14:33 +0000 | [diff] [blame] | 251 | * @param key The text of the key for this dictionary entry. |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 252 | * @param value The value for this dictionary entry. |
| 253 | */ |
halcanary | 8103a34 | 2016-03-08 15:10:16 -0800 | [diff] [blame] | 254 | void insertObject(const char key[], sk_sp<SkPDFObject>); |
| 255 | void insertObject(const SkString& key, sk_sp<SkPDFObject>); |
| 256 | void insertObjRef(const char key[], sk_sp<SkPDFObject>); |
| 257 | void insertObjRef(const SkString& key, sk_sp<SkPDFObject>); |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 258 | |
| 259 | /** Add the value to the dictionary with the given key. |
| 260 | * @param key The text of the key for this dictionary entry. |
| 261 | * @param value The value for this dictionary entry. |
reed@google.com | c789cf1 | 2011-07-20 12:14:33 +0000 | [diff] [blame] | 262 | */ |
halcanary | a25b337 | 2015-04-27 14:00:09 -0700 | [diff] [blame] | 263 | void insertBool(const char key[], bool value); |
reed@google.com | c789cf1 | 2011-07-20 12:14:33 +0000 | [diff] [blame] | 264 | void insertInt(const char key[], int32_t value); |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 265 | void insertInt(const char key[], size_t value); |
reed@google.com | c789cf1 | 2011-07-20 12:14:33 +0000 | [diff] [blame] | 266 | void insertScalar(const char key[], SkScalar value); |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 267 | void insertName(const char key[], const char nameValue[]); |
| 268 | void insertName(const char key[], const SkString& nameValue); |
| 269 | void insertString(const char key[], const char value[]); |
| 270 | void insertString(const char key[], const SkString& value); |
ctguil@chromium.org | a5c7234 | 2011-08-15 23:55:03 +0000 | [diff] [blame] | 271 | |
halcanary | 725c620 | 2015-08-20 08:09:37 -0700 | [diff] [blame] | 272 | /** Emit the dictionary, without the "<<" and ">>". |
| 273 | */ |
| 274 | void emitAll(SkWStream* stream, |
halcanary | 530032a | 2016-08-18 14:22:52 -0700 | [diff] [blame] | 275 | const SkPDFObjNumMap& objNumMap) const; |
halcanary | 725c620 | 2015-08-20 08:09:37 -0700 | [diff] [blame] | 276 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 277 | private: |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 278 | struct Record { |
| 279 | SkPDFUnion fKey; |
| 280 | SkPDFUnion fValue; |
halcanary | bae235e | 2016-03-21 10:05:23 -0700 | [diff] [blame] | 281 | Record(SkPDFUnion&&, SkPDFUnion&&); |
halcanary | 9be3720 | 2016-08-08 07:21:42 -0700 | [diff] [blame] | 282 | Record(Record&&) = default; |
| 283 | Record& operator=(Record&&) = default; |
halcanary | bae235e | 2016-03-21 10:05:23 -0700 | [diff] [blame] | 284 | Record(const Record&) = delete; |
| 285 | Record& operator=(const Record&) = delete; |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 286 | }; |
halcanary | bae235e | 2016-03-21 10:05:23 -0700 | [diff] [blame] | 287 | SkTArray<Record> fRecords; |
| 288 | SkDEBUGCODE(bool fDumped;) |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 289 | }; |
| 290 | |
halcanary | 725c620 | 2015-08-20 08:09:37 -0700 | [diff] [blame] | 291 | /** \class SkPDFSharedStream |
| 292 | |
| 293 | This class takes an asset and assumes that it is backed by |
| 294 | long-lived shared data (for example, an open file |
| 295 | descriptor). That is: no memory savings can be made by holding on |
| 296 | to a compressed version instead. |
| 297 | */ |
halcanary | 70d1554 | 2015-11-22 12:55:04 -0800 | [diff] [blame] | 298 | class SkPDFSharedStream final : public SkPDFObject { |
halcanary | 725c620 | 2015-08-20 08:09:37 -0700 | [diff] [blame] | 299 | public: |
halcanary | fa25106 | 2016-07-29 10:13:18 -0700 | [diff] [blame] | 300 | SkPDFSharedStream(std::unique_ptr<SkStreamAsset> data); |
halcanary | bae235e | 2016-03-21 10:05:23 -0700 | [diff] [blame] | 301 | ~SkPDFSharedStream(); |
halcanary | fa25106 | 2016-07-29 10:13:18 -0700 | [diff] [blame] | 302 | SkPDFDict* dict() { return &fDict; } |
halcanary | 725c620 | 2015-08-20 08:09:37 -0700 | [diff] [blame] | 303 | void emitObject(SkWStream*, |
halcanary | 530032a | 2016-08-18 14:22:52 -0700 | [diff] [blame] | 304 | const SkPDFObjNumMap&) const override; |
| 305 | void addResources(SkPDFObjNumMap*) const override; |
halcanary | bae235e | 2016-03-21 10:05:23 -0700 | [diff] [blame] | 306 | void drop() override; |
halcanary | 725c620 | 2015-08-20 08:09:37 -0700 | [diff] [blame] | 307 | |
| 308 | private: |
halcanary | b8fb993 | 2016-03-28 07:58:30 -0700 | [diff] [blame] | 309 | std::unique_ptr<SkStreamAsset> fAsset; |
halcanary | fa25106 | 2016-07-29 10:13:18 -0700 | [diff] [blame] | 310 | SkPDFDict fDict; |
halcanary | 725c620 | 2015-08-20 08:09:37 -0700 | [diff] [blame] | 311 | typedef SkPDFObject INHERITED; |
| 312 | }; |
| 313 | |
halcanary | fa25106 | 2016-07-29 10:13:18 -0700 | [diff] [blame] | 314 | /** \class SkPDFStream |
| 315 | |
| 316 | This class takes an asset and assumes that it is the only owner of |
| 317 | the asset's data. It immediately compresses the asset to save |
| 318 | memory. |
| 319 | */ |
| 320 | |
halcanary | dabd4f0 | 2016-08-03 11:16:56 -0700 | [diff] [blame] | 321 | class SkPDFStream final : public SkPDFObject { |
halcanary | fa25106 | 2016-07-29 10:13:18 -0700 | [diff] [blame] | 322 | |
| 323 | public: |
| 324 | /** Create a PDF stream. A Length entry is automatically added to the |
| 325 | * stream dictionary. |
| 326 | * @param data The data part of the stream. |
| 327 | * @param stream The data part of the stream. */ |
| 328 | explicit SkPDFStream(sk_sp<SkData> data); |
| 329 | explicit SkPDFStream(std::unique_ptr<SkStreamAsset> stream); |
| 330 | virtual ~SkPDFStream(); |
| 331 | |
| 332 | SkPDFDict* dict() { return &fDict; } |
| 333 | |
| 334 | // The SkPDFObject interface. |
| 335 | void emitObject(SkWStream* stream, |
halcanary | 530032a | 2016-08-18 14:22:52 -0700 | [diff] [blame] | 336 | const SkPDFObjNumMap& objNumMap) const override; |
| 337 | void addResources(SkPDFObjNumMap*) const final; |
halcanary | fa25106 | 2016-07-29 10:13:18 -0700 | [diff] [blame] | 338 | void drop() override; |
| 339 | |
| 340 | protected: |
| 341 | /* Create a PDF stream with no data. The setData method must be called to |
| 342 | * set the data. */ |
| 343 | SkPDFStream(); |
| 344 | |
| 345 | /** Only call this function once. */ |
| 346 | void setData(std::unique_ptr<SkStreamAsset> stream); |
| 347 | |
| 348 | private: |
| 349 | std::unique_ptr<SkStreamAsset> fCompressedData; |
| 350 | SkPDFDict fDict; |
| 351 | |
| 352 | typedef SkPDFDict INHERITED; |
| 353 | }; |
| 354 | |
halcanary | 37c46ca | 2015-03-31 12:30:20 -0700 | [diff] [blame] | 355 | //////////////////////////////////////////////////////////////////////////////// |
| 356 | |
halcanary | 37c46ca | 2015-03-31 12:30:20 -0700 | [diff] [blame] | 357 | /** \class SkPDFObjNumMap |
| 358 | |
| 359 | The PDF Object Number Map manages object numbers. It is used to |
| 360 | create the PDF cross reference table. |
| 361 | */ |
| 362 | class SkPDFObjNumMap : SkNoncopyable { |
| 363 | public: |
| 364 | /** Add the passed object to the catalog. |
| 365 | * @param obj The object to add. |
| 366 | * @return True iff the object was not already added to the catalog. |
| 367 | */ |
| 368 | bool addObject(SkPDFObject* obj); |
| 369 | |
halcanary | 3442261 | 2015-10-12 10:11:18 -0700 | [diff] [blame] | 370 | /** Add the passed object to the catalog, as well as all its dependencies. |
| 371 | * @param obj The object to add. If nullptr, this is a noop. |
halcanary | 3442261 | 2015-10-12 10:11:18 -0700 | [diff] [blame] | 372 | */ |
halcanary | 530032a | 2016-08-18 14:22:52 -0700 | [diff] [blame] | 373 | void addObjectRecursively(SkPDFObject* obj); |
halcanary | 3442261 | 2015-10-12 10:11:18 -0700 | [diff] [blame] | 374 | |
halcanary | 37c46ca | 2015-03-31 12:30:20 -0700 | [diff] [blame] | 375 | /** Get the object number for the passed object. |
| 376 | * @param obj The object of interest. |
| 377 | */ |
| 378 | int32_t getObjectNumber(SkPDFObject* obj) const; |
| 379 | |
halcanary | bae235e | 2016-03-21 10:05:23 -0700 | [diff] [blame] | 380 | const SkTArray<sk_sp<SkPDFObject>>& objects() const { return fObjects; } |
halcanary | 37c46ca | 2015-03-31 12:30:20 -0700 | [diff] [blame] | 381 | |
| 382 | private: |
halcanary | bae235e | 2016-03-21 10:05:23 -0700 | [diff] [blame] | 383 | SkTArray<sk_sp<SkPDFObject>> fObjects; |
halcanary | 37c46ca | 2015-03-31 12:30:20 -0700 | [diff] [blame] | 384 | SkTHashMap<SkPDFObject*, int32_t> fObjectNumbers; |
| 385 | }; |
| 386 | |
halcanary | 130444f | 2015-04-25 06:45:07 -0700 | [diff] [blame] | 387 | //////////////////////////////////////////////////////////////////////////////// |
| 388 | |
halcanary | 7a14b31 | 2015-10-01 07:28:13 -0700 | [diff] [blame] | 389 | #ifdef SK_PDF_IMAGE_STATS |
| 390 | extern SkAtomic<int> gDrawImageCalls; |
| 391 | extern SkAtomic<int> gJpegImageObjects; |
| 392 | extern SkAtomic<int> gRegularImageObjects; |
| 393 | extern void SkPDFImageDumpStats(); |
| 394 | #endif // SK_PDF_IMAGE_STATS |
| 395 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 396 | #endif |