label-printer 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +80 -47
- package/dist/index.d.ts +80 -47
- package/dist/index.js +30 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +29 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/Command.ts","../src/commands/CommandGroup.ts","../src/commands/tspl/index.ts","../src/commands/tspl/TSPLCommand.ts","../src/commands/tspl/commands/TSPLRawCommand.ts","../src/commands/tspl/commands/TSPLCommandGroup.ts","../src/commands/tspl/commands/TSPLVisualCommand.ts","../src/helpers/ImageUtils.ts","../src/helpers/UnitUtils.ts","../src/commands/tspl/commands/basic/TSPLBitmapCommand.ts","../src/commands/tspl/types.ts","../src/commands/tspl/commands/basic/TSPLTextCommand.ts","../src/commands/tspl/commands/basic/TSPLGapCommand.ts","../src/commands/tspl/commands/basic/TSPLSizeCommand.ts","../src/commands/tspl/commands/basic/TSPLCLSCommand.ts","../src/commands/tspl/commands/basic/TSPLDirectionCommand.ts","../src/commands/tspl/commands/basic/TSPLPrintCommand.ts","../src/commands/tspl/commands/basic/TSPLBarCommand.ts","../src/commands/tspl/commands/basic/TSPLQRCommand.ts","../src/commands/tspl/commands/basic/TSPLBlockCommand.ts","../src/commands/tspl/commands/basic/TSPLDownload.ts","../src/commands/tspl/commands/basic/TSPLDisplay.ts","../src/commands/tspl/commands/basic/TSPLDiagonal.ts","../src/commands/tspl/commands/basic/TSPLBarcodeCommand.ts","../src/helpers/QRCodeUtils.ts","../src/commands/tspl/TSPLCommandGenerator.ts","../src/printers/Printer.ts","../src/helpers/StringUtils.ts","../src/helpers/USBUtils.ts","../src/printers/TSPLPrinter.ts","../src/printers/PrinterService.ts","../src/labels/Printable.ts","../src/labels/Label.ts","../src/labels/fields/LabelField.ts","../src/labels/fields/Line.ts","../src/labels/fields/Text.ts","../src/labels/fields/BarCode.ts","../src/labels/fields/Image.ts","../src/labels/fields/QRCode.ts"],"sourcesContent":["export * from \"./commands\"\nexport * from \"./printers\"\nexport * from \"./labels\"","import { UsbDevice } from \"@/helpers/USBUtils\"\n\n/**\n * Base implementation for all types of command\n * Represents a command to be send to the printer to execute, such as print\n */\nexport default abstract class Command {\n /**\n * Returns a string representation of the command\n */\n abstract get commandString(): string\n\n print(fn: (command: string) => void) {\n fn(this.commandString)\n }\n\n /**\n * Write the command data to a USB device\n * @param device Device to write to\n */\n async write(device: UsbDevice): Promise<void> {\n await this.writeString(this.commandString, device)\n await this.terminateCommand(device)\n }\n\n /**\n * Byte representation of a newline\n */\n protected get commandTerminatorBytes(): Uint8Array {\n return new Uint8Array([10])\n }\n\n /**\n * Writes a string to a device\n * @param data String representation of data\n * @param device Device to write to\n */\n protected async writeString(data: string, device: UsbDevice): Promise<void> {\n await device.writeString(data)\n }\n\n /**\n * Writes bytes to a device. It will automatically end a command with @see{commandTerminatorBytes}\n * @param data Byte array to send\n * @param device Device to write to\n */\n protected async writeBytes(data: Uint8Array|ArrayBuffer, device: UsbDevice): Promise<void> {\n await device.writeData(data)\n }\n\n /**\n * Write the command terminator to the device\n * @param device \n */\n protected async terminateCommand(device: UsbDevice): Promise<void> {\n await this.writeBytes(this.commandTerminatorBytes, device)\n }\n}","import { UsbDevice } from \"@/helpers/USBUtils\";\nimport Command from \"./Command\";\n\n/**\n * A utility class that helps groupping commands together\n * Should be implemnted with a specific command type to ensure only commands for the same lagnuage are\n * groupped together\n */\nexport default abstract class CommandGroup<T extends Command> extends Command {\n private commands: T[]\n\n constructor(commands: T[]) {\n super()\n this.commands = commands\n }\n\n print(fn: (command: string) => void) {\n for (let commandIndex in this.commands) {\n this.commands[commandIndex].print(fn)\n }\n }\n\n async write(device: UsbDevice): Promise<void> {\n for (let commandIndex in this.commands) {\n await this.commands[commandIndex].write(device)\n }\n }\n\n get commandString(): string {\n return \"\"\n }\n}","export { default as TSPLCommand } from \"./TSPLCommand\"\nexport { default as commandGenerator } from \"./TSPLCommandGenerator\"\n\nexport * from \"./commands\"\nexport * from \"./types\"","import Command from \"@/commands/Command\";\n\n/**\n * Base for TSPL specific commands\n */\nexport default abstract class TSPLCommand extends Command {\n}","import TSPLCommand from \"../TSPLCommand\"\n\n/**\n * A raw TSPL command. Can be used to use a command that is not yet supported\n */\nexport default class TSPLRawCommand extends TSPLCommand {\n /**\n * Raw command string\n */\n private readonly commandBody: string\n\n /**\n * Initialize a command with a raw body\n * @param body\n */\n constructor(body: string) {\n super()\n this.commandBody = body\n }\n\n get commandString(): string {\n return this.commandBody;\n }\n}\n","import CommandGroup from \"@/commands/CommandGroup\";\nimport TSPLCommand from \"../TSPLCommand\";\n\n/**\n * Command group for tspl commands\n */\nexport default class TSPLCommandGroup extends CommandGroup<TSPLCommand> {}","import TSPLCommand from \"../TSPLCommand\";\n\n/**\n * Base for all TSPL commands that have a visual effect on the final label\n */\nexport default abstract class TSPLVisualCommand extends TSPLCommand {\n protected readonly x: number\n protected readonly y: number\n\n constructor(x: number, y: number) {\n super()\n this.x = x\n this.y = y\n }\n}","// @ts-ignore\nimport pixels from \"image-pixels\"\nimport { getSizePreserveAspect } from \"./UnitUtils\"\n\n/**\n * Helper type to transmit image bitmap data\n */\nexport type Pixels = {\n data: Uint8Array, \n width: number,\n height: number, \n bitsPerPixel: number\n}\n\nexport type BitmapLike = {\n width: number,\n height: number,\n bytes: Uint8Array\n}\n\n/**\n * Helper type to transmit black and white bitmap data\n */\nexport type BWBitmap = BitmapLike\n\nconst BLACK_PIXEL = 0\nconst WHITE_PIXEL = 1\n\n/**\n * Set of image utility\n */\nexport default class ImageUtils {\n /**\n * Get pixel information about an image\n * @param image Image to process\n * @returns \n */\n static async getPixels(image: string|Blob): Promise<Pixels> {\n const {width, height, data} = await pixels(image) as Omit<Pixels, \"bitsPerPixel\">\n const bitsPerPixel = data.length / height / width\n\n return {\n data, width, height, bitsPerPixel\n }\n }\n\n /**\n * Return a bitmap in which all pixels are represented with one bit of either 1 or 0 representing white and black\n * pixels respectively. `destinationWidth` and `destinationHeight` have to be smaller or equal to the\n * input size as only downscaling is performed\n * \n * @param image Image to process \n * @param destinationWidth Width of the ouput bitmap\n * @param destinationHeight Height of the output bitmap\n * @returns \n */\n static async getBWBitmap(image: string, destinationWidth?: number, destinationHeight?: number): Promise<BWBitmap> {\n const {\n data,\n width,\n height,\n bitsPerPixel\n } = await this.getPixels(image)\n \n const dim = getSizePreserveAspect(width, height, destinationWidth, destinationHeight)\n // Number of pixels width and height => number of bits for each row and number of rows\n const dWidth = dim.width\n const dHeight = dim.height\n \n const differenceToDividable = dWidth % 8 == 0 ? 0 : (8 - (dWidth % 8))\n const dividableDWidth = dWidth + differenceToDividable\n \n // Size of the array has to be with * height but width has to be extended to be dividable by 8\n const bitmapData = new Uint8Array(dividableDWidth * dHeight)\n \n let destinationIndex = 0\n for (let h=0; h < dHeight; h++) {\n const originalHeight = Math.round((h * (height - 1)) / (dHeight - 1))\n \n for(let w=0; w < dWidth; w++) {\n const originalWidth = Math.round((w * (width - 1)) / (dWidth - 1))\n \n const baseIndex = (originalHeight * width * bitsPerPixel) + (originalWidth * bitsPerPixel)\n \n const r = data[baseIndex]\n const g = data[baseIndex + 1]\n const b = data[baseIndex + 2]\n const a = data[baseIndex + 3]\n \n if(a > 128) {\n const avg = (r + g + b) / 3\n \n if(avg > 128) {\n bitmapData[destinationIndex] = WHITE_PIXEL\n } else {\n bitmapData[destinationIndex] = BLACK_PIXEL\n }\n } else {\n bitmapData[destinationIndex] = WHITE_PIXEL\n }\n destinationIndex += 1\n }\n \n for(let i=0; i < differenceToDividable; i++) {\n bitmapData[destinationIndex] = WHITE_PIXEL\n destinationIndex += 1\n }\n }\n \n const byteArrays = this.chunk(bitmapData,8)\n const widthInBytes = dividableDWidth / 8\n \n const bytes = byteArrays.map(this.bitsToByte)\n const finalBytes = new Uint8Array(bytes)\n \n return {\n width: widthInBytes,\n height: dHeight,\n bytes: finalBytes\n }\n }\n\n /**\n * Splits an array into chunks.\n * @param originalArray\n * @param chunkSize\n * @returns\n */\n private static chunk(originalArray: Uint8Array, chunkSize: number): Uint8Array[] {\n const resultArray = [];\n\n for (let i = 0; i < originalArray.length; i += chunkSize) {\n const chunk = originalArray.slice(i, i + chunkSize);\n resultArray.push(chunk);\n }\n\n return resultArray;\n }\n\n /**\n * Converts an array of bits to a byte\n * @param bits\n * @returns\n */\n private static bitsToByte(bits: Uint8Array) {\n let byteValue = 0;\n for (let i = 0; i < bits.length; i++) {\n byteValue = (byteValue << 1) | bits[i];\n }\n return byteValue;\n }\n}","import { UnitSystem } from \"@/commands\"\n\nconst pointsPerInch = 72\n\nexport function getSizePreserveAspect(width: number, height: number, desiredWidth?: number, desiredHeight?: number) {\n // 0 width or height is not a valid number so we filter those dogether with undefined or null values\n if(desiredHeight && desiredWidth) {\n return { width: desiredWidth, height: desiredHeight }\n }\n if(desiredHeight) {\n const scaleFactor = desiredHeight / height\n return { width: width * scaleFactor, height: desiredHeight }\n } else if (desiredWidth) {\n const scaleFactor = desiredWidth / width\n return { width: desiredWidth, height: height * scaleFactor }\n } else {\n return { width, height }\n }\n}\n\nexport function valueWithUnit(value: number, unitSystem: UnitSystem) {\n switch(unitSystem) {\n case \"dot\": return `${value} dot`\n case \"imperial\": return value\n case \"metric\": return `${value} mm`\n }\n}\n\n/**\n * Convert a value from dots in points in a given dpi\n */\nexport function dotToPoint(dots: number, dpi: number): number {\n const inch = dots / dpi\n return Math.round(inch * pointsPerInch)\n}\n\n/**\n * Converts the points value to dots\n * 1 inch = 72 points (standard in typography)\n * Formula: dots = points * dpi / pointsPerInch\n * @param points \n * @param dpi \n * @returns \n */\nexport function pointsToDots(points: number, dpi: number): number {\n const pointsPerInch = 72;\n const dots = points * dpi / pointsPerInch;\n return dots;\n}","import ImageUtils, { BWBitmap } from \"@/helpers/ImageUtils\";\nimport { GraphicMode } from \"../../types\";\nimport TSPLVisualCommand from \"../TSPLVisualCommand\";\nimport { UsbDevice } from \"@/helpers/USBUtils\";\n\n/**\n * Represents a bitmap command. Can be used to draw an image to the label\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLBitmapCommand extends TSPLVisualCommand {\n /**\n * Bitmap to present. \n * TSPL only supports black and write printing so this bitmap contains a matrix of 1 (White pixel)\n * and 0 (Black pixel) values\n */\n private readonly bitmap: BWBitmap\n private readonly mode: GraphicMode\n\n /**\n * @param bitmap Bitmap to present. \n * @param x X coordinates in dots\n * @param y Y Coordinates in dots\n * @param mode Represents the strategy to use when two bitmaps overlap. The final value will be determined by\n * either overwriting the first bitmap's value with the second one or performing an 'or' or 'xor' operation on the values\n */\n constructor(bitmap: BWBitmap, x: number, y: number, mode?: GraphicMode) {\n super(x, y);\n this.bitmap = bitmap;\n this.mode = mode ?? \"overwrite\"\n }\n\n get commandString(): string {\n const textDecoder = new TextDecoder('utf-8')\n const bytesString = textDecoder.decode(this.bitmap.bytes)\n\n return `${this.commandWithoutBytes}${bytesString.slice(0,5)}...\\n`;\n }\n\n private get commandWithoutBytes(): string {\n return `BITMAP ${this.x}, ${this.y},${this.bitmap.width},${this.bitmap.height},${this.modeValue},`\n }\n\n private get modeValue(): 0|1|2 {\n switch (this.mode) {\n case \"overwrite\": return 0\n case \"or\": return 1\n case \"xor\": return 2\n }\n }\n\n async write(device: UsbDevice): Promise<void> {\n await this.writeString(this.commandWithoutBytes, device)\n await this.writeBytes(this.bitmap.bytes, device)\n await this.terminateCommand(device)\n }\n\n /**\n * Create a new bitmap command for the given image url\n * @param image Image to create command for \n * @param x X coordinate of the image\n * @param y Y coordinate of the image\n * @param imageWidth Desired width of the image\n * @param imageHeight Desired height of the image\n * @param mode Graphics mode\n * @returns \n */\n static async forImageUrl(image: string, x: number, y: number, imageWidth?: number, imageHeight?: number, mode?: GraphicMode) {\n const bitmap = await ImageUtils.getBWBitmap(image, imageWidth, imageHeight)\n return new TSPLBitmapCommand(bitmap, x, y, mode)\n }\n}","export type Rotation = 0|90|180|270\nexport type Alignment = undefined|\"left\"|\"center\"|\"right\"\n\n/**\n * Convert an alignemnt string to its number value\n * @param alignment \n * @returns \n */\nexport const alignmentToNumber = (alignment: Alignment): 0|1|2|3 => {\n switch(alignment) {\n case undefined: return 0\n case \"left\": return 1\n case \"center\": return 2\n case \"right\": return 3\n }\n}\n\n/**\n * Represents the strategy to use when two bitmaps overlap. The final value will be determined by\n * either overwriting the first bitmap's value with the second one or performing an 'or' or 'xor' operation\n * on the values\n */\nexport type GraphicMode = \"overwrite\"|\"or\"|\"xor\"\nexport type LabelDirection = \"normal\"|\"inverse\"\nexport type ECCLevel = \"L\"|\"M\"|\"Q\"|\"H\"\nexport type AutoManual = \"A\"|\"M\"\nexport type QRModel = \"M1\"|\"M2\"\nexport type BarcodeType = \"CODE128\"|\"EAN13\"|\"EAN8\"|\"EAN5\"|\"EAN2\"|\"UPC\"|\"CODE39\"|\"ITF14\"|\"MSI10\"|\"MSI11\"|\"MSI1010\"|\"MSI1110\"|\"pharmacode\"|\"codabar\"\nexport type BarcodeHumanReable = \"none\"|\"left\"|\"right\"|\"center\"","import { Alignment, Rotation, alignmentToNumber } from \"../../types\";\nimport TSPLVisualCommand from \"../TSPLVisualCommand\";\n\n/**\n * Prints a single line text on the label\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLTextCommand extends TSPLVisualCommand {\n /**\n * Name of the font to use. Consult documentation for more info\n */\n protected readonly font: string\n /**\n * Angle of rotation of the text. 0, 90, 180 or 270\n */\n protected readonly rotatation: Rotation\n /**\n * Multiplication of the font size in x axis\n */\n protected readonly xMultiplication: number\n /**\n * Multiplication of the font size in y axis\n */\n protected readonly yMultiplication: number\n /**\n * Text alignment. Left, Center or Right. The default alignmnet is left\n */\n protected readonly alignment: number\n /**\n * Text to print\n */\n protected readonly content: string\n\n constructor(content: string, x: number, y: number, font: string, rotation?: Rotation, xMultiplication?: number, yMultiplication?: number, alignment?: Alignment) {\n super(x, y)\n this.font = font\n this.rotatation = rotation ?? 0\n this.xMultiplication = xMultiplication ?? 1\n this.yMultiplication = yMultiplication ?? 1\n this.alignment = alignmentToNumber(alignment)\n this.content = content\n }\n\n get commandString(): string {\n return `TEXT ${this.x},${this.y},\\\"${this.font}\\\",${this.rotatation},${this.xMultiplication},${this.yMultiplication},${this.alignment},\\\"${this.content}\\\"`\n }\n}","import { valueWithUnit } from \"@/helpers/UnitUtils\";\nimport TSPLCommand from \"../../TSPLCommand\";\nimport { UnitSystem } from \"@/commands\";\n\n/**\n * Defines the gap between two labels\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLGapCommand extends TSPLCommand {\n private readonly gap: number\n private readonly offset: number\n\n /**\n * This controls what unit the {@link width} and {@link height} will be\n * - For imperial, the unit is inches\n * - For metric, the unit is milimeters\n * - For dots, the unit is dots\n */\n private readonly unitSystem: UnitSystem\n\n constructor(gap: number, offset: number, unitSystem: UnitSystem) {\n super()\n this.gap = gap\n this.offset = offset\n this.unitSystem = unitSystem\n } \n\n get commandString(): string {\n return `GAP ${valueWithUnit(this.gap, this.unitSystem)}, ${valueWithUnit(this.offset, this.unitSystem)}`\n }\n}","import { valueWithUnit } from \"@/helpers/UnitUtils\";\nimport TSPLCommand from \"../../TSPLCommand\";\nimport { UnitSystem } from \"@/commands\";\n\n/**\n * Defines the size of the label to rpint\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLSizeCommand extends TSPLCommand {\n private readonly width: number\n private readonly height: number\n /**\n * This controls what unit the {@link width} and {@link height} will be\n * - For imperial, the unit is inches\n * - For metric, the unit is milimeters\n * - For dots, the unit is dots\n */\n private readonly unitSystem: UnitSystem\n\n constructor(width: number, height: number, unitSystem: UnitSystem) {\n super()\n this.width = width\n this.height = height\n this.unitSystem = unitSystem\n } \n\n get commandString(): string {\n return `SIZE ${valueWithUnit(this.width, this.unitSystem)}, ${valueWithUnit(this.height, this.unitSystem)}`\n }\n}","import TSPLCommand from \"../../TSPLCommand\";\n\n/**\n * Clear the image buffer\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLCLSCommand extends TSPLCommand {\n get commandString(): string {\n return \"CLS\"\n }\n}","import TSPLCommand from \"../../TSPLCommand\";\nimport { LabelDirection } from \"../../types\";\n\n/**\n * This command defines in which direction will the label be printed and wether or not to mirror the image\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLDirectionCommand extends TSPLCommand {\n private readonly direction: 0|1\n private readonly mirror: 0|1\n\n /**\n * @param direction Controls the orientation of the resulting label compared to the printer\n * @param mirror Controls mirroring relative to the center line of the label perpendicular to the printhead. See the documentsion for examples\n */\n constructor(direction: LabelDirection, mirror?: boolean) {\n super()\n this.direction = direction == \"normal\" ? 1 : 0\n this.mirror = mirror ? 1 : 0\n }\n\n get commandString(): string {\n return `DIRECTION ${this.direction}, ${this.mirror}`\n }\n}\n","import TSPLCommand from \"../../TSPLCommand\";\n\n/**\n * Prints the current image buffer\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLPrintCommand extends TSPLCommand {\n /**\n * The number of set to print.\n */\n private readonly sets: number\n /**\n * The number of copies to print of each set.\n * The difference between a set and a copy is that if you have a counter for example,\n * the counter will be incremented for each set but not for each copy\n */\n private readonly copies: number\n\n constructor(sets: number, copies: number = 1) {\n super()\n this.sets = sets\n this.copies = copies\n }\n\n get commandString(): string {\n return `PRINT ${this.sets}, ${this.copies}`\n }\n}","import TSPLVisualCommand from \"../TSPLVisualCommand\";\n\n/**\n * Draws a black bar\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLBarCommand extends TSPLVisualCommand {\n private readonly width: number\n private readonly height: number\n\n /**\n * @param x X coordinates in dots\n * @param y Y coordinates in dots\n * @param width Width of tha bar in dots\n * @param height Height of the bar in dots\n */\n constructor(x: number, y: number, width: number, height: number) {\n super(x,y)\n this.width = width\n this.height = height\n }\n\n get commandString(): string {\n return `BAR ${this.x}, ${this.y}, ${this.width}, ${this.height}`\n }\n}","import { ECCLevel, AutoManual, Rotation, QRModel } from \"../../types\";\nimport TSPLVisualCommand from \"../TSPLVisualCommand\";\n\n/**\n * Prints a QR code\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLQRCommand extends TSPLVisualCommand {\n private readonly ecc: ECCLevel\n private readonly cellWidth: number\n private readonly mode: AutoManual\n private readonly rotation: Rotation\n private readonly model: QRModel\n /**\n * Should be between 0 and 7\n */\n private readonly mask: number\n private readonly content: string\n\n constructor(content: string, \n x: number, \n y: number, \n cellWidth: number, \n ecc: ECCLevel = \"H\", \n mode: AutoManual = \"A\", \n rotation: Rotation = 0, \n model: QRModel = \"M2\", \n mask: number = 7) {\n super(x,y)\n this.content = content\n this.cellWidth = cellWidth\n this.ecc = ecc\n this.mode = mode\n this.rotation = rotation\n this.model = model\n this.mask = mask\n\n if (mask < 0 || mask > 8) {\n throw new Error(`Invalid mask provided: ${mask}`)\n }\n }\n\n get commandString(): string {\n return `QRCODE ${this.x}, ${this.y}, ${this.ecc}, ${this.cellWidth}, ${this.mode}, ${this.rotation}, ${this.model}, \\\"${this.content}\\\"`\n }\n}","import { Alignment, Rotation } from \"../../types\";\nimport TSPLTextCommand from \"./TSPLTextCommand\";\n\nexport default class TSPLBlockCommand extends TSPLTextCommand {\n private readonly width: number\n private readonly height: number\n private readonly lineSpacing: number\n\n constructor(content: string, \n x: number, \n y: number, \n width: number,\n height: number,\n font: string, \n rotation?: Rotation, \n xMultiplication?: number, \n yMultiplication?: number, \n lineSpacing: number = 0,\n alignment?: Alignment) {\n super(content, x, y, font, rotation, xMultiplication, yMultiplication, alignment)\n this.width = width\n this.height = height\n this.lineSpacing = lineSpacing\n }\n\n get commandString(): string {\n return `BLOCK ${this.x},${this.y},${this.width}, ${this.height},\\\"${this.font}\\\",${this.rotatation},${this.xMultiplication},${this.yMultiplication},${this.lineSpacing},${this.alignment},\\\"${this.content}\\\"`\n }\n}","import { UsbDevice } from \"@/helpers/USBUtils\"\nimport TSPLCommand from \"../../TSPLCommand\"\n\ntype Data = ArrayBuffer|Uint8Array\n/**\n * A raw TSPL command. Can be used to use a command that is not yet supported\n */\nexport default class TSPLDownload extends TSPLCommand {\n /**\n * Name of the file on the printer\n */\n private readonly fileName: string\n private readonly data: Data\n\n /**\n * Initialize a command with a raw body\n * @param body\n */\n constructor(fileName: string, data: Data) {\n super()\n this.fileName = fileName\n this.data = data\n }\n\n get commandString(): string {\n return `DOWNLOAD \"${this.fileName}\", ${this.data.byteLength},`\n }\n\n async write(device: UsbDevice): Promise<void> {\n await this.writeString(this.commandString, device)\n await this.writeBytes(this.data, device)\n await this.terminateCommand(device)\n }\n}","import TSPLCommand from \"../../TSPLCommand\";\n\nexport type DisplayType = \"CLS\"|\"IMAGE\"|\"OFF\"\n\n/**\n * Displays the image buffer on the screen\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLDisplay extends TSPLCommand {\n private readonly type: DisplayType\n\n constructor(type: DisplayType) {\n super()\n this.type = type\n }\n\n get commandString(): string {\n return `DISPLAY ${this.type}`\n }\n}","import TSPLCommand from \"../../TSPLCommand\";\nimport { Point } from \"@/commands\";\n\nexport default class TSPLDiagonal extends TSPLCommand {\n private readonly start: Point\n private readonly end: Point\n private readonly thickness: number\n\n constructor(start: Point, end: Point, thickness: number = 3) {\n super()\n this.start = start\n this.end = end\n this.thickness = thickness\n }\n\n get commandString(): string {\n return `DIAGONAL ${this.start.x}, ${this.start.y}, ${this.end.x}, ${this.end.y}, ${this.thickness}`\n }\n}","import { Alignment, BarcodeHumanReable, BarcodeType, Rotation, alignmentToNumber } from \"../../types\";\nimport TSPLVisualCommand from \"../TSPLVisualCommand\";\n\nexport default class TSPLBarcodeCommand extends TSPLVisualCommand {\n private readonly type: BarcodeType\n private readonly height: number\n private readonly rotation: Rotation\n private readonly humanReadable: number\n private readonly narrow: number\n private readonly wide: number\n private readonly alignment: number\n private readonly content: string\n\n /**\n * @param x X coordinate in dots\n * @param y Y Coordinate in dots\n * @param type Type of the barcode\n * @param height Height of the barcode in dots\n * @param narrow Width of narrow elements in dots\n * @param wide Width of the wide elements in dots\n * @param content Content of the barcode. Supported content depends on the barcode type\n * @param rotation Rotation \n * @param alignment Alignment of the barcode\n */\n constructor(x: number, \n y: number, \n type: BarcodeType, \n height: number, \n narrow: number, \n wide: number,\n content: string,\n rotation: Rotation = 0, \n humanReadable: BarcodeHumanReable = \"left\",\n alignment: Alignment = \"left\") {\n super(x,y)\n this.type = type\n this.height = height\n this.narrow = narrow\n this.wide = wide\n this.content = content\n this.rotation = rotation\n this.humanReadable = TSPLBarcodeCommand.humanReadableValue(humanReadable)\n this.alignment = alignmentToNumber(alignment)\n }\n \n get commandString(): string {\n return `BARCODE ${this.x}, ${this.y}, \\\"${this.type}\\\", ${this.height}, ${this.humanReadable},${this.rotation}, ${this.narrow}, ${this.wide},${this.alignment}, \\\"${this.content}\\\"`\n }\n\n private static humanReadableValue(hr: BarcodeHumanReable): number {\n switch (hr) {\n case \"none\": return 0\n case \"left\": return 1\n case \"center\": return 2\n case \"right\": return 3\n }\n }\n}","// These mappings are for hight error correction level and for alpahnumeric data\n// The mapping has to be interpreted like this: up to (including) 10 characters, we have 21 cells\nexport const QRLengthMapping = {\n 10: 21,\n 20: 25,\n 35: 29,\n 50: 33,\n 64: 37,\n 84: 41,\n 93: 45,\n 122: 49,\n 143: 53,\n 174: 57,\n 200: 61,\n 227: 65,\n 259: 69,\n 283: 73,\n 321: 77,\n 365: 81,\n 408: 85,\n 452: 89,\n 493: 93,\n 557: 97,\n 587: 101,\n 640: 105,\n 672: 109,\n 744: 113,\n 779: 117,\n 864: 121,\n 910: 125,\n 958: 129,\n 1016: 133,\n 1080: 137,\n 1150: 141,\n 1226: 145,\n 1307: 149,\n 1394: 153,\n 1431: 157,\n 1530: 161,\n 1591: 165,\n 1658: 169,\n 1774: 173,\n 1852: 177\n}","import { BitmapLike } from \"@/helpers/ImageUtils\";\nimport { Point, UnitSystem } from \"..\";\nimport CommandGenerator from \"../CommandGenerator\";\nimport TSPLCommand from \"./TSPLCommand\";\nimport { TSPLBitmapCommand, TSPLCLSCommand, TSPLCommandGroup, TSPLDiagonal, TSPLDirectionCommand, TSPLDisplay, TSPLDownload, TSPLGapCommand, TSPLPrintCommand, TSPLQRCommand, TSPLRawCommand, TSPLSizeCommand, TSPLTextCommand } from \"./commands\";\nimport { Alignment, BarcodeHumanReable, BarcodeType, GraphicMode, LabelDirection, Rotation } from \"./types\";\nimport TSPLBarcodeCommand from \"./commands/basic/TSPLBarcodeCommand\";\nimport { QRLengthMapping } from \"@/helpers/QRCodeUtils\";\n\n/**\n * Command generator for tspl commands\n */\nclass TSPLCommandGenerator implements CommandGenerator<TSPLCommand> {\n commandGroup(commands: TSPLCommand[]) {\n return new TSPLCommandGroup(commands)\n }\n\n print(sets: number, copiesPerSet: number): TSPLCommand {\n return new TSPLPrintCommand(sets, copiesPerSet)\n }\n\n text(content: string, x: number, y: number, font: string|\"default\", size: number): TSPLCommand {\n const fontName = font == \"default\" ? \"0\" : font\n return new TSPLTextCommand(content, x, y, fontName, 0, size, size, \"left\")\n }\n\n upload(name: string, data: ArrayBuffer | Uint8Array): TSPLCommand {\n return new TSPLDownload(name, data)\n }\n\n setUp(width: number, height: number, gap: number, offset: number, direction: LabelDirection, mirror: boolean = false, unitSystem: UnitSystem): TSPLCommand {\n const commands = [\n new TSPLSizeCommand(width, height, unitSystem),\n new TSPLGapCommand(gap, offset, unitSystem),\n new TSPLDirectionCommand(direction, mirror),\n new TSPLCLSCommand()\n ]\n\n return new TSPLCommandGroup(commands)\n }\n\n display() {\n return new TSPLCommandGroup([\n new TSPLDisplay(\"CLS\"),\n new TSPLDisplay(\"IMAGE\")\n ])\n }\n\n line(start: Point, end: Point, thickness: number): TSPLCommand {\n return new TSPLDiagonal(start, end, thickness)\n }\n \n image(image: BitmapLike, x: number, y: number, mode?: GraphicMode | undefined): TSPLCommand {\n return new TSPLBitmapCommand(image, x, y, mode)\n }\n\n qrCode(content: string, width: number, x: number, y: number): TSPLCommand {\n const cellCount = this.cellCount(content)\n const cellWidth = Math.round(width / cellCount)\n // We start the content With A to indicate that our data is alphanumeric. \n // Not using auto ensures that we can easily calculate the cell with for a given content\n return new TSPLQRCommand(`A${content}`, x, y, cellWidth, 'H', \"M\")\n }\n \n barCode(content: string, x: number, y: number, type: BarcodeType, height: number, rotation: Rotation, humanReadable: BarcodeHumanReable, alignment: Alignment): TSPLCommand {\n return new TSPLBarcodeCommand(x, y, type, height, 1, 1, content, rotation, humanReadable, alignment)\n }\n\n private cellCount(content: string): number {\n const limits = Object.keys(QRLengthMapping).map( limit => Number(limit) ).sort((a, b) => a - b)\n const contentLength = content.length\n\n let i = 0\n while(limits[i] < contentLength && i < limits.length - 1) {\n i ++\n }\n\n return QRLengthMapping[limits[i] as keyof typeof QRLengthMapping]\n }\n}\n\nexport default new TSPLCommandGenerator()","import { Command, PrinterLanguage } from \"@/commands\";\nimport { LabelDirection } from \"@/commands/tspl\";\nimport { UsbDevice } from \"@/helpers/USBUtils\";\nimport { Label } from \"@/labels\"\n\n/**\n * Base class that encapsulates functionality of all printers\n */\nexport default abstract class Printer {\n private readonly usbDevice: UsbDevice\n\n /**\n * Printer language used by the type of printer the subclass represents\n */\n abstract get language(): PrinterLanguage\n\n /**\n * When called, it will feed the labels to the beginig of the next label\n */\n abstract feedLabel(): Promise<void>\n\n constructor(device: UsbDevice) {\n this.usbDevice = device\n }\n\n /**\n * Close the printer USB\n */\n async close() {\n await this.usbDevice.close()\n }\n\n /**\n * Prints a label\n * @param label \n */\n async print(label: Label, \n sets: number,\n gap: number, \n copiesPerSet: number = 1,\n direction: LabelDirection = \"normal\",\n mirror: boolean = false, \n gapOffset: number = 0) {\n const commands = await label.fullPrintCommand(this.language, gap, direction, sets, copiesPerSet, mirror, gapOffset)\n await this.writeCommand(commands)\n }\n\n /**\n * Display label on the printer's screen\n * @param label \n */\n async display(label: Label, direction: LabelDirection = \"normal\", mirror: boolean = false) {\n const command = await label.fullDisplayCommand(this.language, direction, mirror)\n await this.writeCommand(command)\n }\n\n /**\n * Writes a command to the printers usb\n * @param command Command to send to the usb\n */\n async writeCommand(command: Command): Promise<void> {\n if(!this.usbDevice.opened) await this.usbDevice.openAndConfigure()\n await command.write(this.usbDevice)\n }\n\n /**\n * Check if the device is indeed a printer\n * @param device \n */\n static try(_device: UsbDevice): Promise<boolean> {\n throw new Error(\"try(device:) should be implemented\")\n }\n}","/**\n * Collection of helpers to work with strings\n */\nexport default class StringUtils {\n /**\n * Convert string to utf8 array\n * @param str Convert string to byte array\n */\n toUTF8Array(str: string) {\n let utf8Encode = new TextEncoder();\n return utf8Encode.encode(str)\n }\n\n /**\n * Convert bytes to utf8 encoded string\n * @param bytes Bytes to decode\n * @returns A string\n */\n toString(bytes: Uint8Array|DataView) {\n let decoder = new TextDecoder()\n return decoder.decode(bytes)\n }\n}\n\nexport const isWhitespace = (text: string) => text.trim() === \"\"","import StringUtils from \"./StringUtils\";\n\nconst unsupportedUsbError = \"usb-unsupported\"\nconst stringHelper = new StringUtils()\n\nlet usbAgent: USB\n\n/**\n * @returns The appropiate USB agent based on the environment\n */\nconst getUSB = async (): Promise<USB> => {\n if(usbAgent) return usbAgent\n\n if(typeof window !== \"undefined\") {\n if(navigator.usb) {\n usbAgent = navigator.usb\n } else {\n throw unsupportedUsbError\n }\n } else {\n // TODO: Check how to avoid eval\n const { WebUSB } = eval(\"require\")(\"usb\")\n usbAgent = new WebUSB({allowAllDevices: true})\n }\n\n return usbAgent\n}\n\n/**\n * Returns the list of available devices\n * In node this returns all the connected devices but in the browser it will only return devices \n * that the user already gave permission to\n * @returns A list of available devices\n */\nexport const getDevices = async (): Promise<UsbDevice[]> => {\n const agent = await getUSB()\n const devices = await agent.getDevices()\n return devices.map(device => new UsbDevice(device) )\n}\n\n/**\n * In node, it returns the first available device, in the browser (supported browsers only) it shows \n * a UI for the user to choose a device\n * @returns The first available device\n */\nexport const requestDevice = async (): Promise<UsbDevice|undefined> => {\n const agent = await getUSB()\n const device = await agent.requestDevice({filters: []})\n if(device) {\n return new UsbDevice(device)\n } else {\n return undefined\n }\n}\n\n/**\n * Convenience wrapper for a web usb device\n * Its main purpose is to hide the details of the usb library from client code so in case\n * it needs to be switched, compatibility can be retained\n */\nexport class UsbDevice {\n private readonly device: USBDevice\n\n get opened() {\n return this.device.opened\n }\n\n /**\n * All available endpoints\n */\n private get endpoints() {\n return this.device.configuration?.interfaces[0].alternate.endpoints ?? []\n }\n\n /**\n * Endpoint for writing\n */\n private get outEndpoint() {\n return this.endpoints.find(e => e.direction == \"out\")?.endpointNumber\n }\n\n /**\n * Endpoint for reading\n */\n private get inEndpoint() {\n return this.endpoints.find(e => e.direction == \"in\")?.endpointNumber\n }\n\n constructor(device: USBDevice) {\n this.device = device\n }\n\n /**\n * Open the device and claim its interface\n */\n async openAndConfigure() {\n await this.device.open();\n await this.device.selectConfiguration(1);\n await this.device.claimInterface(0);\n }\n\n /**\n * Closes the device\n */\n async close() {\n await this.device.releaseInterface(0)\n await this.device.close()\n }\n\n /**\n * Write data to an USB device\n * @param data Data to write\n */\n async writeData(data: Uint8Array|ArrayBuffer): Promise<void> {\n const endpointNumber = this.outEndpoint\n await this.device.transferOut(endpointNumber!, data)\n }\n\n /**\n * Writes a text to a device\n * @param text Text to write\n */\n async writeString(text: string): Promise<void> {\n const bytes = stringHelper.toUTF8Array(text)\n await this.writeData(bytes)\n }\n\n /**\n * Reads bytes from the usb device\n * @param length The max length of the incoming data. \n * @returns Bytes received as a DataView or undefined. If data is longer then `length`, undefined will be returned\n */\n async readData(length: number): Promise<DataView|undefined> {\n const endpointNumber = this.inEndpoint\n const result = await this.device.transferIn(endpointNumber!, length)\n\n if(result.status == \"ok\" && result.data) {\n return result.data\n } else {\n return undefined\n }\n }\n\n /**\n * Reads data from the usb device and converts it to string\n * {@see readData}\n */\n async readString(length: number): Promise<string|undefined> {\n const bytes = await this.readData(length)\n if(bytes) return stringHelper.toString(bytes)\n return undefined\n }\n}\n","import { TSPLRawCommand } from \"@/commands/tspl\";\nimport { PrinterLanguage } from \"@/commands\"\nimport Printer from \"./Printer\";\nimport { UsbDevice } from \"@/helpers/USBUtils\";\n\nexport default class TSPLPrinter extends Printer {\n get language(): PrinterLanguage {\n return \"tspl\"\n }\n\n async feedLabel(): Promise<void> {\n const feedCommand = new TSPLRawCommand(\"FORMFEED\")\n await this.writeCommand(feedCommand)\n }\n\n static async try(device: UsbDevice): Promise<boolean> {\n if(!device.opened) await device.openAndConfigure()\n const testCommand = new TSPLRawCommand(\"~!I\")\n await testCommand.write(device)\n\n const response = await device.readString(64)\n await device.close()\n // If there is a response, we have a TSPL printer\n return !!response\n }\n}","import { UsbDevice, getDevices, requestDevice } from \"@/helpers/USBUtils\"\nimport TSPLPrinter from \"./TSPLPrinter\"\nimport Printer from \"./Printer\"\n\nexport class PrinterService {\n /**\n * Try each type of printer and return the one that mathces the usb device\n * @param device \n * @returns \n */\n static async printerForDevice(device: UsbDevice): Promise<Printer|undefined> {\n const classes = [TSPLPrinter]\n\n for (const key in classes) {\n if(await classes[key].try(device)) {\n return new classes[key](device)\n }\n }\n\n return undefined\n }\n\n /**\n * @returns List of available printers\n */\n static async getPrinters(): Promise<Printer[]> {\n const devices = await getDevices()\n const optionalPrinters = await Promise.all(devices.map(PrinterService.printerForDevice))\n return optionalPrinters.filter(printer => !!printer) as Printer[]\n }\n\n /**\n * This is intended to be used in the browser although it also works in node\n * In the browser, it provides a UI for the user to choose a USB device and if it is a\n * printer, it returns a new printer instance. In Node however, this will try to create\n * a printer for the first available device and returns it. This means that even if there is a \n * printer, it may return undefined. In node, use `getPrinters` instead\n */\n static async requestPrinter(): Promise<Printer|undefined> {\n const device = await requestDevice()\n if(device) {\n return PrinterService.printerForDevice(device)\n }\n }\n}","import { Command, PrinterLanguage, tspl } from \"@/commands\";\nimport CommandGenerator from \"@/commands/CommandGenerator\";\nimport { Printer } from \"@/printers\";\nimport { FontOption } from \"./types\";\n\nexport type PrintConfig = {\n dpi: number,\n textWidth: (text: string, font: FontOption) => number,\n getFontName: (font: FontOption) => string\n}\n\n/**\n * A component that can be directly printed to label printer\n */\nexport default abstract class Printable {\n /**\n * Generates a printable command\n * @param language The printing language that should be used\n * @returns A promise of a command that can be printed\n */\n abstract commandForLanguage(language: PrinterLanguage, config?: PrintConfig): Promise<Command>\n\n /**\n * Generates printable command for the given printer. Can be used to obtain a command for fields supported by the package then customizing it before printing\n * @param printer Printer to generate the command. Important because the command is printer language specific\n * @returns A promise for a command. Most commands are syncronouse but some may require to access async resources\n */\n async commandForPrinter(printer: Printer, config?: PrintConfig): Promise<Command> {\n return await this.commandForLanguage(printer.language, config)\n }\n\n /**\n * Obtain a command generator for the given language\n * @param language Language to get generator for\n */\n protected commandGeneratorFor(language: PrinterLanguage): CommandGenerator<any> {\n switch(language) {\n case \"tspl\": return tspl.commandGenerator\n }\n }\n}","import { Command, PrinterLanguage } from \"@/commands\";\nimport Printable, { PrintConfig } from \"./Printable\";\nimport { UnitSystem } from \"@/commands\";\nimport { LabelDirection } from \"@/commands/tspl\";\nimport LabelField from \"./fields/LabelField\";\nimport { Font, FontFamily, FontOption, FontStyle, IndexedFontFamily, NamelessFont } from \"./types\";\nimport CommandGenerator from \"@/commands/CommandGenerator\";\nimport fontkit from \"fontkit\"\nimport { dotToPoint, pointsToDots } from \"@/helpers/UnitUtils\";\n\nconst DEFAULT_FONT_WEIGHT = 400\nconst DEFAULT_FONT_STYLE = \"normal\"\nconst FONT_PREFIX = \"f\"\n\n/**\n * Holds the content of a label and handles printing\n */\nexport default class Label extends Printable {\n /**\n * Width of label in dots, mm or inch\n */\n private readonly width: number\n /**\n * Height of label in dots, mm or inch\n */\n private readonly height: number\n\n /**\n * Units for width, height, gap and offset\n */\n private readonly unitSystem: UnitSystem\n private fonts: Record<string, IndexedFontFamily> = {}\n private dpi: number\n\n /**\n * List of fields on the label\n */\n private fields: LabelField[] = []\n private fontCounter = 0\n\n /**\n * Configuration used when generating commands\n */\n get printConfig(): PrintConfig {\n return { \n dpi: this.dpi,\n textWidth: (text, font) => {\n const size = dotToPoint(font.size, this.dpi)\n const fontObject = this.getIndexedFont(font).font\n \n const run = fontObject.layout(text)\n\n const scaledWidth = size * run.advanceWidth / fontObject.unitsPerEm\n return pointsToDots(scaledWidth, this.dpi)\n },\n getFontName: this.getFontName.bind(this)\n } \n }\n\n constructor(width: number, height: number, dimensionUnit: UnitSystem = \"metric\", dpi: number = 203) {\n super()\n this.width = width\n this.height = height\n this.unitSystem = dimensionUnit\n this.dpi = dpi\n }\n\n async commandForLanguage(language: PrinterLanguage, config?: PrintConfig): Promise<Command> {\n const commandList = await Promise.all(this.fields.map(field => field.commandForLanguage(language, config)))\n return this.commandGeneratorFor(language).commandGroup(commandList)\n }\n\n /**\n * Place fields to a label\n * @param fields \n */\n add(...fields: LabelField[]) {\n this.fields.push(...fields)\n }\n\n /**\n * Register a font to be used. Use the name provided in components to use the font. \n * For example: textField.setFont('myFont.ttf', 12)\n * @param file Font file. Can be a blob or a url\n * @param name Name to be used to reference the font\n */\n async registerFont(font: Omit<Font, \"font\">) {\n const key = this.fontKey(font.weight, font.style)\n\n if(!this.fonts[font.name]) {\n this.fonts[font.name] = {\n fonts: {}\n }\n }\n\n const fontBuffer = Buffer.from(font.data)\n this.fonts[font.name].fonts[key] = {\n ...font,\n font: fontkit.create(fontBuffer),\n alias: `${FONT_PREFIX}${this.fontCounter}.${this.fontExtension}`\n }\n this.fontCounter += 1\n }\n\n /**\n * Generate a command that is complete for printing\n * @param language Printing language to use\n * @param gap Distance between two labels. It is measured between the two points where the sensor \n * leaves the label and enters the next one\n * @param direction Direction relative to printing direction. See documentation for more details\n * @param sets Number of sets to print. If you have counters for example, it will not change in a set\n * @param copiesPerSet Number of labels per set\n * @param mirror Mirror the label along the vertical axis\n * @param gapOffset Used with non uniform shaped labels. Is the distance between the point where the sensor leaves the label and the \n * furthest point of the label in the direction of printing. Check documentation for more info\n * TODO: Is this too TSPL Specific?\n */\n async fullPrintCommand(language: PrinterLanguage, \n gap: number, \n direction: LabelDirection, \n sets: number, \n copiesPerSet: number = 1,\n mirror: boolean = false, \n gapOffset: number = 0\n ): Promise<Command> {\n\n const generator = this.commandGeneratorFor(language)\n const commands = await this.fullCommand(language, gap, direction, mirror, gapOffset, generator)\n commands.push(generator.print(sets, copiesPerSet))\n\n return generator.commandGroup(commands)\n }\n\n /**\n * Generate commands needed to display the label on the printer screen\n * @param language Printing language to use\n * @param direction Direction relative to printing direction. See documentation for more details\n * @param mirror Mirror the label along the vertical axis\n */\n async fullDisplayCommand(language: PrinterLanguage, direction: LabelDirection, mirror: boolean = false) {\n const generator = this.commandGeneratorFor(language)\n const commands = await this.fullCommand(language, 0, direction, mirror, 0, generator)\n commands.push(generator.display())\n \n const group = generator.commandGroup(commands)\n group.print(console.log)\n return group\n }\n\n /**\n * Helper function that generates common commands for print and display\n */\n private async fullCommand(language: PrinterLanguage, \n gap: number, \n direction: LabelDirection, \n mirror: boolean = false, \n gapOffset: number = 0, \n generator: CommandGenerator<any>) {\n const commands = [\n this.fontUploadCommands(generator),\n generator.setUp(this.width, this.height, gap, gapOffset, direction, mirror, this.unitSystem),\n (await this.commandForLanguage(language, this.printConfig)),\n ]\n return commands\n }\n\n private fontUploadCommands(generator: CommandGenerator<any>): Command {\n const families = Object.keys(this.fonts)\n const commands = families.flatMap(family => {\n const familyFonts = this.fonts[family].fonts\n const fontNames = Object.keys(familyFonts)\n\n return fontNames.map(name => {\n const font = familyFonts[name]\n const fileName = font.alias\n\n return generator.upload(fileName, font.data)\n })\n })\n\n return generator.commandGroup(commands)\n }\n\n private getIndexedFont(font: FontOption) {\n const family = this.fonts[font.name]\n\n const style = font.style ?? DEFAULT_FONT_STYLE\n const weigth = font.weight ?? DEFAULT_FONT_WEIGHT\n\n const fontKeys = Object.keys(family.fonts)\n const exactMatch = fontKeys.find(key => \n family.fonts[key].style == style &&\n family.fonts[key].weight == weigth\n )\n\n // If there is a font that matches exactly the requested one we return that\n // otherwise we find the one that is the closest in weight\n // if there is no font with the same style, we return the first normal font in the family\n if(exactMatch) {\n return family.fonts[exactMatch]\n } else {\n const sameStyleKeys = fontKeys.filter(key => family.fonts[key].style == style)\n\n if(sameStyleKeys.length > 0){\n let weigthDiff = 99999999\n let selectedKey = \"\"\n\n sameStyleKeys.forEach(key => {\n const diff = Math.abs(weigth - family.fonts[key].weight)\n if(diff < weigthDiff) {\n weigthDiff = diff\n selectedKey = key\n }\n })\n\n return family.fonts[selectedKey]\n } else {\n return family.fonts[fontKeys[0]]\n }\n }\n }\n\n private getFontName(font: FontOption) {\n // We don't access values directly passed in to make sure the font name we return exists\n const indexedFont = this.getIndexedFont(font)\n return indexedFont.alias\n // return this.getFontNameForIndexed({name: font.name, weight: indexedFont.weight, style: indexedFont.style})\n }\n\n /// This can be extended when we want support multiple fonts\n private get fontExtension() {\n return \"TTF\"\n }\n\n private fontKey(weight: number, style?: FontStyle) {\n return `${weight}${style ?? DEFAULT_FONT_STYLE}`\n }\n}","import Printable from \"../Printable\";\n\nexport default abstract class LabelField extends Printable {}","import { Command, Point, PrinterLanguage } from \"@/commands\";\nimport LabelField from \"./LabelField\";\n\n/**\n * Draws a line to the screen\n */\nexport default class Line extends LabelField {\n private readonly start: Point\n private readonly end: Point\n private readonly thickness: number\n\n /**\n * \n * @param start Start point of the line. Values are in dots\n * @param end End point of the line. Values are in dots\n * @param thickness Thickness of the line in dots \n */\n constructor(start: Point, end: Point, thickness: number = 3) {\n super()\n this.start = start\n this.end = end\n this.thickness = thickness\n }\n\n commandForLanguage(language: PrinterLanguage): Promise<Command> {\n return this.commandGeneratorFor(language).line(this.start, this.end, this.thickness)\n }\n}","import { Command, PrinterLanguage } from \"@/commands\"\nimport LabelField from \"./LabelField\"\nimport { PrintConfig } from \"../Printable\"\nimport { dotToPoint } from \"@/helpers/UnitUtils\"\nimport CommandGenerator from \"@/commands/CommandGenerator\"\nimport { isWhitespace } from \"@/helpers/StringUtils\"\nimport { NodeType, parse, HTMLElement, Node } from \"node-html-parser\"\nimport { FontOption } from \"../types\"\n\nexport type TextFieldType = \"singleline\"|\"multiline\"\ntype Context = {\n language: PrinterLanguage,\n generator: CommandGenerator<any>,\n config?: PrintConfig\n}\n\ntype TextDecoration = \"underline\"|\"strike\"\n\nconst BOLD_WEIGTH = 700\nconst BOLD_TAG = \"b\"\nconst ITALIC_TAG = \"i\"\nconst UNDERLINE_TAG = \"u\"\nconst STRIKE_TAG = \"s\"\n\n/**\n * Presents a piece of text on the label\n */\nexport default class Text extends LabelField {\n private readonly content: string\n /**\n * X coordinate in dots\n */\n private readonly x: number\n /**\n * Y coordinate in dots\n */\n private readonly y: number\n /**\n * If true, basic html elements will be interpretted, otherwise the raw string is printed out\n */\n private readonly formatted: boolean\n private font: FontOption = {name: \"default\", size: 10}\n private type: TextFieldType = \"singleline\"\n private context: Context|undefined = undefined\n private readonly lineSpacing = 1\n\n /**\n * Width of the text. \n * If set, the text will be clipped to this size\n * If the type is set to multiline, this is where the text is split to a newline\n */\n private width: number|undefined\n /**\n * Height of the text box, if empty and the type is multiline, the box can grow infinitely\n */\n private height: number|undefined\n \n constructor(content: string, x: number, y: number, formatted: boolean = true) {\n super()\n this.content = content.replace(\"\\n\", \"\") // Newline can break text generation\n this.x = x\n this.y = y\n this.formatted = formatted\n }\n\n /**\n * Sets the field to single line\n * @param width Max width of the text. Leave it undefined to allow the field to grow \n */\n setSingleLine(width?: number) {\n this.type = \"singleline\"\n this.width = width\n this.height = undefined\n }\n\n /**\n * Sets the field to multi line\n * @param width Max width of text before it gets wrapped to a new line\n * @param height Max height of the text box, leave undefined to allow the text box to grow infinitly\n */\n setMultiLine(width: number, height?: number) {\n this.type = \"multiline\"\n this.width = width\n this.height = height\n }\n\n /**\n * Set a font to use as a base. If no formatting is set on the text with a html tag, this will be used \n * Note: The font name either has to be a built in font on your printer or a font\n * that is registered on the label using 'registerFont'.\n */\n setFont(font: FontOption) {\n this.font = font\n }\n\n async commandForLanguage(language: PrinterLanguage, config?: PrintConfig): Promise<Command> {\n this.context = {\n config,\n language,\n generator: this.commandGeneratorFor(language)\n }\n\n let command: Command\n if(this.formatted) {\n command = this.generateFormattedText()\n } else {\n command = this.generatePlainText()\n }\n this.context = undefined\n \n return command\n }\n \n /**\n * Generate commands for formatted text\n * @returns \n */\n private generateFormattedText(): Command {\n if(!this.context) throw \"context-not-set\"\n \n const rootNode = parse(this.content)\n const { command } = this.generateFormattedRecursive(this.x, this.y, rootNode, this.font, [])\n return command\n }\n\n /**\n * Generate commands for plain text\n * @returns \n */\n private generatePlainText(): Command {\n const {command} = this.generatePlainTextCore(this.content, this.x, this.y, this.font)\n return command\n }\n\n /**\n * Iterats the nodes in a html text and generates text commands for it\n */\n private generateFormattedRecursive(initialX: number, initialY: number, rootNode: Node, font: FontOption, features: TextDecoration[]): {x: number, y: number, command: Command} {\n if(rootNode.nodeType == NodeType.TEXT_NODE) {\n const result = this.generatePlainTextCore(rootNode.innerText, initialX, initialY, font, features)\n return result\n } else {\n const elementNode = rootNode as HTMLElement\n const tag = elementNode.rawTagName\n\n let commands: Command[] = []\n let currentX = initialX\n let currentY = initialY\n\n let baseFont = {...font}\n let baseFeatures = [...features]\n \n if(tag == UNDERLINE_TAG) {\n baseFeatures.push(\"underline\")\n } else if(tag == STRIKE_TAG) {\n baseFeatures.push(\"strike\")\n } else if(tag == BOLD_TAG) {\n baseFont.weight = BOLD_WEIGTH\n } else if(tag == ITALIC_TAG) {\n baseFont.style = \"italic\"\n }\n\n elementNode.childNodes.forEach(node => {\n const {x,y,command} = this.generateFormattedRecursive(currentX, currentY, node, baseFont, baseFeatures )\n currentX = x\n currentY = y\n commands.push(command)\n })\n\n return {\n x: currentX,\n y: currentY,\n command: this.context!.generator.commandGroup(commands)\n }\n }\n }\n\n /**\n * Generate commands for plain text\n * @param config \n * @returns \n */\n private generatePlainTextCore(content: string, initialX: number, initialY: number, font: FontOption, features: TextDecoration[] = []): {x: number, y: number, command: Command} {\n if(!this.context) throw \"context-not-set\"\n\n const textWidhtFunction = this.textWithFunction\n let fullWidth = textWidhtFunction(content, font)\n\n if(this.width) {\n const initialPadding = initialX - this.x\n // Because we may start from further in the row, the first rows width may be smaller\n let rowWidth = this.width - initialPadding\n // In theory rowWidth should not be negative, but for some reson it happens.. as a quick work around we make sure it is not negative\n if(rowWidth <= 0) {\n rowWidth = this.width\n initialX = this.x\n initialY += font.size + this.lineSpacing\n }\n\n // Make sure we don't print spaces at the beginig of a row\n if(initialX == this.x) {\n content = content.trimStart()\n fullWidth = textWidhtFunction(content, font)\n }\n\n // We may not start from the begining of the textbox so we have to offset\n // by our current position\n if(fullWidth <= rowWidth) {\n return {\n x: initialX + fullWidth,\n y: initialY,\n command: this.textCommand(content, initialX, initialY, font, features)\n }\n } else {\n const commands: Command[] = []\n \n let x = initialX\n let y = initialY\n let remainingContent = content\n let remainingWidth = fullWidth\n let currentHeight = 0\n\n let finalX = x\n let finalY = y\n\n do {\n // This will be the last row of the text. \n if(remainingWidth < rowWidth) {\n finalX = x + remainingWidth\n finalY = y\n\n commands.push(this.textCommand(remainingContent, x, y, font, features))\n remainingContent = \"\"\n } else {\n // On how many rows this text would fit\n let rows = remainingWidth / rowWidth\n\n // From the second row, all rows are full width\n rowWidth = this.width\n // Which caracter is the last if dividing into the right number of rows\n let rowEndIndex = Math.floor(remainingContent.length / rows)\n let originalRowEndIndex = rowEndIndex\n\n // This means we have to fit a relatively short text into\n // a lot of rows which can only happen if the row width is very small\n // in this case, we have to go to a new line\n // This is used to avoid having to calculate the width of the first character of the current text, to compare with the remainig length\n if(rowEndIndex == 0) {\n x = this.x\n y += font.size + this.lineSpacing\n continue\n }\n\n // Scenario 1: Current index is in a middle of row\n // I am iron m@n\n // End this row with the last words last character\n\n // Scneraio 2: Current index is space:\n // I am iron@man\n // No action, but to simplify code, we threat as scenario 1\n\n // Scenario 3: Current index is right before a sapce\n // I am iro@ man\n // Start next row from the first latter\n\n // Find the end of the last word\n while(\n ! (\n !isWhitespace(remainingContent.charAt(rowEndIndex)) &&\n (\n rowEndIndex == remainingContent.length - 1 ||\n isWhitespace(remainingContent.charAt(rowEndIndex + 1))\n )\n ) && rowEndIndex > 0\n ) { rowEndIndex -- }\n\n let nextRowStartIndex = rowEndIndex + 1\n // We didn't find a space, we split the text wherever we land\n if(rowEndIndex == 0) {\n rowEndIndex = originalRowEndIndex\n nextRowStartIndex = originalRowEndIndex + 1\n } else {\n while(\n isWhitespace(remainingContent.charAt(nextRowStartIndex)) && \n nextRowStartIndex < remainingContent.length\n ) { nextRowStartIndex ++ }\n }\n\n const thisRow = remainingContent.substring(0, rowEndIndex + 1)\n commands.push(this.textCommand(thisRow, x, y, font, features))\n\n if(nextRowStartIndex == remainingContent.length) {\n finalX = x + remainingWidth\n finalY = y\n }\n\n // Make sure to move the cursor back to the left side of the text box\n // as we may have started further into the row\n x = this.x\n y += font.size + this.lineSpacing\n currentHeight = y - this.y\n\n remainingContent = remainingContent.substring(nextRowStartIndex)\n remainingWidth = textWidhtFunction(remainingContent, font)\n }\n } while(\n // We don't have a height constraint or we are still within bounds \n // and there is still content \n // and we are supporting multiline\n (this.height == undefined || (currentHeight + font.size) <= this.height) &&\n (remainingContent != \"\") &&\n this.type == \"multiline\"\n )\n return {\n x: finalX,\n y: finalY,\n command: this.context!.generator.commandGroup(commands)\n }\n }\n } else {\n return {\n x: initialX + fullWidth,\n y: initialY,\n command: this.textCommand(content, initialX, initialY, font, features)\n }\n }\n }\n\n private textCommand(text: string, x: number, y: number, font: FontOption, features: TextDecoration[]) {\n if(!this.context) throw \"no-context\"\n const finalFontSize = dotToPoint(font.size, this.context!.config?.dpi ?? 203)\n const finalFont = this.getFontName(font)\n const finalX = Math.round(x)\n const finalY = Math.round(y)\n\n let commands: Command[] = []\n const textCommand = this.context!.generator.text(text, finalX, finalY, finalFont, finalFontSize)\n\n if(features.length == 0) {\n return textCommand\n } else {\n let lineHeight = font.size * 0.1\n let textWidth = this.textWithFunction(text, font)\n\n if(features.includes(\"strike\")) {\n commands.push(this.textLineCommand(textWidth, x, y, lineHeight, 0.5, font.size))\n }\n\n if(features.includes(\"underline\")) {\n commands.push(this.textLineCommand(textWidth, x, y, lineHeight, 0.9, font.size))\n }\n\n commands.push(textCommand)\n }\n\n return this.context.generator.commandGroup(commands)\n }\n\n private textLineCommand(width: number, x: number, y: number, lineHeight: number, linePercentage: number, fontSize: number): Command {\n const sy = Math.round(y + (fontSize * linePercentage) - (lineHeight / 2))\n\n const sx = Math.round(x)\n return this.context!.generator.line(\n {x: sx, y: sy}, \n {x: sx + width, y: sy}, \n lineHeight)\n }\n\n private getFontName(font: FontOption) {\n if(!this.context) throw \"no-context\"\n if(font.name == \"default\") {\n return \"default\"\n } else {\n return this.context!.config?.getFontName(font)!\n }\n }\n\n private get textWithFunction() {\n if(this.font.name == \"default\") {\n return this.defaultTextWidth\n } else {\n return this.context?.config?.textWidth ?? this.defaultTextWidth\n }\n }\n\n /**\n * This function is used to calculate the font size if no\n * print config is provided. This will asume that the font has square characters\n */\n private defaultTextWidth(text: string, font: FontOption) {\n return text.length * font.size\n }\n}","import { Command, PrinterLanguage } from \"@/commands\";\nimport { PrintConfig } from \"../Printable\";\nimport LabelField from \"./LabelField\"\nimport { Alignment, BarcodeHumanReable, BarcodeType, Rotation } from \"@/commands/tspl\";\n\nexport default class BarCode extends LabelField {\n private readonly content: string\n private readonly x: number\n private readonly y: number\n private readonly type: BarcodeType\n private readonly height: number\n private rotation: Rotation\n private humanReadable: BarcodeHumanReable \n private readonly alignment: Alignment\n\n constructor(content: string, x: number, y: number, type: BarcodeType, height: number) {\n super()\n this.content = content\n this.x = x\n this.y = y\n this.type = type\n this.height = height\n this.rotation = 0\n this.humanReadable = \"none\"\n this.alignment = \"left\"\n }\n\n setRotation(rotation: Rotation) {\n this.rotation = rotation\n }\n\n setHumanReadable(humanReadable: BarcodeHumanReable) {\n this.humanReadable = humanReadable\n }\n\n async commandForLanguage(language: PrinterLanguage, _config?: PrintConfig | undefined): Promise<Command> {\n return await this.commandGeneratorFor(language).barCode(this.content, this.x, this.y, this.type, this.height, this.rotation, this.humanReadable, this.alignment)\n }\n}","import { Command, PrinterLanguage } from \"@/commands\";\nimport { PrintConfig } from \"../Printable\";\nimport LabelField from \"./LabelField\";\nimport ImageUtils, { BitmapLike } from \"@/helpers/ImageUtils\";\n\nexport default class Image extends LabelField {\n /**\n * X coordinate in dots\n */\n private readonly x: number\n /**\n * Y coordinate in dots\n */\n private readonly y: number\n\n private readonly image: BitmapLike\n\n constructor(x: number, y: number, image: BitmapLike) {\n super()\n this.x = x\n this.y = y\n this.image = image\n }\n\n async commandForLanguage(language: PrinterLanguage, _config?: PrintConfig | undefined): Promise<Command> {\n return await this.commandGeneratorFor(language).image(this.image, this.x, this.y)\n }\n\n /**\n * Create an image field for an image\n * @param image \n * @param x \n * @param y \n * @param width \n * @param height \n * @returns \n */\n static async create(image: string, x: number, y: number, width?: number, height?: number): Promise<Image> {\n const bitmap = await ImageUtils.getBWBitmap(image, width, height)\n\n return new Image(x, y, bitmap)\n }\n}","import { Command, PrinterLanguage } from \"@/commands\";\nimport { PrintConfig } from \"../Printable\";\nimport LabelField from \"./LabelField\";\n\nexport default class QRCode extends LabelField {\n private readonly content: string\n private readonly x: number\n private readonly y: number\n private readonly width: number\n\n constructor(content: string, x: number, y: number, width: number) {\n super()\n this.content = content\n this.x = x\n this.y = y\n this.width = width\n }\n\n async commandForLanguage(language: PrinterLanguage, config?: PrintConfig | undefined): Promise<Command> {\n return await this.commandGeneratorFor(language).qrCode(this.content, this.width, this.x, this.y)\n }\n}"],"mappings":"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","names":["pointsPerInch","pixels","fontkit"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/index.ts","../src/commands/Command.ts","../src/commands/CommandGroup.ts","../src/commands/tspl/index.ts","../src/commands/tspl/TSPLCommand.ts","../src/commands/tspl/commands/TSPLRawCommand.ts","../src/commands/tspl/commands/TSPLCommandGroup.ts","../src/commands/tspl/commands/TSPLVisualCommand.ts","../src/helpers/ImageUtils.ts","../src/helpers/UnitUtils.ts","../src/commands/tspl/commands/basic/TSPLBitmapCommand.ts","../src/commands/tspl/types.ts","../src/commands/tspl/commands/basic/TSPLTextCommand.ts","../src/commands/tspl/commands/basic/TSPLGapCommand.ts","../src/commands/tspl/commands/basic/TSPLSizeCommand.ts","../src/commands/tspl/commands/basic/TSPLCLSCommand.ts","../src/commands/tspl/commands/basic/TSPLDirectionCommand.ts","../src/commands/tspl/commands/basic/TSPLPrintCommand.ts","../src/commands/tspl/commands/basic/TSPLBarCommand.ts","../src/commands/tspl/commands/basic/TSPLQRCommand.ts","../src/commands/tspl/commands/basic/TSPLBlockCommand.ts","../src/commands/tspl/commands/basic/TSPLDownload.ts","../src/commands/tspl/commands/basic/TSPLDisplay.ts","../src/commands/tspl/commands/basic/TSPLDiagonal.ts","../src/commands/tspl/commands/basic/TSPLBarcodeCommand.ts","../src/helpers/QRCodeUtils.ts","../src/commands/tspl/TSPLCommandGenerator.ts","../src/printers/index.ts","../src/printers/Printer.ts","../src/helpers/StringUtils.ts","../src/helpers/USBUtils.ts","../src/printers/TSPLPrinter.ts","../src/printers/PrinterService.ts","../src/labels/index.ts","../src/labels/Printable.ts","../src/labels/Label.ts","../src/labels/fields/LabelField.ts","../src/labels/fields/Line.ts","../src/labels/fields/Text.ts","../src/labels/fields/BarCode.ts","../src/labels/fields/Image.ts","../src/labels/fields/QRCode.ts"],"sourcesContent":["export * as commands from \"./commands\"\nexport * as printers from \"./printers\"\nexport * as labels from \"./labels\"","export { default as Command } from \"./Command\"\nexport { default as CommandGroup } from \"./CommandGroup\"\n\nexport type PrinterLanguage = \"tspl\"\nexport type UnitSystem = \"imperial\"|\"metric\"|\"dot\"\n\nexport * as tspl from \"./tspl\"\nexport * from \"./types\"","import { UsbDevice } from \"@/helpers/USBUtils\"\n\n/**\n * Base implementation for all types of command\n * Represents a command to be send to the printer to execute, such as print\n */\nexport default abstract class Command {\n /**\n * Returns a string representation of the command\n */\n abstract get commandString(): string\n\n print(fn: (command: string) => void) {\n fn(this.commandString)\n }\n\n /**\n * Write the command data to a USB device\n * @param device Device to write to\n */\n async write(device: UsbDevice): Promise<void> {\n await this.writeString(this.commandString, device)\n await this.terminateCommand(device)\n }\n\n /**\n * Byte representation of a newline\n */\n protected get commandTerminatorBytes(): Uint8Array {\n return new Uint8Array([10])\n }\n\n /**\n * Writes a string to a device\n * @param data String representation of data\n * @param device Device to write to\n */\n protected async writeString(data: string, device: UsbDevice): Promise<void> {\n await device.writeString(data)\n }\n\n /**\n * Writes bytes to a device. It will automatically end a command with @see{commandTerminatorBytes}\n * @param data Byte array to send\n * @param device Device to write to\n */\n protected async writeBytes(data: Uint8Array|ArrayBuffer, device: UsbDevice): Promise<void> {\n await device.writeData(data)\n }\n\n /**\n * Write the command terminator to the device\n * @param device \n */\n protected async terminateCommand(device: UsbDevice): Promise<void> {\n await this.writeBytes(this.commandTerminatorBytes, device)\n }\n}","import { UsbDevice } from \"@/helpers/USBUtils\";\nimport Command from \"./Command\";\n\n/**\n * A utility class that helps groupping commands together\n * Should be implemnted with a specific command type to ensure only commands for the same lagnuage are\n * groupped together\n */\nexport default abstract class CommandGroup<T extends Command> extends Command {\n private commands: T[]\n\n constructor(commands: T[]) {\n super()\n this.commands = commands\n }\n\n print(fn: (command: string) => void) {\n for (let commandIndex in this.commands) {\n this.commands[commandIndex].print(fn)\n }\n }\n\n async write(device: UsbDevice): Promise<void> {\n for (let commandIndex in this.commands) {\n await this.commands[commandIndex].write(device)\n }\n }\n\n get commandString(): string {\n return \"\"\n }\n}","export { default as TSPLCommand } from \"./TSPLCommand\"\nexport { default as commandGenerator } from \"./TSPLCommandGenerator\"\n\nexport * from \"./commands\"\nexport * from \"./types\"","import Command from \"@/commands/Command\";\n\n/**\n * Base for TSPL specific commands\n */\nexport default abstract class TSPLCommand extends Command {\n}","import TSPLCommand from \"../TSPLCommand\"\n\n/**\n * A raw TSPL command. Can be used to use a command that is not yet supported\n */\nexport default class TSPLRawCommand extends TSPLCommand {\n /**\n * Raw command string\n */\n private readonly commandBody: string\n\n /**\n * Initialize a command with a raw body\n * @param body\n */\n constructor(body: string) {\n super()\n this.commandBody = body\n }\n\n get commandString(): string {\n return this.commandBody;\n }\n}\n","import CommandGroup from \"@/commands/CommandGroup\";\nimport TSPLCommand from \"../TSPLCommand\";\n\n/**\n * Command group for tspl commands\n */\nexport default class TSPLCommandGroup extends CommandGroup<TSPLCommand> {}","import TSPLCommand from \"../TSPLCommand\";\n\n/**\n * Base for all TSPL commands that have a visual effect on the final label\n */\nexport default abstract class TSPLVisualCommand extends TSPLCommand {\n protected readonly x: number\n protected readonly y: number\n\n constructor(x: number, y: number) {\n super()\n this.x = x\n this.y = y\n }\n}","// @ts-ignore\nimport pixels from \"image-pixels\"\nimport { getSizePreserveAspect } from \"./UnitUtils\"\n\n/**\n * Helper type to transmit image bitmap data\n */\nexport type Pixels = {\n data: Uint8Array, \n width: number,\n height: number, \n bitsPerPixel: number\n}\n\nexport type BitmapLike = {\n width: number,\n height: number,\n bytes: Uint8Array\n}\n\n/**\n * Helper type to transmit black and white bitmap data\n */\nexport type BWBitmap = BitmapLike\n\nconst BLACK_PIXEL = 0\nconst WHITE_PIXEL = 1\n\n/**\n * Set of image utility\n */\nexport default class ImageUtils {\n /**\n * Get pixel information about an image\n * @param image Image to process\n * @returns \n */\n static async getPixels(image: string|Blob): Promise<Pixels> {\n const {width, height, data} = await pixels(image) as Omit<Pixels, \"bitsPerPixel\">\n const bitsPerPixel = data.length / height / width\n\n return {\n data, width, height, bitsPerPixel\n }\n }\n\n /**\n * Return a bitmap in which all pixels are represented with one bit of either 1 or 0 representing white and black\n * pixels respectively. `destinationWidth` and `destinationHeight` have to be smaller or equal to the\n * input size as only downscaling is performed\n * \n * @param image Image to process \n * @param destinationWidth Width of the ouput bitmap\n * @param destinationHeight Height of the output bitmap\n * @returns \n */\n static async getBWBitmap(image: string, destinationWidth?: number, destinationHeight?: number): Promise<BWBitmap> {\n const {\n data,\n width,\n height,\n bitsPerPixel\n } = await this.getPixels(image)\n \n const dim = getSizePreserveAspect(width, height, destinationWidth, destinationHeight)\n // Number of pixels width and height => number of bits for each row and number of rows\n const dWidth = dim.width\n const dHeight = dim.height\n \n const differenceToDividable = dWidth % 8 == 0 ? 0 : (8 - (dWidth % 8))\n const dividableDWidth = dWidth + differenceToDividable\n \n // Size of the array has to be with * height but width has to be extended to be dividable by 8\n const bitmapData = new Uint8Array(dividableDWidth * dHeight)\n \n let destinationIndex = 0\n for (let h=0; h < dHeight; h++) {\n const originalHeight = Math.round((h * (height - 1)) / (dHeight - 1))\n \n for(let w=0; w < dWidth; w++) {\n const originalWidth = Math.round((w * (width - 1)) / (dWidth - 1))\n \n const baseIndex = (originalHeight * width * bitsPerPixel) + (originalWidth * bitsPerPixel)\n \n const r = data[baseIndex]\n const g = data[baseIndex + 1]\n const b = data[baseIndex + 2]\n const a = data[baseIndex + 3]\n \n if(a > 128) {\n const avg = (r + g + b) / 3\n \n if(avg > 128) {\n bitmapData[destinationIndex] = WHITE_PIXEL\n } else {\n bitmapData[destinationIndex] = BLACK_PIXEL\n }\n } else {\n bitmapData[destinationIndex] = WHITE_PIXEL\n }\n destinationIndex += 1\n }\n \n for(let i=0; i < differenceToDividable; i++) {\n bitmapData[destinationIndex] = WHITE_PIXEL\n destinationIndex += 1\n }\n }\n \n const byteArrays = this.chunk(bitmapData,8)\n const widthInBytes = dividableDWidth / 8\n \n const bytes = byteArrays.map(this.bitsToByte)\n const finalBytes = new Uint8Array(bytes)\n \n return {\n width: widthInBytes,\n height: dHeight,\n bytes: finalBytes\n }\n }\n\n /**\n * Splits an array into chunks.\n * @param originalArray\n * @param chunkSize\n * @returns\n */\n private static chunk(originalArray: Uint8Array, chunkSize: number): Uint8Array[] {\n const resultArray = [];\n\n for (let i = 0; i < originalArray.length; i += chunkSize) {\n const chunk = originalArray.slice(i, i + chunkSize);\n resultArray.push(chunk);\n }\n\n return resultArray;\n }\n\n /**\n * Converts an array of bits to a byte\n * @param bits\n * @returns\n */\n private static bitsToByte(bits: Uint8Array) {\n let byteValue = 0;\n for (let i = 0; i < bits.length; i++) {\n byteValue = (byteValue << 1) | bits[i];\n }\n return byteValue;\n }\n}","import { UnitSystem } from \"@/commands\"\n\nconst pointsPerInch = 72\n\nexport function getSizePreserveAspect(width: number, height: number, desiredWidth?: number, desiredHeight?: number) {\n // 0 width or height is not a valid number so we filter those dogether with undefined or null values\n if(desiredHeight && desiredWidth) {\n return { width: desiredWidth, height: desiredHeight }\n }\n if(desiredHeight) {\n const scaleFactor = desiredHeight / height\n return { width: width * scaleFactor, height: desiredHeight }\n } else if (desiredWidth) {\n const scaleFactor = desiredWidth / width\n return { width: desiredWidth, height: height * scaleFactor }\n } else {\n return { width, height }\n }\n}\n\nexport function valueWithUnit(value: number, unitSystem: UnitSystem) {\n switch(unitSystem) {\n case \"dot\": return `${value} dot`\n case \"imperial\": return value\n case \"metric\": return `${value} mm`\n }\n}\n\n/**\n * Convert a value from dots in points in a given dpi\n */\nexport function dotToPoint(dots: number, dpi: number): number {\n const inch = dots / dpi\n return Math.round(inch * pointsPerInch)\n}\n\n/**\n * Converts the points value to dots\n * 1 inch = 72 points (standard in typography)\n * Formula: dots = points * dpi / pointsPerInch\n * @param points \n * @param dpi \n * @returns \n */\nexport function pointsToDots(points: number, dpi: number): number {\n const pointsPerInch = 72;\n const dots = points * dpi / pointsPerInch;\n return dots;\n}","import ImageUtils, { BWBitmap } from \"@/helpers/ImageUtils\";\nimport { GraphicMode } from \"../../types\";\nimport TSPLVisualCommand from \"../TSPLVisualCommand\";\nimport { UsbDevice } from \"@/helpers/USBUtils\";\n\n/**\n * Represents a bitmap command. Can be used to draw an image to the label\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLBitmapCommand extends TSPLVisualCommand {\n /**\n * Bitmap to present. \n * TSPL only supports black and write printing so this bitmap contains a matrix of 1 (White pixel)\n * and 0 (Black pixel) values\n */\n private readonly bitmap: BWBitmap\n private readonly mode: GraphicMode\n\n /**\n * @param bitmap Bitmap to present. \n * @param x X coordinates in dots\n * @param y Y Coordinates in dots\n * @param mode Represents the strategy to use when two bitmaps overlap. The final value will be determined by\n * either overwriting the first bitmap's value with the second one or performing an 'or' or 'xor' operation on the values\n */\n constructor(bitmap: BWBitmap, x: number, y: number, mode?: GraphicMode) {\n super(x, y);\n this.bitmap = bitmap;\n this.mode = mode ?? \"overwrite\"\n }\n\n get commandString(): string {\n const textDecoder = new TextDecoder('utf-8')\n const bytesString = textDecoder.decode(this.bitmap.bytes)\n\n return `${this.commandWithoutBytes}${bytesString.slice(0,5)}...\\n`;\n }\n\n private get commandWithoutBytes(): string {\n return `BITMAP ${this.x}, ${this.y},${this.bitmap.width},${this.bitmap.height},${this.modeValue},`\n }\n\n private get modeValue(): 0|1|2 {\n switch (this.mode) {\n case \"overwrite\": return 0\n case \"or\": return 1\n case \"xor\": return 2\n }\n }\n\n async write(device: UsbDevice): Promise<void> {\n await this.writeString(this.commandWithoutBytes, device)\n await this.writeBytes(this.bitmap.bytes, device)\n await this.terminateCommand(device)\n }\n\n /**\n * Create a new bitmap command for the given image url\n * @param image Image to create command for \n * @param x X coordinate of the image\n * @param y Y coordinate of the image\n * @param imageWidth Desired width of the image\n * @param imageHeight Desired height of the image\n * @param mode Graphics mode\n * @returns \n */\n static async forImageUrl(image: string, x: number, y: number, imageWidth?: number, imageHeight?: number, mode?: GraphicMode) {\n const bitmap = await ImageUtils.getBWBitmap(image, imageWidth, imageHeight)\n return new TSPLBitmapCommand(bitmap, x, y, mode)\n }\n}","export type Rotation = 0|90|180|270\nexport type Alignment = undefined|\"left\"|\"center\"|\"right\"\n\n/**\n * Convert an alignemnt string to its number value\n * @param alignment \n * @returns \n */\nexport const alignmentToNumber = (alignment: Alignment): 0|1|2|3 => {\n switch(alignment) {\n case undefined: return 0\n case \"left\": return 1\n case \"center\": return 2\n case \"right\": return 3\n }\n}\n\n/**\n * Represents the strategy to use when two bitmaps overlap. The final value will be determined by\n * either overwriting the first bitmap's value with the second one or performing an 'or' or 'xor' operation\n * on the values\n */\nexport type GraphicMode = \"overwrite\"|\"or\"|\"xor\"\nexport type LabelDirection = \"normal\"|\"inverse\"\nexport type ECCLevel = \"L\"|\"M\"|\"Q\"|\"H\"\nexport type AutoManual = \"A\"|\"M\"\nexport type QRModel = \"M1\"|\"M2\"\nexport type BarcodeType = \"CODE128\"|\"EAN13\"|\"EAN8\"|\"EAN5\"|\"EAN2\"|\"UPC\"|\"CODE39\"|\"ITF14\"|\"MSI10\"|\"MSI11\"|\"MSI1010\"|\"MSI1110\"|\"pharmacode\"|\"codabar\"\nexport type BarcodeHumanReable = \"none\"|\"left\"|\"right\"|\"center\"","import { Alignment, Rotation, alignmentToNumber } from \"../../types\";\nimport TSPLVisualCommand from \"../TSPLVisualCommand\";\n\n/**\n * Prints a single line text on the label\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLTextCommand extends TSPLVisualCommand {\n /**\n * Name of the font to use. Consult documentation for more info\n */\n protected readonly font: string\n /**\n * Angle of rotation of the text. 0, 90, 180 or 270\n */\n protected readonly rotatation: Rotation\n /**\n * Multiplication of the font size in x axis\n */\n protected readonly xMultiplication: number\n /**\n * Multiplication of the font size in y axis\n */\n protected readonly yMultiplication: number\n /**\n * Text alignment. Left, Center or Right. The default alignmnet is left\n */\n protected readonly alignment: number\n /**\n * Text to print\n */\n protected readonly content: string\n\n constructor(content: string, x: number, y: number, font: string, rotation?: Rotation, xMultiplication?: number, yMultiplication?: number, alignment?: Alignment) {\n super(x, y)\n this.font = font\n this.rotatation = rotation ?? 0\n this.xMultiplication = xMultiplication ?? 1\n this.yMultiplication = yMultiplication ?? 1\n this.alignment = alignmentToNumber(alignment)\n this.content = content\n }\n\n get commandString(): string {\n return `TEXT ${this.x},${this.y},\\\"${this.font}\\\",${this.rotatation},${this.xMultiplication},${this.yMultiplication},${this.alignment},\\\"${this.content}\\\"`\n }\n}","import { valueWithUnit } from \"@/helpers/UnitUtils\";\nimport TSPLCommand from \"../../TSPLCommand\";\nimport { UnitSystem } from \"@/commands\";\n\n/**\n * Defines the gap between two labels\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLGapCommand extends TSPLCommand {\n private readonly gap: number\n private readonly offset: number\n\n /**\n * This controls what unit the {@link width} and {@link height} will be\n * - For imperial, the unit is inches\n * - For metric, the unit is milimeters\n * - For dots, the unit is dots\n */\n private readonly unitSystem: UnitSystem\n\n constructor(gap: number, offset: number, unitSystem: UnitSystem) {\n super()\n this.gap = gap\n this.offset = offset\n this.unitSystem = unitSystem\n } \n\n get commandString(): string {\n return `GAP ${valueWithUnit(this.gap, this.unitSystem)}, ${valueWithUnit(this.offset, this.unitSystem)}`\n }\n}","import { valueWithUnit } from \"@/helpers/UnitUtils\";\nimport TSPLCommand from \"../../TSPLCommand\";\nimport { UnitSystem } from \"@/commands\";\n\n/**\n * Defines the size of the label to rpint\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLSizeCommand extends TSPLCommand {\n private readonly width: number\n private readonly height: number\n /**\n * This controls what unit the {@link width} and {@link height} will be\n * - For imperial, the unit is inches\n * - For metric, the unit is milimeters\n * - For dots, the unit is dots\n */\n private readonly unitSystem: UnitSystem\n\n constructor(width: number, height: number, unitSystem: UnitSystem) {\n super()\n this.width = width\n this.height = height\n this.unitSystem = unitSystem\n } \n\n get commandString(): string {\n return `SIZE ${valueWithUnit(this.width, this.unitSystem)}, ${valueWithUnit(this.height, this.unitSystem)}`\n }\n}","import TSPLCommand from \"../../TSPLCommand\";\n\n/**\n * Clear the image buffer\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLCLSCommand extends TSPLCommand {\n get commandString(): string {\n return \"CLS\"\n }\n}","import TSPLCommand from \"../../TSPLCommand\";\nimport { LabelDirection } from \"../../types\";\n\n/**\n * This command defines in which direction will the label be printed and wether or not to mirror the image\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLDirectionCommand extends TSPLCommand {\n private readonly direction: 0|1\n private readonly mirror: 0|1\n\n /**\n * @param direction Controls the orientation of the resulting label compared to the printer\n * @param mirror Controls mirroring relative to the center line of the label perpendicular to the printhead. See the documentsion for examples\n */\n constructor(direction: LabelDirection, mirror?: boolean) {\n super()\n this.direction = direction == \"normal\" ? 1 : 0\n this.mirror = mirror ? 1 : 0\n }\n\n get commandString(): string {\n return `DIRECTION ${this.direction}, ${this.mirror}`\n }\n}\n","import TSPLCommand from \"../../TSPLCommand\";\n\n/**\n * Prints the current image buffer\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLPrintCommand extends TSPLCommand {\n /**\n * The number of set to print.\n */\n private readonly sets: number\n /**\n * The number of copies to print of each set.\n * The difference between a set and a copy is that if you have a counter for example,\n * the counter will be incremented for each set but not for each copy\n */\n private readonly copies: number\n\n constructor(sets: number, copies: number = 1) {\n super()\n this.sets = sets\n this.copies = copies\n }\n\n get commandString(): string {\n return `PRINT ${this.sets}, ${this.copies}`\n }\n}","import TSPLVisualCommand from \"../TSPLVisualCommand\";\n\n/**\n * Draws a black bar\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLBarCommand extends TSPLVisualCommand {\n private readonly width: number\n private readonly height: number\n\n /**\n * @param x X coordinates in dots\n * @param y Y coordinates in dots\n * @param width Width of tha bar in dots\n * @param height Height of the bar in dots\n */\n constructor(x: number, y: number, width: number, height: number) {\n super(x,y)\n this.width = width\n this.height = height\n }\n\n get commandString(): string {\n return `BAR ${this.x}, ${this.y}, ${this.width}, ${this.height}`\n }\n}","import { ECCLevel, AutoManual, Rotation, QRModel } from \"../../types\";\nimport TSPLVisualCommand from \"../TSPLVisualCommand\";\n\n/**\n * Prints a QR code\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLQRCommand extends TSPLVisualCommand {\n private readonly ecc: ECCLevel\n private readonly cellWidth: number\n private readonly mode: AutoManual\n private readonly rotation: Rotation\n private readonly model: QRModel\n /**\n * Should be between 0 and 7\n */\n private readonly mask: number\n private readonly content: string\n\n constructor(content: string, \n x: number, \n y: number, \n cellWidth: number, \n ecc: ECCLevel = \"H\", \n mode: AutoManual = \"A\", \n rotation: Rotation = 0, \n model: QRModel = \"M2\", \n mask: number = 7) {\n super(x,y)\n this.content = content\n this.cellWidth = cellWidth\n this.ecc = ecc\n this.mode = mode\n this.rotation = rotation\n this.model = model\n this.mask = mask\n\n if (mask < 0 || mask > 8) {\n throw new Error(`Invalid mask provided: ${mask}`)\n }\n }\n\n get commandString(): string {\n return `QRCODE ${this.x}, ${this.y}, ${this.ecc}, ${this.cellWidth}, ${this.mode}, ${this.rotation}, ${this.model}, \\\"${this.content}\\\"`\n }\n}","import { Alignment, Rotation } from \"../../types\";\nimport TSPLTextCommand from \"./TSPLTextCommand\";\n\nexport default class TSPLBlockCommand extends TSPLTextCommand {\n private readonly width: number\n private readonly height: number\n private readonly lineSpacing: number\n\n constructor(content: string, \n x: number, \n y: number, \n width: number,\n height: number,\n font: string, \n rotation?: Rotation, \n xMultiplication?: number, \n yMultiplication?: number, \n lineSpacing: number = 0,\n alignment?: Alignment) {\n super(content, x, y, font, rotation, xMultiplication, yMultiplication, alignment)\n this.width = width\n this.height = height\n this.lineSpacing = lineSpacing\n }\n\n get commandString(): string {\n return `BLOCK ${this.x},${this.y},${this.width}, ${this.height},\\\"${this.font}\\\",${this.rotatation},${this.xMultiplication},${this.yMultiplication},${this.lineSpacing},${this.alignment},\\\"${this.content}\\\"`\n }\n}","import { UsbDevice } from \"@/helpers/USBUtils\"\nimport TSPLCommand from \"../../TSPLCommand\"\n\ntype Data = ArrayBuffer|Uint8Array\n/**\n * A raw TSPL command. Can be used to use a command that is not yet supported\n */\nexport default class TSPLDownload extends TSPLCommand {\n /**\n * Name of the file on the printer\n */\n private readonly fileName: string\n private readonly data: Data\n\n /**\n * Initialize a command with a raw body\n * @param body\n */\n constructor(fileName: string, data: Data) {\n super()\n this.fileName = fileName\n this.data = data\n }\n\n get commandString(): string {\n return `DOWNLOAD \"${this.fileName}\", ${this.data.byteLength},`\n }\n\n async write(device: UsbDevice): Promise<void> {\n await this.writeString(this.commandString, device)\n await this.writeBytes(this.data, device)\n await this.terminateCommand(device)\n }\n}","import TSPLCommand from \"../../TSPLCommand\";\n\nexport type DisplayType = \"CLS\"|\"IMAGE\"|\"OFF\"\n\n/**\n * Displays the image buffer on the screen\n * {@link /documentsions/TSPL.pdf}\n */\nexport default class TSPLDisplay extends TSPLCommand {\n private readonly type: DisplayType\n\n constructor(type: DisplayType) {\n super()\n this.type = type\n }\n\n get commandString(): string {\n return `DISPLAY ${this.type}`\n }\n}","import TSPLCommand from \"../../TSPLCommand\";\nimport { Point } from \"@/commands\";\n\nexport default class TSPLDiagonal extends TSPLCommand {\n private readonly start: Point\n private readonly end: Point\n private readonly thickness: number\n\n constructor(start: Point, end: Point, thickness: number = 3) {\n super()\n this.start = start\n this.end = end\n this.thickness = thickness\n }\n\n get commandString(): string {\n return `DIAGONAL ${this.start.x}, ${this.start.y}, ${this.end.x}, ${this.end.y}, ${this.thickness}`\n }\n}","import { Alignment, BarcodeHumanReable, BarcodeType, Rotation, alignmentToNumber } from \"../../types\";\nimport TSPLVisualCommand from \"../TSPLVisualCommand\";\n\nexport default class TSPLBarcodeCommand extends TSPLVisualCommand {\n private readonly type: BarcodeType\n private readonly height: number\n private readonly rotation: Rotation\n private readonly humanReadable: number\n private readonly narrow: number\n private readonly wide: number\n private readonly alignment: number\n private readonly content: string\n\n /**\n * @param x X coordinate in dots\n * @param y Y Coordinate in dots\n * @param type Type of the barcode\n * @param height Height of the barcode in dots\n * @param narrow Width of narrow elements in dots\n * @param wide Width of the wide elements in dots\n * @param content Content of the barcode. Supported content depends on the barcode type\n * @param rotation Rotation \n * @param alignment Alignment of the barcode\n */\n constructor(x: number, \n y: number, \n type: BarcodeType, \n height: number, \n narrow: number, \n wide: number,\n content: string,\n rotation: Rotation = 0, \n humanReadable: BarcodeHumanReable = \"left\",\n alignment: Alignment = \"left\") {\n super(x,y)\n this.type = type\n this.height = height\n this.narrow = narrow\n this.wide = wide\n this.content = content\n this.rotation = rotation\n this.humanReadable = TSPLBarcodeCommand.humanReadableValue(humanReadable)\n this.alignment = alignmentToNumber(alignment)\n }\n \n get commandString(): string {\n return `BARCODE ${this.x}, ${this.y}, \\\"${this.type}\\\", ${this.height}, ${this.humanReadable},${this.rotation}, ${this.narrow}, ${this.wide},${this.alignment}, \\\"${this.content}\\\"`\n }\n\n private static humanReadableValue(hr: BarcodeHumanReable): number {\n switch (hr) {\n case \"none\": return 0\n case \"left\": return 1\n case \"center\": return 2\n case \"right\": return 3\n }\n }\n}","// These mappings are for hight error correction level and for alpahnumeric data\n// The mapping has to be interpreted like this: up to (including) 10 characters, we have 21 cells\nexport const QRLengthMapping = {\n 10: 21,\n 20: 25,\n 35: 29,\n 50: 33,\n 64: 37,\n 84: 41,\n 93: 45,\n 122: 49,\n 143: 53,\n 174: 57,\n 200: 61,\n 227: 65,\n 259: 69,\n 283: 73,\n 321: 77,\n 365: 81,\n 408: 85,\n 452: 89,\n 493: 93,\n 557: 97,\n 587: 101,\n 640: 105,\n 672: 109,\n 744: 113,\n 779: 117,\n 864: 121,\n 910: 125,\n 958: 129,\n 1016: 133,\n 1080: 137,\n 1150: 141,\n 1226: 145,\n 1307: 149,\n 1394: 153,\n 1431: 157,\n 1530: 161,\n 1591: 165,\n 1658: 169,\n 1774: 173,\n 1852: 177\n}","import { BitmapLike } from \"@/helpers/ImageUtils\";\nimport { Point, UnitSystem } from \"..\";\nimport CommandGenerator from \"../CommandGenerator\";\nimport TSPLCommand from \"./TSPLCommand\";\nimport { TSPLBitmapCommand, TSPLCLSCommand, TSPLCommandGroup, TSPLDiagonal, TSPLDirectionCommand, TSPLDisplay, TSPLDownload, TSPLGapCommand, TSPLPrintCommand, TSPLQRCommand, TSPLRawCommand, TSPLSizeCommand, TSPLTextCommand } from \"./commands\";\nimport { Alignment, BarcodeHumanReable, BarcodeType, GraphicMode, LabelDirection, Rotation } from \"./types\";\nimport TSPLBarcodeCommand from \"./commands/basic/TSPLBarcodeCommand\";\nimport { QRLengthMapping } from \"@/helpers/QRCodeUtils\";\n\n/**\n * Command generator for tspl commands\n */\nclass TSPLCommandGenerator implements CommandGenerator<TSPLCommand> {\n commandGroup(commands: TSPLCommand[]) {\n return new TSPLCommandGroup(commands)\n }\n\n print(sets: number, copiesPerSet: number): TSPLCommand {\n return new TSPLPrintCommand(sets, copiesPerSet)\n }\n\n text(content: string, x: number, y: number, font: string|\"default\", size: number): TSPLCommand {\n const fontName = font == \"default\" ? \"0\" : font\n return new TSPLTextCommand(content, x, y, fontName, 0, size, size, \"left\")\n }\n\n upload(name: string, data: ArrayBuffer | Uint8Array): TSPLCommand {\n return new TSPLDownload(name, data)\n }\n\n setUp(width: number, height: number, gap: number, offset: number, direction: LabelDirection, mirror: boolean = false, unitSystem: UnitSystem): TSPLCommand {\n const commands = [\n new TSPLSizeCommand(width, height, unitSystem),\n new TSPLGapCommand(gap, offset, unitSystem),\n new TSPLDirectionCommand(direction, mirror),\n new TSPLCLSCommand()\n ]\n\n return new TSPLCommandGroup(commands)\n }\n\n display() {\n return new TSPLCommandGroup([\n new TSPLDisplay(\"CLS\"),\n new TSPLDisplay(\"IMAGE\")\n ])\n }\n\n line(start: Point, end: Point, thickness: number): TSPLCommand {\n return new TSPLDiagonal(start, end, thickness)\n }\n \n image(image: BitmapLike, x: number, y: number, mode?: GraphicMode | undefined): TSPLCommand {\n return new TSPLBitmapCommand(image, x, y, mode)\n }\n\n qrCode(content: string, width: number, x: number, y: number): TSPLCommand {\n const cellCount = this.cellCount(content)\n const cellWidth = Math.round(width / cellCount)\n // We start the content With A to indicate that our data is alphanumeric. \n // Not using auto ensures that we can easily calculate the cell with for a given content\n return new TSPLQRCommand(`A${content}`, x, y, cellWidth, 'H', \"M\")\n }\n \n barCode(content: string, x: number, y: number, type: BarcodeType, height: number, rotation: Rotation, humanReadable: BarcodeHumanReable, alignment: Alignment): TSPLCommand {\n return new TSPLBarcodeCommand(x, y, type, height, 1, 1, content, rotation, humanReadable, alignment)\n }\n\n private cellCount(content: string): number {\n const limits = Object.keys(QRLengthMapping).map( limit => Number(limit) ).sort((a, b) => a - b)\n const contentLength = content.length\n\n let i = 0\n while(limits[i] < contentLength && i < limits.length - 1) {\n i ++\n }\n\n return QRLengthMapping[limits[i] as keyof typeof QRLengthMapping]\n }\n}\n\nexport default new TSPLCommandGenerator()","export { default as Printer } from \"./Printer\"\nexport { PrinterService } from \"./PrinterService\"","import { Command, PrinterLanguage } from \"@/commands\";\nimport { LabelDirection } from \"@/commands/tspl\";\nimport { UsbDevice } from \"@/helpers/USBUtils\";\nimport { Label } from \"@/labels\"\n\n/**\n * Base class that encapsulates functionality of all printers\n */\nexport default abstract class Printer {\n private readonly usbDevice: UsbDevice\n\n /**\n * Printer language used by the type of printer the subclass represents\n */\n abstract get language(): PrinterLanguage\n\n /**\n * When called, it will feed the labels to the beginig of the next label\n */\n abstract feedLabel(): Promise<void>\n\n constructor(device: UsbDevice) {\n this.usbDevice = device\n }\n\n /**\n * Close the printer USB\n */\n async close() {\n await this.usbDevice.close()\n }\n\n /**\n * Prints a label\n * @param label \n */\n async print(label: Label, \n sets: number,\n gap: number, \n copiesPerSet: number = 1,\n direction: LabelDirection = \"normal\",\n mirror: boolean = false, \n gapOffset: number = 0) {\n const commands = await label.fullPrintCommand(this.language, gap, direction, sets, copiesPerSet, mirror, gapOffset)\n await this.writeCommand(commands)\n }\n\n /**\n * Display label on the printer's screen\n * @param label \n */\n async display(label: Label, direction: LabelDirection = \"normal\", mirror: boolean = false) {\n const command = await label.fullDisplayCommand(this.language, direction, mirror)\n await this.writeCommand(command)\n }\n\n /**\n * Writes a command to the printers usb\n * @param command Command to send to the usb\n */\n async writeCommand(command: Command): Promise<void> {\n if(!this.usbDevice.opened) await this.usbDevice.openAndConfigure()\n await command.write(this.usbDevice)\n }\n\n /**\n * Check if the device is indeed a printer\n * @param device \n */\n static try(_device: UsbDevice): Promise<boolean> {\n throw new Error(\"try(device:) should be implemented\")\n }\n}","/**\n * Collection of helpers to work with strings\n */\nexport default class StringUtils {\n /**\n * Convert string to utf8 array\n * @param str Convert string to byte array\n */\n toUTF8Array(str: string) {\n let utf8Encode = new TextEncoder();\n return utf8Encode.encode(str)\n }\n\n /**\n * Convert bytes to utf8 encoded string\n * @param bytes Bytes to decode\n * @returns A string\n */\n toString(bytes: Uint8Array|DataView) {\n let decoder = new TextDecoder()\n return decoder.decode(bytes)\n }\n}\n\nexport const isWhitespace = (text: string) => text.trim() === \"\"","import StringUtils from \"./StringUtils\";\n\nconst unsupportedUsbError = \"usb-unsupported\"\nconst stringHelper = new StringUtils()\n\nlet usbAgent: USB\n\n/**\n * @returns The appropiate USB agent based on the environment\n */\nconst getUSB = async (): Promise<USB> => {\n if(usbAgent) return usbAgent\n\n if(typeof window !== \"undefined\") {\n if(navigator.usb) {\n usbAgent = navigator.usb\n } else {\n throw unsupportedUsbError\n }\n } else {\n // TODO: Check how to avoid eval\n const { WebUSB } = eval(\"require\")(\"usb\")\n usbAgent = new WebUSB({allowAllDevices: true})\n }\n\n return usbAgent\n}\n\n/**\n * Returns the list of available devices\n * In node this returns all the connected devices but in the browser it will only return devices \n * that the user already gave permission to\n * @returns A list of available devices\n */\nexport const getDevices = async (): Promise<UsbDevice[]> => {\n const agent = await getUSB()\n const devices = await agent.getDevices()\n return devices.map(device => new UsbDevice(device) )\n}\n\n/**\n * In node, it returns the first available device, in the browser (supported browsers only) it shows \n * a UI for the user to choose a device\n * @returns The first available device\n */\nexport const requestDevice = async (): Promise<UsbDevice|undefined> => {\n const agent = await getUSB()\n const device = await agent.requestDevice({filters: []})\n if(device) {\n return new UsbDevice(device)\n } else {\n return undefined\n }\n}\n\n/**\n * Convenience wrapper for a web usb device\n * Its main purpose is to hide the details of the usb library from client code so in case\n * it needs to be switched, compatibility can be retained\n */\nexport class UsbDevice {\n private readonly device: USBDevice\n\n get opened() {\n return this.device.opened\n }\n\n /**\n * All available endpoints\n */\n private get endpoints() {\n return this.device.configuration?.interfaces[0].alternate.endpoints ?? []\n }\n\n /**\n * Endpoint for writing\n */\n private get outEndpoint() {\n return this.endpoints.find(e => e.direction == \"out\")?.endpointNumber\n }\n\n /**\n * Endpoint for reading\n */\n private get inEndpoint() {\n return this.endpoints.find(e => e.direction == \"in\")?.endpointNumber\n }\n\n constructor(device: USBDevice) {\n this.device = device\n }\n\n /**\n * Open the device and claim its interface\n */\n async openAndConfigure() {\n await this.device.open();\n await this.device.selectConfiguration(1);\n await this.device.claimInterface(0);\n }\n\n /**\n * Closes the device\n */\n async close() {\n await this.device.releaseInterface(0)\n await this.device.close()\n }\n\n /**\n * Write data to an USB device\n * @param data Data to write\n */\n async writeData(data: Uint8Array|ArrayBuffer): Promise<void> {\n const endpointNumber = this.outEndpoint\n await this.device.transferOut(endpointNumber!, data)\n }\n\n /**\n * Writes a text to a device\n * @param text Text to write\n */\n async writeString(text: string): Promise<void> {\n const bytes = stringHelper.toUTF8Array(text)\n await this.writeData(bytes)\n }\n\n /**\n * Reads bytes from the usb device\n * @param length The max length of the incoming data. \n * @returns Bytes received as a DataView or undefined. If data is longer then `length`, undefined will be returned\n */\n async readData(length: number): Promise<DataView|undefined> {\n const endpointNumber = this.inEndpoint\n const result = await this.device.transferIn(endpointNumber!, length)\n\n if(result.status == \"ok\" && result.data) {\n return result.data\n } else {\n return undefined\n }\n }\n\n /**\n * Reads data from the usb device and converts it to string\n * {@see readData}\n */\n async readString(length: number): Promise<string|undefined> {\n const bytes = await this.readData(length)\n if(bytes) return stringHelper.toString(bytes)\n return undefined\n }\n}\n","import { TSPLRawCommand } from \"@/commands/tspl\";\nimport { PrinterLanguage } from \"@/commands\"\nimport Printer from \"./Printer\";\nimport { UsbDevice } from \"@/helpers/USBUtils\";\n\nexport default class TSPLPrinter extends Printer {\n get language(): PrinterLanguage {\n return \"tspl\"\n }\n\n async feedLabel(): Promise<void> {\n const feedCommand = new TSPLRawCommand(\"FORMFEED\")\n await this.writeCommand(feedCommand)\n }\n\n static async try(device: UsbDevice): Promise<boolean> {\n if(!device.opened) await device.openAndConfigure()\n const testCommand = new TSPLRawCommand(\"~!I\")\n await testCommand.write(device)\n\n const response = await device.readString(64)\n await device.close()\n // If there is a response, we have a TSPL printer\n return !!response\n }\n}","import { UsbDevice, getDevices, requestDevice } from \"@/helpers/USBUtils\"\nimport TSPLPrinter from \"./TSPLPrinter\"\nimport Printer from \"./Printer\"\n\nexport class PrinterService {\n /**\n * Try each type of printer and return the one that mathces the usb device\n * @param device \n * @returns \n */\n static async printerForDevice(device: UsbDevice): Promise<Printer|undefined> {\n const classes = [TSPLPrinter]\n\n for (const key in classes) {\n if(await classes[key].try(device)) {\n return new classes[key](device)\n }\n }\n\n return undefined\n }\n\n /**\n * @returns List of available printers\n */\n static async getPrinters(): Promise<Printer[]> {\n const devices = await getDevices()\n const optionalPrinters = await Promise.all(devices.map(PrinterService.printerForDevice))\n return optionalPrinters.filter(printer => !!printer) as Printer[]\n }\n\n /**\n * This is intended to be used in the browser although it also works in node\n * In the browser, it provides a UI for the user to choose a USB device and if it is a\n * printer, it returns a new printer instance. In Node however, this will try to create\n * a printer for the first available device and returns it. This means that even if there is a \n * printer, it may return undefined. In node, use `getPrinters` instead\n */\n static async requestPrinter(): Promise<Printer|undefined> {\n const device = await requestDevice()\n if(device) {\n return PrinterService.printerForDevice(device)\n }\n }\n}","export { default as Label } from \"./Label\"\nexport * from \"./fields\"","import { Command, PrinterLanguage, tspl } from \"@/commands\";\nimport CommandGenerator from \"@/commands/CommandGenerator\";\nimport { Printer } from \"@/printers\";\nimport { FontOption } from \"./types\";\n\nexport type PrintConfig = {\n dpi: number,\n textWidth: (text: string, font: FontOption) => number,\n getFontName: (font: FontOption) => string\n}\n\n/**\n * A component that can be directly printed to label printer\n */\nexport default abstract class Printable {\n /**\n * Generates a printable command\n * @param language The printing language that should be used\n * @returns A promise of a command that can be printed\n */\n abstract commandForLanguage(language: PrinterLanguage, config?: PrintConfig): Promise<Command>\n\n /**\n * Generates printable command for the given printer. Can be used to obtain a command for fields supported by the package then customizing it before printing\n * @param printer Printer to generate the command. Important because the command is printer language specific\n * @returns A promise for a command. Most commands are syncronouse but some may require to access async resources\n */\n async commandForPrinter(printer: Printer, config?: PrintConfig): Promise<Command> {\n return await this.commandForLanguage(printer.language, config)\n }\n\n /**\n * Obtain a command generator for the given language\n * @param language Language to get generator for\n */\n protected commandGeneratorFor(language: PrinterLanguage): CommandGenerator<any> {\n switch(language) {\n case \"tspl\": return tspl.commandGenerator\n }\n }\n}","import { Command, PrinterLanguage } from \"@/commands\";\nimport Printable, { PrintConfig } from \"./Printable\";\nimport { UnitSystem } from \"@/commands\";\nimport { LabelDirection } from \"@/commands/tspl\";\nimport LabelField from \"./fields/LabelField\";\nimport { Font, FontFamily, FontOption, FontStyle, IndexedFontFamily, NamelessFont } from \"./types\";\nimport CommandGenerator from \"@/commands/CommandGenerator\";\nimport fontkit from \"fontkit\"\nimport { dotToPoint, pointsToDots } from \"@/helpers/UnitUtils\";\n\nconst DEFAULT_FONT_WEIGHT = 400\nconst DEFAULT_FONT_STYLE = \"normal\"\nconst FONT_PREFIX = \"f\"\n\n/**\n * Holds the content of a label and handles printing\n */\nexport default class Label extends Printable {\n /**\n * Width of label in dots, mm or inch\n */\n private readonly width: number\n /**\n * Height of label in dots, mm or inch\n */\n private readonly height: number\n\n /**\n * Units for width, height, gap and offset\n */\n private readonly unitSystem: UnitSystem\n private fonts: Record<string, IndexedFontFamily> = {}\n private dpi: number\n\n /**\n * List of fields on the label\n */\n private fields: LabelField[] = []\n private fontCounter = 0\n\n /**\n * Configuration used when generating commands\n */\n get printConfig(): PrintConfig {\n return { \n dpi: this.dpi,\n textWidth: (text, font) => {\n const size = dotToPoint(font.size, this.dpi)\n const fontObject = this.getIndexedFont(font).font\n \n const run = fontObject.layout(text)\n\n const scaledWidth = size * run.advanceWidth / fontObject.unitsPerEm\n return pointsToDots(scaledWidth, this.dpi)\n },\n getFontName: this.getFontName.bind(this)\n } \n }\n\n constructor(width: number, height: number, dimensionUnit: UnitSystem = \"metric\", dpi: number = 203) {\n super()\n this.width = width\n this.height = height\n this.unitSystem = dimensionUnit\n this.dpi = dpi\n }\n\n async commandForLanguage(language: PrinterLanguage, config?: PrintConfig): Promise<Command> {\n const commandList = await Promise.all(this.fields.map(field => field.commandForLanguage(language, config)))\n return this.commandGeneratorFor(language).commandGroup(commandList)\n }\n\n /**\n * Place fields to a label\n * @param fields \n */\n add(...fields: LabelField[]) {\n this.fields.push(...fields)\n }\n\n /**\n * Register a font to be used. Use the name provided in components to use the font. \n * For example: textField.setFont('myFont.ttf', 12)\n * @param file Font file. Can be a blob or a url\n * @param name Name to be used to reference the font\n */\n async registerFont(font: Omit<Font, \"font\">) {\n const key = this.fontKey(font.weight, font.style)\n\n if(!this.fonts[font.name]) {\n this.fonts[font.name] = {\n fonts: {}\n }\n }\n\n const fontBuffer = Buffer.from(font.data)\n this.fonts[font.name].fonts[key] = {\n ...font,\n font: fontkit.create(fontBuffer),\n alias: `${FONT_PREFIX}${this.fontCounter}.${this.fontExtension}`\n }\n this.fontCounter += 1\n }\n\n /**\n * Generate a command that is complete for printing\n * @param language Printing language to use\n * @param gap Distance between two labels. It is measured between the two points where the sensor \n * leaves the label and enters the next one\n * @param direction Direction relative to printing direction. See documentation for more details\n * @param sets Number of sets to print. If you have counters for example, it will not change in a set\n * @param copiesPerSet Number of labels per set\n * @param mirror Mirror the label along the vertical axis\n * @param gapOffset Used with non uniform shaped labels. Is the distance between the point where the sensor leaves the label and the \n * furthest point of the label in the direction of printing. Check documentation for more info\n * TODO: Is this too TSPL Specific?\n */\n async fullPrintCommand(language: PrinterLanguage, \n gap: number, \n direction: LabelDirection, \n sets: number, \n copiesPerSet: number = 1,\n mirror: boolean = false, \n gapOffset: number = 0\n ): Promise<Command> {\n\n const generator = this.commandGeneratorFor(language)\n const commands = await this.fullCommand(language, gap, direction, mirror, gapOffset, generator)\n commands.push(generator.print(sets, copiesPerSet))\n\n return generator.commandGroup(commands)\n }\n\n /**\n * Generate commands needed to display the label on the printer screen\n * @param language Printing language to use\n * @param direction Direction relative to printing direction. See documentation for more details\n * @param mirror Mirror the label along the vertical axis\n */\n async fullDisplayCommand(language: PrinterLanguage, direction: LabelDirection, mirror: boolean = false) {\n const generator = this.commandGeneratorFor(language)\n const commands = await this.fullCommand(language, 0, direction, mirror, 0, generator)\n commands.push(generator.display())\n \n const group = generator.commandGroup(commands)\n group.print(console.log)\n return group\n }\n\n /**\n * Helper function that generates common commands for print and display\n */\n private async fullCommand(language: PrinterLanguage, \n gap: number, \n direction: LabelDirection, \n mirror: boolean = false, \n gapOffset: number = 0, \n generator: CommandGenerator<any>) {\n const commands = [\n this.fontUploadCommands(generator),\n generator.setUp(this.width, this.height, gap, gapOffset, direction, mirror, this.unitSystem),\n (await this.commandForLanguage(language, this.printConfig)),\n ]\n return commands\n }\n\n private fontUploadCommands(generator: CommandGenerator<any>): Command {\n const families = Object.keys(this.fonts)\n const commands = families.flatMap(family => {\n const familyFonts = this.fonts[family].fonts\n const fontNames = Object.keys(familyFonts)\n\n return fontNames.map(name => {\n const font = familyFonts[name]\n const fileName = font.alias\n\n return generator.upload(fileName, font.data)\n })\n })\n\n return generator.commandGroup(commands)\n }\n\n private getIndexedFont(font: FontOption) {\n const family = this.fonts[font.name]\n\n const style = font.style ?? DEFAULT_FONT_STYLE\n const weigth = font.weight ?? DEFAULT_FONT_WEIGHT\n\n const fontKeys = Object.keys(family.fonts)\n const exactMatch = fontKeys.find(key => \n family.fonts[key].style == style &&\n family.fonts[key].weight == weigth\n )\n\n // If there is a font that matches exactly the requested one we return that\n // otherwise we find the one that is the closest in weight\n // if there is no font with the same style, we return the first normal font in the family\n if(exactMatch) {\n return family.fonts[exactMatch]\n } else {\n const sameStyleKeys = fontKeys.filter(key => family.fonts[key].style == style)\n\n if(sameStyleKeys.length > 0){\n let weigthDiff = 99999999\n let selectedKey = \"\"\n\n sameStyleKeys.forEach(key => {\n const diff = Math.abs(weigth - family.fonts[key].weight)\n if(diff < weigthDiff) {\n weigthDiff = diff\n selectedKey = key\n }\n })\n\n return family.fonts[selectedKey]\n } else {\n return family.fonts[fontKeys[0]]\n }\n }\n }\n\n private getFontName(font: FontOption) {\n // We don't access values directly passed in to make sure the font name we return exists\n const indexedFont = this.getIndexedFont(font)\n return indexedFont.alias\n // return this.getFontNameForIndexed({name: font.name, weight: indexedFont.weight, style: indexedFont.style})\n }\n\n /// This can be extended when we want support multiple fonts\n private get fontExtension() {\n return \"TTF\"\n }\n\n private fontKey(weight: number, style?: FontStyle) {\n return `${weight}${style ?? DEFAULT_FONT_STYLE}`\n }\n}","import Printable from \"../Printable\";\n\nexport default abstract class LabelField extends Printable {}","import { Command, Point, PrinterLanguage } from \"@/commands\";\nimport LabelField from \"./LabelField\";\n\n/**\n * Draws a line to the screen\n */\nexport default class Line extends LabelField {\n private readonly start: Point\n private readonly end: Point\n private readonly thickness: number\n\n /**\n * \n * @param start Start point of the line. Values are in dots\n * @param end End point of the line. Values are in dots\n * @param thickness Thickness of the line in dots \n */\n constructor(start: Point, end: Point, thickness: number = 3) {\n super()\n this.start = start\n this.end = end\n this.thickness = thickness\n }\n\n commandForLanguage(language: PrinterLanguage): Promise<Command> {\n return this.commandGeneratorFor(language).line(this.start, this.end, this.thickness)\n }\n}","import { Command, PrinterLanguage } from \"@/commands\"\nimport LabelField from \"./LabelField\"\nimport { PrintConfig } from \"../Printable\"\nimport { dotToPoint } from \"@/helpers/UnitUtils\"\nimport CommandGenerator from \"@/commands/CommandGenerator\"\nimport { isWhitespace } from \"@/helpers/StringUtils\"\nimport { NodeType, parse, HTMLElement, Node } from \"node-html-parser\"\nimport { FontOption } from \"../types\"\n\nexport type TextFieldType = \"singleline\"|\"multiline\"\ntype Context = {\n language: PrinterLanguage,\n generator: CommandGenerator<any>,\n config?: PrintConfig\n}\n\ntype TextDecoration = \"underline\"|\"strike\"\n\nconst BOLD_WEIGTH = 700\nconst BOLD_TAG = \"b\"\nconst ITALIC_TAG = \"i\"\nconst UNDERLINE_TAG = \"u\"\nconst STRIKE_TAG = \"s\"\n\n/**\n * Presents a piece of text on the label\n */\nexport default class Text extends LabelField {\n private readonly content: string\n /**\n * X coordinate in dots\n */\n private readonly x: number\n /**\n * Y coordinate in dots\n */\n private readonly y: number\n /**\n * If true, basic html elements will be interpretted, otherwise the raw string is printed out\n */\n private readonly formatted: boolean\n private font: FontOption = {name: \"default\", size: 10}\n private type: TextFieldType = \"singleline\"\n private context: Context|undefined = undefined\n private readonly lineSpacing = 1\n\n /**\n * Width of the text. \n * If set, the text will be clipped to this size\n * If the type is set to multiline, this is where the text is split to a newline\n */\n private width: number|undefined\n /**\n * Height of the text box, if empty and the type is multiline, the box can grow infinitely\n */\n private height: number|undefined\n \n constructor(content: string, x: number, y: number, formatted: boolean = true) {\n super()\n this.content = content.replace(\"\\n\", \"\") // Newline can break text generation\n this.x = x\n this.y = y\n this.formatted = formatted\n }\n\n /**\n * Sets the field to single line\n * @param width Max width of the text. Leave it undefined to allow the field to grow \n */\n setSingleLine(width?: number) {\n this.type = \"singleline\"\n this.width = width\n this.height = undefined\n }\n\n /**\n * Sets the field to multi line\n * @param width Max width of text before it gets wrapped to a new line\n * @param height Max height of the text box, leave undefined to allow the text box to grow infinitly\n */\n setMultiLine(width: number, height?: number) {\n this.type = \"multiline\"\n this.width = width\n this.height = height\n }\n\n /**\n * Set a font to use as a base. If no formatting is set on the text with a html tag, this will be used \n * Note: The font name either has to be a built in font on your printer or a font\n * that is registered on the label using 'registerFont'.\n */\n setFont(font: FontOption) {\n this.font = font\n }\n\n async commandForLanguage(language: PrinterLanguage, config?: PrintConfig): Promise<Command> {\n this.context = {\n config,\n language,\n generator: this.commandGeneratorFor(language)\n }\n\n let command: Command\n if(this.formatted) {\n command = this.generateFormattedText()\n } else {\n command = this.generatePlainText()\n }\n this.context = undefined\n \n return command\n }\n \n /**\n * Generate commands for formatted text\n * @returns \n */\n private generateFormattedText(): Command {\n if(!this.context) throw \"context-not-set\"\n \n const rootNode = parse(this.content)\n const { command } = this.generateFormattedRecursive(this.x, this.y, rootNode, this.font, [])\n return command\n }\n\n /**\n * Generate commands for plain text\n * @returns \n */\n private generatePlainText(): Command {\n const {command} = this.generatePlainTextCore(this.content, this.x, this.y, this.font)\n return command\n }\n\n /**\n * Iterats the nodes in a html text and generates text commands for it\n */\n private generateFormattedRecursive(initialX: number, initialY: number, rootNode: Node, font: FontOption, features: TextDecoration[]): {x: number, y: number, command: Command} {\n if(rootNode.nodeType == NodeType.TEXT_NODE) {\n const result = this.generatePlainTextCore(rootNode.innerText, initialX, initialY, font, features)\n return result\n } else {\n const elementNode = rootNode as HTMLElement\n const tag = elementNode.rawTagName\n\n let commands: Command[] = []\n let currentX = initialX\n let currentY = initialY\n\n let baseFont = {...font}\n let baseFeatures = [...features]\n \n if(tag == UNDERLINE_TAG) {\n baseFeatures.push(\"underline\")\n } else if(tag == STRIKE_TAG) {\n baseFeatures.push(\"strike\")\n } else if(tag == BOLD_TAG) {\n baseFont.weight = BOLD_WEIGTH\n } else if(tag == ITALIC_TAG) {\n baseFont.style = \"italic\"\n }\n\n elementNode.childNodes.forEach(node => {\n const {x,y,command} = this.generateFormattedRecursive(currentX, currentY, node, baseFont, baseFeatures )\n currentX = x\n currentY = y\n commands.push(command)\n })\n\n return {\n x: currentX,\n y: currentY,\n command: this.context!.generator.commandGroup(commands)\n }\n }\n }\n\n /**\n * Generate commands for plain text\n * @param config \n * @returns \n */\n private generatePlainTextCore(content: string, initialX: number, initialY: number, font: FontOption, features: TextDecoration[] = []): {x: number, y: number, command: Command} {\n if(!this.context) throw \"context-not-set\"\n\n const textWidhtFunction = this.textWithFunction\n let fullWidth = textWidhtFunction(content, font)\n\n if(this.width) {\n const initialPadding = initialX - this.x\n // Because we may start from further in the row, the first rows width may be smaller\n let rowWidth = this.width - initialPadding\n // In theory rowWidth should not be negative, but for some reson it happens.. as a quick work around we make sure it is not negative\n if(rowWidth <= 0) {\n rowWidth = this.width\n initialX = this.x\n initialY += font.size + this.lineSpacing\n }\n\n // Make sure we don't print spaces at the beginig of a row\n if(initialX == this.x) {\n content = content.trimStart()\n fullWidth = textWidhtFunction(content, font)\n }\n\n // We may not start from the begining of the textbox so we have to offset\n // by our current position\n if(fullWidth <= rowWidth) {\n return {\n x: initialX + fullWidth,\n y: initialY,\n command: this.textCommand(content, initialX, initialY, font, features)\n }\n } else {\n const commands: Command[] = []\n \n let x = initialX\n let y = initialY\n let remainingContent = content\n let remainingWidth = fullWidth\n let currentHeight = 0\n\n let finalX = x\n let finalY = y\n\n do {\n // This will be the last row of the text. \n if(remainingWidth < rowWidth) {\n finalX = x + remainingWidth\n finalY = y\n\n commands.push(this.textCommand(remainingContent, x, y, font, features))\n remainingContent = \"\"\n } else {\n // On how many rows this text would fit\n let rows = remainingWidth / rowWidth\n\n // From the second row, all rows are full width\n rowWidth = this.width\n // Which caracter is the last if dividing into the right number of rows\n let rowEndIndex = Math.floor(remainingContent.length / rows)\n let originalRowEndIndex = rowEndIndex\n\n // This means we have to fit a relatively short text into\n // a lot of rows which can only happen if the row width is very small\n // in this case, we have to go to a new line\n // This is used to avoid having to calculate the width of the first character of the current text, to compare with the remainig length\n if(rowEndIndex == 0) {\n x = this.x\n y += font.size + this.lineSpacing\n continue\n }\n\n // Scenario 1: Current index is in a middle of row\n // I am iron m@n\n // End this row with the last words last character\n\n // Scneraio 2: Current index is space:\n // I am iron@man\n // No action, but to simplify code, we threat as scenario 1\n\n // Scenario 3: Current index is right before a sapce\n // I am iro@ man\n // Start next row from the first latter\n\n // Find the end of the last word\n while(\n ! (\n !isWhitespace(remainingContent.charAt(rowEndIndex)) &&\n (\n rowEndIndex == remainingContent.length - 1 ||\n isWhitespace(remainingContent.charAt(rowEndIndex + 1))\n )\n ) && rowEndIndex > 0\n ) { rowEndIndex -- }\n\n let nextRowStartIndex = rowEndIndex + 1\n // We didn't find a space, we split the text wherever we land\n if(rowEndIndex == 0) {\n rowEndIndex = originalRowEndIndex\n nextRowStartIndex = originalRowEndIndex + 1\n } else {\n while(\n isWhitespace(remainingContent.charAt(nextRowStartIndex)) && \n nextRowStartIndex < remainingContent.length\n ) { nextRowStartIndex ++ }\n }\n\n const thisRow = remainingContent.substring(0, rowEndIndex + 1)\n commands.push(this.textCommand(thisRow, x, y, font, features))\n\n if(nextRowStartIndex == remainingContent.length) {\n finalX = x + remainingWidth\n finalY = y\n }\n\n // Make sure to move the cursor back to the left side of the text box\n // as we may have started further into the row\n x = this.x\n y += font.size + this.lineSpacing\n currentHeight = y - this.y\n\n remainingContent = remainingContent.substring(nextRowStartIndex)\n remainingWidth = textWidhtFunction(remainingContent, font)\n }\n } while(\n // We don't have a height constraint or we are still within bounds \n // and there is still content \n // and we are supporting multiline\n (this.height == undefined || (currentHeight + font.size) <= this.height) &&\n (remainingContent != \"\") &&\n this.type == \"multiline\"\n )\n return {\n x: finalX,\n y: finalY,\n command: this.context!.generator.commandGroup(commands)\n }\n }\n } else {\n return {\n x: initialX + fullWidth,\n y: initialY,\n command: this.textCommand(content, initialX, initialY, font, features)\n }\n }\n }\n\n private textCommand(text: string, x: number, y: number, font: FontOption, features: TextDecoration[]) {\n if(!this.context) throw \"no-context\"\n const finalFontSize = dotToPoint(font.size, this.context!.config?.dpi ?? 203)\n const finalFont = this.getFontName(font)\n const finalX = Math.round(x)\n const finalY = Math.round(y)\n\n let commands: Command[] = []\n const textCommand = this.context!.generator.text(text, finalX, finalY, finalFont, finalFontSize)\n\n if(features.length == 0) {\n return textCommand\n } else {\n let lineHeight = font.size * 0.1\n let textWidth = this.textWithFunction(text, font)\n\n if(features.includes(\"strike\")) {\n commands.push(this.textLineCommand(textWidth, x, y, lineHeight, 0.5, font.size))\n }\n\n if(features.includes(\"underline\")) {\n commands.push(this.textLineCommand(textWidth, x, y, lineHeight, 0.9, font.size))\n }\n\n commands.push(textCommand)\n }\n\n return this.context.generator.commandGroup(commands)\n }\n\n private textLineCommand(width: number, x: number, y: number, lineHeight: number, linePercentage: number, fontSize: number): Command {\n const sy = Math.round(y + (fontSize * linePercentage) - (lineHeight / 2))\n\n const sx = Math.round(x)\n return this.context!.generator.line(\n {x: sx, y: sy}, \n {x: sx + width, y: sy}, \n lineHeight)\n }\n\n private getFontName(font: FontOption) {\n if(!this.context) throw \"no-context\"\n if(font.name == \"default\") {\n return \"default\"\n } else {\n return this.context!.config?.getFontName(font)!\n }\n }\n\n private get textWithFunction() {\n if(this.font.name == \"default\") {\n return this.defaultTextWidth\n } else {\n return this.context?.config?.textWidth ?? this.defaultTextWidth\n }\n }\n\n /**\n * This function is used to calculate the font size if no\n * print config is provided. This will asume that the font has square characters\n */\n private defaultTextWidth(text: string, font: FontOption) {\n return text.length * font.size\n }\n}","import { Command, PrinterLanguage } from \"@/commands\";\nimport { PrintConfig } from \"../Printable\";\nimport LabelField from \"./LabelField\"\nimport { Alignment, BarcodeHumanReable, BarcodeType, Rotation } from \"@/commands/tspl\";\n\nexport default class BarCode extends LabelField {\n private readonly content: string\n private readonly x: number\n private readonly y: number\n private readonly type: BarcodeType\n private readonly height: number\n private rotation: Rotation\n private humanReadable: BarcodeHumanReable \n private readonly alignment: Alignment\n\n constructor(content: string, x: number, y: number, type: BarcodeType, height: number) {\n super()\n this.content = content\n this.x = x\n this.y = y\n this.type = type\n this.height = height\n this.rotation = 0\n this.humanReadable = \"none\"\n this.alignment = \"left\"\n }\n\n setRotation(rotation: Rotation) {\n this.rotation = rotation\n }\n\n setHumanReadable(humanReadable: BarcodeHumanReable) {\n this.humanReadable = humanReadable\n }\n\n async commandForLanguage(language: PrinterLanguage, _config?: PrintConfig | undefined): Promise<Command> {\n return await this.commandGeneratorFor(language).barCode(this.content, this.x, this.y, this.type, this.height, this.rotation, this.humanReadable, this.alignment)\n }\n}","import { Command, PrinterLanguage } from \"@/commands\";\nimport { PrintConfig } from \"../Printable\";\nimport LabelField from \"./LabelField\";\nimport ImageUtils, { BitmapLike } from \"@/helpers/ImageUtils\";\n\nexport default class Image extends LabelField {\n /**\n * X coordinate in dots\n */\n private readonly x: number\n /**\n * Y coordinate in dots\n */\n private readonly y: number\n\n private readonly image: BitmapLike\n\n constructor(x: number, y: number, image: BitmapLike) {\n super()\n this.x = x\n this.y = y\n this.image = image\n }\n\n async commandForLanguage(language: PrinterLanguage, _config?: PrintConfig | undefined): Promise<Command> {\n return await this.commandGeneratorFor(language).image(this.image, this.x, this.y)\n }\n\n /**\n * Create an image field for an image\n * @param image \n * @param x \n * @param y \n * @param width \n * @param height \n * @returns \n */\n static async create(image: string, x: number, y: number, width?: number, height?: number): Promise<Image> {\n const bitmap = await ImageUtils.getBWBitmap(image, width, height)\n\n return new Image(x, y, bitmap)\n }\n}","import { Command, PrinterLanguage } from \"@/commands\";\nimport { PrintConfig } from \"../Printable\";\nimport LabelField from \"./LabelField\";\n\nexport default class QRCode extends LabelField {\n private readonly content: string\n private readonly x: number\n private readonly y: number\n private readonly width: number\n\n constructor(content: string, x: number, y: number, width: number) {\n super()\n this.content = content\n this.x = x\n this.y = y\n this.width = width\n }\n\n async commandForLanguage(language: PrinterLanguage, config?: PrintConfig | undefined): Promise<Command> {\n return await this.commandGeneratorFor(language).qrCode(this.content, this.width, this.x, this.y)\n }\n}"],"mappings":"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","names":["pointsPerInch","pixels","fontkit"]}
|
package/dist/index.mjs
CHANGED
|
@@ -42,6 +42,14 @@ var __async = (__this, __arguments, generator) => {
|
|
|
42
42
|
});
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
+
// src/commands/index.ts
|
|
46
|
+
var commands_exports = {};
|
|
47
|
+
__export(commands_exports, {
|
|
48
|
+
Command: () => Command,
|
|
49
|
+
CommandGroup: () => CommandGroup,
|
|
50
|
+
tspl: () => tspl_exports
|
|
51
|
+
});
|
|
52
|
+
|
|
45
53
|
// src/commands/Command.ts
|
|
46
54
|
var Command = class {
|
|
47
55
|
print(fn) {
|
|
@@ -711,6 +719,13 @@ var TSPLCommandGenerator = class {
|
|
|
711
719
|
};
|
|
712
720
|
var TSPLCommandGenerator_default = new TSPLCommandGenerator();
|
|
713
721
|
|
|
722
|
+
// src/printers/index.ts
|
|
723
|
+
var printers_exports = {};
|
|
724
|
+
__export(printers_exports, {
|
|
725
|
+
Printer: () => Printer,
|
|
726
|
+
PrinterService: () => PrinterService
|
|
727
|
+
});
|
|
728
|
+
|
|
714
729
|
// src/printers/Printer.ts
|
|
715
730
|
var Printer = class {
|
|
716
731
|
constructor(device) {
|
|
@@ -985,6 +1000,17 @@ var PrinterService = class _PrinterService {
|
|
|
985
1000
|
}
|
|
986
1001
|
};
|
|
987
1002
|
|
|
1003
|
+
// src/labels/index.ts
|
|
1004
|
+
var labels_exports = {};
|
|
1005
|
+
__export(labels_exports, {
|
|
1006
|
+
BarCode: () => BarCode,
|
|
1007
|
+
Image: () => Image,
|
|
1008
|
+
Label: () => Label,
|
|
1009
|
+
Line: () => Line,
|
|
1010
|
+
Text: () => Text,
|
|
1011
|
+
qrCode: () => QRCode
|
|
1012
|
+
});
|
|
1013
|
+
|
|
988
1014
|
// src/labels/Printable.ts
|
|
989
1015
|
var Printable = class {
|
|
990
1016
|
/**
|
|
@@ -1556,16 +1582,8 @@ var QRCode = class extends LabelField {
|
|
|
1556
1582
|
}
|
|
1557
1583
|
};
|
|
1558
1584
|
export {
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
Image,
|
|
1563
|
-
Label,
|
|
1564
|
-
Line,
|
|
1565
|
-
Printer,
|
|
1566
|
-
PrinterService,
|
|
1567
|
-
Text,
|
|
1568
|
-
QRCode as qrCode,
|
|
1569
|
-
tspl_exports as tspl
|
|
1585
|
+
commands_exports as commands,
|
|
1586
|
+
labels_exports as labels,
|
|
1587
|
+
printers_exports as printers
|
|
1570
1588
|
};
|
|
1571
1589
|
//# sourceMappingURL=index.mjs.map
|