diff --git a/src/utils.ts b/src/utils.ts index 24b56bf..fc6a7c9 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -14,28 +14,40 @@ export function colorToHex(color: number | string): string { return `#${(color >>> 8).toString(16).padStart(6, "0")}`; } +const svgMove = (left: number, top: number) => ['M', left, top] +const svgReturn = () => ['z'] +const svgDeltaArc = (borderRadius: number, dx: number, dy: number, sweep: number = 0) => borderRadius > 0 ? ['a', borderRadius, borderRadius, 0, 0, sweep, dx, dy] : []; +const svgVerticalDeltaLite = (dy: number) => ['v', dy]; +const svgHorizontalDeltaLine = (dx: number) => ['h', dx]; + 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 sides = [[0, 0], [1, 0], [0, 1]] as const; const rectangles = []; for (const side of sides) { - const signs = side.map(sidePoint => sidePoint == 0 ? 1 : -1); + const [ xSign, ySign ] = 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 xCorner = matrixSize * side[0] + xSign * (margin + size * offset); + let yCorner = matrixSize * side[1] + ySign * (margin + size * offset); + + const xDelta = xSign * (size * (finderEnd - 2 * offset) - 2 * borderRadius); + const yDelta = ySign * (size * (finderEnd - 2 * offset) - 2 * borderRadius); 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', + svgMove(xCorner, yCorner + borderRadius * ySign), + svgVerticalDeltaLite(yDelta), + svgDeltaArc(borderRadius, borderRadius * xSign, borderRadius * ySign, side[1] | side[0]), + svgHorizontalDeltaLine(xDelta), + svgDeltaArc(borderRadius, borderRadius * xSign, - borderRadius * ySign, (side[1] | side[0])), + svgVerticalDeltaLite(-yDelta), + svgDeltaArc(borderRadius, - borderRadius * xSign, - borderRadius * ySign, (side[1] | side[0])), + svgHorizontalDeltaLine(-xDelta), + svgDeltaArc(borderRadius, - borderRadius * xSign, borderRadius * ySign, (side[1] | side[0])), + svgReturn(), ] - rectangles.push(...rectangle) + rectangles.push(...rectangle.flat()) } } @@ -49,29 +61,21 @@ export function getDotsSVGPath(matrix: Matrix, size: number, margin: number = 0, for (let y = 0; y < column.length; y++) { if (column[y]) { const leftX = x * size + margin; - const rightX = (x + 1) * size + margin; const topY = y * size + margin; - const bottomY = (y + 1) * size + margin; - const rectangle = []; - rectangle.push(`M ${leftX} ${topY + borderRadius}`); - rectangle.push(`L ${leftX} ${bottomY - borderRadius}`); - if (borderRadius > 0) { - rectangle.push(`A ${borderRadius} ${borderRadius} 0 0 0 ${leftX + borderRadius} ${bottomY}`); - } - rectangle.push(`L ${rightX - borderRadius} ${bottomY}`); - if (borderRadius > 0) { - rectangle.push(`A ${borderRadius} ${borderRadius} 0 0 0 ${rightX} ${bottomY - borderRadius}`); - } - rectangle.push(`L ${rightX} ${topY + borderRadius}`); - if (borderRadius > 0) { - rectangle.push(`A ${borderRadius} ${borderRadius} 0 0 0 ${rightX - borderRadius} ${topY}`); - } - rectangle.push(`L ${leftX + borderRadius} ${topY}`); - if (borderRadius > 0) { - rectangle.push(`A ${borderRadius} ${borderRadius} 0 0 0 ${leftX} ${topY + borderRadius}`); - } - rectangle.push(`z`); - rectangles.push(rectangle.join(" ")); + const delta = size - 2 * borderRadius; + const rectangle = [ + svgMove(leftX, topY + borderRadius), + svgVerticalDeltaLite(delta), + svgDeltaArc(borderRadius, borderRadius, borderRadius), + svgHorizontalDeltaLine(delta), + svgDeltaArc(borderRadius, borderRadius, -borderRadius), + svgVerticalDeltaLite(-delta), + svgDeltaArc(borderRadius, -borderRadius, -borderRadius), + svgHorizontalDeltaLine(-delta), + svgDeltaArc(borderRadius, -borderRadius, borderRadius), + svgReturn(), + ]; + rectangles.push(...rectangle.flat()); } } } diff --git a/test_data/golden/browser_qr.pdf b/test_data/golden/browser_qr.pdf index 864b00f..39b86e4 100644 Binary files a/test_data/golden/browser_qr.pdf and b/test_data/golden/browser_qr.pdf differ diff --git a/test_data/golden/browser_qr.svg b/test_data/golden/browser_qr.svg index 5ae4c45..a2a66e5 100644 --- a/test_data/golden/browser_qr.svg +++ b/test_data/golden/browser_qr.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/browser_qr_logo_arraybuffer.pdf b/test_data/golden/browser_qr_logo_arraybuffer.pdf index 11bfd4d..0c40fc6 100644 Binary files a/test_data/golden/browser_qr_logo_arraybuffer.pdf and b/test_data/golden/browser_qr_logo_arraybuffer.pdf differ diff --git a/test_data/golden/browser_qr_with_border_radius.pdf b/test_data/golden/browser_qr_with_border_radius.pdf index e27eb11..ef1ef7d 100644 Binary files a/test_data/golden/browser_qr_with_border_radius.pdf and b/test_data/golden/browser_qr_with_border_radius.pdf differ diff --git a/test_data/golden/browser_qr_with_border_radius.png b/test_data/golden/browser_qr_with_border_radius.png index c00b1e1..dbb7fff 100644 Binary files a/test_data/golden/browser_qr_with_border_radius.png and b/test_data/golden/browser_qr_with_border_radius.png differ diff --git a/test_data/golden/browser_qr_with_border_radius.svg b/test_data/golden/browser_qr_with_border_radius.svg index c995bb0..a9115b9 100644 --- a/test_data/golden/browser_qr_with_border_radius.svg +++ b/test_data/golden/browser_qr_with_border_radius.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/browser_qr_with_colors.pdf b/test_data/golden/browser_qr_with_colors.pdf index d88057e..db8736c 100644 Binary files a/test_data/golden/browser_qr_with_colors.pdf and b/test_data/golden/browser_qr_with_colors.pdf differ diff --git a/test_data/golden/browser_qr_with_colors.svg b/test_data/golden/browser_qr_with_colors.svg index 42e9cfa..a1b8089 100644 --- a/test_data/golden/browser_qr_with_colors.svg +++ b/test_data/golden/browser_qr_with_colors.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/browser_qr_with_colors_hex.svg b/test_data/golden/browser_qr_with_colors_hex.svg index 13fe803..b770432 100644 --- a/test_data/golden/browser_qr_with_colors_hex.svg +++ b/test_data/golden/browser_qr_with_colors_hex.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/browser_qr_with_ec_level.svg b/test_data/golden/browser_qr_with_ec_level.svg index 6f3575a..f83a18d 100644 --- a/test_data/golden/browser_qr_with_ec_level.svg +++ b/test_data/golden/browser_qr_with_ec_level.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/browser_qr_with_logo_as_arraybuffer.svg b/test_data/golden/browser_qr_with_logo_as_arraybuffer.svg index f372e54..c4933cd 100644 --- a/test_data/golden/browser_qr_with_logo_as_arraybuffer.svg +++ b/test_data/golden/browser_qr_with_logo_as_arraybuffer.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/browser_qr_with_logo_as_arraybuffer_jpg.svg b/test_data/golden/browser_qr_with_logo_as_arraybuffer_jpg.svg index efe3e53..771ff07 100644 --- a/test_data/golden/browser_qr_with_logo_as_arraybuffer_jpg.svg +++ b/test_data/golden/browser_qr_with_logo_as_arraybuffer_jpg.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/browser_qr_with_size.svg b/test_data/golden/browser_qr_with_size.svg index 3d992ca..f02909b 100644 --- a/test_data/golden/browser_qr_with_size.svg +++ b/test_data/golden/browser_qr_with_size.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/qr.pdf b/test_data/golden/qr.pdf index 06e61a0..39b86e4 100644 Binary files a/test_data/golden/qr.pdf and b/test_data/golden/qr.pdf differ diff --git a/test_data/golden/qr.png b/test_data/golden/qr.png index 47227ca..80bed2e 100644 Binary files a/test_data/golden/qr.png and b/test_data/golden/qr.png differ diff --git a/test_data/golden/qr.svg b/test_data/golden/qr.svg index 5ae4c45..a2a66e5 100644 --- a/test_data/golden/qr.svg +++ b/test_data/golden/qr.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/qr_excavate.pdf b/test_data/golden/qr_excavate.pdf index a5f69fb..8fe3707 100644 Binary files a/test_data/golden/qr_excavate.pdf and b/test_data/golden/qr_excavate.pdf differ diff --git a/test_data/golden/qr_excavate.png b/test_data/golden/qr_excavate.png index 7918b6c..60ea8af 100644 Binary files a/test_data/golden/qr_excavate.png and b/test_data/golden/qr_excavate.png differ diff --git a/test_data/golden/qr_excavate.svg b/test_data/golden/qr_excavate.svg index d14b827..8ea4a8c 100644 --- a/test_data/golden/qr_excavate.svg +++ b/test_data/golden/qr_excavate.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/qr_large.png b/test_data/golden/qr_large.png index c905146..a9a7571 100644 Binary files a/test_data/golden/qr_large.png and b/test_data/golden/qr_large.png differ diff --git a/test_data/golden/qr_logo_arraybuffer.pdf b/test_data/golden/qr_logo_arraybuffer.pdf index 5072dcd..03e5efd 100644 Binary files a/test_data/golden/qr_logo_arraybuffer.pdf and b/test_data/golden/qr_logo_arraybuffer.pdf differ diff --git a/test_data/golden/qr_logo_arraybuffer_jpg.pdf b/test_data/golden/qr_logo_arraybuffer_jpg.pdf index 8991b8f..0c40fc6 100644 Binary files a/test_data/golden/qr_logo_arraybuffer_jpg.pdf and b/test_data/golden/qr_logo_arraybuffer_jpg.pdf differ diff --git a/test_data/golden/qr_noexcavate.pdf b/test_data/golden/qr_noexcavate.pdf index 1cb524d..4acbcbe 100644 Binary files a/test_data/golden/qr_noexcavate.pdf and b/test_data/golden/qr_noexcavate.pdf differ diff --git a/test_data/golden/qr_noexcavate.png b/test_data/golden/qr_noexcavate.png index 46bc869..9ab8612 100644 Binary files a/test_data/golden/qr_noexcavate.png and b/test_data/golden/qr_noexcavate.png differ diff --git a/test_data/golden/qr_noexcavate.svg b/test_data/golden/qr_noexcavate.svg index 7f86b10..e2c4dea 100644 --- a/test_data/golden/qr_noexcavate.svg +++ b/test_data/golden/qr_noexcavate.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/qr_with_border_radius.pdf b/test_data/golden/qr_with_border_radius.pdf index c489751..21611bd 100644 Binary files a/test_data/golden/qr_with_border_radius.pdf and b/test_data/golden/qr_with_border_radius.pdf differ diff --git a/test_data/golden/qr_with_border_radius.png b/test_data/golden/qr_with_border_radius.png index 9d0632b..11ca861 100644 Binary files a/test_data/golden/qr_with_border_radius.png and b/test_data/golden/qr_with_border_radius.png differ diff --git a/test_data/golden/qr_with_border_radius.svg b/test_data/golden/qr_with_border_radius.svg index a6eb6b0..a08845d 100644 --- a/test_data/golden/qr_with_border_radius.svg +++ b/test_data/golden/qr_with_border_radius.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/qr_with_colors.pdf b/test_data/golden/qr_with_colors.pdf index 63851fe..db8736c 100644 Binary files a/test_data/golden/qr_with_colors.pdf and b/test_data/golden/qr_with_colors.pdf differ diff --git a/test_data/golden/qr_with_colors.png b/test_data/golden/qr_with_colors.png index 9220f6f..40208d0 100644 Binary files a/test_data/golden/qr_with_colors.png and b/test_data/golden/qr_with_colors.png differ diff --git a/test_data/golden/qr_with_colors.svg b/test_data/golden/qr_with_colors.svg index 42e9cfa..a1b8089 100644 --- a/test_data/golden/qr_with_colors.svg +++ b/test_data/golden/qr_with_colors.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/qr_with_colors_hex.svg b/test_data/golden/qr_with_colors_hex.svg index 13fe803..b770432 100644 --- a/test_data/golden/qr_with_colors_hex.svg +++ b/test_data/golden/qr_with_colors_hex.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/qr_with_colors_rgba.png b/test_data/golden/qr_with_colors_rgba.png index c8271e9..170ca0d 100644 Binary files a/test_data/golden/qr_with_colors_rgba.png and b/test_data/golden/qr_with_colors_rgba.png differ diff --git a/test_data/golden/qr_with_colors_rgba.svg b/test_data/golden/qr_with_colors_rgba.svg index 9dc83a9..7c429d1 100644 --- a/test_data/golden/qr_with_colors_rgba.svg +++ b/test_data/golden/qr_with_colors_rgba.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/qr_with_ec_level.svg b/test_data/golden/qr_with_ec_level.svg index 6f3575a..f83a18d 100644 --- a/test_data/golden/qr_with_ec_level.svg +++ b/test_data/golden/qr_with_ec_level.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/qr_with_empty_options.png b/test_data/golden/qr_with_empty_options.png index 47227ca..80bed2e 100644 Binary files a/test_data/golden/qr_with_empty_options.png and b/test_data/golden/qr_with_empty_options.png differ diff --git a/test_data/golden/qr_with_logo.pdf b/test_data/golden/qr_with_logo.pdf index 5072dcd..03e5efd 100644 Binary files a/test_data/golden/qr_with_logo.pdf and b/test_data/golden/qr_with_logo.pdf differ diff --git a/test_data/golden/qr_with_logo.png b/test_data/golden/qr_with_logo.png index e451a46..3849a56 100644 Binary files a/test_data/golden/qr_with_logo.png and b/test_data/golden/qr_with_logo.png differ diff --git a/test_data/golden/qr_with_logo.svg b/test_data/golden/qr_with_logo.svg index f372e54..c4933cd 100644 --- a/test_data/golden/qr_with_logo.svg +++ b/test_data/golden/qr_with_logo.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/qr_with_logo_as_arraybuffer.svg b/test_data/golden/qr_with_logo_as_arraybuffer.svg index f372e54..c4933cd 100644 --- a/test_data/golden/qr_with_logo_as_arraybuffer.svg +++ b/test_data/golden/qr_with_logo_as_arraybuffer.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/qr_with_logo_as_arraybuffer_jpg.svg b/test_data/golden/qr_with_logo_as_arraybuffer_jpg.svg index efe3e53..771ff07 100644 --- a/test_data/golden/qr_with_logo_as_arraybuffer_jpg.svg +++ b/test_data/golden/qr_with_logo_as_arraybuffer_jpg.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/qr_with_logo_jpg.png b/test_data/golden/qr_with_logo_jpg.png index a92ff38..3ed7c34 100644 Binary files a/test_data/golden/qr_with_logo_jpg.png and b/test_data/golden/qr_with_logo_jpg.png differ diff --git a/test_data/golden/qr_with_margin.png b/test_data/golden/qr_with_margin.png index 54eaea2..b1b7405 100644 Binary files a/test_data/golden/qr_with_margin.png and b/test_data/golden/qr_with_margin.png differ diff --git a/test_data/golden/qr_with_size.png b/test_data/golden/qr_with_size.png index 5458e4b..261f6d2 100644 Binary files a/test_data/golden/qr_with_size.png and b/test_data/golden/qr_with_size.png differ diff --git a/test_data/golden/qr_with_size.svg b/test_data/golden/qr_with_size.svg index 3d992ca..f02909b 100644 --- a/test_data/golden/qr_with_size.svg +++ b/test_data/golden/qr_with_size.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/test_data/golden/qr_with_undefined_size.png b/test_data/golden/qr_with_undefined_size.png index 47227ca..80bed2e 100644 Binary files a/test_data/golden/qr_with_undefined_size.png and b/test_data/golden/qr_with_undefined_size.png differ