@danielsimonjr/sciengjs 0.9.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/THIRD_PARTY_NOTICES.md +65 -4
- package/dist/browser/render.d.ts +13 -0
- package/dist/browser/render.js +10 -6
- package/dist/browser/render.js.map +1 -1
- package/dist/core.js +20 -12
- package/dist/core.js.map +1 -1
- package/dist/registry.d.ts +6 -0
- package/dist/registry.js +20 -0
- package/dist/registry.js.map +1 -1
- package/dist/tex/backend-pdf.d.ts +3 -0
- package/dist/tex/backend-pdf.js +10 -0
- package/dist/tex/backend-pdf.js.map +1 -0
- package/dist/tex/backend-png.d.ts +6 -0
- package/dist/tex/backend-png.js +19 -0
- package/dist/tex/backend-png.js.map +1 -0
- package/dist/tex/backend-svg.d.ts +3 -0
- package/dist/tex/backend-svg.js +8 -0
- package/dist/tex/backend-svg.js.map +1 -0
- package/dist/tex/bundles.d.ts +49 -0
- package/dist/tex/bundles.js +170 -0
- package/dist/tex/bundles.js.map +1 -0
- package/dist/tex/bundles.json +26 -0
- package/dist/tex/detect.d.ts +27 -0
- package/dist/tex/detect.js +212 -0
- package/dist/tex/detect.js.map +1 -0
- package/dist/tex/dvi.d.ts +44 -0
- package/dist/tex/dvi.js +280 -0
- package/dist/tex/dvi.js.map +1 -0
- package/dist/tex/host.d.ts +82 -0
- package/dist/tex/host.js +313 -0
- package/dist/tex/host.js.map +1 -0
- package/dist/tex/index.d.ts +16 -0
- package/dist/tex/index.js +17 -0
- package/dist/tex/index.js.map +1 -0
- package/dist/tex/render.d.ts +66 -0
- package/dist/tex/render.js +72 -0
- package/dist/tex/render.js.map +1 -0
- package/dist/tex/run.d.ts +51 -0
- package/dist/tex/run.js +54 -0
- package/dist/tex/run.js.map +1 -0
- package/dist/tex/specials.d.ts +32 -0
- package/dist/tex/specials.js +145 -0
- package/dist/tex/specials.js.map +1 -0
- package/dist/tex/stage.d.ts +34 -0
- package/dist/tex/stage.js +102 -0
- package/dist/tex/stage.js.map +1 -0
- package/dist/tex/tfm.d.ts +15 -0
- package/dist/tex/tfm.js +33 -0
- package/dist/tex/tfm.js.map +1 -0
- package/dist/tex/type1.d.ts +32 -0
- package/dist/tex/type1.js +402 -0
- package/dist/tex/type1.js.map +1 -0
- package/dist/tex/vfs.d.ts +37 -0
- package/dist/tex/vfs.js +80 -0
- package/dist/tex/vfs.js.map +1 -0
- package/dist/tex/wasm.d.ts +16 -0
- package/dist/tex/wasm.js +8 -0
- package/dist/tex/wasm.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker/protocol.d.ts +6 -0
- package/package.json +110 -106
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** The SVG unit of the specials of dvisvgm: the big point (72 bp = 72.27 pt). */
|
|
2
|
+
export declare const SPECIAL_UNIT_PER_PT: number;
|
|
3
|
+
/** The position of a special on the page, in SVG units, and the size of one TeX point in these units. */
|
|
4
|
+
export interface SpecialPosition {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
unit: number;
|
|
8
|
+
}
|
|
9
|
+
/** What a special gives to the page: SVG text, a box for the bounds, or nothing. */
|
|
10
|
+
export interface SpecialResult {
|
|
11
|
+
/** SVG text for the page. */
|
|
12
|
+
svg?: string;
|
|
13
|
+
/** The box `[x0, y0, x1, y1]` that joins the bounds of the page. */
|
|
14
|
+
box?: number[];
|
|
15
|
+
}
|
|
16
|
+
/** The reader of the dvisvgm specials. */
|
|
17
|
+
export interface Specials {
|
|
18
|
+
/** Turns one special into SVG text, a box or `null`. */
|
|
19
|
+
special(text: string, at: SpecialPosition): SpecialResult | null;
|
|
20
|
+
/** The first words of the specials that the reader did not handle, in order and without repeats. */
|
|
21
|
+
ignored(): string[];
|
|
22
|
+
/**
|
|
23
|
+
* Tells whether the page is inside a raw group with a `transform` attribute. A pgf picture moves its text
|
|
24
|
+
* with such a group, so the DVI position of a glyph there is not its place on the page.
|
|
25
|
+
*/
|
|
26
|
+
transformed(): boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Creates a reader for the `dvisvgm:raw`, `rawdef`, `rawset`, `endrawset`, `rawput` and `bbox` specials
|
|
30
|
+
* and for the `color push` and `color pop` specials. The reader keeps the named raw sets between calls.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createSpecials(): Specials;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/** The SVG unit of the specials of dvisvgm: the big point (72 bp = 72.27 pt). */
|
|
2
|
+
export const SPECIAL_UNIT_PER_PT = 72 / 72.27;
|
|
3
|
+
const round4 = (v) => Math.round(v * 1e4) / 1e4;
|
|
4
|
+
// The rounding removes float noise, so 10 stays "10".
|
|
5
|
+
const fmt = (v) => String(round4(v));
|
|
6
|
+
function fill(text, at) {
|
|
7
|
+
return text.replace(/\{\?x\}/g, fmt(at.x)).replace(/\{\?y\}/g, fmt(at.y)).replace(/\{\?nl\}/g, "\n");
|
|
8
|
+
}
|
|
9
|
+
function firstWord(text) {
|
|
10
|
+
return text.trim().split(/\s+/)[0];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Creates a reader for the `dvisvgm:raw`, `rawdef`, `rawset`, `endrawset`, `rawput` and `bbox` specials
|
|
14
|
+
* and for the `color push` and `color pop` specials. The reader keeps the named raw sets between calls.
|
|
15
|
+
*/
|
|
16
|
+
export function createSpecials() {
|
|
17
|
+
const sets = new Map();
|
|
18
|
+
let active = null;
|
|
19
|
+
const ignoredList = [];
|
|
20
|
+
// One entry for each open group on the page: true when the group has a transform attribute.
|
|
21
|
+
const groups = [];
|
|
22
|
+
function track(r) {
|
|
23
|
+
if (r?.svg === undefined)
|
|
24
|
+
return r;
|
|
25
|
+
for (const m of r.svg.matchAll(/<g(\s[^>]*)?>|<\/g>/g)) {
|
|
26
|
+
if (m[0] === "</g>")
|
|
27
|
+
groups.pop();
|
|
28
|
+
else
|
|
29
|
+
groups.push(/transform\s*=/.test(m[1] ?? ""));
|
|
30
|
+
}
|
|
31
|
+
return r;
|
|
32
|
+
}
|
|
33
|
+
function remember(word) {
|
|
34
|
+
if (word && !ignoredList.includes(word))
|
|
35
|
+
ignoredList.push(word);
|
|
36
|
+
}
|
|
37
|
+
// The numbers of dvisvgm:bbox are in TeX points.
|
|
38
|
+
function bbox(arg, at) {
|
|
39
|
+
const t = arg.trim();
|
|
40
|
+
const toks = t.length === 0 ? [] : t.split(/\s+/);
|
|
41
|
+
const head = toks[0];
|
|
42
|
+
if (head === "lock" || head === "unlock" || head === "fix" || head === "new")
|
|
43
|
+
return null;
|
|
44
|
+
if (toks.length < 2)
|
|
45
|
+
return null;
|
|
46
|
+
const w = Number(toks[0]);
|
|
47
|
+
const h = Number(toks[1]);
|
|
48
|
+
const d = toks.length > 2 ? Number(toks[2]) : 0;
|
|
49
|
+
if (![w, h, d].every(Number.isFinite))
|
|
50
|
+
return null;
|
|
51
|
+
// The box runs W wide from the point, H high above and D deep below it.
|
|
52
|
+
return { box: [round4(at.x), round4(at.y - h * at.unit), round4(at.x + w * at.unit), round4(at.y + d * at.unit)] };
|
|
53
|
+
}
|
|
54
|
+
function dvisvgm(rest, first, at) {
|
|
55
|
+
const m = rest.match(/^\s*(\S+)(?:\s([\s\S]*))?$/);
|
|
56
|
+
if (m === null) {
|
|
57
|
+
remember(first);
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
const cmd = m[1];
|
|
61
|
+
const arg = m[2] === undefined ? "" : m[2];
|
|
62
|
+
if (cmd === "raw") {
|
|
63
|
+
if (active !== null) {
|
|
64
|
+
// Inside a capture the text is stored unreplaced.
|
|
65
|
+
sets.set(active, sets.get(active) + arg);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
return { svg: fill(arg, at) };
|
|
69
|
+
}
|
|
70
|
+
if (cmd === "rawdef")
|
|
71
|
+
return { svg: "<defs>" + fill(arg, at) + "</defs>" };
|
|
72
|
+
if (cmd === "rawset") {
|
|
73
|
+
const name = firstWord(arg);
|
|
74
|
+
if (name !== "" && active === null) {
|
|
75
|
+
active = name;
|
|
76
|
+
sets.set(name, "");
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
if (cmd === "endrawset") {
|
|
81
|
+
active = null;
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
if (cmd === "rawput") {
|
|
85
|
+
const name = firstWord(arg);
|
|
86
|
+
const stored = name === "" ? undefined : sets.get(name);
|
|
87
|
+
// A set that still captures is not ready for a put. The placeholders are replaced at the time of the put.
|
|
88
|
+
if (stored === undefined || name === active)
|
|
89
|
+
return null;
|
|
90
|
+
return { svg: fill(stored, at) };
|
|
91
|
+
}
|
|
92
|
+
if (cmd === "bbox")
|
|
93
|
+
return bbox(arg, at);
|
|
94
|
+
remember(first);
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
function color(words) {
|
|
98
|
+
if (words[1] === "pop")
|
|
99
|
+
return { svg: "</g>" };
|
|
100
|
+
if (words[1] !== "push") {
|
|
101
|
+
remember(words[0]);
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
const chan = (v) => Math.round(v * 255);
|
|
105
|
+
const model = words[2];
|
|
106
|
+
let rgb = null;
|
|
107
|
+
if (model === "rgb" && words.length >= 6) {
|
|
108
|
+
const v = words.slice(3, 6).map(Number);
|
|
109
|
+
if (v.every(Number.isFinite))
|
|
110
|
+
rgb = v.map(chan);
|
|
111
|
+
}
|
|
112
|
+
else if (model === "gray" && words.length >= 4) {
|
|
113
|
+
const v = Number(words[3]);
|
|
114
|
+
if (Number.isFinite(v))
|
|
115
|
+
rgb = [chan(v), chan(v), chan(v)];
|
|
116
|
+
}
|
|
117
|
+
else if (model === "cmyk" && words.length >= 7) {
|
|
118
|
+
const v = words.slice(3, 7).map(Number);
|
|
119
|
+
if (v.every(Number.isFinite)) {
|
|
120
|
+
const [c, m, y, k] = v;
|
|
121
|
+
rgb = [chan((1 - c) * (1 - k)), chan((1 - m) * (1 - k)), chan((1 - y) * (1 - k))];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (rgb === null) {
|
|
125
|
+
remember(words[0]);
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
return { svg: '<g fill="rgb(' + rgb.join(",") + ')">' };
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
special(text, at) {
|
|
132
|
+
const lead = text.match(/^\s*dvisvgm:/);
|
|
133
|
+
if (lead !== null)
|
|
134
|
+
return track(dvisvgm(text.slice(lead[0].length), text.trim().split(/\s+/)[0], at));
|
|
135
|
+
const words = text.trim().split(/\s+/);
|
|
136
|
+
if (words[0] === "color")
|
|
137
|
+
return track(color(words));
|
|
138
|
+
remember(words[0]);
|
|
139
|
+
return null;
|
|
140
|
+
},
|
|
141
|
+
ignored: () => ignoredList.slice(),
|
|
142
|
+
transformed: () => groups.some((g) => g),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=specials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"specials.js","sourceRoot":"","sources":["../../src/tex/specials.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { BackendSettings } from "../worker/protocol.ts";
|
|
2
|
+
import { type BundleSettings } from "./bundles.ts";
|
|
3
|
+
import { type TexEngine } from "./render.ts";
|
|
4
|
+
import { TexTree } from "./vfs.ts";
|
|
5
|
+
/** The loaded engine of the core bundle: the module, the format and the tree of the core files. */
|
|
6
|
+
export interface LoadedCore {
|
|
7
|
+
engine: TexEngine;
|
|
8
|
+
format: {
|
|
9
|
+
name: string;
|
|
10
|
+
bytes: Uint8Array;
|
|
11
|
+
};
|
|
12
|
+
tree: TexTree;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Loads the core bundle once per process. The loaded value is reused while the pinned hash is the same. When the
|
|
16
|
+
* parent process gives the files in `settings.texCore`, the worker uses them, reads no bundle file and keeps no copy.
|
|
17
|
+
*/
|
|
18
|
+
export declare function loadCore(settings: BundleSettings & {
|
|
19
|
+
texCore?: ReadonlyMap<string, Uint8Array>;
|
|
20
|
+
}): Promise<LoadedCore>;
|
|
21
|
+
/**
|
|
22
|
+
* Makes a standalone document from a TikZ source. A source with a `\documentclass` is a document: the function only adds
|
|
23
|
+
* the class option `dvisvgm`, which selects the DVI driver of the format. Any other source is the body: the function
|
|
24
|
+
* adds the `standalone` class, one `\usepackage` line for each detected package that the format does not hold, and the
|
|
25
|
+
* `document` environment.
|
|
26
|
+
*/
|
|
27
|
+
export declare function wrapSource(source: string, packages: readonly string[]): string;
|
|
28
|
+
/** What a tikz render gives: the SVG text and the warnings. */
|
|
29
|
+
export interface TikzSvg {
|
|
30
|
+
svg: string;
|
|
31
|
+
warnings: string[];
|
|
32
|
+
}
|
|
33
|
+
/** Renders one tikz source to SVG: detects the bundles, loads them, wraps the source and runs the engine. */
|
|
34
|
+
export declare function renderTikzSvg(source: string, options: Record<string, unknown>, settings: Pick<BackendSettings, "cacheDir" | "texBundleUrl" | "allowNetwork" | "timeoutMs" | "texCore">): Promise<TikzSvg>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { RenderError } from "../errors.js";
|
|
2
|
+
import { findBundle, loadBundleBytes, loadBundles, unpackBundle } from "./bundles.js";
|
|
3
|
+
import { detectBundles } from "./detect.js";
|
|
4
|
+
import { renderTex } from "./render.js";
|
|
5
|
+
import { TexTree } from "./vfs.js";
|
|
6
|
+
/** The packages that the format holds. A wrapped source does not load them again. */
|
|
7
|
+
const FORMAT_PACKAGES = new Set(["tikz", "pgf", "xcolor", "circuitikz", "standalone"]);
|
|
8
|
+
let loadedCore;
|
|
9
|
+
/** The names in the core bundle that are the engine, not tree files. */
|
|
10
|
+
const ENGINE_FILES = new Set(["engine.wasm", "engine.symbols.json", "tex.pool", "scieng.fmt"]);
|
|
11
|
+
async function wasmModule(bytes) {
|
|
12
|
+
const api = globalThis.WebAssembly;
|
|
13
|
+
return api.compile(bytes);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Loads the core bundle once per process. The loaded value is reused while the pinned hash is the same. When the
|
|
17
|
+
* parent process gives the files in `settings.texCore`, the worker uses them, reads no bundle file and keeps no copy.
|
|
18
|
+
*/
|
|
19
|
+
export async function loadCore(settings) {
|
|
20
|
+
if (settings.texCore !== undefined)
|
|
21
|
+
return coreOf(settings.texCore);
|
|
22
|
+
const entry = findBundle("core");
|
|
23
|
+
if (loadedCore?.sha256 === entry.sha256)
|
|
24
|
+
return loadedCore.value;
|
|
25
|
+
const value = await coreOf(unpackBundle(await loadBundleBytes(entry, settings)));
|
|
26
|
+
loadedCore = { sha256: entry.sha256, value };
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
/** Builds the loaded core from the files of the core bundle. */
|
|
30
|
+
async function coreOf(files) {
|
|
31
|
+
const need = (name) => {
|
|
32
|
+
const f = files.get(name);
|
|
33
|
+
if (f === undefined)
|
|
34
|
+
throw new RenderError("E_INTEGRITY", `the core TeX bundle has no file ${name}`);
|
|
35
|
+
return f;
|
|
36
|
+
};
|
|
37
|
+
const tree = new TexTree();
|
|
38
|
+
for (const [name, bytes] of files)
|
|
39
|
+
if (!ENGINE_FILES.has(name))
|
|
40
|
+
tree.add(name, bytes);
|
|
41
|
+
const value = {
|
|
42
|
+
engine: {
|
|
43
|
+
module: await wasmModule(need("engine.wasm")),
|
|
44
|
+
symbols: JSON.parse(new TextDecoder().decode(need("engine.symbols.json"))),
|
|
45
|
+
pool: need("tex.pool"),
|
|
46
|
+
},
|
|
47
|
+
format: { name: "scieng.fmt", bytes: need("scieng.fmt") },
|
|
48
|
+
tree,
|
|
49
|
+
};
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Makes a standalone document from a TikZ source. A source with a `\documentclass` is a document: the function only adds
|
|
54
|
+
* the class option `dvisvgm`, which selects the DVI driver of the format. Any other source is the body: the function
|
|
55
|
+
* adds the `standalone` class, one `\usepackage` line for each detected package that the format does not hold, and the
|
|
56
|
+
* `document` environment.
|
|
57
|
+
*/
|
|
58
|
+
export function wrapSource(source, packages) {
|
|
59
|
+
if (/\\documentclass\b/.test(source)) {
|
|
60
|
+
return source.replace(/\\documentclass(?:\[([^\]]*)\])?/, (_m, opts) => {
|
|
61
|
+
const list = (opts ?? "").split(",").map((s) => s.trim()).filter((s) => s !== "");
|
|
62
|
+
return `\\documentclass[${[...new Set([...list, "dvisvgm"])].join(",")}]`;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
const uses = packages.filter((p) => !FORMAT_PACKAGES.has(p)).map((p) => `\\usepackage{${p}}\n`);
|
|
66
|
+
return `\\documentclass[dvisvgm]{standalone}\n${uses.join("")}\\begin{document}\n${source}\n\\end{document}\n`;
|
|
67
|
+
}
|
|
68
|
+
/** Renders one tikz source to SVG: detects the bundles, loads them, wraps the source and runs the engine. */
|
|
69
|
+
export async function renderTikzSvg(source, options, settings) {
|
|
70
|
+
const detected = detectBundles(source);
|
|
71
|
+
const bundleSettings = {
|
|
72
|
+
cacheDir: settings.cacheDir,
|
|
73
|
+
texBundleUrl: settings.texBundleUrl,
|
|
74
|
+
allowNetwork: settings.allowNetwork,
|
|
75
|
+
timeoutMs: settings.timeoutMs,
|
|
76
|
+
};
|
|
77
|
+
const base = await loadCore({ ...bundleSettings, ...(settings.texCore === undefined ? {} : { texCore: settings.texCore }) });
|
|
78
|
+
const extra = detected.bundles.filter((b) => b !== "core");
|
|
79
|
+
const tree = base.tree.fork();
|
|
80
|
+
for (const files of (await loadBundles(extra, bundleSettings)).values()) {
|
|
81
|
+
for (const [name, bytes] of files)
|
|
82
|
+
tree.add(name, bytes);
|
|
83
|
+
}
|
|
84
|
+
const margin = options.margin;
|
|
85
|
+
if (margin !== undefined && (typeof margin !== "number" || !Number.isFinite(margin) || margin < 0)) {
|
|
86
|
+
throw new RenderError("E_INPUT", "option margin must be a number that is zero or more");
|
|
87
|
+
}
|
|
88
|
+
const result = await renderTex({
|
|
89
|
+
engine: base.engine,
|
|
90
|
+
format: base.format,
|
|
91
|
+
tree,
|
|
92
|
+
source: wrapSource(source, detected.packages),
|
|
93
|
+
jobName: "job",
|
|
94
|
+
timeoutMs: settings.timeoutMs,
|
|
95
|
+
...(margin === undefined ? {} : { margin }),
|
|
96
|
+
});
|
|
97
|
+
const warnings = [];
|
|
98
|
+
if (result.missing.length > 0)
|
|
99
|
+
warnings.push(`${result.missing.length} glyph(s) have no outline in the bundled fonts`);
|
|
100
|
+
return { svg: result.svg, warnings };
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=stage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stage.js","sourceRoot":"","sources":["../../src/tex/stage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** The data of a TFM file that the DVI converter uses. */
|
|
2
|
+
export interface Tfm {
|
|
3
|
+
/** The design size in points. */
|
|
4
|
+
designSize: number;
|
|
5
|
+
/** The checksum word of the font. */
|
|
6
|
+
checksum: number;
|
|
7
|
+
/** The width of each character that exists, in design-size units. */
|
|
8
|
+
widths: Map<number, number>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Reads the character widths and the design size of a TFM file.
|
|
12
|
+
* The format is the one of `tftopl.web`. A width is a fix_word, which is a multiple of 2^-20.
|
|
13
|
+
* A header that does not fit the file, or a width index outside the table, throws an error.
|
|
14
|
+
*/
|
|
15
|
+
export declare function readTfm(bytes: Uint8Array): Tfm;
|
package/dist/tex/tfm.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads the character widths and the design size of a TFM file.
|
|
3
|
+
* The format is the one of `tftopl.web`. A width is a fix_word, which is a multiple of 2^-20.
|
|
4
|
+
* A header that does not fit the file, or a width index outside the table, throws an error.
|
|
5
|
+
*/
|
|
6
|
+
export function readTfm(bytes) {
|
|
7
|
+
const d = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
8
|
+
if (bytes.length < 24)
|
|
9
|
+
throw new Error("bad TFM header");
|
|
10
|
+
const half = (i) => d.getUint16(2 * i, false);
|
|
11
|
+
const lf = half(0);
|
|
12
|
+
const lh = half(1);
|
|
13
|
+
const bc = half(2);
|
|
14
|
+
const ec = half(3);
|
|
15
|
+
const nw = half(4);
|
|
16
|
+
if (lf * 4 > bytes.length || bc > ec + 1 || ec > 255)
|
|
17
|
+
throw new Error("bad TFM header");
|
|
18
|
+
const word = (i) => d.getUint32(4 * i, false);
|
|
19
|
+
const fix = (i) => d.getInt32(4 * i, false) / 2 ** 20;
|
|
20
|
+
const charBase = 6 + lh;
|
|
21
|
+
const widthBase = charBase + (ec - bc + 1);
|
|
22
|
+
const widths = new Map();
|
|
23
|
+
for (let c = bc; c <= ec; c++) {
|
|
24
|
+
const widthIndex = word(charBase + c - bc) >>> 24;
|
|
25
|
+
if (widthIndex === 0)
|
|
26
|
+
continue;
|
|
27
|
+
if (widthIndex >= nw)
|
|
28
|
+
throw new Error("bad width index");
|
|
29
|
+
widths.set(c, fix(widthBase + widthIndex));
|
|
30
|
+
}
|
|
31
|
+
return { designSize: fix(7), checksum: word(6), widths };
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=tfm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tfm.js","sourceRoot":"","sources":["../../src/tex/tfm.ts"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,KAAiB;IACvC,MAAM,CAAC,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IACzE,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;IAC9D,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACnB,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACnB,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACnB,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACnB,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACnB,IAAI,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACxF,MAAM,IAAI,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;IAC9D,MAAM,GAAG,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IACtE,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,CAAC;IACxB,MAAM,SAAS,GAAG,QAAQ,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC;QAClD,IAAI,UAAU,KAAK,CAAC;YAAE,SAAS;QAC/B,IAAI,UAAU,IAAI,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACzD,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** The outline and the metrics of one glyph. */
|
|
2
|
+
export interface Type1Glyph {
|
|
3
|
+
/** The glyph name. */
|
|
4
|
+
name: string;
|
|
5
|
+
/** The advance width in font units. */
|
|
6
|
+
advance: number;
|
|
7
|
+
/** The SVG path data, in font units with the y axis up. Empty for a glyph with no outline. */
|
|
8
|
+
d: string;
|
|
9
|
+
/** The box `[minX, minY, maxX, maxY]` of the outline and its control points. */
|
|
10
|
+
bbox: [number, number, number, number];
|
|
11
|
+
}
|
|
12
|
+
/** A Type 1 font after reading. */
|
|
13
|
+
export interface Type1Font {
|
|
14
|
+
fontName: string;
|
|
15
|
+
fontBBox: number[];
|
|
16
|
+
fontMatrix: number[];
|
|
17
|
+
/** The glyph name of each character code. */
|
|
18
|
+
encoding: (string | undefined)[];
|
|
19
|
+
/** The glyph of a character code, or `null` when the code has no glyph. */
|
|
20
|
+
glyph(code: number): Type1Glyph | null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Decrypts Type 1 data with the cipher of the font format: `c1 = 52845`, `c2 = 22719`.
|
|
24
|
+
* Use `r = 55665` for the eexec section and `r = 4330` for a charstring.
|
|
25
|
+
* The function drops the first `skip` plain bytes, which are the random lead bytes.
|
|
26
|
+
*/
|
|
27
|
+
export declare function decryptType1(b: Uint8Array, r: number, skip: number): Uint8Array;
|
|
28
|
+
/**
|
|
29
|
+
* Reads a Type 1 font from the bytes of a PFB or PFA file. The function decrypts the private part at once.
|
|
30
|
+
* It runs the charstring of a glyph on the first request for it and keeps the result.
|
|
31
|
+
*/
|
|
32
|
+
export declare function readType1(pfb: Uint8Array): Type1Font;
|