// Xref table and footer void SkPDFObjectSerializer::serializeFooter(SkWStream* wStream, const sk_sp<SkPDFObject> docCatalog, sk_sp<SkPDFObject> id) { this->serializeObjects(wStream); int32_t xRefFileOffset = this->offset(wStream); // Include the special zeroth object in the count. int32_t objCount = SkToS32(fOffsets.count() + 1); wStream->writeText("xref\n0 "); wStream->writeDecAsText(objCount); wStream->writeText("\n0000000000 65535 f \n"); for (int i = 0; i < fOffsets.count(); i++) { wStream->writeBigDecAsText(fOffsets[i], 10); wStream->writeText(" 00000 n \n"); } SkPDFDict trailerDict; trailerDict.insertInt("Size", objCount); SkASSERT(docCatalog); trailerDict.insertObjRef("Root", docCatalog); SkASSERT(fInfoDict); trailerDict.insertObjRef("Info", std::move(fInfoDict)); if (id) { trailerDict.insertObject("ID", std::move(id)); } wStream->writeText("trailer\n"); trailerDict.emitObject(wStream, fObjNumMap); wStream->writeText("\nstartxref\n"); wStream->writeBigDecAsText(xRefFileOffset); wStream->writeText("\n%%EOF"); }
static void emit_pdf_footer(SkWStream* stream, const SkPDFObjNumMap& objNumMap, const SkPDFSubstituteMap& substitutes, SkPDFObject* docCatalog, int64_t objCount, int32_t xRefFileOffset) { SkPDFDict trailerDict; // TODO(vandebo): Linearized format will take a Prev entry too. // TODO(vandebo): PDF/A requires an ID entry. trailerDict.insertInt("Size", int(objCount)); trailerDict.insertObjRef("Root", SkRef(docCatalog)); stream->writeText("trailer\n"); trailerDict.emitObject(stream, objNumMap, substitutes); stream->writeText("\nstartxref\n"); stream->writeBigDecAsText(xRefFileOffset); stream->writeText("\n%%EOF"); }