180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2010 The Android Open Source Project 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SkPDFCatalog_DEFINED 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkPDFCatalog_DEFINED 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <sys/types.h> 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPDFDocument.h" 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPDFTypes.h" 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkRefCnt.h" 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTDArray.h" 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** \class SkPDFCatalog 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru The PDF catalog manages object numbers and file offsets. It is used 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru to create the PDF cross reference table. 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/ 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkPDFCatalog { 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Create a PDF catalog. 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru explicit SkPDFCatalog(SkPDFDocument::Flags flags); 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ~SkPDFCatalog(); 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Add the passed object to the catalog. Refs obj. 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param obj The object to add. 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param onFirstPage Is the object on the first page. 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @return The obj argument is returned. 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFObject* addObject(SkPDFObject* obj, bool onFirstPage); 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Inform the catalog of the object's position in the final stream. 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * The object should already have been added to the catalog. Returns 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * the object's size. 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param obj The object to add. 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param offset The byte offset in the output stream of this object. 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t setFileOffset(SkPDFObject* obj, off_t offset); 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Output the object number for the passed object. 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param obj The object of interest. 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param stream The writable output stream to send the output to. 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void emitObjectNumber(SkWStream* stream, SkPDFObject* obj); 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Return the number of bytes that would be emitted for the passed 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * object's object number. 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param obj The object of interest 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t getObjectNumberSize(SkPDFObject* obj); 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Return the document flags in effect for this catalog/document. 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFDocument::Flags getDocumentFlags() const { return fDocumentFlags; } 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Output the cross reference table for objects in the catalog. 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Returns the total number of objects. 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param stream The writable output stream to send the output to. 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param firstPage If true, include first page objects only, otherwise 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * include all objects not on the first page. 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int32_t emitXrefTable(SkWStream* stream, bool firstPage); 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Set substitute object for the passed object. 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setSubstitute(SkPDFObject* original, SkPDFObject* substitute); 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Find and return any substitute object set for the passed object. If 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * there is none, return the passed object. 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFObject* getSubstituteObject(SkPDFObject* object); 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Set file offsets for the resources of substitute objects. 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param fileOffset Accumulated offset of current document. 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param firstPage Indicate whether this is for the first page only. 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @return Total size of resources of substitute objects. 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru off_t setSubstituteResourcesOffsets(off_t fileOffset, bool firstPage); 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Emit the resources of substitute objects. 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void emitSubstituteResources(SkWStream* stream, bool firstPage); 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct Rec { 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Rec(SkPDFObject* object, bool onFirstPage) 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : fObject(object), 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFileOffset(0), 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fObjNumAssigned(false), 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fOnFirstPage(onFirstPage) { 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFObject* fObject; 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru off_t fFileOffset; 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool fObjNumAssigned; 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool fOnFirstPage; 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct SubstituteMapping { 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SubstituteMapping(SkPDFObject* original, SkPDFObject* substitute) 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : fOriginal(original), fSubstitute(substitute) { 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFObject* fOriginal; 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFObject* fSubstitute; 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO(vandebo): Make this a hash if it's a performance problem. 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTDArray<struct Rec> fCatalog; 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO(arthurhsu): Make this a hash if it's a performance problem. 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTDArray<SubstituteMapping> fSubstituteMap; 1187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkTSet<SkPDFObject*> fSubstituteResourcesFirstPage; 1197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkTSet<SkPDFObject*> fSubstituteResourcesRemaining; 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Number of objects on the first page. 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t fFirstPageCount; 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Next object number to assign (on page > 1). 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t fNextObjNum; 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Next object number to assign on the first page. 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t fNextFirstPageObjNum; 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFDocument::Flags fDocumentFlags; 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int findObjectIndex(SkPDFObject* obj) const; 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int assignObjNum(SkPDFObject* obj); 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkTSet<SkPDFObject*>* getSubstituteList(bool firstPage); 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 138