| Index: src/pdf/SkPDFDocument.cpp
|
| diff --git a/src/pdf/SkPDFDocument.cpp b/src/pdf/SkPDFDocument.cpp
|
| index 42744a847f5c6dc255ae63ad3f8c04101435082a..5f86598c08e27f882f320b3b9bb56e1801d88a09 100644
|
| --- a/src/pdf/SkPDFDocument.cpp
|
| +++ b/src/pdf/SkPDFDocument.cpp
|
| @@ -17,10 +17,8 @@
|
|
|
|
|
| static void perform_font_subsetting(SkPDFCatalog* catalog,
|
| - const SkTDArray<SkPDFPage*>& pages,
|
| - SkTDArray<SkPDFObject*>* substitutes) {
|
| + const SkTDArray<SkPDFPage*>& pages) {
|
| SkASSERT(catalog);
|
| - SkASSERT(substitutes);
|
|
|
| SkPDFGlyphSetMap usage;
|
| for (int i = 0; i < pages.count(); ++i) {
|
| @@ -29,11 +27,10 @@ static void perform_font_subsetting(SkPDFCatalog* catalog,
|
| SkPDFGlyphSetMap::F2BIter iterator(usage);
|
| const SkPDFGlyphSetMap::FontGlyphSetPair* entry = iterator.next();
|
| while (entry) {
|
| - SkPDFFont* subsetFont =
|
| - entry->fFont->getFontSubset(entry->fGlyphSet);
|
| + SkAutoTUnref<SkPDFFont> subsetFont(
|
| + entry->fFont->getFontSubset(entry->fGlyphSet));
|
| if (subsetFont) {
|
| - catalog->setSubstitute(entry->fFont, subsetFont);
|
| - substitutes->push(subsetFont); // Transfer ownership to substitutes
|
| + catalog->setSubstitute(entry->fFont, subsetFont.get());
|
| }
|
| entry = iterator.next();
|
| }
|
| @@ -72,24 +69,26 @@ bool SkPDFDocument::EmitPDF(const SkTDArray<const SkPDFDevice*>& pageDevices,
|
| }
|
|
|
| SkTDArray<SkPDFPage*> pages;
|
| + SkAutoTUnref<SkPDFDict> dests(SkNEW(SkPDFDict));
|
| +
|
| for (int i = 0; i < pageDevices.count(); i++) {
|
| SkASSERT(pageDevices[i]);
|
| SkASSERT(i == 0 ||
|
| pageDevices[i - 1]->getCanon() == pageDevices[i]->getCanon());
|
| // Reference from new passed to pages.
|
| - pages.push(SkNEW_ARGS(SkPDFPage, (pageDevices[i])));
|
| + SkAutoTUnref<SkPDFPage> page(SkNEW_ARGS(SkPDFPage, (pageDevices[i])));
|
| + page->finalizePage();
|
| + page->appendDestinations(dests);
|
| + pages.push(page.detach());
|
| }
|
| SkPDFCatalog catalog;
|
|
|
| SkTDArray<SkPDFDict*> pageTree;
|
| SkAutoTUnref<SkPDFDict> docCatalog(SkNEW_ARGS(SkPDFDict, ("Catalog")));
|
| - SkTSet<SkPDFObject*> firstPageResources;
|
| - SkTSet<SkPDFObject*> otherPageResources;
|
| - SkTDArray<SkPDFObject*> substitutes;
|
| - catalog.addObject(docCatalog.get(), true);
|
|
|
| SkPDFDict* pageTreeRoot;
|
| - SkPDFPage::GeneratePageTree(pages, &catalog, &pageTree, &pageTreeRoot);
|
| + SkPDFPage::GeneratePageTree(pages, &pageTree, &pageTreeRoot);
|
| +
|
| docCatalog->insert("Pages", new SkPDFObjRef(pageTreeRoot))->unref();
|
|
|
| /* TODO(vandebo): output intent
|
| @@ -102,78 +101,47 @@ bool SkPDFDocument::EmitPDF(const SkTDArray<const SkPDFDevice*>& pageDevices,
|
| docCatalog->insert("OutputIntent", intentArray.get());
|
| */
|
|
|
| - SkAutoTUnref<SkPDFDict> dests(SkNEW(SkPDFDict));
|
| -
|
| - bool firstPage = true;
|
| - /* The references returned in newResources are transfered to
|
| - * firstPageResources or otherPageResources depending on firstPage and
|
| - * knownResources doesn't have a reference but just relies on the other
|
| - * two sets to maintain a reference.
|
| - */
|
| - SkTSet<SkPDFObject*> knownResources;
|
| -
|
| - // mergeInto returns the number of duplicates.
|
| - // If there are duplicates, there is a bug and we mess ref counting.
|
| - SkDEBUGCODE(int duplicates = ) knownResources.mergeInto(firstPageResources);
|
| - SkASSERT(duplicates == 0);
|
| -
|
| - for (int i = 0; i < pages.count(); i++) {
|
| - if (i == 1) {
|
| - firstPage = false;
|
| - SkDEBUGCODE(duplicates = )
|
| - knownResources.mergeInto(otherPageResources);
|
| - }
|
| - SkTSet<SkPDFObject*> newResources;
|
| - pages[i]->finalizePage(&catalog, firstPage, knownResources,
|
| - &newResources);
|
| - for (int j = 0; j < newResources.count(); j++) {
|
| - catalog.addObject(newResources[i], firstPage);
|
| - }
|
| - if (firstPage) {
|
| - SkDEBUGCODE(duplicates = )
|
| - firstPageResources.mergeInto(newResources);
|
| - } else {
|
| - SkDEBUGCODE(duplicates = )
|
| - otherPageResources.mergeInto(newResources);
|
| - }
|
| - SkASSERT(duplicates == 0);
|
| -
|
| - SkDEBUGCODE(duplicates = ) knownResources.mergeInto(newResources);
|
| - SkASSERT(duplicates == 0);
|
| -
|
| - pages[i]->appendDestinations(dests);
|
| - }
|
| -
|
| if (dests->size() > 0) {
|
| - SkPDFDict* raw_dests = dests.get();
|
| - firstPageResources.add(dests.detach()); // Transfer ownership.
|
| - catalog.addObject(raw_dests, true /* onFirstPage */);
|
| - docCatalog->insert("Dests", SkNEW_ARGS(SkPDFObjRef, (raw_dests)))
|
| + docCatalog->insert("Dests", SkNEW_ARGS(SkPDFObjRef, (dests.get())))
|
| ->unref();
|
| }
|
|
|
| // Build font subsetting info before proceeding.
|
| - perform_font_subsetting(&catalog, pages, &substitutes);
|
| + perform_font_subsetting(&catalog, pages);
|
|
|
| SkTSet<SkPDFObject*> resourceSet;
|
| if (resourceSet.add(docCatalog.get())) {
|
| docCatalog->addResources(&resourceSet, &catalog);
|
| }
|
| + for (int i = 0; i < resourceSet.count(); ++i) {
|
| + SkAssertResult(catalog.addObject(resourceSet[i]));
|
| + }
|
| +
|
| size_t baseOffset = SkToOffT(stream->bytesWritten());
|
| emit_pdf_header(stream);
|
| + SkTDArray<int32_t> offsets;
|
| for (int i = 0; i < resourceSet.count(); ++i) {
|
| SkPDFObject* object = resourceSet[i];
|
| - catalog.setFileOffset(object,
|
| - SkToOffT(stream->bytesWritten() - baseOffset));
|
| + offsets.push(SkToS32(stream->bytesWritten() - baseOffset));
|
| SkASSERT(object == catalog.getSubstituteObject(object));
|
| - stream->writeDecAsText(catalog.getObjectNumber(object));
|
| + SkASSERT(catalog.getObjectNumber(object) == i + 1);
|
| + stream->writeDecAsText(i + 1);
|
| stream->writeText(" 0 obj\n"); // Generation number is always 0.
|
| object->emitObject(stream, &catalog);
|
| stream->writeText("\nendobj\n");
|
| }
|
| int32_t xRefFileOffset = SkToS32(stream->bytesWritten() - baseOffset);
|
| - int64_t objCount = catalog.emitXrefTable(stream, pages.count() > 1);
|
|
|
| + int32_t objCount = SkToS32(offsets.count() + 1);
|
| +
|
| + stream->writeText("xref\n0 ");
|
| + stream->writeDecAsText(objCount + 1);
|
| + stream->writeText("\n0000000000 65535 f \n");
|
| + for (int i = 0; i < offsets.count(); i++) {
|
| + SkASSERT(offsets[i] > 0);
|
| + stream->writeBigDecAsText(offsets[i], 10);
|
| + stream->writeText(" 00000 n \n");
|
| + }
|
| emit_pdf_footer(stream, &catalog, docCatalog.get(), objCount,
|
| xRefFileOffset);
|
|
|
| @@ -184,12 +152,6 @@ bool SkPDFDocument::EmitPDF(const SkTDArray<const SkPDFDevice*>& pageDevices,
|
| }
|
| pageTree.safeUnrefAll();
|
| pages.unrefAll();
|
| -
|
| - firstPageResources.safeUnrefAll();
|
| - otherPageResources.safeUnrefAll();
|
| -
|
| - substitutes.unrefAll();
|
| - docCatalog.reset(NULL);
|
| return true;
|
| }
|
|
|
|
|