Skip to content

Commit b108cb6

Browse files
committed
Better SVG dimensions to match built-in drawing - #330
1 parent 571ae91 commit b108cb6

38 files changed

+1523
-1446
lines changed

LICENSE

-1
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2121
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2222
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2323
THE SOFTWARE.
24-

LICENSE.INCONSOLATA

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ with others.
2222

2323
The OFL allows the licensed fonts to be used, studied, modified and
2424
redistributed freely as long as they are not sold by themselves. The
25-
fonts, including any derivative works, can be bundled, embedded,
25+
fonts, including any derivative works, can be bundled, embedded,
2626
redistributed and/or sold with any software provided that any reserved
2727
names are not used by derivative works. The fonts and derivatives,
2828
however, cannot be released under any other type of license. The

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ or as SVG (all platforms).
1414
1515
## Status
1616

17-
* Current bwip-js version is 4.3.0 (2024-03-12)
17+
* Current bwip-js version is 4.3.1 (2024-03-16)
1818
* Current BWIPP version is 2024-01-03
1919
* Node.js compatibility: 0.12+
2020
* Browser compatibility: Edge, Firefox, Chrome

bin/bwip-js.js

+16-13
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ function loadfont(spec) {
6060
}
6161

6262
var optlist = [
63-
{ name: 'help', type: 'boolean',
63+
{ name: 'help', type: 'boolean',
6464
desc: 'Displays this help message.' },
6565
{ name: 'version', type: 'boolean',
6666
desc: 'Displays the bwip-js and BWIPP version strings.' },
@@ -131,20 +131,23 @@ var optlist = [
131131
'non-data function characters can be specified by escaped combinations such\n' +
132132
'as ^FNC1, ^FNC4 and ^SFT.' },
133133
{ name: 'height', type: 'float',
134-
desc: 'Height of longest bar, in millimetermillimeters.' },
134+
desc: 'Height of longest bar, in millimeters.' },
135135
{ name: 'width', type: 'float',
136-
desc: 'Stretch the symbol to precisely this width, in millimeters.' },
136+
desc: 'Stretch the symbol to approximately this width, in millimeters.\n' +
137+
'Not recommended unless scale is at least 5.' },
137138
{ name: 'inkspread', type: 'float',
138139
desc: 'Amount by which to reduce the bar widths to compensate for inkspread,\n' +
139-
'in points.' },
140+
'in points. Not recommended unless scale is at least 5.' },
140141
{ name: 'inkspreadh', type: 'float',
141-
desc: 'For matrix barcodes, the amount by which the reduce the width of dark\n' +
142-
'modules to compensate for inkspread, in points.\n\n' +
142+
desc: 'For matrix barcodes, the amount by which to reduce the width of dark\n' +
143+
'modules to compensate for inkspread, in points.\n' +
144+
'Not recommended unless scale is at least 5.\n\n' +
143145
'Note: inkspreadh is most useful for stacked-linear type barcodes such as\n' +
144146
'PDF417 and Codablock F.' },
145147
{ name: 'inkspreadv', type: 'float',
146-
desc: 'For matrix barcodes, the amount by which the reduce the height of dark\n' +
147-
'modules to compensate for inkspread, in points.' },
148+
desc: 'For matrix barcodes, the amount by which to reduce the height of dark\n' +
149+
'modules to compensate for inkspread, in points.\n' +
150+
'Not recommended unless scale is at least 5.' },
148151
{ name: 'dotty', type: 'boolean',
149152
desc: 'For matrix barcodes, render the modules as dots rather than squares.\n' +
150153
'The dot radius can be adjusted using the inkspread option.' },
@@ -179,15 +182,15 @@ var optlist = [
179182
{ name: 'borderbottom', type: 'int',
180183
desc: 'Bottom margin gap of the border, in points.' },
181184
{ name: 'barcolor', type: 'string',
182-
desc: 'Color of the bars, either as a hex RRGGBB value or a hex CCMMYYKK value.' },
185+
desc: 'Color of the bars, either as a hex RGB or RRGGBB value or a hex CCMMYYKK value.' },
183186
{ name: 'backgroundcolor', type: 'string',
184-
desc: 'Color of a the image background, either as a hex RRGGBB value or a\n' +
187+
desc: 'Color of the image background, either as a hex RGB or RRGGBB value or a\n' +
185188
'hex CCMMYYKK value. The default is a transparent background.' },
186189
{ name: 'bordercolor', type: 'string',
187-
desc: 'Color of the border, either as a hex RRGGBB value or a hex CCMMYYKK value.\n' +
190+
desc: 'Color of the border, either as a hex RGB or RRGGBB value or a hex CCMMYYKK value.\n' +
188191
'You must specify --showborder for this setting to take effect.' },
189192
{ name: 'textcolor', type: 'string',
190-
desc: 'Color of the text, either as a hex RRGGBB value or a hex CCMMYYKK value.' },
193+
desc: 'Color of the text, either as a hex RGB or RRGGBB value or a hex CCMMYYKK value.' },
191194
{ name: 'addontextfont', type: 'string',
192195
desc: 'The font name to use for the add-on text in ISBN, ISMN, and ISSN barcodes.' },
193196
{ name: 'addontextsize', type: 'int',
@@ -211,7 +214,7 @@ var optlist = [
211214
{ name: 'guardrightypos', type: 'int',
212215
desc: 'Vertical position of the guard symbols on the right, in points.' },
213216
];
214-
var optmap = optlist.reduce(function(map, elt) { map[elt.name] = elt; return map; }, {});
217+
var optmap = optlist.reduce(function(map, elt) { map[elt.name] = elt; return map; }, {});
215218
var opts = {};
216219
var argv = process.argv;
217220
var outfile;

demo.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@
178178
document.getElementById('output').textContent = msg;
179179
} else if (e.stack) {
180180
// GC includes the message in the stack. FF does not.
181-
document.getElementById('output').textContent =
181+
document.getElementById('output').textContent =
182182
(e.stack.indexOf(msg) == -1 ? msg + '\n' : '') + e.stack;
183183
} else {
184184
document.getElementById('output').textContent = msg;
@@ -198,7 +198,7 @@
198198
document.getElementById('output').textContent = msg;
199199
} else if (e.stack) {
200200
// GC includes the message in the stack. FF does not.
201-
document.getElementById('output').textContent =
201+
document.getElementById('output').textContent =
202202
(e.stack.indexOf(msg) == -1 ? msg + '\n' : '') + e.stack;
203203
} else {
204204
document.getElementById('output').textContent = msg;
@@ -249,7 +249,7 @@
249249
var scaleX = +document.getElementById('scaleX').value || 2;
250250
var scaleY = +document.getElementById('scaleY').value || scaleX;
251251

252-
var url = 'http://bwipjs-api.metafloor.com/?bcid=' + elt.sym +
252+
var url = 'http://bwipjs-api.metafloor.com/?bcid=' + elt.sym +
253253
'&text=' + encodeURIComponent(text) +
254254
(alttext ? '&alttext=' + encodeURIComponent(alttext) : '') +
255255
(options ? '&' + options.replace(/ +/g, '&') : '') +

dist/bwip-js-gen.d.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Type definitions for bwip-js 4.3.0 (2024-03-12)
1+
// Type definitions for bwip-js 4.3.1 (2024-03-16)
22
//
33
// THIS DEFINITION FILE IS MACHINE GENERATED - DO NOT EDIT
44
//
@@ -135,7 +135,7 @@ declare namespace BwipJs {
135135
):
136136
| Array<{ bbs: number[]; bhs: number[]; sbs: number[] }>
137137
| Array<{ pixs: number[]; pixx: number; pixy: number; height: number; width: number }>;
138-
138+
139139
export const BWIPP_VERSION: string;
140140
export const BWIPJS_VERSION: string;
141141

@@ -182,7 +182,7 @@ declare namespace BwipJs {
182182
}
183183
export function toSVG(opts: RenderOptions): string;
184184
export function drawingSVG(): DrawingContext<string>;
185-
185+
186186
// platform-specific exports
187187
export function auspost<T>(opts: RenderOptions, drawing: DrawingContext<Promise<T>>): Promise<T>;
188188
export function auspost<T>(opts: RenderOptions, drawing: DrawingContext<T>): T;

dist/bwip-js-gen.mjs

+30-19
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
import { bwipp_auspost,bwipp_azteccode,bwipp_azteccodecompact,bwipp_aztecrune,bwipp_bc412,bwipp_channelcode,bwipp_codablockf,bwipp_code11,bwipp_code128,bwipp_code16k,bwipp_code2of5,bwipp_code32,bwipp_code39,bwipp_code39ext,bwipp_code49,bwipp_code93,bwipp_code93ext,bwipp_codeone,bwipp_coop2of5,bwipp_daft,bwipp_databarexpanded,bwipp_databarexpandedcomposite,bwipp_databarexpandedstacked,bwipp_databarexpandedstackedcomposite,bwipp_databarlimited,bwipp_databarlimitedcomposite,bwipp_databaromni,bwipp_databaromnicomposite,bwipp_databarstacked,bwipp_databarstackedcomposite,bwipp_databarstackedomni,bwipp_databarstackedomnicomposite,bwipp_databartruncated,bwipp_databartruncatedcomposite,bwipp_datalogic2of5,bwipp_datamatrix,bwipp_datamatrixrectangular,bwipp_datamatrixrectangularextension,bwipp_dotcode,bwipp_ean13,bwipp_ean13composite,bwipp_ean14,bwipp_ean2,bwipp_ean5,bwipp_ean8,bwipp_ean8composite,bwipp_flattermarken,bwipp_gs1_128,bwipp_gs1_128composite,bwipp_gs1_cc,bwipp_gs1datamatrix,bwipp_gs1datamatrixrectangular,bwipp_gs1dldatamatrix,bwipp_gs1dlqrcode,bwipp_gs1dotcode,bwipp_gs1northamericancoupon,bwipp_gs1qrcode,bwipp_hanxin,bwipp_hibcazteccode,bwipp_hibccodablockf,bwipp_hibccode128,bwipp_hibccode39,bwipp_hibcdatamatrix,bwipp_hibcdatamatrixrectangular,bwipp_hibcmicropdf417,bwipp_hibcpdf417,bwipp_hibcqrcode,bwipp_iata2of5,bwipp_identcode,bwipp_industrial2of5,bwipp_interleaved2of5,bwipp_isbn,bwipp_ismn,bwipp_issn,bwipp_itf14,bwipp_jabcode,bwipp_japanpost,bwipp_kix,bwipp_leitcode,bwipp_mailmark,bwipp_mands,bwipp_matrix2of5,bwipp_maxicode,bwipp_micropdf417,bwipp_microqrcode,bwipp_msi,bwipp_onecode,bwipp_pdf417,bwipp_pdf417compact,bwipp_pharmacode,bwipp_pharmacode2,bwipp_planet,bwipp_plessey,bwipp_posicode,bwipp_postnet,bwipp_pzn,bwipp_qrcode,bwipp_rationalizedCodabar,bwipp_raw,bwipp_rectangularmicroqrcode,bwipp_royalmail,bwipp_sscc18,bwipp_swissqrcode,bwipp_symbol,bwipp_telepen,bwipp_telepennumeric,bwipp_ultracode,bwipp_upca,bwipp_upcacomposite,bwipp_upce,bwipp_upcecomposite,bwipp_lookup,bwipp_encode,BWIPP_VERSION } from './bwipp.mjs';
3434

3535
// exports.js
36-
const BWIPJS_VERSION = '4.3.0 (2024-03-12)';
36+
const BWIPJS_VERSION = '4.3.1 (2024-03-16)';
3737

3838

3939
// bwipjs.toSVG(options)
@@ -338,7 +338,7 @@ BWIPJS.prototype.restore = function() {
338338
// coordinates corresponding to the current point according to the current
339339
// value of the CTM. Thus, if a current point is set and then the CTM is
340340
// changed, the coordinates returned by currentpoint will be different
341-
// from those that were originally specified for the point.
341+
// from those that were originally specified for the point.
342342
BWIPJS.prototype.currpos = function() {
343343
return { x:(this.g_posx-this.g_tdx)/this.g_tsx,
344344
y:(this.g_posy-this.g_tdy)/this.g_tsy
@@ -392,7 +392,7 @@ BWIPJS.prototype.setcolor = function(s) {
392392
return;
393393
}
394394
if (!/^(?:#?[0-9a-fA-F]{3}(?:[0-9a-fA-F]{3})?|[0-9a-fA-F]{8})$/.test(s)) {
395-
throw new Error('bwip-js: invalid color: ' + s);
395+
throw new Error('bwip-js: invalid color: ' + s);
396396
}
397397
if (s[0] == '#') {
398398
s = s.substr(1);
@@ -836,9 +836,9 @@ BWIPJS.prototype.maxicode = function(pix) {
836836
y *= tsy * 3;
837837
y += tsy * 2 - h/2;
838838
y = y|0;
839-
839+
840840
// Build bottom up so the drawing is top-down.
841-
var pts = [ [ x-0.5, y-- ] ];
841+
var pts = [ [ x-0.5, y-- ] ];
842842
y -= qh-1;
843843
pts.push([x-1-w2, y--]);
844844
y -= vh;
@@ -1117,7 +1117,7 @@ function DrawingBuiltin() {
11171117

11181118
// Polygons are used to draw the connected regions in a 2d barcode.
11191119
// These will always be unstroked, filled, orthogonal shapes.
1120-
//
1120+
//
11211121
// You will see a series of polygon() calls, followed by a fill().
11221122
polygon : function(pts) {
11231123
var npts = pts.length;
@@ -1410,7 +1410,7 @@ function DrawingBuiltin() {
14101410
for (var y = left.min, max = left.length-1; y <= max; y++) {
14111411
addPoint(left[y], y);
14121412
}
1413-
// The points we calculated are "inside". The fill algorithm excludes
1413+
// The points we calculated are "inside". The fill algorithm excludes
14141414
// right edges, so +1 on each x.
14151415
for (var y = right.min, max = right.length-1; y <= max; y++) {
14161416
addPoint(right[y]+1, y);
@@ -1448,7 +1448,7 @@ function DrawingBuiltin() {
14481448
for (var n = 0, npts = pts.length; n < npts; n++) {
14491449
var xn = pts[n];
14501450
if (xn > x) {
1451-
return !wn;
1451+
return !wn;
14521452
} else if (xn == x) {
14531453
return wn;
14541454
}
@@ -1524,15 +1524,19 @@ function DrawingSVG() {
15241524
var width = 0;
15251525
var ascent = 0;
15261526
var descent = 0;
1527-
for (var i = 0; i < str.length; i++) {
1527+
for (var i = 0, l = str.length; i < l; i++) {
15281528
var ch = str.charCodeAt(i);
1529-
var glyph = FontLib.getpaths(fontid, ch, fwidth, fheight);
1529+
var glyph = FontLib.getglyph(fontid, ch, fwidth, fheight);
15301530
if (!glyph) {
15311531
continue;
15321532
}
1533-
ascent = Math.max(ascent, glyph.ascent);
1534-
descent = Math.max(descent, -glyph.descent);
1535-
width += glyph.advance;
1533+
ascent = Math.max(ascent, glyph.top);
1534+
descent = Math.max(descent, glyph.height - glyph.top);
1535+
if (i == l-1) {
1536+
width += glyph.left + glyph.width;
1537+
} else {
1538+
width += glyph.advance;
1539+
}
15361540
}
15371541
return { width, ascent, descent };
15381542
},
@@ -1592,6 +1596,12 @@ function DrawingSVG() {
15921596
y1 += 0.5;
15931597
}
15941598
}
1599+
// The svg path does not include the start pixel, but the bwip-js drawing does.
1600+
if (x0 == x1) {
1601+
y0++;
1602+
} else if (y0 == y1) {
1603+
x0++;
1604+
}
15951605

15961606
// Group together all lines of the same width and emit as single paths.
15971607
// Dramatically reduces resulting text size.
@@ -1720,7 +1730,9 @@ function DrawingSVG() {
17201730
// Close the shape
17211731
path += 'Z';
17221732
}
1723-
x += glyph.advance + dx;
1733+
// getglyph() provides slightly different metrics than getpaths(). Keep
1734+
// it consistent with the built-in drawing.
1735+
x += FontLib.getglyph(fontid, ch, fwidth, fheight).advance + dx;
17241736
}
17251737
if (path) {
17261738
svg += '<path d="' + path + '" fill="#' + rgb + '" />\n';
@@ -1837,7 +1849,7 @@ var FontLib = (function() {
18371849
}
18381850

18391851
// In the cache?
1840-
var cachekey = '' + fontid + 'c' + charcode + 'w' + width + 'h' + height;
1852+
var cachekey = '' + fontid + 'c' + charcode + 'w' + width + 'h' + height;
18411853
var glyph = glyphcache[cachekey];
18421854
if (glyph) {
18431855
// Unthread from the MRU
@@ -1850,7 +1862,7 @@ var FontLib = (function() {
18501862
glyph.next = sntl.next;
18511863
glyph.prev = sntl;
18521864
sntl.next = glyph;
1853-
1865+
18541866
return glyph;
18551867
}
18561868

@@ -1859,7 +1871,7 @@ var FontLib = (function() {
18591871
height * font.bwipjs_multy / 100) ||
18601872
STBTT.GetGlyph(font, 0, width * font.bwipjs_multx / 100,
18611873
height * font.bwipjs_multy / 100);
1862-
1874+
18631875
glyph.bytes = glyph.pixels;
18641876
glyph.cachekey = cachekey;
18651877
glyph.offset = 0;
@@ -1928,7 +1940,6 @@ var FontLib = (function() {
19281940
function LoadFont() {
19291941
return FontLib.loadFont.apply(FontLib, Array.prototype.slice.call(arguments));
19301942
}
1931-
19321943
// bwip-js/stb_trutype.js
19331944
//
19341945
// JavaScript implementation of stb_truetype.h @ https://github.com/nothings/stb.
@@ -3876,7 +3887,7 @@ function toUint8Array(data) {
38763887
}
38773888
throw new ReferenceError("data must be a binary or base64 encoded string or Uint8Array");
38783889
}
3879-
toUint8Array.b64map = (function() {
3890+
toUint8Array.b64map = (function() {
38803891
var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
38813892
var map = {};
38823893
for (var i = 0; i < 64; i++) {

dist/bwip-js-min.js

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/bwip-js-node.d.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Type definitions for bwip-js 4.3.0 (2024-03-12)
1+
// Type definitions for bwip-js 4.3.1 (2024-03-16)
22
//
33
// THIS DEFINITION FILE IS MACHINE GENERATED - DO NOT EDIT
44
//
@@ -139,7 +139,7 @@ declare namespace BwipJs {
139139
):
140140
| Array<{ bbs: number[]; bhs: number[]; sbs: number[] }>
141141
| Array<{ pixs: number[]; pixx: number; pixy: number; height: number; width: number }>;
142-
142+
143143
export const BWIPP_VERSION: string;
144144
export const BWIPJS_VERSION: string;
145145

@@ -186,7 +186,7 @@ declare namespace BwipJs {
186186
}
187187
export function toSVG(opts: RenderOptions): string;
188188
export function drawingSVG(): DrawingContext<string>;
189-
189+
190190
// platform-specific exports
191191
export type ToBufferCallback = (err: string | Error, png: Buffer) => void;
192192
export function toBuffer(opts: RenderOptions, callback: ToBufferCallback): void;

0 commit comments

Comments
 (0)