Treader-open/docs/epub-reader/lib/mupdf.js

2911 lines
67 KiB
JavaScript

// Copyright (C) 2004-2023 Artifex Software, Inc.
//
// This file is part of MuPDF WASM Library.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
// CA 94945, U.S.A., +1(415)492-9861, for further information.
"use strict"
var libmupdf
class TryLaterError extends Error {
constructor(message) {
super(message)
this.name = "TryLaterError"
}
}
const libmupdf_injections = {
fetchOpen,
fetchRead,
fetchClose,
TryLaterError,
}
// If running in Node.js environment
if (typeof require === "function")
libmupdf = require("./mupdf-wasm.js")(libmupdf_injections)
else
libmupdf = libmupdf(libmupdf_injections)
libmupdf._wasm_init_context()
// To pass Rect and Matrix as pointer arguments
var _wasm_point = libmupdf._wasm_malloc(4 * 4) >> 2
var _wasm_rect = libmupdf._wasm_malloc(4 * 8) >> 2
var _wasm_matrix = libmupdf._wasm_malloc(4 * 6) >> 2
var _wasm_color = libmupdf._wasm_malloc(4 * 4) >> 2
var _wasm_quad = libmupdf._wasm_malloc(4 * 8) >> 2
var _wasm_string = [ 0, 0 ]
function checkType(value, type) {
if (typeof type === "string" && typeof value !== type)
throw new TypeError("expected " + type)
if (typeof type === "function" && !(value instanceof type))
throw new TypeError("expected " + type.name)
}
function checkPoint(value) {
if (!Array.isArray(value) || value.length !== 2)
throw new TypeError("expected point")
}
function checkRect(value) {
if (!Array.isArray(value) || value.length !== 4)
throw new TypeError("expected rectangle")
}
function checkMatrix(value) {
if (!Array.isArray(value) || value.length !== 6)
throw new TypeError("expected matrix")
}
function checkQuad(value) {
if (!Array.isArray(value) || value.length !== 8)
throw new TypeError("expected quad")
}
function checkColor(value) {
if (!Array.isArray(value) || (value.length !== 1 && value.length !== 3 && value.length !== 4))
throw new TypeError("expected color array")
}
function toBuffer(input) {
if (input instanceof Buffer)
return input
if (input instanceof ArrayBuffer || input instanceof Uint8Array)
return new Buffer(input)
if (typeof input === "string")
return new Buffer(input)
throw new TypeError("expected buffer")
}
function toEnum(value, list) {
if (typeof value === "number") {
if (value >= 0 && value < list.length)
return value
}
if (typeof value === "string") {
let idx = list.indexOf(value)
if (idx >= 0)
return idx
}
throw new TypeError(`invalid enum value ("${value}"; expected ${list.join(", ")})`)
}
function allocateUTF8(str) {
var size = libmupdf.lengthBytesUTF8(str) + 1
var pointer = libmupdf._wasm_malloc(size)
libmupdf.stringToUTF8(str, pointer, size)
return pointer
}
function STRING_N(s,i) {
if (_wasm_string[i]) {
libmupdf._wasm_free(_wasm_string[i])
_wasm_string[i] = i
}
_wasm_string[i] = allocateUTF8(s)
return _wasm_string[i]
}
function STRING(s) {
return STRING_N(s, 0)
}
function STRING2(s) {
return STRING_N(s, 1)
}
function STRING_OPT(s) {
return typeof s === "string" ? STRING_N(s, 0) : 0
}
function STRING2_OPT(s) {
return typeof s === "string" ? STRING_N(s, 1) : 0
}
function POINT(p) {
libmupdf.HEAPF32[_wasm_point + 0] = p[0]
libmupdf.HEAPF32[_wasm_point + 1] = p[1]
return _wasm_point << 2
}
function POINT2(p) {
libmupdf.HEAPF32[_wasm_point + 2] = p[0]
libmupdf.HEAPF32[_wasm_point + 3] = p[1]
return (_wasm_point + 2) << 2
}
function RECT(r) {
libmupdf.HEAPF32[_wasm_rect + 0] = r[0]
libmupdf.HEAPF32[_wasm_rect + 1] = r[1]
libmupdf.HEAPF32[_wasm_rect + 2] = r[2]
libmupdf.HEAPF32[_wasm_rect + 3] = r[3]
return _wasm_rect << 2
}
function RECT2(r) {
libmupdf.HEAPF32[_wasm_rect + 4] = r[0]
libmupdf.HEAPF32[_wasm_rect + 5] = r[1]
libmupdf.HEAPF32[_wasm_rect + 6] = r[2]
libmupdf.HEAPF32[_wasm_rect + 7] = r[3]
return (_wasm_rect + 4) << 2
}
function MATRIX(m) {
libmupdf.HEAPF32[_wasm_matrix + 0] = m[0]
libmupdf.HEAPF32[_wasm_matrix + 1] = m[1]
libmupdf.HEAPF32[_wasm_matrix + 2] = m[2]
libmupdf.HEAPF32[_wasm_matrix + 3] = m[3]
libmupdf.HEAPF32[_wasm_matrix + 4] = m[4]
libmupdf.HEAPF32[_wasm_matrix + 5] = m[5]
return _wasm_matrix << 2
}
function QUAD(q) {
libmupdf.HEAPF32[_wasm_quad + 0] = q[0]
libmupdf.HEAPF32[_wasm_quad + 1] = q[1]
libmupdf.HEAPF32[_wasm_quad + 2] = q[2]
libmupdf.HEAPF32[_wasm_quad + 3] = q[3]
libmupdf.HEAPF32[_wasm_quad + 4] = q[4]
libmupdf.HEAPF32[_wasm_quad + 5] = q[5]
libmupdf.HEAPF32[_wasm_quad + 6] = q[6]
libmupdf.HEAPF32[_wasm_quad + 7] = q[7]
return _wasm_quad << 2
}
function COLOR(c) {
if (c) {
for (let i = 0; i < c.length && i < 4; ++i)
libmupdf.HEAPF32[_wasm_color + i] = c[i]
}
return _wasm_color << 2
}
function fromColor(n) {
let result = new Array(n)
for (let i = 0; i < n; ++i)
result[i] = libmupdf.HEAPF32[_wasm_color + i]
return result
}
function fromString(ptr) {
return libmupdf.UTF8ToString(ptr)
}
function fromStringFree(ptr) {
let str = libmupdf.UTF8ToString(ptr)
libmupdf._wasm_free(ptr)
return str
}
function fromPoint(ptr) {
ptr = ptr >> 2
return [
libmupdf.HEAPF32[ptr + 0],
libmupdf.HEAPF32[ptr + 1],
]
}
function fromRect(ptr) {
ptr = ptr >> 2
return [
libmupdf.HEAPF32[ptr + 0],
libmupdf.HEAPF32[ptr + 1],
libmupdf.HEAPF32[ptr + 2],
libmupdf.HEAPF32[ptr + 3],
]
}
function fromMatrix(ptr) {
ptr = ptr >> 2
return [
libmupdf.HEAPF32[ptr + 0],
libmupdf.HEAPF32[ptr + 1],
libmupdf.HEAPF32[ptr + 2],
libmupdf.HEAPF32[ptr + 3],
libmupdf.HEAPF32[ptr + 4],
libmupdf.HEAPF32[ptr + 5],
]
}
function fromQuad(ptr) {
ptr = ptr >> 2
return [
libmupdf.HEAPF32[ptr + 0],
libmupdf.HEAPF32[ptr + 1],
libmupdf.HEAPF32[ptr + 2],
libmupdf.HEAPF32[ptr + 3],
libmupdf.HEAPF32[ptr + 4],
libmupdf.HEAPF32[ptr + 5],
libmupdf.HEAPF32[ptr + 6],
libmupdf.HEAPF32[ptr + 7],
]
}
function fromBuffer(buf) {
let data = libmupdf._wasm_buffer_get_data(buf)
let size = libmupdf._wasm_buffer_get_len(buf)
return libmupdf.HEAPU8.slice(data, data + size)
}
function runSearch(searchFun, searchThis, needle, max_hits = 500) {
checkType(needle, "string")
let hits = 0
let marks = 0
try {
hits = libmupdf._wasm_malloc(32 * max_hits)
marks = libmupdf._wasm_malloc(4 * max_hits)
let n = searchFun(searchThis, STRING(needle), marks, hits, max_hits)
let outer = []
if (n > 0) {
let inner = []
for (let i = 0; i < n; ++i) {
let mark = libmupdf.HEAP32[(marks>>2) + i]
let quad = fromQuad(hits + i * 32)
if (i > 0 && mark) {
outer.push(inner)
inner = []
}
inner.push(quad)
}
outer.push(inner)
}
return outer
} finally {
libmupdf._wasm_free(marks)
libmupdf._wasm_free(hits)
}
}
const Matrix = {
identity: [ 1, 0, 0, 1, 0, 0 ],
scale(sx, sy) {
return [ sx, 0, 0, sy, 0, 0 ]
},
translate(tx, ty) {
return [ 1, 0, 0, 1, tx, ty ]
},
rotate(d) {
while (d < 0)
d += 360
while (d >= 360)
d -= 360
let s = Math.sin((d * Math.PI) / 180)
let c = Math.cos((d * Math.PI) / 180)
return [ c, s, -s, c, 0, 0 ]
},
invert(m) {
checkMatrix(m)
let det = m[0] * m[3] - m[1] * m[2]
if (det > -1e-23 && det < 1e-23)
return m
let rdet = 1 / det
let inva = m[3] * rdet
let invb = -m[1] * rdet
let invc = -m[2] * rdet
let invd = m[0] * rdet
let inve = -m[4] * inva - m[5] * invc
let invf = -m[4] * invb - m[5] * invd
return [ inva, invb, invc, invd, inve, invf ]
},
concat(one, two) {
checkMatrix(one)
checkMatrix(two)
return [
one[0] * two[0] + one[1] * two[2],
one[0] * two[1] + one[1] * two[3],
one[2] * two[0] + one[3] * two[2],
one[2] * two[1] + one[3] * two[3],
one[4] * two[0] + one[5] * two[2] + two[4],
one[4] * two[1] + one[5] * two[3] + two[5],
]
},
}
const Rect = {
MIN_INF_RECT: 0x80000000,
MAX_INF_RECT: 0x7fffff80,
isEmpty: function (rect) {
checkRect(rect)
return rect[0] >= rect[2] || rect[1] >= rect[3]
},
isValid: function (rect) {
checkRect(rect)
return rect[0] <= rect[2] && rect[1] <= rect[3]
},
isInfinite: function (rect) {
checkRect(rect)
return (
rect[0] === Rect.MIN_INF_RECT &&
rect[1] === Rect.MIN_INF_RECT &&
rect[2] === Rect.MAX_INF_RECT &&
rect[3] === Rect.MAX_INF_RECT
)
},
transform: function (rect, matrix) {
checkRect(rect)
checkMatrix(matrix)
var t
if (Rect.isInfinite(rect))
return rect
if (!Rect.isValid(rect))
return rect
var ax0 = rect[0] * matrix[0]
var ax1 = rect[2] * matrix[0]
if (ax0 > ax1)
t = ax0, ax0 = ax1, ax1 = t
var cy0 = rect[1] * matrix[2]
var cy1 = rect[3] * matrix[2]
if (cy0 > cy1)
t = cy0, cy0 = cy1, cy1 = t
ax0 += cy0 + matrix[4]
ax1 += cy1 + matrix[4]
var bx0 = rect[0] * matrix[1]
var bx1 = rect[2] * matrix[1]
if (bx0 > bx1)
t = bx0, bx0 = bx1, bx1 = t
var dy0 = rect[1] * matrix[3]
var dy1 = rect[3] * matrix[3]
if (dy0 > dy1)
t = dy0, dy0 = dy1, dy1 = t
bx0 += dy0 + matrix[5]
bx1 += dy1 + matrix[5]
return [ ax0, bx0, ax1, bx1 ]
},
}
class Userdata {
constructor(pointer) {
if (typeof pointer !== "number")
throw new Error("invalid pointer: " + typeof pointer)
if (!this.constructor._finalizer) {
this.constructor._drop = libmupdf[this.constructor._drop]
this.constructor._finalizer = new FinalizationRegistry(this.constructor._drop)
}
this.constructor._finalizer.register(this, pointer, this)
this.pointer = pointer
}
destroy() {
this.constructor._finalizer.unregister(this)
this.constructor._drop(this.pointer)
this.pointer = 0
}
// Custom "console.log" formatting for Node
[Symbol.for("nodejs.util.inspect.custom")]() {
return this.toString()
}
toString() {
return `[${this.constructor.name} ${this.pointer}]`
}
valueOf() {
return this.pointer
}
}
class Buffer extends Userdata {
static _drop = "_wasm_drop_buffer"
constructor(arg) {
let pointer = 0
if (typeof arg === "undefined") {
pointer = libmupdf._wasm_new_buffer(1024)
} else if (typeof arg === "number") {
pointer = arg
} else if (typeof arg === "string") {
let data_len = libmupdf.lengthBytesUTF8(arg)
let data_ptr = libmupdf._wasm_malloc(data_len + 1)
libmupdf.stringToUTF8(arg, data_ptr, data_len + 1)
pointer = libmupdf._wasm_new_buffer_from_data(data_ptr, data_len)
} else if (arg instanceof ArrayBuffer || arg instanceof Uint8Array) {
let data_len = arg.byteLength
let data_ptr = libmupdf._wasm_malloc(data_len)
libmupdf.HEAPU8.set(new Uint8Array(arg), data_ptr)
pointer = libmupdf._wasm_new_buffer_from_data(data_ptr, data_len)
}
super(pointer)
}
getLength() {
return libmupdf._wasm_buffer_get_len(this)
}
readByte(at) {
let data = libmupdf._wasm_buffer_get_data(this)
libmupdf.HEAPU8[data + at]
}
write(s) {
libmupdf._wasm_append_string(this, STRING(s))
}
writeByte(b) {
libmupdf._wasm_append_byte(this, b)
}
writeLine(s) {
this.write(s)
this.writeByte(10)
}
writeBuffer(other) {
if (!(other instanceof Buffer))
other = new Buffer(other)
libmupdf._wasm_append_buffer(this, other)
}
asUint8Array() {
let data = libmupdf._wasm_buffer_get_data(this)
let size = libmupdf._wasm_buffer_get_len(this)
return libmupdf.HEAPU8.subarray(data, data + size)
}
asString() {
return fromString(libmupdf._wasm_string_from_buffer(this))
}
}
class ColorSpace extends Userdata {
static _drop = "_wasm_drop_colorspace"
static TYPES = [
"None",
"Gray",
"RGB",
"BGR",
"CMYK",
"Lab",
"Indexed",
"Separation"
]
constructor(from, name) {
let pointer = from
if (from instanceof ArrayBuffer || from instanceof Uint8Array)
from = new Buffer(from)
if (from instanceof Buffer)
pointer = libmupdf._wasm_new_icc_colorspace(name, from)
super(pointer)
}
getName() {
return fromString(libmupdf._wasm_colorspace_get_name(this))
}
getType() {
return ColorSpace.TYPES[libmupdf._wasm_colorspace_get_type(this)]
}
getNumberOfComponents() {
return libmupdf._wasm_colorspace_get_n(this)
}
isGray() { return getType() === "Gray" }
isRGB() { return getType() === "RGB" }
isCMYK() { return getType() === "CMYK" }
isIndexed() { return getType() === "Indexed" }
isLab() { return getType() === "Lab" }
isDeviceN() { return getType() === "Separation" }
isSubtractive() { return getType() === "CMYK" || getType() === "Separation" }
toString() {
return "[ColorSpace " + this.getName() + "]"
}
}
ColorSpace.DeviceGray = new ColorSpace(libmupdf._wasm_device_gray())
ColorSpace.DeviceRGB = new ColorSpace(libmupdf._wasm_device_rgb())
ColorSpace.DeviceBGR = new ColorSpace(libmupdf._wasm_device_bgr())
ColorSpace.DeviceCMYK = new ColorSpace(libmupdf._wasm_device_cmyk())
ColorSpace.Lab = new ColorSpace(libmupdf._wasm_device_lab())
class Font extends Userdata {
static _drop = "_wasm_drop_font"
static ADOBE_CNS = 0
static ADOBE_GB = 1
static ADOBE_JAPAN = 2
static ADOBE_KOREA = 3
static CJK_ORDERING_BY_LANG = {
"Adobe-CNS1": 0,
"Adobe-GB1": 1,
"Adobe-Japan1": 2,
"Adobe-Korea1": 3,
"zh-Hant": 0,
"zh-TW": 0,
"zh-HK": 0,
"zh-Hans": 1,
"zh-CN": 1,
"ja": 2,
"ko": 3,
}
constructor(name_or_pointer, buffer=null, subfont=0) {
let pointer = 0
if (typeof name_or_pointer === "number") {
pointer = libmupdf._wasm_keep_font(name_or_pointer)
} else {
if (buffer)
pointer = libmupdf._wasm_new_font_from_buffer(STRING(name_or_pointer), toBuffer(buffer), subfont)
else
pointer = libmupdf._wasm_new_base14_font(STRING(name_or_pointer))
}
super(pointer)
}
getName() {
return fromString(libmupdf._wasm_font_get_name(this))
}
encodeCharacter(uni) {
if (typeof uni === "string")
uni = uni.charCodeAt(0)
return libmupdf._wasm_encode_character(this, uni)
}
advanceGlyph(gid, wmode = 0) {
return libmupdf._wasm_advance_glyph(this, gid, wmode)
}
}
class Image extends Userdata {
static _drop = "_wasm_drop_image"
constructor(arg1, arg2) {
let pointer = 0
if (typeof arg1 === "number")
pointer = libmupdf._wasm_keep_image(arg1)
else if (arg1 instanceof Pixmap)
pointer = libmupdf._wasm_new_image_from_pixmap(arg1, arg2)
else
pointer = libmupdf._wasm_new_image_from_buffer(toBuffer(arg1))
super(pointer)
}
getWidth() {
return libmupdf._wasm_image_get_w(this)
}
getHeight() {
return libmupdf._wasm_image_get_h(this)
}
getNumberOfComponents() {
return libmupdf._wasm_image_get_n(this)
}
getBitsPerComponent() {
return libmupdf._wasm_image_get_bpc(this)
}
getXResolution() {
return libmupdf._wasm_image_get_xres(this)
}
getYResolution() {
return libmupdf._wasm_image_get_yres(this)
}
getImageMask() {
return libmupdf._wasm_image_get_imagemask(this)
}
getColorSpace() {
let cs = libmupdf._wasm_image_get_colorspace(this)
if (cs)
return new ColorSpace(libmupdf._wasm_keep_colorspace(cs))
return null
}
getMask() {
let mask = libmupdf._wasm_image_get_mask(this)
if (mask)
return new Image(mask)
return null
}
toPixmap() {
return new Pixmap(libmupdf._wasm_pdf_get_pixmap_from_image(this))
}
}
class StrokeState extends Userdata {
static _drop = "_wasm_drop_stroke_state"
constructor(pointer) {
if (pointer === undefined)
pointer = libmupdf._wasm_new_stroke_state()
super(pointer)
}
getLineCap() {
return libmupdf._wasm_stroke_state_get_start_cap(this)
}
setLineCap(j) {
libmupdf._wasm_stroke_state_set_start_cap(this, j)
libmupdf._wasm_stroke_state_set_dash_cap(this, j)
libmupdf._wasm_stroke_state_set_end_cap(this, j)
}
setLineJoin(j) {
libmupdf._wasm_stroke_state_set_linejoin(this, j)
}
getLineJoin() {
return libmupdf._wasm_stroke_state_get_linejoin(this)
}
setLineWidth(w) {
libmupdf._wasm_stroke_state_set_linewidth(this, w)
}
getLineWidth(w) {
libmupdf._wasm_stroke_state_get_linewidth(this, w)
}
getMiterLimit() {
return libmupdf._wasm_stroke_state_get_miterlimit(this)
}
setMiterLimit(m) {
libmupdf._wasm_stroke_state_set_miterlimit(this, m)
}
// TODO: dashes
}
class Path extends Userdata {
static _drop = "_wasm_drop_path"
constructor(pointer) {
if (pointer === undefined)
pointer = libmupdf._wasm_new_path()
super(pointer)
}
getBounds(strokeState, transform) {
return fromRect(libmupdf._wasm_bound_path(this, strokeState, MATRIX(transform)))
}
moveTo(x, y) {
libmupdf._wasm_moveto(this, x, y)
}
lineTo(x, y) {
libmupdf._wasm_lineto(this, x, y)
}
curveTo(x1, y1, x2, y2, x3, y3) {
libmupdf._wasm_curveto(this, x1, y1, x2, y2, x3, y3)
}
curveToV(cx, cy, ex, ey) {
libmupdf._wasm_curvetov(this, cx, cy, ex, ey)
}
curveToY(cx, cy, ex, ey) {
libmupdf._wasm_curvetoy(this, cx, cy, ex, ey)
}
closePath() {
libmupdf._wasm_closepath(this)
}
rect(x1, y1, x2, y2) {
libmupdf._wasm_rectto(this, x1, y1, x2, y2)
}
transform(matrix) {
checkMatrix(matrix)
libmupdf._wasm_transform_path(this, MATRIX(matrix))
}
walk(walker) {
throw "TODO"
}
}
class Text extends Userdata {
static _drop = "_wasm_drop_text"
constructor(pointer) {
if (pointer === undefined)
pointer = libmupdf._wasm_new_text()
super(pointer)
}
getBounds(strokeState, transform) {
return fromRect(libmupdf._wasm_bound_text(this, strokeState, MATRIX(transform)))
}
showGlyph(font, trm, gid, uni, wmode = 0) {
checkType(font, Font)
checkMatrix(trm)
checkType(gid, "number")
checkType(uni, "number")
libmupdf._wasm_show_glyph(
this,
font,
MATRIX(trm),
gid,
uni,
wmode
)
}
showString(font, trm, str, wmode = 0) {
checkType(font, Font)
checkMatrix(trm)
checkType(str, "string")
let out_trm = fromMatrix(
libmupdf._wasm_show_string(
this,
font,
MATRIX(trm),
STRING(str),
wmode
)
)
trm[4] = out_trm[4]
trm[5] = out_trm[5]
}
walk(walker) {
throw "TODO"
}
}
class DisplayList extends Userdata {
static _drop = "_wasm_drop_display_list"
constructor(arg1) {
let pointer = 0
if (typeof arg1 === "number") {
pointer = arg1
} else {
checkRect(arg1)
pointer = libmupdf._wasm_new_display_list(RECT(arg1))
}
super(pointer)
}
getBounds() {
return fromRect(libmupdf._wasm_bound_display_list(this))
}
toPixmap(matrix, colorspace, alpha = false) {
checkMatrix(matrix)
checkType(colorspace, ColorSpace)
return new Pixmap(
libmupdf._wasm_new_pixmap_from_display_list(
this,
MATRIX(matrix),
colorspace,
alpha
)
)
}
toStructuredText() {
return new StructuredText(libmupdf._wasm_new_stext_page_from_display_list(this))
}
run(device, matrix) {
checkType(device, Device)
checkMatrix(matrix)
libmupdf._wasm_run_display_list(this, device, MATRIX(matrix))
}
search(needle, max_hits = 500) {
return runSearch(libmupdf._wasm_search_display_list, this, needle, max_hits)
}
}
class Pixmap extends Userdata {
static _drop = "_wasm_drop_pixmap"
constructor(arg1, bbox = null, alpha = false) {
let pointer = arg1
if (arg1 instanceof ColorSpace) {
checkRect(bbox)
pointer = libmupdf._wasm_new_pixmap_with_bbox(arg1, RECT(bbox), alpha)
}
super(pointer)
}
getBounds() {
let x = libmupdf._wasm_pixmap_get_x(this)
let y = libmupdf._wasm_pixmap_get_y(this)
let w = libmupdf._wasm_pixmap_get_w(this)
let h = libmupdf._wasm_pixmap_get_h(this)
return [ x, y, x + w, y + h ]
}
clear(value) {
if (typeof value === "undefined")
libmupdf._wasm_clear_pixmap(this)
else
libmupdf._wasm_clear_pixmap_with_value(this, value)
}
getWidth() {
return libmupdf._wasm_pixmap_get_w(this)
}
getHeight() {
return libmupdf._wasm_pixmap_get_h(this)
}
getX() {
return libmupdf._wasm_pixmap_get_x(this)
}
getY() {
return libmupdf._wasm_pixmap_get_y(this)
}
getStride() {
return libmupdf._wasm_pixmap_get_stride(this)
}
getNumberOfComponents() {
return libmupdf._wasm_pixmap_get_n(this)
}
getAlpha() {
return libmupdf._wasm_pixmap_get_alpha(this)
}
getXResolution() {
return libmupdf._wasm_pixmap_get_xres(this)
}
getYResolution() {
return libmupdf._wasm_pixmap_get_yres(this)
}
setResolution(x, y) {
libmupdf._wasm_pixmap_set_xres(this, x)
libmupdf._wasm_pixmap_set_yres(this, y)
}
getColorSpace() {
let cs = libmupdf._wasm_pixmap_get_colorspace(this)
if (cs)
return new ColorSpace(libmupdf._wasm_keep_colorspace(cs))
return null
}
getPixels() {
let s = libmupdf._wasm_pixmap_get_stride(this)
let h = libmupdf._wasm_pixmap_get_h(this)
let p = libmupdf._wasm_pixmap_get_samples(this)
return new Uint8ClampedArray(libmupdf.HEAPU8.buffer, p, s * h)
}
asPNG() {
let buf = libmupdf._wasm_new_buffer_from_pixmap_as_png(this)
try {
return fromBuffer(buf)
} finally {
libmupdf._wasm_drop_buffer(buf)
}
}
asPSD() {
let buf = libmupdf._wasm_new_buffer_from_pixmap_as_psd(this)
try {
return fromBuffer(buf)
} finally {
libmupdf._wasm_drop_buffer(buf)
}
}
asPAM() {
let buf = libmupdf._wasm_new_buffer_from_pixmap_as_pam(this)
try {
return fromBuffer(buf)
} finally {
libmupdf._wasm_drop_buffer(buf)
}
}
asJPEG(quality) {
let buf = libmupdf._wasm_new_buffer_from_pixmap_as_jpeg(this, quality)
try {
return fromBuffer(buf)
} finally {
libmupdf._wasm_drop_buffer(buf)
}
}
invert() {
libmupdf._wasm_invert_pixmap(this)
}
invertLuminance() {
libmupdf._wasm_invert_pixmap_luminance(this)
}
gamma(p) {
libmupdf._wasm_gamma_pixmap(this, p)
}
tint(black, white) {
if (black instanceof Array)
black = ( ( (black[0] * 255) << 16 ) | ( (black[1] * 255) << 8 ) | ( (black[2] * 255) ) )
if (white instanceof Array)
white = ( ( (white[0] * 255) << 16 ) | ( (white[1] * 255) << 8 ) | ( (white[2] * 255) ) )
libmupdf._wasm_tint_pixmap(this, black, white)
}
}
class Shade extends Userdata {
static _drop = "_wasm_drop_shade"
constructor(pointer) {
super(pointer)
}
getBounds() {
return fromRect(libmupdf._wasm_bound_shade(this))
}
}
class StructuredText extends Userdata {
static _drop = "_wasm_drop_stext_page"
static SELECT_CHARS = 0
static SELECT_WORDS = 1
static SELECT_LINES = 2
walk(walker) {
let block = libmupdf._wasm_stext_page_get_first_block(this)
while (block) {
let block_type = libmupdf._wasm_stext_block_get_type(block)
let block_bbox = fromRect(libmupdf._wasm_stext_block_get_bbox(block))
if (block_type === 1) {
if (walker.onImageBlock) {
let matrix = fromMatrix(libmupdf._wasm_stext_block_get_transform(block))
let image = new Image(libmupdf._wasm_stext_block_get_image(block))
walker.onImageBlock(block_bbox, matrix, image)
}
} else {
if (walker.beginTextBlock)
walker.beginTextBlock(block_bbox)
let line = libmupdf._wasm_stext_block_get_first_line(block)
while (line) {
let line_bbox = fromRect(libmupdf._wasm_stext_line_get_bbox(line))
let line_wmode = libmupdf._wasm_stext_line_get_wmode(line)
let line_dir = fromPoint(libmupdf._wasm_stext_line_get_dir(line))
if (walker.beginLine)
walker.beginLine(line_bbox, line_wmode, line_dir)
if (walker.onChar) {
let ch = libmupdf._wasm_stext_line_get_first_char(line)
while (ch) {
let ch_rune = String.fromCharCode(libmupdf._wasm_stext_char_get_c(ch))
let ch_origin = fromPoint(libmupdf._wasm_stext_char_get_origin(ch))
let ch_font = new Font(libmupdf._wasm_stext_char_get_font(ch))
let ch_size = libmupdf._wasm_stext_char_get_size(ch)
let ch_quad = fromQuad(libmupdf._wasm_stext_char_get_quad(ch))
walker.onChar(ch_rune, ch_origin, ch_font, ch_size, ch_quad)
ch = libmupdf._wasm_stext_char_get_next(ch)
}
}
if (walker.endLine)
walker.endLine()
line = libmupdf._wasm_stext_line_get_next(line)
}
if (walker.endTextBlock)
walker.endTextBlock()
}
block = libmupdf._wasm_stext_block_get_next(block)
}
}
asJSON(scale = 1) {
return fromStringFree(libmupdf._wasm_print_stext_page_as_json(this, scale))
}
// TODO: highlight(a, b) -> quad[]
// TODO: copy(a, b) -> string
search(needle, max_hits = 500) {
return runSearch(libmupdf._wasm_search_stext_page, this, needle, max_hits)
}
}
class Device extends Userdata {
static _drop = "_wasm_drop_device"
static BLEND_MODES = [
"Normal",
"Multiply",
"Screen",
"Overlay",
"Darken",
"Lighten",
"ColorDodge",
"ColorBurn",
"HardLight",
"SoftLight",
"Difference",
"Exclusion",
"Hue",
"Saturation",
"Color",
"Luminosity",
]
fillPath(path, evenOdd, ctm, colorspace, color, alpha) {
checkType(path, Path)
checkMatrix(ctm)
checkType(colorspace, ColorSpace)
checkColor(color)
libmupdf._wasm_fill_path(this, path, evenOdd, MATRIX(ctm), colorspace, COLOR(color), alpha)
}
strokePath(path, stroke, ctm, colorspace, color, alpha) {
checkType(path, Path)
checkType(stroke, StrokeState)
checkMatrix(ctm)
checkType(colorspace, ColorSpace)
checkColor(color)
libmupdf._wasm_stroke_path(
this,
path,
stroke,
MATRIX(ctm),
colorspace,
COLOR(color),
alpha
)
}
clipPath(path, evenOdd, ctm) {
checkType(path, Path)
checkMatrix(ctm)
libmupdf._wasm_clip_path(this, path, evenOdd, MATRIX(ctm))
}
clipStrokePath(path, stroke, ctm) {
checkType(path, Path)
checkType(stroke, StrokeState)
checkMatrix(ctm)
libmupdf._wasm_clip_stroke_path(this, path, stroke, MATRIX(ctm))
}
fillText(text, ctm, colorspace, color, alpha) {
checkType(text, Text)
checkMatrix(ctm)
checkType(colorspace, ColorSpace)
checkColor(color)
libmupdf._wasm_fill_text(this, text, MATRIX(ctm), colorspace, COLOR(color), alpha)
}
strokeText(text, stroke, ctm, colorspace, color, alpha) {
checkType(text, Text)
checkType(stroke, StrokeState)
checkMatrix(ctm)
checkType(colorspace, ColorSpace)
checkColor(color)
libmupdf._wasm_stroke_text(
this,
text,
stroke,
MATRIX(ctm),
colorspace,
COLOR(color),
alpha
)
}
clipText(text, ctm) {
checkType(text, Text)
checkMatrix(ctm)
libmupdf._wasm_clip_text(this, text, MATRIX(ctm))
}
clipStrokeText(text, stroke, ctm) {
checkType(text, Text)
checkType(stroke, StrokeState)
checkMatrix(ctm)
libmupdf._wasm_clip_stroke_text(this, text, stroke, MATRIX(ctm))
}
ignoreText(text, ctm) {
checkType(text, Text)
checkMatrix(ctm)
libmupdf._wasm_ignore_text(this, text, MATRIX(ctm))
}
fillShade(shade, ctm, alpha) {
checkType(shade, Shade)
checkMatrix(ctm)
libmupdf._wasm_fill_shade(this, shade, MATRIX(ctm), alpha)
}
fillImage(image, ctm, alpha) {
checkType(image, Image)
checkMatrix(ctm)
libmupdf._wasm_fill_image(this, image, MATRIX(ctm), alpha)
}
fillImageMask(image, ctm, colorspace, color, alpha) {
checkType(image, Image)
checkMatrix(ctm)
checkType(colorspace, ColorSpace)
checkColor(color)
libmupdf._wasm_fill_image_mask(this, image, MATRIX(ctm), colorspace, COLOR(color), alpha)
}
clipImageMask(image, ctm) {
checkType(image, Image)
checkMatrix(ctm)
libmupdf._wasm_clip_image_mask(this, image, MATRIX(ctm))
}
popClip() {
libmupdf._wasm_pop_clip(this)
}
beginMask(area, luminosity, colorspace, color) {
checkRect(area)
checkType(colorspace, ColorSpace)
checkColor(color)
libmupdf._wasm_begin_mask(this, RECT(area), luminosity, colorspace, COLOR(color))
}
endMask() {
libmupdf._wasm_end_mask(this)
}
beginGroup(area, colorspace, isolated, knockout, blendmode, alpha) {
checkRect(area)
checkType(colorspace, ColorSpace)
blendmode = toEnum(blendmode, Device.BLEND_MODES)
libmupdf._wasm_begin_group(this, RECT(area), colorspace, isolated, knockout, blendmode, alpha)
}
endGroup() {
libmupdf._wasm_end_group(this)
}
beginTile(area, view, xstep, ystep, ctm, id) {
checkRect(area)
checkRect(view)
checkMatrix(ctm)
return libmupdf._wasm_begin_tile(this, RECT(area), RECT2(view), xstep, ystep, MATRIX(ctm), id)
}
endTile() {
libmupdf._wasm_end_tile(this)
}
beginLayer(name) {
libmupdf._wasm_begin_layer(this, STRING(name))
}
endLayer() {
libmupdf._wasm_end_layer(this)
}
close() {
libmupdf._wasm_close_device(this)
}
}
class DrawDevice extends Device {
constructor(matrix, pixmap) {
checkMatrix(matrix)
checkType(pixmap, Pixmap)
super(libmupdf._wasm_new_draw_device(MATRIX(matrix), pixmap))
}
}
class DisplayListDevice extends Device {
constructor(displayList) {
checkType(displayList, DisplayList)
super(
libmupdf._wasm_new_display_list_device(displayList)
)
}
}
// === DocumentWriter ===
class DocumentWriter extends Userdata {
static _drop = "_wasm_drop_document_writer"
constructor(buffer, format, options) {
buffer = toBuffer(buffer)
super(
libmupdf._wasm_new_document_writer_with_buffer(
buffer,
STRING(format),
STRING(options)
)
)
}
beginPage(mediabox) {
checkRect(mediabox)
return new Device(libmupdf._wasm_begin_page(this, RECT(mediabox)))
}
endPage() {
libmupdf._wasm_end_page(this)
}
close() {
libmupdf._wasm_close_document_writer(this)
}
}
// === Document ===
class Document extends Userdata {
static _drop = "_wasm_drop_document"
static META_FORMAT = "format"
static META_ENCRYPTION = "encryption"
static META_INFO_AUTHOR = "info:Author"
static META_INFO_TITLE = "info:Title"
static META_INFO_SUBJECT = "info:Subject"
static META_INFO_KEYWORDS = "info:Keywords"
static META_INFO_CREATOR = "info:Creator"
static META_INFO_PRODUCER = "info:Producer"
static META_INFO_CREATIONDATE = "info:CreationDate"
static META_INFO_MODIFICATIONDATE = "info:ModDate"
static PERMISSION = {
"print": "p".charCodeAt(0),
"copy": "c".charCodeAt(0),
"edit": "e".charCodeAt(0),
"annotate": "n".charCodeAt(0),
"form": "f".charCodeAt(0),
"accessibility": "y".charCodeAt(0),
"assemble": "a".charCodeAt(0),
"print-hq": "h".charCodeAt(0),
}
static LINK_DEST = [
"Fit",
"FitB",
"FitH",
"FitBH",
"FitV",
"FitBV",
"FitR",
"XYZ",
]
static openDocument(from, magic) {
checkType(magic, "string")
let pointer = 0
libmupdf._wasm_set_user_css(STRING(
"@page{margin:1.5em !important;} body{display:block; padding:0 !important; margin:0 !important;}"
))
if (from instanceof ArrayBuffer || from instanceof Uint8Array)
from = new Buffer(from)
if (from instanceof Buffer)
pointer = libmupdf._wasm_open_document_with_buffer(STRING(magic), from)
else if (from instanceof Stream)
pointer = libmupdf._wasm_open_document_with_stream(STRING(magic), from)
else
throw new Error("not a Buffer or Stream")
let pdf_ptr = libmupdf._wasm_pdf_document_from_fz_document(pointer)
if (pdf_ptr)
return new PDFDocument(pointer)
return new Document(pointer)
}
formatLinkURI(dest) {
return fromStringFree(
libmupdf._wasm_format_link_uri(this,
dest.chapter | 0,
dest.page | 0,
toEnum(dest.type, Document.LINK_DEST),
+dest.x,
+dest.y,
+dest.width,
+dest.height,
+dest.zoom
)
)
}
isPDF() {
return false
}
needsPassword() {
return libmupdf._wasm_needs_password(this)
}
authenticatePassword(password) {
return libmupdf._wasm_authenticate_password(this, STRING(password))
}
hasPermission(flag) {
if (!Document.PERMISSION[flag])
throw new Error("invalid permission flag: " + flag)
return libmupdf._wasm_has_permission(this, Document.PERMISSION[flag])
}
getMetaData(key) {
let value = libmupdf._wasm_lookup_metadata(this, STRING(key))
if (value)
return fromString(value)
return undefined
}
setMetaData(key, value) {
key = allocateUTF8(key)
value = allocateUTF8(value)
try {
libmupdf._wasm_set_metadata(this, key, value)
} finally {
libmupdf._wasm_free(value)
libmupdf._wasm_free(key)
}
}
countPages() {
return libmupdf._wasm_count_pages(this)
}
isReflowable() {
// TODO: No HTML/EPUB support in WASM.
return false
}
layout(w, h, em) {
libmupdf._wasm_layout_document(this, w, h, em)
}
userCSS(css){
libmupdf._wasm_set_user_css(this, css)
}
loadPage(index) {
let fz_ptr = libmupdf._wasm_load_page(this, index)
let pdf_ptr = libmupdf._wasm_pdf_page_from_fz_page(fz_ptr)
if (pdf_ptr)
return new PDFPage(this, pdf_ptr)
return new Page(fz_ptr)
}
loadOutline() {
let doc = this
function to_outline(outline) {
let result = []
while (outline) {
let item = {}
let title = libmupdf._wasm_outline_get_title(outline)
if (title)
item.title = fromString(title)
let uri = libmupdf._wasm_outline_get_uri(outline)
if (uri)
item.uri = fromString(uri)
let page = libmupdf._wasm_outline_get_page(doc, outline)
if (page >= 0){
item.page = page
}else{
item.page = libmupdf._wasm_resolve_link(doc, uri)
}
let down = libmupdf._wasm_outline_get_down(outline)
if (down)
item.down = to_outline(down)
result.push(item)
outline = libmupdf._wasm_outline_get_next(outline)
}
return result
}
let root = libmupdf._wasm_load_outline(this)
if (root)
return to_outline(root)
return null
}
resolveLink(link) {
if (link instanceof Link) {
return libmupdf._wasm_resolve_link(this, libmupdf._wasm_link_get_uri(link))
}
return libmupdf._wasm_resolve_link(this, STRING(link))
}
outlineIterator() {
return new OutlineIterator(libmupdf._wasm_new_outline_iterator(this))
}
}
class OutlineIterator extends Userdata {
static _drop = "_wasm_drop_outline_iterator"
item() {
let item = libmupdf._wasm_outline_iterator_item(this)
if (item) {
let title_ptr = "SAdf"// libmupdf._wasm_outline_item_get_title(item)
let uri_ptr = libmupdf._wasm_outline_item_get_uri(item)
let is_open = libmupdf._wasm_outline_item_get_is_open(item)
return {
title: title_ptr ? fromString(title_ptr) : null,
uri: uri_ptr ? fromString(uri_ptr) : null,
open: !!is_open
}
}
return null
}
next() {
return libmupdf._wasm_outline_iterator_next(this)
}
prev() {
return libmupdf._wasm_outline_iterator_prev(this)
}
up() {
return libmupdf._wasm_outline_iterator_up(this)
}
down() {
return libmupdf._wasm_outline_iterator_down(this)
}
delete() {
return libmupdf._wasm_outline_iterator_delete(this)
}
insert(item) {
return libmupdf._wasm_outline_insert(this, STRING_OPT(item.title), STRING2_OPT(item.uri), item.open)
}
update(item) {
libmupdf._wasm_outline_update(this, STRING_OPT(item.title), STRING2_OPT(item.uri), item.open)
}
}
class Link extends Userdata {
static _drop = "_wasm_drop_link"
getBounds() {
return fromRect(libmupdf._wasm_link_get_rect(this))
}
getURI() {
return fromString(libmupdf._wasm_link_get_uri(this))
}
isExternal() {
return /^\w[\w+-.]*:/.test(this.getURI())
}
}
class Page extends Userdata {
static _drop = "_wasm_drop_page"
isPDF() {
return false
}
getBounds() {
return fromRect(libmupdf._wasm_bound_page(this))
}
getLabel() {
return fromString(libmupdf._wasm_page_label(this))
}
run(device, matrix) {
checkType(device, Device)
checkMatrix(matrix)
libmupdf._wasm_run_page(this, device, MATRIX(matrix))
}
runPageContents(device, matrix) {
checkType(device, Device)
checkMatrix(matrix)
libmupdf._wasm_run_page_contents(this, device, MATRIX(matrix))
}
runPageAnnots(device, matrix) {
checkType(device, Device)
checkMatrix(matrix)
libmupdf._wasm_run_page_annots(this, device, MATRIX(matrix))
}
runPageWidgets(device, matrix) {
checkType(device, Device)
checkMatrix(matrix)
libmupdf._wasm_run_page_widgets(this, device, MATRIX(matrix))
}
toPixmap(matrix, colorspace, alpha = false, showExtras = true) {
checkType(colorspace, ColorSpace)
checkMatrix(matrix)
let result
if (showExtras)
result = libmupdf._wasm_new_pixmap_from_page(this,
MATRIX(matrix),
colorspace,
alpha)
else
result = libmupdf._wasm_new_pixmap_from_page_contents(this,
MATRIX(matrix),
colorspace,
alpha)
return new Pixmap(result)
}
toDisplayList(showExtras = true) {
let result
if (showExtras)
result = libmupdf._wasm_new_display_list_from_page(this)
else
result = libmupdf._wasm_new_display_list_from_page_contents(this)
return new DisplayList(result)
}
toStructuredText(options) {
// TODO: parse options
return new StructuredText(libmupdf._wasm_new_stext_page_from_page(this))
}
getLinks() {
let links = []
let link = libmupdf._wasm_load_links(this)
while (link) {
links.push(new Link(libmupdf._wasm_keep_link(link)))
link = libmupdf._wasm_link_get_next(link)
}
return links
}
createLink(bbox, uri) {
checkRect(bbox)
return new Link(libmupdf._wasm_create_link(this, RECT(bbox), STRING(uri)))
}
deleteLink(link) {
checkType(link, Link)
libmupdf._wasm_delete_link(this, link)
}
search(needle, max_hits = 500) {
return runSearch(libmupdf._wasm_search_page, this, needle, max_hits)
}
}
// === PDFDocument ===
class PDFDocument extends Document {
constructor(pointer) {
if (!pointer)
pointer = libmupdf._wasm_pdf_create_document()
super(pointer)
}
isPDF() {
return true
}
getVersion() {
return libmupdf._wasm_pdf_version(this)
}
getLanguage() {
return fromString(libmupdf._wasm_pdf_document_language(this))
}
setLanguage(lang) {
libmupdf._wasm_pdf_set_document_language(this, STRING(lang))
}
countObjects() {
return libmupdf._wasm_pdf_xref_len(this)
}
getTrailer() {
return new PDFObject(this, libmupdf._wasm_pdf_trailer(this))
}
createObject() {
let num = libmupdf._wasm_pdf_create_object(this)
return fromPDFObject(this, libmupdf._wasm_pdf_new_indirect(this, num))
}
newNull() { return PDFObject.Null }
newBool(v) { return fromPDFObject(this, libmupdf._wasm_pdf_new_bool(v)) }
newInteger(v) { return fromPDFObject(this, libmupdf._wasm_pdf_new_int(v)) }
newReal(v) { return fromPDFObject(this, libmupdf._wasm_pdf_new_real(v)) }
newName(v) { return fromPDFObject(this, libmupdf._wasm_pdf_new_name(STRING(v))) }
newString(v) { return fromPDFObject(this, libmupdf._wasm_pdf_new_text_string(STRING(v))) }
newIndirect(v) { return fromPDFObject(this, libmupdf._wasm_pdf_new_indirect(this, v)) }
newArray(cap=8) { return fromPDFObject(this, libmupdf._wasm_pdf_new_array(this, cap)) }
newDictionary(cap=8) { return fromPDFObject(this, libmupdf._wasm_pdf_new_dict(this, cap)) }
deleteObject(num) {
if (num instanceof PDFObject)
num = num.asIndirect()
else
checkType(num, "number")
libmupdf._wasm_pdf_delete_object(this, num)
}
addObject(obj) {
obj = PDFOBJ(this, obj)
return fromPDFObject(this, libmupdf._wasm_pdf_add_object(this, obj))
}
addStream(buf, obj) {
obj = PDFOBJ(this, obj)
buf = toBuffer(buf)
libmupdf._wasm_pdf_add_stream(this, buf, obj, 0)
}
addRawStream(buf, obj) {
obj = PDFOBJ(this, obj)
buf = toBuffer(buf)
libmupdf._wasm_pdf_add_stream(this, buf, obj, 1)
}
addSimpleFont(font, encoding) {
checkType(font, Font)
if (encoding === "Latin" || encoding === "Latn") encoding = 0
else if (encoding === "Greek" || encoding === "Grek") encoding = 1
else if (encoding === "Cyrillic" || encoding === "Cyrl") encoding = 2
else encoding = 0
return fromPDFObject(this, libmupdf._wasm_pdf_add_simple_font(this, font, encoding))
}
addCJKFont(font, lang, wmode, serif) {
checkType(font, Font)
if (typeof lang === "string")
lang = Font.CJK_ORDERING_BY_LANG[lang]
return fromPDFObject(this, libmupdf._wasm_pdf_add_cjk_font(this, font, lang, wmode, serif))
}
addFont(font) {
checkType(font, Font)
return fromPDFObject(this, libmupdf._wasm_pdf_add_font(this, font))
}
addImage(image) {
checkType(image, Image)
return fromPDFObject(this, libmupdf._wasm_pdf_add_image(this, image))
}
loadImage(ref) {
checkType(ref, PDFObject)
return new Image(libmupdf._wasm_pdf_load_image(this, ref))
}
findPage(index) {
checkType(index, "number")
return fromPDFObject(this, libmupdf._wasm_pdf_lookup_page_obj(this, index))
}
addPage(mediabox, rotate, resources, contents) {
resources = PDFOBJ(this, resources)
checkRect(mediabox)
checkType(rotate, "number")
contents = toBuffer(contents)
return fromPDFObject(
this,
libmupdf._wasm_pdf_add_page(
this,
RECT(mediabox),
rotate,
resources,
contents
)
)
}
insertPage(at, obj) {
obj = PDFOBJ(this, obj)
checkType(at, "number")
libmupdf._wasm_pdf_insert_page(this, at, obj)
}
deletePage(at) {
checkType(at, "number")
libmupdf._wasm_pdf_delete_page(this, at)
}
isEmbeddedFile(ref) {
checkType(ref, PDFObject)
return libmupdf._wasm_pdf_is_embedded_file(ref)
}
addEmbeddedFile(filename, mimetype, contents, created, modified, checksum = false) {
checkType(filename, "string")
checkType(mimetype, "string")
contents = toBuffer(contents)
checkType(created, Date)
checkType(modified, Date)
checkType(checksum, "boolean")
return fromPDFObject(
this,
libmupdf._wasm_pdf_add_embedded_file(
this,
STRING(filename),
STRING2(mimetype),
contents,
created.getTime() / 1000 | 0,
modified.getTime() / 1000 | 0,
checksum
)
)
}
getEmbeddedFileParams(ref) {
checkType(ref, PDFObject)
let ptr = libmupdf._wasm_pdf_get_embedded_file_params(ref)
return {
filename:
fromString(libmupdf._wasm_pdf_embedded_file_params_get_filename(ptr)),
mimetype:
fromString(libmupdf._wasm_pdf_embedded_file_params_get_mimetype(ptr)),
size:
libmupdf._wasm_pdf_embedded_file_params_get_filename(ptr),
creationDate:
new Date(libmupdf._wasm_pdf_embedded_file_params_get_created(ptr) * 1000),
modificationDate:
new Date(libmupdf._wasm_pdf_embedded_file_params_get_modified(ptr) * 1000),
}
}
getEmbeddedFileContents(ref) {
checkType(ref, PDFObject)
let contents = libmupdf._wasm_pdf_load_embedded_file_contents(ref)
if (contents)
return new Buffer(contents)
return null
}
getEmbeddedFiles() {
function _getEmbeddedFilesRec(result, N) {
var i, n
if (N) {
var NN = N.get("Names")
if (NN)
for (i = 0, n = NN.length; i < n; i += 2)
result[NN.get(i+0).asString()] = NN.get(i+1)
var NK = N.get("Kids")
if (NK)
for (i = 0, n = NK.length; i < n; i += 1)
_getEmbeddedFilesRec(result, NK.get(i))
}
return result
}
return _getEmbeddedFilesRec({}, this.getTrailer().get("Root", "Names", "EmbeddedFiles"))
}
saveToBuffer(options) {
checkType(options, "string")
// TODO: object options to string options?
return new Buffer(libmupdf._wasm_pdf_write_document_buffer(this, STRING(options)))
}
static PAGE_LABEL_NONE = "\0"
static PAGE_LABEL_DECIMAL = "D"
static PAGE_LABEL_ROMAN_UC = "R"
static PAGE_LABEL_ROMAN_LC = "r"
static PAGE_LABEL_ALPHA_UC = "A"
static PAGE_LABEL_ALPHA_LC = "a"
setPageLabels(index, style = "D", prefix = "", start = 1) {
libmupdf._wasm_pdf_set_page_labels(this, index, style.charCodeAt(0), STRING(prefix), start)
}
deletePageLabels(index) {
libmupdf._wasm_pdf_delete_page_labels(this, index)
}
wasRepaired() {
return libmupdf._wasm_pdf_was_repaired(this)
}
hasUnsavedChanges() {
return libmupdf._wasm_pdf_has_unsaved_changes(this)
}
countVersions() {
return libmupdf._wasm_pdf_count_versions(this)
}
countUnsavedVersions() {
return libmupdf._wasm_pdf_count_unsaved_versions(this)
}
validateChangeHistory() {
return libmupdf._wasm_pdf_validate_change_history(this)
}
canBeSavedIncrementally() {
return libmupdf._wasm_pdf_can_be_saved_incrementally(this)
}
enableJournal() {
libmupdf._wasm_pdf_enable_journal(this)
}
getJournal() {
let position = libmupdf._wasm_pdf_undoredo_state_position(this)
let n = libmupdf._wasm_pdf_undoredo_state_count(this)
let steps = []
for (let i = 0; i < n; ++i)
steps.push(
fromString(
libmupdf._wasm_pdf_undoredo_step(this, i),
)
)
return { position, steps }
}
beginOperation(op) {
libmupdf._wasm_pdf_begin_operation(this, STRING(op))
}
beginImplicitOperation() {
libmupdf._wasm_pdf_begin_implicit_operation(this)
}
endOperation() {
libmupdf._wasm_pdf_end_operation(this)
}
canUndo() {
return libmupdf._wasm_pdf_can_undo(this)
}
canRedo() {
return libmupdf._wasm_pdf_can_redo(this)
}
undo() {
libmupdf._wasm_pdf_undo(this)
}
redo() {
libmupdf._wasm_pdf_redo(this)
}
}
class PDFPage extends Page {
constructor(doc, pointer) {
super(pointer)
this._doc = doc
this._annots = null
}
static BOXES = [
"MediaBox",
"CropBox",
"BleedBox",
"TrimBox",
"ArtBox"
]
isPDF() {
return true
}
toPixmap(matrix, colorspace, alpha = false, showExtras = true, usage = "View", box = "MediaBox") {
checkType(colorspace, ColorSpace)
checkMatrix(matrix)
box = toEnum(box, PDFPage.BOXES)
let result
if (showExtras)
result = libmupdf._wasm_pdf_new_pixmap_from_page_with_usage(this,
MATRIX(matrix),
colorspace,
alpha,
STRING(usage),
box)
else
result = libmupdf._wasm_pdf_new_pixmap_from_page_contents_with_usage(this,
MATRIX(matrix),
colorspace,
alpha,
STRING(usage),
box)
return new Pixmap(result)
}
getWidgets() {
let list = []
let widget = libmupdf._wasm_pdf_first_widget(this)
while (widget) {
list.push(new PDFWidget(this._doc, libmupdf._wasm_pdf_keep_annot(widget)))
widget = libmupdf._wasm_pdf_next_widget(widget)
}
return list
}
getAnnotations() {
if (!this._annots) {
this._annots = []
let annot = libmupdf._wasm_pdf_first_annot(this)
while (annot) {
this._annots.push(new PDFAnnotation(this._doc, libmupdf._wasm_pdf_keep_annot(annot)))
annot = libmupdf._wasm_pdf_next_annot(annot)
}
}
return this._annots
}
createAnnotation(type) {
type = toEnum(type, PDFAnnotation.TYPES)
let annot = new PDFAnnotation(this._doc, libmupdf._wasm_pdf_create_annot(this, type))
if (this._annots)
this._annots.push(annot)
return annot
}
deleteAnnotation(annot) {
checkType(annot, PDFAnnotation)
libmupdf._wasm_pdf_delete_annot(this, annot)
if (this._annots) {
let ix = this._annots.indexOf(annot)
if (ix >= 0)
this._annots.splice(ix, 1)
}
}
static REDACT_IMAGE_NONE = 0
static REDACT_IMAGE_REMOVE = 1
static REDACT_IMAGE_PIXELS = 2
applyRedactions(black_boxes = 1, image_method = 2) {
libmupdf._wasm_pdf_redact_page(this, black_boxes, image_method)
}
update() {
return !!libmupdf._wasm_pdf_update_page(this)
}
}
function fromPDFObject(doc, ptr) {
if (ptr === 0)
return PDFObject.Null
return new PDFObject(doc, ptr)
}
function keepPDFObject(doc, ptr) {
return new PDFObject(doc, libmupdf._wasm_pdf_keep_obj(ptr))
}
function PDFOBJ(doc, obj) {
if (obj instanceof PDFObject)
return obj
if (obj === null || obj === undefined)
return doc.newNull()
if (typeof obj === "string")
return doc.newString(obj)
if (typeof obj === "number")
return obj | (0 === obj) ? doc.newInteger(obj) : doc.newReal(obj)
if (typeof obj === "boolean")
return doc.newBool(obj)
if (obj instanceof Array) {
let result = doc.newArray(obj.length)
for (let item of obj)
result.push(PDFOBJ(doc, item))
return result
}
if (obj instanceof Object) {
let result = doc.newDictionary()
for (let key in obj)
result.put(key, PDFOBJ(doc, obj[key]))
return result
}
throw new TypeError("cannot convert value to PDFObject")
}
class PDFObject extends Userdata {
static _drop = "_wasm_pdf_drop_obj"
constructor(doc, pointer) {
super(libmupdf._wasm_pdf_keep_obj(pointer))
this._doc = doc
}
isNull() { return this === PDFObject.Null }
isIndirect() { return libmupdf._wasm_pdf_is_indirect(this) }
isBoolean() { return libmupdf._wasm_pdf_is_bool(this) }
isInteger() { return libmupdf._wasm_pdf_is_int(this) }
isNumber() { return libmupdf._wasm_pdf_is_number(this) }
isName() { return libmupdf._wasm_pdf_is_name(this) }
isString() { return libmupdf._wasm_pdf_is_string(this) }
isArray() { return libmupdf._wasm_pdf_is_array(this) }
isDictionary() { return libmupdf._wasm_pdf_is_dict(this) }
isStream() { return libmupdf._wasm_pdf_is_stream(this) }
asIndirect() { return libmupdf._wasm_pdf_to_num(this) }
asBoolean() { return libmupdf._wasm_pdf_to_bool(this) }
asNumber() { return libmupdf._wasm_pdf_to_number(this) }
asName() { return fromString(libmupdf._wasm_pdf_to_name(this)) }
asString() { return fromString(libmupdf._wasm_pdf_to_text_string(this)) }
readStream() { return new Buffer(libmupdf._wasm_pdf_load_stream(this)) }
readRawStream() { return new Buffer(libmupdf._wasm_pdf_load_raw_stream(this)) }
resolve() {
return fromPDFObject(this, libmupdf._wasm_pdf_resolve_indirect(this))
}
get length() {
return libmupdf._wasm_pdf_array_len(this)
}
_get(path) {
let obj = this.pointer
for (let key of path) {
if (typeof key === "number")
obj = libmupdf._wasm_pdf_array_get(obj, key)
else if (typeof key === PDFObject)
obj = libmupdf._wasm_pdf_dict_get(obj, key.pointer)
else
obj = libmupdf._wasm_pdf_dict_gets(obj, STRING(key))
if (obj === 0)
break
}
return obj
}
get(...path) { return fromPDFObject(this, this._get(path)) }
getIndirect(...path) { return libmupdf._wasm_pdf_to_num(this._get(path)) }
getBoolean(...path) { return libmupdf._wasm_pdf_to_bool(this._get(path)) }
getNumber(...path) { return libmupdf._wasm_pdf_to_number(this._get(path)) }
getName(...path) { return fromString(libmupdf._wasm_pdf_to_name(this._get(path))) }
getString(...path) { return fromString(libmupdf._wasm_pdf_to_text_string(this._get(path))) }
put(key, value) {
value = PDFOBJ(this._doc, value)
if (typeof key === "number")
libmupdf._wasm_pdf_array_put(this, key, value)
else if (typeof key === PDFObject)
libmupdf._wasm_pdf_dict_put(this, key, value)
else
libmupdf._wasm_pdf_dict_puts(this, STRING(key), value)
}
push(value) {
value = PDFOBJ(this._doc, value)
libmupdf._wasm_pdf_array_push(this, value)
}
delete(key) {
if (typeof key === "number")
libmupdf._wasm_pdf_array_delete(this, key)
else if (typeof key === PDFObject)
libmupdf._wasm_pdf_dict_del(this, key)
else
libmupdf._wasm_pdf_dict_dels(this, STRING(key))
}
asPrimitive() {
if (this.isNull()) return null
if (this.isBoolean()) return this.asBoolean()
if (this.isNumber()) return this.asNumber()
if (this.isName()) return this.asName()
if (this.isString()) return this.asString()
if (this.isIndirect()) return "R"
return this
}
toString(tight = true, ascii = true) {
return fromStringFree(libmupdf._wasm_pdf_sprint_obj(this, tight, ascii))
}
}
PDFObject.Null = new PDFObject(null, 0)
class PDFAnnotation extends Userdata {
static _drop = "_wasm_pdf_drop_annot"
/* IMPORTANT: Keep in sync with mupdf/pdf/annot.h and PDFAnnotation.java */
static TYPES = [
"Text",
"Link",
"FreeText",
"Line",
"Square",
"Circle",
"Polygon",
"PolyLine",
"Highlight",
"Underline",
"Squiggly",
"StrikeOut",
"Redact",
"Stamp",
"Caret",
"Ink",
"Popup",
"FileAttachment",
"Sound",
"Movie",
"RichMedia",
"Widget",
"Screen",
"PrinterMark",
"TrapNet",
"Watermark",
"3D",
"Projection",
]
static LINE_ENDING = [
"None",
"Square",
"Circle",
"Diamond",
"OpenArrow",
"ClosedArrow",
"Butt",
"ROpenArrow",
"RClosedArrow",
"Slash",
]
static LINE_ENDING_NONE = 0
static LINE_ENDING_SQUARE = 1
static LINE_ENDING_CIRCLE = 2
static LINE_ENDING_DIAMOND = 3
static LINE_ENDING_OPEN_ARROW = 4
static LINE_ENDING_CLOSED_ARROW = 5
static LINE_ENDING_BUTT = 6
static LINE_ENDING_R_OPEN_ARROW = 7
static LINE_ENDING_R_CLOSED_ARROW = 8
static LINE_ENDING_SLASH = 9
static BORDER_STYLE = [
"Solid",
"Dashed",
"Beveled",
"Inset",
"Underline"
]
static BORDER_STYLE_SOLID = 0
static BORDER_STYLE_DASHED = 1
static BORDER_STYLE_BEVELED = 2
static BORDER_STYLE_INSET = 3
static BORDER_STYLE_UNDERLINE = 4
static BORDER_EFFECT = [
"None",
"Cloudy",
]
static BORDER_EFFECT_NONE = 0
static BORDER_EFFECT_CLOUDY = 1
static IS_INVISIBLE = 1 << (1-1)
static IS_HIDDEN = 1 << (2-1)
static IS_PRINT = 1 << (3-1)
static IS_NO_ZOOM = 1 << (4-1)
static IS_NO_ROTATE = 1 << (5-1)
static IS_NO_VIEW = 1 << (6-1)
static IS_READ_ONLY = 1 << (7-1)
static IS_LOCKED = 1 << (8-1)
static IS_TOGGLE_NO_VIEW = 1 << (9-1)
static IS_LOCKED_CONTENTS = 1 << (10-1)
constructor(doc, pointer) {
super(pointer)
this._doc = doc
}
getObject() {
return keepPDFObject(this._doc, libmupdf._wasm_pdf_annot_obj(this))
}
getBounds() {
return fromRect(libmupdf._wasm_pdf_bound_annot(this))
}
run(device, matrix) {
checkType(device, Device)
checkMatrix(matrix)
libmupdf._wasm_pdf_run_annot(this, device, MATRIX(matrix))
}
toPixmap(matrix, colorspace, alpha = false) {
checkMatrix(matrix)
checkType(colorspace, ColorSpace)
return new Pixmap(
libmupdf._wasm_pdf_new_pixmap_from_annot(
this,
MATRIX(matrix),
colorspace,
alpha)
)
}
toDisplayList() {
return new DisplayList(libmupdf._wasm_pdf_new_display_list_from_annot(this))
}
update() {
return !!libmupdf._wasm_pdf_update_annot(this)
}
getType() {
let type = libmupdf._wasm_pdf_annot_type(this)
return PDFAnnotation.TYPES[type]
}
getLanguage() {
return fromString(libmupdf._wasm_pdf_annot_language(this))
}
setLanguage(lang) {
libmupdf._wasm_pdf_set_annot_language(this, STRING(lang))
}
getFlags() {
return libmupdf._wasm_pdf_annot_flags(this)
}
setFlags(flags) {
return libmupdf._wasm_pdf_set_annot_flags(this, flags)
}
getContents() {
return fromString(libmupdf._wasm_pdf_annot_contents(this))
}
setContents(text) {
libmupdf._wasm_pdf_set_annot_contents(this, STRING(text))
}
getAuthor() {
return fromString(libmupdf._wasm_pdf_annot_author(this))
}
setAuthor(text) {
libmupdf._wasm_pdf_set_annot_author(this, STRING(text))
}
getCreationDate() {
return new Date(libmupdf._wasm_pdf_annot_creation_date(this) * 1000)
}
setCreationDate(date) {
checkType(date, Date)
return new Date(libmupdf._wasm_pdf_annot_creation_date(this, date.getTime() / 1000))
}
getModificationDate() {
return new Date(libmupdf._wasm_pdf_annot_modification_date(this) * 1000)
}
setModificationDate(date) {
checkType(date, Date)
return new Date(libmupdf._wasm_pdf_annot_modification_date(this, date.getTime() / 1000))
}
getRect() {
return fromRect(libmupdf._wasm_pdf_annot_rect(this))
}
setRect(rect) {
checkRect(rect)
return fromRect(libmupdf._wasm_pdf_set_annot_rect(this, RECT(rect)))
}
getPopup() {
return fromRect(libmupdf._wasm_pdf_annot_popup(this))
}
setPopup(rect) {
checkType(rect)
libmupdf._wasm_pdf_set_annot_popup(this, RECT(rect))
}
getIsOpen() {
return libmupdf._wasm_pdf_annot_is_open(this)
}
setIsOpen(isOpen) {
return libmupdf._wasm_pdf_set_annot_is_open(this, isOpen)
}
getIcon() {
return fromString(libmupdf._wasm_pdf_annot_icon_name(this))
}
setIcon(text) {
libmupdf._wasm_pdf_set_annot_icon_name(this, STRING(text))
}
getOpacity() {
return libmupdf._wasm_pdf_annot_opacity(this)
}
setOpacity(opacity) {
libmupdf._wasm_pdf_set_annot_opacity(this, opacity)
}
getQuadding() {
return libmupdf._wasm_pdf_annot_quadding(this)
}
setQuadding(quadding) {
return libmupdf._wasm_pdf_set_annot_quadding(this, quadding)
}
getLine() {
let a = fromPoint(libmupdf._wasm_pdf_annot_line_1(this))
let b = fromPoint(libmupdf._wasm_pdf_annot_line_2(this))
return [ a, b ]
}
setLine(a, b) {
libmupdf._wasm_pdf_set_annot_line(this, POINT(a), POINT2(b))
}
getLineEndingStyles() {
let a = libmupdf._wasm_pdf_annot_line_ending_styles_start(this)
let b = libmupdf._wasm_pdf_annot_line_ending_styles_end(this)
return {
start: PDFAnnotation.LINE_ENDING[a],
end: PDFAnnotation.LINE_ENDING[b]
}
}
setLineEndingStyles(start, end) {
start = toEnum(start, PDFAnnotation.LINE_ENDING)
end = toEnum(end, PDFAnnotation.LINE_ENDING)
return libmupdf._wasm_pdf_set_annot_line_ending_styles(this, start, end)
}
getColor() {
return fromColor(libmupdf._wasm_pdf_annot_color(this, COLOR()))
}
getInteriorColor() {
return fromColor(libmupdf._wasm_pdf_annot_interior_color(this, COLOR()))
}
setColor(color) {
checkType(color, Array)
libmupdf._wasm_pdf_set_annot_color(this, color.length, COLOR(color))
}
setInteriorColor(color) {
checkType(color, Array)
libmupdf._wasm_pdf_set_annot_interior_color(this, color.length, COLOR(color))
}
getBorderWidth() {
return libmupdf._wasm_pdf_annot_border_width(this)
}
setBorderWidth(value) {
checkType(value, "number")
return libmupdf._wasm_pdf_set_annot_border_width(this, value)
}
getBorderStyle() {
return PDFAnnotation.BORDER_STYLE[libmupdf._wasm_pdf_annot_border_style(this)]
}
setBorderStyle(value) {
value = toEnum(value, PDFAnnotation.BORDER_STYLE)
return libmupdf._wasm_pdf_set_annot_border_style(this, value)
}
getBorderEffect() {
return PDFAnnotation.BORDER_EFFECT[libmupdf._wasm_pdf_annot_border_effect(this)]
}
setBorderEffect(value) {
value = toEnum(value, PDFAnnotation.BORDER_EFFECT)
return libmupdf._wasm_pdf_set_annot_border_effect(this, value)
}
getBorderEffectIntensity() {
return libmupdf._wasm_pdf_annot_border_effect_intensity(this)
}
setBorderEffectIntensity(value) {
checkType(value, "number")
return libmupdf._wasm_pdf_set_annot_border_effect_intensity(this, value)
}
getBorderDashCount() {
return libmupdf._wasm_pdf_annot_border_dash_count(this)
}
getBorderDashItem(idx) {
return libmupdf._wasm_pdf_annot_border_dash_item(this, idx)
}
clearBorderDash() {
return libmupdf._wasm_pdf_clear_annot_border_dash(this)
}
addBorderDashItem(v) {
checkType(v, "number")
return libmupdf._wasm_pdf_add_annot_border_dash_item(this, v)
}
getBorderDashPattern() {
let n = this.getBorderDashCount()
let result = new Array(n)
for (let i = 0; i < n; ++i)
result[i] = this.getBorderDashItem(i)
return result
}
setBorderDashPattern(list) {
this.clearBorderDash()
for (let v of list)
this.addBorderDashItem(v)
}
setDefaultAppearance(fontName, size, color) {
checkType(fontName, "string")
checkType(size, "number")
checkColor(color)
libmupdf._wasm_pdf_set_annot_default_appearance(this, STRING(fontName), size, color.length, COLOR(color))
}
getDefaultAppearance() {
let font = fromString(libmupdf._wasm_pdf_annot_default_appearance_font(this))
let size = libmupdf._wasm_pdf_annot_default_appearance_size(this)
let color = fromColor(libmupdf._wasm_pdf_annot_default_appearance_color(this, COLOR()))
return { font, size, color }
}
getFileSpec() {
return keepPDFObject(this._doc, libmupdf._wasm_pdf_annot_filespec(this))
}
setFileSpec(fs) {
fs = PDFOBJ(this._doc, fs)
return libmupdf._wasm_pdf_set_annot_filespec(this, fs)
}
getQuadPoints() {
let n = libmupdf._wasm_pdf_annot_quad_point_count(this)
let result = []
for (let i = 0; i < n; ++i)
result.push(fromQuad(libmupdf._wasm_pdf_annot_quad_point(this, i)))
return result
}
clearQuadPoints() {
libmupdf._wasm_pdf_clear_annot_quad_points(this)
}
addQuadPoint(quad) {
checkQuad(quad)
libmupdf._wasm_pdf_add_annot_quad_point(this, QUAD(quad))
}
setQuadPoints(quadlist) {
this.clearQuadPoints()
for (let quad of quadlist)
this.addQuadPoint(quad)
}
getVertices() {
let n = libmupdf._wasm_pdf_annot_vertex_count(this)
let result = new Array(n)
for (let i = 0; i < n; ++i)
result[i] = fromPoint(libmupdf._wasm_pdf_annot_vertex(this, i))
return result
}
clearVertices() {
libmupdf._wasm_pdf_clear_annot_vertices(this)
}
addVertex(vertex) {
checkPoint(vertex)
libmupdf._wasm_pdf_add_annot_vertex(this, POINT(vertex))
}
setVertices(vertexlist) {
this.clearVertices()
for (let vertex of vertexlist)
this.addVertex(vertex)
}
getInkList() {
let n = libmupdf._wasm_pdf_annot_ink_list_count(this)
let result = new Array(n)
for (let i = 0; i < n; ++i) {
let m = libmupdf._wasm_pdf_annot_ink_list_stroke_count(this, i)
result[i] = new Array(m)
for (let k = 0; k < m; ++k)
result[i][k] = fromPoint(libmupdf._wasm_pdf_annot_ink_list_stroke_vertex(this, i, k))
}
return result
}
clearInkList() {
libmupdf._wasm_pdf_clear_annot_ink_list(this)
}
addInkListStroke() {
libmupdf._wasm_pdf_add_annot_ink_list_stroke(this)
}
addInkListStrokeVertex(v) {
checkPoint(v)
libmupdf._wasm_pdf_add_annot_ink_list_stroke_vertex(this, POINT(v))
}
setInkList(inklist) {
this.clearInkList()
for (let stroke of inklist) {
this.addInkListStroke()
for (let vertex of stroke)
this.addInkListStrokeVertex(vertex)
}
}
setAppearanceFromDisplayList(appearance, state, transform, list) {
checkMatrix(transform)
checkType(list, DisplayList)
libmupdf._wasm_pdf_set_annot_appearance_from_display_list(
this,
appearance ? STRING(appearance) : 0,
state ? STRING2(state) : 0,
MATRIX(transform),
list
)
}
setAppearance(appearance, state, transform, bbox, resources, contents) {
checkMatrix(transform)
checkRect(bbox)
libmupdf._wasm_pdf_set_annot_appearance(
this,
appearance ? STRING(appearance) : 0,
state ? STRING2(state) : 0,
MATRIX(transform),
RECT(bbox),
PDFOBJ(this._doc, resources),
toBuffer(contents)
)
}
applyRedaction(black_boxes = 1, image_method = 2) {
libmupdf._wasm_pdf_apply_redaction(this, black_boxes, image_method)
}
}
class PDFWidget extends PDFAnnotation {
/* IMPORTANT: Keep in sync with mupdf/pdf/widget.h and PDFWidget.java */
static TYPES = [
"button",
"button",
"checkbox",
"combobox",
"listbox",
"radiobutton",
"signature",
"text",
]
/* Field flags */
static FIELD_IS_READ_ONLY = 1
static FIELD_IS_REQUIRED = 1 << 1
static FIELD_IS_NO_EXPORT = 1 << 2
/* Text fields */
static TX_FIELD_IS_MULTILINE = 1 << 12
static TX_FIELD_IS_PASSWORD = 1 << 13
static TX_FIELD_IS_COMB = 1 << 24
/* Button fields */
static BTN_FIELD_IS_NO_TOGGLE_TO_OFF = 1 << 14
static BTN_FIELD_IS_RADIO = 1 << 15
static BTN_FIELD_IS_PUSHBUTTON = 1 << 16
/* Choice fields */
static CH_FIELD_IS_COMBO = 1 << 17
static CH_FIELD_IS_EDIT = 1 << 18
static CH_FIELD_IS_SORT = 1 << 19
static CH_FIELD_IS_MULTI_SELECT = 1 << 21
getFieldType() {
return PDFWidget.TYPES(libmupdf._wasm_pdf_annot_field_type(this))
}
isButton() {
let type = this.getFieldType()
return type === "button" || type === "checkbox" || type === "radiobutton"
}
isPushButton() {
return this.getFieldType() === "button"
}
isCheckbox() {
return this.getFieldType() === "checkbox"
}
isRadioButton() {
return this.getFieldType() === "radiobutton"
}
isText() {
return this.getFieldType() === "text"
}
isChoice() {
let type = this.getFieldType()
return type === "combobox" || type === "listbox"
}
isListBox() {
return this.getFieldType() === "listbox"
}
isComboBox() {
return this.getFieldType() === "combobox"
}
getFieldFlags() {
return libmupdf._wasm_pdf_annot_field_flags(this)
}
isMultiline() {
return (this.getFieldFlags() & PDFWidget.TX_FIELD_IS_MULTILINE) !== 0
}
isPassword() {
return (this.getFieldFlags() & PDFWidget.TX_FIELD_IS_PASSWORD) !== 0
}
isComb() {
return (this.getFieldFlags() & PDFWidget.TX_FIELD_IS_COMB) !== 0
}
isReadOnly() {
return (this.getFieldFlags() & PDFWidget.FIELD_IS_READ_ONLY) !== 0
}
getLabel() {
return fromString(libmupdf._wasm_pdf_annot_field_label(this))
}
getName() {
return fromStringFree(libmupdf._wasm_pdf_load_field_name(this))
}
getValue() {
return fromString(libmupdf._wasm_pdf_annot_field_value(this))
}
setTextValue(value) {
return libmupdf._wasm_pdf_set_annot_text_field_value(this, STRING(value))
}
getMaxLen() {
return libmupdf._wasm_pdf_annot_text_widget_max_len(this)
}
setChoiceValue(value) {
return libmupdf._wasm_pdf_set_annot_choice_field_value(this, STRING(value))
}
getOptions(isExport=false) {
let result = []
let n = libmupdf._wasm_pdf_annot_choice_field_option_count(this)
for (let i = 0; i < n; ++i) {
result.push(
fromString(
libmupdf._wasm_pdf_annot_choice_field_option(this, isExport, i)
)
)
}
}
toggle() {
libmupdf._wasm_pdf_toggle_widget(this)
}
// Interactive Text Widget editing in a GUI.
// TODO: getEditingState()
// TODO: setEditingState()
// TODO: clearEditingState()
// TODO: layoutTextWidget()
// Interactive form validation Javascript triggers.
// NOTE: No embedded PDF Javascript engine in WASM build.
// TODO: eventEnter()
// TODO: eventExit()
// TODO: eventDown()
// TODO: eventUp()
// TODO: eventFocus()
// TODO: eventBlur()
// NOTE: No OpenSSL support in WASM build.
// TODO: isSigned()
// TODO: validateSignature()
// TODO: checkCertificate()
// TODO: checkDigest()
// TODO: getSignature()
// TODO: previewSignature()
// TODO: clearSignature()
// TODO: sign()
}
// Background progressive fetch
class Stream extends Userdata {
static _drop = "_wasm_drop_stream"
constructor(url, contentLength, block_size, prefetch) {
super(libmupdf._wasm_open_stream_from_url(STRING(url), contentLength, block_size, prefetch))
}
}
// TODO - move in Stream
function onFetchData(id, block, data) {
let n = data.byteLength
let p = libmupdf._wasm_malloc(n)
libmupdf.HEAPU8.set(new Uint8Array(data), p)
libmupdf._wasm_on_data_fetched(id, block, p, n)
libmupdf._wasm_free(p)
}
// TODO - replace with map
let fetchStates = {}
function fetchOpen(id, url, contentLength, blockShift, prefetch) {
console.log("OPEN", url, "PROGRESSIVELY")
fetchStates[id] = {
url: url,
blockShift: blockShift,
blockSize: 1 << blockShift,
prefetch: prefetch,
contentLength: contentLength,
map: new Array((contentLength >>> blockShift) + 1).fill(0),
closed: false,
}
}
async function fetchRead(id, block) {
let state = fetchStates[id]
if (state.map[block] > 0)
return
state.map[block] = 1
let contentLength = state.contentLength
let url = state.url
let start = block << state.blockShift
let end = start + state.blockSize
if (end > contentLength)
end = contentLength
try {
let response = await fetch(url, { headers: { Range: `bytes=${start}-${end - 1}` } })
if (state.closed)
return
// TODO - use ReadableStream instead?
let buffer = await response.arrayBuffer()
if (state.closed)
return
console.log("READ", url, block + 1, "/", state.map.length)
state.map[block] = 2
onFetchData(id, block, buffer)
onFetchCompleted(id)
// TODO - Does this create a risk of stack overflow?
if (state.prefetch)
fetchReadNext(id, block + 1)
} catch (error) {
state.map[block] = 0
console.log("FETCH ERROR", url, block, error.toString)
}
}
function fetchReadNext(id, next) {
let state = fetchStates[id]
if (!state)
return
// Don't prefetch if we're already waiting for any blocks.
for (let block = 0; block < state.map.length; ++block)
if (state.map[block] === 1)
return
// Find next block to prefetch (starting with the last fetched block)
for (let block = next; block < state.map.length; ++block)
if (state.map[block] === 0)
return fetchRead(id, block)
// Find next block to prefetch (starting from the beginning)
for (let block = 0; block < state.map.length; ++block)
if (state.map[block] === 0)
return fetchRead(id, block)
console.log("ALL BLOCKS READ")
}
function fetchClose(id) {
fetchStates[id].closed = true
delete fetchStates[id]
}
// TODO - Figure out better naming scheme for fetch methods
function onFetchCompleted(id) {
mupdf.onFetchCompleted(id)
}
// --- EXPORTS ---
const mupdf = {
Matrix,
Rect,
Buffer,
ColorSpace,
Font,
StrokeState,
Image,
Path,
Text,
Pixmap,
DisplayList,
DrawDevice,
DisplayListDevice,
Document,
DocumentWriter,
PDFDocument,
PDFAnnotation,
PDFPage,
PDFObject,
TryLaterError,
Stream,
onFetchCompleted: () => {},
}
// If running in Node.js environment
if (typeof require === "function")
module.exports = mupdf