• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
size()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      */
getAt(int index)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      */
size()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      */
insertName(const char key[],const SkString & name)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