Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/platform/wasm/examples/simple-viewer/worker.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 // Copyright (C) 2022, 2024 Artifex Software, Inc. | |
| 2 // | |
| 3 // This file is part of MuPDF. | |
| 4 // | |
| 5 // MuPDF is free software: you can redistribute it and/or modify it under the | |
| 6 // terms of the GNU Affero General Public License as published by the Free | |
| 7 // Software Foundation, either version 3 of the License, or (at your option) | |
| 8 // any later version. | |
| 9 // | |
| 10 // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY | |
| 11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
| 12 // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more | |
| 13 // details. | |
| 14 // | |
| 15 // You should have received a copy of the GNU Affero General Public License | |
| 16 // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html> | |
| 17 // | |
| 18 // Alternative licensing terms are available from the licensor. | |
| 19 // For commercial licensing, see <https://www.artifex.com/> or contact | |
| 20 // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, | |
| 21 // CA 94129, USA, for further information. | |
| 22 | |
| 23 "use strict" | |
| 24 | |
| 25 import * as mupdf from "../../dist/mupdf.js" | |
| 26 | |
| 27 const methods = {} | |
| 28 | |
| 29 onmessage = async function (event) { | |
| 30 let [ func, id, args ] = event.data | |
| 31 try { | |
| 32 let result = methods[func](...args) | |
| 33 postMessage([ "RESULT", id, result ]) | |
| 34 } catch (error) { | |
| 35 postMessage([ "ERROR", id, { name: error.name, message: error.message, stack: error.stack } ]) | |
| 36 } | |
| 37 } | |
| 38 | |
| 39 var document_next_id = 1 | |
| 40 var document_map = {} // open mupdf.Document handles | |
| 41 | |
| 42 class WorkerBlobStream { | |
| 43 constructor(blob) { | |
| 44 this.reader = new FileReaderSync() | |
| 45 this.blob = blob | |
| 46 } | |
| 47 fileSize() { | |
| 48 return this.blob.size | |
| 49 } | |
| 50 read(memory, offset, size, position) { | |
| 51 let data = this.reader.readAsArrayBuffer(this.blob.slice(position, position + size)) | |
| 52 memory.set(new Uint8Array(data), offset) | |
| 53 return data.byteLength | |
| 54 } | |
| 55 close() { | |
| 56 this.reader = null | |
| 57 this.blob = null | |
| 58 } | |
| 59 } | |
| 60 | |
| 61 methods.openDocumentFromBlob = function (blob, magic) { | |
| 62 let stm = new mupdf.Stream(new WorkerBlobStream(blob)) | |
| 63 let doc_id = document_next_id++ | |
| 64 document_map[doc_id] = mupdf.Document.openDocument(stm, magic) | |
| 65 return doc_id | |
| 66 } | |
| 67 | |
| 68 methods.openDocumentFromBuffer = function (buffer, magic) { | |
| 69 let doc_id = document_next_id++ | |
| 70 document_map[doc_id] = mupdf.Document.openDocument(buffer, magic) | |
| 71 return doc_id | |
| 72 } | |
| 73 | |
| 74 methods.closeDocument = function (doc_id) { | |
| 75 let doc = document_map[doc_id] | |
| 76 doc.destroy() | |
| 77 delete document_map[doc_id] | |
| 78 } | |
| 79 | |
| 80 methods.documentTitle = function (doc_id) { | |
| 81 let doc = document_map[doc_id] | |
| 82 return doc.getMetaData(mupdf.Document.META_INFO_TITLE) | |
| 83 } | |
| 84 | |
| 85 methods.documentOutline = function (doc_id) { | |
| 86 let doc = document_map[doc_id] | |
| 87 return doc.loadOutline() | |
| 88 } | |
| 89 | |
| 90 methods.countPages = function (doc_id) { | |
| 91 let doc = document_map[doc_id] | |
| 92 return doc.countPages() | |
| 93 } | |
| 94 | |
| 95 methods.getPageSize = function (doc_id, page_number) { | |
| 96 let doc = document_map[doc_id] | |
| 97 let page = doc.loadPage(page_number) | |
| 98 let bounds = page.getBounds() | |
| 99 return { width: bounds[2] - bounds[0], height: bounds[3] - bounds[1] } | |
| 100 } | |
| 101 | |
| 102 methods.getPageLinks = function (doc_id, page_number) { | |
| 103 let doc = document_map[doc_id] | |
| 104 let page = doc.loadPage(page_number) | |
| 105 let links = page.getLinks() | |
| 106 | |
| 107 return links.map((link) => { | |
| 108 const [ x0, y0, x1, y1 ] = link.getBounds() | |
| 109 | |
| 110 let href | |
| 111 if (link.isExternal()) | |
| 112 href = link.getURI() | |
| 113 else | |
| 114 href = `#page${doc.resolveLink(link) + 1}` | |
| 115 | |
| 116 return { | |
| 117 x: x0, | |
| 118 y: y0, | |
| 119 w: x1 - x0, | |
| 120 h: y1 - y0, | |
| 121 href, | |
| 122 } | |
| 123 }) | |
| 124 } | |
| 125 | |
| 126 methods.getPageText = function (doc_id, page_number) { | |
| 127 let doc = document_map[doc_id] | |
| 128 let page = doc.loadPage(page_number) | |
| 129 let text = page.toStructuredText().asJSON() | |
| 130 return JSON.parse(text) | |
| 131 } | |
| 132 | |
| 133 methods.search = function (doc_id, page_number, needle) { | |
| 134 let doc = document_map[doc_id] | |
| 135 let page = doc.loadPage(page_number) | |
| 136 const hits = page.search(needle) | |
| 137 let result = [] | |
| 138 for (let hit of hits) { | |
| 139 for (let quad of hit) { | |
| 140 const [ ulx, uly, urx, ury, llx, lly, lrx, lry ] = quad | |
| 141 result.push({ | |
| 142 x: ulx, | |
| 143 y: uly, | |
| 144 w: urx - ulx, | |
| 145 h: lly - uly, | |
| 146 }) | |
| 147 } | |
| 148 } | |
| 149 return result | |
| 150 } | |
| 151 | |
| 152 methods.getPageAnnotations = function (doc_id, page_number, dpi) { | |
| 153 let doc = document_map[doc_id] | |
| 154 let page = doc.loadPage(page_number) | |
| 155 | |
| 156 if (page == null) { | |
| 157 return [] | |
| 158 } | |
| 159 | |
| 160 const annotations = page.getAnnotations() | |
| 161 const doc_to_screen = [ dpi = 72, 0, 0, dpi / 72, 0, 0 ] | |
| 162 | |
| 163 return annotations.map((annotation) => { | |
| 164 const [ x0, y0, x1, y1 ] = mupdf.Matrix.transformRect(annotation.getBounds()) | |
| 165 return { | |
| 166 x: x0, | |
| 167 y: y0, | |
| 168 w: x1 - x0, | |
| 169 h: y1 - y0, | |
| 170 type: annotation.getType(), | |
| 171 ref: annotation.pointer, | |
| 172 } | |
| 173 }) | |
| 174 } | |
| 175 | |
| 176 methods.drawPageAsPixmap = function (doc_id, page_number, dpi) { | |
| 177 const doc_to_screen = mupdf.Matrix.scale(dpi / 72, dpi / 72) | |
| 178 | |
| 179 let doc = document_map[doc_id] | |
| 180 let page = doc.loadPage(page_number) | |
| 181 let bbox = mupdf.Rect.transform(page.getBounds(), doc_to_screen) | |
| 182 | |
| 183 let pixmap = new mupdf.Pixmap(mupdf.ColorSpace.DeviceRGB, bbox, true) | |
| 184 pixmap.clear(255) | |
| 185 | |
| 186 let device = new mupdf.DrawDevice(doc_to_screen, pixmap) | |
| 187 page.run(device, mupdf.Matrix.identity) | |
| 188 device.close() | |
| 189 | |
| 190 // TODO: do we need to make a copy with slice() ? | |
| 191 let imageData = new ImageData(pixmap.getPixels().slice(), pixmap.getWidth(), pixmap.getHeight()) | |
| 192 | |
| 193 pixmap.destroy() | |
| 194 | |
| 195 // TODO: do we need to pass image data as transferable to avoid copying? | |
| 196 return imageData | |
| 197 } | |
| 198 | |
| 199 postMessage([ "INIT", 0, Object.keys(methods) ]) |
