aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorGravatar vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2010-10-12 23:08:13 +0000
committerGravatar vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2010-10-12 23:08:13 +0000
commitd877fdbb6e64692285c3e6532d88b9458f65b3cd (patch)
treec346892a4d2d014c95acc6729174c779d0bfcd02 /include
parentf66025d59ab4c8c4439fabf6ad89ddf35a19d1fd (diff)
High level pdf classes and pdf specific interface.
The guts of the implementation will be in SkPDFDevice and below. This is a first implementation of everything above that point. Review URL: http://codereview.appspot.com/2342043 git-svn-id: http://skia.googlecode.com/svn/trunk@602 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include')
-rw-r--r--include/core/SkStream.h2
-rw-r--r--include/core/SkString.h6
-rw-r--r--include/pdf/SkPDFCatalog.h33
-rw-r--r--include/pdf/SkPDFDocument.h80
-rw-r--r--include/pdf/SkPDFPage.h98
-rw-r--r--include/pdf/SkPDFStream.h10
-rw-r--r--include/pdf/SkPDFTypes.h21
7 files changed, 237 insertions, 13 deletions
diff --git a/include/core/SkStream.h b/include/core/SkStream.h
index 3a82991eba..487c7d68c4 100644
--- a/include/core/SkStream.h
+++ b/include/core/SkStream.h
@@ -91,6 +91,7 @@ public:
bool writeText(const char text[]);
bool writeDecAsText(int32_t);
+ bool writeBigDecAsText(int64_t, int minDigits = 0);
bool writeHexAsText(uint32_t, int minDigits = 0);
bool writeScalarAsText(SkScalar);
@@ -308,4 +309,3 @@ public:
typedef SkFILEStream SkURLStream;
#endif
-
diff --git a/include/core/SkString.h b/include/core/SkString.h
index 5ecfb1e108..4498bba768 100644
--- a/include/core/SkString.h
+++ b/include/core/SkString.h
@@ -28,6 +28,8 @@ int SkStrStartsWithOneOf(const char string[], const char prefixes[]);
#define SkStrAppendS32_MaxSize 11
char* SkStrAppendS32(char buffer[], int32_t);
+#define SkStrAppendS64_MaxSize 20
+char* SkStrAppendS64(char buffer[], int64_t, int minDigits);
#define SkStrAppendScalar_MaxSize 11
char* SkStrAppendScalar(char buffer[], SkScalar);
@@ -93,6 +95,7 @@ public:
void insert(size_t offset, const char text[], size_t len);
void insertUnichar(size_t offset, SkUnichar);
void insertS32(size_t offset, int32_t value);
+ void insertS64(size_t offset, int64_t value, int minDigits = 0);
void insertHex(size_t offset, uint32_t value, int minDigits = 0);
void insertScalar(size_t offset, SkScalar);
@@ -101,6 +104,7 @@ public:
void append(const char text[], size_t len) { this->insert((size_t)-1, text, len); }
void appendUnichar(SkUnichar uni) { this->insertUnichar((size_t)-1, uni); }
void appendS32(int32_t value) { this->insertS32((size_t)-1, value); }
+ void appendS64(int64_t value, int minDigits = 0) { this->insertS64((size_t)-1, value, minDigits); }
void appendHex(uint32_t value, int minDigits = 0) { this->insertHex((size_t)-1, value, minDigits); }
void appendScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
@@ -109,6 +113,7 @@ public:
void prepend(const char text[], size_t len) { this->insert(0, text, len); }
void prependUnichar(SkUnichar uni) { this->insertUnichar(0, uni); }
void prependS32(int32_t value) { this->insertS32(0, value); }
+ void prependS64(int32_t value, int minDigits = 0) { this->insertS64(0, value, minDigits); }
void prependHex(uint32_t value, int minDigits = 0) { this->insertHex(0, value, minDigits); }
void prependScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
@@ -165,4 +170,3 @@ private:
};
#endif
-
diff --git a/include/pdf/SkPDFCatalog.h b/include/pdf/SkPDFCatalog.h
index 932f1c895b..6e530db33b 100644
--- a/include/pdf/SkPDFCatalog.h
+++ b/include/pdf/SkPDFCatalog.h
@@ -34,23 +34,39 @@ public:
~SkPDFCatalog();
/** Add the passed object to the catalog.
- * @param obj The object to add.
- * @param onFirstPage Is the object on the first page.
+ * @param obj The object to add.
+ * @param onFirstPage Is the object on the first page.
*/
void 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, size_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.
+ * @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
+ * @param obj The object of interest
*/
size_t getObjectNumberSize(SkPDFObject* obj);
+ /** 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);
+
private:
struct Rec {
Rec(SkPDFObject* object, bool onFirstPage)
@@ -68,9 +84,12 @@ private:
// TODO(vandebo) Make this a hash if it's a performance problem.
SkTDArray<struct Rec> fCatalog;
+ // Number of objects on the first page.
+ uint32_t fFirstPageCount;
+ // Next object number to assign (on page > 1).
uint32_t fNextObjNum;
- bool fStartedAssigningObjNums;
- bool fAssigningFirstPageObjNums;
+ // Next object number to assign on the first page.
+ uint32_t fNextFirstPageObjNum;
int findObjectIndex(SkPDFObject* obj) const;
diff --git a/include/pdf/SkPDFDocument.h b/include/pdf/SkPDFDocument.h
new file mode 100644
index 0000000000..91dd379214
--- /dev/null
+++ b/include/pdf/SkPDFDocument.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPDFDocument_DEFINED
+#define SkPDFDocument_DEFINED
+
+#include "SkPDFCatalog.h"
+#include "SkPDFTypes.h"
+#include "SkRefCnt.h"
+#include "SkTDArray.h"
+
+class SkPDFDevice;
+class SkPDFPage;
+class SkWSteam;
+
+/** \class SkPDFDocument
+
+ A SkPDFDocument assembles pages together and generates the final PDF file.
+*/
+class SkPDFDocument {
+public:
+ /** Create a PDF document.
+ */
+ SkPDFDocument();
+ ~SkPDFDocument();
+
+ /** Output the PDF to the passed stream.
+ * @param stream The writable output stream to send the PDF to.
+ */
+ bool emitPDF(SkWStream* stream);
+
+ /** Append the passed pdf device to the document as a new page. Returns
+ * true if successful. Will fail if the document has already been emitted.
+ *
+ * @param pdfDevice The page to add to this document.
+ */
+ bool appendPage(const SkRefPtr<SkPDFDevice>& pdfDevice);
+
+private:
+ SkPDFCatalog fCatalog;
+ int64_t fXRefFileOffset;
+
+ SkTDArray<SkPDFPage*> fPages;
+ SkTDArray<SkPDFDict*> fPageTree;
+ SkRefPtr<SkPDFDict> fDocCatalog;
+ SkTDArray<SkPDFObject*> fPageResources;
+ int fSecondPageFirstResouceIndex;
+
+ SkRefPtr<SkPDFDict> fTrailerDict;
+
+ /** Output the PDF header to the passed stream.
+ * @param stream The writable output stream to send the header to.
+ */
+ void emitHeader(SkWStream* stream);
+
+ /** Get the size of the header.
+ */
+ size_t headerSize();
+
+ /** Output the PDF footer to the passed stream.
+ * @param stream The writable output stream to send the footer to.
+ * @param objCount The number of objects in the PDF.
+ */
+ void emitFooter(SkWStream* stream, int64_t objCount);
+};
+
+#endif
diff --git a/include/pdf/SkPDFPage.h b/include/pdf/SkPDFPage.h
new file mode 100644
index 0000000000..7e96212bbf
--- /dev/null
+++ b/include/pdf/SkPDFPage.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkPDFPage_DEFINED
+#define SkPDFPage_DEFINED
+
+#include "SkPDFTypes.h"
+#include "SkPDFStream.h"
+#include "SkRefCnt.h"
+#include "SkTDArray.h"
+
+class SkPDFCatalog;
+class SkPDFDevice;
+class SkWStream;
+
+/** \class SkPDFPage
+
+ A SkPDFPage contains meta information about a page, is used in the page
+ tree and points to the content of the page.
+*/
+class SkPDFPage : public SkPDFDict {
+public:
+ /** Create a PDF page with the passed PDF device. The device need not
+ * have content on it yet.
+ * @param content The page content.
+ */
+ explicit SkPDFPage(const SkRefPtr<SkPDFDevice>& content);
+ ~SkPDFPage();
+
+ /** Before a page and its contents can be sized and emitted, it must
+ * be finalized. No changes to the PDFDevice will be honored after
+ * finalizePage has been called. This function adds the page content
+ * to the passed catalog, so it must be called for each document
+ * that the page is part of.
+ * @param catalog The catalog to add page content objects to.
+ * @param firstPage Indicate if this is the first page of a document.
+ * @param resouceObjects The resource objects used on the page are added
+ * to this array. This gives the caller a chance
+ * to deduplicate resources across pages.
+ */
+ void finalizePage(SkPDFCatalog* catalog, bool firstPage,
+ SkTDArray<SkPDFObject*>* resourceObjects);
+
+ /** Determine the size of the page content and store to the catalog
+ * the offsets of all nonresource-indirect objects that make up the page
+ * content. This must be called before emitPage(), but after finalizePage.
+ * @param catalog The catalog to add the object offsets to.
+ * @param fileOffset The file offset where the page content will be
+ * emitted.
+ */
+ off_t getPageSize(SkPDFCatalog* catalog, off_t fileOffset);
+
+ /** Output the page content to the passed stream.
+ * @param stream The writable output stream to send the content to.
+ * @param catalog The active object catalog.
+ */
+ void emitPage(SkWStream* stream, SkPDFCatalog* catalog);
+
+ /** Generate a page tree for the passed vector of pages. New objects are
+ * added to the catalog. The pageTree vector is populated with all of
+ * the 'Pages' dictionaries as well as the 'Page' objects. Page trees
+ * have both parent and children links, creating reference cycles, so
+ * it must be torn down explicitly. The first page is not added to
+ * the pageTree dictionary array so the caller can handle it specially.
+ * @param pages The ordered vector of page objects.
+ * @param catalog The catalog to add new objects into.
+ * @param pageTree An output vector with all of the internal and leaf
+ * nodes of the pageTree.
+ * @param rootNode An output parameter set to the root node.
+ */
+ static void generatePageTree(const SkTDArray<SkPDFPage*>& pages,
+ SkPDFCatalog* catalog,
+ SkTDArray<SkPDFDict*>* pageTree,
+ SkPDFDict** rootNode);
+
+private:
+ // Multiple pages may reference the content.
+ SkRefPtr<SkPDFDevice> fDevice;
+
+ SkString fContent;
+ // Once the content is finalized, put it into a stream for output.
+ SkRefPtr<SkPDFStream> fContentStream;
+};
+
+#endif
diff --git a/include/pdf/SkPDFStream.h b/include/pdf/SkPDFStream.h
index b83aa591f6..24a96422be 100644
--- a/include/pdf/SkPDFStream.h
+++ b/include/pdf/SkPDFStream.h
@@ -44,11 +44,17 @@ public:
virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
/** Add the value to the stream dictionary with the given key.
- * @param index The index into the array to set.
- * @param value The value to add to the array.
+ * @param key The key for this dictionary entry.
+ * @param value The value for this dictionary entry.
*/
void insert(SkPDFName* key, SkPDFObject* value);
+ /** Add the value to the stream dictionary with the given key.
+ * @param key The text of the key for this dictionary entry.
+ * @param value The value for this dictionary entry.
+ */
+ void insert(const char key[], SkPDFObject* value);
+
private:
SkPDFDict fDict;
SkRefPtr<SkStream> fData;
diff --git a/include/pdf/SkPDFTypes.h b/include/pdf/SkPDFTypes.h
index 9324595339..e0b1041b92 100644
--- a/include/pdf/SkPDFTypes.h
+++ b/include/pdf/SkPDFTypes.h
@@ -147,7 +147,7 @@ public:
virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
private:
- static const uint32_t kMaxLen = 65535;
+ static const size_t kMaxLen = 65535;
const SkString fValue;
@@ -173,7 +173,7 @@ public:
virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
private:
- static const uint32_t kMaxLen = 127;
+ static const size_t kMaxLen = 127;
const SkString fValue;
@@ -235,6 +235,12 @@ public:
/** Create a PDF dictionary. Maximum number of entries is 4095.
*/
SkPDFDict();
+
+ /** Create a PDF dictionary with a Type entry.
+ * @param type The value of the Type entry.
+ */
+ explicit SkPDFDict(const char type[]);
+
virtual ~SkPDFDict();
// The SkPDFObject interface.
@@ -252,6 +258,17 @@ public:
*/
void insert(SkPDFName* key, SkPDFObject* value);
+ /** Add the value to the dictionary with the given key. The method will
+ * create the SkPDFName object.
+ * @param key The text of the key for this dictionary entry.
+ * @param value The value for this dictionary entry.
+ */
+ void insert(const char key[], SkPDFObject* value);
+
+ /** Remove all entries from the dictionary.
+ */
+ void clear();
+
private:
static const int kMaxLen = 4095;