| /* | |
| * Copyright 2010 The Android Open Source Project | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #ifndef SkPDFTypes_DEFINED | |
| #define SkPDFTypes_DEFINED | |
| #include "SkRefCnt.h" | |
| #include "SkScalar.h" | |
| #include "SkString.h" | |
| #include "SkTDArray.h" | |
| #include "SkTSet.h" | |
| #include "SkTypes.h" | |
| class SkPDFCatalog; | |
| class SkWStream; | |
| /** \class SkPDFObject | |
| A PDF Object is the base class for primitive elements in a PDF file. A | |
| common subtype is used to ease the use of indirect object references, | |
| which are common in the PDF format. | |
| */ | |
| class SkPDFObject : public SkRefCnt { | |
| public: | |
| SK_DECLARE_INST_COUNT(SkPDFObject) | |
| /** Return the size (number of bytes) of this object in the final output | |
| * file. Compound objects or objects that are computationally intensive | |
| * to output should override this method. | |
| * @param catalog The object catalog to use. | |
| * @param indirect If true, output an object identifier with the object. | |
| */ | |
| virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); | |
| /** For non-primitive objects (i.e. objects defined outside this file), | |
| * this method will add to newResourceObjects any objects that this method | |
| * depends on, but not already in knownResourceObjects. This operates | |
| * recursively so if this object depends on another object and that object | |
| * depends on two more, all three objects will be added. | |
| * | |
| * @param knownResourceObjects The set of resources to be ignored. | |
| * @param newResourceObjects The set to append dependant resources to. | |
| */ | |
| virtual void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, | |
| SkTSet<SkPDFObject*>* newResourceObjects); | |
| /** Emit this object unless the catalog has a substitute object, in which | |
| * case emit that. | |
| * @see emitObject | |
| */ | |
| void emit(SkWStream* stream, SkPDFCatalog* catalog, bool indirect); | |
| /** Helper function to output an indirect object. | |
| * @param catalog The object catalog to use. | |
| * @param stream The writable output stream to send the output to. | |
| */ | |
| void emitIndirectObject(SkWStream* stream, SkPDFCatalog* catalog); | |
| /** Helper function to find the size of an indirect object. | |
| * @param catalog The object catalog to use. | |
| */ | |
| size_t getIndirectOutputSize(SkPDFCatalog* catalog); | |
| /** Static helper function to add a resource to a list. The list takes | |
| * a reference. | |
| * @param resource The resource to add. | |
| * @param list The list to add the resource to. | |
| */ | |
| static void AddResourceHelper(SkPDFObject* resource, | |
| SkTDArray<SkPDFObject*>* list); | |
| /** Static helper function to copy and reference the resources (and all | |
| * their subresources) into a new list. | |
| * @param resources The resource list. | |
| * @param newResourceObjects All the resource objects (recursively) used on | |
| * the page are added to this array. This gives | |
| * the caller a chance to deduplicate resources | |
| * across pages. | |
| * @param knownResourceObjects The set of resources to be ignored. | |
| */ | |
| static void GetResourcesHelper( | |
| const SkTDArray<SkPDFObject*>* resources, | |
| const SkTSet<SkPDFObject*>& knownResourceObjects, | |
| SkTSet<SkPDFObject*>* newResourceObjects); | |
| protected: | |
| /** Subclasses must implement this method to print the object to the | |
| * PDF file. | |
| * @param catalog The object catalog to use. | |
| * @param indirect If true, output an object identifier with the object. | |
| * @param stream The writable output stream to send the output to. | |
| */ | |
| virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, | |
| bool indirect) = 0; | |
| typedef SkRefCnt INHERITED; | |
| }; | |
| /** \class SkPDFObjRef | |
| An indirect reference to a PDF object. | |
| */ | |
| class SkPDFObjRef : public SkPDFObject { | |
| public: | |
| SK_DECLARE_INST_COUNT(SkPDFObjRef) | |
| /** Create a reference to an existing SkPDFObject. | |
| * @param obj The object to reference. | |
| */ | |
| explicit SkPDFObjRef(SkPDFObject* obj); | |
| virtual ~SkPDFObjRef(); | |
| // The SkPDFObject interface. | |
| virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, | |
| bool indirect); | |
| virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); | |
| private: | |
| SkAutoTUnref<SkPDFObject> fObj; | |
| typedef SkPDFObject INHERITED; | |
| }; | |
| /** \class SkPDFInt | |
| An integer object in a PDF. | |
| */ | |
| class SkPDFInt : public SkPDFObject { | |
| public: | |
| SK_DECLARE_INST_COUNT(SkPDFInt) | |
| /** Create a PDF integer (usually for indirect reference purposes). | |
| * @param value An integer value between 2^31 - 1 and -2^31. | |
| */ | |
| explicit SkPDFInt(int32_t value); | |
| virtual ~SkPDFInt(); | |
| // The SkPDFObject interface. | |
| virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, | |
| bool indirect); | |
| private: | |
| int32_t fValue; | |
| typedef SkPDFObject INHERITED; | |
| }; | |
| /** \class SkPDFBool | |
| An boolean value in a PDF. | |
| */ | |
| class SkPDFBool : public SkPDFObject { | |
| public: | |
| SK_DECLARE_INST_COUNT(SkPDFBool) | |
| /** Create a PDF boolean. | |
| * @param value true or false. | |
| */ | |
| explicit SkPDFBool(bool value); | |
| virtual ~SkPDFBool(); | |
| // The SkPDFObject interface. | |
| virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, | |
| bool indirect); | |
| virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); | |
| private: | |
| bool fValue; | |
| typedef SkPDFObject INHERITED; | |
| }; | |
| /** \class SkPDFScalar | |
| A real number object in a PDF. | |
| */ | |
| class SkPDFScalar : public SkPDFObject { | |
| public: | |
| SK_DECLARE_INST_COUNT(SkPDFScalar) | |
| /** Create a PDF real number. | |
| * @param value A real value. | |
| */ | |
| explicit SkPDFScalar(SkScalar value); | |
| virtual ~SkPDFScalar(); | |
| static void Append(SkScalar value, SkWStream* stream); | |
| // The SkPDFObject interface. | |
| virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, | |
| bool indirect); | |
| private: | |
| SkScalar fValue; | |
| typedef SkPDFObject INHERITED; | |
| }; | |
| /** \class SkPDFString | |
| A string object in a PDF. | |
| */ | |
| class SkPDFString : public SkPDFObject { | |
| public: | |
| SK_DECLARE_INST_COUNT(SkPDFString) | |
| /** Create a PDF string. Maximum length (in bytes) is 65,535. | |
| * @param value A string value. | |
| */ | |
| explicit SkPDFString(const char value[]); | |
| explicit SkPDFString(const SkString& value); | |
| /** Create a PDF string. Maximum length (in bytes) is 65,535. | |
| * @param value A string value. | |
| * @param len The length of value. | |
| * @param wideChars Indicates if the top byte in value is significant and | |
| * should be encoded (true) or not (false). | |
| */ | |
| SkPDFString(const uint16_t* value, size_t len, bool wideChars); | |
| virtual ~SkPDFString(); | |
| // The SkPDFObject interface. | |
| virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, | |
| bool indirect); | |
| virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); | |
| static SkString FormatString(const char* input, size_t len); | |
| static SkString FormatString(const uint16_t* input, size_t len, | |
| bool wideChars); | |
| private: | |
| static const size_t kMaxLen = 65535; | |
| const SkString fValue; | |
| static SkString DoFormatString(const void* input, size_t len, | |
| bool wideInput, bool wideOutput); | |
| typedef SkPDFObject INHERITED; | |
| }; | |
| /** \class SkPDFName | |
| A name object in a PDF. | |
| */ | |
| class SkPDFName : public SkPDFObject { | |
| public: | |
| SK_DECLARE_INST_COUNT(SkPDFName) | |
| /** Create a PDF name object. Maximum length is 127 bytes. | |
| * @param value The name. | |
| */ | |
| explicit SkPDFName(const char name[]); | |
| explicit SkPDFName(const SkString& name); | |
| virtual ~SkPDFName(); | |
| bool operator==(const SkPDFName& b) const; | |
| // The SkPDFObject interface. | |
| virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, | |
| bool indirect); | |
| virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); | |
| private: | |
| static const size_t kMaxLen = 127; | |
| const SkString fValue; | |
| static SkString FormatName(const SkString& input); | |
| typedef SkPDFObject INHERITED; | |
| }; | |
| /** \class SkPDFArray | |
| An array object in a PDF. | |
| */ | |
| class SkPDFArray : public SkPDFObject { | |
| public: | |
| SK_DECLARE_INST_COUNT(SkPDFArray) | |
| /** Create a PDF array. Maximum length is 8191. | |
| */ | |
| SkPDFArray(); | |
| virtual ~SkPDFArray(); | |
| // The SkPDFObject interface. | |
| virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, | |
| bool indirect); | |
| virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); | |
| /** The size of the array. | |
| */ | |
| int size() { return fValue.count(); } | |
| /** Preallocate space for the given number of entries. | |
| * @param length The number of array slots to preallocate. | |
| */ | |
| void reserve(int length); | |
| /** Returns the object at the given offset in the array. | |
| * @param index The index into the array to retrieve. | |
| */ | |
| SkPDFObject* getAt(int index) { return fValue[index]; } | |
| /** Set the object at the given offset in the array. Ref's value. | |
| * @param index The index into the array to set. | |
| * @param value The value to add to the array. | |
| * @return The value argument is returned. | |
| */ | |
| SkPDFObject* setAt(int index, SkPDFObject* value); | |
| /** Append the object to the end of the array and increments its ref count. | |
| * @param value The value to add to the array. | |
| * @return The value argument is returned. | |
| */ | |
| SkPDFObject* append(SkPDFObject* value); | |
| /** Creates a SkPDFInt object and appends it to the array. | |
| * @param value The value to add to the array. | |
| */ | |
| void appendInt(int32_t value); | |
| /** Creates a SkPDFScalar object and appends it to the array. | |
| * @param value The value to add to the array. | |
| */ | |
| void appendScalar(SkScalar value); | |
| /** Creates a SkPDFName object and appends it to the array. | |
| * @param value The value to add to the array. | |
| */ | |
| void appendName(const char name[]); | |
| private: | |
| static const int kMaxLen = 8191; | |
| SkTDArray<SkPDFObject*> fValue; | |
| typedef SkPDFObject INHERITED; | |
| }; | |
| /** \class SkPDFDict | |
| A dictionary object in a PDF. | |
| */ | |
| class SkPDFDict : public SkPDFObject { | |
| public: | |
| SK_DECLARE_INST_COUNT(SkPDFDict) | |
| /** Create a PDF dictionary. Maximum number of entries is 4095. | |
| */ | |
| SkPDFDict(); | |
| /** Create a PDF dictionary with a Type entry. | |
| * @param type The value of the Type entry. | |
| */ | |
| explicit SkPDFDict(const char type[]); | |
| virtual ~SkPDFDict(); | |
| // The SkPDFObject interface. | |
| virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, | |
| bool indirect); | |
| virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); | |
| /** The size of the dictionary. | |
| */ | |
| int size() const; | |
| /** Add the value to the dictionary with the given key. Refs value. | |
| * @param key The key for this dictionary entry. | |
| * @param value The value for this dictionary entry. | |
| * @return The value argument is returned. | |
| */ | |
| SkPDFObject* insert(SkPDFName* key, SkPDFObject* value); | |
| /** Add the value to the dictionary with the given key. Refs value. The | |
| * method will create the SkPDFName object. | |
| * @param key The text of the key for this dictionary entry. | |
| * @param value The value for this dictionary entry. | |
| * @return The value argument is returned. | |
| */ | |
| SkPDFObject* insert(const char key[], SkPDFObject* value); | |
| /** Add the int to the dictionary with the given key. | |
| * @param key The text of the key for this dictionary entry. | |
| * @param value The int value for this dictionary entry. | |
| */ | |
| void insertInt(const char key[], int32_t value); | |
| /** | |
| * Calls insertInt() but asserts in debug builds that the value can be represented | |
| * by an int32_t. | |
| */ | |
| void insertInt(const char key[], size_t value) { | |
| this->insertInt(key, SkToS32(value)); | |
| } | |
| /** Add the scalar to the dictionary with the given key. | |
| * @param key The text of the key for this dictionary entry. | |
| * @param value The scalar value for this dictionary entry. | |
| */ | |
| void insertScalar(const char key[], SkScalar value); | |
| /** Add the name to the dictionary with the given key. | |
| * @param key The text of the key for this dictionary entry. | |
| * @param name The name for this dictionary entry. | |
| */ | |
| void insertName(const char key[], const char name[]); | |
| /** Add the name to the dictionary with the given key. | |
| * @param key The text of the key for this dictionary entry. | |
| * @param name The name for this dictionary entry. | |
| */ | |
| void insertName(const char key[], const SkString& name) { | |
| this->insertName(key, name.c_str()); | |
| } | |
| /** Remove all entries from the dictionary. | |
| */ | |
| void clear(); | |
| protected: | |
| /** Use to remove a single key from the dictionary. | |
| */ | |
| void remove(const char key[]); | |
| /** Insert references to all of the key-value pairs from the other | |
| * dictionary into this one. | |
| */ | |
| void mergeFrom(const SkPDFDict& other); | |
| private: | |
| struct Rec { | |
| SkPDFName* key; | |
| SkPDFObject* value; | |
| Rec(SkPDFName* k, SkPDFObject* v) : key(k), value(v) {} | |
| }; | |
| static const int kMaxLen = 4095; | |
| mutable SkMutex fMutex; // protects modifications to fValue | |
| SkTDArray<struct Rec> fValue; | |
| SkPDFObject* append(SkPDFName* key, SkPDFObject* value); | |
| typedef SkPDFObject INHERITED; | |
| }; | |
| #endif |