label-printer 0.10.0 → 0.11.0
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 +27 -6
- package/dist/index.d.ts +27 -6
- package/dist/index.js +224 -46
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +224 -46
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -97,11 +97,11 @@ type BWBitmap = BitmapLike;
|
|
|
97
97
|
interface CommandGenerator<T extends Command> {
|
|
98
98
|
commandGroup: (commands: T[]) => CommandGroup<T>;
|
|
99
99
|
print: (sets: number, copiesPerSet: number) => T;
|
|
100
|
-
text: (content: string, x: number, y: number, font: string | "default", size: number) => T;
|
|
100
|
+
text: (content: string, x: number, y: number, font: string | "default", size: number, rotation?: Rotation) => T;
|
|
101
101
|
upload: (name: string, data: ArrayBuffer | Uint8Array) => T;
|
|
102
102
|
line: (start: Point, end: Point, thickness: number) => T;
|
|
103
103
|
image: (image: BitmapLike, x: number, y: number, mode?: GraphicMode) => T;
|
|
104
|
-
qrCode: (content: string, width: number, x: number, y: number) => T;
|
|
104
|
+
qrCode: (content: string, width: number, x: number, y: number, rotation?: Rotation) => T;
|
|
105
105
|
barCode: (content: string, x: number, y: number, type: BarcodeType, height: number, rotation: Rotation, humanReadable: BarcodeHumanReable, alignment: Alignment, barWidth?: number) => T;
|
|
106
106
|
/**
|
|
107
107
|
* Should instruct the printer to display the image of the label on its screen instead of printing it
|
|
@@ -413,13 +413,13 @@ declare class TSPLDensityCommand extends TSPLCommand {
|
|
|
413
413
|
declare class TSPLCommandGenerator implements CommandGenerator<TSPLCommand> {
|
|
414
414
|
commandGroup(commands: TSPLCommand[]): TSPLCommandGroup;
|
|
415
415
|
print(sets: number, copiesPerSet: number): TSPLCommand;
|
|
416
|
-
text(content: string, x: number, y: number, font: string | "default", size: number): TSPLCommand;
|
|
416
|
+
text(content: string, x: number, y: number, font: string | "default", size: number, rotation?: Rotation): TSPLCommand;
|
|
417
417
|
upload(name: string, data: ArrayBuffer | Uint8Array): TSPLCommand;
|
|
418
418
|
setUp(width: number, height: number, gap: number, offset: number, direction: LabelDirection, mirror: boolean | undefined, unitSystem: UnitSystem, density: number): TSPLCommand;
|
|
419
419
|
display(): TSPLCommandGroup;
|
|
420
420
|
line(start: Point, end: Point, thickness: number): TSPLCommand;
|
|
421
421
|
image(image: BitmapLike, x: number, y: number, mode?: GraphicMode | undefined): TSPLCommand;
|
|
422
|
-
qrCode(content: string, width: number, x: number, y: number): TSPLCommand;
|
|
422
|
+
qrCode(content: string, width: number, x: number, y: number, rotation?: Rotation): TSPLCommand;
|
|
423
423
|
barCode(content: string, x: number, y: number, type: BarcodeType, height: number, rotation: Rotation, humanReadable: BarcodeHumanReable, alignment: Alignment, barWidth?: number): TSPLCommand;
|
|
424
424
|
/**
|
|
425
425
|
* Calculates the narrow and wide element widths for a barcode type based on the
|
|
@@ -670,6 +670,7 @@ declare class Text extends LabelField {
|
|
|
670
670
|
private readonly formatted;
|
|
671
671
|
private font;
|
|
672
672
|
private type;
|
|
673
|
+
private rotation;
|
|
673
674
|
private context;
|
|
674
675
|
private readonly lineSpacing;
|
|
675
676
|
/**
|
|
@@ -701,6 +702,21 @@ declare class Text extends LabelField {
|
|
|
701
702
|
* that is registered on the label using 'registerFont'.
|
|
702
703
|
*/
|
|
703
704
|
setFont(font: FontOption): void;
|
|
705
|
+
/**
|
|
706
|
+
* Set the rotation of the text field. All text commands in this field will be rotated.
|
|
707
|
+
* For multiline text, lines advance perpendicular to the character direction.
|
|
708
|
+
*/
|
|
709
|
+
setRotation(rotation: Rotation): void;
|
|
710
|
+
/** Advance cursor by `amount` along the character direction */
|
|
711
|
+
private advanceChar;
|
|
712
|
+
/** Advance to the next line (reset char axis, advance in line direction) */
|
|
713
|
+
private advanceLine;
|
|
714
|
+
/** How far into the current line the cursor is (for width constraint calc) */
|
|
715
|
+
private charOffset;
|
|
716
|
+
/** How many lines deep we are (for height constraint calc) */
|
|
717
|
+
private lineOffset;
|
|
718
|
+
/** Whether the cursor is at the start of its line (char axis at origin) */
|
|
719
|
+
private atLineStart;
|
|
704
720
|
commandForLanguage(language: PrinterLanguage, config?: PrintConfig): Promise<Command>;
|
|
705
721
|
/**
|
|
706
722
|
* Generate commands for formatted text
|
|
@@ -727,8 +743,9 @@ declare class Text extends LabelField {
|
|
|
727
743
|
private getFontName;
|
|
728
744
|
private get textWidthFunction();
|
|
729
745
|
/**
|
|
730
|
-
*
|
|
731
|
-
*
|
|
746
|
+
* Fallback width estimate when no font metrics are available.
|
|
747
|
+
* Uses the TSPL x-multiplication value (dotToPoint of the dot size) as
|
|
748
|
+
* the per-character width, which matches the rendered width of font "0".
|
|
732
749
|
*/
|
|
733
750
|
private defaultTextWidth;
|
|
734
751
|
}
|
|
@@ -768,7 +785,9 @@ declare class Image extends LabelField {
|
|
|
768
785
|
*/
|
|
769
786
|
private readonly y;
|
|
770
787
|
private readonly image;
|
|
788
|
+
private rotation;
|
|
771
789
|
constructor(x: number, y: number, image: BitmapLike);
|
|
790
|
+
setRotation(rotation: Rotation): void;
|
|
772
791
|
commandForLanguage(language: PrinterLanguage, _config?: PrintConfig | undefined): Promise<Command>;
|
|
773
792
|
/**
|
|
774
793
|
* Create an image field for an image
|
|
@@ -787,7 +806,9 @@ declare class QRCode extends LabelField {
|
|
|
787
806
|
private readonly x;
|
|
788
807
|
private readonly y;
|
|
789
808
|
private readonly width;
|
|
809
|
+
private rotation;
|
|
790
810
|
constructor(content: string, x: number, y: number, width: number);
|
|
811
|
+
setRotation(rotation: Rotation): void;
|
|
791
812
|
commandForLanguage(language: PrinterLanguage, config?: PrintConfig | undefined): Promise<Command>;
|
|
792
813
|
}
|
|
793
814
|
|
package/dist/index.d.ts
CHANGED
|
@@ -97,11 +97,11 @@ type BWBitmap = BitmapLike;
|
|
|
97
97
|
interface CommandGenerator<T extends Command> {
|
|
98
98
|
commandGroup: (commands: T[]) => CommandGroup<T>;
|
|
99
99
|
print: (sets: number, copiesPerSet: number) => T;
|
|
100
|
-
text: (content: string, x: number, y: number, font: string | "default", size: number) => T;
|
|
100
|
+
text: (content: string, x: number, y: number, font: string | "default", size: number, rotation?: Rotation) => T;
|
|
101
101
|
upload: (name: string, data: ArrayBuffer | Uint8Array) => T;
|
|
102
102
|
line: (start: Point, end: Point, thickness: number) => T;
|
|
103
103
|
image: (image: BitmapLike, x: number, y: number, mode?: GraphicMode) => T;
|
|
104
|
-
qrCode: (content: string, width: number, x: number, y: number) => T;
|
|
104
|
+
qrCode: (content: string, width: number, x: number, y: number, rotation?: Rotation) => T;
|
|
105
105
|
barCode: (content: string, x: number, y: number, type: BarcodeType, height: number, rotation: Rotation, humanReadable: BarcodeHumanReable, alignment: Alignment, barWidth?: number) => T;
|
|
106
106
|
/**
|
|
107
107
|
* Should instruct the printer to display the image of the label on its screen instead of printing it
|
|
@@ -413,13 +413,13 @@ declare class TSPLDensityCommand extends TSPLCommand {
|
|
|
413
413
|
declare class TSPLCommandGenerator implements CommandGenerator<TSPLCommand> {
|
|
414
414
|
commandGroup(commands: TSPLCommand[]): TSPLCommandGroup;
|
|
415
415
|
print(sets: number, copiesPerSet: number): TSPLCommand;
|
|
416
|
-
text(content: string, x: number, y: number, font: string | "default", size: number): TSPLCommand;
|
|
416
|
+
text(content: string, x: number, y: number, font: string | "default", size: number, rotation?: Rotation): TSPLCommand;
|
|
417
417
|
upload(name: string, data: ArrayBuffer | Uint8Array): TSPLCommand;
|
|
418
418
|
setUp(width: number, height: number, gap: number, offset: number, direction: LabelDirection, mirror: boolean | undefined, unitSystem: UnitSystem, density: number): TSPLCommand;
|
|
419
419
|
display(): TSPLCommandGroup;
|
|
420
420
|
line(start: Point, end: Point, thickness: number): TSPLCommand;
|
|
421
421
|
image(image: BitmapLike, x: number, y: number, mode?: GraphicMode | undefined): TSPLCommand;
|
|
422
|
-
qrCode(content: string, width: number, x: number, y: number): TSPLCommand;
|
|
422
|
+
qrCode(content: string, width: number, x: number, y: number, rotation?: Rotation): TSPLCommand;
|
|
423
423
|
barCode(content: string, x: number, y: number, type: BarcodeType, height: number, rotation: Rotation, humanReadable: BarcodeHumanReable, alignment: Alignment, barWidth?: number): TSPLCommand;
|
|
424
424
|
/**
|
|
425
425
|
* Calculates the narrow and wide element widths for a barcode type based on the
|
|
@@ -670,6 +670,7 @@ declare class Text extends LabelField {
|
|
|
670
670
|
private readonly formatted;
|
|
671
671
|
private font;
|
|
672
672
|
private type;
|
|
673
|
+
private rotation;
|
|
673
674
|
private context;
|
|
674
675
|
private readonly lineSpacing;
|
|
675
676
|
/**
|
|
@@ -701,6 +702,21 @@ declare class Text extends LabelField {
|
|
|
701
702
|
* that is registered on the label using 'registerFont'.
|
|
702
703
|
*/
|
|
703
704
|
setFont(font: FontOption): void;
|
|
705
|
+
/**
|
|
706
|
+
* Set the rotation of the text field. All text commands in this field will be rotated.
|
|
707
|
+
* For multiline text, lines advance perpendicular to the character direction.
|
|
708
|
+
*/
|
|
709
|
+
setRotation(rotation: Rotation): void;
|
|
710
|
+
/** Advance cursor by `amount` along the character direction */
|
|
711
|
+
private advanceChar;
|
|
712
|
+
/** Advance to the next line (reset char axis, advance in line direction) */
|
|
713
|
+
private advanceLine;
|
|
714
|
+
/** How far into the current line the cursor is (for width constraint calc) */
|
|
715
|
+
private charOffset;
|
|
716
|
+
/** How many lines deep we are (for height constraint calc) */
|
|
717
|
+
private lineOffset;
|
|
718
|
+
/** Whether the cursor is at the start of its line (char axis at origin) */
|
|
719
|
+
private atLineStart;
|
|
704
720
|
commandForLanguage(language: PrinterLanguage, config?: PrintConfig): Promise<Command>;
|
|
705
721
|
/**
|
|
706
722
|
* Generate commands for formatted text
|
|
@@ -727,8 +743,9 @@ declare class Text extends LabelField {
|
|
|
727
743
|
private getFontName;
|
|
728
744
|
private get textWidthFunction();
|
|
729
745
|
/**
|
|
730
|
-
*
|
|
731
|
-
*
|
|
746
|
+
* Fallback width estimate when no font metrics are available.
|
|
747
|
+
* Uses the TSPL x-multiplication value (dotToPoint of the dot size) as
|
|
748
|
+
* the per-character width, which matches the rendered width of font "0".
|
|
732
749
|
*/
|
|
733
750
|
private defaultTextWidth;
|
|
734
751
|
}
|
|
@@ -768,7 +785,9 @@ declare class Image extends LabelField {
|
|
|
768
785
|
*/
|
|
769
786
|
private readonly y;
|
|
770
787
|
private readonly image;
|
|
788
|
+
private rotation;
|
|
771
789
|
constructor(x: number, y: number, image: BitmapLike);
|
|
790
|
+
setRotation(rotation: Rotation): void;
|
|
772
791
|
commandForLanguage(language: PrinterLanguage, _config?: PrintConfig | undefined): Promise<Command>;
|
|
773
792
|
/**
|
|
774
793
|
* Create an image field for an image
|
|
@@ -787,7 +806,9 @@ declare class QRCode extends LabelField {
|
|
|
787
806
|
private readonly x;
|
|
788
807
|
private readonly y;
|
|
789
808
|
private readonly width;
|
|
809
|
+
private rotation;
|
|
790
810
|
constructor(content: string, x: number, y: number, width: number);
|
|
811
|
+
setRotation(rotation: Rotation): void;
|
|
791
812
|
commandForLanguage(language: PrinterLanguage, config?: PrintConfig | undefined): Promise<Command>;
|
|
792
813
|
}
|
|
793
814
|
|
package/dist/index.js
CHANGED
|
@@ -521,7 +521,6 @@ var ImageProcessor = class {
|
|
|
521
521
|
*/
|
|
522
522
|
static getImageDataNode(image2, _target) {
|
|
523
523
|
return __async(this, null, function* () {
|
|
524
|
-
console.log("Processing image in Node.js environment");
|
|
525
524
|
if (image2 instanceof Blob) {
|
|
526
525
|
throw new Error("Blob input not supported in Node.js environment. Use file path or data URL instead.");
|
|
527
526
|
}
|
|
@@ -690,7 +689,6 @@ var ImageProcessor = class {
|
|
|
690
689
|
*/
|
|
691
690
|
static parse(buffer2, extension) {
|
|
692
691
|
const normalizedExtension = extension.startsWith(".") ? extension.slice(1) : extension;
|
|
693
|
-
console.log(`Parsing image with extension: ${normalizedExtension}`);
|
|
694
692
|
if (normalizedExtension === "png") {
|
|
695
693
|
return parsePNG(buffer2);
|
|
696
694
|
} else if (normalizedExtension === "jpeg" || normalizedExtension === "jpg") {
|
|
@@ -1104,6 +1102,54 @@ ${widthBits} ${height}
|
|
|
1104
1102
|
fs.writeFileSync(filePath, bytes);
|
|
1105
1103
|
});
|
|
1106
1104
|
}
|
|
1105
|
+
/**
|
|
1106
|
+
* Rotate a BW bitmap by 90, 180 or 270 degrees clockwise.
|
|
1107
|
+
* The bitmap uses 0=black, 1=white with MSB-first packing.
|
|
1108
|
+
*/
|
|
1109
|
+
static rotateBWBitmap(bitmap2, rotation) {
|
|
1110
|
+
const srcWidthBytes = bitmap2.width;
|
|
1111
|
+
const srcWidthBits = srcWidthBytes * 8;
|
|
1112
|
+
const srcHeight = bitmap2.height;
|
|
1113
|
+
const src = bitmap2.bytes;
|
|
1114
|
+
const getBit = (col, row) => {
|
|
1115
|
+
const byteIndex = row * srcWidthBytes + (col >> 3);
|
|
1116
|
+
const bitIndex = 7 - (col & 7);
|
|
1117
|
+
return src[byteIndex] >> bitIndex & 1;
|
|
1118
|
+
};
|
|
1119
|
+
let dstWidthBits;
|
|
1120
|
+
let dstHeight;
|
|
1121
|
+
let getNewPixel;
|
|
1122
|
+
if (rotation === 90) {
|
|
1123
|
+
dstWidthBits = srcHeight;
|
|
1124
|
+
dstHeight = srcWidthBits;
|
|
1125
|
+
getNewPixel = (col, row) => getBit(srcWidthBits - 1 - row, col);
|
|
1126
|
+
} else if (rotation === 270) {
|
|
1127
|
+
dstWidthBits = srcHeight;
|
|
1128
|
+
dstHeight = srcWidthBits;
|
|
1129
|
+
getNewPixel = (col, row) => getBit(row, srcHeight - 1 - col);
|
|
1130
|
+
} else {
|
|
1131
|
+
dstWidthBits = srcWidthBits;
|
|
1132
|
+
dstHeight = srcHeight;
|
|
1133
|
+
getNewPixel = (col, row) => getBit(srcWidthBits - 1 - col, srcHeight - 1 - row);
|
|
1134
|
+
}
|
|
1135
|
+
const dstPad = dstWidthBits % 8 === 0 ? 0 : 8 - dstWidthBits % 8;
|
|
1136
|
+
const dstWidthBitsPadded = dstWidthBits + dstPad;
|
|
1137
|
+
const dstWidthBytes = dstWidthBitsPadded / 8;
|
|
1138
|
+
const dst = new Uint8Array(dstWidthBytes * dstHeight).fill(255);
|
|
1139
|
+
for (let row = 0; row < dstHeight; row++) {
|
|
1140
|
+
for (let col = 0; col < dstWidthBits; col++) {
|
|
1141
|
+
const bit = getNewPixel(col, row);
|
|
1142
|
+
const byteIndex = row * dstWidthBytes + (col >> 3);
|
|
1143
|
+
const mask = 1 << 7 - (col & 7);
|
|
1144
|
+
if (bit === 1) {
|
|
1145
|
+
dst[byteIndex] |= mask;
|
|
1146
|
+
} else {
|
|
1147
|
+
dst[byteIndex] &= ~mask & 255;
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
return { width: dstWidthBytes, height: dstHeight, bytes: dst };
|
|
1152
|
+
}
|
|
1107
1153
|
static dilateOnce(bitmap2) {
|
|
1108
1154
|
const widthBytes = bitmap2.width;
|
|
1109
1155
|
const widthBits = widthBytes * 8;
|
|
@@ -1509,9 +1555,9 @@ var TSPLCommandGenerator = class _TSPLCommandGenerator {
|
|
|
1509
1555
|
print(sets, copiesPerSet) {
|
|
1510
1556
|
return new TSPLPrintCommand(sets, copiesPerSet);
|
|
1511
1557
|
}
|
|
1512
|
-
text(content, x, y, font, size) {
|
|
1558
|
+
text(content, x, y, font, size, rotation) {
|
|
1513
1559
|
const fontName = font == "default" ? "0" : font;
|
|
1514
|
-
return new TSPLTextCommand(content, x, y, fontName, 0, size, size, "left");
|
|
1560
|
+
return new TSPLTextCommand(content, x, y, fontName, rotation != null ? rotation : 0, size, size, "left");
|
|
1515
1561
|
}
|
|
1516
1562
|
upload(name, data) {
|
|
1517
1563
|
return new TSPLDownload(name, data);
|
|
@@ -1538,10 +1584,10 @@ var TSPLCommandGenerator = class _TSPLCommandGenerator {
|
|
|
1538
1584
|
image(image2, x, y, mode) {
|
|
1539
1585
|
return new TSPLBitmapCommand(image2, x, y, mode);
|
|
1540
1586
|
}
|
|
1541
|
-
qrCode(content, width, x, y) {
|
|
1587
|
+
qrCode(content, width, x, y, rotation) {
|
|
1542
1588
|
const cellCount = this.cellCount(content);
|
|
1543
1589
|
const cellWidth = Math.round(width / cellCount);
|
|
1544
|
-
return new TSPLQRCommand(`A${content}`, x, y, cellWidth, "H", "M");
|
|
1590
|
+
return new TSPLQRCommand(`A${content}`, x, y, cellWidth, "H", "M", rotation != null ? rotation : 0);
|
|
1545
1591
|
}
|
|
1546
1592
|
barCode(content, x, y, type, height, rotation, humanReadable, alignment, barWidth = 2) {
|
|
1547
1593
|
const { narrow, wide } = _TSPLCommandGenerator.narrowWideFor(type, barWidth);
|
|
@@ -2679,6 +2725,7 @@ var Text = class extends LabelField {
|
|
|
2679
2725
|
super();
|
|
2680
2726
|
this.font = { name: "default", size: 10 };
|
|
2681
2727
|
this.type = "singleline";
|
|
2728
|
+
this.rotation = 0;
|
|
2682
2729
|
this.context = void 0;
|
|
2683
2730
|
this.lineSpacing = 1;
|
|
2684
2731
|
this.content = content.replace("\n", "").replace('"', '\\"');
|
|
@@ -2724,13 +2771,88 @@ var Text = class extends LabelField {
|
|
|
2724
2771
|
this.height = height;
|
|
2725
2772
|
}
|
|
2726
2773
|
/**
|
|
2727
|
-
* Set a font to use as a base. If no formatting is set on the text with a html tag, this will be used
|
|
2774
|
+
* Set a font to use as a base. If no formatting is set on the text with a html tag, this will be used
|
|
2728
2775
|
* Note: The font name either has to be a built in font on your printer or a font
|
|
2729
2776
|
* that is registered on the label using 'registerFont'.
|
|
2730
2777
|
*/
|
|
2731
2778
|
setFont(font) {
|
|
2732
2779
|
this.font = font;
|
|
2733
2780
|
}
|
|
2781
|
+
/**
|
|
2782
|
+
* Set the rotation of the text field. All text commands in this field will be rotated.
|
|
2783
|
+
* For multiline text, lines advance perpendicular to the character direction.
|
|
2784
|
+
*/
|
|
2785
|
+
setRotation(rotation) {
|
|
2786
|
+
this.rotation = rotation;
|
|
2787
|
+
}
|
|
2788
|
+
// --- Rotation-aware position helpers ---
|
|
2789
|
+
/** Advance cursor by `amount` along the character direction */
|
|
2790
|
+
advanceChar(x, y, amount) {
|
|
2791
|
+
switch (this.rotation) {
|
|
2792
|
+
case 0:
|
|
2793
|
+
return { x: x + amount, y };
|
|
2794
|
+
case 90:
|
|
2795
|
+
return { x, y: y + amount };
|
|
2796
|
+
// 90° CW: chars go downward
|
|
2797
|
+
case 180:
|
|
2798
|
+
return { x: x - amount, y };
|
|
2799
|
+
case 270:
|
|
2800
|
+
return { x, y: y - amount };
|
|
2801
|
+
}
|
|
2802
|
+
}
|
|
2803
|
+
/** Advance to the next line (reset char axis, advance in line direction) */
|
|
2804
|
+
advanceLine(x, y, lineHeight) {
|
|
2805
|
+
switch (this.rotation) {
|
|
2806
|
+
case 0:
|
|
2807
|
+
return { x: this.x, y: y + lineHeight };
|
|
2808
|
+
case 90:
|
|
2809
|
+
return { x: x - lineHeight, y: this.y };
|
|
2810
|
+
// 90° CW: lines stack leftward (-x)
|
|
2811
|
+
case 180:
|
|
2812
|
+
return { x: this.x, y: y - lineHeight };
|
|
2813
|
+
case 270:
|
|
2814
|
+
return { x: x + lineHeight, y: this.y };
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
/** How far into the current line the cursor is (for width constraint calc) */
|
|
2818
|
+
charOffset(x, y) {
|
|
2819
|
+
switch (this.rotation) {
|
|
2820
|
+
case 0:
|
|
2821
|
+
return x - this.x;
|
|
2822
|
+
case 90:
|
|
2823
|
+
return y - this.y;
|
|
2824
|
+
// 90° CW: char axis is +y
|
|
2825
|
+
case 180:
|
|
2826
|
+
return this.x - x;
|
|
2827
|
+
case 270:
|
|
2828
|
+
return this.y - y;
|
|
2829
|
+
}
|
|
2830
|
+
}
|
|
2831
|
+
/** How many lines deep we are (for height constraint calc) */
|
|
2832
|
+
lineOffset(x, y) {
|
|
2833
|
+
switch (this.rotation) {
|
|
2834
|
+
case 0:
|
|
2835
|
+
return y - this.y;
|
|
2836
|
+
case 90:
|
|
2837
|
+
return this.x - x;
|
|
2838
|
+
// 90° CW: line axis is -x
|
|
2839
|
+
case 180:
|
|
2840
|
+
return this.y - y;
|
|
2841
|
+
case 270:
|
|
2842
|
+
return x - this.x;
|
|
2843
|
+
}
|
|
2844
|
+
}
|
|
2845
|
+
/** Whether the cursor is at the start of its line (char axis at origin) */
|
|
2846
|
+
atLineStart(x, y) {
|
|
2847
|
+
switch (this.rotation) {
|
|
2848
|
+
case 0:
|
|
2849
|
+
case 180:
|
|
2850
|
+
return x === this.x;
|
|
2851
|
+
case 90:
|
|
2852
|
+
case 270:
|
|
2853
|
+
return y === this.y;
|
|
2854
|
+
}
|
|
2855
|
+
}
|
|
2734
2856
|
commandForLanguage(language, config) {
|
|
2735
2857
|
return __async(this, null, function* () {
|
|
2736
2858
|
this.context = {
|
|
@@ -2777,9 +2899,10 @@ var Text = class extends LabelField {
|
|
|
2777
2899
|
const elementNode = rootNode;
|
|
2778
2900
|
const tag = elementNode.rawTagName;
|
|
2779
2901
|
if (tag == BREAK_TAG) {
|
|
2902
|
+
const linePos = this.advanceLine(initialX, initialY, font.size + this.lineSpacing);
|
|
2780
2903
|
return {
|
|
2781
|
-
x:
|
|
2782
|
-
y:
|
|
2904
|
+
x: linePos.x,
|
|
2905
|
+
y: linePos.y,
|
|
2783
2906
|
command: this.context.generator.commandGroup([])
|
|
2784
2907
|
};
|
|
2785
2908
|
}
|
|
@@ -2798,9 +2921,10 @@ var Text = class extends LabelField {
|
|
|
2798
2921
|
baseFont.style = "italic";
|
|
2799
2922
|
}
|
|
2800
2923
|
if (tag == PARAGRAPH_TAG) {
|
|
2801
|
-
if (initialX
|
|
2802
|
-
|
|
2803
|
-
|
|
2924
|
+
if (!this.atLineStart(initialX, initialY)) {
|
|
2925
|
+
const linePos = this.advanceLine(initialX, initialY, baseFont.size + this.lineSpacing);
|
|
2926
|
+
currentX = linePos.x;
|
|
2927
|
+
currentY = linePos.y;
|
|
2804
2928
|
}
|
|
2805
2929
|
}
|
|
2806
2930
|
elementNode.childNodes.forEach((node) => {
|
|
@@ -2811,8 +2935,9 @@ var Text = class extends LabelField {
|
|
|
2811
2935
|
});
|
|
2812
2936
|
if (tag == PARAGRAPH_TAG) {
|
|
2813
2937
|
if (!this.endsWithBreak(elementNode)) {
|
|
2814
|
-
|
|
2815
|
-
|
|
2938
|
+
const linePos = this.advanceLine(currentX, currentY, baseFont.size + this.lineSpacing);
|
|
2939
|
+
currentX = linePos.x;
|
|
2940
|
+
currentY = linePos.y;
|
|
2816
2941
|
}
|
|
2817
2942
|
}
|
|
2818
2943
|
return {
|
|
@@ -2832,21 +2957,23 @@ var Text = class extends LabelField {
|
|
|
2832
2957
|
const textWidhtFunction = this.textWidthFunction;
|
|
2833
2958
|
let fullWidth = textWidhtFunction(content, font);
|
|
2834
2959
|
if (this.width) {
|
|
2835
|
-
const initialPadding = initialX
|
|
2960
|
+
const initialPadding = this.charOffset(initialX, initialY);
|
|
2836
2961
|
let rowWidth = this.width - initialPadding;
|
|
2837
2962
|
if (rowWidth <= 0) {
|
|
2838
2963
|
rowWidth = this.width;
|
|
2839
|
-
|
|
2840
|
-
|
|
2964
|
+
const linePos = this.advanceLine(initialX, initialY, font.size + this.lineSpacing);
|
|
2965
|
+
initialX = linePos.x;
|
|
2966
|
+
initialY = linePos.y;
|
|
2841
2967
|
}
|
|
2842
|
-
if (initialX
|
|
2968
|
+
if (this.atLineStart(initialX, initialY)) {
|
|
2843
2969
|
content = content.trimStart();
|
|
2844
2970
|
fullWidth = textWidhtFunction(content, font);
|
|
2845
2971
|
}
|
|
2846
2972
|
if (fullWidth <= rowWidth) {
|
|
2973
|
+
const end = this.advanceChar(initialX, initialY, fullWidth);
|
|
2847
2974
|
return {
|
|
2848
|
-
x:
|
|
2849
|
-
y:
|
|
2975
|
+
x: end.x,
|
|
2976
|
+
y: end.y,
|
|
2850
2977
|
command: this.textCommand(content, initialX, initialY, font, features)
|
|
2851
2978
|
};
|
|
2852
2979
|
} else {
|
|
@@ -2860,8 +2987,9 @@ var Text = class extends LabelField {
|
|
|
2860
2987
|
let finalY = y;
|
|
2861
2988
|
do {
|
|
2862
2989
|
if (remainingWidth < rowWidth) {
|
|
2863
|
-
|
|
2864
|
-
|
|
2990
|
+
const end = this.advanceChar(x, y, remainingWidth);
|
|
2991
|
+
finalX = end.x;
|
|
2992
|
+
finalY = end.y;
|
|
2865
2993
|
commands.push(this.textCommand(remainingContent, x, y, font, features));
|
|
2866
2994
|
remainingContent = "";
|
|
2867
2995
|
} else {
|
|
@@ -2879,8 +3007,9 @@ var Text = class extends LabelField {
|
|
|
2879
3007
|
let originalRowEndIndex = rowEndIndex;
|
|
2880
3008
|
rowWidth = this.width;
|
|
2881
3009
|
if (rowEndIndex < 0) {
|
|
2882
|
-
|
|
2883
|
-
|
|
3010
|
+
const linePos2 = this.advanceLine(x, y, font.size + this.lineSpacing);
|
|
3011
|
+
x = linePos2.x;
|
|
3012
|
+
y = linePos2.y;
|
|
2884
3013
|
continue;
|
|
2885
3014
|
}
|
|
2886
3015
|
while (!(!isWhitespace(remainingContent.charAt(rowEndIndex)) && (rowEndIndex == remainingContent.length - 1 || isWhitespace(remainingContent.charAt(rowEndIndex + 1))) || isBreakAfterChar(remainingContent.charAt(rowEndIndex))) && rowEndIndex > 0) {
|
|
@@ -2958,12 +3087,14 @@ var Text = class extends LabelField {
|
|
|
2958
3087
|
const thisRow = remainingContent.substring(0, rowEndIndex + 1);
|
|
2959
3088
|
commands.push(this.textCommand(thisRow, x, y, font, features));
|
|
2960
3089
|
if (nextRowStartIndex == remainingContent.length) {
|
|
2961
|
-
|
|
2962
|
-
|
|
3090
|
+
const end = this.advanceChar(x, y, remainingWidth);
|
|
3091
|
+
finalX = end.x;
|
|
3092
|
+
finalY = end.y;
|
|
2963
3093
|
}
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
3094
|
+
const linePos = this.advanceLine(x, y, font.size + this.lineSpacing);
|
|
3095
|
+
x = linePos.x;
|
|
3096
|
+
y = linePos.y;
|
|
3097
|
+
currentHeight = this.lineOffset(x, y);
|
|
2967
3098
|
remainingContent = remainingContent.substring(nextRowStartIndex);
|
|
2968
3099
|
remainingWidth = textWidhtFunction(remainingContent, font);
|
|
2969
3100
|
}
|
|
@@ -2980,9 +3111,10 @@ var Text = class extends LabelField {
|
|
|
2980
3111
|
};
|
|
2981
3112
|
}
|
|
2982
3113
|
} else {
|
|
3114
|
+
const end = this.advanceChar(initialX, initialY, fullWidth);
|
|
2983
3115
|
return {
|
|
2984
|
-
x:
|
|
2985
|
-
y:
|
|
3116
|
+
x: end.x,
|
|
3117
|
+
y: end.y,
|
|
2986
3118
|
command: this.textCommand(content, initialX, initialY, font, features)
|
|
2987
3119
|
};
|
|
2988
3120
|
}
|
|
@@ -2995,7 +3127,7 @@ var Text = class extends LabelField {
|
|
|
2995
3127
|
const finalX = Math.round(x);
|
|
2996
3128
|
const finalY = Math.round(y);
|
|
2997
3129
|
let commands = [];
|
|
2998
|
-
const textCommand = this.context.generator.text(text, finalX, finalY, finalFont, finalFontSize);
|
|
3130
|
+
const textCommand = this.context.generator.text(text, finalX, finalY, finalFont, finalFontSize, this.rotation);
|
|
2999
3131
|
if (features.length == 0) {
|
|
3000
3132
|
return textCommand;
|
|
3001
3133
|
} else {
|
|
@@ -3012,13 +3144,28 @@ var Text = class extends LabelField {
|
|
|
3012
3144
|
return this.context.generator.commandGroup(commands);
|
|
3013
3145
|
}
|
|
3014
3146
|
textLineCommand(width, x, y, lineHeight, linePercentage, fontSize) {
|
|
3015
|
-
const
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3147
|
+
const offset = Math.round(fontSize * linePercentage - lineHeight / 2);
|
|
3148
|
+
let start;
|
|
3149
|
+
let end;
|
|
3150
|
+
switch (this.rotation) {
|
|
3151
|
+
case 0:
|
|
3152
|
+
start = { x: Math.round(x), y: Math.round(y) + offset };
|
|
3153
|
+
end = { x: Math.round(x) + Math.round(width), y: start.y };
|
|
3154
|
+
break;
|
|
3155
|
+
case 90:
|
|
3156
|
+
start = { x: Math.round(x) - offset, y: Math.round(y) };
|
|
3157
|
+
end = { x: start.x, y: Math.round(y) + Math.round(width) };
|
|
3158
|
+
break;
|
|
3159
|
+
case 180:
|
|
3160
|
+
start = { x: Math.round(x), y: Math.round(y) - offset };
|
|
3161
|
+
end = { x: Math.round(x) - Math.round(width), y: start.y };
|
|
3162
|
+
break;
|
|
3163
|
+
case 270:
|
|
3164
|
+
start = { x: Math.round(x) + offset, y: Math.round(y) };
|
|
3165
|
+
end = { x: start.x, y: Math.round(y) - Math.round(width) };
|
|
3166
|
+
break;
|
|
3167
|
+
}
|
|
3168
|
+
return this.context.generator.line(start, end, lineHeight);
|
|
3022
3169
|
}
|
|
3023
3170
|
getFontName(font) {
|
|
3024
3171
|
var _a;
|
|
@@ -3032,17 +3179,20 @@ var Text = class extends LabelField {
|
|
|
3032
3179
|
get textWidthFunction() {
|
|
3033
3180
|
var _a, _b, _c;
|
|
3034
3181
|
if (this.font.name == "default") {
|
|
3035
|
-
return this.defaultTextWidth;
|
|
3182
|
+
return (text, font) => this.defaultTextWidth(text, font);
|
|
3036
3183
|
} else {
|
|
3037
|
-
return (_c = (_b = (_a = this.context) == null ? void 0 : _a.config) == null ? void 0 : _b.textWidth) != null ? _c : this.defaultTextWidth;
|
|
3184
|
+
return (_c = (_b = (_a = this.context) == null ? void 0 : _a.config) == null ? void 0 : _b.textWidth) != null ? _c : (text, font) => this.defaultTextWidth(text, font);
|
|
3038
3185
|
}
|
|
3039
3186
|
}
|
|
3040
3187
|
/**
|
|
3041
|
-
*
|
|
3042
|
-
*
|
|
3188
|
+
* Fallback width estimate when no font metrics are available.
|
|
3189
|
+
* Uses the TSPL x-multiplication value (dotToPoint of the dot size) as
|
|
3190
|
+
* the per-character width, which matches the rendered width of font "0".
|
|
3043
3191
|
*/
|
|
3044
3192
|
defaultTextWidth(text, font) {
|
|
3045
|
-
|
|
3193
|
+
var _a, _b, _c;
|
|
3194
|
+
const dpi = (_c = (_b = (_a = this.context) == null ? void 0 : _a.config) == null ? void 0 : _b.dpi) != null ? _c : 203;
|
|
3195
|
+
return text.length * dotToPoint(font.size, dpi);
|
|
3046
3196
|
}
|
|
3047
3197
|
};
|
|
3048
3198
|
|
|
@@ -3086,13 +3236,37 @@ var BarCode = class extends LabelField {
|
|
|
3086
3236
|
var Image2 = class _Image extends LabelField {
|
|
3087
3237
|
constructor(x, y, image2) {
|
|
3088
3238
|
super();
|
|
3239
|
+
this.rotation = 0;
|
|
3089
3240
|
this.x = x;
|
|
3090
3241
|
this.y = y;
|
|
3091
3242
|
this.image = image2;
|
|
3092
3243
|
}
|
|
3244
|
+
setRotation(rotation) {
|
|
3245
|
+
this.rotation = rotation;
|
|
3246
|
+
}
|
|
3093
3247
|
commandForLanguage(language, _config) {
|
|
3094
3248
|
return __async(this, null, function* () {
|
|
3095
|
-
|
|
3249
|
+
if (this.rotation === 0) {
|
|
3250
|
+
return yield this.commandGeneratorFor(language).image(this.image, this.x, this.y);
|
|
3251
|
+
}
|
|
3252
|
+
const srcW = this.image.width * 8;
|
|
3253
|
+
const srcH = this.image.height;
|
|
3254
|
+
const bitmap2 = ImageUtils.rotateBWBitmap(this.image, 360 - this.rotation);
|
|
3255
|
+
let dx = this.x;
|
|
3256
|
+
let dy = this.y;
|
|
3257
|
+
switch (this.rotation) {
|
|
3258
|
+
case 90:
|
|
3259
|
+
dx = this.x - srcH;
|
|
3260
|
+
break;
|
|
3261
|
+
case 180:
|
|
3262
|
+
dx = this.x - srcW;
|
|
3263
|
+
dy = this.y - srcH;
|
|
3264
|
+
break;
|
|
3265
|
+
case 270:
|
|
3266
|
+
dy = this.y - srcW;
|
|
3267
|
+
break;
|
|
3268
|
+
}
|
|
3269
|
+
return yield this.commandGeneratorFor(language).image(bitmap2, dx, dy);
|
|
3096
3270
|
});
|
|
3097
3271
|
}
|
|
3098
3272
|
/**
|
|
@@ -3116,14 +3290,18 @@ var Image2 = class _Image extends LabelField {
|
|
|
3116
3290
|
var QRCode = class extends LabelField {
|
|
3117
3291
|
constructor(content, x, y, width) {
|
|
3118
3292
|
super();
|
|
3293
|
+
this.rotation = 0;
|
|
3119
3294
|
this.content = content;
|
|
3120
3295
|
this.x = x;
|
|
3121
3296
|
this.y = y;
|
|
3122
3297
|
this.width = width;
|
|
3123
3298
|
}
|
|
3299
|
+
setRotation(rotation) {
|
|
3300
|
+
this.rotation = rotation;
|
|
3301
|
+
}
|
|
3124
3302
|
commandForLanguage(language, config) {
|
|
3125
3303
|
return __async(this, null, function* () {
|
|
3126
|
-
return yield this.commandGeneratorFor(language).qrCode(this.content, this.width, this.x, this.y);
|
|
3304
|
+
return yield this.commandGeneratorFor(language).qrCode(this.content, this.width, this.x, this.y, this.rotation);
|
|
3127
3305
|
});
|
|
3128
3306
|
}
|
|
3129
3307
|
};
|