|  | 
 | /* | 
 |  * Copyright 2010 The Android Open Source Project | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 |  | 
 |  | 
 | #ifndef SkPDFCatalog_DEFINED | 
 | #define SkPDFCatalog_DEFINED | 
 |  | 
 | #include <sys/types.h> | 
 |  | 
 | #include "SkPDFDocument.h" | 
 | #include "SkPDFTypes.h" | 
 | #include "SkRefCnt.h" | 
 | #include "SkTDArray.h" | 
 |  | 
 | /** \class SkPDFCatalog | 
 |  | 
 |     The PDF catalog manages object numbers and file offsets.  It is used | 
 |     to create the PDF cross reference table. | 
 | */ | 
 | class SkPDFCatalog { | 
 | public: | 
 |     /** Create a PDF catalog. | 
 |      */ | 
 |     explicit SkPDFCatalog(SkPDFDocument::Flags flags); | 
 |     ~SkPDFCatalog(); | 
 |  | 
 |     /** Add the passed object to the catalog.  Refs obj. | 
 |      *  @param obj         The object to add. | 
 |      *  @param onFirstPage Is the object on the first page. | 
 |      *  @return The obj argument is returned. | 
 |      */ | 
 |     SkPDFObject* addObject(SkPDFObject* obj, bool onFirstPage); | 
 |  | 
 |     /** Inform the catalog of the object's position in the final stream. | 
 |      *  The object should already have been added to the catalog.  Returns | 
 |      *  the object's size. | 
 |      *  @param obj         The object to add. | 
 |      *  @param offset      The byte offset in the output stream of this object. | 
 |      */ | 
 |     size_t setFileOffset(SkPDFObject* obj, off_t offset); | 
 |  | 
 |     /** Output the object number for the passed object. | 
 |      *  @param obj         The object of interest. | 
 |      *  @param stream      The writable output stream to send the output to. | 
 |      */ | 
 |     void emitObjectNumber(SkWStream* stream, SkPDFObject* obj); | 
 |  | 
 |     /** Return the number of bytes that would be emitted for the passed | 
 |      *  object's object number. | 
 |      *  @param obj         The object of interest | 
 |      */ | 
 |     size_t getObjectNumberSize(SkPDFObject* obj); | 
 |  | 
 |     /** Return the document flags in effect for this catalog/document. | 
 |      */ | 
 |     SkPDFDocument::Flags getDocumentFlags() const { return fDocumentFlags; } | 
 |  | 
 |     /** Output the cross reference table for objects in the catalog. | 
 |      *  Returns the total number of objects. | 
 |      *  @param stream      The writable output stream to send the output to. | 
 |      *  @param firstPage   If true, include first page objects only, otherwise | 
 |      *                     include all objects not on the first page. | 
 |      */ | 
 |     int32_t emitXrefTable(SkWStream* stream, bool firstPage); | 
 |  | 
 |     /** Set substitute object for the passed object. | 
 |      */ | 
 |     void setSubstitute(SkPDFObject* original, SkPDFObject* substitute); | 
 |  | 
 |     /** Find and return any substitute object set for the passed object. If | 
 |      *  there is none, return the passed object. | 
 |      */ | 
 |     SkPDFObject* getSubstituteObject(SkPDFObject* object); | 
 |  | 
 |     /** Set file offsets for the resources of substitute objects. | 
 |      *  @param fileOffset Accumulated offset of current document. | 
 |      *  @param firstPage  Indicate whether this is for the first page only. | 
 |      *  @return           Total size of resources of substitute objects. | 
 |      */ | 
 |     off_t setSubstituteResourcesOffsets(off_t fileOffset, bool firstPage); | 
 |  | 
 |     /** Emit the resources of substitute objects. | 
 |      */ | 
 |     void emitSubstituteResources(SkWStream* stream, bool firstPage); | 
 |  | 
 | private: | 
 |     struct Rec { | 
 |         Rec(SkPDFObject* object, bool onFirstPage) | 
 |             : fObject(object), | 
 |               fFileOffset(0), | 
 |               fObjNumAssigned(false), | 
 |               fOnFirstPage(onFirstPage) { | 
 |         } | 
 |         SkPDFObject* fObject; | 
 |         off_t fFileOffset; | 
 |         bool fObjNumAssigned; | 
 |         bool fOnFirstPage; | 
 |     }; | 
 |  | 
 |     struct SubstituteMapping { | 
 |         SubstituteMapping(SkPDFObject* original, SkPDFObject* substitute) | 
 |             : fOriginal(original), fSubstitute(substitute) { | 
 |         } | 
 |         SkPDFObject* fOriginal; | 
 |         SkPDFObject* fSubstitute; | 
 |     }; | 
 |  | 
 |     // TODO(vandebo): Make this a hash if it's a performance problem. | 
 |     SkTDArray<struct Rec> fCatalog; | 
 |  | 
 |     // TODO(arthurhsu): Make this a hash if it's a performance problem. | 
 |     SkTDArray<SubstituteMapping> fSubstituteMap; | 
 |     SkTSet<SkPDFObject*> fSubstituteResourcesFirstPage; | 
 |     SkTSet<SkPDFObject*> fSubstituteResourcesRemaining; | 
 |  | 
 |     // Number of objects on the first page. | 
 |     uint32_t fFirstPageCount; | 
 |     // Next object number to assign (on page > 1). | 
 |     uint32_t fNextObjNum; | 
 |     // Next object number to assign on the first page. | 
 |     uint32_t fNextFirstPageObjNum; | 
 |  | 
 |     SkPDFDocument::Flags fDocumentFlags; | 
 |  | 
 |     int findObjectIndex(SkPDFObject* obj) const; | 
 |  | 
 |     int assignObjNum(SkPDFObject* obj); | 
 |  | 
 |     SkTSet<SkPDFObject*>* getSubstituteList(bool firstPage); | 
 | }; | 
 |  | 
 | #endif |