UNPKG

@nuintun/qrcode

Version:

A pure JavaScript QRCode encode and decode library.

82 lines (77 loc) 2.89 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 */ 'use strict'; const utils = require('../../common/utils.cjs'); const PlotLine = require('../../common/PlotLine.cjs'); const Point = require('../../common/Point.cjs'); /** * @module module */ function sizeOfBlackWhiteBlackRun(matrix, from, to) { // In black pixels, looking for white, first or second time. let state = 0; const { width, height } = matrix; const centerX = (from.x + to.x) / 2; const centerY = (from.y + to.y) / 2; // Center point is already enough. const center = new Point.Point(centerX, centerY); const points = new PlotLine.PlotLine(from, center).points(); for (const [x, y] of points) { // Now count other way -- don't run off image though of course. if (x < 0 || y < 0 || x >= width || y >= height) { if (state === 2) { return Point.distance(from, new Point.Point(x, y)); } return NaN; } // Does current pixel mean we have moved white to black or vice versa? // Scanning black in state 0,2 and white in state 1, so if we find the wrong // color, advance to next state or end if we are in state 2 already. if ((state === 1) === (matrix.get(x, y) === 1)) { if (state === 2) { return Point.distance(from, new Point.Point(x, y)); } state++; } } return NaN; } function sizeOfBlackWhiteBlackRunBothWays(matrix, from, to) { const size1 = sizeOfBlackWhiteBlackRun(matrix, from, to); if (Number.isNaN(size1)) { return NaN; } const { x: toX, y: toY } = to; const { x: fromX, y: fromY } = from; const otherToX = fromX - (toX - fromX); const otherToY = fromY - (toY - fromY); const size2 = sizeOfBlackWhiteBlackRun(matrix, from, new Point.Point(otherToX, otherToY)); if (Number.isNaN(size2)) { return NaN; } // Middle pixel is double-counted this way; subtract 1. return size1 + size2 - 1; } function calculateModuleSizeOneWay(matrix, pattern1, pattern2) { const point1 = new Point.Point(utils.toInt32(pattern1.x), utils.toInt32(pattern1.y)); const point2 = new Point.Point(utils.toInt32(pattern2.x), utils.toInt32(pattern2.y)); const moduleSize1 = sizeOfBlackWhiteBlackRunBothWays(matrix, point1, point2); const moduleSize2 = sizeOfBlackWhiteBlackRunBothWays(matrix, point2, point1); if (Number.isNaN(moduleSize1)) { return moduleSize2 / 7; } if (Number.isNaN(moduleSize2)) { return moduleSize1 / 7; } // Average them, and divide by 7 since we've counted the width of 3 black modules, // and 1 white and 1 black module on either side. Ergo, divide sum by 14. return (moduleSize1 + moduleSize2) / 14; } exports.calculateModuleSizeOneWay = calculateModuleSizeOneWay;