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