/** * Alignment pattern are fixed reference pattern in defined positions * in a matrix symbology, which enables the decode software to re-synchronise * the coordinate mapping of the image modules in the event of moderate amounts * of distortion of the image. * * Alignment patterns are present only in QR Code symbols of version 2 or larger * and their number depends on the symbol version. */ const getSymbolSize = require('./utils').getSymbolSize /** * Calculate the row/column coordinates of the center module of each alignment pattern * for the specified QR Code version. * * The alignment patterns are positioned symmetrically on either side of the diagonal * running from the top left corner of the symbol to the bottom right corner. * * Since positions are simmetrical only half of the coordinates are returned. * Each item of the array will represent in turn the x and y coordinate. * @see {@link getPositions} * * @param {Number} version QR Code version * @return {Array} Array of coordinate */ exports.getRowColCoords = function getRowColCoords (version) { if (version === 1) return [] const posCount = Math.floor(version / 7) + 2 const size = getSymbolSize(version) const intervals = size === 145 ? 26 : Math.ceil((size - 13) / (2 * posCount - 2)) * 2 const positions = [size - 7] // Last coord is always (size - 7) for (let i = 1; i < posCount - 1; i++) { positions[i] = positions[i - 1] - intervals } positions.push(6) // First coord is always 6 return positions.reverse() } /** * Returns an array containing the positions of each alignment pattern. * Each array's element represent the center point of the pattern as (x, y) coordinates * * Coordinates are calculated expanding the row/column coordinates returned by {@link getRowColCoords} * and filtering out the items that overlaps with finder pattern * * @example * For a Version 7 symbol {@link getRowColCoords} returns values 6, 22 and 38. * The alignment patterns, therefore, are to be centered on (row, column) * positions (6,22), (22,6), (22,22), (22,38), (38,22), (38,38). * Note that the coordinates (6,6), (6,38), (38,6) are occupied by finder patterns * and are not therefore used for alignment patterns. * * let pos = getPositions(7) * // [[6,22], [22,6], [22,22], [22,38], [38,22], [38,38]] * * @param {Number} version QR Code version * @return {Array} Array of coordinates */ exports.getPositions = function getPositions (version) { const coords = [] const pos = exports.getRowColCoords(version) const posLength = pos.length for (let i = 0; i < posLength; i++) { for (let j = 0; j < posLength; j++) { // Skip if position is occupied by finder patterns if ((i === 0 && j === 0) || // top-left (i === 0 && j === posLength - 1) || // bottom-left (i === posLength - 1 && j === 0)) { // top-right continue } coords.push([pos[i], pos[j]]) } } return coords }