• 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 SkPDFCatalog_DEFINED
11 #define SkPDFCatalog_DEFINED
12 
13 #include <sys/types.h>
14 
15 #include "SkPDFDocument.h"
16 #include "SkPDFTypes.h"
17 #include "SkRefCnt.h"
18 #include "SkTDArray.h"
19 
20 /** \class SkPDFCatalog
21 
22     The PDF catalog manages object numbers and file offsets.  It is used
23     to create the PDF cross reference table.
24 */
25 class SkPDFCatalog {
26 public:
27     /** Create a PDF catalog.
28      */
29     explicit SkPDFCatalog(SkPDFDocument::Flags flags);
30     ~SkPDFCatalog();
31 
32     /** Add the passed object to the catalog.  Refs obj.
33      *  @param obj         The object to add.
34      *  @param onFirstPage Is the object on the first page.
35      *  @return The obj argument is returned.
36      */
37     SkPDFObject* addObject(SkPDFObject* obj, bool onFirstPage);
38 
39     /** 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      */
45     size_t setFileOffset(SkPDFObject* obj, off_t offset);
46 
47     /** Output the object number for the passed object.
48      *  @param obj         The object of interest.
49      *  @param stream      The writable output stream to send the output to.
50      */
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.
55      *  @param obj         The object of interest
56      */
57     size_t getObjectNumberSize(SkPDFObject* obj);
58 
59     /** Return the document flags in effect for this catalog/document.
60      */
getDocumentFlags()61     SkPDFDocument::Flags getDocumentFlags() const { return fDocumentFlags; }
62 
63     /** 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 
71     /** 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.
83      *  @return           Total size of resources of substitute objects.
84      */
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 
91 private:
92     struct Rec {
RecRec93         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 
105     struct SubstituteMapping {
SubstituteMappingSubstituteMapping106         SubstituteMapping(SkPDFObject* original, SkPDFObject* substitute)
107             : fOriginal(original), fSubstitute(substitute) {
108         }
109         SkPDFObject* fOriginal;
110         SkPDFObject* fSubstitute;
111     };
112 
113     // TODO(vandebo): Make this a hash if it's a performance problem.
114     SkTDArray<struct Rec> fCatalog;
115 
116     // TODO(arthurhsu): Make this a hash if it's a performance problem.
117     SkTDArray<SubstituteMapping> fSubstituteMap;
118     SkTSet<SkPDFObject*> fSubstituteResourcesFirstPage;
119     SkTSet<SkPDFObject*> fSubstituteResourcesRemaining;
120 
121     // Number of objects on the first page.
122     uint32_t fFirstPageCount;
123     // Next object number to assign (on page > 1).
124     uint32_t fNextObjNum;
125     // Next object number to assign on the first page.
126     uint32_t fNextFirstPageObjNum;
127 
128     SkPDFDocument::Flags fDocumentFlags;
129 
130     int findObjectIndex(SkPDFObject* obj) const;
131 
132     int assignObjNum(SkPDFObject* obj);
133 
134     SkTSet<SkPDFObject*>* getSubstituteList(bool firstPage);
135 };
136 
137 #endif
138