blob: 5c5edd6d580d5e1d125bc959e001a6b1eb96e063 [file] [log] [blame]
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +00001/*
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"
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000024#include "SkTypes.h"
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000025
26class SkPDFCatalog;
27class 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*/
35class SkPDFObject : public SkRefCnt {
36public:
37 /** Create a PDF object.
38 */
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +000039 SkPDFObject();
40 virtual ~SkPDFObject();
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000041
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000042 /** Return the size (number of bytes) of this object in the final output
43 * file. Compound objects or objects that are computationally intensive
44 * to output should override this method.
45 * @param catalog The object catalog to use.
46 * @param indirect If true, output an object identifier with the object.
47 */
48 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
49
vandebo@chromium.orga5180862010-10-26 19:48:49 +000050 /** If this object explicitly depends on other objects, add them to the
51 * end of the list. This only applies to higher level object, where
52 * the depenency is explicit and introduced by the class. i.e. an
53 * SkPDFImage added to an SkPDFDevice, but not an SkPDFObjRef added to
54 * an SkPDFArray.
55 * @param resourceList The list to append dependant resources to.
56 */
57 virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
58
vandebo@chromium.org2ef12d42011-07-06 23:31:24 +000059 /** Emit this object unless the catalog has a substitute object, in which
60 * case emit that.
61 * @see emitObject
62 */
63 void emit(SkWStream* stream, SkPDFCatalog* catalog, bool indirect);
64
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000065 /** Helper function to output an indirect object.
66 * @param catalog The object catalog to use.
67 * @param stream The writable output stream to send the output to.
68 */
69 void emitIndirectObject(SkWStream* stream, SkPDFCatalog* catalog);
70
71 /** Helper function to find the size of an indirect object.
72 * @param catalog The object catalog to use.
73 */
74 size_t getIndirectOutputSize(SkPDFCatalog* catalog);
vandebo@chromium.org2ef12d42011-07-06 23:31:24 +000075
76protected:
77 /** Subclasses must implement this method to print the object to the
78 * PDF file.
79 * @param catalog The object catalog to use.
80 * @param indirect If true, output an object identifier with the object.
81 * @param stream The writable output stream to send the output to.
82 */
83 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
84 bool indirect) = 0;
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000085};
86
87/** \class SkPDFObjRef
88
89 An indirect reference to a PDF object.
90*/
91class SkPDFObjRef : public SkPDFObject {
92public:
93 /** Create a reference to an existing SkPDFObject.
94 * @param obj The object to reference.
95 */
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +000096 explicit SkPDFObjRef(SkPDFObject* obj);
97 virtual ~SkPDFObjRef();
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000098
99 // The SkPDFObject interface.
100 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
101 bool indirect);
102 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
103
104private:
105 SkRefPtr<SkPDFObject> fObj;
106};
107
108/** \class SkPDFInt
109
110 An integer object in a PDF.
111*/
112class SkPDFInt : public SkPDFObject {
113public:
114 /** Create a PDF integer (usually for indirect reference purposes).
115 * @param value An integer value between 2^31 - 1 and -2^31.
116 */
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +0000117 explicit SkPDFInt(int32_t value);
118 virtual ~SkPDFInt();
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000119
120 // The SkPDFObject interface.
121 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
122 bool indirect);
123
124private:
125 int32_t fValue;
126};
127
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +0000128/** \class SkPDFBool
129
130 An boolean value in a PDF.
131*/
132class SkPDFBool : public SkPDFObject {
133public:
134 /** Create a PDF boolean.
135 * @param value true or false.
136 */
137 explicit SkPDFBool(bool value);
138 virtual ~SkPDFBool();
139
140 // The SkPDFObject interface.
141 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
142 bool indirect);
143 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
144
145private:
146 bool fValue;
147};
148
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000149/** \class SkPDFScalar
150
151 A real number object in a PDF.
152*/
153class SkPDFScalar : public SkPDFObject {
154public:
155 /** Create a PDF real number.
156 * @param value A real value.
157 */
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +0000158 explicit SkPDFScalar(SkScalar value);
159 virtual ~SkPDFScalar();
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000160
vandebo@chromium.orgcae5fba2011-03-28 19:03:50 +0000161 static void Append(SkScalar value, SkWStream* stream);
vandebo@chromium.org094316b2011-03-04 03:15:13 +0000162
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000163 // The SkPDFObject interface.
164 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
165 bool indirect);
166
167private:
168 SkScalar fValue;
169};
170
171/** \class SkPDFString
172
173 A string object in a PDF.
174*/
175class SkPDFString : public SkPDFObject {
176public:
177 /** Create a PDF string. Maximum length (in bytes) is 65,535.
178 * @param value A string value.
179 */
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +0000180 explicit SkPDFString(const char value[]);
181 explicit SkPDFString(const SkString& value);
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000182
183 /** Create a PDF string. Maximum length (in bytes) is 65,535.
184 * @param value A string value.
185 * @param len The length of value.
186 * @param wideChars Indicates if the top byte in value is significant and
187 * should be encoded (true) or not (false).
188 */
189 SkPDFString(const uint16_t* value, size_t len, bool wideChars);
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +0000190 virtual ~SkPDFString();
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000191
192 // The SkPDFObject interface.
193 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
194 bool indirect);
195 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
196
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000197 static SkString formatString(const char* input, size_t len);
198 static SkString formatString(const uint16_t* input, size_t len,
199 bool wideChars);
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000200private:
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +0000201 static const size_t kMaxLen = 65535;
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000202
203 const SkString fValue;
204
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000205 static SkString doFormatString(const void* input, size_t len,
206 bool wideInput, bool wideOutput);
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000207};
208
209/** \class SkPDFName
210
211 A name object in a PDF.
212*/
213class SkPDFName : public SkPDFObject {
214public:
215 /** Create a PDF name object. Maximum length is 127 bytes.
216 * @param value The name.
217 */
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +0000218 explicit SkPDFName(const char name[]);
219 explicit SkPDFName(const SkString& name);
220 virtual ~SkPDFName();
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000221
222 // The SkPDFObject interface.
223 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
224 bool indirect);
225 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
226
227private:
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +0000228 static const size_t kMaxLen = 127;
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000229
230 const SkString fValue;
231
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +0000232 static SkString formatName(const SkString& input);
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000233};
234
235/** \class SkPDFArray
236
237 An array object in a PDF.
238*/
239class SkPDFArray : public SkPDFObject {
240public:
241 /** Create a PDF array. Maximum length is 8191.
242 */
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +0000243 SkPDFArray();
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000244 virtual ~SkPDFArray();
245
246 // The SkPDFObject interface.
247 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
248 bool indirect);
249 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
250
251 /** The size of the array.
252 */
253 int size() { return fValue.count(); }
254
255 /** Preallocate space for the given number of entries.
256 * @param length The number of array slots to preallocate.
257 */
258 void reserve(int length);
259
260 /** Returns the object at the given offset in the array.
261 * @param index The index into the array to retrieve.
262 */
263 SkPDFObject* getAt(int index) { return fValue[index]; }
264
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000265 /** Set the object at the given offset in the array. Ref's value.
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000266 * @param index The index into the array to set.
267 * @param value The value to add to the array.
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000268 * @return The value argument is returned.
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000269 */
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000270 SkPDFObject* setAt(int index, SkPDFObject* value);
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000271
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000272 /** Append the object to the end of the array and increments its ref count.
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000273 * @param value The value to add to the array.
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000274 * @return The value argument is returned.
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000275 */
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000276 SkPDFObject* append(SkPDFObject* value);
reed@google.comc789cf12011-07-20 12:14:33 +0000277
278 /** Creates a SkPDFInt object and appends it to the array.
279 * @param value The value to add to the array.
280 */
281 void appendInt(int32_t value);
282
283 /** Creates a SkPDFScalar object and appends it to the array.
284 * @param value The value to add to the array.
285 */
286 void appendScalar(SkScalar value);
287
288 /** Creates a SkPDFName object and appends it to the array.
289 * @param value The value to add to the array.
290 */
291 void appendName(const char name[]);
292
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000293private:
294 static const int kMaxLen = 8191;
295 SkTDArray<SkPDFObject*> fValue;
296};
297
298/** \class SkPDFDict
299
300 A dictionary object in a PDF.
301*/
302class SkPDFDict : public SkPDFObject {
303public:
304 /** Create a PDF dictionary. Maximum number of entries is 4095.
305 */
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +0000306 SkPDFDict();
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +0000307
308 /** Create a PDF dictionary with a Type entry.
309 * @param type The value of the Type entry.
310 */
311 explicit SkPDFDict(const char type[]);
312
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000313 virtual ~SkPDFDict();
314
315 // The SkPDFObject interface.
316 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
317 bool indirect);
318 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
319
320 /** The size of the dictionary.
321 */
322 int size() { return fValue.count(); }
323
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000324 /** Add the value to the dictionary with the given key. Refs value.
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000325 * @param key The key for this dictionary entry.
326 * @param value The value for this dictionary entry.
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000327 * @return The value argument is returned.
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000328 */
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000329 SkPDFObject* insert(SkPDFName* key, SkPDFObject* value);
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000330
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000331 /** Add the value to the dictionary with the given key. Refs value. The
332 * method will create the SkPDFName object.
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +0000333 * @param key The text of the key for this dictionary entry.
334 * @param value The value for this dictionary entry.
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000335 * @return The value argument is returned.
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +0000336 */
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +0000337 SkPDFObject* insert(const char key[], SkPDFObject* value);
reed@google.comc789cf12011-07-20 12:14:33 +0000338
339 /** Add the int to the dictionary with the given key.
340 * @param key The text of the key for this dictionary entry.
341 * @param value The int value for this dictionary entry.
342 */
343 void insertInt(const char key[], int32_t value);
344
345 /** Add the scalar to the dictionary with the given key.
346 * @param key The text of the key for this dictionary entry.
347 * @param value The scalar value for this dictionary entry.
348 */
349 void insertScalar(const char key[], SkScalar value);
350
351 /** Add the name to the dictionary with the given key.
352 * @param key The text of the key for this dictionary entry.
353 * @param name The name for this dictionary entry.
354 */
355 void insertName(const char key[], const char name[]);
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +0000356
reed@google.comc789cf12011-07-20 12:14:33 +0000357 /** Add the name to the dictionary with the given key.
358 * @param key The text of the key for this dictionary entry.
359 * @param name The name for this dictionary entry.
360 */
361 void insertName(const char key[], const SkString& name) {
362 this->insertName(key, name.c_str());
363 }
364
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +0000365 /** Remove all entries from the dictionary.
366 */
367 void clear();
368
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000369private:
370 static const int kMaxLen = 4095;
371
372 struct Rec {
373 SkPDFName* key;
374 SkPDFObject* value;
375 };
376
377 SkTDArray<struct Rec> fValue;
378};
379
380#endif