Mercurial > hgrepos > Python2 > PyMuPDF
diff mupdf-source/docs/examples/pdf-bake.js @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mupdf-source/docs/examples/pdf-bake.js Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,115 @@ +// usage: mutool run pdf-bake.js input.pdf output.pdf +// +// This tool will rewrite all Widgets and Annotations as plain XObjects +// drawn on the page and remove them as interactive objects. +// +// Links will be preserved. All other Annotations will be removed. +// The AcroForm object will be deleted if present. +// + +"use strict" + +function request_synthesis(list) { + if (list) + for (var i = 0; i < list.length; ++i) + list[i].requestSynthesis() +} + +function bake_document(doc, do_bake_annots, do_bake_widgets) { + var i, n, page, list + n = doc.countPages() + for (i = 0; i < n; ++i) { + page = doc.loadPage(i) + if (do_bake_annots) + request_synthesis(page.getAnnotations()) + if (do_bake_widgets) + request_synthesis(page.getWidgets()) + page.update() + bake_page(doc, page.getObject(), do_bake_annots, do_bake_widgets) + } + if (do_bake_widgets) + delete doc.getTrailer().Root.AcroForm +} + +function bake_page(doc, page, do_bake_annots, do_bake_widgets) { + var i, n, list, keep, buf + list = page.Annots + if (list) { + if (!page.Resources) + page.Resources = {} + if (!page.Resources.XObject) + page.Resources.XObject = {} + if (!page.Contents.isArray()) + page.Contents = [ page.Contents ] + + keep = [] + buf = "" + for (i = 0; i < list.length; ++i) { + if (list[i].Subtype == "Link") { + keep.push(list[i]) + } else if (list[i].Subtype == "Widget") { + if (do_bake_widgets) + buf += bake_annot(doc, page, list[i]) + else + keep.push(list[i]) + } else { + if (do_bake_annots) + buf += bake_annot(doc, page, list[i]) + else + keep.push(list[i]) + } + } + + if (keep.length > 0) + page.Annots = keep + else + delete page.Annots + + page.Contents.push(doc.addStream(buf)) + } +} + +function get_annot_ap(annot) { + var ap = annot.AP + if (ap) { + ap = ap.N + if (ap.isStream()) + return ap + ap = ap[annot.AS] + if (ap.isStream()) + return ap + } + return null +} + +function get_annot_transform(rect, bbox, transform) { + var w, h, x, y + if (!transform) + transform = [ 1, 0, 0, 1, 0, 0 ] + bbox = mupdf.Rect.transform(bbox, transform) + w = (rect[2] - rect[0]) / (bbox[2] - bbox[0]) + h = (rect[3] - rect[1]) / (bbox[3] - bbox[1]) + x = rect[0] - bbox[0] * w + y = rect[1] - bbox[1] * h + return [ w, 0, 0, h, x, y ] +} + +function bake_annot(doc, page, annot) { + var name = "Annot" + annot.asIndirect() + var ap = get_annot_ap(annot) + if (ap) { + var transform = get_annot_transform(annot.Rect, ap.BBox, ap.Matrix) + page.Resources.XObject[name] = ap + ap.Type = "XObject" + ap.Subtype = "Form" + return "q\n" + transform.join(" ") + " cm\n/" + name + " Do\nQ\n" + } + return "" +} + +var doc = mupdf.Document.openDocument(scriptArgs[0]) +doc.enableJournal() +doc.beginOperation("bake") +bake_document(doc, true, true) +doc.endOperation() +doc.save(scriptArgs[1], "garbage,compress")
