Index: src/pdf/SkPDFDocument.cpp |
diff --git a/src/pdf/SkPDFDocument.cpp b/src/pdf/SkPDFDocument.cpp |
index 632cbcfe3ee5f3c706ce84cae5c1e90f15f20b14..c4a5d448a54cc1ca6dd873a4a7737b3095aee7ac 100644 |
--- a/src/pdf/SkPDFDocument.cpp |
+++ b/src/pdf/SkPDFDocument.cpp |
@@ -82,6 +82,29 @@ SkPDFDocument::~SkPDFDocument() { |
SkDELETE(fOtherPageResources); |
} |
+namespace { |
+class Streamer { |
+public: |
+ Streamer(SkPDFCatalog* cat, SkWStream* out) |
+ : fCat(cat), fOut(out), fBaseOffset(SkToOffT(out->bytesWritten())) { |
+ } |
+ |
+ void stream(SkPDFObject* obj) { |
+ fCat->setFileOffset(obj, this->offset()); |
+ obj->emit(fOut, fCat, true); |
+ } |
+ |
+ off_t offset() { |
+ return SkToOffT(fOut->bytesWritten()) - fBaseOffset; |
+ } |
+ |
+private: |
+ SkPDFCatalog* const fCat; |
+ SkWStream* const fOut; |
+ const off_t fBaseOffset; |
+}; |
+} // namespace |
+ |
bool SkPDFDocument::emitPDF(SkWStream* stream) { |
if (fPages.isEmpty()) { |
return false; |
@@ -158,46 +181,24 @@ bool SkPDFDocument::emitPDF(SkWStream* stream) { |
// Build font subsetting info before proceeding. |
perform_font_subsetting(fCatalog.get(), fPages, &fSubstitutes); |
+ } |
- // Figure out the size of things and inform the catalog of file offsets. |
- off_t fileOffset = SkToOffT(this->headerSize()); |
- fileOffset += SkToOffT(fCatalog->setFileOffset(fDocCatalog, fileOffset)); |
- fileOffset += SkToOffT(fCatalog->setFileOffset(fPages[0], fileOffset)); |
- fileOffset += fPages[0]->getPageSize(fCatalog.get(), fileOffset); |
- for (int i = 0; i < fFirstPageResources->count(); i++) { |
- fileOffset += SkToOffT(fCatalog->setFileOffset((*fFirstPageResources)[i], fileOffset)); |
- } |
- // Add the size of resources of substitute objects used on page 1. |
- fileOffset += fCatalog->setSubstituteResourcesOffsets(fileOffset, true); |
- if (fPages.count() > 1) { |
- // TODO(vandebo): For linearized format, save the start of the |
- // first page xref table and calculate the size. |
- } |
- |
- for (int i = 0; i < fPageTree.count(); i++) { |
- fileOffset += SkToOffT(fCatalog->setFileOffset(fPageTree[i], fileOffset)); |
- } |
- |
- for (int i = 1; i < fPages.count(); i++) { |
- fileOffset += fPages[i]->getPageSize(fCatalog.get(), fileOffset); |
- } |
+ Streamer out(fCatalog, stream); |
+ emitHeader(stream); |
- for (int i = 0; i < fOtherPageResources->count(); i++) { |
- fileOffset += SkToOffT(fCatalog->setFileOffset((*fOtherPageResources)[i], fileOffset)); |
- } |
+ out.stream(fDocCatalog); |
+ out.stream(fPages[0]); |
+ out.stream(fPages[0]->getContentStream()); |
- fileOffset += fCatalog->setSubstituteResourcesOffsets(fileOffset, false); |
- fXRefFileOffset = fileOffset; |
+ for (int i = 0; i < fFirstPageResources->count(); i++) { |
+ out.stream((*fFirstPageResources)[i]); |
} |
- emitHeader(stream); |
- fDocCatalog->emitIndirectObject(stream, fCatalog.get()); |
- fPages[0]->emitIndirectObject(stream, fCatalog.get()); |
- fPages[0]->emitPage(stream, fCatalog.get()); |
- for (int i = 0; i < fFirstPageResources->count(); i++) { |
- (*fFirstPageResources)[i]->emit(stream, fCatalog.get(), true); |
+ SkTSet<SkPDFObject*>* firstPageSubstituteResources = |
+ fCatalog->getSubstituteList(true); |
+ for (int i = 0; i < firstPageSubstituteResources->count(); ++i) { |
+ out.stream((*firstPageSubstituteResources)[i]); |
} |
- fCatalog->emitSubstituteResources(stream, true); |
// TODO(vandebo): Support linearized format |
// if (fPages.size() > 1) { |
// // TODO(vandebo): Save the file offset for the first page xref table. |
@@ -205,18 +206,24 @@ bool SkPDFDocument::emitPDF(SkWStream* stream) { |
// } |
for (int i = 0; i < fPageTree.count(); i++) { |
- fPageTree[i]->emitIndirectObject(stream, fCatalog.get()); |
+ out.stream(fPageTree[i]); |
} |
for (int i = 1; i < fPages.count(); i++) { |
- fPages[i]->emitPage(stream, fCatalog.get()); |
+ out.stream(fPages[i]->getContentStream()); |
} |
for (int i = 0; i < fOtherPageResources->count(); i++) { |
- (*fOtherPageResources)[i]->emit(stream, fCatalog.get(), true); |
+ out.stream((*fOtherPageResources)[i]); |
+ } |
+ |
+ SkTSet<SkPDFObject*>* otherSubstituteResources = |
+ fCatalog->getSubstituteList(false); |
+ for (int i = 0; i < otherSubstituteResources->count(); ++i) { |
+ out.stream((*otherSubstituteResources)[i]); |
} |
- fCatalog->emitSubstituteResources(stream, false); |
+ fXRefFileOffset = out.offset(); |
int64_t objCount = fCatalog->emitXrefTable(stream, fPages.count() > 1); |
emitFooter(stream, objCount); |
return true; |