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