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,297 lines (1,287 loc) 353 kB
import { createElement, Browser, ChildProperty, Property, Complex, Component, L10n, Event } from '@syncfusion/ej2-base'; /** * Enum */ /** * Defines the event of the barcode * * BarcodeEvent - Throws when an invalid input was given. */ var BarcodeEvent; (function (BarcodeEvent) { BarcodeEvent[BarcodeEvent["invalid"] = 0] = "invalid"; })(BarcodeEvent || (BarcodeEvent = {})); /** * Defines the quite zone for the Qr Code. */ /** @private */ var QuietZone; (function (QuietZone) { QuietZone[QuietZone["All"] = 2] = "All"; })(QuietZone || (QuietZone = {})); /** * Defines the size for the datamatrix code. The defined size are * * Auto * * Size10x10 * * Size12x12 * * Size14x14 * * Size16x16 * * Size18x18 * * Size20x20 * * Size22x22 * * Size24x24 * * Size26x26 * * Size32x32 * * Size36x36 * * Size40x40 * * Size44x44 * * Size48x48 * * Size52x52 * * Size64x64 * * Size72x72 * * Size80x80 * * Size88x88 * * Size96x96 * * Size104x104 * * Size120x120 * * Size132x132 * * Size144x144 * * Size8x18 * * Size8x32 * * Size12x26 * * Size12x36 * * Size16x36 * * Size16x48 * * @aspNumberEnum * @IgnoreSingular */ var DataMatrixSize; (function (DataMatrixSize) { /** * modules will be generated automatically. */ DataMatrixSize[DataMatrixSize["Auto"] = 0] = "Auto"; /** * will generate 10*10 modules. */ DataMatrixSize[DataMatrixSize["Size10x10"] = 1] = "Size10x10"; /** * will generate 12*12 modules. */ DataMatrixSize[DataMatrixSize["Size12x12"] = 2] = "Size12x12"; /** * will generate 14*14 modules. */ DataMatrixSize[DataMatrixSize["Size14x14"] = 3] = "Size14x14"; /** * will generate 16*16 modules. */ DataMatrixSize[DataMatrixSize["Size16x16"] = 4] = "Size16x16"; /** * will generate 18*18 modules. */ DataMatrixSize[DataMatrixSize["Size18x18"] = 5] = "Size18x18"; /** * will generate 20*20 modules. */ DataMatrixSize[DataMatrixSize["Size20x20"] = 6] = "Size20x20"; /** * will generate 22*22 modules. */ DataMatrixSize[DataMatrixSize["Size22x22"] = 7] = "Size22x22"; /** * will generate 24*24 modules. */ DataMatrixSize[DataMatrixSize["Size24x24"] = 8] = "Size24x24"; /** * will generate 26*26 modules. */ DataMatrixSize[DataMatrixSize["Size26x26"] = 9] = "Size26x26"; /** * will generate 32*32 modules. */ DataMatrixSize[DataMatrixSize["Size32x32"] = 10] = "Size32x32"; /** * will generate 32*32 modules. */ DataMatrixSize[DataMatrixSize["Size36x36"] = 11] = "Size36x36"; /** * will generate 40*40 modules. */ DataMatrixSize[DataMatrixSize["Size40x40"] = 12] = "Size40x40"; /** * will generate 44*44 modules. */ DataMatrixSize[DataMatrixSize["Size44x44"] = 13] = "Size44x44"; /** * will generate 48*48 modules. */ DataMatrixSize[DataMatrixSize["Size48x48"] = 14] = "Size48x48"; /** * will generate 52*52 modules. */ DataMatrixSize[DataMatrixSize["Size52x52"] = 15] = "Size52x52"; /** * will generate 64*64 modules. */ DataMatrixSize[DataMatrixSize["Size64x64"] = 16] = "Size64x64"; /** * will generate 72*72 modules. */ DataMatrixSize[DataMatrixSize["Size72x72"] = 17] = "Size72x72"; /** * will generate 80*80 modules. */ DataMatrixSize[DataMatrixSize["Size80x80"] = 18] = "Size80x80"; /** * will generate 88*88 modules. */ DataMatrixSize[DataMatrixSize["Size88x88"] = 19] = "Size88x88"; /** * will generate 96*96 modules. */ DataMatrixSize[DataMatrixSize["Size96x96"] = 20] = "Size96x96"; /** * will generate 104*104 modules. */ DataMatrixSize[DataMatrixSize["Size104x104"] = 21] = "Size104x104"; /** * will generate 120*120 modules. */ DataMatrixSize[DataMatrixSize["Size120x120"] = 22] = "Size120x120"; /** * will generate 132*132 modules. */ DataMatrixSize[DataMatrixSize["Size132x132"] = 23] = "Size132x132"; /** * will generate 144*144 modules. */ DataMatrixSize[DataMatrixSize["Size144x144"] = 24] = "Size144x144"; /** * will generate 8*18 modules. */ DataMatrixSize[DataMatrixSize["Size8x18"] = 25] = "Size8x18"; /** * will generate 8*32 modules. */ DataMatrixSize[DataMatrixSize["Size8x32"] = 26] = "Size8x32"; /** * will generate 12*26 modules. */ DataMatrixSize[DataMatrixSize["Size12x26"] = 27] = "Size12x26"; /** * will generate 12*36 modules. */ DataMatrixSize[DataMatrixSize["Size12x36"] = 28] = "Size12x36"; /** * will generate 16*36 modules. */ DataMatrixSize[DataMatrixSize["Size16x36"] = 29] = "Size16x36"; /** * will generate 16*48 modules. */ DataMatrixSize[DataMatrixSize["Size16x48"] = 30] = "Size16x48"; })(DataMatrixSize || (DataMatrixSize = {})); /** * Defines the Qrcode QRCodeVersion. They are * * Auto * * Version01 * * Version02 * * Version03 * * Version04 * * Version05 * * Version06 * * Version07 * * Version08 * * Version09 * * Version10 * * Version11 * * Version12 * * Version13 * * Version14 * * Version15 * * Version16 * * Version17 * * Version18 * * Version19 * * Version20 * * Version21 * * Version22 * * Version23 * * Version24 * * Version25 * * Version26 * * Version27 * * Version28 * * Version29 * * Version30 * * Version31 * * Version32 * * Version33 * * Version34 * * Version35 * * Version36 * * Version37 * * Version38 * * Version39 * * Version40 * * @aspNumberEnum * @IgnoreSingular */ var QRCodeVersion; (function (QRCodeVersion) { /** * Specifies the default version. */ QRCodeVersion[QRCodeVersion["Auto"] = 0] = "Auto"; /** * Specifies version 1 (21 x 21 modules). */ QRCodeVersion[QRCodeVersion["Version01"] = 1] = "Version01"; /** * Specifies version 2 (25 x 25 modules). */ QRCodeVersion[QRCodeVersion["Version02"] = 2] = "Version02"; /** * Specifies version 3 (29 x 29 modules). */ QRCodeVersion[QRCodeVersion["Version03"] = 3] = "Version03"; /** * Specifies version 4 (33 x 33 modules). */ QRCodeVersion[QRCodeVersion["Version04"] = 4] = "Version04"; /** * Specifies version 5 (37 x 37 modules). */ QRCodeVersion[QRCodeVersion["Version05"] = 5] = "Version05"; /** * Specifies version 6 (41 x 41 modules). */ QRCodeVersion[QRCodeVersion["Version06"] = 6] = "Version06"; /** * Specifies version 7 (45 x 45 modules). */ QRCodeVersion[QRCodeVersion["Version07"] = 7] = "Version07"; /** * Specifies version 8 (49 x 49 modules). */ QRCodeVersion[QRCodeVersion["Version08"] = 8] = "Version08"; /** * Specifies version 9 (53 x 53 modules). */ QRCodeVersion[QRCodeVersion["Version09"] = 9] = "Version09"; /** * Specifies version 10 (57 x 57 modules). */ QRCodeVersion[QRCodeVersion["Version10"] = 10] = "Version10"; /** * Specifies version 11 (61 x 61 modules). */ QRCodeVersion[QRCodeVersion["Version11"] = 11] = "Version11"; /** * Specifies version 12 (65 x 65 modules). */ QRCodeVersion[QRCodeVersion["Version12"] = 12] = "Version12"; /** * Specifies version 13 (69 x 69 modules). */ QRCodeVersion[QRCodeVersion["Version13"] = 13] = "Version13"; /** * Specifies version 14 (73 x 73 modules). */ QRCodeVersion[QRCodeVersion["Version14"] = 14] = "Version14"; /** * Specifies version 15 (77 x 77 modules). */ QRCodeVersion[QRCodeVersion["Version15"] = 15] = "Version15"; /** * Specifies version 17 (85 x 85 modules). */ QRCodeVersion[QRCodeVersion["Version16"] = 16] = "Version16"; /** * Specifies version 17 (85 x 85 modules). */ QRCodeVersion[QRCodeVersion["Version17"] = 17] = "Version17"; /** * Specifies version 18 (89 x 89 modules). */ QRCodeVersion[QRCodeVersion["Version18"] = 18] = "Version18"; /** * Specifies version 19 (93 x 93 modules). */ QRCodeVersion[QRCodeVersion["Version19"] = 19] = "Version19"; /** * Specifies version 20 (97 x 97 modules). */ QRCodeVersion[QRCodeVersion["Version20"] = 20] = "Version20"; /** * Specifies version 21 (101 x 101 modules). */ QRCodeVersion[QRCodeVersion["Version21"] = 21] = "Version21"; /** * Specifies version 22 (105 x 105 modules). */ QRCodeVersion[QRCodeVersion["Version22"] = 22] = "Version22"; /** * Specifies version 23 (109 x 109 modules). */ QRCodeVersion[QRCodeVersion["Version23"] = 23] = "Version23"; /** * Specifies version 24 (113 x 113 modules). */ QRCodeVersion[QRCodeVersion["Version24"] = 24] = "Version24"; /** * Specifies version 25 (117 x 117 modules). */ QRCodeVersion[QRCodeVersion["Version25"] = 25] = "Version25"; /** * Specifies version 26 (121 x 121 modules). */ QRCodeVersion[QRCodeVersion["Version26"] = 26] = "Version26"; /** * Specifies version 27 (125 x 125 modules). */ QRCodeVersion[QRCodeVersion["Version27"] = 27] = "Version27"; /** * Specifies version 28 (129 x 129 modules). */ QRCodeVersion[QRCodeVersion["Version28"] = 28] = "Version28"; /** * Specifies version 29 (133 x 133 modules). */ QRCodeVersion[QRCodeVersion["Version29"] = 29] = "Version29"; /** * Specifies version 30 (137 x 137 modules). */ QRCodeVersion[QRCodeVersion["Version30"] = 30] = "Version30"; /** * Specifies version 31 (141 x 141 modules). */ QRCodeVersion[QRCodeVersion["Version31"] = 31] = "Version31"; /** * Specifies version 32 (145 x 145 modules). */ QRCodeVersion[QRCodeVersion["Version32"] = 32] = "Version32"; /** * Specifies version 33 (149 x 149 modules). */ QRCodeVersion[QRCodeVersion["Version33"] = 33] = "Version33"; /** * Specifies version 34 (153 x 153 modules). */ QRCodeVersion[QRCodeVersion["Version34"] = 34] = "Version34"; /** * Specifies version 35 (157 x 157 modules). */ QRCodeVersion[QRCodeVersion["Version35"] = 35] = "Version35"; /** * Specifies version 36 (161 x 161 modules). */ QRCodeVersion[QRCodeVersion["Version36"] = 36] = "Version36"; /** * Specifies version 37 (165 x 165 modules). */ QRCodeVersion[QRCodeVersion["Version37"] = 37] = "Version37"; /** * Specifies version 38 (169 x 169 modules). */ QRCodeVersion[QRCodeVersion["Version38"] = 38] = "Version38"; /** * Specifies version 39 (173 x 173 modules). */ QRCodeVersion[QRCodeVersion["Version39"] = 39] = "Version39"; /** * Specifies version 40 (177 x 177 modules). */ QRCodeVersion[QRCodeVersion["Version40"] = 40] = "Version40"; })(QRCodeVersion || (QRCodeVersion = {})); /** * Indicated the recovery capacity of the qrcode. The default capacity levels are * * Low * * Medium * * Quartile * * High * * @aspNumberEnum * @IgnoreSingular */ var ErrorCorrectionLevel; (function (ErrorCorrectionLevel) { /** * The Recovery capacity is 7%(approx.) */ ErrorCorrectionLevel[ErrorCorrectionLevel["Low"] = 7] = "Low"; /** * The Recovery capacity is 15%(approx.) */ ErrorCorrectionLevel[ErrorCorrectionLevel["Medium"] = 15] = "Medium"; /** * The Recovery capacity is 25%(approx.) */ ErrorCorrectionLevel[ErrorCorrectionLevel["Quartile"] = 25] = "Quartile"; /** * The Recovery capacity is 30%(approx.) */ ErrorCorrectionLevel[ErrorCorrectionLevel["High"] = 30] = "High"; })(ErrorCorrectionLevel || (ErrorCorrectionLevel = {})); /** * Size defines and processes the size(width/height) of the objects */ class Size { constructor(width, height) { this.width = width; this.height = height; } } /** * DOM util */ /** *will create the hrml element for the barcode .\ * * @returns {HTMLElement} Will download the barode as image . * @param {string} elementType - Provide the element type as string . * @param {HTMLCanvasElement} attribute - Provide the object . * @private */ // eslint-disable-next-line function createHtmlElement(elementType, attribute) { const element = createElement(elementType); if (attribute) { setAttribute(element, attribute); } return element; } /** *will get the child nodes .\ * * @returns {HTMLElement} will provide the svg element . * @param {string} node - Provide the element type as string . * @private */ function getChildNode(node) { let child; let collection = []; if (Browser.info.name === 'msie' || Browser.info.name === 'edge') { for (let i = 0; i < node.childNodes.length; i++) { child = node.childNodes[parseInt(i.toString(), 10)]; if (child.nodeType === 1) { collection.push(child); } } } else { collection = node.children; } return collection; } /** *will return the size of the text .\ * * @returns {Size} will provide the svg element . * @param {BaseAttributes} textContent - Provide the base attribtues of the text . * @private */ function measureText(textContent) { const measureElement = 'barcodeMeasureElement'; window[`${measureElement}`].style.visibility = 'visible'; const svg = window[`${measureElement}`].children[1]; const text = getChildNode(svg)[0]; text.textContent = textContent.string; text.style.fontSize = textContent.stringSize + 'px'; text.style.fontFamily = textContent.fontStyle; text.style.fontWeight = ''; const bBox = new Size(0, 0); bBox.width = text.getBBox().width; bBox.height = text.getBBox().height; window[`${measureElement}`].style.visibility = 'hidden'; return bBox; } /** *Will assign the attributes .\ * * @returns {void} Will assign the attrbutes . * @param {HTMLElement} element - Provide the element . * @param {Object} attributes - Provide the attribtues . * @private */ // eslint-disable-next-line function setAttribute(element, attributes) { const keys = Object.keys(attributes); for (let i = 0; i < keys.length; i++) { keys.forEach((key) => { // eslint-disable-next-line security/detect-object-injection const value = attributes[key]; if (key === 'style' && typeof value === 'string') { // Handle `style` attributes specifically by splitting and setting them directly const styleProperties = value.split(';'); styleProperties.forEach((property) => { const [propName, propValue] = property.split(':'); if (propName && propValue) { element.style.setProperty(propName.trim(), propValue.trim()); } }); } else { // Set other attributes normally element.setAttribute(key, value); } }); } } /** *Will create the required SVG element .\ * * @returns {HTMLElement | SVGElement} Will create the required SVG element . * @param {string} elementType - Provide the element type. * @param {Object} attribute - Provide the attribtues . * @private */ // eslint-disable-next-line function createSvgElement(elementType, attribute) { const element = document.createElementNS('http://www.w3.org/2000/svg', elementType); setAttribute(element, attribute); return element; } /** *Will create measure element .\ * * @returns {void} Will create measure element . * @private */ function createMeasureElements() { const measureElement = 'barcodeMeasureElement'; if (!window[`${measureElement}`]) { const divElement = createHtmlElement('div', { id: 'barcodeMeasureElement', class: 'barcodeMeasureElement', style: 'visibility:hidden ; height: 0px ; width: 0px; overflow: hidden;' }); const text = createHtmlElement('span', { 'style': 'display:inline-block ; line-height: normal' }); divElement.appendChild(text); const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); svg.setAttribute('xlink', 'http://www.w3.org/1999/xlink'); divElement.appendChild(svg); const tSpan = document.createElementNS('http://www.w3.org/2000/svg', 'text'); tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve'); svg.appendChild(tSpan); window[`${measureElement}`] = divElement; window[`${measureElement}`].usageCount = 1; document.body.appendChild(divElement); } else { window[`${measureElement}`].usageCount += 1; } } /** * canvas renderer */ /** @private */ class BarcodeCanvasRenderer { /** * Get the context value for the canvas.\ * * @returns {CanvasRenderingContext2D} Get the context value for the canvas . * @param {HTMLCanvasElement} canvas - Provide the canvas element . * @private */ static getContext(canvas) { return canvas.getContext('2d'); } /** * Draw the root element for the barcode.\ * * @returns {HTMLElement} Draw the barcode SVG . * @param {Object} attribute - Provide the canvas element . * @param {string} backGroundColor - Provide the canvas element . * @param {number} width - Provide the canvas element . * @param {number} height - Provide the canvas element . * @private */ // eslint-disable-next-line renderRootElement(attribute, backGroundColor, width, height) { const canvasObj = createHtmlElement('canvas', attribute); const ctx = canvasObj.getContext('2d'); ctx.fillStyle = backGroundColor; ctx.fillRect(0, 0, width, height); return canvasObj; } /** * Draw the rect for the barcode.\ * * @returns {HTMLElement} Draw the barcode SVG . * @param {Object} canvas - Provide the canvas element . * @param {Object} attribute - Provide the canvas element . * @private */ renderRect(canvas, attribute) { const ctx = canvas.getContext('2d'); if (attribute.imageSource) { const image = new Image(); image.src = attribute.imageSource; image.onload = function () { ctx.drawImage(image, attribute.x, attribute.y, attribute.width, attribute.height); }; } else { ctx.fillStyle = attribute.color; ctx.fillRect(attribute.x, attribute.y, attribute.width, attribute.height); } return canvas; } /** * Draw the text for the barcode.\ * * @returns {HTMLElement} Draw the barcode SVG . * @param {Object} canvas - Provide the canvas element . * @param {Object} attribute - Provide the canvas element . * @private */ renderText(canvas, attribute) { const ctx = canvas.getContext('2d'); ctx.save(); ctx.font = (attribute.stringSize) + 'px ' + attribute.fontStyle; ctx.fillStyle = attribute.color; ctx.fillText(attribute.string, attribute.x, attribute.y); return canvas; } } /** * svg renderer */ /** @private */ class BarcodeSVGRenderering { /** * Draw the root element for the barcode.\ * * @returns {HTMLElement} Draw the barcode SVG . * @param {Object} attribute - Provide the canvas element . * @param {string} backGroundColor - Provide the canvas element . * @private */ // eslint-disable-next-line renderRootElement(attribute, backGroundColor) { const canvasObj = createSvgElement('svg', attribute); canvasObj.style.background = backGroundColor; return canvasObj; } /** * Draw the rect for the barcode.\ * * @returns {HTMLElement} Draw the barcode SVG . * @param {Object} svg - Provide the canvas element . * @param {Object} attribute - Provide the canvas element . * @private */ renderRect(svg, attribute) { if (attribute.imageSource) { return this.renderImage(svg, attribute); } const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); rect.setAttribute('x', attribute.x.toString()); rect.setAttribute('y', attribute.y.toString()); rect.setAttribute('width', attribute.width.toString()); rect.setAttribute('height', attribute.height.toString()); rect.setAttribute('fill', attribute.color); rect.style['shapeRendering'] = 'crispEdges'; svg.appendChild(rect); return svg; } /** * Draw the text for the barcode.\ * * @returns {HTMLElement} Draw the barcode SVG . * @param {Object} svg - Provide the canvas element . * @param {Object} attribute - Provide the canvas element . * @private */ renderText(svg, attribute) { const text = document.createElementNS('http://www.w3.org/2000/svg', 'text'); text.setAttribute('x', attribute.x.toString()); text.setAttribute('y', attribute.y.toString()); text.setAttribute('fill', attribute.color); text.style.fontSize = attribute.stringSize.toString() + 'px'; text.style.fontFamily = attribute.fontStyle; text.textContent = attribute.string; svg.appendChild(text); return svg; } /** * Draw the image for the barcode. * * @returns {HTMLElement} Draw the barcode SVG . * @param {Object} svg - Provide the canvas element . * @param {Object} attribute - Provide the canvas element . * @private */ renderImage(svg, attribute) { const image = document.createElementNS('http://www.w3.org/2000/svg', 'image'); image.setAttribute('x', attribute.x.toString()); image.setAttribute('y', attribute.y.toString()); image.setAttribute('width', attribute.width.toString()); image.setAttribute('height', attribute.height.toString()); image.setAttribute('href', attribute.imageSource); image.setAttribute('preserveAspectRatio', 'none'); svg.appendChild(image); return svg; } } /** * Renderer */ /** * Renderer module is used to render basic barcode elements */ /** @private */ class BarcodeRenderer { constructor(name, isSvgMode) { /** @private */ this.renderer = null; this.isSvgMode = null; this.isSvgMode = isSvgMode; this.renderer = isSvgMode ? new BarcodeSVGRenderering() : new BarcodeCanvasRenderer(); } /** * Draw the root element for the barcode.\ * * @returns {HTMLElement} Draw the barcode SVG . * @param {Object} attribute - Provide the canvas element . * @param {string} backGroundColor - Provide the canvas element . * @param {number} width - Provide the canvas element . * @param {number} height - Provide the canvas element . * @private */ // eslint-disable-next-line renderRootElement(attribute, backGroundColor, width, height) { const canvasObj = this.renderer.renderRootElement(attribute, backGroundColor, width, height); return canvasObj; } /** * Draw the rect for the barcode.\ * * @returns {HTMLElement} Draw the barcode SVG . * @param {Object} canvas - Provide the canvas element . * @param {Object} attribute - Provide the canvas element . * @private */ // eslint-disable-next-line renderRectElement(canvas, attribute) { const canvasObj = this.renderer.renderRect(canvas, attribute); return canvasObj; } /** * Draw the text for the barcode.\ * * @returns {HTMLElement} Draw the barcode SVG . * @param {Object} canvas - Provide the canvas element . * @param {Object} attribute - Provide the canvas element . * @private */ // eslint-disable-next-line renderTextElement(canvas, attribute) { const canvasObj = this.renderer.renderText(canvas, attribute); return canvasObj; } } /** * defines the common methods for the barcode */ class BarcodeBase { } /** * Rect defines and processes rectangular regions */ class Rect { constructor(x, y, width, height) { /** * Sets the x-coordinate of the starting point of a rectangular region * * @default 0 */ this.x = Number.MAX_VALUE; /** * Sets the y-coordinate of the starting point of a rectangular region * * @default 0 */ this.y = Number.MAX_VALUE; /** * Sets the width of a rectangular region * * @default 0 */ this.width = 0; /** * Sets the height of a rectangular region * * @default 0 */ this.height = 0; this.x = x; this.y = y; this.width = width; this.height = height; } } /** * onedimension class is used to render all type of one dimensional shapes */ class OneDimension extends BarcodeBase { getInstance(id) { const barCode = document.getElementById(id); const barcodeRenderer = new BarcodeRenderer(barCode.id, this.isSvgMode); return barcodeRenderer; } /** * Return the drawable size of the rectangle . * * @returns {Rect} Return the drawable size of the rectangle. * @param {MarginModel} margin - Specifies the filename of the barcode image to be download. * @param {number} w - Specifies the filename of the barcode image to be download. * @param {number} h - Defines the format of the barcode to be exported * @private */ getDrawableSize(margin, w, h) { const topMargin = ((this.isSvgMode ? margin.bottom : margin.bottom * 1.5) + (this.isSvgMode ? margin.top : margin.top * 1.5)); const rightMargin = ((this.isSvgMode ? margin.right : margin.right * 1.5) + (this.isSvgMode ? margin.left : margin.left * 1.5)); const barcodeSize = new Rect(margin.left, margin.top, (w - rightMargin), h - topMargin); return barcodeSize; } getBaseAttributes(width, height, offSetX, offsetY, color, string, stringSize, visibility, fontStyle) { const options = { width: width, height: height, x: offSetX, y: offsetY, color: color, string: string, stringSize: stringSize, visibility: visibility, fontStyle: fontStyle }; if (!this.isSvgMode) { options.height = options.height / 1.5; } if (string && !this.isSvgMode) { const scaleValue = this.margin.bottom * 1.5 - this.margin.bottom; options.y += scaleValue; } return options; } getBarLineRatio(code, widthValue) { const type = this.type; if (type === 'Code39' || type === 'Code32' || type === 'Code39Extension' || type === 'Code11') { // total number of line for single width lines const singlewidth = code.length * ((type === 'Code39' || type === 'Code32' || type === 'Code39Extension') ? 6 : 3); // total number of line for double width lines const doublwidth = code.length * ((type === 'Code39' || type === 'Code32' || type === 'Code39Extension') ? 3 : 2) * 2; return (widthValue / (doublwidth + singlewidth + code.length - 1)); } else if (type === 'Code128A' || type === 'Code128B' || type === 'Code128C' || type === 'Code128') { const lineCount = code[0].length; return (widthValue / (lineCount + code.length - 1)); } else if (type === 'Code93Extension') { let count = 0; for (let i = 0; i < code.length; i++) { const numberOfDigits = code[parseInt(i.toString(), 10)]; for (let j = 0; j < numberOfDigits.length; j++) { count += Number(numberOfDigits[parseInt(j.toString(), 10)]); } } return widthValue / count; } else { let lineCount = 0; for (let i = 0; i < code.length; i++) { const numberOfDigits = code[parseInt(i.toString(), 10)].length; lineCount += numberOfDigits; } let additionalValue; if (type === 'Ean8' || type === 'Ean13' || type === 'UpcA') { additionalValue = 2; } else if (type === 'Code93') { additionalValue = -code.length + 1; } return (widthValue / (additionalValue ? ((lineCount + code.length - 1) + additionalValue) : (lineCount + code.length - 1))); } } multipleWidth(codeValue, k, value) { let number; if (codeValue[parseInt(k.toString(), 10)] === '1' && codeValue[k + 1] === '1') { number = value + 1; return this.multipleWidth(codeValue, k + 1, number); } return value; } barCodeType(type) { if (type === 'Code39' || type === 'UpcE' || type === 'Code39Extension') { return 'twoBars'; } else if (type === 'UpcA' || type === 'Ean13' || type === 'Ean8') { return 'threeBars'; } else { return 'noBars'; } } checkStartValueCondition(j, k, numberOfDigits, barType) { if ((j === 1 && k === 0 && barType === 'twoBars' && this.type !== 'UpcE' || (((j === 0 && k === numberOfDigits - 1) || j === 2 && k === numberOfDigits - 2) && (this.type === 'Ean8' || this.type === 'Ean13'))) || (this.type === 'UpcE' && j === 2 && k === 0) || (this.type !== 'UpcA' && barType === 'threeBars' && (j === 2 && k === numberOfDigits - 1)) || this.type === 'UpcA' && ((j === 1 && k === numberOfDigits - 2) || (j === 3 && k === numberOfDigits - 2)) || (barType === 'noBars' && j === 0 && k === 0)) { return true; } else { return false; } } checkEndValueCondition(k, j, numberOfDigits, code, temp, doublwidth) { const type = this.type; if ((k === numberOfDigits && j === code.length - 2 && (type === 'Code39' || type === 'Code39Extension')) || (type === 'Code11' && j === code.length - 1 && k === numberOfDigits - 1) || type === 'Code93Extension' && j === code.length - 1 && k === numberOfDigits - 1 || ((type === 'Ean8') && (j === 1 && k === numberOfDigits || j === code.length - 2 && k === numberOfDigits)) || ((this.type === 'Ean13') && ((j === 2 && k === 1) || j === code.length - 2 && k === numberOfDigits)) || (type === 'UpcA' && (j === 3 && k === 0 || j === 5 && (!temp ? (k === 1) : ((k === (doublwidth)))))) || (type === 'UpcE' && (j === code.length - 2 && k === 1)) || (type === 'Code93' && j === code.length - 1 && k === numberOfDigits - 1) || ((type !== 'Code39' && type !== 'Code39Extension' && type !== 'Ean8' && type !== 'Ean13') && j === code.length - 1 && k === numberOfDigits)) { return true; } else { return false; } } getDisplayText(j, textProperty) { let text; if (this.type === 'Ean8') { text = j === 1 ? (this.value.substring(0, 4)) : (this.value.substring(4, 8)); } else if (this.type === 'Ean13') { text = j === 2 ? (this.value.substring(1, 7)) : (this.value.substring(7)); } else if (this.type === 'UpcA') { text = j === 3 ? ((this.value.substring(0, 6))) : (this.value.substring(6, 12)); } else { text = textProperty.text ? textProperty.text : this.value; } return text; } checkExtraHeight(j, type, code) { if (((j === 0 || j === code.length - 1) && (type === 'Code39' || type === 'Code39Extension')) || ((type === 'Ean8' || type === 'Ean13') && (j === 0 || j === 2 || j === code.length - 1)) || type === 'UpcA' && (j === 1 || j === code.length - 2 || j === code.length - 4) || type === 'UpcE' && (j === 1 || j === code.length - 2 || j === code.length - 4)) { return true; } else { return false; } } getWidthValue(number, width, type) { if (this.type !== 'Code93Extension') { if (number) { const dividerValue = type === 'Code32' ? 3 : 2; width = number % dividerValue ? 1 : 2; } else { width = 1; } } if (this.type === 'Code93Extension') { if (number && !(number % 4)) { width = 4; } else if (number && !(number % 2)) { width = 2; } else if (number && !(number % 3)) { width = 3; } else { width = 1; } } return width; } /* eslint:disable */ /** * Returns the module name of the barcode * * @param {number[] | string[]} code - Returns the code as string or number collection. * @param {HTMLElement} canvas - Returns the canvas. * @param {string} isUpcE - Returns the UPCE values as string. * @returns {void} Calculate the barcode attribute * @private */ calculateBarCodeAttributes(code, canvas, isUpcE) { let temp = false; let canDoubleWidth; const barcodeSize = this.getDrawableSize(this.margin, this.width, this.height); if (barcodeSize.height > 0 && barcodeSize.width > 0) { let tempBaseAttributes; const options = []; let offsetX = barcodeSize.x; let ratio = this.getBarLineRatio(code, barcodeSize.width); ratio = this.isSvgMode ? ratio : ratio / 1.5; let startValue = 0; let endValue; const type = this.type; const position = this.displayText.position; const scaleValue = this.isSvgMode ? 1 : 1.5; let textOptions; let textSize; let textHeight; let textProperty; for (let j = 0; j < code.length; j++) { const codeValue = code[parseInt(j.toString(), 10)]; const check = (type !== 'UpcA' && type !== 'UpcE' && type !== 'Code11' && type !== 'Code93' && type !== 'Code93Extension'); const barType = this.barCodeType(this.type); const extraHeight = this.checkExtraHeight(j, type, code); const numberOfDigits = codeValue.length; temp = false; for (let k = 0; check ? k <= numberOfDigits : k < numberOfDigits; k++) { let renderText = false; if (this.checkStartValueCondition(j, k, numberOfDigits, barType)) { startValue = offsetX; } else if (this.checkEndValueCondition(k, j, numberOfDigits, code, temp, canDoubleWidth)) { endValue = offsetX; if (this.type === 'UpcA' && temp && canDoubleWidth) { endValue -= canDoubleWidth * ratio; } renderText = true; } const canDrawCheck = (type === 'Code39' || type === 'Code93Extension' || type === 'Code32' || type === 'Code11' || type === 'Code39Extension'); const candraw = canDrawCheck ? (k % 2 ? false : true) : (codeValue[parseInt(k.toString(), 10)] === '1' ? true : false); const string = codeValue.toString(); const number = Number(string[parseInt(k.toString(), 10)]); let width; width = this.getWidthValue(number, width, type); width = width * ratio; textProperty = this.displayText; const text = this.getDisplayText(j, textProperty); textOptions = this.getBaseAttributes(undefined, undefined, startValue, position === 'Bottom' ? (barcodeSize.y + barcodeSize.height) + 2 : (barcodeSize.y + textHeight) - 2, this.foreColor, isUpcE || text, textProperty.size, textProperty.visibility, textProperty.font); if (!textHeight) { createMeasureElements(); textSize = measureText(textOptions); textHeight = (textSize.height / 2) + 2; } if (extraHeight) { tempBaseAttributes = this.getBaseAttributes(width, position === 'Top' && barType !== 'noBars' ? (barcodeSize.height - textHeight - this.displayText.margin.top) : (barcodeSize.height), offsetX, position === 'Bottom' ? barcodeSize.y : barcodeSize.y + textHeight + this.displayText.margin.top, this.foreColor); } if ((type === 'Ean13') && k === 0 && j === 0 && textProperty.visibility) { textOptions = this.getBaseAttributes(undefined, undefined, startValue, position === 'Bottom' ? (barcodeSize.y + barcodeSize.height) + 2 : ((barcodeSize.y + textHeight + this.displayText.margin.top) - 2) - this.displayText.margin.bottom, this.foreColor, isUpcE || text, textProperty.size, textProperty.visibility, textProperty.font); textOptions.string = this.value[0]; this.drawText(canvas, textOptions); } if (!extraHeight || renderText || (type === 'UpcA' && extraHeight)) { const checkCode = type === 'Code39' || type === 'Code32' || type === 'Code93Extension' || type === 'Code39Extension' || type === 'Code11'; const value = barcodeSize.height; let barCodeHeight = (((value) - textHeight * scaleValue) > 0 ? ((value) - textHeight * scaleValue) : 0); if (checkCode || type === 'Ean8' || type === 'Ean13') { barCodeHeight = position === 'Top' && barType !== 'noBars' ? (barCodeHeight - textHeight) : barCodeHeight; let height = extraHeight ? barcodeSize.height : barCodeHeight; if (this.type !== 'Code39') { height = position === 'Top' && barType !== 'noBars' ? (height - this.displayText.margin.top) - textHeight : height; } tempBaseAttributes = this.getBaseAttributes(width, height, offsetX, position === 'Bottom' ? barcodeSize.y : barcodeSize.y + textHeight + this.displayText.margin.top, this.foreColor); } if ((!checkCode || (!renderText && !checkCode)) && (!renderText || this.type !== 'UpcE')) { canDoubleWidth = this.multipleWidth((codeValue), k, 1); k += canDoubleWidth - 1; if (canDoubleWidth > 1) { temp = true; } const rectWidth = canDoubleWidth > 1 ? (canDoubleWidth * width) : width; const rectHeight = (barcodeSize.height - textHeight * scaleValue); let height = extraHeight ? barcodeSize.height : rectHeight; height = position === 'Top' && barType !== 'noBars' ? (height - this.displayText.margin.top) - textHeight : height; tempBaseAttributes = this.getBaseAttributes(rectWidth, height, offsetX, position === 'Bottom' ? barcodeSize.y : barcodeSize.y + textHeight + this.displayText.margin.top, this.foreColor); offsetX = canDoubleWidth > 1 ? offsetX + (canDoubleWidth * (width)) : offsetX + (1 * (width)); } if (renderText || !extraHeight) { this.verticalTextMargin(textProperty, tempBaseAttributes, textOptions); } if (textProperty.visibility && ((endValue && type !== 'Ean8' && type !== 'Ean13' && type !== 'UpcA' && type !== 'UpcE') || ((type === 'Ean8' || type === 'UpcA' || type === 'UpcE' || type === 'Ean13') && renderText))) { if (!textProperty.margin.left && !textProperty.margin.right && (textProperty.text || type === 'UpcA')) { this.updateOverlappedTextPosition((endValue - startValue), textOptions, textSize, startValue, textProperty, endValue); } else { this.getAlignmentPosition(textOptions, endValue, startValue, textSize); } if (type === 'UpcA') { const checkVAl = (textOptions.string === this.value.substr(0, 6)) ? true : false; textOptions.string = checkVAl ? this.value.substr(0, 1) : textOptions.string.substr(0, 5); const xPosition = checkVAl ? options[0].x / 2 : options[options.length - 1].x + textOptions.stringSize; let yPosition = 0; if (checkVAl) { const tempPosition = textOptions.x; textOptions.x = xPosition; yPosition = textOptions.y; this.drawText(canvas, textOptions); textOptions.x = tempPosition; if (!this.isSvgMode) { textOptions.y = yPosition; } textOptions.string = this.value.substr(1, 5); this.updateOverlappedTextPosition((endValue - startValue), textOptions, textSize, startValue, textProperty, endValue); } else { this.updateOverlappedTextPosition((endValue - startValue), textOptions, textSize, startValue, textProperty, endValue); yPosition = textOptions.y; this.drawText(canvas, textOptions); if (!this.isSvgMode) { textOptions.y = yPosition; } textOptions.string = this.value.substr(11, 12); textOptions.x = xPosition; } } this.alignDisplayText(textOptions, textProperty, startValue, endValue, textSize); this.drawText(canvas, textOptions); } } if (candraw) { options.push(tempBaseAttributes); } if (this.canIncrementCheck(type, j, code)) { offsetX += (width); } } } this.drawImage(canvas, options); } } /* eslint:enable */ canIncrementCheck(type, j, code) { if ((type === 'Code39' || type === 'Code32' || type === 'Code39Extension' || type === 'Code93Extension' || type === 'Code11') || (type === 'UpcE' && (j === 1 || j === code.length - 2)) || ((type === 'Ean8' || type === 'Ean13') && (j === 0 || j === code.length - 1 || j === 2))) { return true; } else { return false; } } verticalTextMargin(textProperty, tempBaseAttributes, textOptions) { if (textProperty.margin.top && tempBaseAttributes.height - textProperty.margin.top > 0) { if (textProperty.margin.top > 0 && textProperty.position === 'Bottom') { tempBaseAttributes.height -= textProperty.margin.top; } else { textOptions.y += textProperty.margin.top; } } if (textProperty.margin.bottom && tempBaseAttributes.height - textProperty.margin.bottom > 0) { if (textProperty.margin.bottom > 0) { textOptions.y -= textProperty.margin.bottom; if (this.displayText.position === 'Bottom') { tempBaseAttributes.height -= textProperty.margin.bottom; } } else { textOptions.y -= textProperty.margin.bottom; } } } getAlignmentPosition(textOptions, endValue, startValue, textSize) { if (this.displayText.alignment === 'Center') { textOptions.x += (((endValue - startValue)) / 2) - textSize.width * .5; } else if (this.displayText.alignment === 'Left') { textOptions.x = startValue; } else { textOptions.x = endValue - textSize.width; } } /** *Will draw the image for the barcode . * * @param {HTMLCanvasElement} canvas Barcode canvas element. * @param {BaseAttributes []} options Barcode attributes . * @function drawImage * @returns {void} Export the barcode as an image in the specified image type and downloads it in the browser. * @memberof Barcode * @private */ drawImage(canvas, options) { const barcodeRenderer = this.getInstance(canvas.id); for (let i = 0; i < options.length; i++) { barcodeRenderer.renderRectElement(canvas, options[parseInt(i.toString(), 10)]); } } updateDisplayTextSize(options, size, endValue, startValue, textProperty) { if (options.x + size.width > endValue || (options.x < startValue) && options.stringSize > 2) { // eslint-disable-next-line const rightAlign = options.x < startValue && textProperty.margin.right ? true : false; if (options.x < startValue && textProperty.margin.right) { // if the displaytext rendering overlaps the barcode then need to reduce the displaytext size gradually by 2 options.stringSize -= 2; const newSize = measureText(options); // used to get the middle value for the text as well the total barcode size options.x += (((endValue - startValue)) / 2) - newSize.width * .5; const diff = textProperty.margin.right - (endValue - (options.x + size.width)); options.x -= diff; this.updateDisplayTextSize(options, newSize, endValue, startValue, textProperty); } } } alignDisplayText(options, textProperty, startValue, endValue, size) { let leftMargin = false; // have to adjust the displaytext position during the rendering of default displaytext size if ((textProperty.margin.left || textProperty.margin.right)) { if (options.x - startValue < textProperty.margin.left && textProperty.margin.left) { leftMargin = true; const diff = textProperty.margin.left - (options.x - startValue); options.x += diff; this.updateDisplayTextSize(options, size, endValue, startValue, textProperty); } if ((endValue - (options.x + size.width) < textProperty.margin.right) && textProperty.margin.right && !leftMargin) { const diff = textProperty.margin.right - (endValue - (options.x + size.width)); options.x -= diff; this.updateDisplayTextSize(options, size, endValue, startValue, textProperty); } else if ((endValue - (options.x + size.width) < textProperty.margin.right)) { const newSize = measureText(options); this.updateOverlappedTextPosition((endValue - startValue), options, newSize, startValue, textProperty, endValue); this.updateDisplayTextSize(options, newSize, endValue, startValue, textProperty); } } } updateOverlappedTextPosition(width, options, size, startValue, textProperty, endValue) { if ((size.width > width || textProperty) && (endValue - (options.x + size.width) <= textProperty.margin.right) && options.stringSize > 2) { options.stringSize -= !textProperty ? 2 : .2; const newSize = measureText(options); this.updateOverlappedTextPosition(width, options, newSize, startValue, textProperty, endValue); } else if (!textProperty.margin.left && !textProperty.margin.right && options.stringSize > 2) { this.getAlignmentPosition(options, endValue, startValue, size); } } drawText(canvas, options) { if (!this.isSvgMode) { options.y /= 1.5; } const barcodeRenderer = this.getInstance(canvas.id); barcodeRenderer.renderTextElement(canvas, options); } } /** * code128 used to calculate the barcode of type 128 */ class Code128 extends OneDimension { /** * Validate the given input. * * @returns {string} Validate the given input. * @para