diff --git a/src/app/barcode-data-matrix/barcode-data-matrix.component.ts b/src/app/barcode-data-matrix/barcode-data-matrix.component.ts
index 929e004..00fa93a 100644
--- a/src/app/barcode-data-matrix/barcode-data-matrix.component.ts
+++ b/src/app/barcode-data-matrix/barcode-data-matrix.component.ts
@@ -1,6 +1,7 @@
import {AfterViewInit, Component, Input, OnInit} from '@angular/core';
import bwipjs from 'bwip-js';
import {AppDefaults} from '../models/appDefaults.interface';
+import DrawingSVG from './draw-svg.js';
@Component({
selector: 'app-barcode-data-matrix',
@@ -21,7 +22,7 @@ export class BarcodeDataMatrixComponent implements OnInit {
renderBarcode(): void {
if (!!(bwipjs && bwipjs.toCanvas && this.settings && this.format)) {
- bwipjs.toCanvas('barcodeCanvas', {
+ const opts = {
bcid: this.format,
text: this.value,
scale: 1,
@@ -31,7 +32,9 @@ export class BarcodeDataMatrixComponent implements OnInit {
// textalign: 'center',
// version: '12x64',
// padding: this.settings.labelLayout.marginSize,
- });
+ };
+ const barcodeSVG = bwipjs.render(opts, DrawingSVG(opts), bwipjs.FontLib);
+ // bwipjs.toCanvas('barcodeCanvas', );
}
}
}
diff --git a/src/app/barcode-data-matrix/draw-svg.js b/src/app/barcode-data-matrix/draw-svg.js
new file mode 100644
index 0000000..c812826
--- /dev/null
+++ b/src/app/barcode-data-matrix/draw-svg.js
@@ -0,0 +1,270 @@
+// bwip-js/examples/drawing-svg.js
+//
+// This is an advanced demonstation of using the drawing interface.
+//
+// It converts the drawing primitives into the equivalent SVG. Linear barcodes
+// are rendered as a series of stroked paths. 2D barcodes are rendered as a
+// series of filled paths.
+//
+// Rotation is handled during drawing. The resulting SVG will contain the
+// already-rotated barcode without an SVG transform.
+//
+// If the requested barcode image contains text, the glyph paths are
+// extracted from the font file (via the builtin FontLib and stb_truetype.js)
+// and added as filled SVG paths.
+//
+// This code can run in the browser and in nodejs.
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ define([], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ module.exports = factory();
+ } else {
+ root.DrawingSVG = factory();
+ }
+}(typeof self !== 'undefined' ? self : this, function () {
+"use strict";
+
+function DrawingSVG(opts, FontLib) {
+ // Unrolled x,y rotate/translate matrix
+ var tx0 = 0, tx1 = 0, tx2 = 0, tx3 = 0;
+ var ty0 = 0, ty1 = 0, ty2 = 0, ty3 = 0;
+
+ var svg = '';
+ var path;
+ var lines = {};
+
+ // Magic number to approximate an ellipse/circle using 4 cubic beziers.
+ var ELLIPSE_MAGIC = 0.55228475 - 0.00045;
+
+ // Global graphics state
+ var gs_width, gs_height; // image size, in pixels
+ var gs_dx, gs_dy; // x,y translate (padding)
+
+ return {
+ // Make no adjustments
+ scale(sx, sy) {
+ },
+ // Measure text. This and scale() are the only drawing primitives that
+ // are called before init().
+ //
+ // `font` is the font name typically OCR-A or OCR-B.
+ // `fwidth` and `fheight` are the requested font cell size. They will
+ // usually be the same, except when the scaling is not symetric.
+ measure(str, font, fwidth, fheight) {
+ fwidth = fwidth|0;
+ fheight = fheight|0;
+
+ var fontid = FontLib.lookup(font);
+ var width = 0;
+ var ascent = 0;
+ var descent = 0;
+ for (var i = 0; i < str.length; i++) {
+ var ch = str.charCodeAt(i);
+ var glyph = FontLib.getpaths(fontid, ch, fwidth, fheight);
+ if (!glyph) {
+ continue;
+ }
+ ascent = Math.max(ascent, glyph.ascent);
+ descent = Math.max(descent, -glyph.descent);
+ width += glyph.advance;
+ }
+ return { width, ascent, descent };
+ },
+
+ // width and height represent the maximum bounding box the graphics will occupy.
+ // The dimensions are for an unrotated rendering. Adjust as necessary.
+ init(width, height) {
+ // Add in the effects of padding. These are always set before the
+ // drawing constructor is called.
+ var padl = opts.paddingleft;
+ var padr = opts.paddingright;
+ var padt = opts.paddingtop;
+ var padb = opts.paddingbottom;
+ var rot = opts.rotate || 'N';
+
+ width += padl + padr;
+ height += padt + padb;
+
+ // Transform indexes are: x, y, w, h
+ switch (rot) {
+ // tx = w-y, ty = x
+ case 'R': tx1 = -1; tx2 = 1; ty0 = 1; break;
+ // tx = w-x, ty = h-y
+ case 'I': tx0 = -1; tx2 = 1; ty1 = -1; ty3 = 1; break;
+ // tx = y, ty = h-x
+ case 'L': tx1 = 1; ty0 = -1; ty3 = 1; break;
+ // tx = x, ty = y
+ default: tx0 = ty1 = 1; break;
+ }
+
+ // Setup the graphics state
+ var swap = rot == 'L' || rot == 'R';
+ gs_width = swap ? height : width;
+ gs_height = swap ? width : height;
+ gs_dx = padl;
+ gs_dy = padt;
+
+ svg = '';
+ },
+ // Unconnected stroked lines are used to draw the bars in linear barcodes.
+ // No line cap should be applied. These lines are always orthogonal.
+ line(x0, y0, x1, y1, lw, rgb) {
+ // Try to get non-blurry lines...
+ x0 = x0|0;
+ y0 = y0|0;
+ x1 = x1|0;
+ y1 = y1|0;
+ lw = Math.round(lw);
+
+ // Try to keep the lines "crisp" by using with the SVG line drawing spec to
+ // our advantage.
+ if (lw & 1) {
+ if (x0 == x1) {
+ x0 += 0.5;
+ x1 += 0.5;
+ }
+ if (y0 == y1) {
+ y0 += 0.5;
+ y1 += 0.5;
+ }
+ }
+
+ // Group together all lines of the same width and emit as single paths.
+ // Dramatically reduces resulting text size.
+ var key = '' + lw + '#' + rgb;
+ if (!lines[key]) {
+ lines[key] = '\n';
+ path = null;
+ }
+ },
+ // Draw text with optional inter-character spacing. `y` is the baseline.
+ // font is an object with properties { name, width, height, dx }
+ // width and height are the font cell size.
+ // dx is extra space requested between characters (usually zero).
+ text(x, y, str, rgb, font) {
+ var fontid = FontLib.lookup(font.name);
+ var fwidth = font.width|0;
+ var fheight = font.height|0;
+ var dx = font.dx|0;
+ var path = '';
+ for (var k = 0; k < str.length; k++) {
+ var ch = str.charCodeAt(k);
+ var glyph = FontLib.getpaths(fontid, ch, fwidth, fheight);
+ if (!glyph) {
+ continue;
+ }
+ if (glyph.length) {
+ // A glyph is composed of sequence of curve and line segments.
+ // M is move-to
+ // L is line-to
+ // Q is quadratic bezier curve-to
+ // C is cubic bezier curve-to
+ for (var i = 0, l = glyph.length; i < l; i++) {
+ let seg = glyph[i];
+ if (seg.type == 'M' || seg.type == 'L') {
+ path += seg.type + transform(seg.x + x, y - seg.y);
+ } else if (seg.type == 'Q') {
+ path += seg.type + transform(seg.cx + x, y - seg.cy) + ' ' +
+ transform(seg.x + x, y - seg.y);
+ } else if (seg.type == 'C') {
+ path += seg.type + transform(seg.cx1 + x, y - seg.cy1) + ' ' +
+ transform(seg.cx2 + x, y - seg.cy2) + ' ' +
+ transform(seg.x + x, y - seg.y);
+ }
+ }
+ // Close the shape
+ path += 'Z';
+ }
+ x += glyph.advance + dx;
+ }
+ if (path) {
+ svg += '\n';
+ }
+ },
+ // Called after all drawing is complete. The return value from this method
+ // is the return value from `bwipjs.render()`.
+ end() {
+ var linesvg = '';
+ for (var key in lines) {
+ linesvg += lines[key] + '" />\n';
+ }
+ var bg = opts.backgroundcolor;
+ return '\n';
+ },
+ };
+
+ // translate/rotate and return as an SVG coordinate pair
+ function transform(x, y) {
+ x += gs_dx;
+ y += gs_dy;
+ var tx = tx0 * x + tx1 * y + tx2 * (gs_width-1) + tx3 * (gs_height-1);
+ var ty = ty0 * x + ty1 * y + ty2 * (gs_width-1) + ty3 * (gs_height-1);
+ return '' + ((tx|0) == tx ? tx : tx.toFixed(2)) + ' ' +
+ ((ty|0) == ty ? ty : ty.toFixed(2));
+ }
+}
+
+return DrawingSVG;
+}));
diff --git a/src/app/config/defaults.ts b/src/app/config/defaults.ts
index 65a03b5..a9d3b6e 100644
--- a/src/app/config/defaults.ts
+++ b/src/app/config/defaults.ts
@@ -2,10 +2,10 @@ import {AppDefaultsOptions} from '../models/appDefaults.interface';
import {LabelLayout} from '../models/labelLayout.interface';
export const labelLayouts = {
- round_32mm_1up: new LabelLayout({
- name: '32mm Round Label - 1up',
+ circle_1up_32mm_x_32mm_qrcode: new LabelLayout({
+ name: '32mm Round Label - QR Code (1up)',
barcodeType: 'qrcode',
- type: 'round_32mm_1up',
+ type: 'circle_1up_32mm_x_32mm_qrcode',
numCols: 1,
columnGap: 0,
barcodeWidth: 28.6,
@@ -14,10 +14,10 @@ export const labelLayouts = {
topTextMargin: 0,
bottomTextMargin: 0,
}),
- round_32mm_2up: new LabelLayout({
- name: '32mm Round Label - 2up',
+ circle_2up_32mm_x_32mm_qrcode: new LabelLayout({
+ name: '32mm Round Label - QR Code (2up)',
barcodeType: 'qrcode',
- type: 'round_32mm_2up',
+ type: 'circle_2up_64mm_x_32mm_qrcode',
numCols: 2,
columnGap: 3.4,
barcodeWidth: 28.6,
@@ -26,10 +26,10 @@ export const labelLayouts = {
topTextMargin: 0,
bottomTextMargin: 0,
}),
- rectangular_54x32: new LabelLayout({
- name: '2in x 1.25in Rectangular Label',
- barcodeType: 'datamatrix',
- type: 'rectangular_54x32',
+ rectangular_54mm_x_34mm_code128: new LabelLayout({
+ name: '2in x 1.25in Rectangular Label - CODE128',
+ barcodeType: 'code128',
+ type: 'rectangular_54mm_x_34mm_code128',
numCols: 1,
columnGap: 0,
columnWidth: 54,
@@ -40,35 +40,38 @@ export const labelLayouts = {
topTextMargin: 0,
bottomTextMargin: 0,
}),
- rectangular_sm: new LabelLayout({
- name: '96mm x 15mm Rectangular Label',
+ rectangular_54mm_x_34mm_datamatrix: new LabelLayout({
+ name: '2in x 1.25in Rectangular Label - DataMatrix',
barcodeType: 'datamatrix',
- type: 'rectangular_sm',
+ type: 'rectangular_54mm_x_34mm_datamatrix',
numCols: 1,
columnGap: 0,
- barcodeWidth: 32,
- barcodeHeight: 16,
- marginSize: 6,
- sideTextMargin: 2,
- topTextMargin: 3,
- bottomTextMargin: 3,
+ columnWidth: 54,
+ columnHeight: 34,
+ barcodeWidth: 10,
+ barcodeHeight: 10,
+ sideTextMargin: 0,
+ topTextMargin: 0,
+ bottomTextMargin: 0,
}),
};
export const defaultOptions: AppDefaultsOptions = {
- barCodeNumLength: 9, // Number of digits in Bar Code.
- barCodeRegExp: /^[\d]{14}$|^[\d]{9}$/, // Pattern for Bar Code data. Scanned barcodes will be either 9 or 14 digits long.
- // Manually-entered ID numbers will be exactly 9 digits long.
- countsCollection: 'counts', // Name of collection for Line Counts in Firebase.
- dateDisplayFormat: 'MM/dd/yyyy, hh:mm aa', // Format for dates when displayed to user.
- dateEncodedFormat: 'yyyyMMddHHmm', // Format for dates when encoded in IDs for database records.
+ barCodeNumLength: 9, // Number of digits in Bar Code.
+ barCodeRegExp: /^[\d]{14}$|^[\d]{9}$/, // Pattern for Bar Code data.
+ // Scanned barcodes will be either 9 or 14 digits long.
+ // Manually-entered ID numbers will be exactly 9 digits long.
+ countsCollection: 'counts', // Name of collection for Line Counts in Firebase.
+ dateDisplayFormat: 'MM/dd/yyyy, hh:mm aa', // Format for dates when displayed to user.
+ dateEncodedFormat: 'yyyyMMddHHmm', // Format for dates when encoded in IDs for database records.
initialsLength: 5,
initialsRegExp: /^[a-zA-Z]{2,5}$/,
- labelLayout: labelLayouts.round_32mm_1up, // Which label layout to use for printing. Can be overridden by user setting.
- lineCountRegExp: /^[\d]{4}-[\d]{12}$/, // ID format for Line Count records.
- locationId: '0000', // Default location ID. Can be overridden by user setting.
- locationIdRegExp: /^[\d]{4}$/, // ID format for Line Count records.
- numCopies: 1, // Default number of copies of labels to print. Can be overridden by user setting.
- qrCodeRegExp: /^[\d]{9}-[a-zA-Z]+-[\d]{12}-[\d]{4}$/, // ID format for QR Code records.
- samplesCollection: 'samples', // Name of collection for Line Counts in Firebase.
+ labelLayout: labelLayouts.circle_1up_32mm_x_32mm_qrcode, // Which label layout to use for printing. Can be overridden by user setting.
+ lineCountRegExp: /^[\d]{4}-[\d]{12}$/, // ID format for Line Count records.
+ locationId: '0000', // Default location ID. Can be overridden by user setting.
+ locationIdRegExp: /^[\d]{4}$/, // ID format for Line Count records.
+ numCopies: 1, // Default number of copies of labels to print.
+ // Can be overridden by user setting.
+ qrCodeRegExp: /^[\d]{9}-[a-zA-Z]+-[\d]{12}-[\d]{4}$/, // ID format for QR Code records.
+ samplesCollection: 'samples', // Name of collection for Line Counts in Firebase.
};
diff --git a/src/app/models/labelLayout.interface.ts b/src/app/models/labelLayout.interface.ts
index e4b6330..6a3c6ea 100644
--- a/src/app/models/labelLayout.interface.ts
+++ b/src/app/models/labelLayout.interface.ts
@@ -21,9 +21,9 @@ export interface LayoutOptions {
}
export class LabelLayout {
+ name = '32mm Round Label - QR Code (1up)';
barcodeType = 'qrcode';
- type = 'round_32mm_1up';
- name = '32mm Round Label - 1up';
+ type = 'circle_1up_32mm_x_32mm_qrcode';
units = 'mm';
pointsPerUnit = 0.3528;
barcodeHeight = 28.6;
diff --git a/src/app/settings/settings.component.html b/src/app/settings/settings.component.html
index 630ddaf..3f2759a 100644
--- a/src/app/settings/settings.component.html
+++ b/src/app/settings/settings.component.html
@@ -28,7 +28,16 @@
#labelLayoutSelect="matSelect"
[formControl]="labelLayoutFormControl"
>
- {{layout.name}}
+
+
+
+ {{layout.name}}
+
+
+
+
+
+ This field is required.
diff --git a/src/assets/formats/circle_1up_32mm_x_32mm_qrcode.svg b/src/assets/formats/circle_1up_32mm_x_32mm_qrcode.svg
new file mode 100644
index 0000000..78951df
--- /dev/null
+++ b/src/assets/formats/circle_1up_32mm_x_32mm_qrcode.svg
@@ -0,0 +1,143 @@
+
+
+
+
diff --git a/src/assets/formats/circle_2up_64mm_x_32mm_qrcode.svg b/src/assets/formats/circle_2up_64mm_x_32mm_qrcode.svg
new file mode 100644
index 0000000..6d172e5
--- /dev/null
+++ b/src/assets/formats/circle_2up_64mm_x_32mm_qrcode.svg
@@ -0,0 +1,225 @@
+
+
+
+
diff --git a/src/assets/formats/rectangular_54mm_x_34mm_code128.svg b/src/assets/formats/rectangular_54mm_x_34mm_code128.svg
new file mode 100644
index 0000000..5eaec98
--- /dev/null
+++ b/src/assets/formats/rectangular_54mm_x_34mm_code128.svg
@@ -0,0 +1,572 @@
+
+
+
+
diff --git a/src/assets/formats/rectangular_54mm_x_34mm_datamatrix.svg b/src/assets/formats/rectangular_54mm_x_34mm_datamatrix.svg
new file mode 100644
index 0000000..3db474e
--- /dev/null
+++ b/src/assets/formats/rectangular_54mm_x_34mm_datamatrix.svg
@@ -0,0 +1,161 @@
+
+
+
+