UNPKG

@syncfusion/ej2-barcode-generator

Version:

Barcode generator component is a pure JavaScript library which will convert a string to Barcode and show it to the user. This supports major 1D and 2D barcodes including coda bar, code 128, QR Code.

1,056 lines (927 loc) 68.8 kB
import { BaseAttributes } from '../barcode/rendering/canvas-interface'; import { MarginModel } from '../barcode/primitives/margin-model'; import { QRInputMode, QRCodeVersion, ErrorCorrectionLevel, QuietZone } from '../barcode/enum/enum'; import { PdfQRBarcodeValues } from './qr-barcode-values'; import { ErrorCorrectionCodewords } from './qr-error-correction'; import { createMeasureElements, measureText } from '../barcode/utility/dom-util'; import { Size } from '../barcode/primitives/size'; import { DisplayTextModel } from '../barcode/primitives/displaytext-model'; import { BarcodeRenderer } from '../barcode/rendering/renderer'; import { Rect } from '../barcode'; import { QRCodeLogoModel } from '../barcode/primitives/icon-model'; /** * Qrcode used to calculate the Qrcode control */ export class QRCode { private mVersion: QRCodeVersion = QRCodeVersion.Version01; private mInputMode: QRInputMode = 'NumericMode'; private validInput: boolean = true; /** * Total bits required in mixing mode. */ private totalBits: number = 0; /** * Holds the data of Function Pattern. */ private mModuleValue: ModuleValue[][] = []; private mDataAllocationValues: ModuleValue[][] = [[], []]; private mQrBarcodeValues: PdfQRBarcodeValues; /** * Set version for mixing mode. */ private mixVersionERC: boolean = true; /** * Data to be currently encoded in Mixing Mode */ private mixExecutablePart: string = null; /** * Count of mixing mode blocks. */ private mixDataCount: number = 0; /** * Holds the Number of Modules. */ private mNoOfModules: number = 21; /** * Check if User Mentioned Mode */ private mIsUserMentionedMode: boolean = false; private chooseDefaultMode: boolean = false; /** @private */ public text: string; private mixRemainingPart: string = null; private isXdimension: boolean = false; private mXDimension: number = 1; /** * Get or Private set the XDimension values. * * @returns {number}Get or Private set the XDimension values.. * @private */ public get XDimension(): number { return this.mXDimension; } /** * Get or Private set the XDimension values. * * @param {number} value - Get or Private set the XDimension values. * @private */ public set XDimension(value: number) { this.mXDimension = value; } private get inputMode(): QRInputMode { return this.mInputMode; } private set inputMode(value: QRInputMode) { this.mInputMode = value; this.mIsUserMentionedMode = true; } /** *Get or Private set the version * * @returns {QRCodeVersion}Get or Private set the version * @private */ public get version(): QRCodeVersion { return this.mVersion; } /** * Get or Private set the version * * @param {QRCodeVersion} value - Get or Private set the version * @private */ public set version(value: QRCodeVersion) { this.mVersion = value; this.mNoOfModules = (this.mVersion - 1) * 4 + 21; if (value !== QRCodeVersion.Auto) { this.mIsUserMentionedVersion = true; } } private mIsEci: boolean = false; /** @private */ public mIsUserMentionedErrorCorrectionLevel: boolean = false; private isSvgMode: boolean; private mEciAssignmentNumber: number = 3; /** @private */ public mIsUserMentionedVersion: boolean = false; /** @private */ public mErrorCorrectionLevel: ErrorCorrectionLevel = ErrorCorrectionLevel.Low; private textList: string[] = []; private mode: QRInputMode[] = []; private getBaseAttributes( width: number, height: number, offSetX: number, offsetY: number, color: string, strokeColor?: string): BaseAttributes { const options: BaseAttributes = { width: width, height: height, x: offSetX, y: offsetY, color: color, strokeColor: strokeColor }; return options; } private getInstance(id: string): BarcodeRenderer { const barCode: HTMLElement = document.getElementById(id); const barcodeRenderer: BarcodeRenderer = new BarcodeRenderer(barCode.id, this.isSvgMode); return barcodeRenderer; } private drawImage(canvas: HTMLCanvasElement, options: BaseAttributes[]): void { // render image for the qrcode generator const barcodeRenderer: BarcodeRenderer = this.getInstance(canvas.id); for (let i: number = 0; i < options.length; i++) { barcodeRenderer.renderRectElement(canvas as HTMLCanvasElement, options[parseInt(i.toString(), 10)]); } } /** * Draw the QR code in SVG. * * @param {HTMLElement} char - Provide the char to render . * @param {HTMLElement} canvas - Provide the canvas element . * @param {HTMLElement} height - Provide the height for the canvas element . * @param {HTMLElement} width - Provide the width for the canvas element . * @param {HTMLElement} margin - Provide the margin for thecanvas element . * @param {HTMLElement} displayText - Provide display text for the canvas element . * @param {HTMLElement} mode - Provide the mode to render . * @param {HTMLElement} foreColor - Provide the color for the barcode to render. * @param {HTMLElement} logo - Provide the logo for the QR code. * @returns {boolean} Draw the barcode SVG . * @private */ public draw( char: string, canvas: HTMLElement, height: number, width: number, margin?: MarginModel, displayText?: DisplayTextModel, mode?: boolean, foreColor?: string, logo?: QRCodeLogoModel): boolean { this.isSvgMode = mode; this.generateValues(); if (this.validInput) { let size: number; const actualWidth: number = width - (margin.left + margin.right); let actualHeight: number = height - (margin.top + margin.bottom); size = (actualWidth >= actualHeight) ? actualHeight : actualWidth; let dimension: number = this.XDimension; const quietZone: number = QuietZone.All; let x: number = (actualWidth >= size) ? (actualWidth - size) / 2 : 0; let y: number = (actualHeight >= size) ? (actualHeight - size) / 2 : 0; y += margin.top; x += margin.left; const textBounds: BaseAttributes = this.drawDisplayText( canvas as HTMLCanvasElement, x, y, size, actualHeight, displayText, char, margin, foreColor); actualHeight -= (textBounds.height); if (displayText.margin.bottom > 0) { if (displayText.position === 'Top') { y += (displayText.margin.bottom); actualHeight -= (displayText.margin.bottom); } else { actualHeight -= displayText.margin.bottom; } } if (displayText.margin.top > 0) { if (displayText.position === 'Top') { y += (displayText.margin.top); actualHeight -= (displayText.margin.top); } else { actualHeight -= displayText.margin.top; } } size = (actualWidth >= actualHeight) ? actualHeight : actualWidth; const moduleCount: number = this.mNoOfModules + 2 * quietZone + 1; dimension = size / moduleCount; // Calculations to place the logo in the center of the QR code. let imageBound: Rect = null; let imageAttributes: BaseAttributes = null; if (logo !== null && logo.imageSource !== '') { x = ((actualWidth >= size) ? (actualWidth - size) / 2 : 0) + margin.left; const qrsize: number = size - (((2 * quietZone) + 1) * dimension); const sizeRatio: number = 0.3; const imgwidth: number = logo.width ? Math.min(logo.width, qrsize * sizeRatio) : qrsize * sizeRatio; const imgheight: number = logo.height ? Math.min(logo.height, qrsize * sizeRatio) : qrsize * sizeRatio; const ximg: number = (x + (quietZone * dimension)) + (qrsize / 2) - (imgwidth / 2); const yimg: number = (y + (quietZone * dimension)) + (qrsize / 2) - (imgheight / 2); imageAttributes = { x: ximg, y: yimg, width: imgwidth, height: imgheight, color: 'transparent', imageSource: logo.imageSource }; imageBound = { x: imageAttributes.x, y: imageAttributes.y, width: imageAttributes.width, height: imageAttributes.height }; } this.isXdimension = true; width = (this.mNoOfModules + 2 * quietZone) * dimension; height = (this.mNoOfModules + 2 * quietZone) * dimension; const w: number = this.mNoOfModules + 2 * quietZone; const h: number = this.mNoOfModules + 2 * quietZone; const optionsCollection: BaseAttributes[] = []; for (let i: number = 0; i < w; i++) { for (let j: number = 0; j < h; j++) { let color: string; color = (this.mModuleValue[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)].isBlack) ? foreColor : 'white'; if (this.mDataAllocationValues[parseInt(j.toString(), 10)][parseInt(i.toString(), 10)].isFilled) { if (this.mDataAllocationValues[parseInt(j.toString(), 10)][parseInt(i.toString(), 10)].isBlack) { color = foreColor; } } if (color !== 'white') { const options: BaseAttributes = this.getBaseAttributes( dimension, dimension, x, displayText.position === 'Bottom' ? y : y + textBounds.height / 2, color); // To exclude options, if it is contained by imageBounds region. const currentBound: Rect = { x: options.x, y: options.y, width: dimension, height: dimension}; if (imageBound == null || !this.containsRect(imageBound, currentBound)) { optionsCollection.push(options); } } x = x + dimension; } y = y + dimension; x = ((actualWidth >= size) ? (actualWidth - size) / 2 : 0) + margin.left; } this.drawImage(canvas as HTMLCanvasElement, optionsCollection); if (imageAttributes) { this.drawImage(canvas as HTMLCanvasElement, [imageAttributes] as any); } this.mModuleValue = undefined; this.mDataAllocationValues = undefined; return true; } else { return false; } } // Helper function to check if one rectangle contains another private containsRect(rect1: Rect, rect2: Rect): boolean { return rect1.x <= rect2.x && rect1.x + rect1.width >= rect2.x + rect2.width && rect1.y <= rect2.y && rect1.y + rect1.height >= rect2.y + rect2.height; } private drawText(canvas: HTMLCanvasElement, options: BaseAttributes): void { const barcodeRenderer: BarcodeRenderer = this.getInstance(canvas.id); barcodeRenderer.renderTextElement(canvas as HTMLCanvasElement, options); } private drawDisplayText( canvas: HTMLCanvasElement, x: number, y: number, width: number, height: number, text?: DisplayTextModel, value?: string, margin?: MarginModel, foreColor?: string) : BaseAttributes { const displayText: DisplayTextModel = text; createMeasureElements(); const options: BaseAttributes = this.getBaseAttributes(width, height, x, y, 'black'); options.string = (displayText.text ? displayText.text : value); options.color = foreColor; options.fontStyle = displayText.font; options.stringSize = displayText.size; options.visibility = displayText.visibility; const textSize: Size = measureText(options); const textHeight: number = (textSize.height / 2) + 2; options.height = textHeight; options.x = ((x + width / 2) - textSize.width / 2) + displayText.margin.left - displayText.margin.right; if (text.position === 'Bottom') { if (text.margin.top > 0) { options.y = ((y + height)); } if (text.margin.bottom > 0) { options.y = ((y + height)) - displayText.margin.bottom; } else { if (margin.top < 10) { options.y = height + textSize.height / 2; } else { options.y = height + margin.top; } } } else { if (text.margin.top > 0) { options.y = y + text.margin.top + textSize.height / 2; } else { options.y = y + textSize.height / 2; } } if (text.visibility) { this.drawText(canvas as HTMLCanvasElement, options); } return options; } private generateValues(): void { this.mQrBarcodeValues = new PdfQRBarcodeValues(this.mVersion, this.mErrorCorrectionLevel); this.initialize(); this.mQrBarcodeValues = new PdfQRBarcodeValues(this.mVersion, this.mErrorCorrectionLevel); for (let i: number = 0; i < this.mNoOfModules; i++) { // eslint-disable-next-line this.mModuleValue.push([0] as any); for (let j: number = 0; j < this.mNoOfModules; j++) { this.mModuleValue[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)] = new ModuleValue(); } } this.drawPDP(0, 0); this.drawPDP(this.mNoOfModules - 7, 0); this.drawPDP(0, this.mNoOfModules - 7); this.drawTimingPattern(); if (this.mVersion !== 1) { const allignCoOrdinates: number[] = this.getAlignmentPatternCoOrdinates(); for (const i of Object.keys(allignCoOrdinates)) { for (const j of Object.keys(allignCoOrdinates)) { if (!this.mModuleValue[allignCoOrdinates[`${i}`]][allignCoOrdinates[`${j}`]].isPdp) { this.drawAlignmentPattern(allignCoOrdinates[`${i}`], allignCoOrdinates[`${j}`]); } } } } this.allocateFormatAndVersionInformation(); let encodeData: boolean[] = null; encodeData = this.encodeData(); this.dataAllocationAndMasking(encodeData); this.drawFormatInformation(); this.addQuietZone(); this.mQrBarcodeValues.FormatInformation = undefined; this.mQrBarcodeValues.NumberOfDataCodeWord = undefined; this.mQrBarcodeValues.NumberOfErrorCorrectingCodeWords = undefined; this.mQrBarcodeValues.VersionInformation = undefined; this.mQrBarcodeValues.alphanumericDataCapacityHigh = undefined; this.mQrBarcodeValues.alphanumericDataCapacityLow = undefined; this.mQrBarcodeValues.alphanumericDataCapacityMedium = undefined; this.mQrBarcodeValues.alphanumericDataCapacityQuartile = undefined; this.mQrBarcodeValues.binaryDataCapacityHigh = undefined; this.mQrBarcodeValues.dataCapacityValues = undefined; this.mQrBarcodeValues.endValues = undefined; this.mQrBarcodeValues.dataCapacityValues = undefined; this.mQrBarcodeValues = undefined; this.mIsUserMentionedVersion = undefined; this.mVersion = undefined; } /** * Draw the PDP in the given location * * @returns {void} Draw the PDP in the given location. * @param {string} x - The x co-ordinate. * @param {string} y - The y co-ordinate. * @private */ private drawPDP(x: number, y: number): void { let i: number; let j: number; for (i = x, j = y; i < x + 7; i++ , j++) { this.mModuleValue[parseInt(i.toString(), 10)][parseInt(y.toString(), 10)].isBlack = true; this.mModuleValue[parseInt(i.toString(), 10)][parseInt(y.toString(), 10)].isFilled = true; this.mModuleValue[parseInt(i.toString(), 10)][parseInt(y.toString(), 10)].isPdp = true; this.mModuleValue[parseInt(i.toString(), 10)][y + 6].isBlack = true; this.mModuleValue[parseInt(i.toString(), 10)][y + 6].isFilled = true; this.mModuleValue[parseInt(i.toString(), 10)][y + 6].isPdp = true; if (y + 7 < this.mNoOfModules) { this.mModuleValue[parseInt(i.toString(), 10)][y + 7].isBlack = false; this.mModuleValue[parseInt(i.toString(), 10)][y + 7].isFilled = true; this.mModuleValue[parseInt(i.toString(), 10)][y + 7].isPdp = true; } else if (y - 1 >= 0) { this.mModuleValue[parseInt(i.toString(), 10)][y - 1].isBlack = false; this.mModuleValue[parseInt(i.toString(), 10)][y - 1].isFilled = true; this.mModuleValue[parseInt(i.toString(), 10)][y - 1].isPdp = true; } this.mModuleValue[parseInt(x.toString(), 10)][parseInt(j.toString(), 10)].isBlack = true; this.mModuleValue[parseInt(x.toString(), 10)][parseInt(j.toString(), 10)].isFilled = true; this.mModuleValue[parseInt(x.toString(), 10)][parseInt(j.toString(), 10)].isPdp = true; this.mModuleValue[x + 6][parseInt(j.toString(), 10)].isBlack = true; this.mModuleValue[x + 6][parseInt(j.toString(), 10)].isFilled = true; this.mModuleValue[x + 6][parseInt(j.toString(), 10)].isPdp = true; if (x + 7 < this.mNoOfModules) { this.mModuleValue[x + 7][parseInt(j.toString(), 10)].isBlack = false; this.mModuleValue[x + 7][parseInt(j.toString(), 10)].isFilled = true; this.mModuleValue[x + 7][parseInt(j.toString(), 10)].isPdp = true; } else if (x - 1 >= 0) { this.mModuleValue[x - 1][parseInt(j.toString(), 10)].isBlack = false; this.mModuleValue[x - 1][parseInt(j.toString(), 10)].isFilled = true; this.mModuleValue[x - 1][parseInt(j.toString(), 10)].isPdp = true; } } if (x + 7 < this.mNoOfModules && y + 7 < this.mNoOfModules) { this.mModuleValue[x + 7][y + 7].isBlack = false; this.mModuleValue[x + 7][y + 7].isFilled = true; this.mModuleValue[x + 7][y + 7].isPdp = true; } else if (x + 7 < this.mNoOfModules && y + 7 >= this.mNoOfModules) { this.mModuleValue[x + 7][y - 1].isBlack = false; this.mModuleValue[x + 7][y - 1].isFilled = true; this.mModuleValue[x + 7][y - 1].isPdp = true; } else if (x + 7 >= this.mNoOfModules && y + 7 < this.mNoOfModules) { this.mModuleValue[x - 1][y + 7].isBlack = false; this.mModuleValue[x - 1][y + 7].isFilled = true; this.mModuleValue[x - 1][y + 7].isPdp = true; } x++; y++; for (i = x, j = y; i < x + 5; i++ , j++) { this.mModuleValue[parseInt(i.toString(), 10)][parseInt(y.toString(), 10)].isBlack = false; this.mModuleValue[parseInt(i.toString(), 10)][parseInt(y.toString(), 10)].isFilled = true; this.mModuleValue[parseInt(i.toString(), 10)][parseInt(y.toString(), 10)].isPdp = true; this.mModuleValue[parseInt(i.toString(), 10)][y + 4].isBlack = false; this.mModuleValue[parseInt(i.toString(), 10)][y + 4].isFilled = true; this.mModuleValue[parseInt(i.toString(), 10)][y + 4].isPdp = true; this.mModuleValue[parseInt(x.toString(), 10)][parseInt(j.toString(), 10)].isBlack = false; this.mModuleValue[parseInt(x.toString(), 10)][parseInt(j.toString(), 10)].isFilled = true; this.mModuleValue[parseInt(x.toString(), 10)][parseInt(j.toString(), 10)].isPdp = true; this.mModuleValue[x + 4][parseInt(j.toString(), 10)].isBlack = false; this.mModuleValue[x + 4][parseInt(j.toString(), 10)].isFilled = true; this.mModuleValue[x + 4][parseInt(j.toString(), 10)].isPdp = true; } x++; y++; for (i = x, j = y; i < x + 3; i++ , j++) { this.mModuleValue[parseInt(i.toString(), 10)][parseInt(y.toString(), 10)].isBlack = true; this.mModuleValue[parseInt(i.toString(), 10)][parseInt(y.toString(), 10)].isFilled = true; this.mModuleValue[parseInt(i.toString(), 10)][parseInt(y.toString(), 10)].isPdp = true; this.mModuleValue[parseInt(i.toString(), 10)][y + 2].isBlack = true; this.mModuleValue[parseInt(i.toString(), 10)][y + 2].isFilled = true; this.mModuleValue[parseInt(i.toString(), 10)][y + 2].isPdp = true; this.mModuleValue[parseInt(x.toString(), 10)][parseInt(j.toString(), 10)].isBlack = true; this.mModuleValue[parseInt(x.toString(), 10)][parseInt(j.toString(), 10)].isFilled = true; this.mModuleValue[parseInt(x.toString(), 10)][parseInt(j.toString(), 10)].isPdp = true; this.mModuleValue[x + 2][parseInt(j.toString(), 10)].isBlack = true; this.mModuleValue[x + 2][parseInt(j.toString(), 10)].isFilled = true; this.mModuleValue[x + 2][parseInt(j.toString(), 10)].isPdp = true; } this.mModuleValue[x + 1][y + 1].isBlack = true; this.mModuleValue[x + 1][y + 1].isFilled = true; this.mModuleValue[x + 1][y + 1].isPdp = true; } /** * Draw the Timing Pattern * * @returns {void} Draw the PDP in the given location. * @private */ private drawTimingPattern(): void { for (let i: number = 8; i < this.mNoOfModules - 8; i += 2) { this.mModuleValue[parseInt(i.toString(), 10)][6].isBlack = true; this.mModuleValue[parseInt(i.toString(), 10)][6].isFilled = true; this.mModuleValue[i + 1][6].isBlack = false; this.mModuleValue[i + 1][6].isFilled = true; this.mModuleValue[6][parseInt(i.toString(), 10)].isBlack = true; this.mModuleValue[6][parseInt(i.toString(), 10)].isFilled = true; this.mModuleValue[6][i + 1].isBlack = false; this.mModuleValue[6][i + 1].isFilled = true; } this.mModuleValue[this.mNoOfModules - 8][8].isBlack = true; this.mModuleValue[this.mNoOfModules - 8][8].isFilled = true; } /* tslint:disable */ private initialize(): void { if (!this.mIsUserMentionedMode) { this.chooseDefaultMode = true; } //Task 913517: Handle null properties for diagram and barcode properties -phase1 this.mVersion = this.mVersion || 1; this.mErrorCorrectionLevel = this.mErrorCorrectionLevel || 7; let mode: QRInputMode = 'NumericMode'; //const alphaCount: number = 0; //const numCount: number = 0; //const binaryCount: number = 0; for (let i: number = 0; i < this.text.length; i++) { // eslint-disable-next-line if (this.text.charCodeAt(i) < 58 && this.text.charCodeAt(i) > 47) { } else if ((this.text.charCodeAt(i) < 91 && this.text.charCodeAt(i) > 64) || this.text[parseInt(i.toString(), 10)] === '$' || this.text[parseInt(i.toString(), 10)] === '%' || this.text[parseInt(i.toString(), 10)] === '*' || this.text[parseInt(i.toString(), 10)] === '+' || this.text[parseInt(i.toString(), 10)] === '-' || this.text[parseInt(i.toString(), 10)] === '.' || this.text[parseInt(i.toString(), 10)] === '/' || this.text[parseInt(i.toString(), 10)] === ':' || this.text[parseInt(i.toString(), 10)] === ' ') { mode = 'AlphaNumericMode'; } else if ((this.text.charCodeAt(i) >= 65377 && this.text.charCodeAt(i) <= 65439) || (this.text.charCodeAt(i) >= 97 && this.text.charCodeAt(i) <= 122)) { mode = 'BinaryMode'; break; } else { mode = 'BinaryMode'; this.mIsEci = true; break; } } if (this.mIsUserMentionedMode) { if (mode !== this.mInputMode) { if (((mode === 'AlphaNumericMode' || mode === 'BinaryMode') && this.mInputMode === 'NumericMode') || (mode === 'BinaryMode' && this.mInputMode === 'AlphaNumericMode')) { this.validInput = false; if (mode !== this.mInputMode) { if (((mode === 'AlphaNumericMode' || mode === 'BinaryMode') && this.mInputMode === 'NumericMode') || (mode === 'BinaryMode' && this.mInputMode === 'AlphaNumericMode')) { this.validInput = false; } } } } } this.inputMode = mode; if (this.mIsEci === true) { for (let i: number = 0; i < this.text.length; i++) { if (this.text.charCodeAt(i) >= 32 && this.text.charCodeAt(i) <= 255) { continue; } } } if (this.mixVersionERC) { if (!this.mIsUserMentionedVersion || (this.mVersion & QRCodeVersion.Auto)) { let dataCapacityOfVersions: number[] = null; if (this.mIsUserMentionedErrorCorrectionLevel) { switch (this.mInputMode) { case 'NumericMode': switch (this.mErrorCorrectionLevel) { case 7: dataCapacityOfVersions = this.mQrBarcodeValues.numericDataCapacityLow; break; case 15: dataCapacityOfVersions = this.mQrBarcodeValues.numericDataCapacityMedium; break; case 25: dataCapacityOfVersions = this.mQrBarcodeValues.numericDataCapacityQuartile; break; case 30: dataCapacityOfVersions = this.mQrBarcodeValues.numericDataCapacityHigh; break; } break; case 'AlphaNumericMode': switch (this.mErrorCorrectionLevel) { case 7: dataCapacityOfVersions = this.mQrBarcodeValues.alphanumericDataCapacityLow; break; case 15: dataCapacityOfVersions = this.mQrBarcodeValues.alphanumericDataCapacityMedium; break; case 25: dataCapacityOfVersions = this.mQrBarcodeValues.alphanumericDataCapacityQuartile; break; case 30: dataCapacityOfVersions = this.mQrBarcodeValues.alphanumericDataCapacityHigh; break; } break; case 'BinaryMode': switch (this.mErrorCorrectionLevel) { case 7: dataCapacityOfVersions = this.mQrBarcodeValues.binaryDataCapacityLow; break; case 15: dataCapacityOfVersions = this.mQrBarcodeValues.binaryDataCapacityMedium; break; case 25: dataCapacityOfVersions = this.mQrBarcodeValues.binaryDataCapacityQuartile; break; case 30: dataCapacityOfVersions = this.mQrBarcodeValues.binaryDataCapacityHigh; break; } break; } } else { this.mErrorCorrectionLevel = ErrorCorrectionLevel.Medium; switch (this.mInputMode) { case 'NumericMode': dataCapacityOfVersions = this.mQrBarcodeValues.numericDataCapacityMedium; break; case 'AlphaNumericMode': dataCapacityOfVersions = this.mQrBarcodeValues.alphanumericDataCapacityMedium; break; case 'BinaryMode': dataCapacityOfVersions = this.mQrBarcodeValues.binaryDataCapacityMedium; break; } } let i: number; for (i = 0; i < dataCapacityOfVersions.length; i++) { if (dataCapacityOfVersions[parseInt(i.toString(), 10)] > this.text.length) { break; } } this.version = i + 1; } else if (this.mIsUserMentionedVersion) { if (this.mIsUserMentionedErrorCorrectionLevel) { let capacity: number = 0; if (this.mInputMode === 'AlphaNumericMode') { capacity = this.mQrBarcodeValues.getAlphanumericDataCapacity(this.mVersion, this.mErrorCorrectionLevel); } else if (this.mInputMode === 'NumericMode') { capacity = this.mQrBarcodeValues.getNumericDataCapacity(this.mVersion, this.mErrorCorrectionLevel); } if (this.mInputMode === 'BinaryMode') { capacity = this.mQrBarcodeValues.getBinaryDataCapacity(this.mVersion, this.mErrorCorrectionLevel); } if (capacity < this.text.length) { if (!this.chooseDefaultMode) { this.validInput = false; } else { this.mixVersionERC = false; } } } else { let capacityLow: number = 0; let capacityMedium: number = 0; let capacityQuartile: number = 0; let capacityHigh: number = 0; if (this.mInputMode === 'AlphaNumericMode') { capacityLow = this.mQrBarcodeValues.getAlphanumericDataCapacity(this.mVersion, ErrorCorrectionLevel.Low); capacityMedium = this.mQrBarcodeValues.getAlphanumericDataCapacity(this.mVersion, ErrorCorrectionLevel.Medium); capacityQuartile = this.mQrBarcodeValues.getAlphanumericDataCapacity( this.mVersion, ErrorCorrectionLevel.Quartile); capacityHigh = this.mQrBarcodeValues.getAlphanumericDataCapacity(this.mVersion, ErrorCorrectionLevel.High); } else if (this.mInputMode === 'NumericMode') { capacityLow = this.mQrBarcodeValues.getNumericDataCapacity(this.mVersion, ErrorCorrectionLevel.Low); capacityMedium = this.mQrBarcodeValues.getNumericDataCapacity(this.mVersion, ErrorCorrectionLevel.Medium); capacityQuartile = this.mQrBarcodeValues.getNumericDataCapacity(this.mVersion, ErrorCorrectionLevel.Quartile); capacityHigh = this.mQrBarcodeValues.getNumericDataCapacity(this.mVersion, ErrorCorrectionLevel.High); } else if (this.mInputMode === 'BinaryMode') { capacityLow = this.mQrBarcodeValues.getBinaryDataCapacity(this.mVersion, ErrorCorrectionLevel.Low); capacityMedium = this.mQrBarcodeValues.getBinaryDataCapacity(this.mVersion, ErrorCorrectionLevel.Medium); capacityQuartile = this.mQrBarcodeValues.getBinaryDataCapacity(this.mVersion, ErrorCorrectionLevel.Quartile); capacityHigh = this.mQrBarcodeValues.getBinaryDataCapacity(this.mVersion, ErrorCorrectionLevel.High); } if (capacityHigh > this.text.length) { this.mErrorCorrectionLevel = ErrorCorrectionLevel.High; } else if (capacityQuartile > this.text.length) { this.mErrorCorrectionLevel = ErrorCorrectionLevel.Quartile; } else if (capacityMedium > this.text.length) { this.mErrorCorrectionLevel = ErrorCorrectionLevel.Medium; } else if (capacityLow > this.text.length) { this.mErrorCorrectionLevel = ErrorCorrectionLevel.Low; } else { this.validInput = false; } } } } } /* tslint:enable */ /** * Adds quietzone to the QR Barcode..\ * * @returns {void} Adds quietzone to the QR Barcode. . * @private */ private addQuietZone(): void { const quietZone: number = QuietZone.All; const w: number = this.mNoOfModules + 2 * quietZone; const h: number = this.mNoOfModules + 2 * quietZone; const tempValue1: ModuleValue[][] = []; const tempValue2: ModuleValue[][] = []; for (let i: number = 0; i < w; i++) { // tslint:disable-next-line:no-any // eslint-disable-next-line tempValue1.push([0] as any); // tslint:disable-next-line:no-any // eslint-disable-next-line tempValue2.push([0] as any); for (let j: number = 0; j < h; j++) { tempValue1[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)] = new ModuleValue(); tempValue2[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)] = new ModuleValue(); } } // Top quietzone. for (let i: number = 0; i < h; i++) { tempValue1[0][parseInt(i.toString(), 10)] = new ModuleValue(); tempValue1[0][parseInt(i.toString(), 10)].isBlack = false; tempValue1[0][parseInt(i.toString(), 10)].isFilled = false; tempValue1[0][parseInt(i.toString(), 10)].isPdp = false; tempValue2[0][parseInt(i.toString(), 10)] = new ModuleValue(); tempValue2[0][parseInt(i.toString(), 10)].isBlack = false; tempValue2[0][parseInt(i.toString(), 10)].isFilled = false; tempValue2[0][parseInt(i.toString(), 10)].isPdp = false; } for (let i: number = quietZone; i < w - quietZone; i++) { // Left quietzone. tempValue1[parseInt(i.toString(), 10)][0] = new ModuleValue(); tempValue1[parseInt(i.toString(), 10)][0].isBlack = false; tempValue1[parseInt(i.toString(), 10)][0].isFilled = false; tempValue1[parseInt(i.toString(), 10)][0].isPdp = false; tempValue2[parseInt(i.toString(), 10)][0] = new ModuleValue(); tempValue2[parseInt(i.toString(), 10)][0].isBlack = false; tempValue2[parseInt(i.toString(), 10)][0].isFilled = false; tempValue2[parseInt(i.toString(), 10)][0].isPdp = false; for (let j: number = quietZone; j < h - quietZone; j++) { tempValue1[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)] = this.mModuleValue[i - quietZone][j - quietZone]; tempValue2[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)] = this.mDataAllocationValues[i - quietZone][j - quietZone]; } // Right quietzone. tempValue1[parseInt(i.toString(), 10)][h - quietZone] = new ModuleValue(); tempValue1[parseInt(i.toString(), 10)][h - quietZone].isBlack = false; tempValue1[parseInt(i.toString(), 10)][h - quietZone].isFilled = false; tempValue1[parseInt(i.toString(), 10)][h - quietZone].isPdp = false; tempValue2[parseInt(i.toString(), 10)][h - quietZone] = new ModuleValue(); tempValue2[parseInt(i.toString(), 10)][h - quietZone].isBlack = false; tempValue2[parseInt(i.toString(), 10)][h - quietZone].isFilled = false; tempValue2[parseInt(i.toString(), 10)][h - quietZone].isPdp = false; } //Bottom quietzone. for (let i: number = 0; i < h; i++) { tempValue1[w - quietZone][parseInt(i.toString(), 10)] = new ModuleValue(); tempValue1[w - quietZone][parseInt(i.toString(), 10)].isBlack = false; tempValue1[w - quietZone][parseInt(i.toString(), 10)].isFilled = false; tempValue1[w - quietZone][parseInt(i.toString(), 10)].isPdp = false; tempValue2[w - quietZone][parseInt(i.toString(), 10)] = new ModuleValue(); tempValue2[w - quietZone][parseInt(i.toString(), 10)].isBlack = false; tempValue2[w - quietZone][parseInt(i.toString(), 10)].isFilled = false; tempValue2[w - quietZone][parseInt(i.toString(), 10)].isPdp = false; } this.mModuleValue = tempValue1; this.mDataAllocationValues = tempValue2; } /** * Draw the Format Information.\ * * @returns {void} Draw the Format Information . * @private */ private drawFormatInformation(): void { const formatInformation: number[] = this.mQrBarcodeValues.FormatInformation; let count: number = 0; for (let i: number = 0; i < 7; i++) { //Draw from 14 to 8 if (i === 6) { this.mModuleValue[i + 1][8].isBlack = formatInformation[parseInt(count.toString(), 10)] === 1 ? true : false; } else { this.mModuleValue[parseInt(i.toString(), 10)][8].isBlack = formatInformation[parseInt(count.toString(), 10)] === 1 ? true : false; } this.mModuleValue[8][this.mNoOfModules - i - 1].isBlack = formatInformation[count++] === 1 ? true : false; } count = 14; for (let i: number = 0; i < 7; i++) { //Draw from 0 to 6 if (i === 6) { this.mModuleValue[8][i + 1].isBlack = formatInformation[parseInt(count.toString(), 10)] === 1 ? true : false; } else { this.mModuleValue[8][parseInt(i.toString(), 10)].isBlack = formatInformation[parseInt(count.toString(), 10)] === 1 ? true : false; } this.mModuleValue[this.mNoOfModules - i - 1][8].isBlack = formatInformation[count--] === 1 ? true : false; } //Draw 7 this.mModuleValue[8][8].isBlack = formatInformation[7] === 1 ? true : false; this.mModuleValue[8][this.mNoOfModules - 8].isBlack = formatInformation[7] === 1 ? true : false; } /** * Allocates the Encoded Data and then Mask * * @param Data - Encoded Data */ /* tslint:disable */ private dataAllocationAndMasking(data: boolean[]): void { this.mDataAllocationValues = []; for (let i: number = 0; i < this.mNoOfModules; i++) { // tslint:disable-next-line:no-any // eslint-disable-next-line this.mDataAllocationValues.push([0] as any); for (let j: number = 0; j < this.mNoOfModules; j++) { this.mDataAllocationValues[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)] = new ModuleValue(); } } let point: number = 0; for (let i: number = this.mNoOfModules - 1; i >= 0; i -= 2) { for (let j: number = this.mNoOfModules - 1; j >= 0; j--) { if (!(this.mModuleValue[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)].isFilled && this.mModuleValue[i - 1][parseInt(j.toString(), 10)].isFilled)) { if (!this.mModuleValue[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)].isFilled) { if (point + 1 < data.length) { this.mDataAllocationValues[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)].isBlack = data[point++]; } if ((i + j) % 3 === 0) { this.mDataAllocationValues[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)].isBlack = (this.mDataAllocationValues[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)].isBlack) ? true : false; } else { this.mDataAllocationValues[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)].isBlack = (this.mDataAllocationValues[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)].isBlack) ? false : true; } this.mDataAllocationValues[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)].isFilled = true; } if (!this.mModuleValue[i - 1][parseInt(j.toString(), 10)].isFilled) { if (point + 1 < data.length) { this.mDataAllocationValues[i - 1][parseInt(j.toString(), 10)].isBlack = data[point++]; } if ((i - 1 + j) % 3 === 0) { this.mDataAllocationValues[i - 1][parseInt(j.toString(), 10)].isBlack = (this.mDataAllocationValues[i - 1][parseInt(j.toString(), 10)].isBlack) ? true : false; } else { this.mDataAllocationValues[i - 1][parseInt(j.toString(), 10)].isBlack = (this.mDataAllocationValues[i - 1][parseInt(j.toString(), 10)].isBlack) ? false : true; } this.mDataAllocationValues[i - 1][parseInt(j.toString(), 10)].isFilled = true; } } } i -= 2; if (i === 6) { i--; } for (let k: number = 0; k < this.mNoOfModules; k++) { if (!(this.mModuleValue[parseInt(i.toString(), 10)][parseInt(k.toString(), 10)].isFilled && this.mModuleValue[i - 1][parseInt(k.toString(), 10)].isFilled)) { if (!this.mModuleValue[parseInt(i.toString(), 10)][parseInt(k.toString(), 10)].isFilled) { if (point + 1 < data.length) { this.mDataAllocationValues[parseInt(i.toString(), 10)][parseInt(k.toString(), 10)].isBlack = data[point++]; } if ((i + k) % 3 !== 0) { this.mDataAllocationValues[parseInt(i.toString(), 10)][parseInt(k.toString(), 10)].isBlack = (this.mDataAllocationValues[parseInt(i.toString(), 10)][parseInt(k.toString(), 10)].isBlack) ? false : true; } else { this.mDataAllocationValues[parseInt(i.toString(), 10)][parseInt(k.toString(), 10)].isBlack = (this.mDataAllocationValues[parseInt(i.toString(), 10)][parseInt(k.toString(), 10)].isBlack) ? true : false; } this.mDataAllocationValues[parseInt(i.toString(), 10)][parseInt(k.toString(), 10)].isFilled = true; } if (!this.mModuleValue[i - 1][parseInt(k.toString(), 10)].isFilled) { if (point + 1 < data.length) { this.mDataAllocationValues[i - 1][parseInt(k.toString(), 10)].isBlack = data[point++]; } if ((i - 1 + k) % 3 !== 0) { this.mDataAllocationValues[i - 1][parseInt(k.toString(), 10)].isBlack = (this.mDataAllocationValues[i - 1][parseInt(k.toString(), 10)].isBlack) ? false : true; } else { this.mDataAllocationValues[i - 1][parseInt(k.toString(), 10)].isBlack = (this.mDataAllocationValues[i - 1][parseInt(k.toString(), 10)].isBlack) ? true : false; } this.mDataAllocationValues[i - 1][parseInt(k.toString(), 10)].isFilled = true; } } } } for (let i: number = 0; i < this.mNoOfModules; i++) { for (let j: number = 0; j < this.mNoOfModules; j++) { if (!this.mModuleValue[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)].isFilled) { const flag: boolean = this.mDataAllocationValues[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)].isBlack; if (flag) { this.mDataAllocationValues[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)].isBlack = false; } else { this.mDataAllocationValues[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)].isBlack = true; } } } } } /* tslint:enable */ /** * Allocates Format and Version Information.\ * * @returns {void} Allocates Format and Version Information. * @private */ private allocateFormatAndVersionInformation(): void { for (let i: number = 0; i < 9; i++) { this.mModuleValue[8][parseInt(i.toString(), 10)].isFilled = true; this.mModuleValue[parseInt(i.toString(), 10)][8].isFilled = true; } for (let i: number = this.mNoOfModules - 8; i < this.mNoOfModules; i++) { this.mModuleValue[8][parseInt(i.toString(), 10)].isFilled = true; this.mModuleValue[parseInt(i.toString(), 10)][8].isFilled = true; } if (this.mVersion > 6) { const versionInformation: number[] = this.mQrBarcodeValues.VersionInformation; let count: number = 0; for (let i: number = 0; i < 6; i++) { for (let j: number = 2; j >= 0; j--) { this.mModuleValue[parseInt(i.toString(), 10)][this.mNoOfModules - 9 - j].isBlack = versionInformation[parseInt(count.toString(), 10)] === 1 ? true : false; this.mModuleValue[parseInt(i.toString(), 10)][this.mNoOfModules - 9 - j].isFilled = true; this.mModuleValue[this.mNoOfModules - 9 - j][parseInt(i.toString(), 10)].isBlack = versionInformation[count++] === 1 ? true : false; this.mModuleValue[this.mNoOfModules - 9 - j][parseInt(i.toString(), 10)].isFilled = true; } } } } /** *Draw the Alignment Pattern in the given location.\ * * @returns {void} Draw the Alignment Pattern in the given location . * @param {HTMLElement} x - Provide the canvas element . * @param {HTMLElement} y - Provide the canvas element . * @private */ private drawAlignmentPattern(x: number, y: number): void { let i: number; let j: number; for (i = x - 2, j = y - 2; i < x + 3; i++ , j++) { this.mModuleValue[parseInt(i.toString(), 10)][y - 2].isBlack = true; this.mModuleValue[parseInt(i.toString(), 10)][y - 2].isFilled = true; this.mModuleValue[parseInt(i.toString(), 10)][y + 2].isBlack = true; this.mModuleValue[parseInt(i.toString(), 10)][y + 2].isFilled = true; this.mModuleValue[x - 2][parseInt(j.toString(), 10)].isBlack = true; this.mModuleValue[x - 2][parseInt(j.toString(), 10)].isFilled = true; this.mModuleValue[x + 2][parseInt(j.toString(), 10)].isBlack = true; this.mModuleValue[x + 2][parseInt(j.toString(), 10)].isFilled = true; } for (i = x - 1, j = y - 1; i < x + 2; i++ , j++) { this.mModuleValue[parseInt(i.toString(), 10)][y - 1].isBlack = false; this.mModuleValue[parseInt(i.toString(), 10)][y - 1].isFilled = true; this.mModuleValue[parseInt(i.toString(), 10)][y + 1].isBlack = false; this.mModuleValue[parseInt(i.toString(), 10)][y + 1].isFilled = true; this.mModuleValue[x - 1][parseInt(j.toString(), 10)].isBlack = false; this.mModuleValue[x - 1][parseInt(j.toString(), 10)].isFilled = true; this.mModuleValue[x + 1][parseInt(j.toString(), 10)].isBlack = false; this.mModuleValue[x + 1][parseInt(j.toString(), 10)].isFilled = true; } this.mModuleValue[parseInt(x.toString(), 10)][parseInt(y.toString(), 10)].isBlack = true; this.mModuleValue[parseInt(x.toString(), 10)][parseInt(y.toString(), 10)].isFilled = true; } /** *Gets the Allignment pattern coordinates of the current version.\ * * @returns {number[]}Gets the Allignment pattern coordinates of the current version. . * @private */ private getAlignmentPatternCoOrdinates(): number[] { let allign: number[] = null; switch ((this.mVersion)) { case 2: allign = [6, 18]; break; case 3: allign = [6, 22]; break; case 4: