Mercurial > hgrepos > Python2 > PyMuPDF
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 // usage: mutool run pdf-bake.js input.pdf output.pdf | |
| 2 // | |
| 3 // This tool will rewrite all Widgets and Annotations as plain XObjects | |
| 4 // drawn on the page and remove them as interactive objects. | |
| 5 // | |
| 6 // Links will be preserved. All other Annotations will be removed. | |
| 7 // The AcroForm object will be deleted if present. | |
| 8 // | |
| 9 | |
| 10 "use strict" | |
| 11 | |
| 12 function request_synthesis(list) { | |
| 13 if (list) | |
| 14 for (var i = 0; i < list.length; ++i) | |
| 15 list[i].requestSynthesis() | |
| 16 } | |
| 17 | |
| 18 function bake_document(doc, do_bake_annots, do_bake_widgets) { | |
| 19 var i, n, page, list | |
| 20 n = doc.countPages() | |
| 21 for (i = 0; i < n; ++i) { | |
| 22 page = doc.loadPage(i) | |
| 23 if (do_bake_annots) | |
| 24 request_synthesis(page.getAnnotations()) | |
| 25 if (do_bake_widgets) | |
| 26 request_synthesis(page.getWidgets()) | |
| 27 page.update() | |
| 28 bake_page(doc, page.getObject(), do_bake_annots, do_bake_widgets) | |
| 29 } | |
| 30 if (do_bake_widgets) | |
| 31 delete doc.getTrailer().Root.AcroForm | |
| 32 } | |
| 33 | |
| 34 function bake_page(doc, page, do_bake_annots, do_bake_widgets) { | |
| 35 var i, n, list, keep, buf | |
| 36 list = page.Annots | |
| 37 if (list) { | |
| 38 if (!page.Resources) | |
| 39 page.Resources = {} | |
| 40 if (!page.Resources.XObject) | |
| 41 page.Resources.XObject = {} | |
| 42 if (!page.Contents.isArray()) | |
| 43 page.Contents = [ page.Contents ] | |
| 44 | |
| 45 keep = [] | |
| 46 buf = "" | |
| 47 for (i = 0; i < list.length; ++i) { | |
| 48 if (list[i].Subtype == "Link") { | |
| 49 keep.push(list[i]) | |
| 50 } else if (list[i].Subtype == "Widget") { | |
| 51 if (do_bake_widgets) | |
| 52 buf += bake_annot(doc, page, list[i]) | |
| 53 else | |
| 54 keep.push(list[i]) | |
| 55 } else { | |
| 56 if (do_bake_annots) | |
| 57 buf += bake_annot(doc, page, list[i]) | |
| 58 else | |
| 59 keep.push(list[i]) | |
| 60 } | |
| 61 } | |
| 62 | |
| 63 if (keep.length > 0) | |
| 64 page.Annots = keep | |
| 65 else | |
| 66 delete page.Annots | |
| 67 | |
| 68 page.Contents.push(doc.addStream(buf)) | |
| 69 } | |
| 70 } | |
| 71 | |
| 72 function get_annot_ap(annot) { | |
| 73 var ap = annot.AP | |
| 74 if (ap) { | |
| 75 ap = ap.N | |
| 76 if (ap.isStream()) | |
| 77 return ap | |
| 78 ap = ap[annot.AS] | |
| 79 if (ap.isStream()) | |
| 80 return ap | |
| 81 } | |
| 82 return null | |
| 83 } | |
| 84 | |
| 85 function get_annot_transform(rect, bbox, transform) { | |
| 86 var w, h, x, y | |
| 87 if (!transform) | |
| 88 transform = [ 1, 0, 0, 1, 0, 0 ] | |
| 89 bbox = mupdf.Rect.transform(bbox, transform) | |
| 90 w = (rect[2] - rect[0]) / (bbox[2] - bbox[0]) | |
| 91 h = (rect[3] - rect[1]) / (bbox[3] - bbox[1]) | |
| 92 x = rect[0] - bbox[0] * w | |
| 93 y = rect[1] - bbox[1] * h | |
| 94 return [ w, 0, 0, h, x, y ] | |
| 95 } | |
| 96 | |
| 97 function bake_annot(doc, page, annot) { | |
| 98 var name = "Annot" + annot.asIndirect() | |
| 99 var ap = get_annot_ap(annot) | |
| 100 if (ap) { | |
| 101 var transform = get_annot_transform(annot.Rect, ap.BBox, ap.Matrix) | |
| 102 page.Resources.XObject[name] = ap | |
| 103 ap.Type = "XObject" | |
| 104 ap.Subtype = "Form" | |
| 105 return "q\n" + transform.join(" ") + " cm\n/" + name + " Do\nQ\n" | |
| 106 } | |
| 107 return "" | |
| 108 } | |
| 109 | |
| 110 var doc = mupdf.Document.openDocument(scriptArgs[0]) | |
| 111 doc.enableJournal() | |
| 112 doc.beginOperation("bake") | |
| 113 bake_document(doc, true, true) | |
| 114 doc.endOperation() | |
| 115 doc.save(scriptArgs[1], "garbage,compress") |
