// 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 SkPDFDict* SkPDFGraphicState::GetSMaskGraphicState(SkPDFFormXObject* sMask, bool invert, SkPDFSMaskMode sMaskMode) { // The practical chances of using the same mask more than once are unlikely // enough that it's not worth canonicalizing. SkAutoTUnref<SkPDFDict> sMaskDict(new SkPDFDict("Mask")); if (sMaskMode == kAlpha_SMaskMode) { sMaskDict->insertName("S", "Alpha"); } else if (sMaskMode == kLuminosity_SMaskMode) { sMaskDict->insertName("S", "Luminosity"); } sMaskDict->insertObjRef("G", SkRef(sMask)); if (invert) { sMaskDict->insertObjRef("TR", SkRef(invertFunction.get())); } SkPDFDict* result = new SkPDFDict("ExtGState"); result->insertObject("SMask", sMaskDict.detach()); return result; }