@nuintun/qrcode
Version:
A pure JavaScript QRCode encode and decode library.
82 lines (77 loc) • 2.89 kB
JavaScript
/**
* @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
*/
;
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;