Comparing version 9.4.0 to 9.5.0
@@ -1,4 +0,5 @@ | ||
import { Data, EcLevel, Matrix } from "./typing/types"; | ||
import { BitMatrix, Data, EcLevel, Matrix } from "./typing/types"; | ||
export declare function init(version: number): Matrix; | ||
export declare function fillFinders(matrix: Matrix): void; | ||
export declare function zeroFillFinders(matrix: BitMatrix): void; | ||
export declare function fillAlignAndTiming(matrix: Matrix): void; | ||
@@ -9,3 +10,3 @@ export declare function fillStub(matrix: Matrix): void; | ||
export declare function calculatePenalty(matrix: Matrix): number; | ||
export declare function getMatrix(data: Data): number[][]; | ||
export declare function clearMatrixCenter(matrix: Matrix, widthPct: number, heightPct: number): Matrix; | ||
export declare function getMatrix(data: Data): BitMatrix; | ||
export declare function clearMatrixCenter(matrix: BitMatrix, widthPct: number, heightPct: number): BitMatrix; |
@@ -205,12 +205,7 @@ (function (global, factory) { | ||
const N = (version << 2) + 0b10001; | ||
const matrix = []; | ||
let zeros = Array(N).fill(0); | ||
for (let i = 0; i < N; i++) { | ||
matrix[i] = [...zeros]; | ||
} | ||
return matrix; | ||
return Array(N).fill(null).map(() => Array(N).fill(0)); | ||
} | ||
function fillFinders(matrix) { | ||
const N = matrix.length; | ||
for (var i = -3; i <= 3; i++) { | ||
for (let i = -3; i <= 3; i++) { | ||
for (let j = -3; j <= 3; j++) { | ||
@@ -220,4 +215,4 @@ const max = Math.max(i, j); | ||
const pixel = (max == 2 && min >= -2) || (min == -2 && max <= 2) | ||
? 0x80 | ||
: 0x81; | ||
? 128 | ||
: 129; | ||
matrix[3 + i][3 + j] = pixel; | ||
@@ -228,3 +223,3 @@ matrix[3 + i][N - 4 + j] = pixel; | ||
} | ||
for (var i = 0; i < 8; i++) { | ||
for (let i = 0; i < 8; i++) { | ||
matrix[7][i] = | ||
@@ -236,5 +231,25 @@ matrix[i][7] = | ||
matrix[N - 1 - i][7] = | ||
0x80; | ||
128; | ||
} | ||
} | ||
function zeroFillFinders(matrix) { | ||
const N = matrix.length; | ||
const zeroPixel = 0; | ||
for (let i = -3; i <= 3; i++) { | ||
for (let j = -3; j <= 3; j++) { | ||
matrix[3 + i][3 + j] = zeroPixel; | ||
matrix[3 + i][N - 4 + j] = zeroPixel; | ||
matrix[N - 4 + i][3 + j] = zeroPixel; | ||
} | ||
} | ||
for (let i = 0; i < 8; i++) { | ||
matrix[7][i] = | ||
matrix[i][7] = | ||
matrix[7][N - i - 1] = | ||
matrix[i][N - 8] = | ||
matrix[N - 8][i] = | ||
matrix[N - 1 - i][7] = | ||
zeroPixel; | ||
} | ||
} | ||
function fillAlignAndTiming(matrix) { | ||
@@ -551,3 +566,3 @@ const N = matrix.length; | ||
fillReserved(matrix, data.ec_level, bestMask); | ||
return matrix.map((row) => row.map((cell) => cell & 1)); | ||
return matrix.map((row) => row.map((cell) => (cell & 1))); | ||
} | ||
@@ -608,3 +623,3 @@ function clearMatrixCenter(matrix, widthPct, heightPct) { | ||
function fillTemplate(message, template) { | ||
const blocks = new Uint8Array(template.data_len); | ||
const blocks = new Uint8ClampedArray(template.data_len); | ||
let messageUpdated; | ||
@@ -1176,3 +1191,3 @@ if (template.version < 10) { | ||
} | ||
function getSVGPath(matrix, size, margin = 0, borderRadius = 0) { | ||
function getDotsSVGPath(matrix, size, margin = 0, borderRadius = 0) { | ||
let rectangles = []; | ||
@@ -1508,2 +1523,3 @@ for (let x = 0; x < matrix.length; x++) { | ||
let matrix = QR(text, options.ec_level, options.parse_url); | ||
zeroFillFinders(matrix); | ||
if (options.logo && options.logoWidth && options.logoHeight) { | ||
@@ -1542,3 +1558,3 @@ matrix = clearMatrixCenter(matrix, options.logoWidth, options.logoHeight); | ||
context.fillRect(0, 0, imageSizePx, imageSizePx); | ||
const path = new Path2D(getSVGPath(matrix, size, marginPx, borderRadius)); | ||
const path = new Path2D(getDotsSVGPath(matrix, size, marginPx, borderRadius)); | ||
context.fillStyle = colorToHex(color); | ||
@@ -1545,0 +1561,0 @@ context.fill(path); |
import { Data, EcLevel, NumberData } from "./typing/types"; | ||
export declare function getTemplate(message: NumberData, ec_level: EcLevel): Data; | ||
export declare function fillTemplate(message: NumberData, template: Data): Data; | ||
export declare function QR(text: string, ec_level: EcLevel, parse_url: boolean): number[][]; | ||
export declare function QR(text: string, ec_level: EcLevel, parse_url: boolean): import("./typing/types").BitMatrix; |
@@ -9,12 +9,7 @@ (function (global, factory) { | ||
const N = (version << 2) + 0b10001; | ||
const matrix = []; | ||
let zeros = Array(N).fill(0); | ||
for (let i = 0; i < N; i++) { | ||
matrix[i] = [...zeros]; | ||
} | ||
return matrix; | ||
return Array(N).fill(null).map(() => Array(N).fill(0)); | ||
} | ||
function fillFinders(matrix) { | ||
const N = matrix.length; | ||
for (var i = -3; i <= 3; i++) { | ||
for (let i = -3; i <= 3; i++) { | ||
for (let j = -3; j <= 3; j++) { | ||
@@ -24,4 +19,4 @@ const max = Math.max(i, j); | ||
const pixel = (max == 2 && min >= -2) || (min == -2 && max <= 2) | ||
? 0x80 | ||
: 0x81; | ||
? 128 | ||
: 129; | ||
matrix[3 + i][3 + j] = pixel; | ||
@@ -32,3 +27,3 @@ matrix[3 + i][N - 4 + j] = pixel; | ||
} | ||
for (var i = 0; i < 8; i++) { | ||
for (let i = 0; i < 8; i++) { | ||
matrix[7][i] = | ||
@@ -40,5 +35,25 @@ matrix[i][7] = | ||
matrix[N - 1 - i][7] = | ||
0x80; | ||
128; | ||
} | ||
} | ||
function zeroFillFinders(matrix) { | ||
const N = matrix.length; | ||
const zeroPixel = 0; | ||
for (let i = -3; i <= 3; i++) { | ||
for (let j = -3; j <= 3; j++) { | ||
matrix[3 + i][3 + j] = zeroPixel; | ||
matrix[3 + i][N - 4 + j] = zeroPixel; | ||
matrix[N - 4 + i][3 + j] = zeroPixel; | ||
} | ||
} | ||
for (let i = 0; i < 8; i++) { | ||
matrix[7][i] = | ||
matrix[i][7] = | ||
matrix[7][N - i - 1] = | ||
matrix[i][N - 8] = | ||
matrix[N - 8][i] = | ||
matrix[N - 1 - i][7] = | ||
zeroPixel; | ||
} | ||
} | ||
function fillAlignAndTiming(matrix) { | ||
@@ -355,3 +370,3 @@ const N = matrix.length; | ||
fillReserved(matrix, data.ec_level, bestMask); | ||
return matrix.map((row) => row.map((cell) => cell & 1)); | ||
return matrix.map((row) => row.map((cell) => (cell & 1))); | ||
} | ||
@@ -608,3 +623,3 @@ function clearMatrixCenter(matrix, widthPct, heightPct) { | ||
function fillTemplate(message, template) { | ||
const blocks = new Uint8Array(template.data_len); | ||
const blocks = new Uint8ClampedArray(template.data_len); | ||
let messageUpdated; | ||
@@ -1176,3 +1191,28 @@ if (template.version < 10) { | ||
} | ||
function getSVGPath(matrix, size, margin = 0, borderRadius = 0) { | ||
function getFindersSVGPath(matrix, size = 0, margin = 0, borderRadius = 0) { | ||
const matrixSize = matrix.length * size + margin * 2; | ||
let finderSize = 8; | ||
let finderEnd = finderSize - 1; | ||
const sides = [[0, 0], [1, 0], [0, 1]]; | ||
const rectangles = []; | ||
for (const side of sides) { | ||
const signs = side.map(sidePoint => sidePoint == 0 ? 1 : -1); | ||
for (const offset of [0, 1, 2]) { | ||
let corners = [ | ||
[matrixSize * side[0] + signs[0] * (margin + size * offset), matrixSize * side[1] + signs[1] * (margin + size * offset)], | ||
[matrixSize * side[0] + signs[0] * (margin + size * (finderEnd - offset)), matrixSize * side[1] + signs[1] * (margin + size * (finderEnd - offset))], | ||
]; | ||
let rectangle = [ | ||
'M', corners[0][0], corners[0][1], | ||
'L', corners[0][0], corners[1][1], | ||
'L', corners[1][0], corners[1][1], | ||
'L', corners[1][0], corners[0][1], | ||
'z', | ||
]; | ||
rectangles.push(...rectangle); | ||
} | ||
} | ||
return rectangles.join(" "); | ||
} | ||
function getDotsSVGPath(matrix, size, margin = 0, borderRadius = 0) { | ||
let rectangles = []; | ||
@@ -1508,2 +1548,3 @@ for (let x = 0; x < matrix.length; x++) { | ||
let matrix = QR(text, options.ec_level, options.parse_url); | ||
zeroFillFinders(matrix); | ||
if (options.logo && options.logoWidth && options.logoHeight) { | ||
@@ -1537,5 +1578,7 @@ matrix = clearMatrixCenter(matrix, options.logoWidth, options.logoHeight); | ||
function getSVGBody(matrix, options) { | ||
const path = getSVGPath(matrix, options.blockSize, options.margin * options.blockSize, options.borderRadius); | ||
const dotsPath = getDotsSVGPath(matrix, options.blockSize, options.margin * options.blockSize, options.borderRadius); | ||
const outerFindersPath = getFindersSVGPath(matrix, options.blockSize, options.margin * options.blockSize, options.borderRadius); | ||
let svgBody = `<rect width="${options.size}" height="${options.size}" fill="${colorToHex(options.bgColor)}"></rect>`; | ||
svgBody += `<path shape-rendering="geometricPrecision" d="${path}" fill="${colorToHex(options.color)}"/>`; | ||
svgBody += `<path shape-rendering="geometricPrecision" d="${outerFindersPath}" fill-rule="evenodd" fill="${colorToHex(options.color)}"/>`; | ||
svgBody += `<path shape-rendering="geometricPrecision" d="${dotsPath}" fill="${colorToHex(options.color)}"/>`; | ||
return svgBody; | ||
@@ -1542,0 +1585,0 @@ } |
@@ -1,2 +0,4 @@ | ||
export type Matrix = number[][]; | ||
export type MatrixValue = 0 | 1 | 128 | 129; | ||
export type Matrix = MatrixValue[][]; | ||
export type BitMatrix = (0 | 1)[][]; | ||
export interface Data { | ||
@@ -3,0 +5,0 @@ blocks: number[][]; |
@@ -16,2 +16,3 @@ import { ImageOptions, ImageType, Matrix } from "./typing/types"; | ||
export declare function colorToHex(color: number | string): string; | ||
export declare function getSVGPath(matrix: Matrix, size: number, margin?: number, borderRadius?: number): string; | ||
export declare function getFindersSVGPath(matrix: Matrix, size?: number, margin?: number, borderRadius?: number): string; | ||
export declare function getDotsSVGPath(matrix: Matrix, size: number, margin?: number, borderRadius?: number): string; |
@@ -1,4 +0,5 @@ | ||
import { Data, EcLevel, Matrix } from "./typing/types"; | ||
import { BitMatrix, Data, EcLevel, Matrix } from "./typing/types"; | ||
export declare function init(version: number): Matrix; | ||
export declare function fillFinders(matrix: Matrix): void; | ||
export declare function zeroFillFinders(matrix: BitMatrix): void; | ||
export declare function fillAlignAndTiming(matrix: Matrix): void; | ||
@@ -9,3 +10,3 @@ export declare function fillStub(matrix: Matrix): void; | ||
export declare function calculatePenalty(matrix: Matrix): number; | ||
export declare function getMatrix(data: Data): number[][]; | ||
export declare function clearMatrixCenter(matrix: Matrix, widthPct: number, heightPct: number): Matrix; | ||
export declare function getMatrix(data: Data): BitMatrix; | ||
export declare function clearMatrixCenter(matrix: BitMatrix, widthPct: number, heightPct: number): BitMatrix; |
export function init(version) { | ||
const N = (version << 2) + 0b10001; | ||
const matrix = []; | ||
let zeros = Array(N).fill(0); | ||
for (let i = 0; i < N; i++) { | ||
matrix[i] = [...zeros]; | ||
} | ||
return matrix; | ||
return Array(N).fill(null).map(() => Array(N).fill(0)); | ||
} | ||
export function fillFinders(matrix) { | ||
const N = matrix.length; | ||
for (var i = -3; i <= 3; i++) { | ||
for (let i = -3; i <= 3; i++) { | ||
for (let j = -3; j <= 3; j++) { | ||
@@ -17,4 +12,4 @@ const max = Math.max(i, j); | ||
const pixel = (max == 2 && min >= -2) || (min == -2 && max <= 2) | ||
? 0x80 | ||
: 0x81; | ||
? 128 | ||
: 129; | ||
matrix[3 + i][3 + j] = pixel; | ||
@@ -25,3 +20,3 @@ matrix[3 + i][N - 4 + j] = pixel; | ||
} | ||
for (var i = 0; i < 8; i++) { | ||
for (let i = 0; i < 8; i++) { | ||
matrix[7][i] = | ||
@@ -33,5 +28,25 @@ matrix[i][7] = | ||
matrix[N - 1 - i][7] = | ||
0x80; | ||
128; | ||
} | ||
} | ||
export function zeroFillFinders(matrix) { | ||
const N = matrix.length; | ||
const zeroPixel = 0; | ||
for (let i = -3; i <= 3; i++) { | ||
for (let j = -3; j <= 3; j++) { | ||
matrix[3 + i][3 + j] = zeroPixel; | ||
matrix[3 + i][N - 4 + j] = zeroPixel; | ||
matrix[N - 4 + i][3 + j] = zeroPixel; | ||
} | ||
} | ||
for (let i = 0; i < 8; i++) { | ||
matrix[7][i] = | ||
matrix[i][7] = | ||
matrix[7][N - i - 1] = | ||
matrix[i][N - 8] = | ||
matrix[N - 8][i] = | ||
matrix[N - 1 - i][7] = | ||
zeroPixel; | ||
} | ||
} | ||
export function fillAlignAndTiming(matrix) { | ||
@@ -348,3 +363,3 @@ const N = matrix.length; | ||
fillReserved(matrix, data.ec_level, bestMask); | ||
return matrix.map((row) => row.map((cell) => cell & 1)); | ||
return matrix.map((row) => row.map((cell) => (cell & 1))); | ||
} | ||
@@ -351,0 +366,0 @@ export function clearMatrixCenter(matrix, widthPct, heightPct) { |
import { PDFDocument, rgb } from "pdf-lib"; | ||
import { QR } from "./qr-base.js"; | ||
import { getOptions, getSVGPath } from "./utils.js"; | ||
import { getOptions, getDotsSVGPath } from "./utils.js"; | ||
import colorString from "color-string"; | ||
import { clearMatrixCenter } from "./matrix.js"; | ||
import { clearMatrixCenter, zeroFillFinders } from "./matrix.js"; | ||
const textDec = new TextDecoder(); | ||
@@ -10,2 +10,3 @@ export async function getPDF(text, inOptions) { | ||
let matrix = QR(text, options.ec_level, options.parse_url); | ||
zeroFillFinders(matrix); | ||
if (options.logo && options.logoWidth && options.logoHeight) { | ||
@@ -41,3 +42,3 @@ matrix = clearMatrixCenter(matrix, options.logoWidth, options.logoHeight); | ||
page.moveTo(0, page.getHeight()); | ||
const path = getSVGPath(matrix, size, marginPx, borderRadius); | ||
const path = getDotsSVGPath(matrix, size, marginPx, borderRadius); | ||
page.drawSvgPath(path, { | ||
@@ -44,0 +45,0 @@ color: rgb(...colorToRGB(color)), |
import { QR } from "./qr-base.js"; | ||
import { colorToHex, getOptions, getSVGPath } from "./utils.js"; | ||
import { colorToHex, getOptions, getDotsSVGPath } from "./utils.js"; | ||
import { Base64 } from "js-base64"; | ||
import { clearMatrixCenter } from "./matrix.js"; | ||
import { clearMatrixCenter, zeroFillFinders } from "./matrix.js"; | ||
export async function getPNG(text, inOptions) { | ||
const options = getOptions(inOptions); | ||
let matrix = QR(text, options.ec_level, options.parse_url); | ||
zeroFillFinders(matrix); | ||
if (options.logo && options.logoWidth && options.logoHeight) { | ||
@@ -41,3 +42,3 @@ matrix = clearMatrixCenter(matrix, options.logoWidth, options.logoHeight); | ||
context.fillRect(0, 0, imageSizePx, imageSizePx); | ||
const path = new Path2D(getSVGPath(matrix, size, marginPx, borderRadius)); | ||
const path = new Path2D(getDotsSVGPath(matrix, size, marginPx, borderRadius)); | ||
context.fillStyle = colorToHex(color); | ||
@@ -44,0 +45,0 @@ context.fill(path); |
@@ -5,6 +5,7 @@ import { QR } from "./qr-base.js"; | ||
import sharp from "sharp"; | ||
import { clearMatrixCenter } from "./matrix.js"; | ||
import { clearMatrixCenter, zeroFillFinders } from "./matrix.js"; | ||
export async function getPNG(text, inOptions = {}) { | ||
const options = getOptions({ ...inOptions, type: "png" }); | ||
let matrix = QR(text, options.ec_level, options.parse_url); | ||
zeroFillFinders(matrix); | ||
if (options.logo && options.logoWidth && options.logoHeight) { | ||
@@ -11,0 +12,0 @@ matrix = clearMatrixCenter(matrix, options.logoWidth, options.logoHeight); |
import { Data, EcLevel, NumberData } from "./typing/types"; | ||
export declare function getTemplate(message: NumberData, ec_level: EcLevel): Data; | ||
export declare function fillTemplate(message: NumberData, template: Data): Data; | ||
export declare function QR(text: string, ec_level: EcLevel, parse_url: boolean): number[][]; | ||
export declare function QR(text: string, ec_level: EcLevel, parse_url: boolean): import("./typing/types").BitMatrix; |
@@ -42,3 +42,3 @@ import { encode } from "./encode.js"; | ||
export function fillTemplate(message, template) { | ||
const blocks = new Uint8Array(template.data_len); | ||
const blocks = new Uint8ClampedArray(template.data_len); | ||
let messageUpdated; | ||
@@ -45,0 +45,0 @@ if (template.version < 10) { |
@@ -1,4 +0,4 @@ | ||
import { clearMatrixCenter } from "./matrix.js"; | ||
import { clearMatrixCenter, zeroFillFinders } from "./matrix.js"; | ||
import { QR } from "./qr-base.js"; | ||
import { colorToHex, getOptions, getSVGPath } from "./utils.js"; | ||
import { colorToHex, getOptions, getDotsSVGPath, getFindersSVGPath } from "./utils.js"; | ||
import { Base64 } from "js-base64"; | ||
@@ -8,2 +8,3 @@ export async function getSVG(text, inOptions = {}) { | ||
let matrix = QR(text, options.ec_level, options.parse_url); | ||
zeroFillFinders(matrix); | ||
if (options.logo && options.logoWidth && options.logoHeight) { | ||
@@ -37,5 +38,7 @@ matrix = clearMatrixCenter(matrix, options.logoWidth, options.logoHeight); | ||
function getSVGBody(matrix, options) { | ||
const path = getSVGPath(matrix, options.blockSize, options.margin * options.blockSize, options.borderRadius); | ||
const dotsPath = getDotsSVGPath(matrix, options.blockSize, options.margin * options.blockSize, options.borderRadius); | ||
const outerFindersPath = getFindersSVGPath(matrix, options.blockSize, options.margin * options.blockSize, options.borderRadius); | ||
let svgBody = `<rect width="${options.size}" height="${options.size}" fill="${colorToHex(options.bgColor)}"></rect>`; | ||
svgBody += `<path shape-rendering="geometricPrecision" d="${path}" fill="${colorToHex(options.color)}"/>`; | ||
svgBody += `<path shape-rendering="geometricPrecision" d="${outerFindersPath}" fill-rule="evenodd" fill="${colorToHex(options.color)}"/>`; | ||
svgBody += `<path shape-rendering="geometricPrecision" d="${dotsPath}" fill="${colorToHex(options.color)}"/>`; | ||
return svgBody; | ||
@@ -42,0 +45,0 @@ } |
@@ -1,2 +0,4 @@ | ||
export type Matrix = number[][]; | ||
export type MatrixValue = 0 | 1 | 128 | 129; | ||
export type Matrix = MatrixValue[][]; | ||
export type BitMatrix = (0 | 1)[][]; | ||
export interface Data { | ||
@@ -3,0 +5,0 @@ blocks: number[][]; |
@@ -16,2 +16,3 @@ import { ImageOptions, ImageType, Matrix } from "./typing/types"; | ||
export declare function colorToHex(color: number | string): string; | ||
export declare function getSVGPath(matrix: Matrix, size: number, margin?: number, borderRadius?: number): string; | ||
export declare function getFindersSVGPath(matrix: Matrix, size?: number, margin?: number, borderRadius?: number): string; | ||
export declare function getDotsSVGPath(matrix: Matrix, size: number, margin?: number, borderRadius?: number): string; |
@@ -13,3 +13,28 @@ import colorString from "color-string"; | ||
} | ||
export function getSVGPath(matrix, size, margin = 0, borderRadius = 0) { | ||
export function getFindersSVGPath(matrix, size = 0, margin = 0, borderRadius = 0) { | ||
const matrixSize = matrix.length * size + margin * 2; | ||
let finderSize = 8; | ||
let finderEnd = finderSize - 1; | ||
const sides = [[0, 0], [1, 0], [0, 1]]; | ||
const rectangles = []; | ||
for (const side of sides) { | ||
const signs = side.map(sidePoint => sidePoint == 0 ? 1 : -1); | ||
for (const offset of [0, 1, 2]) { | ||
let corners = [ | ||
[matrixSize * side[0] + signs[0] * (margin + size * offset), matrixSize * side[1] + signs[1] * (margin + size * offset)], | ||
[matrixSize * side[0] + signs[0] * (margin + size * (finderEnd - offset)), matrixSize * side[1] + signs[1] * (margin + size * (finderEnd - offset))], | ||
]; | ||
let rectangle = [ | ||
'M', corners[0][0], corners[0][1], | ||
'L', corners[0][0], corners[1][1], | ||
'L', corners[1][0], corners[1][1], | ||
'L', corners[1][0], corners[0][1], | ||
'z', | ||
]; | ||
rectangles.push(...rectangle); | ||
} | ||
} | ||
return rectangles.join(" "); | ||
} | ||
export function getDotsSVGPath(matrix, size, margin = 0, borderRadius = 0) { | ||
let rectangles = []; | ||
@@ -16,0 +41,0 @@ for (let x = 0; x < matrix.length; x++) { |
{ | ||
"name": "qreator", | ||
"version": "9.4.0", | ||
"version": "9.5.0", | ||
"description": "QR Code generator for browser and node.js with tree shaking and logo support", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/Short-io/qreator", |
@@ -1,2 +0,2 @@ | ||
import { Data, EcLevel, Matrix } from "./typing/types"; | ||
import { BitMatrix, Data, EcLevel, Matrix } from "./typing/types"; | ||
@@ -6,14 +6,9 @@ // {{{1 Initialize matrix with zeros | ||
const N = (version << 2) + 0b10001; | ||
const matrix: Matrix = []; | ||
let zeros: number[] = Array(N).fill(0); | ||
for (let i = 0; i < N; i++) { | ||
matrix[i] = [...zeros]; | ||
} | ||
return matrix; | ||
return Array(N).fill(null).map(() => Array(N).fill(0)) | ||
} | ||
// {{{1 Put finders into matrix | ||
// Not used | ||
export function fillFinders(matrix: Matrix) { | ||
const N = matrix.length; | ||
for (var i = -3; i <= 3; i++) { | ||
for (let i = -3; i <= 3; i++) { | ||
for (let j = -3; j <= 3; j++) { | ||
@@ -24,4 +19,4 @@ const max = Math.max(i, j); | ||
(max == 2 && min >= -2) || (min == -2 && max <= 2) | ||
? 0x80 | ||
: 0x81; | ||
? 0b010_000_000 | ||
: 0b010_000_001; | ||
matrix[3 + i][3 + j] = pixel; | ||
@@ -32,3 +27,3 @@ matrix[3 + i][N - 4 + j] = pixel; | ||
} | ||
for (var i = 0; i < 8; i++) { | ||
for (let i = 0; i < 8; i++) { | ||
matrix[7][i] = | ||
@@ -40,6 +35,33 @@ matrix[i][7] = | ||
matrix[N - 1 - i][7] = | ||
0x80; | ||
0b010_000_000; | ||
} | ||
} | ||
/** | ||
* Finders require different UI representation, so we zero-fill finders and draw them later | ||
*/ | ||
export function zeroFillFinders(matrix: BitMatrix) { | ||
const N = matrix.length; | ||
const zeroPixel = 0; | ||
// squares | ||
for (let i = -3; i <= 3; i++) { | ||
for (let j = -3; j <= 3; j++) { | ||
matrix[3 + i][3 + j] = zeroPixel; | ||
matrix[3 + i][N - 4 + j] = zeroPixel; | ||
matrix[N - 4 + i][3 + j] = zeroPixel; | ||
} | ||
} | ||
// border | ||
for (let i = 0; i < 8; i++) { | ||
matrix[7][i] = | ||
matrix[i][7] = | ||
matrix[7][N - i - 1] = | ||
matrix[i][N - 8] = | ||
matrix[N - 8][i] = | ||
matrix[N - 1 - i][7] = | ||
zeroPixel; | ||
} | ||
} | ||
// {{{1 Put align and timinig | ||
@@ -375,3 +397,3 @@ export function fillAlignAndTiming(matrix: Matrix) { | ||
// {{{1 All-in-one function | ||
export function getMatrix(data: Data) { | ||
export function getMatrix(data: Data): BitMatrix { | ||
const matrix = init(data.version); | ||
@@ -397,6 +419,9 @@ fillFinders(matrix); | ||
return matrix.map((row) => row.map((cell) => cell & 1)); | ||
return matrix.map((row) => row.map((cell) => (cell & 1) as 0 | 1)); | ||
} | ||
export function clearMatrixCenter(matrix: Matrix, widthPct: number, heightPct: number): Matrix { | ||
/** | ||
* Before we insert logo in the QR we need to clear pixels under the logo. This function clears pixels | ||
*/ | ||
export function clearMatrixCenter(matrix: BitMatrix, widthPct: number, heightPct: number): BitMatrix { | ||
matrix = matrix.map((x) => x.slice()); // avoid mutating input arg | ||
@@ -403,0 +428,0 @@ |
import { PDFDocument, PDFImage, rgb } from "pdf-lib"; | ||
import { QR } from "./qr-base.js"; | ||
import { ImageOptions, Matrix } from "./typing/types"; | ||
import { getOptions, getSVGPath } from "./utils.js"; | ||
import { getOptions, getDotsSVGPath } from "./utils.js"; | ||
import colorString from "color-string"; | ||
import { clearMatrixCenter } from "./matrix.js"; | ||
import { clearMatrixCenter, zeroFillFinders } from "./matrix.js"; | ||
@@ -14,2 +14,3 @@ const textDec = new TextDecoder(); | ||
let matrix = QR(text, options.ec_level, options.parse_url); | ||
zeroFillFinders(matrix) | ||
if (options.logo && options.logoWidth && options.logoHeight) { | ||
@@ -62,3 +63,3 @@ matrix = clearMatrixCenter(matrix, options.logoWidth, options.logoHeight); | ||
const path = getSVGPath(matrix, size, marginPx, borderRadius); | ||
const path = getDotsSVGPath(matrix, size, marginPx, borderRadius); | ||
page.drawSvgPath(path, { | ||
@@ -65,0 +66,0 @@ color: rgb(...colorToRGB(color)), |
import { QR } from "./qr-base.js"; | ||
import { colorToHex, getOptions, getSVGPath } from "./utils.js"; | ||
import { colorToHex, getOptions, getDotsSVGPath } from "./utils.js"; | ||
import { ImageOptions, Matrix } from "./typing/types"; | ||
import { Base64 } from "js-base64"; | ||
import { clearMatrixCenter } from "./matrix.js"; | ||
import { clearMatrixCenter, zeroFillFinders } from "./matrix.js"; | ||
@@ -11,2 +11,3 @@ export async function getPNG(text: string, inOptions: ImageOptions) { | ||
let matrix = QR(text, options.ec_level, options.parse_url); | ||
zeroFillFinders(matrix) | ||
if (options.logo && options.logoWidth && options.logoHeight) { | ||
@@ -60,3 +61,3 @@ matrix = clearMatrixCenter(matrix, options.logoWidth, options.logoHeight); | ||
const path = new Path2D(getSVGPath(matrix, size, marginPx, borderRadius)); | ||
const path = new Path2D(getDotsSVGPath(matrix, size, marginPx, borderRadius)); | ||
context.fillStyle = colorToHex(color); | ||
@@ -63,0 +64,0 @@ context.fill(path); |
@@ -6,3 +6,3 @@ import { ImageOptions, Matrix } from "./typing/types"; | ||
import sharp from "sharp"; | ||
import { clearMatrixCenter } from "./matrix.js"; | ||
import { clearMatrixCenter, zeroFillFinders } from "./matrix.js"; | ||
@@ -13,2 +13,3 @@ export async function getPNG(text: string, inOptions: ImageOptions = {}) { | ||
let matrix = QR(text, options.ec_level, options.parse_url); | ||
zeroFillFinders(matrix) | ||
if (options.logo && options.logoWidth && options.logoHeight) { | ||
@@ -15,0 +16,0 @@ matrix = clearMatrixCenter(matrix, options.logoWidth, options.logoHeight); |
@@ -53,3 +53,3 @@ import { encode } from "./encode.js"; | ||
export function fillTemplate(message: NumberData, template: Data): Data { | ||
const blocks = new Uint8Array(template.data_len); | ||
const blocks = new Uint8ClampedArray(template.data_len); | ||
let messageUpdated: number[]; | ||
@@ -56,0 +56,0 @@ |
@@ -1,5 +0,5 @@ | ||
import { clearMatrixCenter } from "./matrix.js"; | ||
import { clearMatrixCenter, zeroFillFinders } from "./matrix.js"; | ||
import { QR } from "./qr-base.js"; | ||
import { ImageOptions, Matrix } from "./typing/types"; | ||
import { colorToHex, getOptions, getSVGPath } from "./utils.js"; | ||
import { colorToHex, getOptions, getDotsSVGPath, getFindersSVGPath } from "./utils.js"; | ||
import { Base64 } from "js-base64"; | ||
@@ -15,2 +15,3 @@ | ||
let matrix = QR(text, options.ec_level, options.parse_url); | ||
zeroFillFinders(matrix) | ||
if (options.logo && options.logoWidth && options.logoHeight) { | ||
@@ -66,7 +67,9 @@ matrix = clearMatrixCenter(matrix, options.logoWidth, options.logoHeight); | ||
function getSVGBody(matrix: Matrix, options: FillSVGOptions): string { | ||
const path = getSVGPath(matrix, options.blockSize, options.margin * options.blockSize, options.borderRadius); | ||
const dotsPath = getDotsSVGPath(matrix, options.blockSize, options.margin * options.blockSize, options.borderRadius); | ||
const outerFindersPath = getFindersSVGPath(matrix, options.blockSize, options.margin * options.blockSize, options.borderRadius); | ||
let svgBody = `<rect width="${options.size}" height="${options.size}" fill="${colorToHex( | ||
options.bgColor | ||
)}"></rect>`; | ||
svgBody += `<path shape-rendering="geometricPrecision" d="${path}" fill="${colorToHex(options.color)}"/>`; | ||
svgBody += `<path shape-rendering="geometricPrecision" d="${outerFindersPath}" fill-rule="evenodd" fill="${colorToHex(options.color)}"/>`; | ||
svgBody += `<path shape-rendering="geometricPrecision" d="${dotsPath}" fill="${colorToHex(options.color)}"/>`; | ||
return svgBody; | ||
@@ -73,0 +76,0 @@ } |
@@ -1,2 +0,4 @@ | ||
export type Matrix = number[][]; | ||
export type MatrixValue = 0 | 1 | 128 | 129; | ||
export type Matrix = MatrixValue[][]; | ||
export type BitMatrix = (0 | 1)[][]; | ||
@@ -3,0 +5,0 @@ export interface Data { |
@@ -17,3 +17,31 @@ import colorString from "color-string"; | ||
export function getSVGPath(matrix: Matrix, size: number, margin: number = 0, borderRadius: number = 0) { | ||
export function getFindersSVGPath(matrix: Matrix, size: number = 0, margin: number = 0, borderRadius: number = 0) { | ||
const matrixSize = matrix.length * size + margin * 2; | ||
let finderSize = 8; | ||
let finderEnd = finderSize - 1; | ||
const sides = [[0, 0], [1, 0], [0, 1]] | ||
const rectangles = []; | ||
for (const side of sides) { | ||
const signs = side.map(sidePoint => sidePoint == 0 ? 1 : -1); | ||
for (const offset of [0, 1, 2]) { | ||
let corners = [ | ||
[matrixSize * side[0] + signs[0] * (margin + size * offset), matrixSize * side[1] + signs[1] * (margin + size * offset)], | ||
[matrixSize * side[0] + signs[0] * (margin + size * (finderEnd - offset)), matrixSize * side[1] + signs[1] * (margin + size * (finderEnd - offset))], | ||
] | ||
let rectangle = [ | ||
'M', corners[0][0], corners[0][1], | ||
'L', corners[0][0], corners[1][1], | ||
'L', corners[1][0], corners[1][1], | ||
'L', corners[1][0], corners[0][1], | ||
'z', | ||
] | ||
rectangles.push(...rectangle) | ||
} | ||
} | ||
return rectangles.join(" ") | ||
} | ||
export function getDotsSVGPath(matrix: Matrix, size: number, margin: number = 0, borderRadius: number = 0) { | ||
let rectangles = []; | ||
@@ -20,0 +48,0 @@ for (let x = 0; x < matrix.length; x++) { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
3828905
32624