blob: d5825ace5ae602ec99b276e726624e1797de82e6 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2010 The Android Open Source Project
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000010#ifndef SkPDFCatalog_DEFINED
11#define SkPDFCatalog_DEFINED
12
vandebo@chromium.org8af0b362011-01-26 21:59:00 +000013#include <sys/types.h>
14
vandebo@chromium.org421d6442011-07-20 17:39:01 +000015#include "SkPDFDocument.h"
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000016#include "SkPDFTypes.h"
17#include "SkRefCnt.h"
18#include "SkTDArray.h"
19
20/** \class SkPDFCatalog
21
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +000022 The PDF catalog manages object numbers and file offsets. It is used
23 to create the PDF cross reference table.
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000024*/
vandebo@chromium.org7d6c8f92012-03-22 20:45:15 +000025class SkPDFCatalog {
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000026public:
27 /** Create a PDF catalog.
28 */
vandebo@chromium.org421d6442011-07-20 17:39:01 +000029 explicit SkPDFCatalog(SkPDFDocument::Flags flags);
vandebo@chromium.orgf66025d2010-10-01 23:26:55 +000030 ~SkPDFCatalog();
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000031
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +000032 /** Add the passed object to the catalog. Refs obj.
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +000033 * @param obj The object to add.
34 * @param onFirstPage Is the object on the first page.
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +000035 * @return The obj argument is returned.
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000036 */
vandebo@chromium.orgf7c15762011-02-01 22:19:44 +000037 SkPDFObject* addObject(SkPDFObject* obj, bool onFirstPage);
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000038
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +000039 /** Inform the catalog of the object's position in the final stream.
40 * The object should already have been added to the catalog. Returns
41 * the object's size.
42 * @param obj The object to add.
43 * @param offset The byte offset in the output stream of this object.
44 */
vandebo@chromium.org30580f62012-07-12 20:22:04 +000045 size_t setFileOffset(SkPDFObject* obj, off_t offset);
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +000046
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000047 /** Output the object number for the passed object.
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +000048 * @param obj The object of interest.
49 * @param stream The writable output stream to send the output to.
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000050 */
51 void emitObjectNumber(SkWStream* stream, SkPDFObject* obj);
52
53 /** Return the number of bytes that would be emitted for the passed
54 * object's object number.
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +000055 * @param obj The object of interest
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000056 */
57 size_t getObjectNumberSize(SkPDFObject* obj);
58
vandebo@chromium.org421d6442011-07-20 17:39:01 +000059 /** Return the document flags in effect for this catalog/document.
60 */
61 SkPDFDocument::Flags getDocumentFlags() const { return fDocumentFlags; }
62
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +000063 /** Output the cross reference table for objects in the catalog.
64 * Returns the total number of objects.
65 * @param stream The writable output stream to send the output to.
66 * @param firstPage If true, include first page objects only, otherwise
67 * include all objects not on the first page.
68 */
69 int32_t emitXrefTable(SkWStream* stream, bool firstPage);
70
vandebo@chromium.org2ef12d42011-07-06 23:31:24 +000071 /** Set substitute object for the passed object.
72 */
73 void setSubstitute(SkPDFObject* original, SkPDFObject* substitute);
74
75 /** Find and return any substitute object set for the passed object. If
76 * there is none, return the passed object.
77 */
78 SkPDFObject* getSubstituteObject(SkPDFObject* object);
79
80 /** Set file offsets for the resources of substitute objects.
81 * @param fileOffset Accumulated offset of current document.
82 * @param firstPage Indicate whether this is for the first page only.
vandebo@chromium.orgf5181a42011-07-20 00:33:53 +000083 * @return Total size of resources of substitute objects.
vandebo@chromium.org2ef12d42011-07-06 23:31:24 +000084 */
85 off_t setSubstituteResourcesOffsets(off_t fileOffset, bool firstPage);
86
87 /** Emit the resources of substitute objects.
88 */
89 void emitSubstituteResources(SkWStream* stream, bool firstPage);
90
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000091private:
92 struct Rec {
93 Rec(SkPDFObject* object, bool onFirstPage)
94 : fObject(object),
95 fFileOffset(0),
96 fObjNumAssigned(false),
97 fOnFirstPage(onFirstPage) {
98 }
99 SkPDFObject* fObject;
100 off_t fFileOffset;
101 bool fObjNumAssigned;
102 bool fOnFirstPage;
103 };
104
vandebo@chromium.org2ef12d42011-07-06 23:31:24 +0000105 struct SubstituteMapping {
106 SubstituteMapping(SkPDFObject* original, SkPDFObject* substitute)
107 : fOriginal(original), fSubstitute(substitute) {
108 }
109 SkPDFObject* fOriginal;
110 SkPDFObject* fSubstitute;
111 };
112
ctguil@chromium.org769fa6a2011-08-20 00:36:18 +0000113 // TODO(vandebo): Make this a hash if it's a performance problem.
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000114 SkTDArray<struct Rec> fCatalog;
115
ctguil@chromium.org769fa6a2011-08-20 00:36:18 +0000116 // TODO(arthurhsu): Make this a hash if it's a performance problem.
vandebo@chromium.org2ef12d42011-07-06 23:31:24 +0000117 SkTDArray<SubstituteMapping> fSubstituteMap;
118 SkTDArray<SkPDFObject*> fSubstituteResourcesFirstPage;
119 SkTDArray<SkPDFObject*> fSubstituteResourcesRemaining;
120
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +0000121 // Number of objects on the first page.
122 uint32_t fFirstPageCount;
123 // Next object number to assign (on page > 1).
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000124 uint32_t fNextObjNum;
vandebo@chromium.orgd877fdb2010-10-12 23:08:13 +0000125 // Next object number to assign on the first page.
126 uint32_t fNextFirstPageObjNum;
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000127
vandebo@chromium.org421d6442011-07-20 17:39:01 +0000128 SkPDFDocument::Flags fDocumentFlags;
129
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000130 int findObjectIndex(SkPDFObject* obj) const;
131
132 int assignObjNum(SkPDFObject* obj);
vandebo@chromium.org2ef12d42011-07-06 23:31:24 +0000133
134 SkTDArray<SkPDFObject*>* getSubstituteList(bool firstPage);
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000135};
136
137#endif