@zebrash/core 0.1.0 → 0.1.4
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/dist/assets/fonts-browser.d.ts +2 -0
- package/dist/assets/fonts-browser.d.ts.map +1 -1
- package/dist/assets/fonts-browser.js +6 -0
- package/dist/assets/fonts.d.ts +3 -6
- package/dist/assets/fonts.d.ts.map +1 -1
- package/dist/assets/fonts.js +15 -5
- package/dist/assets/index.d.ts +1 -1
- package/dist/assets/index.d.ts.map +1 -1
- package/dist/assets/index.js +1 -1
- package/dist/drawer-options.d.ts +20 -2
- package/dist/drawer-options.d.ts.map +1 -1
- package/dist/drawer-options.js +3 -1
- package/dist/drawer.d.ts +27 -0
- package/dist/drawer.d.ts.map +1 -1
- package/dist/drawer.js +96 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/svg/emitter.d.ts +76 -0
- package/dist/svg/emitter.d.ts.map +1 -0
- package/dist/svg/emitter.js +207 -0
- package/dist/svg/font_embed.d.ts +12 -0
- package/dist/svg/font_embed.d.ts.map +1 -0
- package/dist/svg/font_embed.js +61 -0
- package/dist/svg-drawers/barcode_128.d.ts +3 -0
- package/dist/svg-drawers/barcode_128.d.ts.map +1 -0
- package/dist/svg-drawers/barcode_128.js +74 -0
- package/dist/svg-drawers/barcode_2of5.d.ts +3 -0
- package/dist/svg-drawers/barcode_2of5.d.ts.map +1 -0
- package/dist/svg-drawers/barcode_2of5.js +36 -0
- package/dist/svg-drawers/barcode_39.d.ts +3 -0
- package/dist/svg-drawers/barcode_39.d.ts.map +1 -0
- package/dist/svg-drawers/barcode_39.js +34 -0
- package/dist/svg-drawers/barcode_aztec.d.ts +3 -0
- package/dist/svg-drawers/barcode_aztec.d.ts.map +1 -0
- package/dist/svg-drawers/barcode_aztec.js +48 -0
- package/dist/svg-drawers/barcode_datamatrix.d.ts +3 -0
- package/dist/svg-drawers/barcode_datamatrix.d.ts.map +1 -0
- package/dist/svg-drawers/barcode_datamatrix.js +44 -0
- package/dist/svg-drawers/barcode_ean13.d.ts +3 -0
- package/dist/svg-drawers/barcode_ean13.d.ts.map +1 -0
- package/dist/svg-drawers/barcode_ean13.js +76 -0
- package/dist/svg-drawers/barcode_paint_svg.d.ts +35 -0
- package/dist/svg-drawers/barcode_paint_svg.d.ts.map +1 -0
- package/dist/svg-drawers/barcode_paint_svg.js +144 -0
- package/dist/svg-drawers/barcode_pdf417.d.ts +3 -0
- package/dist/svg-drawers/barcode_pdf417.d.ts.map +1 -0
- package/dist/svg-drawers/barcode_pdf417.js +43 -0
- package/dist/svg-drawers/barcode_qr.d.ts +3 -0
- package/dist/svg-drawers/barcode_qr.d.ts.map +1 -0
- package/dist/svg-drawers/barcode_qr.js +39 -0
- package/dist/svg-drawers/graphic_box.d.ts +3 -0
- package/dist/svg-drawers/graphic_box.d.ts.map +1 -0
- package/dist/svg-drawers/graphic_box.js +64 -0
- package/dist/svg-drawers/graphic_circle.d.ts +3 -0
- package/dist/svg-drawers/graphic_circle.d.ts.map +1 -0
- package/dist/svg-drawers/graphic_circle.js +19 -0
- package/dist/svg-drawers/graphic_diagonal_line.d.ts +3 -0
- package/dist/svg-drawers/graphic_diagonal_line.d.ts.map +1 -0
- package/dist/svg-drawers/graphic_diagonal_line.js +36 -0
- package/dist/svg-drawers/graphic_field.d.ts +3 -0
- package/dist/svg-drawers/graphic_field.d.ts.map +1 -0
- package/dist/svg-drawers/graphic_field.js +72 -0
- package/dist/svg-drawers/index.d.ts +10 -0
- package/dist/svg-drawers/index.d.ts.map +1 -0
- package/dist/svg-drawers/index.js +41 -0
- package/dist/svg-drawers/maxicode.d.ts +3 -0
- package/dist/svg-drawers/maxicode.d.ts.map +1 -0
- package/dist/svg-drawers/maxicode.js +87 -0
- package/dist/svg-drawers/svg_element_drawer.d.ts +13 -0
- package/dist/svg-drawers/svg_element_drawer.d.ts.map +1 -0
- package/dist/svg-drawers/svg_element_drawer.js +2 -0
- package/dist/svg-drawers/text_field.d.ts +3 -0
- package/dist/svg-drawers/text_field.d.ts.map +1 -0
- package/dist/svg-drawers/text_field.js +264 -0
- package/dist/svg-drawers/transform.d.ts +20 -0
- package/dist/svg-drawers/transform.d.ts.map +1 -0
- package/dist/svg-drawers/transform.js +52 -0
- package/package.json +11 -2
- package/dist/assets/fonts-browser.js.map +0 -1
- package/dist/assets/fonts.js.map +0 -1
- package/dist/assets/index.js.map +0 -1
- package/dist/assets/register.js.map +0 -1
- package/dist/barcodes/aztec/azteccode.js.map +0 -1
- package/dist/barcodes/aztec/encoder.js.map +0 -1
- package/dist/barcodes/aztec/errorcorrection.js.map +0 -1
- package/dist/barcodes/aztec/highlevel.js.map +0 -1
- package/dist/barcodes/aztec/index.js.map +0 -1
- package/dist/barcodes/aztec/state.js.map +0 -1
- package/dist/barcodes/aztec/token.js.map +0 -1
- package/dist/barcodes/code128/code128.js.map +0 -1
- package/dist/barcodes/code128/encoder.js.map +0 -1
- package/dist/barcodes/code128/index.js.map +0 -1
- package/dist/barcodes/code39/encoder.js.map +0 -1
- package/dist/barcodes/code39/index.js.map +0 -1
- package/dist/barcodes/datamatrix/datamatrix_writer.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/ascii_encoder.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/base256_encoder.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/byte_matrix.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/c40_encoder.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/datamatrix_symbol_info_144.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/default_placement.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/dimension.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/edifact_encoder.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/encoder.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/encoder_context.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/error_correction.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/high_level_encoder.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/options.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/symbol_info.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/symbol_shape_hint.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/text_encoder.js.map +0 -1
- package/dist/barcodes/datamatrix/encoder/x12_encoder.js.map +0 -1
- package/dist/barcodes/datamatrix/index.js.map +0 -1
- package/dist/barcodes/ean13/ean13.js.map +0 -1
- package/dist/barcodes/ean13/encoder.js.map +0 -1
- package/dist/barcodes/ean13/index.js.map +0 -1
- package/dist/barcodes/maxicode/index.js.map +0 -1
- package/dist/barcodes/maxicode/maxicode.js.map +0 -1
- package/dist/barcodes/maxicode/readsolomon.js.map +0 -1
- package/dist/barcodes/maxicode/symbolgrid.js.map +0 -1
- package/dist/barcodes/pdf417/codewords.js.map +0 -1
- package/dist/barcodes/pdf417/dimensions.js.map +0 -1
- package/dist/barcodes/pdf417/encoder.js.map +0 -1
- package/dist/barcodes/pdf417/errorcorrection.js.map +0 -1
- package/dist/barcodes/pdf417/highlevel.js.map +0 -1
- package/dist/barcodes/pdf417/index.js.map +0 -1
- package/dist/barcodes/qrcode/encoder/block-pair.js.map +0 -1
- package/dist/barcodes/qrcode/encoder/byte-matrix.js.map +0 -1
- package/dist/barcodes/qrcode/encoder/character-set-eci.js.map +0 -1
- package/dist/barcodes/qrcode/encoder/encoder.js.map +0 -1
- package/dist/barcodes/qrcode/encoder/error-correction-level.js.map +0 -1
- package/dist/barcodes/qrcode/encoder/format-information.js.map +0 -1
- package/dist/barcodes/qrcode/encoder/index.js.map +0 -1
- package/dist/barcodes/qrcode/encoder/mask-util.js.map +0 -1
- package/dist/barcodes/qrcode/encoder/matrix-util.js.map +0 -1
- package/dist/barcodes/qrcode/encoder/mode.js.map +0 -1
- package/dist/barcodes/qrcode/encoder/options.js.map +0 -1
- package/dist/barcodes/qrcode/encoder/qrcode.js.map +0 -1
- package/dist/barcodes/qrcode/encoder/string-utils.js.map +0 -1
- package/dist/barcodes/qrcode/encoder/version.js.map +0 -1
- package/dist/barcodes/qrcode/index.js.map +0 -1
- package/dist/barcodes/qrcode/qrcode-writer.js.map +0 -1
- package/dist/barcodes/twooffive/encoder.js.map +0 -1
- package/dist/barcodes/twooffive/index.js.map +0 -1
- package/dist/barcodes/utils/bit_array.js.map +0 -1
- package/dist/barcodes/utils/bit_matrix.js.map +0 -1
- package/dist/barcodes/utils/bitlist.js.map +0 -1
- package/dist/barcodes/utils/bitlist_image.js.map +0 -1
- package/dist/barcodes/utils/bitlist_widenarrow.js.map +0 -1
- package/dist/barcodes/utils/bitops.js.map +0 -1
- package/dist/barcodes/utils/galoisfield.js.map +0 -1
- package/dist/barcodes/utils/gfpoly.js.map +0 -1
- package/dist/barcodes/utils/index.js.map +0 -1
- package/dist/barcodes/utils/reedsolomon.js.map +0 -1
- package/dist/barcodes/utils/runeint.js.map +0 -1
- package/dist/drawer-options.js.map +0 -1
- package/dist/drawer.js.map +0 -1
- package/dist/drawers/barcode_128.js.map +0 -1
- package/dist/drawers/barcode_2of5.js.map +0 -1
- package/dist/drawers/barcode_39.js.map +0 -1
- package/dist/drawers/barcode_aztec.js.map +0 -1
- package/dist/drawers/barcode_datamatrix.js.map +0 -1
- package/dist/drawers/barcode_ean13.js.map +0 -1
- package/dist/drawers/barcode_paint.js.map +0 -1
- package/dist/drawers/barcode_pdf417.js.map +0 -1
- package/dist/drawers/barcode_qr.js.map +0 -1
- package/dist/drawers/drawer_state.js.map +0 -1
- package/dist/drawers/element_drawer.js.map +0 -1
- package/dist/drawers/graphic_box.js.map +0 -1
- package/dist/drawers/graphic_circle.js.map +0 -1
- package/dist/drawers/graphic_diagonal_line.js.map +0 -1
- package/dist/drawers/graphic_field.js.map +0 -1
- package/dist/drawers/index.js.map +0 -1
- package/dist/drawers/maxicode.js.map +0 -1
- package/dist/drawers/text_field.js.map +0 -1
- package/dist/elements/barcode_128.js.map +0 -1
- package/dist/elements/barcode_2of5.js.map +0 -1
- package/dist/elements/barcode_39.js.map +0 -1
- package/dist/elements/barcode_aztec.js.map +0 -1
- package/dist/elements/barcode_datamatrix.js.map +0 -1
- package/dist/elements/barcode_ean13.js.map +0 -1
- package/dist/elements/barcode_info.js.map +0 -1
- package/dist/elements/barcode_pdf417.js.map +0 -1
- package/dist/elements/barcode_qr.js.map +0 -1
- package/dist/elements/field_alignment.js.map +0 -1
- package/dist/elements/field_block.js.map +0 -1
- package/dist/elements/field_info.js.map +0 -1
- package/dist/elements/field_orientation.js.map +0 -1
- package/dist/elements/font.js.map +0 -1
- package/dist/elements/graphic_box.js.map +0 -1
- package/dist/elements/graphic_circle.js.map +0 -1
- package/dist/elements/graphic_diagonal_line.js.map +0 -1
- package/dist/elements/graphic_field.js.map +0 -1
- package/dist/elements/graphic_symbol.js.map +0 -1
- package/dist/elements/index.js.map +0 -1
- package/dist/elements/label_info.js.map +0 -1
- package/dist/elements/label_position.js.map +0 -1
- package/dist/elements/line_color.js.map +0 -1
- package/dist/elements/maxicode.js.map +0 -1
- package/dist/elements/reverse_print.js.map +0 -1
- package/dist/elements/stored_format.js.map +0 -1
- package/dist/elements/stored_graphics.js.map +0 -1
- package/dist/elements/text_alignment.js.map +0 -1
- package/dist/elements/text_field.js.map +0 -1
- package/dist/encodings/decode.js.map +0 -1
- package/dist/encodings/index.js.map +0 -1
- package/dist/hex/decode.js.map +0 -1
- package/dist/hex/index.js.map +0 -1
- package/dist/images/colors.js.map +0 -1
- package/dist/images/encode.js.map +0 -1
- package/dist/images/index.js.map +0 -1
- package/dist/images/reverse_print.js.map +0 -1
- package/dist/images/scaled.js.map +0 -1
- package/dist/images/zerofill.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/parser.js.map +0 -1
- package/dist/parsers/barcode_128.js.map +0 -1
- package/dist/parsers/barcode_2of5.js.map +0 -1
- package/dist/parsers/barcode_39.js.map +0 -1
- package/dist/parsers/barcode_aztec.js.map +0 -1
- package/dist/parsers/barcode_datamatrix.js.map +0 -1
- package/dist/parsers/barcode_ean13.js.map +0 -1
- package/dist/parsers/barcode_field_defaults.js.map +0 -1
- package/dist/parsers/barcode_parsers.js.map +0 -1
- package/dist/parsers/barcode_pdf417.js.map +0 -1
- package/dist/parsers/barcode_qr.js.map +0 -1
- package/dist/parsers/change_charset.js.map +0 -1
- package/dist/parsers/change_default_font.js.map +0 -1
- package/dist/parsers/change_font.js.map +0 -1
- package/dist/parsers/change_font_alias.js.map +0 -1
- package/dist/parsers/command_parser.js.map +0 -1
- package/dist/parsers/download_format.js.map +0 -1
- package/dist/parsers/download_graphics.js.map +0 -1
- package/dist/parsers/download_unbounded_ttf.js.map +0 -1
- package/dist/parsers/field_block.js.map +0 -1
- package/dist/parsers/field_data.js.map +0 -1
- package/dist/parsers/field_number.js.map +0 -1
- package/dist/parsers/field_orientation.js.map +0 -1
- package/dist/parsers/field_origin.js.map +0 -1
- package/dist/parsers/field_reverse_print.js.map +0 -1
- package/dist/parsers/field_separator.js.map +0 -1
- package/dist/parsers/field_typeset.js.map +0 -1
- package/dist/parsers/field_value.js.map +0 -1
- package/dist/parsers/graphic_box.js.map +0 -1
- package/dist/parsers/graphic_circle.js.map +0 -1
- package/dist/parsers/graphic_diagonal_line.js.map +0 -1
- package/dist/parsers/graphic_field.js.map +0 -1
- package/dist/parsers/graphic_format_parsers.js.map +0 -1
- package/dist/parsers/graphic_symbol.js.map +0 -1
- package/dist/parsers/hex_escape.js.map +0 -1
- package/dist/parsers/image_load.js.map +0 -1
- package/dist/parsers/index.js.map +0 -1
- package/dist/parsers/label_home.js.map +0 -1
- package/dist/parsers/label_reverse_print.js.map +0 -1
- package/dist/parsers/maxicode.js.map +0 -1
- package/dist/parsers/print_orientation.js.map +0 -1
- package/dist/parsers/print_width.js.map +0 -1
- package/dist/parsers/recall_format.js.map +0 -1
- package/dist/parsers/recall_graphics.js.map +0 -1
- package/dist/platform/browser.js.map +0 -1
- package/dist/platform/inflate.js.map +0 -1
- package/dist/platform/node.js.map +0 -1
- package/dist/platform/types.js.map +0 -1
- package/dist/platform-browser.js.map +0 -1
- package/dist/platform.js.map +0 -1
- package/dist/printers/fs.js.map +0 -1
- package/dist/printers/index.js.map +0 -1
- package/dist/printers/virtual.js.map +0 -1
|
@@ -11,5 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
export type FontKey = "HelveticaBold" | "DejavuSansMono" | "DejavuSansMonoBold" | "ZplGS";
|
|
13
13
|
export declare function setFontBaseUrl(url: string): void;
|
|
14
|
+
export declare function getFontBaseUrl(): string;
|
|
15
|
+
export declare function getFontFilename(key: FontKey): string;
|
|
14
16
|
export declare function getEmbeddedFont(key: FontKey): Promise<Uint8Array>;
|
|
15
17
|
//# sourceMappingURL=fonts-browser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fonts-browser.d.ts","sourceRoot":"","sources":["../../src/assets/fonts-browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,OAAO,GAAG,eAAe,GAAG,gBAAgB,GAAG,oBAAoB,GAAG,OAAO,CAAC;AAW1F,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEhD;AAKD,wBAAsB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAoBvE"}
|
|
1
|
+
{"version":3,"file":"fonts-browser.d.ts","sourceRoot":"","sources":["../../src/assets/fonts-browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,OAAO,GAAG,eAAe,GAAG,gBAAgB,GAAG,oBAAoB,GAAG,OAAO,CAAC;AAW1F,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAEpD;AAKD,wBAAsB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAoBvE"}
|
|
@@ -19,6 +19,12 @@ let baseUrl = "https://cdn.jsdelivr.net/gh/Fountain-Bio/zebrash-ts@main/src/asse
|
|
|
19
19
|
export function setFontBaseUrl(url) {
|
|
20
20
|
baseUrl = url.endsWith("/") ? url : `${url}/`;
|
|
21
21
|
}
|
|
22
|
+
export function getFontBaseUrl() {
|
|
23
|
+
return baseUrl;
|
|
24
|
+
}
|
|
25
|
+
export function getFontFilename(key) {
|
|
26
|
+
return filenames[key];
|
|
27
|
+
}
|
|
22
28
|
const cache = new Map();
|
|
23
29
|
const inflight = new Map();
|
|
24
30
|
export async function getEmbeddedFont(key) {
|
package/dist/assets/fonts.d.ts
CHANGED
|
@@ -7,10 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
export type FontKey = "HelveticaBold" | "DejavuSansMono" | "DejavuSansMonoBold" | "ZplGS";
|
|
9
9
|
export declare function getEmbeddedFont(key: FontKey): Promise<Uint8Array>;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* API surface.
|
|
14
|
-
*/
|
|
15
|
-
export declare function setFontBaseUrl(_url: string): void;
|
|
10
|
+
export declare function setFontBaseUrl(url: string): void;
|
|
11
|
+
export declare function getFontBaseUrl(): string;
|
|
12
|
+
export declare function getFontFilename(key: FontKey): string;
|
|
16
13
|
//# sourceMappingURL=fonts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../../src/assets/fonts.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AAEH,MAAM,MAAM,OAAO,GAAG,eAAe,GAAG,gBAAgB,GAAG,oBAAoB,GAAG,OAAO,CAAC;AAqB1F,wBAAsB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAMvE;
|
|
1
|
+
{"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../../src/assets/fonts.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AAEH,MAAM,MAAM,OAAO,GAAG,eAAe,GAAG,gBAAgB,GAAG,oBAAoB,GAAG,OAAO,CAAC;AAqB1F,wBAAsB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAMvE;AAYD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAEpD"}
|
package/dist/assets/fonts.js
CHANGED
|
@@ -26,11 +26,21 @@ export async function getEmbeddedFont(key) {
|
|
|
26
26
|
return data;
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
29
|
+
* URL where the bundled TTFs are mirrored. The Node loader reads fonts
|
|
30
|
+
* from disk for canvas rendering, but `drawLabelAsSvg` may emit
|
|
31
|
+
* `@font-face src: url(...)` references — those URLs need to resolve in
|
|
32
|
+
* whichever browser ultimately views the SVG. Defaults to the same
|
|
33
|
+
* jsdelivr URL the browser loader uses; override with `setFontBaseUrl` to
|
|
34
|
+
* point at a self-hosted mirror.
|
|
32
35
|
*/
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
let baseUrl = "https://cdn.jsdelivr.net/gh/Fountain-Bio/zebrash-ts@main/src/assets/fonts/";
|
|
37
|
+
export function setFontBaseUrl(url) {
|
|
38
|
+
baseUrl = url.endsWith("/") ? url : `${url}/`;
|
|
39
|
+
}
|
|
40
|
+
export function getFontBaseUrl() {
|
|
41
|
+
return baseUrl;
|
|
42
|
+
}
|
|
43
|
+
export function getFontFilename(key) {
|
|
44
|
+
return filenames[key];
|
|
35
45
|
}
|
|
36
46
|
//# sourceMappingURL=fonts.js.map
|
package/dist/assets/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { type FontKey, getEmbeddedFont, setFontBaseUrl } from "./fonts.ts";
|
|
1
|
+
export { type FontKey, getEmbeddedFont, getFontBaseUrl, getFontFilename, setFontBaseUrl, } from "./fonts.ts";
|
|
2
2
|
export { EmbeddedFontFamilies, registerEmbeddedFonts } from "./register.ts";
|
|
3
3
|
export type { EmbeddedFontFamily } from "./register.ts";
|
|
4
4
|
export declare const FONT0_NAME = "ZebrashHelveticaBold";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/assets/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/assets/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC5E,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,eAAO,MAAM,UAAU,yBAAyB,CAAC;AACjD,eAAO,MAAM,UAAU,0BAA0B,CAAC;AAElD,eAAO,MAAM,0BAA0B,yBAAyB,CAAC;AACjE,eAAO,MAAM,uBAAuB,0BAA0B,CAAC;AAC/D,eAAO,MAAM,4BAA4B,8BAA8B,CAAC;AACxE,eAAO,MAAM,kBAAkB,iBAAiB,CAAC"}
|
package/dist/assets/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { getEmbeddedFont, setFontBaseUrl } from "./fonts.js";
|
|
1
|
+
export { getEmbeddedFont, getFontBaseUrl, getFontFilename, setFontBaseUrl, } from "./fonts.js";
|
|
2
2
|
export { EmbeddedFontFamilies, registerEmbeddedFonts } from "./register.js";
|
|
3
3
|
export const FONT0_NAME = "ZebrashHelveticaBold";
|
|
4
4
|
export const FONT1_NAME = "ZebrashDejavuSansMono";
|
package/dist/drawer-options.d.ts
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How `<text>` elements declare their font in `drawLabelAsSvg` output. Ignored
|
|
3
|
+
* by `drawLabelAsPng` which always uses platform-registered fonts.
|
|
4
|
+
*
|
|
5
|
+
* - `"url"` (default): emit `@font-face src: url("<cdn>/font.ttf")` so the
|
|
6
|
+
* browser can fetch the same TTFs the runtime font loader uses. Smallest
|
|
7
|
+
* SVGs; requires CDN access at view time.
|
|
8
|
+
* - `"embed"`: base64-inline the TTFs as `data:font/ttf;base64,…`. Fully
|
|
9
|
+
* self-contained; adds ~54KB (Helvetica only) to ~900KB (DejaVu pair) per
|
|
10
|
+
* SVG depending on which families the label references.
|
|
11
|
+
* - `"none"`: emit `font-family` only, no `@font-face` block. Renders only
|
|
12
|
+
* where the host already has the font (system-installed or supplied to
|
|
13
|
+
* the rasteriser directly, as in the test harness).
|
|
14
|
+
*/
|
|
15
|
+
export type SvgFontEmbedMode = "url" | "embed" | "none";
|
|
1
16
|
/**
|
|
2
17
|
* Public drawer options — mirrors Go `drawers.DrawerOptions`.
|
|
3
18
|
*
|
|
@@ -9,13 +24,16 @@ export interface DrawerOptions {
|
|
|
9
24
|
dpmm: number;
|
|
10
25
|
/** Render labels with inverted orientation upside-down. */
|
|
11
26
|
enableInvertedLabels: boolean;
|
|
12
|
-
/** Output 8-bit grayscale PNG preserving anti-aliasing instead of binary monochrome. */
|
|
27
|
+
/** Output 8-bit grayscale PNG preserving anti-aliasing instead of binary monochrome. PNG-only. */
|
|
13
28
|
grayscaleOutput: boolean;
|
|
29
|
+
/** How fonts are referenced in SVG output. SVG-only. */
|
|
30
|
+
fontEmbed: SvgFontEmbedMode;
|
|
14
31
|
}
|
|
15
32
|
/**
|
|
16
33
|
* Returns a copy of `options` with defaults applied for any zero/missing fields.
|
|
17
34
|
*
|
|
18
|
-
* Defaults: 101.6 mm × 203.2 mm at 8 dpmm, monochrome, no inversion
|
|
35
|
+
* Defaults: 101.6 mm × 203.2 mm at 8 dpmm, monochrome, no inversion, SVG
|
|
36
|
+
* fonts referenced by URL.
|
|
19
37
|
*/
|
|
20
38
|
export declare function withDefaults(options?: Partial<DrawerOptions>): DrawerOptions;
|
|
21
39
|
//# sourceMappingURL=drawer-options.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drawer-options.d.ts","sourceRoot":"","sources":["../src/drawer-options.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,oBAAoB,EAAE,OAAO,CAAC;IAC9B,
|
|
1
|
+
{"version":3,"file":"drawer-options.d.ts","sourceRoot":"","sources":["../src/drawer-options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC;AAExD;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,oBAAoB,EAAE,OAAO,CAAC;IAC9B,kGAAkG;IAClG,eAAe,EAAE,OAAO,CAAC;IACzB,wDAAwD;IACxD,SAAS,EAAE,gBAAgB,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,aAAa,CAShF"}
|
package/dist/drawer-options.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Returns a copy of `options` with defaults applied for any zero/missing fields.
|
|
3
3
|
*
|
|
4
|
-
* Defaults: 101.6 mm × 203.2 mm at 8 dpmm, monochrome, no inversion
|
|
4
|
+
* Defaults: 101.6 mm × 203.2 mm at 8 dpmm, monochrome, no inversion, SVG
|
|
5
|
+
* fonts referenced by URL.
|
|
5
6
|
*/
|
|
6
7
|
export function withDefaults(options = {}) {
|
|
7
8
|
return {
|
|
@@ -10,6 +11,7 @@ export function withDefaults(options = {}) {
|
|
|
10
11
|
dpmm: options.dpmm || 8,
|
|
11
12
|
enableInvertedLabels: options.enableInvertedLabels ?? false,
|
|
12
13
|
grayscaleOutput: options.grayscaleOutput ?? false,
|
|
14
|
+
fontEmbed: options.fontEmbed ?? "url",
|
|
13
15
|
};
|
|
14
16
|
}
|
|
15
17
|
//# sourceMappingURL=drawer-options.js.map
|
package/dist/drawer.d.ts
CHANGED
|
@@ -9,7 +9,10 @@ import { type DrawerOptions } from "./drawer-options.ts";
|
|
|
9
9
|
*/
|
|
10
10
|
export declare class Drawer {
|
|
11
11
|
private readonly elementDrawers;
|
|
12
|
+
private svgElementDrawers;
|
|
12
13
|
constructor(elementDrawers?: ElementDrawer[]);
|
|
14
|
+
/** Lazy SVG drawer set — only constructed when `drawLabelAsSvg` is called. */
|
|
15
|
+
private getSvgElementDrawers;
|
|
13
16
|
/**
|
|
14
17
|
* Renders `label` to a PNG `Buffer` according to `options`.
|
|
15
18
|
*
|
|
@@ -23,5 +26,29 @@ export declare class Drawer {
|
|
|
23
26
|
* - Encode as monochrome PNG by default, or 8-bit grayscale when requested.
|
|
24
27
|
*/
|
|
25
28
|
drawLabelAsPng(label: LabelInfo, options?: Partial<DrawerOptions>): Promise<Uint8Array>;
|
|
29
|
+
/**
|
|
30
|
+
* Renders `label` to an SVG document string according to `options`.
|
|
31
|
+
*
|
|
32
|
+
* Behaviour parity with `drawLabelAsPng` for everything geometric:
|
|
33
|
+
* - Apply `withDefaults` to the options.
|
|
34
|
+
* - Compute `imageWidth = min(labelWidth, label.printWidth)`.
|
|
35
|
+
* - Reverse-print elements are wrapped in a
|
|
36
|
+
* `<g style="mix-blend-mode: difference">` group, which is
|
|
37
|
+
* mathematically equivalent to the XOR composite the PNG path uses
|
|
38
|
+
* when the canvas only holds black-on-white (the monochrome case).
|
|
39
|
+
* - If the print width is narrower than the label, or the label is
|
|
40
|
+
* inverted, content is centred and optionally rotated 180° via outer
|
|
41
|
+
* `<g transform>` wrappers — same arithmetic as the canvas pipeline.
|
|
42
|
+
*
|
|
43
|
+
* SVG-specific behaviour (controlled by `options.fontEmbed`):
|
|
44
|
+
* - `"url"` (default): emits one `@font-face url(...)` per used font,
|
|
45
|
+
* pointing at the same CDN base the runtime font loader uses.
|
|
46
|
+
* - `"embed"`: base64-inlines the TTF bytes (large, fully self-contained).
|
|
47
|
+
* - `"none"`: omits `@font-face` entirely (caller supplies fonts to the
|
|
48
|
+
* rasteriser, or the host has them installed).
|
|
49
|
+
*
|
|
50
|
+
* `grayscaleOutput` is ignored (PNG-only encoding concern).
|
|
51
|
+
*/
|
|
52
|
+
drawLabelAsSvg(label: LabelInfo, options?: Partial<DrawerOptions>): Promise<string>;
|
|
26
53
|
}
|
|
27
54
|
//# sourceMappingURL=drawer.d.ts.map
|
package/dist/drawer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drawer.d.ts","sourceRoot":"","sources":["../src/drawer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,EAAE,KAAK,aAAa,EAAgB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"drawer.d.ts","sourceRoot":"","sources":["../src/drawer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,EAAE,KAAK,aAAa,EAAgB,MAAM,qBAAqB,CAAC;AA2CvE;;;;;GAKG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkB;IACjD,OAAO,CAAC,iBAAiB,CAAmC;gBAEhD,cAAc,CAAC,EAAE,aAAa,EAAE;IAI5C,8EAA8E;IAC9E,OAAO,CAAC,oBAAoB;IAO5B;;;;;;;;;;;OAWG;IACG,cAAc,CAClB,KAAK,EAAE,SAAS,EAChB,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GACnC,OAAO,CAAC,UAAU,CAAC;IAwEtB;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACG,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAkF9F"}
|
package/dist/drawer.js
CHANGED
|
@@ -3,6 +3,9 @@ import { DrawerState } from "./drawers/drawer_state.js";
|
|
|
3
3
|
import { defaultElementDrawers as defaultElementDrawersLazy } from "./drawers/index.js";
|
|
4
4
|
import { colorWhite, encodeGrayscale, encodeMonochrome, reversePrint, zerofill, } from "./images/index.js";
|
|
5
5
|
import { platform } from "./platform.js";
|
|
6
|
+
import { defaultSvgElementDrawers } from "./svg-drawers/index.js";
|
|
7
|
+
import { SvgEmitter } from "./svg/emitter.js";
|
|
8
|
+
import { buildFontFaceCss } from "./svg/font_embed.js";
|
|
6
9
|
function isReversePrintable(element) {
|
|
7
10
|
if (typeof element !== "object" || element === null)
|
|
8
11
|
return false;
|
|
@@ -25,9 +28,17 @@ function fillWhite(ctx, width, height) {
|
|
|
25
28
|
*/
|
|
26
29
|
export class Drawer {
|
|
27
30
|
elementDrawers;
|
|
31
|
+
svgElementDrawers = null;
|
|
28
32
|
constructor(elementDrawers) {
|
|
29
33
|
this.elementDrawers = elementDrawers ?? defaultElementDrawersLazy();
|
|
30
34
|
}
|
|
35
|
+
/** Lazy SVG drawer set — only constructed when `drawLabelAsSvg` is called. */
|
|
36
|
+
getSvgElementDrawers() {
|
|
37
|
+
if (this.svgElementDrawers === null) {
|
|
38
|
+
this.svgElementDrawers = defaultSvgElementDrawers();
|
|
39
|
+
}
|
|
40
|
+
return this.svgElementDrawers;
|
|
41
|
+
}
|
|
31
42
|
/**
|
|
32
43
|
* Renders `label` to a PNG `Buffer` according to `options`.
|
|
33
44
|
*
|
|
@@ -98,5 +109,90 @@ export class Drawer {
|
|
|
98
109
|
? encodeGrayscale(finalCtx.canvas)
|
|
99
110
|
: encodeMonochrome(finalCtx.canvas);
|
|
100
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Renders `label` to an SVG document string according to `options`.
|
|
114
|
+
*
|
|
115
|
+
* Behaviour parity with `drawLabelAsPng` for everything geometric:
|
|
116
|
+
* - Apply `withDefaults` to the options.
|
|
117
|
+
* - Compute `imageWidth = min(labelWidth, label.printWidth)`.
|
|
118
|
+
* - Reverse-print elements are wrapped in a
|
|
119
|
+
* `<g style="mix-blend-mode: difference">` group, which is
|
|
120
|
+
* mathematically equivalent to the XOR composite the PNG path uses
|
|
121
|
+
* when the canvas only holds black-on-white (the monochrome case).
|
|
122
|
+
* - If the print width is narrower than the label, or the label is
|
|
123
|
+
* inverted, content is centred and optionally rotated 180° via outer
|
|
124
|
+
* `<g transform>` wrappers — same arithmetic as the canvas pipeline.
|
|
125
|
+
*
|
|
126
|
+
* SVG-specific behaviour (controlled by `options.fontEmbed`):
|
|
127
|
+
* - `"url"` (default): emits one `@font-face url(...)` per used font,
|
|
128
|
+
* pointing at the same CDN base the runtime font loader uses.
|
|
129
|
+
* - `"embed"`: base64-inlines the TTF bytes (large, fully self-contained).
|
|
130
|
+
* - `"none"`: omits `@font-face` entirely (caller supplies fonts to the
|
|
131
|
+
* rasteriser, or the host has them installed).
|
|
132
|
+
*
|
|
133
|
+
* `grayscaleOutput` is ignored (PNG-only encoding concern).
|
|
134
|
+
*/
|
|
135
|
+
async drawLabelAsSvg(label, options = {}) {
|
|
136
|
+
const opts = withDefaults(options);
|
|
137
|
+
const state = new DrawerState();
|
|
138
|
+
const labelWidth = Math.ceil(opts.labelWidthMm * opts.dpmm);
|
|
139
|
+
const imageHeight = Math.ceil(opts.labelHeightMm * opts.dpmm);
|
|
140
|
+
let imageWidth = labelWidth;
|
|
141
|
+
if (label.printWidth > 0) {
|
|
142
|
+
imageWidth = Math.min(labelWidth, label.printWidth);
|
|
143
|
+
}
|
|
144
|
+
const emitter = new SvgEmitter();
|
|
145
|
+
// White background. SVG needs an explicit rect — `<svg>` itself is
|
|
146
|
+
// transparent.
|
|
147
|
+
emitter.rect(0, 0, labelWidth, imageHeight, colorWhite);
|
|
148
|
+
// Mirror the PNG path's outer composition: if `imageWidth < labelWidth`
|
|
149
|
+
// or the label is inverted, wrap content in groups that translate /
|
|
150
|
+
// rotate the inner drawing into place.
|
|
151
|
+
const invertLabel = opts.enableInvertedLabels && label.inverted;
|
|
152
|
+
emitter.save();
|
|
153
|
+
if (invertLabel) {
|
|
154
|
+
// Rotate 180° about the canvas centre — equivalent to the canvas
|
|
155
|
+
// pipeline's `translate(W,H); scale(-1,-1)`.
|
|
156
|
+
emitter.translate(labelWidth, imageHeight);
|
|
157
|
+
emitter.scale(-1, -1);
|
|
158
|
+
}
|
|
159
|
+
if (imageWidth !== labelWidth) {
|
|
160
|
+
emitter.translate(Math.floor((labelWidth - imageWidth) / 2), 0);
|
|
161
|
+
}
|
|
162
|
+
const svgDrawers = this.getSvgElementDrawers();
|
|
163
|
+
let reverseFilterDefined = false;
|
|
164
|
+
for (const element of label.elements) {
|
|
165
|
+
const reverse = isReversePrintable(element) && isReversePrintActive(element);
|
|
166
|
+
if (reverse) {
|
|
167
|
+
if (!reverseFilterDefined) {
|
|
168
|
+
// The canvas reverse-print operation is `dst = 255 - dst` wherever
|
|
169
|
+
// the element drew (regardless of the colour the element drew in).
|
|
170
|
+
// To replicate this with SVG blend modes, we map the element's
|
|
171
|
+
// drawn pixels to white via `feFlood` masked by `SourceAlpha`, then
|
|
172
|
+
// composite the result with `mix-blend-mode: difference`:
|
|
173
|
+
// white over black dst → |255 − 0| = 255 (white)
|
|
174
|
+
// white over white dst → |255 − 255| = 0 (black)
|
|
175
|
+
// i.e. inversion of dst wherever the element drew. The element
|
|
176
|
+
// drawers continue to use black ink — the filter handles the
|
|
177
|
+
// colour swap so no per-drawer change is required.
|
|
178
|
+
emitter.defineFragment("zb-reverse", '<filter id="zb-reverse" x="0%" y="0%" width="100%" height="100%">' +
|
|
179
|
+
'<feFlood flood-color="#ffffff" result="flood"/>' +
|
|
180
|
+
'<feComposite in="flood" in2="SourceAlpha" operator="in"/>' +
|
|
181
|
+
"</filter>");
|
|
182
|
+
reverseFilterDefined = true;
|
|
183
|
+
}
|
|
184
|
+
emitter.pushGroup('filter="url(#zb-reverse)" style="mix-blend-mode:difference;isolation:auto"');
|
|
185
|
+
}
|
|
186
|
+
for (const drawer of svgDrawers) {
|
|
187
|
+
await drawer.draw(emitter, element, opts, state);
|
|
188
|
+
}
|
|
189
|
+
if (reverse) {
|
|
190
|
+
emitter.popGroup();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
emitter.restore();
|
|
194
|
+
const fontFaceCss = await buildFontFaceCss(emitter.usedFonts, opts.fontEmbed);
|
|
195
|
+
return emitter.toSvg(labelWidth, imageHeight, fontFaceCss);
|
|
196
|
+
}
|
|
101
197
|
}
|
|
102
198
|
//# sourceMappingURL=drawer.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export { Parser } from "./parser.ts";
|
|
2
2
|
export { Drawer } from "./drawer.ts";
|
|
3
|
-
export type { DrawerOptions } from "./drawer-options.ts";
|
|
3
|
+
export type { DrawerOptions, SvgFontEmbedMode } from "./drawer-options.ts";
|
|
4
4
|
export { withDefaults as drawerOptionsWithDefaults } from "./drawer-options.ts";
|
|
5
5
|
export type { LabelInfo } from "./elements/index.ts";
|
|
6
|
+
export { SvgEmitter } from "./svg/emitter.ts";
|
|
7
|
+
export type { SvgElementDrawer } from "./svg-drawers/index.ts";
|
|
8
|
+
export { defaultSvgElementDrawers } from "./svg-drawers/index.ts";
|
|
6
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,YAAY,IAAI,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChF,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAIrD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,4 +5,8 @@
|
|
|
5
5
|
export { Parser } from "./parser.js";
|
|
6
6
|
export { Drawer } from "./drawer.js";
|
|
7
7
|
export { withDefaults as drawerOptionsWithDefaults } from "./drawer-options.js";
|
|
8
|
+
// SVG output surface — for advanced consumers who want to register custom
|
|
9
|
+
// per-element SVG emitters.
|
|
10
|
+
export { SvgEmitter } from "./svg/emitter.js";
|
|
11
|
+
export { defaultSvgElementDrawers } from "./svg-drawers/index.js";
|
|
8
12
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { FontKey } from "../assets/fonts.ts";
|
|
2
|
+
/**
|
|
3
|
+
* SVG-side analog of `CanvasRenderingContext2D` used by the per-element SVG
|
|
4
|
+
* drawers. Pure string assembly — no platform dependency, identical
|
|
5
|
+
* behaviour on Node and browser.
|
|
6
|
+
*
|
|
7
|
+
* The transform model mirrors canvas: `save` snapshots the current state and
|
|
8
|
+
* `restore` rolls back to it. `translate`/`rotate`/`scale` and `pushGroup`
|
|
9
|
+
* each emit a `<g>` open whose matching close is deferred until the next
|
|
10
|
+
* `restore` (or `popGroup`). This lets the SVG drawers stay near
|
|
11
|
+
* line-for-line ports of their canvas siblings.
|
|
12
|
+
*/
|
|
13
|
+
export declare class SvgEmitter {
|
|
14
|
+
private body;
|
|
15
|
+
private defs;
|
|
16
|
+
private readonly definedSymbols;
|
|
17
|
+
private readonly saveStack;
|
|
18
|
+
private openGroups;
|
|
19
|
+
private readonly fonts;
|
|
20
|
+
save(): void;
|
|
21
|
+
restore(): void;
|
|
22
|
+
translate(tx: number, ty: number): void;
|
|
23
|
+
rotate(radians: number): void;
|
|
24
|
+
scale(sx: number, sy: number): void;
|
|
25
|
+
/** Open a group with arbitrary attributes (style, mask, etc.). */
|
|
26
|
+
pushGroup(attrs: string): void;
|
|
27
|
+
popGroup(): void;
|
|
28
|
+
rect(x: number, y: number, width: number, height: number, fill: string): void;
|
|
29
|
+
/**
|
|
30
|
+
* Stroked rectangle outline. Width and height are the outer extents; the
|
|
31
|
+
* stroke is centred on the path so the caller is responsible for any
|
|
32
|
+
* inset that mirrors the canvas drawer's `border / 2` adjustment.
|
|
33
|
+
*/
|
|
34
|
+
rectStroke(x: number, y: number, width: number, height: number, stroke: string, strokeWidth: number): void;
|
|
35
|
+
/**
|
|
36
|
+
* Two-rect "donut" emitted as a single `<path>` with `fill-rule: evenodd`.
|
|
37
|
+
* Mirrors the canvas drawer's rounded-rect-with-inner-cutout pattern used
|
|
38
|
+
* by `^GB` (graphic box) when `cornerRounding > 0`.
|
|
39
|
+
*/
|
|
40
|
+
roundedDonut(x: number, y: number, w: number, h: number, rOuter: number, innerX: number, innerY: number, innerW: number, innerH: number, rInner: number, fill: string): void;
|
|
41
|
+
roundedRect(x: number, y: number, w: number, h: number, r: number, fill: string): void;
|
|
42
|
+
polygon(points: ReadonlyArray<readonly [number, number]>, fill: string): void;
|
|
43
|
+
circleStroke(cx: number, cy: number, r: number, stroke: string, strokeWidth: number): void;
|
|
44
|
+
/** Reuse a previously-defined `<symbol id>` at (x, y). Used by maxicode. */
|
|
45
|
+
use(id: string, x: number, y: number): void;
|
|
46
|
+
/**
|
|
47
|
+
* Define a `<symbol>` once, by id, in the SVG `<defs>`. No-ops on repeat
|
|
48
|
+
* calls with the same id, so callers can lazily ensure a symbol exists.
|
|
49
|
+
*/
|
|
50
|
+
defineSymbol(id: string, fragment: string): void;
|
|
51
|
+
/**
|
|
52
|
+
* Define a raw `<defs>` fragment once, by id. The `<defs>` body is kept
|
|
53
|
+
* unique by tracking ids in `definedSymbols` (despite the name —
|
|
54
|
+
* tracking-set is shared so any defs id is global to the document).
|
|
55
|
+
*/
|
|
56
|
+
defineFragment(id: string, fragment: string): void;
|
|
57
|
+
text(x: number, y: number, str: string, opts: {
|
|
58
|
+
fontFamily: string;
|
|
59
|
+
fontSize: number;
|
|
60
|
+
fontKey?: FontKey | undefined;
|
|
61
|
+
anchor?: "start" | "middle" | "end";
|
|
62
|
+
baseline?: "alphabetic" | "hanging" | "middle" | "text-top";
|
|
63
|
+
fill?: string;
|
|
64
|
+
}): void;
|
|
65
|
+
image(href: string, x: number, y: number, width: number, height: number): void;
|
|
66
|
+
/** Set of `FontKey`s referenced by `text` calls so far. */
|
|
67
|
+
get usedFonts(): ReadonlySet<FontKey>;
|
|
68
|
+
/**
|
|
69
|
+
* Wrap the accumulated body in an `<svg>` root and return the document.
|
|
70
|
+
* `extraDefs` is interpolated inside `<defs>` (use it for `@font-face`).
|
|
71
|
+
* The internal `<symbol>` defs collected via `defineSymbol` are emitted
|
|
72
|
+
* unconditionally.
|
|
73
|
+
*/
|
|
74
|
+
toSvg(width: number, height: number, extraDefs: string): string;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=emitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/svg/emitter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG-side analog of `CanvasRenderingContext2D` used by the per-element SVG
|
|
3
|
+
* drawers. Pure string assembly — no platform dependency, identical
|
|
4
|
+
* behaviour on Node and browser.
|
|
5
|
+
*
|
|
6
|
+
* The transform model mirrors canvas: `save` snapshots the current state and
|
|
7
|
+
* `restore` rolls back to it. `translate`/`rotate`/`scale` and `pushGroup`
|
|
8
|
+
* each emit a `<g>` open whose matching close is deferred until the next
|
|
9
|
+
* `restore` (or `popGroup`). This lets the SVG drawers stay near
|
|
10
|
+
* line-for-line ports of their canvas siblings.
|
|
11
|
+
*/
|
|
12
|
+
export class SvgEmitter {
|
|
13
|
+
body = "";
|
|
14
|
+
defs = "";
|
|
15
|
+
definedSymbols = new Set();
|
|
16
|
+
saveStack = [];
|
|
17
|
+
openGroups = 0;
|
|
18
|
+
fonts = new Set();
|
|
19
|
+
save() {
|
|
20
|
+
this.saveStack.push(this.openGroups);
|
|
21
|
+
}
|
|
22
|
+
restore() {
|
|
23
|
+
const target = this.saveStack.pop() ?? 0;
|
|
24
|
+
while (this.openGroups > target) {
|
|
25
|
+
this.body += "</g>";
|
|
26
|
+
this.openGroups -= 1;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
translate(tx, ty) {
|
|
30
|
+
if (tx === 0 && ty === 0)
|
|
31
|
+
return;
|
|
32
|
+
this.body += `<g transform="translate(${n(tx)} ${n(ty)})">`;
|
|
33
|
+
this.openGroups += 1;
|
|
34
|
+
}
|
|
35
|
+
rotate(radians) {
|
|
36
|
+
if (radians === 0)
|
|
37
|
+
return;
|
|
38
|
+
const degrees = (radians * 180) / Math.PI;
|
|
39
|
+
this.body += `<g transform="rotate(${n(degrees)})">`;
|
|
40
|
+
this.openGroups += 1;
|
|
41
|
+
}
|
|
42
|
+
scale(sx, sy) {
|
|
43
|
+
if (sx === 1 && sy === 1)
|
|
44
|
+
return;
|
|
45
|
+
this.body += `<g transform="scale(${n(sx)} ${n(sy)})">`;
|
|
46
|
+
this.openGroups += 1;
|
|
47
|
+
}
|
|
48
|
+
/** Open a group with arbitrary attributes (style, mask, etc.). */
|
|
49
|
+
pushGroup(attrs) {
|
|
50
|
+
this.body += attrs.length > 0 ? `<g ${attrs}>` : "<g>";
|
|
51
|
+
this.openGroups += 1;
|
|
52
|
+
}
|
|
53
|
+
popGroup() {
|
|
54
|
+
if (this.openGroups === 0)
|
|
55
|
+
return;
|
|
56
|
+
this.body += "</g>";
|
|
57
|
+
this.openGroups -= 1;
|
|
58
|
+
}
|
|
59
|
+
rect(x, y, width, height, fill) {
|
|
60
|
+
if (width <= 0 || height <= 0)
|
|
61
|
+
return;
|
|
62
|
+
this.body += `<rect x="${n(x)}" y="${n(y)}" width="${n(width)}" height="${n(height)}" fill="${fill}"/>`;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Stroked rectangle outline. Width and height are the outer extents; the
|
|
66
|
+
* stroke is centred on the path so the caller is responsible for any
|
|
67
|
+
* inset that mirrors the canvas drawer's `border / 2` adjustment.
|
|
68
|
+
*/
|
|
69
|
+
rectStroke(x, y, width, height, stroke, strokeWidth) {
|
|
70
|
+
this.body += `<rect x="${n(x)}" y="${n(y)}" width="${n(width)}" height="${n(height)}" fill="none" stroke="${stroke}" stroke-width="${n(strokeWidth)}"/>`;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Two-rect "donut" emitted as a single `<path>` with `fill-rule: evenodd`.
|
|
74
|
+
* Mirrors the canvas drawer's rounded-rect-with-inner-cutout pattern used
|
|
75
|
+
* by `^GB` (graphic box) when `cornerRounding > 0`.
|
|
76
|
+
*/
|
|
77
|
+
roundedDonut(x, y, w, h, rOuter, innerX, innerY, innerW, innerH, rInner, fill) {
|
|
78
|
+
const outer = roundedRectPath(x, y, w, h, rOuter);
|
|
79
|
+
if (innerW <= 0 || innerH <= 0 || rInner <= 0) {
|
|
80
|
+
this.body += `<path d="${outer}" fill="${fill}"/>`;
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const inner = roundedRectPath(innerX, innerY, innerW, innerH, rInner);
|
|
84
|
+
this.body += `<path d="${outer} ${inner}" fill="${fill}" fill-rule="evenodd"/>`;
|
|
85
|
+
}
|
|
86
|
+
roundedRect(x, y, w, h, r, fill) {
|
|
87
|
+
this.body += `<path d="${roundedRectPath(x, y, w, h, r)}" fill="${fill}"/>`;
|
|
88
|
+
}
|
|
89
|
+
polygon(points, fill) {
|
|
90
|
+
if (points.length === 0)
|
|
91
|
+
return;
|
|
92
|
+
const pts = points.map(([x, y]) => `${n(x)},${n(y)}`).join(" ");
|
|
93
|
+
this.body += `<polygon points="${pts}" fill="${fill}"/>`;
|
|
94
|
+
}
|
|
95
|
+
circleStroke(cx, cy, r, stroke, strokeWidth) {
|
|
96
|
+
this.body += `<circle cx="${n(cx)}" cy="${n(cy)}" r="${n(r)}" fill="none" stroke="${stroke}" stroke-width="${n(strokeWidth)}"/>`;
|
|
97
|
+
}
|
|
98
|
+
/** Reuse a previously-defined `<symbol id>` at (x, y). Used by maxicode. */
|
|
99
|
+
use(id, x, y) {
|
|
100
|
+
this.body += `<use href="#${id}" x="${n(x)}" y="${n(y)}"/>`;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Define a `<symbol>` once, by id, in the SVG `<defs>`. No-ops on repeat
|
|
104
|
+
* calls with the same id, so callers can lazily ensure a symbol exists.
|
|
105
|
+
*/
|
|
106
|
+
defineSymbol(id, fragment) {
|
|
107
|
+
if (this.definedSymbols.has(id))
|
|
108
|
+
return;
|
|
109
|
+
this.definedSymbols.add(id);
|
|
110
|
+
this.defs += `<symbol id="${id}" overflow="visible">${fragment}</symbol>`;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Define a raw `<defs>` fragment once, by id. The `<defs>` body is kept
|
|
114
|
+
* unique by tracking ids in `definedSymbols` (despite the name —
|
|
115
|
+
* tracking-set is shared so any defs id is global to the document).
|
|
116
|
+
*/
|
|
117
|
+
defineFragment(id, fragment) {
|
|
118
|
+
if (this.definedSymbols.has(id))
|
|
119
|
+
return;
|
|
120
|
+
this.definedSymbols.add(id);
|
|
121
|
+
this.defs += fragment;
|
|
122
|
+
}
|
|
123
|
+
text(x, y, str, opts) {
|
|
124
|
+
if (opts.fontKey !== undefined)
|
|
125
|
+
this.fonts.add(opts.fontKey);
|
|
126
|
+
const anchor = opts.anchor ?? "start";
|
|
127
|
+
const fill = opts.fill ?? "#000000";
|
|
128
|
+
const baseline = opts.baseline ?? "alphabetic";
|
|
129
|
+
// SVG `dominant-baseline: alphabetic` is the canvas default; emit only
|
|
130
|
+
// when overridden so the attribute set stays terse.
|
|
131
|
+
const baselineAttr = baseline === "alphabetic" ? "" : ` dominant-baseline="${baseline}"`;
|
|
132
|
+
this.body += `<text x="${n(x)}" y="${n(y)}" font-family="${escapeAttr(opts.fontFamily)}" font-size="${n(opts.fontSize)}" fill="${fill}" text-anchor="${anchor}"${baselineAttr}>${escapeText(str)}</text>`;
|
|
133
|
+
}
|
|
134
|
+
image(href, x, y, width, height) {
|
|
135
|
+
if (width <= 0 || height <= 0)
|
|
136
|
+
return;
|
|
137
|
+
// `image-rendering: pixelated` keeps `^GF` bitmaps crisp when the SVG
|
|
138
|
+
// is scaled up — matches the nearest-neighbor look of the PNG path.
|
|
139
|
+
this.body += `<image href="${escapeAttr(href)}" x="${n(x)}" y="${n(y)}" width="${n(width)}" height="${n(height)}" preserveAspectRatio="none" style="image-rendering:pixelated"/>`;
|
|
140
|
+
}
|
|
141
|
+
/** Set of `FontKey`s referenced by `text` calls so far. */
|
|
142
|
+
get usedFonts() {
|
|
143
|
+
return this.fonts;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Wrap the accumulated body in an `<svg>` root and return the document.
|
|
147
|
+
* `extraDefs` is interpolated inside `<defs>` (use it for `@font-face`).
|
|
148
|
+
* The internal `<symbol>` defs collected via `defineSymbol` are emitted
|
|
149
|
+
* unconditionally.
|
|
150
|
+
*/
|
|
151
|
+
toSvg(width, height, extraDefs) {
|
|
152
|
+
// Close any groups the caller forgot to balance — defensive, mirrors
|
|
153
|
+
// canvas's tolerance for unbalanced save/restore.
|
|
154
|
+
while (this.openGroups > 0) {
|
|
155
|
+
this.body += "</g>";
|
|
156
|
+
this.openGroups -= 1;
|
|
157
|
+
}
|
|
158
|
+
const defsBody = `${extraDefs}${this.defs}`;
|
|
159
|
+
const defsBlock = defsBody.length > 0 ? `<defs>${defsBody}</defs>` : "";
|
|
160
|
+
return (`<svg xmlns="http://www.w3.org/2000/svg" width="${n(width)}" height="${n(height)}" viewBox="0 0 ${n(width)} ${n(height)}">` +
|
|
161
|
+
defsBlock +
|
|
162
|
+
this.body +
|
|
163
|
+
"</svg>");
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Format a number for SVG attribute output. Trims trailing zeros and emits
|
|
168
|
+
* integers without a decimal point. 3 decimal places balances precision
|
|
169
|
+
* (≤ 1/1000 of a pixel) against output size.
|
|
170
|
+
*/
|
|
171
|
+
function n(v) {
|
|
172
|
+
if (Number.isInteger(v))
|
|
173
|
+
return v.toString();
|
|
174
|
+
const s = v.toFixed(3);
|
|
175
|
+
// Trim trailing zeros and a dangling decimal point.
|
|
176
|
+
return s.replace(/(\.\d*?)0+$/, "$1").replace(/\.$/, "");
|
|
177
|
+
}
|
|
178
|
+
function escapeText(s) {
|
|
179
|
+
return s.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
180
|
+
}
|
|
181
|
+
function escapeAttr(s) {
|
|
182
|
+
return s
|
|
183
|
+
.replaceAll("&", "&")
|
|
184
|
+
.replaceAll("<", "<")
|
|
185
|
+
.replaceAll(">", ">")
|
|
186
|
+
.replaceAll('"', """);
|
|
187
|
+
}
|
|
188
|
+
function roundedRectPath(x, y, w, h, r) {
|
|
189
|
+
// Clamp r to half the smaller side, matching SVG's <rect rx ry> behaviour
|
|
190
|
+
// and the canvas drawer's intent.
|
|
191
|
+
const radius = Math.max(0, Math.min(r, Math.min(w, h) / 2));
|
|
192
|
+
if (radius === 0) {
|
|
193
|
+
return `M${n(x)} ${n(y)} h${n(w)} v${n(h)} h${n(-w)} Z`;
|
|
194
|
+
}
|
|
195
|
+
const x2 = x + w;
|
|
196
|
+
const y2 = y + h;
|
|
197
|
+
return (`M${n(x + radius)} ${n(y)} ` +
|
|
198
|
+
`H${n(x2 - radius)} ` +
|
|
199
|
+
`A${n(radius)} ${n(radius)} 0 0 1 ${n(x2)} ${n(y + radius)} ` +
|
|
200
|
+
`V${n(y2 - radius)} ` +
|
|
201
|
+
`A${n(radius)} ${n(radius)} 0 0 1 ${n(x2 - radius)} ${n(y2)} ` +
|
|
202
|
+
`H${n(x + radius)} ` +
|
|
203
|
+
`A${n(radius)} ${n(radius)} 0 0 1 ${n(x)} ${n(y2 - radius)} ` +
|
|
204
|
+
`V${n(y + radius)} ` +
|
|
205
|
+
`A${n(radius)} ${n(radius)} 0 0 1 ${n(x + radius)} ${n(y)} Z`);
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=emitter.js.map
|