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     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