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