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