| 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;
|
|
|