• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
size()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      */
getAt(int index)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      */
size()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