From 5e2898f842269e8de4737770a2f5c423d14802ff Mon Sep 17 00:00:00 2001 From: Erwan Vivien Date: Mon, 11 Mar 2024 10:38:13 +0100 Subject: [PATCH 1/2] feat: add option for ECL/Version in Wasm --- pkg/fast_qr.d.ts | 210 +++++++++++++++++++++++++++++++++-- pkg/fast_qr.js | 232 +++++++++++++++++++++++++++++++++++++-- pkg/fast_qr_bg.wasm.d.ts | 6 +- pkg/package.json | 4 +- src/ecl.rs | 1 + src/version.rs | 1 + src/wasm.rs | 28 ++++- 7 files changed, 455 insertions(+), 27 deletions(-) diff --git a/pkg/fast_qr.d.ts b/pkg/fast_qr.d.ts index 772f70e..98c84e1 100644 --- a/pkg/fast_qr.d.ts +++ b/pkg/fast_qr.d.ts @@ -60,6 +60,192 @@ export enum ImageBackgroundShape { RoundedSquare = 2, } /** +* Error Correction Coding has 4 levels +*/ +export enum ECL { +/** +* Low, 7% +*/ + L = 0, +/** +* Medium, 15% +*/ + M = 1, +/** +* Quartile, 25% +*/ + Q = 2, +/** +* High, 30% +*/ + H = 3, +} +/** +* Enum containing all possible `QRCode` versions +*/ +export enum Version { +/** +* Version n°01 +*/ + V01 = 0, +/** +* Version n°02 +*/ + V02 = 1, +/** +* Version n°03 +*/ + V03 = 2, +/** +* Version n°04 +*/ + V04 = 3, +/** +* Version n°05 +*/ + V05 = 4, +/** +* Version n°06 +*/ + V06 = 5, +/** +* Version n°07 +*/ + V07 = 6, +/** +* Version n°08 +*/ + V08 = 7, +/** +* Version n°09 +*/ + V09 = 8, +/** +* Version n°10 +*/ + V10 = 9, +/** +* Version n°11 +*/ + V11 = 10, +/** +* Version n°12 +*/ + V12 = 11, +/** +* Version n°13 +*/ + V13 = 12, +/** +* Version n°14 +*/ + V14 = 13, +/** +* Version n°15 +*/ + V15 = 14, +/** +* Version n°16 +*/ + V16 = 15, +/** +* Version n°17 +*/ + V17 = 16, +/** +* Version n°18 +*/ + V18 = 17, +/** +* Version n°19 +*/ + V19 = 18, +/** +* Version n°20 +*/ + V20 = 19, +/** +* Version n°21 +*/ + V21 = 20, +/** +* Version n°22 +*/ + V22 = 21, +/** +* Version n°23 +*/ + V23 = 22, +/** +* Version n°24 +*/ + V24 = 23, +/** +* Version n°25 +*/ + V25 = 24, +/** +* Version n°26 +*/ + V26 = 25, +/** +* Version n°27 +*/ + V27 = 26, +/** +* Version n°28 +*/ + V28 = 27, +/** +* Version n°29 +*/ + V29 = 28, +/** +* Version n°30 +*/ + V30 = 29, +/** +* Version n°31 +*/ + V31 = 30, +/** +* Version n°32 +*/ + V32 = 31, +/** +* Version n°33 +*/ + V33 = 32, +/** +* Version n°34 +*/ + V34 = 33, +/** +* Version n°35 +*/ + V35 = 34, +/** +* Version n°36 +*/ + V36 = 35, +/** +* Version n°37 +*/ + V37 = 36, +/** +* Version n°38 +*/ + V38 = 37, +/** +* Version n°39 +*/ + V39 = 38, +/** +* Version n°40 +*/ + V40 = 39, +} +/** * Configuration for the SVG output. */ export class SvgOptions { @@ -120,6 +306,18 @@ export class SvgOptions { */ image_position(image_position: Float64Array): SvgOptions; /** +* Updates the error correction level of the QRCode (can increase the size of the QRCode) +* @param {number} ecl +* @returns {SvgOptions} +*/ + ecl(ecl: number): SvgOptions; +/** +* Forces the version of the QRCode +* @param {number} version +* @returns {SvgOptions} +*/ + version(version: number): SvgOptions; +/** * Creates a new SvgOptions object. */ constructor(); @@ -128,6 +326,7 @@ export class SvgOptions { export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; export interface InitOutput { + readonly memory: WebAssembly.Memory; readonly qr: (a: number, b: number, c: number) => void; readonly __wbg_svgoptions_free: (a: number) => void; readonly svgoptions_shape: (a: number, b: number) => number; @@ -139,15 +338,14 @@ export interface InitOutput { readonly svgoptions_image_background_shape: (a: number, b: number) => number; readonly svgoptions_image_size: (a: number, b: number, c: number) => number; readonly svgoptions_image_position: (a: number, b: number, c: number) => number; + readonly svgoptions_ecl: (a: number, b: number) => number; + readonly svgoptions_version: (a: number, b: number) => number; readonly svgoptions_new: () => number; readonly qr_svg: (a: number, b: number, c: number, d: number) => void; - readonly memory: WebAssembly.Memory; readonly __wbindgen_add_to_stack_pointer: (a: number) => number; readonly __wbindgen_malloc: (a: number, b: number) => number; readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; readonly __wbindgen_free: (a: number, b: number, c: number) => void; - readonly __wbindgen_thread_destroy: (a: number, b: number) => void; - readonly __wbindgen_start: () => void; } export type SyncInitInput = BufferSource | WebAssembly.Module; @@ -156,19 +354,17 @@ export type SyncInitInput = BufferSource | WebAssembly.Module; * a precompiled `WebAssembly.Module`. * * @param {SyncInitInput} module -* @param {WebAssembly.Memory} maybe_memory * * @returns {InitOutput} */ -export function initSync(module: SyncInitInput, maybe_memory?: WebAssembly.Memory): InitOutput; +export function initSync(module: SyncInitInput): InitOutput; /** * If `module_or_path` is {RequestInfo} or {URL}, makes a request and * for everything else, calls `WebAssembly.instantiate` directly. * * @param {InitInput | Promise} module_or_path -* @param {WebAssembly.Memory} maybe_memory * * @returns {Promise} */ -export default function __wbg_init (module_or_path?: InitInput | Promise, maybe_memory?: WebAssembly.Memory): Promise; +export default function __wbg_init (module_or_path?: InitInput | Promise): Promise; diff --git a/pkg/fast_qr.js b/pkg/fast_qr.js index 4acf35c..99d1e25 100644 --- a/pkg/fast_qr.js +++ b/pkg/fast_qr.js @@ -7,7 +7,7 @@ if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); }; let cachedUint8Memory0 = null; function getUint8Memory0() { - if (cachedUint8Memory0 === null || cachedUint8Memory0.buffer !== wasm.memory.buffer) { + if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) { cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); } return cachedUint8Memory0; @@ -15,21 +15,25 @@ function getUint8Memory0() { function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8Memory0().slice(ptr, ptr + len)); + return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); } let WASM_VECTOR_LEN = 0; const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } ); -const encodeString = function (arg, view) { +const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' + ? function (arg, view) { + return cachedTextEncoder.encodeInto(arg, view); +} + : function (arg, view) { const buf = cachedTextEncoder.encode(arg); view.set(buf); return { read: arg.length, written: buf.length }; -}; +}); function passStringToWasm0(arg, malloc, realloc) { @@ -72,7 +76,7 @@ function passStringToWasm0(arg, malloc, realloc) { let cachedInt32Memory0 = null; function getInt32Memory0() { - if (cachedInt32Memory0 === null || cachedInt32Memory0.buffer !== wasm.memory.buffer) { + if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) { cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); } return cachedInt32Memory0; @@ -106,7 +110,7 @@ export function qr(content) { let cachedFloat64Memory0 = null; function getFloat64Memory0() { - if (cachedFloat64Memory0 === null || cachedFloat64Memory0.buffer !== wasm.memory.buffer) { + if (cachedFloat64Memory0 === null || cachedFloat64Memory0.byteLength === 0) { cachedFloat64Memory0 = new Float64Array(wasm.memory.buffer); } return cachedFloat64Memory0; @@ -197,6 +201,190 @@ Circle:1,"1":"Circle", */ RoundedSquare:2,"2":"RoundedSquare", }); /** +* Error Correction Coding has 4 levels +*/ +export const ECL = Object.freeze({ +/** +* Low, 7% +*/ +L:0,"0":"L", +/** +* Medium, 15% +*/ +M:1,"1":"M", +/** +* Quartile, 25% +*/ +Q:2,"2":"Q", +/** +* High, 30% +*/ +H:3,"3":"H", }); +/** +* Enum containing all possible `QRCode` versions +*/ +export const Version = Object.freeze({ +/** +* Version n°01 +*/ +V01:0,"0":"V01", +/** +* Version n°02 +*/ +V02:1,"1":"V02", +/** +* Version n°03 +*/ +V03:2,"2":"V03", +/** +* Version n°04 +*/ +V04:3,"3":"V04", +/** +* Version n°05 +*/ +V05:4,"4":"V05", +/** +* Version n°06 +*/ +V06:5,"5":"V06", +/** +* Version n°07 +*/ +V07:6,"6":"V07", +/** +* Version n°08 +*/ +V08:7,"7":"V08", +/** +* Version n°09 +*/ +V09:8,"8":"V09", +/** +* Version n°10 +*/ +V10:9,"9":"V10", +/** +* Version n°11 +*/ +V11:10,"10":"V11", +/** +* Version n°12 +*/ +V12:11,"11":"V12", +/** +* Version n°13 +*/ +V13:12,"12":"V13", +/** +* Version n°14 +*/ +V14:13,"13":"V14", +/** +* Version n°15 +*/ +V15:14,"14":"V15", +/** +* Version n°16 +*/ +V16:15,"15":"V16", +/** +* Version n°17 +*/ +V17:16,"16":"V17", +/** +* Version n°18 +*/ +V18:17,"17":"V18", +/** +* Version n°19 +*/ +V19:18,"18":"V19", +/** +* Version n°20 +*/ +V20:19,"19":"V20", +/** +* Version n°21 +*/ +V21:20,"20":"V21", +/** +* Version n°22 +*/ +V22:21,"21":"V22", +/** +* Version n°23 +*/ +V23:22,"22":"V23", +/** +* Version n°24 +*/ +V24:23,"23":"V24", +/** +* Version n°25 +*/ +V25:24,"24":"V25", +/** +* Version n°26 +*/ +V26:25,"25":"V26", +/** +* Version n°27 +*/ +V27:26,"26":"V27", +/** +* Version n°28 +*/ +V28:27,"27":"V28", +/** +* Version n°29 +*/ +V29:28,"28":"V29", +/** +* Version n°30 +*/ +V30:29,"29":"V30", +/** +* Version n°31 +*/ +V31:30,"30":"V31", +/** +* Version n°32 +*/ +V32:31,"31":"V32", +/** +* Version n°33 +*/ +V33:32,"32":"V33", +/** +* Version n°34 +*/ +V34:33,"33":"V34", +/** +* Version n°35 +*/ +V35:34,"34":"V35", +/** +* Version n°36 +*/ +V36:35,"35":"V36", +/** +* Version n°37 +*/ +V37:36,"36":"V37", +/** +* Version n°38 +*/ +V38:37,"37":"V38", +/** +* Version n°39 +*/ +V39:38,"38":"V39", +/** +* Version n°40 +*/ +V40:39,"39":"V40", }); +/** * Configuration for the SVG output. */ export class SvgOptions { @@ -322,6 +510,26 @@ export class SvgOptions { return SvgOptions.__wrap(ret); } /** + * Updates the error correction level of the QRCode (can increase the size of the QRCode) + * @param {number} ecl + * @returns {SvgOptions} + */ + ecl(ecl) { + const ptr = this.__destroy_into_raw(); + const ret = wasm.svgoptions_ecl(ptr, ecl); + return SvgOptions.__wrap(ret); + } + /** + * Forces the version of the QRCode + * @param {number} version + * @returns {SvgOptions} + */ + version(version) { + const ptr = this.__destroy_into_raw(); + const ret = wasm.svgoptions_version(ptr, version); + return SvgOptions.__wrap(ret); + } + /** * Creates a new SvgOptions object. */ constructor() { @@ -372,7 +580,7 @@ function __wbg_get_imports() { } function __wbg_init_memory(imports, maybe_memory) { - imports.wbg.memory = maybe_memory || new WebAssembly.Memory({initial:18,maximum:65536,shared:true}); + } function __wbg_finalize_init(instance, module) { @@ -382,16 +590,16 @@ function __wbg_finalize_init(instance, module) { cachedInt32Memory0 = null; cachedUint8Memory0 = null; - wasm.__wbindgen_start(); + return wasm; } -function initSync(module, maybe_memory) { +function initSync(module) { if (wasm !== undefined) return wasm; const imports = __wbg_get_imports(); - __wbg_init_memory(imports, maybe_memory); + __wbg_init_memory(imports); if (!(module instanceof WebAssembly.Module)) { module = new WebAssembly.Module(module); @@ -402,7 +610,7 @@ function initSync(module, maybe_memory) { return __wbg_finalize_init(instance, module); } -async function __wbg_init(input, maybe_memory) { +async function __wbg_init(input) { if (wasm !== undefined) return wasm; if (typeof input === 'undefined') { @@ -414,7 +622,7 @@ async function __wbg_init(input, maybe_memory) { input = fetch(input); } - __wbg_init_memory(imports, maybe_memory); + __wbg_init_memory(imports); const { instance, module } = await __wbg_load(await input, imports); diff --git a/pkg/fast_qr_bg.wasm.d.ts b/pkg/fast_qr_bg.wasm.d.ts index c6e9a11..b0c9696 100644 --- a/pkg/fast_qr_bg.wasm.d.ts +++ b/pkg/fast_qr_bg.wasm.d.ts @@ -1,5 +1,6 @@ /* tslint:disable */ /* eslint-disable */ +export const memory: WebAssembly.Memory; export function qr(a: number, b: number, c: number): void; export function __wbg_svgoptions_free(a: number): void; export function svgoptions_shape(a: number, b: number): number; @@ -11,12 +12,11 @@ export function svgoptions_image_background_color(a: number, b: number, c: numbe export function svgoptions_image_background_shape(a: number, b: number): number; export function svgoptions_image_size(a: number, b: number, c: number): number; export function svgoptions_image_position(a: number, b: number, c: number): number; +export function svgoptions_ecl(a: number, b: number): number; +export function svgoptions_version(a: number, b: number): number; export function svgoptions_new(): number; export function qr_svg(a: number, b: number, c: number, d: number): void; -export const memory: WebAssembly.Memory; export function __wbindgen_add_to_stack_pointer(a: number): number; export function __wbindgen_malloc(a: number, b: number): number; export function __wbindgen_realloc(a: number, b: number, c: number, d: number): number; export function __wbindgen_free(a: number, b: number, c: number): void; -export function __wbindgen_thread_destroy(a: number, b: number): void; -export function __wbindgen_start(): void; diff --git a/pkg/package.json b/pkg/package.json index 4885775..977dd9e 100644 --- a/pkg/package.json +++ b/pkg/package.json @@ -4,7 +4,7 @@ "erwan.vivien " ], "description": "Generates optimized QRCode", - "version": "0.10.3", + "version": "0.12.1", "license": "SEE LICENSE IN LICENSE", "repository": { "type": "git", @@ -26,4 +26,4 @@ "qrcode-generator", "qr-gen" ] -} \ No newline at end of file +} diff --git a/src/ecl.rs b/src/ecl.rs index 266632c..045be7e 100644 --- a/src/ecl.rs +++ b/src/ecl.rs @@ -9,6 +9,7 @@ use std::fmt::Write; /// Error Correction Coding has 4 levels #[derive(Copy, Clone, Debug)] #[allow(dead_code)] +#[cfg_attr(feature = "wasm-bindgen", wasm_bindgen::prelude::wasm_bindgen)] pub enum ECL { /// Low, 7% L, diff --git a/src/version.rs b/src/version.rs index b5c9ff3..83435a9 100644 --- a/src/version.rs +++ b/src/version.rs @@ -5,6 +5,7 @@ use crate::encode::Mode; /// Enum containing all possible `QRCode` versions #[derive(Clone, Copy, Debug)] +#[cfg_attr(feature = "wasm-bindgen", wasm_bindgen::prelude::wasm_bindgen)] pub enum Version { /// Version n°01 V01 = 0, diff --git a/src/wasm.rs b/src/wasm.rs index 403aacc..337e9fe 100644 --- a/src/wasm.rs +++ b/src/wasm.rs @@ -1,6 +1,6 @@ -#[cfg(feature = "svg")] -use crate::convert; use crate::QRCode; +#[cfg(feature = "svg")] +use crate::{convert, Version, ECL}; #[cfg(feature = "wasm-bindgen")] use wasm_bindgen::prelude::*; @@ -29,6 +29,9 @@ pub struct SvgOptions { module_color: Vec, margin: usize, + ecl: Option, + version: Option, + background_color: Vec, image: String, @@ -140,6 +143,22 @@ impl SvgOptions { ..self } } + + /// Updates the error correction level of the QRCode (can increase the size of the QRCode) + pub fn ecl(self, ecl: ECL) -> Self { + Self { + ecl: Some(ecl), + ..self + } + } + + /// Forces the version of the QRCode + pub fn version(self, version: Version) -> Self { + Self { + version: Some(version), + ..self + } + } } #[cfg_attr(feature = "wasm-bindgen", wasm_bindgen)] @@ -153,6 +172,9 @@ impl SvgOptions { module_color: vec![0, 0, 0, 255], margin: 4, + ecl: None, + version: None, + background_color: vec![255, 255, 255, 255], image: String::new(), @@ -170,7 +192,7 @@ impl SvgOptions { pub fn qr_svg(content: &str, options: SvgOptions) -> String { use crate::convert::svg::SvgBuilder; use crate::convert::Builder; - let qrcode = QRCode::new(content.as_bytes(), None, None, None); + let qrcode = QRCode::new(content.as_bytes(), options.ecl, options.version, None); let mut builder = SvgBuilder::default(); builder.shape(options.shape); From 437d33d243093998c32b881f8250d9da151d7c38 Mon Sep 17 00:00:00 2001 From: Erwan Vivien Date: Tue, 12 Mar 2024 09:36:55 +0100 Subject: [PATCH 2/2] feat: 0.12.1 adds more options to Wasm package --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f93dd09..ca9ac29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fast_qr" -version = "0.12.0" +version = "0.12.1" authors = ["erwan.vivien "] edition = "2021" description = "Generates optimized QRCode"