aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pdf/SkPDFDocument.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/pdf/SkPDFDocument.cpp')
-rw-r--r--src/pdf/SkPDFDocument.cpp102
1 files changed, 32 insertions, 70 deletions
diff --git a/src/pdf/SkPDFDocument.cpp b/src/pdf/SkPDFDocument.cpp
index 42744a847f..5f86598c08 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;
}