1 2 /* 3 * Copyright 2010 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #ifndef SkPDFTypes_DEFINED 11 #define SkPDFTypes_DEFINED 12 13 #include "SkRefCnt.h" 14 #include "SkScalar.h" 15 #include "SkString.h" 16 #include "SkTDArray.h" 17 #include "SkTypes.h" 18 19 class SkPDFCatalog; 20 class SkWStream; 21 22 /** \class SkPDFObject 23 24 A PDF Object is the base class for primitive elements in a PDF file. A 25 common subtype is used to ease the use of indirect object references, 26 which are common in the PDF format. 27 */ 28 class SkPDFObject : public SkRefCnt { 29 public: 30 SK_DECLARE_INST_COUNT(SkPDFObject) 31 32 /** Return the size (number of bytes) of this object in the final output 33 * file. Compound objects or objects that are computationally intensive 34 * to output should override this method. 35 * @param catalog The object catalog to use. 36 * @param indirect If true, output an object identifier with the object. 37 */ 38 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); 39 40 /** For non-primitive objects (i.e. objects defined outside this file), 41 * this method will add to resourceList any objects that this method 42 * depends on. This operates recursively so if this object depends on 43 * another object and that object depends on two more, all three objects 44 * will be added. 45 * @param resourceList The list to append dependant resources to. 46 */ 47 virtual void getResources(SkTDArray<SkPDFObject*>* resourceList); 48 49 /** Emit this object unless the catalog has a substitute object, in which 50 * case emit that. 51 * @see emitObject 52 */ 53 void emit(SkWStream* stream, SkPDFCatalog* catalog, bool indirect); 54 55 /** Helper function to output an indirect object. 56 * @param catalog The object catalog to use. 57 * @param stream The writable output stream to send the output to. 58 */ 59 void emitIndirectObject(SkWStream* stream, SkPDFCatalog* catalog); 60 61 /** Helper function to find the size of an indirect object. 62 * @param catalog The object catalog to use. 63 */ 64 size_t getIndirectOutputSize(SkPDFCatalog* catalog); 65 66 /** Static helper function to add a resource to a list. The list takes 67 * a reference. 68 * @param resource The resource to add. 69 * @param list The list to add the resource to. 70 */ 71 static void AddResourceHelper(SkPDFObject* resource, 72 SkTDArray<SkPDFObject*>* list); 73 74 /** Static helper function to copy and reference the resources (and all 75 * their subresources) into a new list. 76 * @param resources The resource list. 77 * @param result The list to add to. 78 */ 79 static void GetResourcesHelper(SkTDArray<SkPDFObject*>* resources, 80 SkTDArray<SkPDFObject*>* result); 81 82 protected: 83 /** Subclasses must implement this method to print the object to the 84 * PDF file. 85 * @param catalog The object catalog to use. 86 * @param indirect If true, output an object identifier with the object. 87 * @param stream The writable output stream to send the output to. 88 */ 89 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, 90 bool indirect) = 0; 91 92 typedef SkRefCnt INHERITED; 93 }; 94 95 /** \class SkPDFObjRef 96 97 An indirect reference to a PDF object. 98 */ 99 class SkPDFObjRef : public SkPDFObject { 100 public: 101 SK_DECLARE_INST_COUNT(SkPDFObjRef) 102 103 /** Create a reference to an existing SkPDFObject. 104 * @param obj The object to reference. 105 */ 106 explicit SkPDFObjRef(SkPDFObject* obj); 107 virtual ~SkPDFObjRef(); 108 109 // The SkPDFObject interface. 110 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, 111 bool indirect); 112 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); 113 114 private: 115 SkAutoTUnref<SkPDFObject> fObj; 116 117 typedef SkPDFObject INHERITED; 118 }; 119 120 /** \class SkPDFInt 121 122 An integer object in a PDF. 123 */ 124 class SkPDFInt : public SkPDFObject { 125 public: 126 SK_DECLARE_INST_COUNT(SkPDFInt) 127 128 /** Create a PDF integer (usually for indirect reference purposes). 129 * @param value An integer value between 2^31 - 1 and -2^31. 130 */ 131 explicit SkPDFInt(int32_t value); 132 virtual ~SkPDFInt(); 133 134 // The SkPDFObject interface. 135 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, 136 bool indirect); 137 138 private: 139 int32_t fValue; 140 141 typedef SkPDFObject INHERITED; 142 }; 143 144 /** \class SkPDFBool 145 146 An boolean value in a PDF. 147 */ 148 class SkPDFBool : public SkPDFObject { 149 public: 150 SK_DECLARE_INST_COUNT(SkPDFBool) 151 152 /** Create a PDF boolean. 153 * @param value true or false. 154 */ 155 explicit SkPDFBool(bool value); 156 virtual ~SkPDFBool(); 157 158 // The SkPDFObject interface. 159 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, 160 bool indirect); 161 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); 162 163 private: 164 bool fValue; 165 166 typedef SkPDFObject INHERITED; 167 }; 168 169 /** \class SkPDFScalar 170 171 A real number object in a PDF. 172 */ 173 class SkPDFScalar : public SkPDFObject { 174 public: 175 SK_DECLARE_INST_COUNT(SkPDFScalar) 176 177 /** Create a PDF real number. 178 * @param value A real value. 179 */ 180 explicit SkPDFScalar(SkScalar value); 181 virtual ~SkPDFScalar(); 182 183 static void Append(SkScalar value, SkWStream* stream); 184 185 // The SkPDFObject interface. 186 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, 187 bool indirect); 188 189 private: 190 SkScalar fValue; 191 192 typedef SkPDFObject INHERITED; 193 }; 194 195 /** \class SkPDFString 196 197 A string object in a PDF. 198 */ 199 class SkPDFString : public SkPDFObject { 200 public: 201 SK_DECLARE_INST_COUNT(SkPDFString) 202 203 /** Create a PDF string. Maximum length (in bytes) is 65,535. 204 * @param value A string value. 205 */ 206 explicit SkPDFString(const char value[]); 207 explicit SkPDFString(const SkString& value); 208 209 /** Create a PDF string. Maximum length (in bytes) is 65,535. 210 * @param value A string value. 211 * @param len The length of value. 212 * @param wideChars Indicates if the top byte in value is significant and 213 * should be encoded (true) or not (false). 214 */ 215 SkPDFString(const uint16_t* value, size_t len, bool wideChars); 216 virtual ~SkPDFString(); 217 218 // The SkPDFObject interface. 219 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, 220 bool indirect); 221 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); 222 223 static SkString FormatString(const char* input, size_t len); 224 static SkString FormatString(const uint16_t* input, size_t len, 225 bool wideChars); 226 private: 227 static const size_t kMaxLen = 65535; 228 229 const SkString fValue; 230 231 static SkString DoFormatString(const void* input, size_t len, 232 bool wideInput, bool wideOutput); 233 234 typedef SkPDFObject INHERITED; 235 }; 236 237 /** \class SkPDFName 238 239 A name object in a PDF. 240 */ 241 class SkPDFName : public SkPDFObject { 242 public: 243 SK_DECLARE_INST_COUNT(SkPDFName) 244 245 /** Create a PDF name object. Maximum length is 127 bytes. 246 * @param value The name. 247 */ 248 explicit SkPDFName(const char name[]); 249 explicit SkPDFName(const SkString& name); 250 virtual ~SkPDFName(); 251 252 bool operator==(const SkPDFName& b) const; 253 254 // The SkPDFObject interface. 255 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, 256 bool indirect); 257 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); 258 259 private: 260 static const size_t kMaxLen = 127; 261 262 const SkString fValue; 263 264 static SkString FormatName(const SkString& input); 265 266 typedef SkPDFObject INHERITED; 267 }; 268 269 /** \class SkPDFArray 270 271 An array object in a PDF. 272 */ 273 class SkPDFArray : public SkPDFObject { 274 public: 275 SK_DECLARE_INST_COUNT(SkPDFArray) 276 277 /** Create a PDF array. Maximum length is 8191. 278 */ 279 SkPDFArray(); 280 virtual ~SkPDFArray(); 281 282 // The SkPDFObject interface. 283 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, 284 bool indirect); 285 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); 286 287 /** The size of the array. 288 */ 289 int size() { return fValue.count(); } 290 291 /** Preallocate space for the given number of entries. 292 * @param length The number of array slots to preallocate. 293 */ 294 void reserve(int length); 295 296 /** Returns the object at the given offset in the array. 297 * @param index The index into the array to retrieve. 298 */ 299 SkPDFObject* getAt(int index) { return fValue[index]; } 300 301 /** Set the object at the given offset in the array. Ref's value. 302 * @param index The index into the array to set. 303 * @param value The value to add to the array. 304 * @return The value argument is returned. 305 */ 306 SkPDFObject* setAt(int index, SkPDFObject* value); 307 308 /** Append the object to the end of the array and increments its ref count. 309 * @param value The value to add to the array. 310 * @return The value argument is returned. 311 */ 312 SkPDFObject* append(SkPDFObject* value); 313 314 /** Creates a SkPDFInt object and appends it to the array. 315 * @param value The value to add to the array. 316 */ 317 void appendInt(int32_t value); 318 319 /** Creates a SkPDFScalar object and appends it to the array. 320 * @param value The value to add to the array. 321 */ 322 void appendScalar(SkScalar value); 323 324 /** Creates a SkPDFName object and appends it to the array. 325 * @param value The value to add to the array. 326 */ 327 void appendName(const char name[]); 328 329 private: 330 static const int kMaxLen = 8191; 331 SkTDArray<SkPDFObject*> fValue; 332 333 typedef SkPDFObject INHERITED; 334 }; 335 336 /** \class SkPDFDict 337 338 A dictionary object in a PDF. 339 */ 340 class SkPDFDict : public SkPDFObject { 341 public: 342 SK_DECLARE_INST_COUNT(SkPDFDict) 343 344 /** Create a PDF dictionary. Maximum number of entries is 4095. 345 */ 346 SkPDFDict(); 347 348 /** Create a PDF dictionary with a Type entry. 349 * @param type The value of the Type entry. 350 */ 351 explicit SkPDFDict(const char type[]); 352 353 virtual ~SkPDFDict(); 354 355 // The SkPDFObject interface. 356 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, 357 bool indirect); 358 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); 359 360 /** The size of the dictionary. 361 */ 362 int size() { return fValue.count(); } 363 364 /** Add the value to the dictionary with the given key. Refs value. 365 * @param key The key for this dictionary entry. 366 * @param value The value for this dictionary entry. 367 * @return The value argument is returned. 368 */ 369 SkPDFObject* insert(SkPDFName* key, SkPDFObject* value); 370 371 /** Add the value to the dictionary with the given key. Refs value. The 372 * method will create the SkPDFName object. 373 * @param key The text of the key for this dictionary entry. 374 * @param value The value for this dictionary entry. 375 * @return The value argument is returned. 376 */ 377 SkPDFObject* insert(const char key[], SkPDFObject* value); 378 379 /** Add the int to the dictionary with the given key. 380 * @param key The text of the key for this dictionary entry. 381 * @param value The int value for this dictionary entry. 382 */ 383 void insertInt(const char key[], int32_t value); 384 385 /** Add the scalar to the dictionary with the given key. 386 * @param key The text of the key for this dictionary entry. 387 * @param value The scalar value for this dictionary entry. 388 */ 389 void insertScalar(const char key[], SkScalar value); 390 391 /** Add the name to the dictionary with the given key. 392 * @param key The text of the key for this dictionary entry. 393 * @param name The name for this dictionary entry. 394 */ 395 void insertName(const char key[], const char name[]); 396 397 /** Add the name to the dictionary with the given key. 398 * @param key The text of the key for this dictionary entry. 399 * @param name The name for this dictionary entry. 400 */ 401 void insertName(const char key[], const SkString& name) { 402 this->insertName(key, name.c_str()); 403 } 404 405 /** Remove all entries from the dictionary. 406 */ 407 void clear(); 408 409 private: 410 struct Rec { 411 SkPDFName* key; 412 SkPDFObject* value; 413 }; 414 415 public: 416 class Iter { 417 public: 418 explicit Iter(const SkPDFDict& dict); 419 SkPDFName* next(SkPDFObject** value); 420 421 private: 422 Rec* fIter; 423 Rec* fStop; 424 }; 425 426 private: 427 static const int kMaxLen = 4095; 428 429 SkTDArray<struct Rec> fValue; 430 431 typedef SkPDFObject INHERITED; 432 }; 433 434 #endif 435