@weasel-js/pdf 0.0.0-stage → 1.11.1
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/LICENSE +21 -0
- package/README.md +69 -2
- package/dist/index.d.ts +58 -0
- package/dist/index.js +1307 -0
- package/dist/index.js.map +1 -0
- package/package.json +50 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 orochi235
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,70 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @weasel-js/pdf
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
PDF documents from weasel draw commands: vector paths, shadings, images, and
|
|
4
|
+
embedded fonts with selectable text. No scene graph, no React.
|
|
5
|
+
|
|
6
|
+
Part of [weasel](https://github.com/orochi235/weasel), a domain-agnostic 2D
|
|
7
|
+
scene-graph canvas kit for React. See the
|
|
8
|
+
[API reference](https://orochi235.github.io/weasel/#pkg/pdf).
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
npm install @weasel-js/pdf
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { registryFontSource, writePdf } from '@weasel-js/pdf';
|
|
20
|
+
|
|
21
|
+
const { bytes, skipped } = await writePdf(
|
|
22
|
+
[{ width: 612, height: 792, commands }],
|
|
23
|
+
{ fonts: registryFontSource, title: 'Chart' },
|
|
24
|
+
);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Page units are points, with the origin at the top left and y growing downward.
|
|
28
|
+
`registryFontSource` reads the faces registered with `@weasel-js/font`, whose
|
|
29
|
+
outlines must be registered for text to embed. `writePdf` rejects an empty
|
|
30
|
+
page list.
|
|
31
|
+
|
|
32
|
+
## What is drawn
|
|
33
|
+
|
|
34
|
+
Written natively, as vectors: paths, solid fills, gradient shadings (with soft
|
|
35
|
+
masks for transparency), strokes (native, or outlined where PDF cannot express
|
|
36
|
+
them) with their markers, images, sprites, tiling patterns, text as Type0 fonts
|
|
37
|
+
with a ToUnicode map, color matrices, and isolated groups.
|
|
38
|
+
|
|
39
|
+
Handed to the `rasterize` hook: effects groups, shader commands, and fills in
|
|
40
|
+
a registered paint kind. Without a hook they are skipped.
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
rasterize(commands, rect, scale, view) => Promise<{ width, height, data }>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`rect` is the region in page points, `scale` the pixels per point, and `view`
|
|
47
|
+
the page's `view`, which `world`-unit paint in `commands` resolves through.
|
|
48
|
+
`data` is straight RGBA, top-down.
|
|
49
|
+
|
|
50
|
+
A face that is CFF-only, restricted (`fsType` 0x0002), bitmap-only (`fsType`
|
|
51
|
+
0x0200), registered from a WOFF file, or unreadable is drawn as glyph outlines
|
|
52
|
+
instead, so its text is not selectable.
|
|
53
|
+
|
|
54
|
+
## `skipped`
|
|
55
|
+
|
|
56
|
+
Each entry is `{ kind: 'glyph' | 'command', detail }`. It reports:
|
|
57
|
+
|
|
58
|
+
- an effects group, shader command or registered-paint fill with no `rasterize` hook, or one whose hook threw or returned the wrong number of pixels;
|
|
59
|
+
- an image that could not be read, and a texture that cannot be drawn;
|
|
60
|
+
- a glyph nothing can draw: a color glyph, a slot the layout left empty, or one with no outline in the outline fallback;
|
|
61
|
+
- a command holding NaN or an infinity, which is left out whole;
|
|
62
|
+
- the approximations below, except the stroke width and `screen`-unit paint.
|
|
63
|
+
|
|
64
|
+
## Known approximations
|
|
65
|
+
|
|
66
|
+
- A `{ px }` stroke width under an anisotropic view uses the mean scale.
|
|
67
|
+
- A `vertexColors` stroke uses a single paint, and a `vertexColors` fill its solid fill.
|
|
68
|
+
- `screen`-unit paint inside a rasterized group is placed in the raster's pixels, not the page's points.
|
|
69
|
+
- A Porter-Duff composite is drawn source-over.
|
|
70
|
+
- An isolated group's color matrix alpha offset is not drawn.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { FontStyle, FaceEmbedding } from '@weasel-js/font';
|
|
2
|
+
import { GlMat3 } from '@weasel-js/geom';
|
|
3
|
+
import { DrawCommand } from '@weasel-js/renderer';
|
|
4
|
+
|
|
5
|
+
/** Where the writer gets the font faces it embeds and the glyph outlines it falls back to; `registryFontSource` reads the font registry. */
|
|
6
|
+
interface PdfFontSource {
|
|
7
|
+
embedding(family: string, weight: number, style: FontStyle): Promise<FaceEmbedding | null>;
|
|
8
|
+
/** Em-space SVG path data, as glyphOutline answers it. */
|
|
9
|
+
outline(family: string, weight: number, style: FontStyle, cp: number): string | null;
|
|
10
|
+
}
|
|
11
|
+
/** The faces registered with `@weasel-js/font`. */
|
|
12
|
+
declare const registryFontSource: PdfFontSource;
|
|
13
|
+
|
|
14
|
+
/** An axis-aligned rectangle in page units. */
|
|
15
|
+
type Rect = {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
};
|
|
21
|
+
/** One page of the document: its size in points and the draw commands painted onto it. */
|
|
22
|
+
interface PdfPage {
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
commands: readonly DrawCommand[];
|
|
26
|
+
view?: GlMat3;
|
|
27
|
+
}
|
|
28
|
+
/** A decoded bitmap handed back by the host, for images and paints the PDF cannot express directly. */
|
|
29
|
+
interface RasterPixels {
|
|
30
|
+
width: number;
|
|
31
|
+
height: number;
|
|
32
|
+
/** Straight RGBA, top-down. */
|
|
33
|
+
data: Uint8ClampedArray;
|
|
34
|
+
}
|
|
35
|
+
/** Settings and host callbacks for `writePdf`; only `fonts` is required. */
|
|
36
|
+
interface WritePdfOptions {
|
|
37
|
+
fonts: PdfFontSource;
|
|
38
|
+
title?: string;
|
|
39
|
+
/** Default true; unit tests pass false because jsdom realms lack `CompressionStream`. */
|
|
40
|
+
compress?: boolean;
|
|
41
|
+
readPixels?: (image: ImageBitmap | HTMLImageElement) => RasterPixels;
|
|
42
|
+
/** `view` is the page's `PdfPage.view`: what a `world`-unit paint in `commands` resolves through. */
|
|
43
|
+
rasterize?: (commands: readonly DrawCommand[], rect: Rect, scale: number, view: GlMat3 | undefined) => Promise<RasterPixels>;
|
|
44
|
+
}
|
|
45
|
+
/** A glyph or command the writer left out of the file, with the reason. */
|
|
46
|
+
interface PdfSkip {
|
|
47
|
+
kind: 'glyph' | 'command';
|
|
48
|
+
detail: string;
|
|
49
|
+
}
|
|
50
|
+
/** The finished file and everything the writer had to leave out of it. */
|
|
51
|
+
interface PdfResult {
|
|
52
|
+
bytes: Uint8Array;
|
|
53
|
+
skipped: readonly PdfSkip[];
|
|
54
|
+
}
|
|
55
|
+
/** One PDF page per entry of `pages`, which must hold at least one. */
|
|
56
|
+
declare function writePdf(pages: readonly PdfPage[], opts: WritePdfOptions): Promise<PdfResult>;
|
|
57
|
+
|
|
58
|
+
export { type PdfFontSource, type PdfPage, type PdfResult, type PdfSkip, type RasterPixels, type Rect, type WritePdfOptions, registryFontSource, writePdf };
|