epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 1 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 2 | /* |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 3 | * Copyright 2010 The Android Open Source Project |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 4 | * |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 5 | * Use of this source code is governed by a BSD-style license that can be |
| 6 | * found in the LICENSE file. |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 7 | */ |
| 8 | |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 9 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 10 | #ifndef SkPDFCatalog_DEFINED |
| 11 | #define SkPDFCatalog_DEFINED |
| 12 | |
vandebo@chromium.org | 8af0b36 | 2011-01-26 21:59:00 +0000 | [diff] [blame] | 13 | #include <sys/types.h> |
| 14 | |
vandebo@chromium.org | 421d644 | 2011-07-20 17:39:01 +0000 | [diff] [blame] | 15 | #include "SkPDFDocument.h" |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 16 | #include "SkPDFTypes.h" |
| 17 | #include "SkRefCnt.h" |
| 18 | #include "SkTDArray.h" |
| 19 | |
| 20 | /** \class SkPDFCatalog |
| 21 | |
vandebo@chromium.org | f66025d | 2010-10-01 23:26:55 +0000 | [diff] [blame] | 22 | The PDF catalog manages object numbers and file offsets. It is used |
| 23 | to create the PDF cross reference table. |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 24 | */ |
vandebo@chromium.org | 7d6c8f9 | 2012-03-22 20:45:15 +0000 | [diff] [blame] | 25 | class SkPDFCatalog { |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 26 | public: |
| 27 | /** Create a PDF catalog. |
| 28 | */ |
vandebo@chromium.org | 421d644 | 2011-07-20 17:39:01 +0000 | [diff] [blame] | 29 | explicit SkPDFCatalog(SkPDFDocument::Flags flags); |
vandebo@chromium.org | f66025d | 2010-10-01 23:26:55 +0000 | [diff] [blame] | 30 | ~SkPDFCatalog(); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 31 | |
vandebo@chromium.org | f7c1576 | 2011-02-01 22:19:44 +0000 | [diff] [blame] | 32 | /** Add the passed object to the catalog. Refs obj. |
vandebo@chromium.org | d877fdb | 2010-10-12 23:08:13 +0000 | [diff] [blame] | 33 | * @param obj The object to add. |
| 34 | * @param onFirstPage Is the object on the first page. |
vandebo@chromium.org | f7c1576 | 2011-02-01 22:19:44 +0000 | [diff] [blame] | 35 | * @return The obj argument is returned. |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 36 | */ |
vandebo@chromium.org | f7c1576 | 2011-02-01 22:19:44 +0000 | [diff] [blame] | 37 | SkPDFObject* addObject(SkPDFObject* obj, bool onFirstPage); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 38 | |
vandebo@chromium.org | d877fdb | 2010-10-12 23:08:13 +0000 | [diff] [blame] | 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 | */ |
vandebo@chromium.org | 30580f6 | 2012-07-12 20:22:04 +0000 | [diff] [blame] | 45 | size_t setFileOffset(SkPDFObject* obj, off_t offset); |
vandebo@chromium.org | d877fdb | 2010-10-12 23:08:13 +0000 | [diff] [blame] | 46 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 47 | /** Output the object number for the passed object. |
vandebo@chromium.org | d877fdb | 2010-10-12 23:08:13 +0000 | [diff] [blame] | 48 | * @param obj The object of interest. |
| 49 | * @param stream The writable output stream to send the output to. |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 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. |
vandebo@chromium.org | d877fdb | 2010-10-12 23:08:13 +0000 | [diff] [blame] | 55 | * @param obj The object of interest |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 56 | */ |
| 57 | size_t getObjectNumberSize(SkPDFObject* obj); |
| 58 | |
vandebo@chromium.org | 421d644 | 2011-07-20 17:39:01 +0000 | [diff] [blame] | 59 | /** Return the document flags in effect for this catalog/document. |
| 60 | */ |
| 61 | SkPDFDocument::Flags getDocumentFlags() const { return fDocumentFlags; } |
| 62 | |
vandebo@chromium.org | d877fdb | 2010-10-12 23:08:13 +0000 | [diff] [blame] | 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 | |
vandebo@chromium.org | 2ef12d4 | 2011-07-06 23:31:24 +0000 | [diff] [blame] | 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. |
vandebo@chromium.org | f5181a4 | 2011-07-20 00:33:53 +0000 | [diff] [blame] | 83 | * @return Total size of resources of substitute objects. |
vandebo@chromium.org | 2ef12d4 | 2011-07-06 23:31:24 +0000 | [diff] [blame] | 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 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 91 | private: |
| 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.org | 2ef12d4 | 2011-07-06 23:31:24 +0000 | [diff] [blame] | 105 | struct SubstituteMapping { |
| 106 | SubstituteMapping(SkPDFObject* original, SkPDFObject* substitute) |
| 107 | : fOriginal(original), fSubstitute(substitute) { |
| 108 | } |
| 109 | SkPDFObject* fOriginal; |
| 110 | SkPDFObject* fSubstitute; |
| 111 | }; |
| 112 | |
ctguil@chromium.org | 769fa6a | 2011-08-20 00:36:18 +0000 | [diff] [blame] | 113 | // TODO(vandebo): Make this a hash if it's a performance problem. |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 114 | SkTDArray<struct Rec> fCatalog; |
| 115 | |
ctguil@chromium.org | 769fa6a | 2011-08-20 00:36:18 +0000 | [diff] [blame] | 116 | // TODO(arthurhsu): Make this a hash if it's a performance problem. |
vandebo@chromium.org | 2ef12d4 | 2011-07-06 23:31:24 +0000 | [diff] [blame] | 117 | SkTDArray<SubstituteMapping> fSubstituteMap; |
| 118 | SkTDArray<SkPDFObject*> fSubstituteResourcesFirstPage; |
| 119 | SkTDArray<SkPDFObject*> fSubstituteResourcesRemaining; |
| 120 | |
vandebo@chromium.org | d877fdb | 2010-10-12 23:08:13 +0000 | [diff] [blame] | 121 | // Number of objects on the first page. |
| 122 | uint32_t fFirstPageCount; |
| 123 | // Next object number to assign (on page > 1). |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 124 | uint32_t fNextObjNum; |
vandebo@chromium.org | d877fdb | 2010-10-12 23:08:13 +0000 | [diff] [blame] | 125 | // Next object number to assign on the first page. |
| 126 | uint32_t fNextFirstPageObjNum; |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 127 | |
vandebo@chromium.org | 421d644 | 2011-07-20 17:39:01 +0000 | [diff] [blame] | 128 | SkPDFDocument::Flags fDocumentFlags; |
| 129 | |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 130 | int findObjectIndex(SkPDFObject* obj) const; |
| 131 | |
| 132 | int assignObjNum(SkPDFObject* obj); |
vandebo@chromium.org | 2ef12d4 | 2011-07-06 23:31:24 +0000 | [diff] [blame] | 133 | |
| 134 | SkTDArray<SkPDFObject*>* getSubstituteList(bool firstPage); |
vandebo@chromium.org | 8459d4e | 2010-09-24 22:25:30 +0000 | [diff] [blame] | 135 | }; |
| 136 | |
| 137 | #endif |