vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2010 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | #ifndef SkPDFTypes_DEFINED |
| 18 | #define SkPDFTypes_DEFINED |
| 19 | |
| 20 | #include "SkRefCnt.h" |
| 21 | #include "SkScalar.h" |
| 22 | #include "SkString.h" |
| 23 | #include "SkTDArray.h" |
vandebo@chromium.org | 28be72b | 2010-11-11 21:37:00 +0000 | [diff] [blame] | 24 | #include "SkTypes.h" |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 25 | |
| 26 | class SkPDFCatalog; |
| 27 | class SkWStream; |
| 28 | |
| 29 | /** \class SkPDFObject |
| 30 | |
| 31 | A PDF Object is the base class for primitive elements in a PDF file. A |
| 32 | common subtype is used to ease the use of indirect object references, |
| 33 | which are common in the PDF format. |
| 34 | */ |
| 35 | class SkPDFObject : public SkRefCnt { |
| 36 | public: |
| 37 | /** Create a PDF object. |
| 38 | */ |
vandebo@chromium.org | f66025d | 2010-10-01 23:26:55 +0000 | [diff] [blame] | 39 | SkPDFObject(); |
| 40 | virtual ~SkPDFObject(); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 41 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 42 | /** Return the size (number of bytes) of this object in the final output |
| 43 | * file. Compound objects or objects that are computationally intensive |
| 44 | * to output should override this method. |
| 45 | * @param catalog The object catalog to use. |
| 46 | * @param indirect If true, output an object identifier with the object. |
| 47 | */ |
| 48 | virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); |
| 49 | |
vandebo@chromium.org | a518086 | 2010-10-26 19:48:49 +0000 | [diff] [blame] | 50 | /** If this object explicitly depends on other objects, add them to the |
| 51 | * end of the list. This only applies to higher level object, where |
| 52 | * the depenency is explicit and introduced by the class. i.e. an |
| 53 | * SkPDFImage added to an SkPDFDevice, but not an SkPDFObjRef added to |
| 54 | * an SkPDFArray. |
| 55 | * @param resourceList The list to append dependant resources to. |
| 56 | */ |
| 57 | virtual void getResources(SkTDArray<SkPDFObject*>* resourceList); |
| 58 | |
vandebo@chromium.org | 2ef12d4 | 2011-07-06 23:31:24 +0000 | [diff] [blame] | 59 | /** Emit this object unless the catalog has a substitute object, in which |
| 60 | * case emit that. |
| 61 | * @see emitObject |
| 62 | */ |
| 63 | void emit(SkWStream* stream, SkPDFCatalog* catalog, bool indirect); |
| 64 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 65 | /** Helper function to output an indirect object. |
| 66 | * @param catalog The object catalog to use. |
| 67 | * @param stream The writable output stream to send the output to. |
| 68 | */ |
| 69 | void emitIndirectObject(SkWStream* stream, SkPDFCatalog* catalog); |
| 70 | |
| 71 | /** Helper function to find the size of an indirect object. |
| 72 | * @param catalog The object catalog to use. |
| 73 | */ |
| 74 | size_t getIndirectOutputSize(SkPDFCatalog* catalog); |
vandebo@chromium.org | 2ef12d4 | 2011-07-06 23:31:24 +0000 | [diff] [blame] | 75 | |
| 76 | protected: |
| 77 | /** Subclasses must implement this method to print the object to the |
| 78 | * PDF file. |
| 79 | * @param catalog The object catalog to use. |
| 80 | * @param indirect If true, output an object identifier with the object. |
| 81 | * @param stream The writable output stream to send the output to. |
| 82 | */ |
| 83 | virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, |
| 84 | bool indirect) = 0; |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 85 | }; |
| 86 | |
| 87 | /** \class SkPDFObjRef |
| 88 | |
| 89 | An indirect reference to a PDF object. |
| 90 | */ |
| 91 | class SkPDFObjRef : public SkPDFObject { |
| 92 | public: |
| 93 | /** Create a reference to an existing SkPDFObject. |
| 94 | * @param obj The object to reference. |
| 95 | */ |
vandebo@chromium.org | f66025d | 2010-10-01 23:26:55 +0000 | [diff] [blame] | 96 | explicit SkPDFObjRef(SkPDFObject* obj); |
| 97 | virtual ~SkPDFObjRef(); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 98 | |
| 99 | // The SkPDFObject interface. |
| 100 | virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, |
| 101 | bool indirect); |
| 102 | virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); |
| 103 | |
| 104 | private: |
| 105 | SkRefPtr<SkPDFObject> fObj; |
| 106 | }; |
| 107 | |
| 108 | /** \class SkPDFInt |
| 109 | |
| 110 | An integer object in a PDF. |
| 111 | */ |
| 112 | class SkPDFInt : public SkPDFObject { |
| 113 | public: |
| 114 | /** Create a PDF integer (usually for indirect reference purposes). |
| 115 | * @param value An integer value between 2^31 - 1 and -2^31. |
| 116 | */ |
vandebo@chromium.org | f66025d | 2010-10-01 23:26:55 +0000 | [diff] [blame] | 117 | explicit SkPDFInt(int32_t value); |
| 118 | virtual ~SkPDFInt(); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 119 | |
| 120 | // The SkPDFObject interface. |
| 121 | virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, |
| 122 | bool indirect); |
| 123 | |
| 124 | private: |
| 125 | int32_t fValue; |
| 126 | }; |
| 127 | |
vandebo@chromium.org | 9b49dc0 | 2010-10-20 22:23:29 +0000 | [diff] [blame] | 128 | /** \class SkPDFBool |
| 129 | |
| 130 | An boolean value in a PDF. |
| 131 | */ |
| 132 | class SkPDFBool : public SkPDFObject { |
| 133 | public: |
| 134 | /** Create a PDF boolean. |
| 135 | * @param value true or false. |
| 136 | */ |
| 137 | explicit SkPDFBool(bool value); |
| 138 | virtual ~SkPDFBool(); |
| 139 | |
| 140 | // The SkPDFObject interface. |
| 141 | virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, |
| 142 | bool indirect); |
| 143 | virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); |
| 144 | |
| 145 | private: |
| 146 | bool fValue; |
| 147 | }; |
| 148 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 149 | /** \class SkPDFScalar |
| 150 | |
| 151 | A real number object in a PDF. |
| 152 | */ |
| 153 | class SkPDFScalar : public SkPDFObject { |
| 154 | public: |
| 155 | /** Create a PDF real number. |
| 156 | * @param value A real value. |
| 157 | */ |
vandebo@chromium.org | f66025d | 2010-10-01 23:26:55 +0000 | [diff] [blame] | 158 | explicit SkPDFScalar(SkScalar value); |
| 159 | virtual ~SkPDFScalar(); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 160 | |
vandebo@chromium.org | cae5fba | 2011-03-28 19:03:50 +0000 | [diff] [blame] | 161 | static void Append(SkScalar value, SkWStream* stream); |
vandebo@chromium.org | 094316b | 2011-03-04 03:15:13 +0000 | [diff] [blame] | 162 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 163 | // The SkPDFObject interface. |
| 164 | virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, |
| 165 | bool indirect); |
| 166 | |
| 167 | private: |
| 168 | SkScalar fValue; |
| 169 | }; |
| 170 | |
| 171 | /** \class SkPDFString |
| 172 | |
| 173 | A string object in a PDF. |
| 174 | */ |
| 175 | class SkPDFString : public SkPDFObject { |
| 176 | public: |
| 177 | /** Create a PDF string. Maximum length (in bytes) is 65,535. |
| 178 | * @param value A string value. |
| 179 | */ |
vandebo@chromium.org | f66025d | 2010-10-01 23:26:55 +0000 | [diff] [blame] | 180 | explicit SkPDFString(const char value[]); |
| 181 | explicit SkPDFString(const SkString& value); |
vandebo@chromium.org | 28be72b | 2010-11-11 21:37:00 +0000 | [diff] [blame] | 182 | |
| 183 | /** Create a PDF string. Maximum length (in bytes) is 65,535. |
| 184 | * @param value A string value. |
| 185 | * @param len The length of value. |
| 186 | * @param wideChars Indicates if the top byte in value is significant and |
| 187 | * should be encoded (true) or not (false). |
| 188 | */ |
| 189 | SkPDFString(const uint16_t* value, size_t len, bool wideChars); |
vandebo@chromium.org | f66025d | 2010-10-01 23:26:55 +0000 | [diff] [blame] | 190 | virtual ~SkPDFString(); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 191 | |
| 192 | // The SkPDFObject interface. |
| 193 | virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, |
| 194 | bool indirect); |
| 195 | virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); |
| 196 | |
vandebo@chromium.org | 28be72b | 2010-11-11 21:37:00 +0000 | [diff] [blame] | 197 | static SkString formatString(const char* input, size_t len); |
| 198 | static SkString formatString(const uint16_t* input, size_t len, |
| 199 | bool wideChars); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 200 | private: |
vandebo@chromium.org | d877fdb | 2010-10-12 23:08:13 +0000 | [diff] [blame] | 201 | static const size_t kMaxLen = 65535; |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 202 | |
| 203 | const SkString fValue; |
| 204 | |
vandebo@chromium.org | 28be72b | 2010-11-11 21:37:00 +0000 | [diff] [blame] | 205 | static SkString doFormatString(const void* input, size_t len, |
| 206 | bool wideInput, bool wideOutput); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 207 | }; |
| 208 | |
| 209 | /** \class SkPDFName |
| 210 | |
| 211 | A name object in a PDF. |
| 212 | */ |
| 213 | class SkPDFName : public SkPDFObject { |
| 214 | public: |
| 215 | /** Create a PDF name object. Maximum length is 127 bytes. |
| 216 | * @param value The name. |
| 217 | */ |
vandebo@chromium.org | f66025d | 2010-10-01 23:26:55 +0000 | [diff] [blame] | 218 | explicit SkPDFName(const char name[]); |
| 219 | explicit SkPDFName(const SkString& name); |
| 220 | virtual ~SkPDFName(); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 221 | |
| 222 | // The SkPDFObject interface. |
| 223 | virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, |
| 224 | bool indirect); |
| 225 | virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); |
| 226 | |
| 227 | private: |
vandebo@chromium.org | d877fdb | 2010-10-12 23:08:13 +0000 | [diff] [blame] | 228 | static const size_t kMaxLen = 127; |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 229 | |
| 230 | const SkString fValue; |
| 231 | |
vandebo@chromium.org | f66025d | 2010-10-01 23:26:55 +0000 | [diff] [blame] | 232 | static SkString formatName(const SkString& input); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 233 | }; |
| 234 | |
| 235 | /** \class SkPDFArray |
| 236 | |
| 237 | An array object in a PDF. |
| 238 | */ |
| 239 | class SkPDFArray : public SkPDFObject { |
| 240 | public: |
| 241 | /** Create a PDF array. Maximum length is 8191. |
| 242 | */ |
vandebo@chromium.org | f66025d | 2010-10-01 23:26:55 +0000 | [diff] [blame] | 243 | SkPDFArray(); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 244 | virtual ~SkPDFArray(); |
| 245 | |
| 246 | // The SkPDFObject interface. |
| 247 | virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, |
| 248 | bool indirect); |
| 249 | virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); |
| 250 | |
| 251 | /** The size of the array. |
| 252 | */ |
| 253 | int size() { return fValue.count(); } |
| 254 | |
| 255 | /** Preallocate space for the given number of entries. |
| 256 | * @param length The number of array slots to preallocate. |
| 257 | */ |
| 258 | void reserve(int length); |
| 259 | |
| 260 | /** Returns the object at the given offset in the array. |
| 261 | * @param index The index into the array to retrieve. |
| 262 | */ |
| 263 | SkPDFObject* getAt(int index) { return fValue[index]; } |
| 264 | |
vandebo@chromium.org | f7c1576 | 2011-02-01 22:19:44 +0000 | [diff] [blame] | 265 | /** Set the object at the given offset in the array. Ref's value. |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 266 | * @param index The index into the array to set. |
| 267 | * @param value The value to add to the array. |
vandebo@chromium.org | f7c1576 | 2011-02-01 22:19:44 +0000 | [diff] [blame] | 268 | * @return The value argument is returned. |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 269 | */ |
vandebo@chromium.org | f7c1576 | 2011-02-01 22:19:44 +0000 | [diff] [blame] | 270 | SkPDFObject* setAt(int index, SkPDFObject* value); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 271 | |
vandebo@chromium.org | f7c1576 | 2011-02-01 22:19:44 +0000 | [diff] [blame] | 272 | /** Append the object to the end of the array and increments its ref count. |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 273 | * @param value The value to add to the array. |
vandebo@chromium.org | f7c1576 | 2011-02-01 22:19:44 +0000 | [diff] [blame] | 274 | * @return The value argument is returned. |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 275 | */ |
vandebo@chromium.org | f7c1576 | 2011-02-01 22:19:44 +0000 | [diff] [blame] | 276 | SkPDFObject* append(SkPDFObject* value); |
reed@google.com | c789cf1 | 2011-07-20 12:14:33 +0000 | [diff] [blame^] | 277 | |
| 278 | /** Creates a SkPDFInt object and appends it to the array. |
| 279 | * @param value The value to add to the array. |
| 280 | */ |
| 281 | void appendInt(int32_t value); |
| 282 | |
| 283 | /** Creates a SkPDFScalar object and appends it to the array. |
| 284 | * @param value The value to add to the array. |
| 285 | */ |
| 286 | void appendScalar(SkScalar value); |
| 287 | |
| 288 | /** Creates a SkPDFName object and appends it to the array. |
| 289 | * @param value The value to add to the array. |
| 290 | */ |
| 291 | void appendName(const char name[]); |
| 292 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 293 | private: |
| 294 | static const int kMaxLen = 8191; |
| 295 | SkTDArray<SkPDFObject*> fValue; |
| 296 | }; |
| 297 | |
| 298 | /** \class SkPDFDict |
| 299 | |
| 300 | A dictionary object in a PDF. |
| 301 | */ |
| 302 | class SkPDFDict : public SkPDFObject { |
| 303 | public: |
| 304 | /** Create a PDF dictionary. Maximum number of entries is 4095. |
| 305 | */ |
vandebo@chromium.org | f66025d | 2010-10-01 23:26:55 +0000 | [diff] [blame] | 306 | SkPDFDict(); |
vandebo@chromium.org | d877fdb | 2010-10-12 23:08:13 +0000 | [diff] [blame] | 307 | |
| 308 | /** Create a PDF dictionary with a Type entry. |
| 309 | * @param type The value of the Type entry. |
| 310 | */ |
| 311 | explicit SkPDFDict(const char type[]); |
| 312 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 313 | virtual ~SkPDFDict(); |
| 314 | |
| 315 | // The SkPDFObject interface. |
| 316 | virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, |
| 317 | bool indirect); |
| 318 | virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); |
| 319 | |
| 320 | /** The size of the dictionary. |
| 321 | */ |
| 322 | int size() { return fValue.count(); } |
| 323 | |
vandebo@chromium.org | f7c1576 | 2011-02-01 22:19:44 +0000 | [diff] [blame] | 324 | /** Add the value to the dictionary with the given key. Refs value. |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 325 | * @param key The key for this dictionary entry. |
| 326 | * @param value The value for this dictionary entry. |
vandebo@chromium.org | f7c1576 | 2011-02-01 22:19:44 +0000 | [diff] [blame] | 327 | * @return The value argument is returned. |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 328 | */ |
vandebo@chromium.org | f7c1576 | 2011-02-01 22:19:44 +0000 | [diff] [blame] | 329 | SkPDFObject* insert(SkPDFName* key, SkPDFObject* value); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 330 | |
vandebo@chromium.org | f7c1576 | 2011-02-01 22:19:44 +0000 | [diff] [blame] | 331 | /** Add the value to the dictionary with the given key. Refs value. The |
| 332 | * method will create the SkPDFName object. |
vandebo@chromium.org | d877fdb | 2010-10-12 23:08:13 +0000 | [diff] [blame] | 333 | * @param key The text of the key for this dictionary entry. |
| 334 | * @param value The value for this dictionary entry. |
vandebo@chromium.org | f7c1576 | 2011-02-01 22:19:44 +0000 | [diff] [blame] | 335 | * @return The value argument is returned. |
vandebo@chromium.org | d877fdb | 2010-10-12 23:08:13 +0000 | [diff] [blame] | 336 | */ |
vandebo@chromium.org | f7c1576 | 2011-02-01 22:19:44 +0000 | [diff] [blame] | 337 | SkPDFObject* insert(const char key[], SkPDFObject* value); |
reed@google.com | c789cf1 | 2011-07-20 12:14:33 +0000 | [diff] [blame^] | 338 | |
| 339 | /** Add the int to the dictionary with the given key. |
| 340 | * @param key The text of the key for this dictionary entry. |
| 341 | * @param value The int value for this dictionary entry. |
| 342 | */ |
| 343 | void insertInt(const char key[], int32_t value); |
| 344 | |
| 345 | /** Add the scalar to the dictionary with the given key. |
| 346 | * @param key The text of the key for this dictionary entry. |
| 347 | * @param value The scalar value for this dictionary entry. |
| 348 | */ |
| 349 | void insertScalar(const char key[], SkScalar value); |
| 350 | |
| 351 | /** Add the name to the dictionary with the given key. |
| 352 | * @param key The text of the key for this dictionary entry. |
| 353 | * @param name The name for this dictionary entry. |
| 354 | */ |
| 355 | void insertName(const char key[], const char name[]); |
vandebo@chromium.org | d877fdb | 2010-10-12 23:08:13 +0000 | [diff] [blame] | 356 | |
reed@google.com | c789cf1 | 2011-07-20 12:14:33 +0000 | [diff] [blame^] | 357 | /** Add the name to the dictionary with the given key. |
| 358 | * @param key The text of the key for this dictionary entry. |
| 359 | * @param name The name for this dictionary entry. |
| 360 | */ |
| 361 | void insertName(const char key[], const SkString& name) { |
| 362 | this->insertName(key, name.c_str()); |
| 363 | } |
| 364 | |
vandebo@chromium.org | d877fdb | 2010-10-12 23:08:13 +0000 | [diff] [blame] | 365 | /** Remove all entries from the dictionary. |
| 366 | */ |
| 367 | void clear(); |
| 368 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 369 | private: |
| 370 | static const int kMaxLen = 4095; |
| 371 | |
| 372 | struct Rec { |
| 373 | SkPDFName* key; |
| 374 | SkPDFObject* value; |
| 375 | }; |
| 376 | |
| 377 | SkTDArray<struct Rec> fValue; |
| 378 | }; |
| 379 | |
| 380 | #endif |