UNPKG

@nuintun/qrcode

Version:

A pure JavaScript QRCode encode and decode library.

74 lines (70 loc) 2.48 kB
/** * @module QRCode * @package @nuintun/qrcode * @license MIT * @version 5.0.2 * @author nuintun <nuintun@qq.com> * @description A pure JavaScript QRCode encode and decode library. * @see https://github.com/nuintun/qrcode#readme */ import { Pattern } from './Pattern.js'; import { accumulate } from '../common/utils.js'; import { centerFromScanlineEnd, getDiagonalScanline } from './utils/scanline.js'; import { alignCrossPattern, isDiagonalScanlineCheckPassed, calculatePatternNoise } from './utils/pattern.js'; /** * @module PatternFinder */ class PatternFinder { #strict; #matrix; #ratios; #patterns = []; constructor(matrix, ratios, strict) { this.#matrix = matrix; this.#ratios = ratios; this.#strict = strict; } get matrix() { return this.#matrix; } get patterns() { return this.#patterns; } match(x, y, scanline, overscan) { const matrix = this.#matrix; const ratios = this.#ratios; let centerX = centerFromScanlineEnd(scanline, x); const [centerY, vertical] = alignCrossPattern(matrix, centerX, y, overscan, ratios, true); if (centerY >= 0) { let horizontal; // Re-horizontal check. [centerX, horizontal] = alignCrossPattern(matrix, centerX, centerY, overscan, ratios); if (centerX >= 0) { const slash = getDiagonalScanline(matrix, centerX, centerY, overscan); const backslash = getDiagonalScanline(matrix, centerX, centerY, overscan, true); if (isDiagonalScanlineCheckPassed(slash, backslash, ratios, this.#strict)) { const noise = calculatePatternNoise(ratios, horizontal, vertical, slash, backslash); const width = accumulate(horizontal); const height = accumulate(vertical); const patterns = this.#patterns; const { length } = patterns; let combined = false; for (let i = 0; i < length; i++) { const pattern = patterns[i]; // Look for about the same center and module size. if (Pattern.equals(pattern, centerX, centerY, width, height)) { combined = true; patterns[i] = Pattern.combine(pattern, centerX, centerY, width, height, noise); break; } } // Hadn't found this before; save it. if (!combined) { patterns.push(new Pattern(ratios, centerX, centerY, width, height, noise)); } } } } } } export { PatternFinder };