xl-public-utils 1.0.2 → 1.0.3

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.
@@ -0,0 +1,4006 @@
1
+ // This file is part of the bwip-js project available at:
2
+ //
3
+ // http://metafloor.github.io/bwip-js
4
+ //
5
+ // Copyright (c) 2011-2024 Mark Warren
6
+ //
7
+ // This file contains code automatically generated from:
8
+ // Barcode Writer in Pure PostScript - Version 2024-06-18
9
+ // Copyright (c) 2004-2024 Terry Burton
10
+ //
11
+ // The MIT License
12
+ //
13
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ // of this software and associated documentation files (the "Software"), to deal
15
+ // in the Software without restriction, including without limitation the rights
16
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ // copies of the Software, and to permit persons to whom the Software is
18
+ // furnished to do so, subject to the following conditions:
19
+ //
20
+ // The above copyright notice and this permission notice shall be included in
21
+ // all copies or substantial portions of the Software.
22
+ //
23
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29
+ // THE SOFTWARE.
30
+ //
31
+ "use strict";
32
+
33
+ import { bwipp_datamatrix,bwipp_qrcode,bwipp_lookup,bwipp_encode,BWIPP_VERSION } from './bwipp.mjs';
34
+
35
+ // exports.js
36
+ const BWIPJS_VERSION = '4.5.1 (2024-08-12)';
37
+
38
+ // bwipjs.toCanvas(canvas, options)
39
+ // bwipjs.toCanvas(options, canvas)
40
+ //
41
+ // Uses the built-in canvas drawing.
42
+ //
43
+ // `canvas` can be an HTMLCanvasElement or an ID string or unique selector string.
44
+ // `options` are a bwip-js/BWIPP options object.
45
+ //
46
+ // This function is synchronous and throws on error.
47
+ //
48
+ // Returns the HTMLCanvasElement.
49
+ function ToCanvas(cvs, opts) {
50
+ if (typeof opts == 'string' || opts instanceof HTMLCanvasElement) {
51
+ let tmp = cvs;
52
+ cvs = opts;
53
+ opts = tmp;
54
+ }
55
+ return _ToAny(bwipp_lookup(opts.bcid), opts, cvs);
56
+ }
57
+ // Entry point for the symbol-specific exports
58
+ //
59
+ // Polymorphic internal interface
60
+ // _ToAny(encoder, string, opts) : HTMLCanvasElement
61
+ // _ToAny(encoder, HTMLCanvasElement, opts) : HTMLCanvasElement
62
+ // _ToAny(encoder, opts, string) : HTMLCanvasElement
63
+ // _ToAny(encoder, opts, HTMLCanvasElement) : HTMLCanvasElement
64
+ // _ToAny(encoder, opts, drawing) : any
65
+ //
66
+ // 'string` can be either an `id` or query selector returning a single canvas element.
67
+ function _ToAny(encoder, opts, drawing) {
68
+ if (typeof opts == 'string') {
69
+ var canvas = document.getElementById(opts) || document.querySelector(opts);
70
+ if (!(canvas instanceof HTMLCanvasElement)) {
71
+ throw new Error('bwipjs: `' + opts + '`: not a canvas');
72
+ }
73
+ opts = drawing;
74
+ drawing = DrawingCanvas(canvas);
75
+ } else if (opts instanceof HTMLCanvasElement) {
76
+ var canvas = opts;
77
+ opts = drawing;
78
+ drawing = DrawingCanvas(canvas);
79
+ } else if (typeof drawing == 'string') {
80
+ var canvas = document.getElementById(drawing) || document.querySelector(drawing);
81
+ if (!(canvas instanceof HTMLCanvasElement)) {
82
+ throw new Error('bwipjs: `' + drawing + '`: not a canvas');
83
+ }
84
+ drawing = DrawingCanvas(canvas);
85
+ } else if (drawing instanceof HTMLCanvasElement) {
86
+ drawing = DrawingCanvas(drawing);
87
+ } else if (!drawing || typeof drawing != 'object' || !drawing.init) {
88
+ throw new Error('bwipjs: not a canvas or drawing object');
89
+ }
90
+ return _Render(encoder, opts, drawing);
91
+ }
92
+
93
+ // bwipjs.toSVG(options)
94
+ //
95
+ // Uses the built-in svg drawing interface.
96
+ //
97
+ // `options` are a bwip-js/BWIPP options object.
98
+ //
99
+ // This function is synchronous and throws on error.
100
+ //
101
+ // Returns a string containing a fully qualified SVG definition,
102
+ // including the natural width and height of the image, in pixels:
103
+ //
104
+ // <svg viewBox="0 0 242 200" xmlns="http://www.w3.org/2000/svg">
105
+ // ...
106
+ // </svg>
107
+ //
108
+ // Available on all platforms.
109
+ function ToSVG(opts) {
110
+ return _Render(bwipp_lookup(opts.bcid), opts, DrawingSVG());
111
+ }
112
+
113
+ function FixupOptions(opts) {
114
+ var scale = opts.scale || 2;
115
+ var scaleX = +opts.scaleX || scale;
116
+ var scaleY = +opts.scaleY || scaleX;
117
+
118
+ // Fix up padding.
119
+ opts.paddingleft = padding(opts.paddingleft, opts.paddingwidth, opts.padding, scaleX);
120
+ opts.paddingright = padding(opts.paddingright, opts.paddingwidth, opts.padding, scaleX);
121
+ opts.paddingtop = padding(opts.paddingtop, opts.paddingheight, opts.padding, scaleY);
122
+ opts.paddingbottom = padding(opts.paddingbottom, opts.paddingheight, opts.padding, scaleY);
123
+
124
+ // We override BWIPP's background color functionality. If in CMYK, convert to RRGGBB so
125
+ // the drawing interface is consistent. Likewise, if in CSS-style #rgb or #rrggbb.
126
+ if (opts.backgroundcolor) {
127
+ var bgc = ''+opts.backgroundcolor;
128
+ if (/^[0-9a-fA-F]{8}$/.test(bgc)) {
129
+ var c = parseInt(bgc.substr(0,2), 16) / 255;
130
+ var m = parseInt(bgc.substr(2,2), 16) / 255;
131
+ var y = parseInt(bgc.substr(4,2), 16) / 255;
132
+ var k = parseInt(bgc.substr(6,2), 16) / 255;
133
+ var r = Math.floor((1-c) * (1-k) * 255).toString(16);
134
+ var g = Math.floor((1-m) * (1-k) * 255).toString(16);
135
+ var b = Math.floor((1-y) * (1-k) * 255).toString(16);
136
+ opts.backgroundcolor = (r.length == 1 ? '0' : '') + r +
137
+ (g.length == 1 ? '0' : '') + g +
138
+ (b.length == 1 ? '0' : '') + b;
139
+ } else {
140
+ if (bgc[0] == '#') {
141
+ bgc = bgc.substr(1);
142
+ }
143
+ if (/^[0-9a-fA-F]{6}$/.test(bgc)) {
144
+ opts.backgroundcolor = bgc;
145
+ } else if (/^[0-9a-fA-F]{3}$/.test(bgc)) {
146
+ opts.backgroundcolor = bgc[0] + bgc[0] + bgc[1] + bgc[1] + bgc[2] + bgc[2];
147
+ } else {
148
+ throw new Error('bwip-js: invalid backgroundcolor: ' + opts.backgroundcolor);
149
+ }
150
+ }
151
+ }
152
+
153
+ return opts;
154
+
155
+ // a is the most specific padding value, e.g. paddingleft
156
+ // b is the next most specific value, e.g. paddingwidth
157
+ // c is the general padding value.
158
+ // s is the scale, either scalex or scaley
159
+ function padding(a, b, c, s) {
160
+ if (a != null) {
161
+ a = a >>> 0;
162
+ return a*s >>> 0;
163
+ }
164
+ if (b != null) {
165
+ b = b >>> 0;
166
+ return b*s >>> 0;
167
+ }
168
+ c = c >>> 0;
169
+ return (c*s >>> 0) || 0;
170
+ }
171
+ }
172
+
173
+ var BWIPJS_OPTIONS = {
174
+ bcid:1,
175
+ text:1,
176
+ scale:1,
177
+ scaleX:1,
178
+ scaleY:1,
179
+ rotate:1,
180
+ padding:1,
181
+ paddingwidth:1,
182
+ paddingheight:1,
183
+ paddingtop:1,
184
+ paddingleft:1,
185
+ paddingright:1,
186
+ paddingbottom:1,
187
+ backgroundcolor:1,
188
+ };
189
+
190
+ // bwipjs.render(options, drawing)
191
+ //
192
+ // Renders a barcode using the provided drawing object.
193
+ //
194
+ // This function is synchronous and throws on error.
195
+ //
196
+ // Browser and nodejs usage.
197
+ function Render(options, drawing) {
198
+ return _Render(bwipp_lookup(options.bcid), options, drawing);
199
+ }
200
+
201
+ // Called by the public exports
202
+ function _Render(encoder, options, drawing) {
203
+ var text = options.text;
204
+ if (!text) {
205
+ throw new ReferenceError('bwip-js: bar code text not specified.');
206
+ }
207
+
208
+ // setopts() is optional on the drawing object.
209
+ FixupOptions(options);
210
+ drawing.setopts && drawing.setopts(options);
211
+
212
+ // Set the bwip-js defaults
213
+ var scale = options.scale || 2;
214
+ var scaleX = +options.scaleX || scale;
215
+ var scaleY = +options.scaleY || scaleX;
216
+ var rotate = options.rotate || 'N';
217
+
218
+ // Create a barcode writer object. This is the interface between
219
+ // the low-level BWIPP code, the bwip-js graphics context, and the
220
+ // drawing interface.
221
+ var bw = new BWIPJS(drawing);
222
+
223
+ // Set the BWIPP options
224
+ var bwippopts = {};
225
+ for (var id in options) {
226
+ if (!BWIPJS_OPTIONS[id]) {
227
+ bwippopts[id] = options[id];
228
+ }
229
+ }
230
+
231
+ // Fix a disconnect in the BWIPP rendering logic
232
+ if (bwippopts.alttext) {
233
+ bwippopts.includetext = true;
234
+ }
235
+ // We use mm rather than inches for height - except pharmacode2 height
236
+ // which is already in mm.
237
+ if (+bwippopts.height && encoder != bwipp_pharmacode2) {
238
+ bwippopts.height = bwippopts.height / 25.4 || 0.5;
239
+ }
240
+ // Likewise, width
241
+ if (+bwippopts.width) {
242
+ bwippopts.width = bwippopts.width / 25.4 || 0;
243
+ }
244
+
245
+ // Scale the image
246
+ bw.scale(scaleX, scaleY);
247
+
248
+ // Call into the BWIPP cross-compiled code and render the image.
249
+ bwipp_encode(bw, encoder, text, bwippopts);
250
+
251
+ // Returns whatever drawing.end() returns, or `false` if nothing rendered.
252
+ return bw.render();
253
+ }
254
+
255
+ // bwipjs.raw(options)
256
+ // bwipjs.raw(bcid, text, opts-string)
257
+ //
258
+ // Invokes the low level BWIPP code and returns the raw encoding data.
259
+ //
260
+ // This function is synchronous and throws on error.
261
+ //
262
+ // Browser and nodejs usage.
263
+ function ToRaw(bcid, text, options) {
264
+ if (arguments.length == 1) {
265
+ options = bcid;
266
+ bcid = options.bcid;
267
+ text = options.text;
268
+ }
269
+
270
+ // The drawing interface is just needed for the pre-init() calls.
271
+ // Don't need to fixup the drawing specific options.
272
+ var drawing = DrawingBuiltin();
273
+ drawing.setopts(options);
274
+
275
+ var bw = new BWIPJS(drawing);
276
+ var stack = bwipp_encode(bw, bwipp_lookup(bcid), text, options, true);
277
+
278
+ // bwip-js uses Maps to emulate PostScript dictionary objects; but Maps
279
+ // are not a typical/expected return value. Convert to plain-old-objects.
280
+ var ids = { pixs:1, pixx:1, pixy:1, sbs:1, bbs:1, bhs:1, width:1, height:1 };
281
+ for (var i = 0; i < stack.length; i++) {
282
+ var elt = stack[i];
283
+ if (elt instanceof Map) {
284
+ var obj = {};
285
+ // Could they make Maps any harder to iterate over???
286
+ for (var keys = elt.keys(), size = elt.size, k = 0; k < size; k++) {
287
+ var id = keys.next().value;
288
+ if (ids[id]) {
289
+ var val = elt.get(id);
290
+ if (val instanceof Array) {
291
+ // The postscript arrays have extra named properties
292
+ // to emulate array views. Return cleaned up arrays.
293
+ obj[id] = val.b.slice(val.o, val.o + val.length);
294
+ } else {
295
+ obj[id] = val;
296
+ }
297
+ }
298
+ }
299
+ stack[i] = obj;
300
+ } else {
301
+ // This should never exec...
302
+ stack.splice(i--, 1);
303
+ }
304
+ }
305
+ return stack;
306
+ }
307
+ // file : bwipjs.js
308
+ //
309
+ // Graphics-context interface to the BWIPP cross-compiled code
310
+
311
+ var BWIPJS = (function() {
312
+
313
+ // Math.floor(), etc. are notoriously slow. Caching seems to help.
314
+ var floor = Math.floor;
315
+ var round = Math.round;
316
+ var ceil = Math.ceil;
317
+ var min = Math.min;
318
+ var max = Math.max;
319
+
320
+ function BWIPJS(drawing) {
321
+ if (this.constructor !== BWIPJS) {
322
+ return new BWIPJS(drawing);
323
+ }
324
+ this.gstk = []; // Graphics save/restore stack
325
+ this.cmds = []; // Graphics primitives to replay when rendering
326
+ this.drawing = drawing; // Drawing interface
327
+
328
+ this.reset();
329
+
330
+ // Drawing surface bounding box
331
+ this.minx = this.miny = Infinity;
332
+ this.maxx = this.maxy = -Infinity;
333
+ };
334
+
335
+ // All graphics state that must be saved/restored is given a prefix of g_
336
+ BWIPJS.prototype.reset = function() {
337
+ // Current Transform Matrix - since we don't do rotation, we can fake
338
+ // the matrix math
339
+ this.g_tdx = 0; // CTM x-offset
340
+ this.g_tdy = 0; // CTM y-offset
341
+ this.g_tsx = 1; // CTM x-scale factor
342
+ this.g_tsy = 1; // CTM y-scale factor
343
+
344
+ this.g_posx = 0; // current x position
345
+ this.g_posy = 0; // current y position
346
+ this.g_penw = 1; // current line/pen width
347
+ this.g_path = []; // current path
348
+ this.g_font = null; // current font object
349
+ this.g_rgb = [0,0,0]; // current color (black)
350
+ this.g_clip = false; // clip region active
351
+ };
352
+ BWIPJS.prototype.save = function() {
353
+ // clone all g_ properties
354
+ var ctx = {};
355
+ for (var id in this) {
356
+ if (id.indexOf('g_') == 0) {
357
+ ctx[id] = clone(this[id]);
358
+ }
359
+ }
360
+ this.gstk.push(ctx);
361
+
362
+ // Perform a deep clone of the graphics state properties
363
+ function clone(v) {
364
+ if (v instanceof Array) {
365
+ var t = [];
366
+ for (var i = 0; i < v.length; i++)
367
+ t[i] = clone(v[i]);
368
+ return t;
369
+ }
370
+ if (v instanceof Object) {
371
+ var t = {};
372
+ for (var id in v)
373
+ t[id] = clone(v[id]);
374
+ return t;
375
+ }
376
+ return v;
377
+ }
378
+ };
379
+ BWIPJS.prototype.restore = function() {
380
+ if (!this.gstk.length) {
381
+ throw new Error('grestore: stack underflow');
382
+ }
383
+ var ctx = this.gstk.pop();
384
+ var self = this;
385
+ if (this.g_clip && !ctx.g_clip) {
386
+ this.cmds.push(function() {
387
+ self.drawing.unclip();
388
+ });
389
+ }
390
+ for (var id in ctx) {
391
+ this[id] = ctx[id];
392
+ }
393
+ };
394
+ // Per the postscript spec:
395
+ // As discussed in Section 4.4.1, Current Path, points entered into a path
396
+ // are immediately converted to device coordinates by the current
397
+ // transformation matrix (CTM); subsequent modifications to the CTM do not
398
+ // affect existing points. `currentpoint` computes the user space
399
+ // coordinates corresponding to the current point according to the current
400
+ // value of the CTM. Thus, if a current point is set and then the CTM is
401
+ // changed, the coordinates returned by currentpoint will be different
402
+ // from those that were originally specified for the point.
403
+ BWIPJS.prototype.currpos = function() {
404
+ return { x:(this.g_posx-this.g_tdx)/this.g_tsx,
405
+ y:(this.g_posy-this.g_tdy)/this.g_tsy
406
+ };
407
+ };
408
+ BWIPJS.prototype.currfont = function() {
409
+ return this.g_font;
410
+ };
411
+ BWIPJS.prototype.translate = function(x, y) {
412
+ this.g_tdx = this.g_tsx * x;
413
+ this.g_tdy = this.g_tsy * y;
414
+ };
415
+ BWIPJS.prototype.scale = function(x, y) {
416
+ this.g_tsx *= x;
417
+ this.g_tsy *= y;
418
+ var sxy = this.drawing.scale(this.g_tsx, this.g_tsy);
419
+ if (sxy && sxy[0] && sxy[1]) {
420
+ this.g_tsx = sxy[0];
421
+ this.g_tsy = sxy[1];
422
+ }
423
+ };
424
+ BWIPJS.prototype.setlinewidth = function(w) {
425
+ this.g_penw = w;
426
+ };
427
+ BWIPJS.prototype.selectfont = function(f, z) {
428
+ this.g_font = { FontName:this.jsstring(f), FontSize:+z };
429
+ };
430
+ BWIPJS.prototype.getfont = function() {
431
+ return this.g_font.FontName;
432
+ };
433
+ // Special function for converting a Uint8Array string to string.
434
+ BWIPJS.prototype.jsstring = function(s) {
435
+ if (s instanceof Uint8Array) {
436
+ // Postscript (like C) treats nul-char as end of string.
437
+ //for (var i = 0, l = s.length; i < l && s[i]; i++);
438
+ //if (i < l) {
439
+ // return String.fromCharCode.apply(null,s.subarray(0, i));
440
+ //}
441
+ return String.fromCharCode.apply(null,s)
442
+ }
443
+ return ''+s;
444
+ };
445
+ // Special function to replace setanycolor in BWIPP.
446
+ // Converts a string of hex digits either rgb, rrggbb or ccmmyykk.
447
+ // Or CSS-style #rgb and #rrggbb.
448
+ BWIPJS.prototype.setcolor = function(s) {
449
+ if (s instanceof Uint8Array) {
450
+ s = this.jsstring(s);
451
+ }
452
+ if (!s) {
453
+ return;
454
+ }
455
+ if (!/^(?:#?[0-9a-fA-F]{3}(?:[0-9a-fA-F]{3})?|[0-9a-fA-F]{8})$/.test(s)) {
456
+ throw new Error('bwip-js: invalid color: ' + s);
457
+ }
458
+ if (s[0] == '#') {
459
+ s = s.substr(1);
460
+ }
461
+ if (s.length == 3) {
462
+ var r = parseInt(s[0], 16);
463
+ var g = parseInt(s[1], 16);
464
+ var b = parseInt(s[2], 16);
465
+ this.g_rgb = [ r<<4|r, g<<4|g, b<<4|b ];
466
+ } else if (s.length == 6) {
467
+ var r = parseInt(s.substr(0,2), 16);
468
+ var g = parseInt(s.substr(2,2), 16);
469
+ var b = parseInt(s.substr(4,2), 16);
470
+ this.g_rgb = [ r, g, b ];
471
+ } else {
472
+ var c = parseInt(s.substr(0,2), 16) / 255;
473
+ var m = parseInt(s.substr(2,2), 16) / 255;
474
+ var y = parseInt(s.substr(4,2), 16) / 255;
475
+ var k = parseInt(s.substr(6,2), 16) / 255;
476
+ var r = round((1-c) * (1-k) * 255);
477
+ var g = round((1-m) * (1-k) * 255);
478
+ var b = round((1-y) * (1-k) * 255);
479
+ this.g_rgb = [ r, g, b ];
480
+ }
481
+ };
482
+ // Used only by swissqrcode
483
+ BWIPJS.prototype.setrgbcolor = function(r,g,b) {
484
+ this.g_rgb = [ r, g, b ];
485
+ };
486
+ // Returns the current rgb values as a 'RRGGBB'
487
+ BWIPJS.prototype.getRGB = function() {
488
+ var r = this.g_rgb[0].toString(16);
489
+ var g = this.g_rgb[1].toString(16);
490
+ var b = this.g_rgb[2].toString(16);
491
+ return '00'.substr(r.length) + r + '00'.substr(g.length) + g + '00'.substr(b.length) + b;
492
+ };
493
+ BWIPJS.prototype.newpath = function() {
494
+ this.g_path = [];
495
+ };
496
+ BWIPJS.prototype.closepath = function() {
497
+ var path = this.g_path;
498
+ var plen = path.length;
499
+ if (!plen) return;
500
+
501
+ var f = plen-1;
502
+ for ( ; f >= 0 && path[f].op == 'l'; f--);
503
+ f++;
504
+ if (f < plen-1) {
505
+ var poly = [];
506
+ var xmin = Infinity;
507
+ var ymin = Infinity;
508
+ var xmax = -Infinity;
509
+ var ymax = -Infinity;
510
+ for (var i = f; i < plen; i++) {
511
+ var a = path[i];
512
+ poly.push([ a.x0, a.y0 ]);
513
+ if (xmin > a.x0) xmin = a.x0;
514
+ if (xmax < a.x0) xmax = a.x0;
515
+ if (ymin > a.y0) ymin = a.y0;
516
+ if (ymax < a.y0) ymax = a.y0;
517
+ }
518
+ var a = path[plen-1];
519
+ var b = path[f];
520
+ if (a.x1 != b.x0 || a.y1 != b.y0) {
521
+ poly.push([ a.x1, a.y1 ]);
522
+ if (xmin > a.x1) xmin = a.x1;
523
+ if (xmax < a.x1) xmax = a.x1;
524
+ if (ymin > a.y1) ymin = a.y1;
525
+ if (ymax < a.y1) ymax = a.y1;
526
+ }
527
+ path.splice(f, plen-f,
528
+ { op:'p', x0:xmin, y0:ymin, x1:xmax, y1:ymax, poly:poly });
529
+ } else {
530
+ path.push({ op:'c' });
531
+ }
532
+ };
533
+ BWIPJS.prototype.moveto = function(x,y) {
534
+ this.g_posx = this.g_tdx + this.g_tsx * x;
535
+ this.g_posy = this.g_tdy + this.g_tsy * y;
536
+ };
537
+ BWIPJS.prototype.rmoveto = function(x,y) {
538
+ this.g_posx += this.g_tsx * x;
539
+ this.g_posy += this.g_tsy * y;
540
+ };
541
+ BWIPJS.prototype.lineto = function(x,y) {
542
+ var x0 = round(this.g_posx);
543
+ var y0 = round(this.g_posy);
544
+ this.g_posx = this.g_tdx + this.g_tsx * x;
545
+ this.g_posy = this.g_tdy + this.g_tsy * y;
546
+ var x1 = round(this.g_posx);
547
+ var y1 = round(this.g_posy);
548
+
549
+ this.g_path.push({ op:'l', x0:x0, y0:y0, x1:x1, y1:y1 });
550
+ };
551
+ BWIPJS.prototype.rlineto = function(x,y) {
552
+ var x0 = round(this.g_posx);
553
+ var y0 = round(this.g_posy);
554
+ this.g_posx += this.g_tsx * x;
555
+ this.g_posy += this.g_tsy * y;
556
+ var x1 = round(this.g_posx);
557
+ var y1 = round(this.g_posy);
558
+
559
+ this.g_path.push({ op:'l', x0:x0, y0:y0, x1:x1, y1:y1 });
560
+ };
561
+ // implements both arc and arcn
562
+ BWIPJS.prototype.arc = function(x,y,r,sa,ea,ccw) {
563
+ if (sa == ea) {
564
+ return;
565
+ }
566
+ // For now, we only implement full circles...
567
+ if (sa != 0 && sa != 360 || ea != 0 && ea != 360) {
568
+ throw new Error('arc: not a full circle (' + sa + ',' + ea + ')');
569
+ }
570
+
571
+ x = this.g_tdx + this.g_tsx * x;
572
+ y = this.g_tdy + this.g_tsy * y;
573
+
574
+ // e == ellipse
575
+ var rx = r * this.g_tsx;
576
+ var ry = r * this.g_tsy;
577
+ this.g_path.push({ op:'e', x0:x-rx, y0:y-ry, x1:x+rx, y1:y+ry,
578
+ x:x, y:y, rx:rx, ry:ry, sa:sa, ea:ea, ccw:ccw });
579
+ };
580
+ BWIPJS.prototype.stringwidth = function(str) {
581
+ var tsx = this.g_tsx;
582
+ var tsy = this.g_tsy;
583
+ var size = +this.g_font.FontSize || 10;
584
+
585
+ // The string can be either a uint8-string or regular string
586
+ str = this.toUCS2(this.jsstring(str));
587
+
588
+ var bbox = this.drawing.measure(str, this.g_font.FontName, size*tsx, size*tsy);
589
+
590
+ return { w:bbox.width/tsx, h:(bbox.ascent+bbox.descent)/tsy,
591
+ a:bbox.ascent/tsy, d:bbox.descent/tsy };
592
+ };
593
+ BWIPJS.prototype.charpath = function(str, b) {
594
+ var sw = this.stringwidth(str);
595
+
596
+ // Emulate the char-path by placing a rectangle around it
597
+ this.rlineto(0, sw.a);
598
+ this.rlineto(sw.w, 0);
599
+ this.rlineto(0, -sw.h);
600
+ };
601
+ BWIPJS.prototype.pathbbox = function() {
602
+ if (!this.g_path.length) throw new Error('pathbbox: --nocurrentpoint--');
603
+ var path = this.g_path;
604
+ var llx = Infinity;
605
+ var lly = Infinity;
606
+ var urx = -Infinity;
607
+ var ury = -Infinity;
608
+ for (var i = 0; i < path.length; i++) {
609
+ var a = path[i];
610
+ if (a.op == 'c') {
611
+ continue;
612
+ }
613
+ if (a.x0 < a.x1) {
614
+ if (llx > a.x0) llx = a.x0;
615
+ if (urx < a.x1) urx = a.x1;
616
+ } else {
617
+ if (llx > a.x1) llx = a.x1;
618
+ if (urx < a.x0) urx = a.x0;
619
+ }
620
+ if (a.y0 < a.y1) {
621
+ if (lly > a.y0) lly = a.y0;
622
+ if (ury < a.y1) ury = a.y1;
623
+ } else {
624
+ if (lly > a.y1) lly = a.y1;
625
+ if (ury < a.y0) ury = a.y0;
626
+ }
627
+ }
628
+
629
+ // Convert to user-space coordinates
630
+ var rv = { llx:(llx-this.g_tdx)/this.g_tsx,
631
+ lly:(lly-this.g_tdy)/this.g_tsy,
632
+ urx:(urx-this.g_tdx)/this.g_tsx,
633
+ ury:(ury-this.g_tdy)/this.g_tsy };
634
+ return rv;
635
+ };
636
+ // Tranforms the pts array to standard (not y-inverted), unscalled values.
637
+ BWIPJS.prototype.transform = function(pts) {
638
+ var minx = this.minx;
639
+ var maxy = this.maxy;
640
+
641
+ for (var i = 0; i < pts.length; i++) {
642
+ var pt = pts[i];
643
+ pt[0] = pt[0] - minx;
644
+ pt[1] = maxy - pt[1];
645
+ }
646
+ };
647
+ BWIPJS.prototype.stroke = function() {
648
+ var tsx = this.g_tsx;
649
+ var tsy = this.g_tsy;
650
+ var path = this.g_path;
651
+ var rgb = this.getRGB();
652
+ this.g_path = [];
653
+
654
+ // This is a "super majority" round i.e. if over .66 round up.
655
+ var penw = floor(this.g_penw * tsx + 0.66);
656
+ var penh = floor(this.g_penw * tsy + 0.66);
657
+
658
+ // Calculate the bounding boxes
659
+ var nlines = 0, npolys = 0;
660
+ for (var i = 0; i < path.length; i++) {
661
+ var a = path[i];
662
+ if (a.op == 'l') {
663
+ // We only stroke vertical and horizontal lines. Complex shapes are
664
+ // always filled.
665
+ if (a.x0 != a.x1 && a.y0 != a.y1) {
666
+ throw new Error('stroke: --not-orthogonal--');
667
+ }
668
+ var x0 = a.x0;
669
+ var y0 = a.y0;
670
+ var x1 = a.x1;
671
+ var y1 = a.y1;
672
+
673
+ // Half widths (may be factional)
674
+ var penw2 = penw/2;
675
+ var penh2 = penh/2;
676
+
677
+ if (x0 > x1) { var t = x0; x0 = x1; x1 = t; }
678
+ if (y0 > y1) { var t = y0; y0 = y1; y1 = t; }
679
+ if (x0 == x1) {
680
+ this.bbox(x0-penw2, y0, x0+penw-penw2-1, y1); // vertical line
681
+ } else {
682
+ this.bbox(x0, y0-penh+penh2+1, x1, y1+penh2); // horizontal line
683
+ }
684
+ nlines++;
685
+ } else if (a.op == 'p') {
686
+ // Closed (rectangular) poly (border around the barcode)
687
+ var minx = Infinity;
688
+ var miny = Infinity;
689
+ var maxx = -Infinity;
690
+ var maxy = -Infinity;
691
+ var pts = a.poly;
692
+ if (pts.length != 4) {
693
+ throw new Error('stroke: --not-a-rect--');
694
+ }
695
+ for (var i = 0, j = pts.length-1; i < pts.length; j = i++) {
696
+ var xj = pts[j][0];
697
+ var yj = pts[j][1];
698
+ var xi = pts[i][0];
699
+ var yi = pts[i][1];
700
+
701
+ if (xi != xj && yi != yj) {
702
+ throw new Error('stroke: --not-orthogonal--');
703
+ }
704
+
705
+ if (xi < minx) minx = xi;
706
+ if (xi > maxx) maxx = xi;
707
+ if (yi < miny) miny = yi;
708
+ if (yi > maxy) maxy = yi;
709
+ }
710
+
711
+ // Half widths (integer)
712
+ var penw2 = ceil(penw/2);
713
+ var penh2 = ceil(penh/2);
714
+
715
+ // We render these as two polygons plus a fill.
716
+ // When border width is odd, allocate the bigger half to the outside.
717
+ this.bbox(minx-penw2, miny-penh2, maxx+penw2, maxy+penh2);
718
+ npolys++;
719
+ } else {
720
+ throw new Error('stroke: --not-a-line--');
721
+ }
722
+ }
723
+
724
+ // Draw the lines
725
+ var self = this;
726
+ this.cmds.push(function() {
727
+ // Half widths (big half and remaining half)
728
+ var bigw2 = ceil(penw/2);
729
+ var bigh2 = ceil(penh/2);
730
+ var remw2 = penw - bigw2;
731
+ var remh2 = penh - bigh2;
732
+
733
+ for (var i = 0; i < path.length; i++) {
734
+ var a = path[i]
735
+ if (a.op == 'l') {
736
+ var pts = [ [ a.x0, a.y0 ], [ a.x1, a.y1 ] ];
737
+ self.transform(pts);
738
+ self.drawing.line(pts[0][0], pts[0][1], pts[1][0], pts[1][1],
739
+ a.x0 == a.x1 ? penw : penh, rgb);
740
+ self.fill(rgb);
741
+ } else {
742
+ var pts = a.poly;
743
+ self.transform(pts);
744
+ var x0 = min(pts[0][0], pts[2][0]);
745
+ var x1 = max(pts[0][0], pts[2][0]);
746
+ var y0 = min(pts[0][1], pts[2][1]);
747
+ var y1 = max(pts[0][1], pts[2][1]);
748
+
749
+ // Top and left edges are "inside" the polygon.
750
+ // Bottom and right edges are outside.
751
+ self.drawing.polygon([
752
+ [ x0-bigw2, y0-bigh2 ],
753
+ [ x0-bigw2, y1+bigh2+1 ],
754
+ [ x1+bigw2+1, y1+bigh2+1 ],
755
+ [ x1+bigw2+1, y0-bigh2 ]
756
+ ]);
757
+ self.drawing.polygon([
758
+ [ x0+remw2, y0+remh2 ],
759
+ [ x0+remw2, y1-remh2+1 ],
760
+ [ x1-remw2+1, y1-remh2+1 ],
761
+ [ x1-remw2+1, y0+remh2 ],
762
+ ]);
763
+ self.drawing.fill(rgb);
764
+ }
765
+ }
766
+ });
767
+ };
768
+ BWIPJS.prototype.fill = function() {
769
+ var path = this.g_path;
770
+ var rgb = this.getRGB();
771
+ this.g_path = [];
772
+
773
+ // Calculate the bounding boxes
774
+ for (var p = 0; p < path.length; p++) {
775
+ var a = path[p];
776
+ if (a.op == 'p') { // polygon
777
+ var minx = Infinity;
778
+ var miny = Infinity;
779
+ var maxx = -Infinity;
780
+ var maxy = -Infinity;
781
+ var pts = a.poly;
782
+ for (var i = 0; i < pts.length; i++) {
783
+ var xi = pts[i][0];
784
+ var yi = pts[i][1];
785
+
786
+ if (xi < minx) minx = xi;
787
+ if (xi > maxx) maxx = xi;
788
+ if (yi < miny) miny = yi;
789
+ if (yi > maxy) maxy = yi;
790
+ }
791
+ // With polygons, the right and bottom edges are "outside" and do not
792
+ // contribute to the bounding box. But we are in postscript inverted-y
793
+ // mode.
794
+ this.bbox(minx, miny+1, maxx-1, maxy);
795
+ } else if (a.op == 'e') { // ellipse
796
+ this.bbox(a.x - a.rx, a.y - a.ry, a.x + a.rx, a.y + a.ry);
797
+ } else {
798
+ throw new Error('fill: --not-a-polygon--');
799
+ }
800
+ }
801
+
802
+ // Render the poly
803
+ var self = this;
804
+ this.cmds.push(function() {
805
+ for (var i = 0; i < path.length; i++) {
806
+ var a = path[i];
807
+ if (a.op == 'p') {
808
+ var pts = a.poly
809
+ self.transform(pts);
810
+ self.drawing.polygon(pts);
811
+ } else if (a.op == 'e') {
812
+ var pts = [ [ a.x, a.y ] ];
813
+ self.transform(pts);
814
+ self.drawing.ellipse(pts[0][0], pts[0][1], a.rx, a.ry, a.ccw);
815
+ }
816
+ }
817
+ self.drawing.fill(rgb);
818
+ });
819
+ };
820
+ BWIPJS.prototype.clip = function() {
821
+ var path = this.g_path;
822
+ this.g_path = [];
823
+ this.g_clip = true;
824
+
825
+ var self = this;
826
+ this.cmds.push(function() {
827
+ var polys = [];
828
+ for (var i = 0; i < path.length; i++) {
829
+ var a = path[i];
830
+ if (a.op == 'p') {
831
+ var pts = a.poly
832
+ self.transform(pts);
833
+ polys.push(pts);
834
+ } else {
835
+ throw new Error('clip: only polygon regions supported');
836
+ }
837
+ }
838
+ self.drawing.clip(polys);
839
+ });
840
+ };
841
+
842
+ // The pix array is in standard (not y-inverted postscript) orientation.
843
+ BWIPJS.prototype.maxicode = function(pix) {
844
+ var tsx = this.g_tsx;
845
+ var tsy = this.g_tsy;
846
+ var rgb = this.getRGB();
847
+
848
+ // Module width. Module height is an integer multiple of tsy.
849
+ var twidth = 1.04 * tsx * 100;
850
+ var mwidth = (twidth / 30)|0;
851
+ if (twidth - (mwidth*30-1) > 9) {
852
+ mwidth++;
853
+ }
854
+
855
+ // Dimensions needed for plotting the hexagons. These must be integer values.
856
+ var w, h, wgap, hgap;
857
+ // if (opts.??? ) {
858
+ // // Create a one or two pixel gap
859
+ // wgap = (mwidth & 1) ? 1 : 2;
860
+ // hgap = 1;
861
+ // w = mwidth - gap;
862
+ // h = 4 * tsy;
863
+ // } else {
864
+ // Create a 1/8mm gap
865
+ wgap = (tsx/2)|0;
866
+ hgap = (tsy/2)|0;
867
+ w = mwidth - wgap;
868
+ if (w & 1) {
869
+ w--;
870
+ }
871
+ h = ((4*tsy)|0) - hgap;
872
+ //}
873
+
874
+ // These must be integer values
875
+ var w2 = w / 2 - 1; // half width
876
+ var qh = ((w2+1) / 2)|0; // quarter height
877
+ var vh = h - 2 - 2 * qh; // side height
878
+
879
+ // Bounding box
880
+ this.bbox(0, 0, mwidth*30 - wgap, tsy * 3 * 32 + tsy * 4 - hgap);
881
+
882
+ // Render the elements
883
+ var self = this;
884
+ this.cmds.push(function() {
885
+ // Draw the hexagons
886
+ for (var i = 0; i < pix.length; i++) {
887
+ var c = pix[i];
888
+ var x = c % 30;
889
+ var y = (c / 30)|0;
890
+
891
+ // Adjust x,y to the top of hexagon
892
+ x *= mwidth;
893
+ x += (y & 1) ? mwidth : mwidth/2;
894
+ x = x|0;
895
+
896
+ y = 33 - y; // invert for postscript notation
897
+ y *= tsy * 3;
898
+ y += tsy * 2 - h/2;
899
+ y = y|0;
900
+
901
+ // Build bottom up so the drawing is top-down.
902
+ var pts = [ [ x-0.5, y-- ] ];
903
+ y -= qh-1;
904
+ pts.push([x-1-w2, y--]);
905
+ y -= vh;
906
+ pts.push([x-1-w2, y--]);
907
+ y -= qh-1;
908
+ pts.push([x-0.5, y++]);
909
+ y += qh-1;
910
+ pts.push([x+w2, y++]);
911
+ y += vh;
912
+ pts.push([x+w2, y++]);
913
+
914
+ self.transform(pts);
915
+ self.drawing.hexagon(pts, rgb);
916
+ }
917
+ self.drawing.fill(rgb);
918
+
919
+
920
+ // Draw the rings
921
+ var x = (14 * mwidth + mwidth/2 + 0.01)|0;
922
+ var y = ((12 * 4 + 3) * tsy - qh/2 + 0.01)|0;
923
+ self.drawing.ellipse(x, y, (0.5774*3.5*tsx+0.01)|0, (0.5774*3.5*tsy+0.01)|0, true);
924
+ self.drawing.ellipse(x, y, (1.3359*3.5*tsx+0.01)|0, (1.3359*3.5*tsy+0.01)|0, false);
925
+ self.drawing.fill(rgb);
926
+ self.drawing.ellipse(x, y, (2.1058*3.5*tsx+0.01)|0, (2.1058*3.5*tsy+0.01)|0, true);
927
+ self.drawing.ellipse(x, y, (2.8644*3.5*tsx+0.01)|0, (2.8644*3.5*tsy+0.01)|0, false);
928
+ self.drawing.fill(rgb);
929
+ self.drawing.ellipse(x, y, (3.6229*3.5*tsx+0.01)|0, (3.6229*3.5*tsy+0.01)|0, true);
930
+ self.drawing.ellipse(x, y, (4.3814*3.5*tsx+0.01)|0, (4.3814*3.5*tsy+0.01)|0, false);
931
+ self.drawing.fill(rgb);
932
+
933
+ });
934
+ };
935
+ // UTF-8 to UCS-2 (no surrogates)
936
+ BWIPJS.prototype.toUCS2 = function(str) {
937
+ return str.replace(/[\xc0-\xdf][\x80-\xbf]|[\xe0-\xff][\x80-\xbf]{2}/g,
938
+ function(s) {
939
+ var code;
940
+ if (s.length == 2) {
941
+ code = ((s.charCodeAt(0)&0x1f)<<6)|
942
+ (s.charCodeAt(1)&0x3f);
943
+ } else {
944
+ code = ((s.charCodeAt(0)&0x0f)<<12)|
945
+ ((s.charCodeAt(1)&0x3f)<<6)|
946
+ (s.charCodeAt(2)&0x3f);
947
+ }
948
+ return String.fromCharCode(code);
949
+ });
950
+ };
951
+ // dx,dy are inter-character gaps
952
+ BWIPJS.prototype.show = function(str, dx, dy) {
953
+ if (!str.length) {
954
+ return;
955
+ }
956
+
957
+ // Capture current graphics state
958
+ var tsx = this.g_tsx;
959
+ var tsy = this.g_tsy;
960
+ var name = this.g_font.FontName || 'OCR-B';
961
+ var size = (this.g_font.FontSize || 10);
962
+ var szx = size * tsx;
963
+ var szy = size * tsy;
964
+ var posx = this.g_posx;
965
+ var posy = this.g_posy;
966
+ var rgb = this.getRGB();
967
+
968
+ // The string can be either a uint8-string or regular string.
969
+ str = this.toUCS2(this.jsstring(str));
970
+
971
+ // Convert dx,dy to device space
972
+ dx = tsx * dx || 0;
973
+ dy = tsy * dy || 0;
974
+
975
+ // Bounding box.
976
+ var base = posy + dy;
977
+ var bbox = this.drawing.measure(str, name, szx, szy);
978
+ var width = bbox.width + (str.length-1) * dx;
979
+ this.bbox(posx, base-bbox.descent+1, posx+width-1, base+bbox.ascent);
980
+ this.g_posx += width;
981
+
982
+ var self = this;
983
+ self.cmds.push(function() {
984
+ // self.transform()
985
+ var x = posx - self.minx;
986
+ var y = self.maxy - posy;
987
+ self.drawing.text(x, y, str, rgb, { name:name, width:szx, height:szy, dx:dx });
988
+ });
989
+ };
990
+ // drawing surface bounding box
991
+ BWIPJS.prototype.bbox = function(x0, y0, x1, y1) {
992
+ if (x0 > x1) { var t = x0; x0 = x1; x1 = t; }
993
+ if (y0 > y1) { var t = y0; y0 = y1; y1 = t; }
994
+
995
+ x0 = floor(x0);
996
+ y0 = floor(y0);
997
+ x1 = ceil(x1);
998
+ y1 = ceil(y1);
999
+
1000
+ if (this.minx > x0) this.minx = x0;
1001
+ if (this.maxx < x1) this.maxx = x1;
1002
+ if (this.miny > y0) this.miny = y0;
1003
+ if (this.maxy < y1) this.maxy = y1;
1004
+ };
1005
+ BWIPJS.prototype.render = function() {
1006
+ if (this.minx === Infinity) {
1007
+ // Most likely, `dontdraw` was set in the options
1008
+ return false;
1009
+ }
1010
+ // Draw the image
1011
+ this.drawing.init(this.maxx - this.minx + 1, this.maxy - this.miny + 1,
1012
+ this.g_tsx, this.g_tsy);
1013
+ for (var i = 0, l = this.cmds.length; i < l; i++) {
1014
+ this.cmds[i]();
1015
+ }
1016
+ return this.drawing.end();
1017
+ };
1018
+
1019
+ return BWIPJS;
1020
+ })(); // BWIPJS closure
1021
+ // drawing-builtin.js
1022
+ //
1023
+ // The aliased (except the fonts) graphics used by drawing-canvas.js and
1024
+ // drawing-zlibpng.js
1025
+ //
1026
+ // All x,y and lengths are integer values.
1027
+ //
1028
+ // For the methods that take a color `rgb` parameter, the value is always a
1029
+ // string with format RRGGBB.
1030
+ function DrawingBuiltin() {
1031
+ var floor = Math.floor;
1032
+
1033
+ // Unrolled x,y rotate/translate matrix
1034
+ var tx0 = 0, tx1 = 0, tx2 = 0, tx3 = 0;
1035
+ var ty0 = 0, ty1 = 0, ty2 = 0, ty3 = 0;
1036
+
1037
+ var opts; // see setopts()
1038
+ var gs_image, gs_rowbyte; // rowbyte will be 1 for png's, 0 for canvas
1039
+ var gs_width, gs_height; // image size, in pixels
1040
+ var gs_dx, gs_dy; // x,y translate (padding)
1041
+ var gs_r, gs_g, gs_b; // rgb
1042
+ var gs_xymap; // edge map
1043
+ var gs_xyclip; // clip region map (similar to xymap)
1044
+
1045
+ return {
1046
+ // setopts() is called after the options are fixed-up/normalized,
1047
+ // but before calling into BWIPP.
1048
+ // This method allows omitting the options in the constructor call.
1049
+ // The method is optional.
1050
+ setopts(options) {
1051
+ opts = options;
1052
+ },
1053
+
1054
+ // Ensure compliant bar codes by always using integer scaling factors.
1055
+ scale : function(sx, sy) {
1056
+ // swissqrcode requires clipping and drawing that are not scaled to the
1057
+ // the barcode module size.
1058
+ if (opts.bcid == 'swissqrcode') {
1059
+ return [ sx, sy ];
1060
+ } else {
1061
+ return [ (sx|0)||1, (sy|0)||1 ];
1062
+ }
1063
+ },
1064
+
1065
+ // Measure text. This and scale() are the only drawing primitives that
1066
+ // are called before init().
1067
+ //
1068
+ // `font` is the font name typically OCR-A or OCR-B.
1069
+ // `fwidth` and `fheight` are the requested font cell size. They will
1070
+ // usually be the same, except when the scaling is not symetric.
1071
+ measure : function(str, font, fwidth, fheight) {
1072
+ fwidth = fwidth|0;
1073
+ fheight = fheight|0;
1074
+
1075
+ var fontid = FontLib.lookup(font);
1076
+ var width = 0;
1077
+ var ascent = 0;
1078
+ var descent = 0;
1079
+ for (var i = 0, l = str.length; i < l; i++) {
1080
+ var ch = str.charCodeAt(i);
1081
+ var glyph = FontLib.getglyph(fontid, ch, fwidth, fheight);
1082
+
1083
+ ascent = Math.max(ascent, glyph.top);
1084
+ descent = Math.max(descent, glyph.height - glyph.top);
1085
+
1086
+ if (i == l-1) {
1087
+ width += glyph.left + glyph.width;
1088
+ } else {
1089
+ width += glyph.advance;
1090
+ }
1091
+ }
1092
+ return { width:width, ascent:ascent, descent:descent };
1093
+ },
1094
+
1095
+ // width and height represent the maximum bounding box the graphics will occupy.
1096
+ // The dimensions are for an unrotated rendering. Adjust as necessary.
1097
+ init : function(width, height) {
1098
+ // Add in the effects of padding. These are always set before the
1099
+ // drawing constructor is called.
1100
+ var padl = opts.paddingleft;
1101
+ var padr = opts.paddingright;
1102
+ var padt = opts.paddingtop;
1103
+ var padb = opts.paddingbottom;
1104
+ var rot = opts.rotate || 'N';
1105
+
1106
+ width += padl + padr;
1107
+ height += padt + padb;
1108
+
1109
+ if (+opts.sizelimit && +opts.sizelimit < width * height) {
1110
+ throw new Error('Image size over limit');
1111
+ }
1112
+
1113
+ // Transform indexes are: x, y, w, h
1114
+ switch (rot) {
1115
+ // tx = w-y, ty = x
1116
+ case 'R': tx1 = -1; tx2 = 1; ty0 = 1; break;
1117
+ // tx = w-x, ty = h-y
1118
+ case 'I': tx0 = -1; tx2 = 1; ty1 = -1; ty3 = 1; break;
1119
+ // tx = y, ty = h-x
1120
+ case 'L': tx1 = 1; ty0 = -1; ty3 = 1; break;
1121
+ // tx = x, ty = y
1122
+ default: tx0 = ty1 = 1; break;
1123
+ }
1124
+
1125
+ // Setup the graphics state
1126
+ var swap = rot == 'L' || rot == 'R';
1127
+ gs_width = swap ? height : width;
1128
+ gs_height = swap ? width : height;
1129
+ gs_dx = padl;
1130
+ gs_dy = padt;
1131
+ gs_xymap = [];
1132
+ gs_xymap.min = Infinity;
1133
+ gs_xyclip = null;
1134
+ gs_r = gs_g = gs_b = 0;
1135
+
1136
+ // Get the rgba image from the constructor
1137
+ var res = this.image(gs_width, gs_height);
1138
+ gs_image = res.buffer;
1139
+ gs_rowbyte = res.ispng ? 1 : 0;
1140
+ },
1141
+ // Unconnected stroked lines are used to draw the bars in linear barcodes;
1142
+ // and the border around a linear barcode (e.g. ITF-14)
1143
+ // No line cap should be applied. These lines are always orthogonal.
1144
+ line : function(x0, y0, x1, y1, lw, rgb) {
1145
+ x0 = x0|0;
1146
+ y0 = y0|0;
1147
+ x1 = x1|0;
1148
+ y1 = y1|0;
1149
+
1150
+ // Most linear barcodes, the line width will be integral. The exceptions
1151
+ // are variable width barcodes (e.g. code39) and the postal 4-state codes.
1152
+ lw = Math.round(lw) || 1;
1153
+
1154
+ if (y1 < y0) { var t = y0; y0 = y1; y1 = t; }
1155
+ if (x1 < x0) { var t = x0; x0 = x1; x1 = t; }
1156
+
1157
+ gs_r = parseInt(rgb.substr(0,2), 16);
1158
+ gs_g = parseInt(rgb.substr(2,2), 16);
1159
+ gs_b = parseInt(rgb.substr(4,2), 16);
1160
+
1161
+ // Horizontal or vertical line?
1162
+ var w2 = (lw/2)|0;
1163
+ if (x0 == x1) {
1164
+ // Vertical line
1165
+ x0 = x0 - lw + w2; // big half
1166
+ x1 = x1 + w2 - 1; // small half
1167
+ } else {
1168
+ // Horizontal line (inverted halves)
1169
+ y0 = y0 - w2;
1170
+ y1 = y1 + lw - w2 - 1;
1171
+ }
1172
+ for (var y = y0; y <= y1; y++) {
1173
+ for (var x = x0; x <= x1; x++) {
1174
+ set(x, y, 255);
1175
+ }
1176
+ }
1177
+ },
1178
+
1179
+ // Polygons are used to draw the connected regions in a 2d barcode.
1180
+ // These will always be unstroked, filled, orthogonal shapes.
1181
+ //
1182
+ // You will see a series of polygon() calls, followed by a fill().
1183
+ polygon : function(pts) {
1184
+ var npts = pts.length;
1185
+ for (var j = npts-1, i = 0; i < npts; j = i++) {
1186
+ if (pts[j][0] == pts[i][0]) {
1187
+ // Vertical lines do not get their end points. End points
1188
+ // are added by the horizontal line logic.
1189
+ var xj = pts[j][0]|0; // i or j, doesn't matter
1190
+ var yj = pts[j][1]|0;
1191
+ var yi = pts[i][1]|0;
1192
+ if (yj > yi) {
1193
+ for (var y = yi+1; y < yj; y++) {
1194
+ addPoint(xj, y);
1195
+ }
1196
+ } else {
1197
+ for (var y = yj+1; y < yi; y++) {
1198
+ addPoint(xj, y);
1199
+ }
1200
+ }
1201
+ } else {
1202
+ var xj = pts[j][0]|0;
1203
+ var xi = pts[i][0]|0;
1204
+ var yj = pts[j][1]|0; // i or j, doesn't matter
1205
+
1206
+ // Horizontal lines are tricky. As a rule, top lines get filled,
1207
+ // bottom lines do not (similar to how left edges get filled and
1208
+ // right edges do not).
1209
+ //
1210
+ // Where it gets complex is deciding whether the line actually
1211
+ // adds edges. There are cases where a horizontal line does
1212
+ // not add anything to the scanline plotting. And it doesn't
1213
+ // actually matter whether the line is a top or bottom edge,
1214
+ // the logic is the same.
1215
+ //
1216
+ // A left edge is added if the edge to its left is below.
1217
+ // A right edge is added if the edge to its right is below.
1218
+ if (xj < xi) {
1219
+ var yl = pts[j == 0 ? npts-1 : j-1][1]; // left edge
1220
+ var yr = pts[i == npts-1 ? 0 : i+1][1]; // right edge
1221
+ if (yl > yj) {
1222
+ addPoint(xj, yj);
1223
+ }
1224
+ if (yr > yj) {
1225
+ addPoint(xi, yj);
1226
+ }
1227
+ } else {
1228
+ var yl = pts[i == npts-1 ? 0 : i+1][1]; // left edge
1229
+ var yr = pts[j == 0 ? npts-1 : j-1][1]; // right edge
1230
+ if (yl > yj) {
1231
+ addPoint(xi, yj);
1232
+ }
1233
+ if (yr > yj) {
1234
+ addPoint(xj, yj);
1235
+ }
1236
+ }
1237
+ }
1238
+ }
1239
+ },
1240
+ // An unstroked, filled hexagon used by maxicode. You can choose to fill
1241
+ // each individually, or wait for the final fill().
1242
+ //
1243
+ // The hexagon is drawn from the top, counter-clockwise.
1244
+ //
1245
+ // The X-coordinate for the top and bottom points on the hexagon is always
1246
+ // .5 pixels. We draw our hexagons with a 2 pixel flat top.
1247
+ //
1248
+ // All other points of the polygon/hexagon are guaranteed to be integer values.
1249
+ hexagon : function(pts, rgb) {
1250
+ var x = pts[0][0]|0;
1251
+ var y = pts[0][1]|0;
1252
+ var qh = (pts[1][1] - pts[0][1])|0; // height of triangle (quarter height)
1253
+ var vh = (pts[2][1] - pts[1][1] - 1)|0; // height of vertical side
1254
+ var xl = (pts[2][0])|0; // left side
1255
+ var xr = (pts[4][0])|0; // right side
1256
+
1257
+ gs_r = parseInt(rgb.substr(0,2), 16);
1258
+ gs_g = parseInt(rgb.substr(2,2), 16);
1259
+ gs_b = parseInt(rgb.substr(4,2), 16);
1260
+
1261
+ fillSegment(x, x+1, y++);
1262
+ for (var k = 1; k < qh; k++) {
1263
+ fillSegment(x-2*k, x+1+2*k, y++);
1264
+ }
1265
+ for (var k = 0; k <= vh; k++) {
1266
+ fillSegment(xl, xr, y++);
1267
+ }
1268
+ for (var k = qh-1; k >= 1; k--) {
1269
+ fillSegment(x-2*k, x+1+2*k, y++);
1270
+ }
1271
+ fillSegment(x, x+1, y);
1272
+ },
1273
+ // An unstroked, filled ellipse. Used by dotcode and maxicode at present.
1274
+ // maxicode issues pairs of ellipse calls (one cw, one ccw) followed by a fill()
1275
+ // to create the bullseye rings. dotcode issues all of its ellipses then a
1276
+ // fill().
1277
+ ellipse : function(x, y, rx, ry, ccw) {
1278
+ drawEllipse((x-rx)|0, (y-ry)|0, (x+rx)|0, (y+ry)|0, ccw);
1279
+ },
1280
+ // PostScript's default fill rule is non-zero but since there are never
1281
+ // intersecting regions, we use the easier to implement even-odd.
1282
+ fill : function(rgb) {
1283
+ gs_r = parseInt(rgb.substr(0,2), 16);
1284
+ gs_g = parseInt(rgb.substr(2,2), 16);
1285
+ gs_b = parseInt(rgb.substr(4,2), 16);
1286
+
1287
+ evenodd();
1288
+ gs_xymap = [];
1289
+ gs_xymap.min = Infinity;
1290
+ },
1291
+ // Currently only used by swissqrcode. The `polys` area is an array of
1292
+ // arrays of points. Each array of points is identical to the `pts`
1293
+ // parameter passed to polygon(). The postscript default clipping rule,
1294
+ // like the fill rule, is even-odd winding.
1295
+ clip : function(polys) {
1296
+ if (!gs_xyclip) {
1297
+ gs_xyclip = [];
1298
+ gs_xyclip.min = Infinity;
1299
+ }
1300
+ // Swap out the xymap for the clip map so addPoint() works on it.
1301
+ var xymap = gs_xymap;
1302
+ gs_xymap = gs_xyclip;
1303
+
1304
+ // Now just use the polygon() logic to fill in the clipping regions.
1305
+ for (var i = 0, l = polys.length; i < l; i++) {
1306
+ this.polygon(polys[i]);
1307
+ }
1308
+
1309
+ // Restore
1310
+ gs_xymap = xymap;
1311
+ },
1312
+ unclip : function() {
1313
+ gs_xyclip = null;
1314
+ },
1315
+ // Draw text with optional inter-character spacing. `y` is the baseline.
1316
+ // font is an object with properties { name, width, height, dx }
1317
+ // width and height are the font cell size.
1318
+ // dx is extra space requested between characters (usually zero).
1319
+ text : function(x, y, str, rgb, font) {
1320
+ x = x|0;
1321
+ y = y|0;
1322
+
1323
+ gs_r = parseInt(rgb.substr(0,2), 16);
1324
+ gs_g = parseInt(rgb.substr(2,2), 16);
1325
+ gs_b = parseInt(rgb.substr(4,2), 16);
1326
+
1327
+ var fontid = FontLib.lookup(font.name);
1328
+ var fwidth = font.width|0;
1329
+ var fheight = font.height|0;
1330
+ var dx = font.dx|0;
1331
+ for (var k = 0; k < str.length; k++) {
1332
+ var ch = str.charCodeAt(k);
1333
+ var glyph = FontLib.getglyph(fontid, ch, fwidth, fheight);
1334
+
1335
+ var gt = y - glyph.top;
1336
+ var gl = glyph.left;
1337
+ var gw = glyph.width;
1338
+ var gh = glyph.height;
1339
+ var gb = glyph.bytes;
1340
+ var go = glyph.offset; // offset into bytes
1341
+
1342
+ for (var i = 0; i < gw; i++) {
1343
+ for (var j = 0; j < gh; j++) {
1344
+ var a = gb[go + j * gw + i];
1345
+ if (a) {
1346
+ set(x+gl+i, gt+j, a);
1347
+ }
1348
+ }
1349
+ }
1350
+ x += glyph.advance + dx;
1351
+ }
1352
+ },
1353
+ // Called after all drawing is complete.
1354
+ end : function() {
1355
+ },
1356
+ };
1357
+
1358
+ // This code is specialized to deal with two types of RGBA buffers:
1359
+ // - canvas style, which is true RGBA
1360
+ // - PNG style, which has a one-byte "filter code" prefixing each row.
1361
+ function set(x, y, a) {
1362
+ if (gs_xyclip && clipped(x, y)) {
1363
+ return;
1364
+ }
1365
+ // translate/rotate
1366
+ x += gs_dx;
1367
+ y += gs_dy;
1368
+ var tx = tx0 * x + tx1 * y + tx2 * (gs_width-1) + tx3 * (gs_height-1);
1369
+ var ty = ty0 * x + ty1 * y + ty2 * (gs_width-1) + ty3 * (gs_height-1);
1370
+
1371
+ // https://en.wikipedia.org/wiki/Alpha_compositing
1372
+ var offs = (ty * gs_width + tx) * 4 + (ty+1) * gs_rowbyte;
1373
+ var dsta = gs_image[offs+3] / 255;
1374
+ var srca = a / 255;
1375
+ var inva = (1 - srca) * dsta;
1376
+ var outa = srca + inva;
1377
+
1378
+ gs_image[offs+0] = ((gs_r * srca + gs_image[offs+0] * inva) / outa)|0;
1379
+ gs_image[offs+1] = ((gs_g * srca + gs_image[offs+1] * inva) / outa)|0;
1380
+ gs_image[offs+2] = ((gs_b * srca + gs_image[offs+2] * inva) / outa)|0;
1381
+ gs_image[offs+3] = (255 * outa)|0;
1382
+ }
1383
+
1384
+ // Add a point on an edge to the scanline map.
1385
+ function addPoint(x, y) {
1386
+ if (gs_xymap.min > y) gs_xymap.min = y;
1387
+ if (!gs_xymap[y]) {
1388
+ gs_xymap[y] = [ x ];
1389
+ } else {
1390
+ gs_xymap[y].push(x);
1391
+ }
1392
+ }
1393
+
1394
+ function fillSegment(x0, x1, y) {
1395
+ while (x0 <= x1) {
1396
+ set(x0++, y, 255);
1397
+ }
1398
+ }
1399
+
1400
+ // even-odd fill
1401
+ //
1402
+ // This implementation is optimized for BWIPP's simple usage.
1403
+ // It is not a general purpose scanline fill. It relies heavily on
1404
+ // polygon() creating the correct intersections.
1405
+ function evenodd() {
1406
+ var ymin = gs_xymap.min;
1407
+ var ymax = gs_xymap.length-1;
1408
+
1409
+ for (var y = ymin; y <= ymax; y++) {
1410
+ var pts = gs_xymap[y];
1411
+ if (!pts) {
1412
+ continue
1413
+ }
1414
+ pts.sort(function(a, b) { return a - b; });
1415
+
1416
+ var wn = false;
1417
+ var xl = 0;
1418
+ for (var n = 0, npts = pts.length; n < npts; n++) {
1419
+ var x = pts[n];
1420
+ if (wn) {
1421
+ fillSegment(xl, x-1, y);
1422
+ } else {
1423
+ xl = x;
1424
+ }
1425
+ wn = !wn;
1426
+ }
1427
+ }
1428
+ }
1429
+
1430
+ function drawEllipse(x0, y0, x1, y1, dir) {
1431
+ x0 = x0|0;
1432
+ y0 = y0|0;
1433
+ x1 = x1|0;
1434
+ y1 = y1|0;
1435
+
1436
+ var a = Math.abs(x1-x0);
1437
+ var b = Math.abs(y1-y0);
1438
+ var b1 = b & 1;
1439
+ var dx = 4*(1-a)*b*b;
1440
+ var dy = 4*(b1+1)*a*a;
1441
+ var err = dx + dy + b1*a*a;
1442
+ var e2;
1443
+
1444
+ // Left and right edges
1445
+ var left = [], right = [];
1446
+ left.min = right.min = Infinity;
1447
+
1448
+ if (x0 > x1) { x0 = x1; x1 += a; }
1449
+ if (y0 > y1) y0 = y1;
1450
+ y0 += ((b+1)/2)|0;
1451
+ y1 = y0 - b1;
1452
+ a *= 8*a; b1 = 8*b*b;
1453
+
1454
+ do {
1455
+ maxedge(right, x1, y0); // 1st quadrant
1456
+ minedge(left, x0, y0); // 2nd quadrant
1457
+ minedge(left, x0, y1); // 3rd quadrant
1458
+ maxedge(right, x1, y1); // 4th quadrant
1459
+ e2 = 2*err;
1460
+ if (e2 >= dx) { x0++; x1--; dx += b1; err += dx; }
1461
+ if (e2 <= dy) { y0++; y1--; dy += a; err += dy; }
1462
+ } while (x0 <= x1);
1463
+
1464
+ while (y0-y1 < b) { // too early stop of flat ellipse
1465
+ maxedge(right, x1+1, y0);
1466
+ minedge(left, x0-1, y0++);
1467
+ minedge(left, x0-1, y1);
1468
+ maxedge(right, x1+1, y1--);
1469
+ }
1470
+
1471
+ for (var y = left.min, max = left.length-1; y <= max; y++) {
1472
+ addPoint(left[y], y);
1473
+ }
1474
+ // The points we calculated are "inside". The fill algorithm excludes
1475
+ // right edges, so +1 on each x.
1476
+ for (var y = right.min, max = right.length-1; y <= max; y++) {
1477
+ addPoint(right[y]+1, y);
1478
+ }
1479
+
1480
+ function minedge(e, x, y) {
1481
+ if (e.min > y) e.min = y;
1482
+ var ey = e[y];
1483
+ if (ey == null || ey > x) {
1484
+ e[y] = x;
1485
+ }
1486
+ }
1487
+
1488
+ function maxedge(e, x, y) {
1489
+ if (e.min > y) e.min = y;
1490
+ var ey = e[y];
1491
+ if (ey == null || ey < x) {
1492
+ e[y] = x;
1493
+ }
1494
+ }
1495
+ }
1496
+
1497
+ // Returns true if outside the clipping region.
1498
+ function clipped(x, y) {
1499
+ var pts = gs_xyclip[y];
1500
+ if (!pts) {
1501
+ return true;
1502
+ }
1503
+ if (!pts.sorted) {
1504
+ pts.sort(function(a, b) { return a - b; });
1505
+ pts.sorted = true;
1506
+ }
1507
+
1508
+ var wn = false;
1509
+ for (var n = 0, npts = pts.length; n < npts; n++) {
1510
+ var xn = pts[n];
1511
+ if (xn > x) {
1512
+ return !wn;
1513
+ } else if (xn == x) {
1514
+ return wn;
1515
+ }
1516
+ wn = !wn;
1517
+ }
1518
+ return true;
1519
+ }
1520
+
1521
+ // Returns 1 if clockwise, -1 if ccw.
1522
+ function polydir(pts) {
1523
+ var xp = 0;
1524
+ for (var i = 0, l = pts.length, j = l-1; i < l; j = i++) {
1525
+ xp += pts[j][0] * pts[i][1] - pts[i][0] * pts[j][1];
1526
+ }
1527
+ return xp > 0 ? 1 : -1;
1528
+ }
1529
+ }
1530
+ // drawing-canvas.js
1531
+ //
1532
+ // `maybe` maybe the canvas, pre v4.0.
1533
+ function DrawingCanvas(canvas, maybe) {
1534
+ // Pre setops() backward compatibility
1535
+ if (maybe && maybe instanceof HTMLCanvasElement) {
1536
+ canvas = maybe;
1537
+ }
1538
+
1539
+ var img;
1540
+ var ctx = canvas.getContext('2d', { willReadFrequently:true });
1541
+ var drawing = DrawingBuiltin();
1542
+
1543
+ // Provide our specializations for the builtin drawing
1544
+ drawing.image = image;
1545
+ drawing.end = end;
1546
+
1547
+ // Reflect setopts() into the super
1548
+ var opts;
1549
+ var _setopts = drawing.setopts;
1550
+ drawing.setopts = function (options) {
1551
+ opts = options;
1552
+ _setopts && _setopts.call(drawing, options);
1553
+ };
1554
+
1555
+ return drawing;
1556
+
1557
+
1558
+ // Called by DrawingBuiltin.init() to get the ARGB bitmap for rendering.
1559
+ function image(width, height) {
1560
+ canvas.width = width;
1561
+ canvas.height = height;
1562
+
1563
+ // Set background
1564
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
1565
+ if (/^[0-9a-fA-F]{6}$/.test(''+opts.backgroundcolor)) {
1566
+ ctx.fillStyle = '#' + opts.backgroundcolor;
1567
+ ctx.fillRect(0, 0, width, height);
1568
+ } else {
1569
+ ctx.clearRect(0, 0, width, height);
1570
+ }
1571
+
1572
+ // Prepare the bitmap
1573
+ img = ctx.getImageData(0, 0, width, height);
1574
+
1575
+ // The return value is designed for both canvas pure-RGBA and PNG RGBA
1576
+ return { buffer:img.data, ispng:false };
1577
+ }
1578
+
1579
+ function end() {
1580
+ ctx.putImageData(img, 0, 0);
1581
+ return canvas;
1582
+ }
1583
+ }
1584
+ // drawing-svg.js
1585
+ //
1586
+ // Converts the drawing primitives into the equivalent SVG. Linear barcodes
1587
+ // are rendered as a series of stroked paths. 2D barcodes are rendered as a
1588
+ // series of filled paths.
1589
+ //
1590
+ // Rotation is handled during drawing. The resulting SVG will contain the
1591
+ // already-rotated barcode without an SVG transform.
1592
+ //
1593
+ // If the requested barcode image contains text, the glyph paths are
1594
+ // extracted from the font file (via the builtin FontLib and stb_truetype.js)
1595
+ // and added as filled SVG paths.
1596
+ //
1597
+ function DrawingSVG() {
1598
+ // Unrolled x,y rotate/translate matrix
1599
+ var tx0 = 0, tx1 = 0, tx2 = 0, tx3 = 0;
1600
+ var ty0 = 0, ty1 = 0, ty2 = 0, ty3 = 0;
1601
+
1602
+ var opts;
1603
+ var svg = '';
1604
+ var path;
1605
+ var clipid = '';
1606
+ var clips = [];
1607
+ var lines = {};
1608
+
1609
+ // We adjust the drawing coordinates by 0.5px when stroke width is odd.
1610
+ // But this creates an odd effect with scale. When scale is even, we
1611
+ // need to add 0.5; when scale is odd, subtract 0.5.
1612
+ var scalex, scaley;
1613
+
1614
+ // Magic number to approximate an ellipse/circle using 4 cubic beziers.
1615
+ var ELLIPSE_MAGIC = 0.55228475 - 0.00045;
1616
+
1617
+ // Global graphics state
1618
+ var gs_width, gs_height; // image size, in pixels
1619
+ var gs_dx, gs_dy; // x,y translate (padding)
1620
+
1621
+ return {
1622
+ // setopts() is called after the options are fixed-up/normalized,
1623
+ // but before calling into BWIPP.
1624
+ // This allows omitting the options in the constructor call.
1625
+ // It is also your last chance to amend the options before usage.
1626
+ setopts(options) {
1627
+ opts = options;
1628
+ },
1629
+
1630
+ // measure() and scale() are the only drawing primitives that are called before init().
1631
+
1632
+ // Make no adjustments
1633
+ scale(sx, sy) {
1634
+ scalex = sx;
1635
+ scaley = sy;
1636
+ },
1637
+ // Measure text.
1638
+ // `font` is the font name typically OCR-A or OCR-B.
1639
+ // `fwidth` and `fheight` are the requested font cell size. They will
1640
+ // usually be the same, except when the scaling is not symetric.
1641
+ measure(str, font, fwidth, fheight) {
1642
+ fwidth = fwidth|0;
1643
+ fheight = fheight|0;
1644
+
1645
+ var fontid = FontLib.lookup(font);
1646
+ var width = 0;
1647
+ var ascent = 0;
1648
+ var descent = 0;
1649
+ for (var i = 0, l = str.length; i < l; i++) {
1650
+ var ch = str.charCodeAt(i);
1651
+ var glyph = FontLib.getglyph(fontid, ch, fwidth, fheight);
1652
+ if (!glyph) {
1653
+ continue;
1654
+ }
1655
+ ascent = Math.max(ascent, glyph.top);
1656
+ descent = Math.max(descent, glyph.height - glyph.top);
1657
+ if (i == l-1) {
1658
+ width += glyph.left + glyph.width;
1659
+ } else {
1660
+ width += glyph.advance;
1661
+ }
1662
+ }
1663
+ return { width, ascent, descent };
1664
+ },
1665
+
1666
+ // `width` and `height` represent the maximum bounding box the graphics will
1667
+ // occupy. The dimensions are for an unrotated rendering. Adjust as necessary.
1668
+ init(width, height) {
1669
+ // Add in the effects of padding. These are always set before the
1670
+ // drawing constructor is called.
1671
+ var padl = opts.paddingleft;
1672
+ var padr = opts.paddingright;
1673
+ var padt = opts.paddingtop;
1674
+ var padb = opts.paddingbottom;
1675
+ var rot = opts.rotate || 'N';
1676
+
1677
+ width += padl + padr;
1678
+ height += padt + padb;
1679
+
1680
+ // Transform indexes are: x, y, w, h
1681
+ switch (rot) {
1682
+ // tx = w-y, ty = x
1683
+ case 'R': tx1 = -1; tx2 = 1; ty0 = 1; break;
1684
+ // tx = w-x, ty = h-y
1685
+ case 'I': tx0 = -1; tx2 = 1; ty1 = -1; ty3 = 1; break;
1686
+ // tx = y, ty = h-x
1687
+ case 'L': tx1 = 1; ty0 = -1; ty3 = 1; break;
1688
+ // tx = x, ty = y
1689
+ default: tx0 = ty1 = 1; break;
1690
+ }
1691
+
1692
+ // Setup the graphics state
1693
+ var swap = rot == 'L' || rot == 'R';
1694
+ gs_width = swap ? height : width;
1695
+ gs_height = swap ? width : height;
1696
+ gs_dx = padl;
1697
+ gs_dy = padt;
1698
+ },
1699
+ // Unconnected stroked lines are used to draw the bars in linear barcodes.
1700
+ // No line cap should be applied. These lines are always orthogonal.
1701
+ line(x0, y0, x1, y1, lw, rgb) {
1702
+ x0 = x0|0;
1703
+ y0 = y0|0;
1704
+ x1 = x1|0;
1705
+ y1 = y1|0;
1706
+ lw = Math.round(lw) || 1;
1707
+
1708
+ // Try to keep the lines "crisp" by using with the SVG line drawing spec to
1709
+ // our advantage and adjust the coordinates by half pixel when stroke width
1710
+ // is odd. Work around an odd effect with scale. When scale is even, we
1711
+ // need to add 0.5; when scale is odd, subtract 0.5.
1712
+ if (lw & 1) {
1713
+ if (x0 == x1) {
1714
+ let dx = (scalex&1) ? -0.5 : 0.5;
1715
+ x0 += dx;
1716
+ x1 += dx;
1717
+ }
1718
+ if (y0 == y1) {
1719
+ let dy = (scaley&1) ? -0.5 : 0.5;
1720
+ y0 += dy;
1721
+ y1 += dy;
1722
+ }
1723
+ }
1724
+ // The svg path does not include the start pixel, but the built-in drawing does.
1725
+ if (x0 == x1) {
1726
+ y0++;
1727
+ } else if (y0 == y1) {
1728
+ x0++;
1729
+ }
1730
+
1731
+ // Group together all lines of the same width and emit as single paths.
1732
+ // Dramatically reduces the svg text size.
1733
+ var key = '' + lw + '#' + rgb;
1734
+ if (!lines[key]) {
1735
+ lines[key] = '<path stroke="#' + rgb + '" stroke-width="' + lw + '" d="';
1736
+ }
1737
+ lines[key] += 'M' + transform(x0, y0) + 'L' + transform(x1, y1);
1738
+ },
1739
+ // Polygons are used to draw the connected regions in a 2d barcode.
1740
+ // These will always be unstroked, filled, non-intersecting,
1741
+ // orthogonal shapes.
1742
+ // You will see a series of polygon() calls, followed by a fill().
1743
+ polygon(pts) {
1744
+ if (!path) {
1745
+ path = '<path d="';
1746
+ }
1747
+ path += 'M' + transform(pts[0][0], pts[0][1]);
1748
+ for (var i = 1, n = pts.length; i < n; i++) {
1749
+ var p = pts[i];
1750
+ path += 'L' + transform(p[0], p[1]);
1751
+ }
1752
+ path += 'Z';
1753
+ },
1754
+ // An unstroked, filled hexagon used by maxicode. You can choose to fill
1755
+ // each individually, or wait for the final fill().
1756
+ //
1757
+ // The hexagon is drawn from the top, counter-clockwise.
1758
+ hexagon(pts, rgb) {
1759
+ this.polygon(pts); // A hexagon is just a polygon...
1760
+ },
1761
+ // An unstroked, filled ellipse. Used by dotcode and maxicode at present.
1762
+ // maxicode issues pairs of ellipse calls (one cw, one ccw) followed by a fill()
1763
+ // to create the bullseye rings. dotcode issues all of its ellipses then a
1764
+ // fill().
1765
+ ellipse(x, y, rx, ry, ccw) {
1766
+ if (!path) {
1767
+ path = '<path d="';
1768
+ }
1769
+ var dx = rx * ELLIPSE_MAGIC;
1770
+ var dy = ry * ELLIPSE_MAGIC;
1771
+
1772
+ // Since there are never overlapping regions, we don't worry about cw/ccw.
1773
+ path += 'M' + transform(x - rx, y) +
1774
+ 'C' + transform(x - rx, y - dy) + ' ' +
1775
+ transform(x - dx, y - ry) + ' ' +
1776
+ transform(x, y - ry) +
1777
+ 'C' + transform(x + dx, y - ry) + ' ' +
1778
+ transform(x + rx, y - dy) + ' ' +
1779
+ transform(x + rx, y) +
1780
+ 'C' + transform(x + rx, y + dy) + ' ' +
1781
+ transform(x + dx, y + ry) + ' ' +
1782
+ transform(x, y + ry) +
1783
+ 'C' + transform(x - dx, y + ry) + ' ' +
1784
+ transform(x - rx, y + dy) + ' ' +
1785
+ transform(x - rx, y) +
1786
+ 'Z';
1787
+ },
1788
+ // PostScript's default fill rule is non-zero but there are never intersecting
1789
+ // regions. The built-in drawing uses even-odd for simplicity - we match that
1790
+ // to be consistent.
1791
+ fill(rgb) {
1792
+ if (path) {
1793
+ svg += path + '" fill="#' + rgb + '" fill-rule="evenodd"' +
1794
+ (clipid ? ' clip-path="url(#' + clipid + ')"' : '') +
1795
+ ' />\n';
1796
+ path = null;
1797
+ }
1798
+ },
1799
+ // Currently only used by swissqrcode. The `polys` area is an array of
1800
+ // arrays of points. Each array of points is identical to the `pts`
1801
+ // parameter passed to polygon(). The clipping rule, like the fill rule,
1802
+ // defaults to non-zero winding.
1803
+ clip : function(polys) {
1804
+ var path = '<clipPath id="clip' + clips.length + '"><path d="';
1805
+ for (let j = 0; j < polys.length; j++) {
1806
+ let pts = polys[j];
1807
+ path += 'M' + transform(pts[0][0], pts[0][1]);
1808
+ for (var i = 1, n = pts.length; i < n; i++) {
1809
+ var p = pts[i];
1810
+ path += 'L' + transform(p[0], p[1]);
1811
+ }
1812
+ path += 'Z';
1813
+ }
1814
+ path += '" clip-rule="nonzero" /></clipPath>';
1815
+ clipid = "clip" + clips.length;
1816
+ clips.push(path);
1817
+ },
1818
+ unclip : function() {
1819
+ clipid = '';
1820
+ },
1821
+ // Draw text with optional inter-character spacing. `y` is the baseline.
1822
+ // font is an object with properties { name, width, height, dx }
1823
+ // width and height are the font cell size.
1824
+ // dx is extra space requested between characters (usually zero).
1825
+ text(x, y, str, rgb, font) {
1826
+ var fontid = FontLib.lookup(font.name);
1827
+ var fwidth = font.width|0;
1828
+ var fheight = font.height|0;
1829
+ var dx = font.dx|0;
1830
+ var path = '';
1831
+ for (var k = 0; k < str.length; k++) {
1832
+ var ch = str.charCodeAt(k);
1833
+ var glyph = FontLib.getpaths(fontid, ch, fwidth, fheight);
1834
+ if (!glyph) {
1835
+ continue;
1836
+ }
1837
+ if (glyph.length) {
1838
+ // A glyph is composed of sequence of curve and line segments.
1839
+ // M is move-to
1840
+ // L is line-to
1841
+ // Q is quadratic bezier curve-to
1842
+ // C is cubic bezier curve-to
1843
+ for (var i = 0, l = glyph.length; i < l; i++) {
1844
+ let seg = glyph[i];
1845
+ if (seg.type == 'M' || seg.type == 'L') {
1846
+ path += seg.type + transform(seg.x + x, y - seg.y);
1847
+ } else if (seg.type == 'Q') {
1848
+ path += seg.type + transform(seg.cx + x, y - seg.cy) + ' ' +
1849
+ transform(seg.x + x, y - seg.y);
1850
+ } else if (seg.type == 'C') {
1851
+ path += seg.type + transform(seg.cx1 + x, y - seg.cy1) + ' ' +
1852
+ transform(seg.cx2 + x, y - seg.cy2) + ' ' +
1853
+ transform(seg.x + x, y - seg.y);
1854
+ }
1855
+ }
1856
+ // Close the shape
1857
+ path += 'Z';
1858
+ }
1859
+ // getglyph() provides slightly different metrics than getpaths(). Keep
1860
+ // it consistent with the built-in drawing.
1861
+ x += FontLib.getglyph(fontid, ch, fwidth, fheight).advance + dx;
1862
+ }
1863
+ if (path) {
1864
+ svg += '<path d="' + path + '" fill="#' + rgb + '" />\n';
1865
+ }
1866
+ },
1867
+ // Called after all drawing is complete. The return value from this method
1868
+ // will be the return value from `bwipjs.render()`.
1869
+ end() {
1870
+ var linesvg = '';
1871
+ for (var key in lines) {
1872
+ linesvg += lines[key] + '" />\n';
1873
+ }
1874
+ var bg = opts.backgroundcolor;
1875
+ return '<svg viewBox="0 0 ' + gs_width + ' ' + gs_height + '" xmlns="http://www.w3.org/2000/svg">\n' +
1876
+ (clips.length ? '<defs>' + clips.join('') + '</defs>' : '') +
1877
+ (/^[0-9A-Fa-f]{6}$/.test(''+bg)
1878
+ ? '<rect width="100%" height="100%" fill="#' + bg + '" />\n'
1879
+ : '') +
1880
+ linesvg + svg + '</svg>\n';
1881
+ },
1882
+ };
1883
+
1884
+ // translate/rotate and return as an SVG coordinate pair
1885
+ function transform(x, y) {
1886
+ x += gs_dx;
1887
+ y += gs_dy;
1888
+ var tx = tx0 * x + tx1 * y + tx2 * (gs_width-1) + tx3 * (gs_height-1);
1889
+ var ty = ty0 * x + ty1 * y + ty2 * (gs_width-1) + ty3 * (gs_height-1);
1890
+ return '' + ((tx|0) == tx ? tx : tx.toFixed(2)) + ' ' +
1891
+ ((ty|0) == ty ? ty : ty.toFixed(2));
1892
+ }
1893
+ }
1894
+ // fontlib.js
1895
+ var FontLib = (function() {
1896
+ var fonts = [];
1897
+ var names = {};
1898
+ var glyphcache = {};
1899
+ var glyphmru = {};
1900
+ var glyphcount = 0;
1901
+
1902
+ // Sentinel to simplify moving entries around in the list.
1903
+ glyphmru.next = glyphmru;
1904
+ glyphmru.prev = glyphmru;
1905
+
1906
+ return {
1907
+ lookup:lookup,
1908
+ monochrome:monochrome,
1909
+ getglyph:getglyph,
1910
+ getpaths:getpaths,
1911
+ loadFont:loadFont,
1912
+ };
1913
+
1914
+ // loadFont(name, data)
1915
+ // loadFont(name, mult, data)
1916
+ // loadFont(name, multy, multx, data) // note order: y,x
1917
+ // data must be the font data, either a binary or base64 encoded string.
1918
+ function loadFont(name /*...args*/) {
1919
+ var multx = 100;
1920
+ var multy = 100;
1921
+ var data = null;
1922
+
1923
+ if (arguments.length == 2) {
1924
+ data = arguments[1];
1925
+ } else if (arguments.length == 3) {
1926
+ multx = multy = +arguments[1] || 100;
1927
+ data = arguments[2];
1928
+ } else if (arguments.length == 4) {
1929
+ multy = +arguments[1] || 100;
1930
+ multx = +arguments[2] || 100;
1931
+ data = arguments[3];
1932
+ } else {
1933
+ throw new Error("bwipjs: loadFont: invalid number of arguments");
1934
+ }
1935
+
1936
+ var font = STBTT.InitFont(toUint8Array(data));
1937
+ font.bwipjs_name = name;
1938
+ font.bwipjs_multx = multx;
1939
+ font.bwipjs_multy = multy;
1940
+
1941
+ var fontid = fonts.push(font)-1;
1942
+ names[name.toUpperCase()] = fontid;
1943
+ return fontid;
1944
+ }
1945
+
1946
+ // Always returns a valid font-id (default OCR-B)
1947
+ function lookup(name) {
1948
+ var fontid = names[name.toUpperCase()];
1949
+ return fontid === undefined ? 1 : fontid; // OCR B default
1950
+ }
1951
+
1952
+ // Not supported by stbtt
1953
+ function monochrome(mono) {
1954
+ if (mono) {
1955
+ throw new Error('bwipjs: monochrome fonts not implemented');
1956
+ }
1957
+ }
1958
+
1959
+ function getglyph(fontid, charcode, width, height) {
1960
+ fontid = fontid|0;
1961
+ charcode = charcode|0;
1962
+ width = +width;
1963
+ height = +height;
1964
+ if (!width || width < 8) {
1965
+ width = 8;
1966
+ }
1967
+ if (!height || height < 8) {
1968
+ height = width;
1969
+ }
1970
+ if (fontid < 0 || fontid >= fonts.length) {
1971
+ fontid = 1; // OCR B default
1972
+ }
1973
+ if (!charcode || charcode < 32) {
1974
+ charcode = 32;
1975
+ }
1976
+
1977
+ // In the cache?
1978
+ var cachekey = '' + fontid + 'c' + charcode + 'w' + width + 'h' + height;
1979
+ var glyph = glyphcache[cachekey];
1980
+ if (glyph) {
1981
+ // Unthread from the MRU
1982
+ glyph.prev.next = glyph.next;
1983
+ glyph.next.prev = glyph.prev;
1984
+
1985
+ // Thread back onto the top
1986
+ var sntl = glyphmru;
1987
+ sntl.next.prev = glyph;
1988
+ glyph.next = sntl.next;
1989
+ glyph.prev = sntl;
1990
+ sntl.next = glyph;
1991
+
1992
+ return glyph;
1993
+ }
1994
+
1995
+ var font = fonts[fontid];
1996
+ var glyph = STBTT.GetGlyph(font, charcode, width * font.bwipjs_multx / 100,
1997
+ height * font.bwipjs_multy / 100) ||
1998
+ STBTT.GetGlyph(font, 0, width * font.bwipjs_multx / 100,
1999
+ height * font.bwipjs_multy / 100);
2000
+
2001
+ glyph.bytes = glyph.pixels;
2002
+ glyph.cachekey = cachekey;
2003
+ glyph.offset = 0;
2004
+
2005
+ //glyph = {
2006
+ // top:font.GlyphTop(),
2007
+ // left:font.GlyphLeft(),
2008
+ // width:font.GlyphWidth(),
2009
+ // height:font.GlyphHeight(),
2010
+ // advance:font.GlyphAdvance(),
2011
+ // bitmap:font.GlyphBitmap(),
2012
+ // offset:0,
2013
+ // cachekey:cachekey,
2014
+ // };
2015
+
2016
+ // Purge old
2017
+ if (glyphcount > 250) {
2018
+ var sntl = glyphmru;
2019
+ var temp = sntl.prev;
2020
+ temp.prev.next = sntl;
2021
+ sntl.prev = temp.prev;
2022
+ temp.next = temp.prev = null;
2023
+ delete glyphcache[temp.cachekey];
2024
+ } else {
2025
+ glyphcount++;
2026
+ }
2027
+
2028
+ // Add to cache and to the top of the MRU
2029
+ glyphcache[cachekey] = glyph;
2030
+
2031
+ var sntl = glyphmru;
2032
+ sntl.next.prev = glyph;
2033
+ glyph.next = sntl.next;
2034
+ glyph.prev = sntl;
2035
+ sntl.next = glyph;
2036
+
2037
+ return glyph;
2038
+ }
2039
+
2040
+ function getpaths(fontid, charcode, width, height) {
2041
+ fontid = fontid|0;
2042
+ charcode = charcode|0;
2043
+ width = +width;
2044
+ height = +height;
2045
+ if (!width || width < 8) {
2046
+ width = 8;
2047
+ }
2048
+ if (!height || height < 8) {
2049
+ height = width;
2050
+ }
2051
+ if (fontid < 0 || fontid >= fonts.length) {
2052
+ fontid = 1; // OCR B default
2053
+ }
2054
+ if (!charcode || charcode < 32) {
2055
+ charcode = 32;
2056
+ }
2057
+
2058
+ var font = fonts[fontid];
2059
+ return STBTT.GetPaths(font, charcode, width * font.bwipjs_multx / 100,
2060
+ height * font.bwipjs_multy / 100);
2061
+ }
2062
+ })();
2063
+
2064
+ // This is needed to make the default exports traceable by esbuild
2065
+ // during its tree shaking phase. See issue #298.
2066
+ function LoadFont() {
2067
+ return FontLib.loadFont.apply(FontLib, Array.prototype.slice.call(arguments));
2068
+ }
2069
+ // bwip-js/stb_trutype.js
2070
+ //
2071
+ // JavaScript implementation of stb_truetype.h @ https://github.com/nothings/stb.
2072
+ //
2073
+ // This file is part of the bwip-js project available at:
2074
+ //
2075
+ // http://metafloor.github.io/bwip-js
2076
+ //
2077
+ // Copyright (c) 2019 Mark Warren : MIT LICENSE
2078
+
2079
+ // Copyright notice from stb_truetype.h:
2080
+ //
2081
+ // MIT License
2082
+ //
2083
+ // Copyright (c) 2017 Sean Barrett
2084
+ //
2085
+ // Permission is hereby granted, free of charge, to any person obtaining a copy of
2086
+ // this software and associated documentation files (the "Software"), to deal in
2087
+ // the Software without restriction, including without limitation the rights to
2088
+ // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
2089
+ // of the Software, and to permit persons to whom the Software is furnished to do
2090
+ // so, subject to the following conditions:
2091
+ // The above copyright notice and this permission notice shall be included in all
2092
+ // copies or substantial portions of the Software.
2093
+ //
2094
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2095
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2096
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2097
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2098
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2099
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2100
+ // SOFTWARE.
2101
+
2102
+ var STBTT = (function () {
2103
+
2104
+ var STBTT_vmove = 1,
2105
+ STBTT_vline = 2,
2106
+ STBTT_vcurve = 3,
2107
+ STBTT_vcubic = 4,
2108
+
2109
+ STBTT_PLATFORM_ID_UNICODE = 0,
2110
+ STBTT_PLATFORM_ID_MAC = 1,
2111
+ STBTT_PLATFORM_ID_ISO = 2,
2112
+ STBTT_PLATFORM_ID_MICROSOFT = 3,
2113
+
2114
+ STBTT_UNICODE_EID_UNICODE_1_0 = 0,
2115
+ STBTT_UNICODE_EID_UNICODE_1_1 = 1,
2116
+ STBTT_UNICODE_EID_ISO_10646 = 2,
2117
+ STBTT_UNICODE_EID_UNICODE_2_0_BMP = 3,
2118
+ STBTT_UNICODE_EID_UNICODE_2_0_FULL = 4,
2119
+
2120
+ STBTT_MS_EID_SYMBOL = 0,
2121
+ STBTT_MS_EID_UNICODE_BMP = 1,
2122
+ STBTT_MS_EID_SHIFTJIS = 2,
2123
+ STBTT_MS_EID_UNICODE_FULL = 10;
2124
+
2125
+ var floor = Math.floor;
2126
+ var ceil = Math.ceil;
2127
+ var sqrt = Math.sqrt;
2128
+ var abs = Math.abs;
2129
+
2130
+ // Allocate an array of objects - replaces malloc(sizeof struct * n)
2131
+ function oalloc(n) {
2132
+ var o = [];
2133
+ for (var i = 0; i < n; i++) {
2134
+ o.push({});
2135
+ }
2136
+ return o;
2137
+ }
2138
+
2139
+ //static unsigned char stbtt__buf_get8(stbtt__buf * b)
2140
+ function stbtt__buf_get8(b) {
2141
+ return b[b.cursor++]||0;
2142
+ }
2143
+
2144
+ //static unsigned char stbtt__buf_peek8(stbtt__buf * b)
2145
+ function stbtt__buf_peek8(b) {
2146
+ return b[b.cursor];
2147
+ }
2148
+
2149
+ //static void stbtt__buf_seek(stbtt__buf * b, int o)
2150
+ function stbtt__buf_seek(b, o) {
2151
+ b.cursor = (o > b.length || o < 0) ? b.length : o;
2152
+ }
2153
+
2154
+ //static void stbtt__buf_skip(stbtt__buf * b, int o)
2155
+ function stbtt__buf_skip(b, o) {
2156
+ stbtt__buf_seek(b, b.cursor + o);
2157
+ }
2158
+
2159
+ //static unsigned int stbtt__buf_get(stbtt__buf * b, int n)
2160
+ function stbtt__buf_get(b, n) {
2161
+ var v = 0;
2162
+ for (var i = 0; i < n; i++) {
2163
+ v = (v << 8) | stbtt__buf_get8(b);
2164
+ }
2165
+ return v;
2166
+ }
2167
+
2168
+ // This function is only called once with a real 'p', all other uses are
2169
+ // for a NULL buffer. The for real usage, the code is inlined.
2170
+ //static stbtt__buf stbtt__new_buf(const void *p, int size)
2171
+ function stbtt__null_buf() {
2172
+ return { length:0 };
2173
+ }
2174
+
2175
+ //static stbtt__buf stbtt__buf_range(const stbtt__buf * b, int o, int s)
2176
+ function stbtt__buf_range(b, o, s) {
2177
+ if (o < 0 || s < 0 || o > b.length || s > b.length - o) {
2178
+ return stbtt__null_buf();
2179
+ }
2180
+ var r = b.subarray(o, o + s);
2181
+ r.cursor = 0;
2182
+ return r;
2183
+ }
2184
+
2185
+ //static stbtt__buf stbtt__cff_get_index(stbtt__buf * b)
2186
+ function stbtt__cff_get_index(b) {
2187
+ var start = b.cursor;
2188
+ var count = stbtt__buf_get(b, 2);
2189
+ if (count) {
2190
+ var offsize = stbtt__buf_get8(b);
2191
+ stbtt__buf_skip(b, offsize * count);
2192
+ stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1);
2193
+ }
2194
+ return stbtt__buf_range(b, start, b.cursor - start);
2195
+ }
2196
+
2197
+ //static unsigned int stbtt__cff_int(stbtt__buf * b)
2198
+ function stbtt__cff_int(b) {
2199
+ var b0 = stbtt__buf_get8(b);
2200
+ if (b0 >= 32 && b0 <= 246) {
2201
+ return b0 - 139;
2202
+ } else if (b0 >= 247 && b0 <= 250) {
2203
+ return (b0 - 247) * 256 + stbtt__buf_get8(b) + 108;
2204
+ } else if (b0 >= 251 && b0 <= 254) {
2205
+ return -(b0 - 251) * 256 - stbtt__buf_get8(b) - 108;
2206
+ } else if (b0 == 28) {
2207
+ return stbtt__buf_get(b, 2);
2208
+ } else if (b0 == 29) {
2209
+ return stbtt__buf_get(b, 4);
2210
+ }
2211
+ return 0;
2212
+ }
2213
+
2214
+ //static void stbtt__cff_skip_operand(stbtt__buf * b)
2215
+ function stbtt__cff_skip_operand(b) {
2216
+ var b0 = stbtt__buf_peek8(b);
2217
+ if (b0 == 30) {
2218
+ stbtt__buf_skip(b, 1);
2219
+ while (b.cursor < b.length) {
2220
+ var v = stbtt__buf_get8(b);
2221
+ if ((v & 0xF) == 0xF || (v >> 4) == 0xF) {
2222
+ break;
2223
+ }
2224
+ }
2225
+ } else {
2226
+ stbtt__cff_int(b);
2227
+ }
2228
+ }
2229
+
2230
+ //static stbtt__buf stbtt__dict_get(stbtt__buf * b, int key)
2231
+ function stbtt__dict_get(b, key) {
2232
+ stbtt__buf_seek(b, 0);
2233
+ while (b.cursor < b.length) {
2234
+ var start = b.cursor, end, op;
2235
+ while (stbtt__buf_peek8(b) >= 28) {
2236
+ stbtt__cff_skip_operand(b);
2237
+ }
2238
+ end = b.cursor;
2239
+ op = stbtt__buf_get8(b);
2240
+ if (op == 12) {
2241
+ op = stbtt__buf_get8(b) | 0x100;
2242
+ }
2243
+ if (op == key) {
2244
+ return stbtt__buf_range(b, start, end - start);
2245
+ }
2246
+ }
2247
+ return stbtt__buf_range(b, 0, 0);
2248
+ }
2249
+
2250
+ //static void stbtt__dict_get_ints(stbtt__buf * b, int key, int outcount, unsigned int *out)
2251
+ function stbtt__dict_get_ints(b, key, outcount, out) {
2252
+ var operands = stbtt__dict_get(b, key);
2253
+ for (var i = 0; i < outcount && operands.cursor < operands.length; i++) {
2254
+ out[i] = stbtt__cff_int(operands);
2255
+ }
2256
+ }
2257
+ // single-integer format of above since javascript doesn't have address-of
2258
+ function stbtt__dict_get_int(b, key, out) {
2259
+ var operands = stbtt__dict_get(b, key);
2260
+ if (operands.cursor < operands.length) {
2261
+ out = stbtt__cff_int(operands);
2262
+ }
2263
+ return out;
2264
+ }
2265
+
2266
+ //static int stbtt__cff_index_count(stbtt__buf * b)
2267
+ function stbtt__cff_index_count(b) {
2268
+ stbtt__buf_seek(b, 0);
2269
+ return stbtt__buf_get(b, 2);
2270
+ }
2271
+
2272
+ //static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int i)
2273
+ function stbtt__cff_index_get(b, i) {
2274
+ var count, offsize, start, end;
2275
+ stbtt__buf_seek(b, 0);
2276
+ count = stbtt__buf_get(b, 2);
2277
+ offsize = stbtt__buf_get8(b);
2278
+ stbtt__buf_skip(b, i * offsize);
2279
+ start = stbtt__buf_get(b, offsize);
2280
+ end = stbtt__buf_get(b, offsize);
2281
+ return stbtt__buf_range(b, 2 + (count + 1) * offsize + start, end - start);
2282
+ }
2283
+
2284
+ // Convert sign-extend a 16-bit integer to JS number
2285
+ function INT16(n) {
2286
+ return n & 0x8000 ? (0xffff0000|n)>>0 : n;
2287
+ }
2288
+
2289
+ //static unsigned short ttUSHORT(unsigned char *p)
2290
+ function ttUSHORT(b, o) {
2291
+ return b[o] * 256 + b[o+1];
2292
+ }
2293
+
2294
+ //static short ttSHORT(unsigned char *p)
2295
+ function ttSHORT(b, o) {
2296
+ var n = b[o] * 256 + b[o+1];
2297
+ return n & 0x8000 ? (0xffff0000|n)>>0 : n;
2298
+ }
2299
+
2300
+ //static unsigned int ttULONG(unsigned char *p)
2301
+ function ttULONG(b, o) {
2302
+ return (b[o] << 24) + (b[o+1] << 16) + (b[o+2] << 8) + b[o+3];
2303
+ }
2304
+
2305
+ //static unsigned int stbtt__find_table(unsigned char *data, unsigned int fontstart, const char *tag)
2306
+ function stbtt__find_table(data, fontstart, tag) {
2307
+ var num_tables = ttUSHORT(data, fontstart + 4);
2308
+ var tabledir = fontstart + 12;
2309
+ for (var i = 0; i < num_tables; ++i) {
2310
+ var loc = tabledir + 16 * i;
2311
+ if (data[loc] == tag[0] && data[loc+1] == tag[1] && data[loc+2] == tag[2] && data[loc+3] == tag[3]) {
2312
+ return ttULONG(data, loc + 8);
2313
+ }
2314
+ }
2315
+ return 0;
2316
+ }
2317
+
2318
+ //static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict)
2319
+ function stbtt__get_subrs(cff, fontdict) {
2320
+ var private_loc = [ 0, 0 ];
2321
+ stbtt__dict_get_ints(fontdict, 18, 2, private_loc);
2322
+ if (!private_loc[1] || !private_loc[0]) {
2323
+ return stbtt__null_buf();
2324
+ }
2325
+ var pdict = stbtt__buf_range(cff, private_loc[1], private_loc[0]);
2326
+ var subrsoff = stbtt__dict_get_int(pdict, 19, 0);
2327
+ if (!subrsoff) {
2328
+ return stbtt__null_buf();
2329
+ }
2330
+ stbtt__buf_seek(cff, private_loc[1] + subrsoff);
2331
+ return stbtt__cff_get_index(cff);
2332
+ }
2333
+
2334
+ //static int stbtt_InitFont_internal(stbtt_fontinfo * info, unsigned char *data, int fontstart)
2335
+ function stbtt_InitFont_internal(info, data, fontstart) {
2336
+ var cmap, t, i, numTables;
2337
+
2338
+ info.data = data;
2339
+ info.fontstart = fontstart;
2340
+ info.cff = stbtt__null_buf();
2341
+
2342
+ cmap = stbtt__find_table(data, fontstart, [ 99, 109, 97, 112 ]); //"cmap"
2343
+ info.loca = stbtt__find_table(data, fontstart, [ 108, 111, 99, 97 ]); //"loca"
2344
+ info.head = stbtt__find_table(data, fontstart, [ 104, 101, 97, 100 ]); //"head"
2345
+ info.glyf = stbtt__find_table(data, fontstart, [ 103, 108, 121, 102 ]); //"glyf"
2346
+ info.hhea = stbtt__find_table(data, fontstart, [ 104, 104, 101, 97 ]); //"hhea"
2347
+ info.hmtx = stbtt__find_table(data, fontstart, [ 104, 109, 116, 120 ]); //"hmtx"
2348
+ info.kern = stbtt__find_table(data, fontstart, [ 107, 101, 114, 110 ]); //"kern"
2349
+
2350
+ if (!cmap || !info.head || !info.hhea || !info.hmtx) {
2351
+ return 0;
2352
+ }
2353
+ if (info.glyf) {
2354
+ if (!info.loca) {
2355
+ return 0;
2356
+ }
2357
+ } else {
2358
+ var b, topdict, topdictidx, cff,
2359
+ cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0;
2360
+
2361
+ cff = stbtt__find_table(data, fontstart, [ 67, 70, 70, 32 ]); //"CFF "
2362
+ if (!cff) {
2363
+ return 0;
2364
+ }
2365
+
2366
+ info.fontdicts = stbtt__null_buf();
2367
+ info.fdselect = stbtt__null_buf();
2368
+
2369
+ info.cff = data.subarray(cff); //stbtt__new_buf(data + cff, 512 * 1024 * 1024);
2370
+ info.cff.cursor = 0;
2371
+ b = info.cff;
2372
+
2373
+ stbtt__buf_skip(b, 2);
2374
+ stbtt__buf_seek(b, stbtt__buf_get8(b));
2375
+
2376
+ stbtt__cff_get_index(b);
2377
+ topdictidx = stbtt__cff_get_index(b);
2378
+ topdict = stbtt__cff_index_get(topdictidx, 0);
2379
+ stbtt__cff_get_index(b);
2380
+ info.gsubrs = stbtt__cff_get_index(b);
2381
+
2382
+ charstrings = stbtt__dict_get_int(topdict, 17, charstrings);
2383
+ cstype = stbtt__dict_get_int(topdict, 0x100 | 6, cstype);
2384
+ fdarrayoff = stbtt__dict_get_int(topdict, 0x100 | 36, fdarrayoff);
2385
+ fdselectoff = stbtt__dict_get_int(topdict, 0x100 | 37, fdselectoff);
2386
+ info.subrs = stbtt__get_subrs(b, topdict);
2387
+
2388
+ if (cstype != 2) {
2389
+ return 0;
2390
+ }
2391
+ if (charstrings == 0) {
2392
+ return 0;
2393
+ }
2394
+
2395
+ if (fdarrayoff) {
2396
+ if (!fdselectoff) {
2397
+ return 0;
2398
+ }
2399
+ stbtt__buf_seek(b, fdarrayoff);
2400
+ info.fontdicts = stbtt__cff_get_index(b);
2401
+ info.fdselect = stbtt__buf_range(b, fdselectoff, b.length - fdselectoff);
2402
+ }
2403
+
2404
+ stbtt__buf_seek(b, charstrings);
2405
+ info.charstrings = stbtt__cff_get_index(b);
2406
+ }
2407
+
2408
+ t = stbtt__find_table(data, fontstart, [ 109, 97, 120, 112 ]); //"maxp"
2409
+ if (t) {
2410
+ info.numGlyphs = ttUSHORT(data, t + 4);
2411
+ }
2412
+ else {
2413
+ info.numGlyphs = 0xffff;
2414
+ }
2415
+
2416
+ numTables = ttUSHORT(data, cmap + 2);
2417
+ info.index_map = 0;
2418
+ for (i = 0; i < numTables; ++i) {
2419
+ var encoding_record = cmap + 4 + 8 * i;
2420
+
2421
+ switch (ttUSHORT(data, encoding_record)) {
2422
+ case STBTT_PLATFORM_ID_MICROSOFT:
2423
+ switch (ttUSHORT(data, encoding_record + 2)) {
2424
+ case STBTT_MS_EID_UNICODE_BMP:
2425
+ case STBTT_MS_EID_UNICODE_FULL:
2426
+ info.index_map = cmap + ttULONG(data, encoding_record + 4);
2427
+ break;
2428
+ }
2429
+ break;
2430
+ case STBTT_PLATFORM_ID_UNICODE:
2431
+ info.index_map = cmap + ttULONG(data, encoding_record + 4);
2432
+ break;
2433
+ }
2434
+ }
2435
+ if (info.index_map == 0) {
2436
+ return 0;
2437
+ }
2438
+
2439
+ info.indexToLocFormat = ttUSHORT(data, info.head + 50);
2440
+ return 1;
2441
+ }
2442
+
2443
+ //extern int stbtt_FindGlyphIndex(const stbtt_fontinfo * info, int unicode_codepoint)
2444
+ function stbtt_FindGlyphIndex(info, unicode_codepoint) {
2445
+ var data = info.data, index_map = info.index_map;
2446
+
2447
+ var format = ttUSHORT(data, index_map + 0);
2448
+ if (format == 0) {
2449
+ var bytes = ttUSHORT(data, index_map + 2);
2450
+ if (unicode_codepoint < bytes - 6) {
2451
+ return data[index_map + 6 + unicode_codepoint];
2452
+ }
2453
+ return 0;
2454
+ } else if (format == 6) {
2455
+ var first = ttUSHORT(data, index_map + 6),
2456
+ count = ttUSHORT(data, index_map + 8);
2457
+ if (unicode_codepoint >= first && unicode_codepoint < first + count) {
2458
+ return ttUSHORT(data, index_map + 10 + (unicode_codepoint - first) * 2);
2459
+ }
2460
+ return 0;
2461
+ } else if (format == 2) {
2462
+ return 0;
2463
+ } else if (format == 4) {
2464
+ var segcount = ttUSHORT(data, index_map + 6) >> 1,
2465
+ searchRange = ttUSHORT(data, index_map + 8) >> 1,
2466
+ entrySelector = ttUSHORT(data, index_map + 10),
2467
+ rangeShift = ttUSHORT(data, index_map + 12) >> 1,
2468
+ endCount = index_map + 14,
2469
+ search = endCount;
2470
+
2471
+ if (unicode_codepoint > 0xffff) {
2472
+ return 0;
2473
+ }
2474
+
2475
+ if (unicode_codepoint >= ttUSHORT(data, search + rangeShift * 2)) {
2476
+ search += rangeShift * 2;
2477
+ }
2478
+
2479
+ search -= 2;
2480
+ while (entrySelector) {
2481
+ searchRange >>= 1;
2482
+ var end = ttUSHORT(data, search + searchRange * 2);
2483
+ if (unicode_codepoint > end) {
2484
+ search += searchRange * 2;
2485
+ }
2486
+ --entrySelector;
2487
+ }
2488
+ search += 2;
2489
+
2490
+ var offset, start, item = (search - endCount) >>> 1;
2491
+
2492
+ start = ttUSHORT(data, index_map + 14 + segcount * 2 + 2 + 2 * item);
2493
+ if (unicode_codepoint < start) {
2494
+ return 0;
2495
+ }
2496
+
2497
+ offset = ttUSHORT(data, index_map + 14 + segcount * 6 + 2 + 2 * item);
2498
+ if (offset == 0) {
2499
+ return unicode_codepoint + ttSHORT(data, index_map + 14 + segcount * 4 + 2 + 2 * item);
2500
+ }
2501
+ return ttUSHORT(data, offset + (unicode_codepoint - start) * 2 +
2502
+ index_map + 14 + segcount * 6 + 2 + 2 * item);
2503
+ } else if (format == 12 || format == 13) {
2504
+ var ngroups = ttULONG(data, index_map + 12),
2505
+ low = 0, high = ngroups;
2506
+ while (low < high) {
2507
+ var mid = low + ((high - low) >> 1);
2508
+ var start_char = ttULONG(data, index_map + 16 + mid * 12);
2509
+ var end_char = ttULONG(data, index_map + 16 + mid * 12 + 4);
2510
+ if (unicode_codepoint < start_char) {
2511
+ high = mid;
2512
+ } else if (unicode_codepoint > end_char) {
2513
+ low = mid + 1;
2514
+ } else {
2515
+ var start_glyph = ttULONG(data, index_map + 16 + mid * 12 + 8);
2516
+ if (format == 12) {
2517
+ return start_glyph + unicode_codepoint - start_char;
2518
+ } else {
2519
+ return start_glyph;
2520
+ }
2521
+ }
2522
+ }
2523
+ return 0;
2524
+ }
2525
+ return 0;
2526
+ }
2527
+
2528
+ //static void stbtt_setvertex(stbtt_vertex * v, unsigned char type, int x, int y, int cx, int cy)
2529
+ function stbtt_setvertex(v, type, x, y, cx, cy) {
2530
+ v.type = type;
2531
+ v.x = x;
2532
+ v.y = y;
2533
+ v.cx = cx;
2534
+ v.cy = cy;
2535
+ }
2536
+
2537
+ //static int stbtt__GetGlyfOffset(const stbtt_fontinfo * info, int glyph_index)
2538
+ function stbtt__GetGlyfOffset(info, glyph_index) {
2539
+ var g1, g2;
2540
+ if (glyph_index >= info.numGlyphs) {
2541
+ return -1;
2542
+ }
2543
+ if (info.indexToLocFormat >= 2) {
2544
+ return -1;
2545
+ }
2546
+
2547
+ if (info.indexToLocFormat == 0) {
2548
+ g1 = info.glyf + ttUSHORT(info.data, info.loca + glyph_index * 2) * 2;
2549
+ g2 = info.glyf + ttUSHORT(info.data, info.loca + glyph_index * 2 + 2) * 2;
2550
+ } else {
2551
+ g1 = info.glyf + ttULONG(info.data, info.loca + glyph_index * 4);
2552
+ g2 = info.glyf + ttULONG(info.data, info.loca + glyph_index * 4 + 4);
2553
+ }
2554
+
2555
+ return g1 == g2 ? -1 : g1;
2556
+ }
2557
+
2558
+ //extern int stbtt_GetGlyphBox(const stbtt_fontinfo * info, int glyph_index, int *x0, int *y0, int *x1, int *y1)
2559
+ function stbtt_GetGlyphBox(info, glyph_index, out) {
2560
+ if (info.cff.length) {
2561
+ stbtt__GetGlyphInfoT2(info, glyph_index, out);
2562
+ } else {
2563
+ var g = stbtt__GetGlyfOffset(info, glyph_index);
2564
+ if (g < 0) {
2565
+ return 0;
2566
+ }
2567
+ out.x0 = ttSHORT(info.data, g + 2);
2568
+ out.y0 = ttSHORT(info.data, g + 4);
2569
+ out.x1 = ttSHORT(info.data, g + 6);
2570
+ out.y1 = ttSHORT(info.data, g + 8);
2571
+ }
2572
+ return 1;
2573
+ }
2574
+
2575
+ //static int stbtt__close_shape(stbtt_vertex * vertices, int num_vertices, int was_off,
2576
+ // int start_off, int sx, int sy, int scx, int scy, int cx, int cy)
2577
+ function stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx, sy, scx, scy, cx, cy) {
2578
+ if (start_off) {
2579
+ if (was_off) {
2580
+ stbtt_setvertex(vertices[num_vertices++], STBTT_vcurve,
2581
+ (cx + scx) >> 1, (cy + scy) >> 1, cx, cy);
2582
+ }
2583
+ stbtt_setvertex(vertices[num_vertices++], STBTT_vcurve, sx, sy, scx, scy);
2584
+ } else {
2585
+ if (was_off) {
2586
+ stbtt_setvertex(vertices[num_vertices++], STBTT_vcurve, sx, sy, cx, cy);
2587
+ } else {
2588
+ stbtt_setvertex(vertices[num_vertices++], STBTT_vline, sx, sy, 0, 0);
2589
+ }
2590
+ }
2591
+ return num_vertices;
2592
+ }
2593
+
2594
+ //static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo * info, int glyph_index, stbtt_vertex ** pvertices)
2595
+ function stbtt__GetGlyphShapeTT(info, glyph_index) {
2596
+ var data = info.data,
2597
+ g = stbtt__GetGlyfOffset(info, glyph_index);
2598
+
2599
+ if (g < 0) {
2600
+ return null;
2601
+ }
2602
+
2603
+ var vertices = [];
2604
+ var numberOfContours = ttSHORT(data, g);
2605
+ if (numberOfContours > 0) {
2606
+ var flags = 0, flagcount,
2607
+ i, j = 0, m, n, next_move, was_off = 0, off, start_off = 0,
2608
+ x, y, cx, cy, sx, sy, scx, scy;
2609
+ var endPtsOfContours = g + 10;
2610
+ var ins = ttUSHORT(data, g + 10 + numberOfContours * 2);
2611
+ var points = data.subarray(g + 10 + numberOfContours * 2 + 2 + ins);
2612
+ var ptsoff = 0;
2613
+
2614
+ n = 1 + ttUSHORT(data, endPtsOfContours + numberOfContours * 2 - 2);
2615
+ m = n + 2 * numberOfContours;
2616
+
2617
+ vertices = oalloc(m);
2618
+ next_move = 0;
2619
+ flagcount = 0;
2620
+ off = m - n;
2621
+
2622
+ for (i = 0; i < n; ++i) {
2623
+ if (flagcount == 0) {
2624
+ flags = points[ptsoff++];
2625
+ if (flags & 8) {
2626
+ flagcount = points[ptsoff++];
2627
+ }
2628
+ } else {
2629
+ --flagcount;
2630
+ }
2631
+ vertices[off + i].type = flags;
2632
+ }
2633
+
2634
+ x = 0;
2635
+ for (i = 0; i < n; ++i) {
2636
+ flags = vertices[off + i].type;
2637
+ if (flags & 2) {
2638
+ var dx = points[ptsoff++];
2639
+ x += (flags & 16) ? dx : -dx;
2640
+ } else {
2641
+ if (!(flags & 16)) {
2642
+ x = x + INT16(points[ptsoff] * 256 + points[ptsoff+1]);
2643
+ ptsoff += 2;
2644
+ }
2645
+ }
2646
+ vertices[off + i].x = x;
2647
+ }
2648
+
2649
+ y = 0;
2650
+ for (i = 0; i < n; ++i) {
2651
+ flags = vertices[off + i].type;
2652
+ if (flags & 4) {
2653
+ var dy = points[ptsoff++];
2654
+ y += (flags & 32) ? dy : -dy;
2655
+ } else {
2656
+ if (!(flags & 32)) {
2657
+ y = y + INT16(points[ptsoff] * 256 + points[ptsoff+1]);
2658
+ ptsoff += 2;
2659
+ }
2660
+ }
2661
+ vertices[off + i].y = y;
2662
+ }
2663
+
2664
+ var num_vertices = 0;
2665
+ sx = sy = cx = cy = scx = scy = 0;
2666
+ for (i = 0; i < n; ++i) {
2667
+ flags = vertices[off + i].type;
2668
+ x = vertices[off + i].x;
2669
+ y = vertices[off + i].y;
2670
+
2671
+ if (next_move == i) {
2672
+ if (i != 0) {
2673
+ num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off,
2674
+ sx, sy, scx, scy, cx, cy);
2675
+ }
2676
+ start_off = !(flags & 1);
2677
+ if (start_off) {
2678
+ scx = x;
2679
+ scy = y;
2680
+ if (!(vertices[off + i + 1].type & 1)) {
2681
+ sx = (x + vertices[off + i + 1].x) >> 1;
2682
+ sy = (y + vertices[off + i + 1].y) >> 1;
2683
+ } else {
2684
+ sx = vertices[off + i + 1].x;
2685
+ sy = vertices[off + i + 1].y;
2686
+ ++i;
2687
+ }
2688
+ } else {
2689
+ sx = x;
2690
+ sy = y;
2691
+ }
2692
+ stbtt_setvertex(vertices[num_vertices++], STBTT_vmove, sx, sy, 0, 0);
2693
+ was_off = 0;
2694
+ next_move = 1 + ttUSHORT(data, endPtsOfContours + j * 2);
2695
+ ++j;
2696
+ } else {
2697
+ if (!(flags & 1)) {
2698
+ if (was_off) {
2699
+ stbtt_setvertex(vertices[num_vertices++], STBTT_vcurve,
2700
+ (cx + x) >> 1, (cy + y) >> 1, cx, cy);
2701
+ }
2702
+ cx = x;
2703
+ cy = y;
2704
+ was_off = 1;
2705
+ } else {
2706
+ if (was_off) {
2707
+ stbtt_setvertex(vertices[num_vertices++], STBTT_vcurve, x, y, cx, cy);
2708
+ } else {
2709
+ stbtt_setvertex(vertices[num_vertices++], STBTT_vline, x, y, 0, 0);
2710
+ }
2711
+ was_off = 0;
2712
+ }
2713
+ }
2714
+ }
2715
+ vertices.length = stbtt__close_shape(vertices, num_vertices, was_off, start_off,
2716
+ sx, sy, scx, scy, cx, cy);
2717
+ } else if (numberOfContours == -1) {
2718
+ var more = 1;
2719
+ var comp = g + 10;
2720
+ while (more) {
2721
+ var flags, gidx, mtx = [ 1, 0, 0, 1, 0, 0 ];
2722
+
2723
+ flags = ttSHORT(data, comp);
2724
+ comp += 2;
2725
+ gidx = ttSHORT(data, comp);
2726
+ comp += 2;
2727
+
2728
+ if (flags & 2) {
2729
+ if (flags & 1) {
2730
+ mtx[4] = ttSHORT(data, comp);
2731
+ comp += 2;
2732
+ mtx[5] = ttSHORT(data, comp);
2733
+ comp += 2;
2734
+ } else {
2735
+ mtx[4] = stbtt__buf_get8(data, comp);
2736
+ comp += 1;
2737
+ mtx[5] = stbtt__buf_get8(data, comp);
2738
+ comp += 1;
2739
+ }
2740
+ }
2741
+ if (flags & (1 << 3)) {
2742
+ mtx[0] = mtx[3] = ttSHORT(data, comp) / 16384.0;
2743
+ comp += 2;
2744
+ mtx[1] = mtx[2] = 0;
2745
+ } else if (flags & (1 << 6)) {
2746
+ mtx[0] = ttSHORT(data, comp) / 16384.0;
2747
+ comp += 2;
2748
+ mtx[1] = mtx[2] = 0;
2749
+ mtx[3] = ttSHORT(data, comp) / 16384.0;
2750
+ comp += 2;
2751
+ } else if (flags & (1 << 7)) {
2752
+ mtx[0] = ttSHORT(data, comp) / 16384.0;
2753
+ comp += 2;
2754
+ mtx[1] = ttSHORT(data, comp) / 16384.0;
2755
+ comp += 2;
2756
+ mtx[2] = ttSHORT(data, comp) / 16384.0;
2757
+ comp += 2;
2758
+ mtx[3] = ttSHORT(data, comp) / 16384.0;
2759
+ comp += 2;
2760
+ }
2761
+
2762
+ var m = sqrt(mtx[0] * mtx[0] + mtx[1] * mtx[1]);
2763
+ var n = sqrt(mtx[2] * mtx[2] + mtx[3] * mtx[3]);
2764
+ var comp_verts = stbtt_GetGlyphShape(info, gidx);
2765
+ if (comp_verts.length > 0) {
2766
+ for (var i = 0, l = comp_verts.length; i < l; ++i) {
2767
+ var v = comp_verts[i], x, y;
2768
+ x = v.x;
2769
+ y = v.y;
2770
+ v.x = floor(m * (mtx[0] * x + mtx[2] * y + mtx[4]));
2771
+ v.y = floor(n * (mtx[1] * x + mtx[3] * y + mtx[5]));
2772
+ x = v.cx;
2773
+ y = v.cy;
2774
+ v.cx = floor(m * (mtx[0] * x + mtx[2] * y + mtx[4]));
2775
+ v.cy = floor(n * (mtx[1] * x + mtx[3] * y + mtx[5]));
2776
+ }
2777
+
2778
+ vertices = vertices.concat(comp_verts);
2779
+ }
2780
+ more = flags & (1 << 5);
2781
+ }
2782
+ }
2783
+ //console.log('vertices(' + vertices.length + ')');
2784
+ //for (var i = 0; i < vertices.length; i++) {
2785
+ // var pt = vertices[i];
2786
+ // console.log(`${i}: ${pt.x},${pt.y} / ${pt.cx},${pt.cy} / ${pt.type}`);
2787
+ //}
2788
+
2789
+ return vertices;
2790
+ }
2791
+
2792
+ //static void stbtt__track_vertex(stbtt__csctx * c, int x, int y)
2793
+ function stbtt__track_vertex(c, x, y) {
2794
+ if (x > c.max_x || !c.started) {
2795
+ c.max_x = x;
2796
+ }
2797
+ if (y > c.max_y || !c.started) {
2798
+ c.max_y = y;
2799
+ }
2800
+ if (x < c.min_x || !c.started) {
2801
+ c.min_x = x;
2802
+ }
2803
+ if (y < c.min_y || !c.started) {
2804
+ c.min_y = y;
2805
+ }
2806
+ c.started = 1;
2807
+ }
2808
+
2809
+ //static void stbtt__csctx_v(stbtt__csctx * c, unsigned char type, int x, int y, int cx, int cy, int cx1, int cy1)
2810
+ function stbtt__csctx_v(c, type, x, y, cx, cy, cx1, cy1) {
2811
+ stbtt__track_vertex(c, x, y);
2812
+ if (type == STBTT_vcubic) {
2813
+ stbtt__track_vertex(c, cx, cy);
2814
+ stbtt__track_vertex(c, cx1, cy1);
2815
+ }
2816
+ var v = {};
2817
+ stbtt_setvertex(v, type, x, y, cx, cy);
2818
+ v.cx1 = cx1;
2819
+ v.cy1 = cy1;
2820
+ c.vertices.push(v);
2821
+ }
2822
+
2823
+ //static void stbtt__csctx_close_shape(stbtt__csctx * ctx)
2824
+ function stbtt__csctx_close_shape(ctx) {
2825
+ if (ctx.first_x != ctx.x || ctx.first_y != ctx.y) {
2826
+ stbtt__csctx_v(ctx, STBTT_vline, ctx.first_x, ctx.first_y, 0, 0, 0, 0);
2827
+ }
2828
+ }
2829
+
2830
+ //static void stbtt__csctx_rmove_to(stbtt__csctx * ctx, float dx, float dy)
2831
+ function stbtt__csctx_rmove_to(ctx, dx, dy) {
2832
+ stbtt__csctx_close_shape(ctx);
2833
+ ctx.first_x = ctx.x = ctx.x + dx;
2834
+ ctx.first_y = ctx.y = ctx.y + dy;
2835
+ stbtt__csctx_v(ctx, STBTT_vmove, ctx.x, ctx.y, 0, 0, 0, 0);
2836
+ }
2837
+
2838
+ //static void stbtt__csctx_rline_to(stbtt__csctx * ctx, float dx, float dy)
2839
+ function stbtt__csctx_rline_to(ctx, dx, dy) {
2840
+ ctx.x += dx;
2841
+ ctx.y += dy;
2842
+ stbtt__csctx_v(ctx, STBTT_vline, ctx.x, ctx.y, 0, 0, 0, 0);
2843
+ }
2844
+
2845
+ //static void stbtt__csctx_rccurve_to(stbtt__csctx * ctx, float dx1, float dy1, float dx2,
2846
+ // float dy2, float dx3, float dy3)
2847
+ function stbtt__csctx_rccurve_to(ctx, dx1, dy1, dx2, dy2, dx3, dy3) {
2848
+ var cx1 = ctx.x + dx1,
2849
+ cy1 = ctx.y + dy1,
2850
+ cx2 = cx1 + dx2,
2851
+ cy2 = cy1 + dy2;
2852
+ ctx.x = cx2 + dx3;
2853
+ ctx.y = cy2 + dy3;
2854
+ stbtt__csctx_v(ctx, STBTT_vcubic, ctx.x, ctx.y, cx1, cy1, cx2, cy2);
2855
+ }
2856
+
2857
+ //static stbtt__buf stbtt__get_subr(stbtt__buf idx, int n)
2858
+ function stbtt__get_subr(b, n) {
2859
+ var count = stbtt__cff_index_count(b);
2860
+ var bias = 107;
2861
+ if (count >= 33900) {
2862
+ bias = 32768;
2863
+ } else if (count >= 1240) {
2864
+ bias = 1131;
2865
+ }
2866
+ n += bias;
2867
+ if (n < 0 || n >= count) {
2868
+ return stbtt__null_buf();
2869
+ }
2870
+ return stbtt__cff_index_get(b, n);
2871
+ }
2872
+
2873
+ //static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo * info, int glyph_index)
2874
+ function stbtt__cid_get_glyph_subrs(info, glyph_index) {
2875
+ var fdselect = info.fdselect;
2876
+ var nranges, start, end, v, fmt, fdselector = -1, i;
2877
+
2878
+ stbtt__buf_seek(fdselect, 0);
2879
+ fmt = stbtt__buf_get8(fdselect);
2880
+ if (fmt == 0) {
2881
+ stbtt__buf_skip(fdselect, glyph_index);
2882
+ fdselector = stbtt__buf_get8(fdselect);
2883
+ } else if (fmt == 3) {
2884
+ nranges = stbtt__buf_get(fdselect, 2);
2885
+ start = stbtt__buf_get(fdselect, 2);
2886
+ for (i = 0; i < nranges; i++) {
2887
+ v = stbtt__buf_get8(fdselect);
2888
+ end = stbtt__buf_get(fdselect, 2);
2889
+ if (glyph_index >= start && glyph_index < end) {
2890
+ fdselector = v;
2891
+ break;
2892
+ }
2893
+ start = end;
2894
+ }
2895
+ }
2896
+ if (fdselector == -1) {
2897
+ stbtt__null_buf();
2898
+ }
2899
+ return stbtt__get_subrs(info.cff, stbtt__cff_index_get(info.fontdicts, fdselector));
2900
+ }
2901
+
2902
+ //static int stbtt__run_charstring(const stbtt_fontinfo * info, int glyph_index,
2903
+ // stbtt__csctx * c)
2904
+ function stbtt__run_charstring(info, glyph_index, c) {
2905
+ var in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0,
2906
+ has_subrs = 0, clear_stack,
2907
+ s = [], subr_stack = [], subrs = info.subrs, b, f;
2908
+
2909
+ b = stbtt__cff_index_get(info.charstrings, glyph_index);
2910
+ while (b.cursor < b.length) {
2911
+ i = 0;
2912
+ clear_stack = 1;
2913
+ b0 = stbtt__buf_get8(b);
2914
+ switch (b0) {
2915
+ case 0x13:
2916
+ case 0x14:
2917
+ if (in_header) {
2918
+ maskbits += (sp / 2)|0;
2919
+ }
2920
+ in_header = 0;
2921
+ stbtt__buf_skip(b, ((maskbits + 7) / 8)|0);
2922
+ break;
2923
+
2924
+ case 0x01:
2925
+ case 0x03:
2926
+ case 0x12:
2927
+ case 0x17:
2928
+ maskbits += (sp / 2)|0;
2929
+ break;
2930
+
2931
+ case 0x15:
2932
+ in_header = 0;
2933
+ if (sp < 2) {
2934
+ return 0;
2935
+ }
2936
+ stbtt__csctx_rmove_to(c, s[sp - 2], s[sp - 1]);
2937
+ break;
2938
+ case 0x04:
2939
+ in_header = 0;
2940
+ if (sp < 1) {
2941
+ return 0;
2942
+ }
2943
+ stbtt__csctx_rmove_to(c, 0, s[sp - 1]);
2944
+ break;
2945
+ case 0x16:
2946
+ in_header = 0;
2947
+ if (sp < 1) {
2948
+ return 0;
2949
+ }
2950
+ stbtt__csctx_rmove_to(c, s[sp - 1], 0);
2951
+ break;
2952
+
2953
+ case 0x05:
2954
+ if (sp < 2) {
2955
+ return 0;
2956
+ }
2957
+ for (; i + 1 < sp; i += 2) {
2958
+ stbtt__csctx_rline_to(c, s[i], s[i + 1]);
2959
+ }
2960
+ break;
2961
+
2962
+ case 0x07:
2963
+ if (sp < 1) {
2964
+ return 0;
2965
+ }
2966
+ for (;;) {
2967
+ if (i >= sp) {
2968
+ break;
2969
+ }
2970
+ stbtt__csctx_rline_to(c, 0, s[i]);
2971
+ i++;
2972
+ if (i >= sp) {
2973
+ break;
2974
+ }
2975
+ stbtt__csctx_rline_to(c, s[i], 0);
2976
+ i++;
2977
+ }
2978
+ break;
2979
+ case 0x06:
2980
+ if (sp < 1) {
2981
+ return 0;
2982
+ }
2983
+ for (;;) {
2984
+ if (i >= sp) {
2985
+ break;
2986
+ }
2987
+ stbtt__csctx_rline_to(c, s[i], 0);
2988
+ i++;
2989
+ if (i >= sp) {
2990
+ break;
2991
+ }
2992
+ stbtt__csctx_rline_to(c, 0, s[i]);
2993
+ i++;
2994
+ }
2995
+ break;
2996
+
2997
+ case 0x1F:
2998
+ if (sp < 4) {
2999
+ return 0;
3000
+ }
3001
+ for (;;) {
3002
+ if (i + 3 >= sp) {
3003
+ break;
3004
+ }
3005
+ stbtt__csctx_rccurve_to(c, s[i], 0, s[i + 1], s[i + 2],
3006
+ (sp - i == 5) ? s[i + 4] : 0.0,
3007
+ s[i + 3]);
3008
+ i += 4;
3009
+ if (i + 3 >= sp) {
3010
+ break;
3011
+ }
3012
+ stbtt__csctx_rccurve_to(c, 0, s[i], s[i + 1],
3013
+ s[i + 2], s[i + 3],
3014
+ (sp - i == 5) ? s[i + 4] : 0.0);
3015
+ i += 4;
3016
+ }
3017
+ break;
3018
+ case 0x1E:
3019
+ if (sp < 4) {
3020
+ return 0;
3021
+ }
3022
+ for (;;) {
3023
+ if (i + 3 >= sp) {
3024
+ break;
3025
+ }
3026
+ stbtt__csctx_rccurve_to(c, 0, s[i], s[i + 1],
3027
+ s[i + 2], s[i + 3],
3028
+ (sp - i == 5) ? s[i + 4] : 0.0);
3029
+ i += 4;
3030
+ if (i + 3 >= sp) {
3031
+ break;
3032
+ }
3033
+ stbtt__csctx_rccurve_to(c, s[i], 0, s[i + 1], s[i + 2],
3034
+ (sp - i == 5) ? s[i + 4] : 0.0,
3035
+ s[i + 3]);
3036
+ i += 4;
3037
+ }
3038
+ break;
3039
+
3040
+ case 0x08:
3041
+ if (sp < 6) {
3042
+ return 0;
3043
+ }
3044
+ for (; i + 5 < sp; i += 6) {
3045
+ stbtt__csctx_rccurve_to(c, s[i], s[i + 1],
3046
+ s[i + 2], s[i + 3],
3047
+ s[i + 4], s[i + 5]);
3048
+ }
3049
+ break;
3050
+
3051
+ case 0x18:
3052
+ if (sp < 8) {
3053
+ return 0;
3054
+ }
3055
+ for (; i + 5 < sp - 2; i += 6) {
3056
+ stbtt__csctx_rccurve_to(c, s[i], s[i + 1],
3057
+ s[i + 2], s[i + 3],
3058
+ s[i + 4], s[i + 5]);
3059
+ }
3060
+ if (i + 1 >= sp) {
3061
+ return 0;
3062
+ }
3063
+ stbtt__csctx_rline_to(c, s[i], s[i + 1]);
3064
+ break;
3065
+
3066
+ case 0x19:
3067
+ if (sp < 8) {
3068
+ return 0;
3069
+ }
3070
+ for (; i + 1 < sp - 6; i += 2) {
3071
+ stbtt__csctx_rline_to(c, s[i], s[i + 1]);
3072
+ }
3073
+ if (i + 5 >= sp) {
3074
+ return 0;
3075
+ }
3076
+ stbtt__csctx_rccurve_to(c, s[i], s[i + 1], s[i + 2],
3077
+ s[i + 3], s[i + 4], s[i + 5]);
3078
+ break;
3079
+
3080
+ case 0x1A:
3081
+ case 0x1B:
3082
+ if (sp < 4) {
3083
+ return 0;
3084
+ }
3085
+ f = 0.0;
3086
+ if (sp & 1) {
3087
+ f = s[i];
3088
+ i++;
3089
+ }
3090
+ for (; i + 3 < sp; i += 4) {
3091
+ if (b0 == 0x1B) {
3092
+ stbtt__csctx_rccurve_to(c, s[i], f,
3093
+ s[i + 1],
3094
+ s[i + 2],
3095
+ s[i + 3], 0.0);
3096
+ } else {
3097
+ stbtt__csctx_rccurve_to(c, f, s[i],
3098
+ s[i + 1],
3099
+ s[i + 2], 0.0,
3100
+ s[i + 3]);
3101
+ }
3102
+ f = 0.0;
3103
+ }
3104
+ break;
3105
+
3106
+ case 0x0A:
3107
+ if (!has_subrs) {
3108
+ if (info.fdselect.length) {
3109
+ subrs = stbtt__cid_get_glyph_subrs(info, glyph_index);
3110
+ }
3111
+ has_subrs = 1;
3112
+ }
3113
+
3114
+ case 0x1D:
3115
+ if (sp < 1) {
3116
+ return 0;
3117
+ }
3118
+ v = s[--sp]|0;
3119
+ if (subr_stack_height >= 10) {
3120
+ return 0;
3121
+ }
3122
+ subr_stack[subr_stack_height++] = b;
3123
+ b = stbtt__get_subr(b0 == 0x0A ? subrs : info.gsubrs, v);
3124
+ if (b.length == 0) {
3125
+ return 0;
3126
+ }
3127
+ b.cursor = 0;
3128
+ clear_stack = 0;
3129
+ break;
3130
+
3131
+ case 0x0B:
3132
+ if (subr_stack_height <= 0) {
3133
+ return 0;
3134
+ }
3135
+ b = subr_stack[--subr_stack_height];
3136
+ clear_stack = 0;
3137
+ break;
3138
+
3139
+ case 0x0E:
3140
+ stbtt__csctx_close_shape(c);
3141
+ return 1;
3142
+
3143
+ case 0x0C:
3144
+ var dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6,
3145
+ dx, dy, b1 = stbtt__buf_get8(b);
3146
+ switch (b1) {
3147
+ case 0x22:
3148
+ if (sp < 7) {
3149
+ return 0;
3150
+ }
3151
+ dx1 = s[0];
3152
+ dx2 = s[1];
3153
+ dy2 = s[2];
3154
+ dx3 = s[3];
3155
+ dx4 = s[4];
3156
+ dx5 = s[5];
3157
+ dx6 = s[6];
3158
+ stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0);
3159
+ stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0);
3160
+ break;
3161
+
3162
+ case 0x23:
3163
+ if (sp < 13) {
3164
+ return 0;
3165
+ }
3166
+ dx1 = s[0];
3167
+ dy1 = s[1];
3168
+ dx2 = s[2];
3169
+ dy2 = s[3];
3170
+ dx3 = s[4];
3171
+ dy3 = s[5];
3172
+ dx4 = s[6];
3173
+ dy4 = s[7];
3174
+ dx5 = s[8];
3175
+ dy5 = s[9];
3176
+ dx6 = s[10];
3177
+ dy6 = s[11];
3178
+
3179
+ stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
3180
+ stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
3181
+ break;
3182
+
3183
+ case 0x24:
3184
+ if (sp < 9) {
3185
+ return 0;
3186
+ }
3187
+ dx1 = s[0];
3188
+ dy1 = s[1];
3189
+ dx2 = s[2];
3190
+ dy2 = s[3];
3191
+ dx3 = s[4];
3192
+ dx4 = s[5];
3193
+ dx5 = s[6];
3194
+ dy5 = s[7];
3195
+ dx6 = s[8];
3196
+ stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0);
3197
+ stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1 + dy2 + dy5));
3198
+ break;
3199
+
3200
+ case 0x25:
3201
+ if (sp < 11) {
3202
+ return 0;
3203
+ }
3204
+ dx1 = s[0];
3205
+ dy1 = s[1];
3206
+ dx2 = s[2];
3207
+ dy2 = s[3];
3208
+ dx3 = s[4];
3209
+ dy3 = s[5];
3210
+ dx4 = s[6];
3211
+ dy4 = s[7];
3212
+ dx5 = s[8];
3213
+ dy5 = s[9];
3214
+ dx6 = dy6 = s[10];
3215
+ dx = dx1 + dx2 + dx3 + dx4 + dx5;
3216
+ dy = dy1 + dy2 + dy3 + dy4 + dy5;
3217
+ if (abs(dx) > abs(dy)) {
3218
+ dy6 = -dy;
3219
+ } else {
3220
+ dx6 = -dx;
3221
+ }
3222
+ stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
3223
+ stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
3224
+ break;
3225
+
3226
+ default:
3227
+ return 0;
3228
+ }
3229
+ break;
3230
+
3231
+ default:
3232
+ if (b0 != 255 && b0 != 28 && (b0 < 32 || b0 > 254)) {
3233
+ return 0;
3234
+ }
3235
+ if (b0 == 255) {
3236
+ // f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000;
3237
+ f = (stbtt__buf_get(b, 4)|0) / 0x10000;
3238
+ } else {
3239
+ stbtt__buf_skip(b, -1);
3240
+ // f = (float)(stbtt_int16)stbtt__cff_int(&b);
3241
+ f = ((stbtt__cff_int(b)<<16)|0)>>16;
3242
+ }
3243
+ if (sp >= 48) {
3244
+ return 0;
3245
+ }
3246
+ s[sp++] = f;
3247
+ clear_stack = 0;
3248
+ break;
3249
+ }
3250
+ if (clear_stack) {
3251
+ sp = 0;
3252
+ }
3253
+ }
3254
+ return 0;
3255
+ }
3256
+
3257
+ function stbtt__csctx_init() {
3258
+ return { started:0, first_x:0, first_y:0, x:0, y:0,
3259
+ min_x:0, max_x:0, min_y:0, max_y:0,
3260
+ vertices:[]
3261
+ };
3262
+ }
3263
+
3264
+ //static int stbtt__GetGlyphShapeT2(const stbtt_fontinfo * info, int glyph_index,
3265
+ // stbtt_vertex ** pvertices)
3266
+ function stbtt__GetGlyphShapeT2(info, glyph_index) {
3267
+ var output_ctx = stbtt__csctx_init();
3268
+ if (stbtt__run_charstring(info, glyph_index, output_ctx)) {
3269
+ return output_ctx.vertices;
3270
+ }
3271
+ return null;
3272
+ }
3273
+
3274
+ //static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo * info, int glyph_index, int *x0,
3275
+ // int *y0, int *x1, int *y1)
3276
+ function stbtt__GetGlyphInfoT2(info, glyph_index, out) {
3277
+ var c = stbtt__csctx_init();
3278
+ var r = stbtt__run_charstring(info, glyph_index, c);
3279
+ out.x0 = r ? c.min_x : 0;
3280
+ out.y0 = r ? c.min_y : 0;
3281
+ out.x1 = r ? c.max_x : 0;
3282
+ out.y1 = r ? c.max_y : 0;
3283
+ return r && c.vertices ? c.vertices.length : 0;
3284
+ }
3285
+
3286
+ //extern int stbtt_GetGlyphShape(const stbtt_fontinfo * info, int glyph_index,
3287
+ // stbtt_vertex ** pvertices)
3288
+ function stbtt_GetGlyphShape(info, glyph_index) {
3289
+ if (!info.cff.length) {
3290
+ return stbtt__GetGlyphShapeTT(info, glyph_index);
3291
+ } else {
3292
+ return stbtt__GetGlyphShapeT2(info, glyph_index);
3293
+ }
3294
+ }
3295
+
3296
+ //extern void stbtt_GetGlyphHMetrics(const stbtt_fontinfo * info, int glyph_index,
3297
+ // int *advanceWidth, int *leftSideBearing)
3298
+ function stbtt_GetGlyphHMetrics(info, glyph_index) {
3299
+ var numOfLongHorMetrics = ttUSHORT(info.data, info.hhea + 34);
3300
+ if (glyph_index < numOfLongHorMetrics) {
3301
+ return {
3302
+ advanceWidth: ttSHORT(info.data, info.hmtx + 4 * glyph_index),
3303
+ leftSideBearing:ttSHORT(info.data, info.hmtx + 4 * glyph_index + 2)
3304
+ };
3305
+ } else {
3306
+ return {
3307
+ advanceWidth: ttSHORT(info.data, info.hmtx + 4 * (numOfLongHorMetrics - 1)),
3308
+ leftSideBearing:ttSHORT(info.data, info.hmtx + 4 * numOfLongHorMetrics +
3309
+ 2 * (glyph_index - numOfLongHorMetrics))
3310
+ };
3311
+ }
3312
+ }
3313
+
3314
+ //extern void stbtt_GetCodepointHMetrics(const stbtt_fontinfo * info, int codepoint,
3315
+ // int *advanceWidth, int *leftSideBearing)
3316
+ function stbtt_GetCodepointHMetrics(info, codepoint) {
3317
+ return stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info, codepoint));
3318
+ }
3319
+
3320
+ //extern void stbtt_GetFontVMetrics(const stbtt_fontinfo * info, int *ascent, int *descent, int *lineGap)
3321
+ function stbtt_GetFontVMetrics(info) {
3322
+ return {
3323
+ ascent: ttSHORT(info.data, info.hhea + 4),
3324
+ descent:ttSHORT(info.data, info.hhea + 6),
3325
+ linegap:ttSHORT(info.data, info.hhea + 8),
3326
+ };
3327
+ }
3328
+
3329
+ //extern void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo * font, int glyph,
3330
+ // float scale_x, float scale_y, float shift_x, float shift_y,
3331
+ // int *ix0, int *iy0, int *ix1, int *iy1)
3332
+ function stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y, shift_x, shift_y) {
3333
+ var tmp = {};
3334
+ if (!stbtt_GetGlyphBox(font, glyph, tmp)) {
3335
+ return { x0:0, y0:0, x1:0, y1:0 };
3336
+ }
3337
+ return {
3338
+ x0:floor(tmp.x0 * scale_x + shift_x),
3339
+ y0:floor(-tmp.y1 * scale_y + shift_y),
3340
+ x1:ceil(tmp.x1 * scale_x + shift_x),
3341
+ y1:ceil(-tmp.y0 * scale_y + shift_y),
3342
+ };
3343
+ }
3344
+
3345
+ //extern void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo * font,
3346
+ // int codepoint, float scale_x, float scale_y, float shift_x,
3347
+ // float shift_y, int *ix0, int *iy0, int *ix1, int *iy1)
3348
+ function stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y, shift_x, shift_y) {
3349
+ return stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font, codepoint),
3350
+ scale_x, scale_y, shift_x, shift_y);
3351
+ }
3352
+
3353
+ //extern void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo * font, int codepoint, float scale_x, float scale_y,
3354
+ // int *ix0, int *iy0, int *ix1, int *iy1)
3355
+ function stbtt_GetCodepointBitmapBox(font, codepoint, scale_x, scale_y) {
3356
+ return stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y, 0, 0);
3357
+ }
3358
+
3359
+ //static stbtt__active_edge *stbtt__new_active(stbtt__hheap * hh, stbtt__edge * e, int off_x, float start_point, void *userdata)
3360
+ function stbtt__new_active(e, off_x, start_point) {
3361
+ var dxdy = (e.x1 - e.x0) / (e.y1 - e.y0);
3362
+ return {
3363
+ fdx:dxdy,
3364
+ fdy:dxdy != 0.0 ? (1.0 / dxdy) : 0.0,
3365
+ fx:(e.x0 + dxdy * (start_point - e.y0)) - (off_x|0),
3366
+ direction:e.invert ? 1.0 : -1.0,
3367
+ sy:e.y0,
3368
+ ey:e.y1,
3369
+ next:0,
3370
+ };
3371
+ }
3372
+
3373
+ //static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge * e,
3374
+ // float x0, float y0, float x1, float y1)
3375
+ function stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1) {
3376
+ x = x|0;
3377
+ if (y0 == y1) {
3378
+ return;
3379
+ }
3380
+ if (y0 > e.ey) {
3381
+ return;
3382
+ }
3383
+ if (y1 < e.sy) {
3384
+ return;
3385
+ }
3386
+ if (y0 < e.sy) {
3387
+ x0 += (x1 - x0) * (e.sy - y0) / (y1 - y0);
3388
+ y0 = e.sy;
3389
+ }
3390
+ if (y1 > e.ey) {
3391
+ x1 += (x1 - x0) * (e.ey - y1) / (y1 - y0);
3392
+ y1 = e.ey;
3393
+ }
3394
+
3395
+ if (x0 <= x && x1 <= x) {
3396
+ scanline[x] += e.direction * (y1 - y0);
3397
+ } else if (x0 >= x + 1 && x1 >= x + 1) {
3398
+
3399
+ } else {
3400
+ scanline[x] += e.direction * (y1 - y0) * (1 - ((x0 - x) + (x1 - x)) / 2);
3401
+ }
3402
+ }
3403
+
3404
+ //static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len,
3405
+ // stbtt__active_edge * e, float y_top)
3406
+ // The C implementation passed scanline_fill as a +1 pointer on the call, and then -1 in
3407
+ // places in this function. That doesn't work with array-views, so we reverse the handling.
3408
+ function stbtt__fill_active_edges_new(scanline, scanline_fill, len, e, y_top) {
3409
+ var y_bottom = y_top + 1;
3410
+ while (e) {
3411
+ if (e.fdx == 0) {
3412
+ var x0 = e.fx;
3413
+ if (x0 < len) {
3414
+ if (x0 >= 0) {
3415
+ stbtt__handle_clipped_edge(scanline, x0, e, x0, y_top, x0, y_bottom);
3416
+ stbtt__handle_clipped_edge(scanline_fill, x0+1, e, x0, y_top, x0, y_bottom);
3417
+ } else {
3418
+ stbtt__handle_clipped_edge(scanline_fill, 0, e, x0, y_top, x0, y_bottom);
3419
+ }
3420
+ }
3421
+ } else {
3422
+ var x0 = e.fx,
3423
+ dx = e.fdx,
3424
+ xb = x0 + dx,
3425
+ x_top, x_bottom,
3426
+ sy0, sy1,
3427
+ dy = e.fdy;
3428
+
3429
+ if (e.sy > y_top) {
3430
+ x_top = x0 + dx * (e.sy - y_top);
3431
+ sy0 = e.sy;
3432
+ } else {
3433
+ x_top = x0;
3434
+ sy0 = y_top;
3435
+ }
3436
+ if (e.ey < y_bottom) {
3437
+ x_bottom = x0 + dx * (e.ey - y_top);
3438
+ sy1 = e.ey;
3439
+ } else {
3440
+ x_bottom = xb;
3441
+ sy1 = y_bottom;
3442
+ }
3443
+
3444
+ if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) {
3445
+ if ((x_top|0) == (x_bottom|0)) {
3446
+ var height = sy1 - sy0,
3447
+ x = x_top|0;
3448
+ scanline[x] += e.direction * (1 - ((x_top - x) + (x_bottom - x)) / 2) * height;
3449
+ scanline_fill[x+1] += e.direction * height;
3450
+ } else {
3451
+ var t, x, x1, x2, y_crossing, step, sign, area;
3452
+ if (x_top > x_bottom) {
3453
+ sy0 = y_bottom - (sy0 - y_top);
3454
+ sy1 = y_bottom - (sy1 - y_top);
3455
+ t = sy0, sy0 = sy1, sy1 = t;
3456
+ t = x_bottom, x_bottom = x_top, x_top = t;
3457
+ dx = -dx;
3458
+ dy = -dy;
3459
+ t = x0, x0 = xb, xb = t;
3460
+ }
3461
+
3462
+ x1 = x_top|0;
3463
+ x2 = x_bottom|0;
3464
+ y_crossing = (x1 + 1 - x0) * dy + y_top;
3465
+ sign = e.direction;
3466
+ area = sign * (y_crossing - sy0);
3467
+
3468
+ scanline[x1] += area * (1 - ((x_top - x1) + (x1 + 1 - x1)) / 2);
3469
+
3470
+ step = sign * dy;
3471
+ for (x = x1 + 1; x < x2; ++x) {
3472
+ scanline[x] += area + step / 2;
3473
+ area += step;
3474
+ }
3475
+ y_crossing += dy * (x2 - (x1 + 1));
3476
+
3477
+ scanline[x2] += area + sign * (1 - ((x2 - x2) + (x_bottom - x2)) / 2) *
3478
+ (sy1 - y_crossing);
3479
+ scanline_fill[x2+1] += sign * (sy1 - sy0);
3480
+ }
3481
+ } else {
3482
+ for (var x = 0; x < len; ++x) {
3483
+ var y0 = y_top,
3484
+ x1 = x,
3485
+ x2 = x + 1,
3486
+ x3 = xb,
3487
+ y3 = y_bottom,
3488
+ y1 = (x - x0) / dx + y_top,
3489
+ y2 = (x + 1 - x0) / dx + y_top;
3490
+
3491
+ if (x0 < x1 && x3 > x2) {
3492
+ stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1);
3493
+ stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x2, y2);
3494
+ stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3);
3495
+ } else if (x3 < x1 && x0 > x2) {
3496
+ stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2);
3497
+ stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x1, y1);
3498
+ stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3);
3499
+ } else if (x0 < x1 && x3 > x1) {
3500
+ stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1);
3501
+ stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3);
3502
+ } else if (x3 < x1 && x0 > x1) {
3503
+ stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1);
3504
+ stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3);
3505
+ } else if (x0 < x2 && x3 > x2) {
3506
+ stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2);
3507
+ stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3);
3508
+ } else if (x3 < x2 && x0 > x2) {
3509
+ stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2);
3510
+ stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3);
3511
+ } else {
3512
+ stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x3, y3);
3513
+ }
3514
+ }
3515
+ }
3516
+ }
3517
+ e = e.next;
3518
+ }
3519
+ }
3520
+
3521
+ //static void stbtt__rasterize_sorted_edges(stbtt__bitmap * result, stbtt__edge * e, int n,
3522
+ // int vsubsample, int off_x, int off_y, void *userdata)
3523
+ function stbtt__rasterize_sorted_edges(result, edges, nedges, vsubsample, off_x, off_y) {
3524
+ vsubsample |= 0, off_x |= 0, off_y |= 0;
3525
+ var active = null, z;
3526
+ var y = off_y, j = 0, i;
3527
+ var scanline = new Float32Array(result.w * 2 + 1);
3528
+ var scanline2 = scanline.subarray(result.w);
3529
+ var eoff = 0;
3530
+
3531
+ edges[nedges].y0 = off_y + result.h + 1;
3532
+ while (j < result.h) {
3533
+ var scan_y_top = y + 0.0,
3534
+ scan_y_bottom = y + 1.0,
3535
+ step = active;
3536
+
3537
+ // F'ing IE
3538
+ if (scanline.fill) { scanline.fill(0); }
3539
+ else { for (var $i = 0, $l = scanline.length; $i < $l; $i++) scanline[$i] = 0; }
3540
+
3541
+ while (step) {
3542
+ z = step;
3543
+ step = z.next;
3544
+ if (z.ey <= scan_y_top) {
3545
+ z.direction = 0;
3546
+ } else {
3547
+ }
3548
+ }
3549
+
3550
+ while (edges[eoff].y0 <= scan_y_bottom) {
3551
+ if (edges[eoff].y0 != edges[eoff].y1) {
3552
+ z = stbtt__new_active(edges[eoff], off_x, scan_y_top);
3553
+ z.next = active;
3554
+ active = z;
3555
+ }
3556
+ ++eoff;
3557
+ }
3558
+
3559
+ if (active) {
3560
+ // C implementation passed scanline2+1. See function for details.
3561
+ stbtt__fill_active_edges_new(scanline, scanline2, result.w, active, scan_y_top);
3562
+ }
3563
+ for (var i = 0, sum = 0; i < result.w; ++i) {
3564
+ var k, m;
3565
+ sum += scanline2[i];
3566
+ k = scanline[i] + sum;
3567
+ k = abs(k) * 255 + 0.5;
3568
+ m = k>>>0;
3569
+ if (m > 255) {
3570
+ m = 255;
3571
+ }
3572
+ result.pixels[j * result.stride + i] = m;
3573
+ }
3574
+
3575
+ step = active;
3576
+ while (step) {
3577
+ z = step;
3578
+ z.fx += z.fdx;
3579
+ step = z.next;
3580
+ }
3581
+ ++y;
3582
+ ++j;
3583
+ }
3584
+ }
3585
+
3586
+ //static void stbtt__sort_edges_ins_sort(stbtt__edge * p, int n)
3587
+ function stbtt__sort_edges_ins_sort(p, n) {
3588
+ for (var i = 1; i < n; ++i) {
3589
+ var t = p[i], j = i;
3590
+ while (j > 0 && t.y0 < p[j-1].y0) {
3591
+ p[j] = p[j - 1];
3592
+ --j;
3593
+ }
3594
+ if (i != j) {
3595
+ p[j] = t;
3596
+ }
3597
+ }
3598
+ }
3599
+
3600
+ //static void stbtt__sort_edges_quicksort(stbtt__edge * p, int n)
3601
+ // The C implementation messed with the p pointer. JS uses an offset instead.
3602
+ function stbtt__sort_edges_quicksort(p, o, n) {
3603
+ while (n > 12) {
3604
+ var t, c, i, j, z,
3605
+ m = n >> 1,
3606
+ c01 = p[o].y0 < p[o+m].y0,
3607
+ c12 = p[o+m].y0 < p[o+n-1].y0;
3608
+
3609
+ if (c01 != c12) {
3610
+ c = p[o].y0 < p[o+n-11].y0;
3611
+ z = (c == c12) ? 0 : n - 1;
3612
+ t = p[o+z];
3613
+ p[o+z] = p[o+m];
3614
+ p[o+m] = t;
3615
+ }
3616
+
3617
+ t = p[o];
3618
+ p[o] = p[o+m];
3619
+ p[o+m] = t;
3620
+
3621
+ i = 1;
3622
+ j = n - 1;
3623
+ for (;;) {
3624
+ for ( ; p[o+i].y0 < p[o].y0; ++i) {
3625
+ }
3626
+ for ( ; p[o].y0 < p[o+j].y0; --j) {
3627
+ }
3628
+ if (i >= j) {
3629
+ break;
3630
+ }
3631
+ t = p[o+i];
3632
+ p[o+i] = p[o+j];
3633
+ p[o+j] = t;
3634
+
3635
+ ++i;
3636
+ --j;
3637
+ }
3638
+
3639
+ if (j < n - i) {
3640
+ stbtt__sort_edges_quicksort(p, o, j);
3641
+ o += i;
3642
+ n -= i;
3643
+ } else {
3644
+ stbtt__sort_edges_quicksort(p, o + i, n - i);
3645
+ n = j;
3646
+ }
3647
+ }
3648
+ }
3649
+
3650
+ //static void stbtt__sort_edges(stbtt__edge * p, int n)
3651
+ function stbtt__sort_edges(p, n) {
3652
+ stbtt__sort_edges_quicksort(p, 0, n);
3653
+ stbtt__sort_edges_ins_sort(p, n);
3654
+ }
3655
+
3656
+ //static void stbtt__rasterize(stbtt__bitmap * result, stbtt__point * pts, int *wcount,
3657
+ // int windings, float scale_x, float scale_y, float shift_x,
3658
+ // float shift_y, int off_x, int off_y, int invert,
3659
+ // void *userdata)
3660
+ function stbtt__rasterize(result, pts, wcount, scale_x, scale_y, shift_x, shift_y, off_x, off_y, invert) {
3661
+ var y_scale_inv = invert ? -scale_y : scale_y,
3662
+ e, n, i, j, k, m,
3663
+ vsubsample = 1;
3664
+
3665
+ n = 0;
3666
+ for (i = 0; i < wcount.length; ++i) {
3667
+ n += wcount[i];
3668
+ }
3669
+
3670
+ e = oalloc(n + 1);
3671
+ n = 0;
3672
+ m = 0;
3673
+ for (i = 0; i < wcount.length; ++i) {
3674
+ var p = m;
3675
+ m += wcount[i];
3676
+ j = wcount[i] - 1;
3677
+ for (k = 0; k < wcount[i]; j = k++) {
3678
+ var a = k, b = j;
3679
+ if (pts[p+j].y == pts[p+k].y) {
3680
+ continue;
3681
+ }
3682
+
3683
+ e[n].invert = 0;
3684
+ if (invert ? pts[p+j].y > pts[p+k].y : pts[p+j].y < pts[p+k].y) {
3685
+ e[n].invert = 1;
3686
+ a = j, b = k;
3687
+ }
3688
+ e[n].x0 = pts[p+a].x * scale_x + shift_x;
3689
+ e[n].y0 = (pts[p+a].y * y_scale_inv + shift_y) * vsubsample;
3690
+ e[n].x1 = pts[p+b].x * scale_x + shift_x;
3691
+ e[n].y1 = (pts[p+b].y * y_scale_inv + shift_y) * vsubsample;
3692
+ ++n;
3693
+ }
3694
+ }
3695
+
3696
+ stbtt__sort_edges(e, n);
3697
+ stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y);
3698
+ }
3699
+
3700
+ //static int stbtt__tesselate_curve(stbtt__point * points, int *num_points, float x0,
3701
+ // float y0, float x1, float y1, float x2, float y2,
3702
+ // float objspace_flatness_squared, int n)
3703
+ function stbtt__tesselate_curve(points, x0, y0, x1, y1, x2, y2, objspace_flatness_squared, n) {
3704
+ var mx = (x0 + 2 * x1 + x2) / 4,
3705
+ my = (y0 + 2 * y1 + y2) / 4,
3706
+ dx = (x0 + x2) / 2 - mx,
3707
+ dy = (y0 + y2) / 2 - my;
3708
+ if (n > 16) {
3709
+ return 1;
3710
+ }
3711
+ if (dx * dx + dy * dy > objspace_flatness_squared) {
3712
+ stbtt__tesselate_curve(points, x0, y0, (x0 + x1) / 2.0, (y0 + y1) / 2.0, mx, my,
3713
+ objspace_flatness_squared, n + 1);
3714
+ stbtt__tesselate_curve(points, mx, my, (x1 + x2) / 2.0, (y1 + y2) / 2.0, x2, y2,
3715
+ objspace_flatness_squared, n + 1);
3716
+ } else {
3717
+ points.push({ x:x2, y:y2 });
3718
+ }
3719
+ return 1;
3720
+ }
3721
+
3722
+ //static void stbtt__tesselate_cubic(stbtt__point * points, int *num_points, float x0,
3723
+ // float y0, float x1, float y1, float x2, float y2,
3724
+ // float x3, float y3, float objspace_flatness_squared, int n)
3725
+ function stbtt__tesselate_cubic(points, x0, y0, x1, y1, x2, y2, x3, y3, objspace_flatness_squared, n) {
3726
+ var dx0 = x1 - x0,
3727
+ dy0 = y1 - y0,
3728
+ dx1 = x2 - x1,
3729
+ dy1 = y2 - y1,
3730
+ dx2 = x3 - x2,
3731
+ dy2 = y3 - y2,
3732
+ dx = x3 - x0,
3733
+ dy = y3 - y0,
3734
+ longlen = sqrt(dx0 * dx0 + dy0 * dy0) +
3735
+ sqrt(dx1 * dx1 + dy1 * dy1) +
3736
+ sqrt(dx2 * dx2 + dy2 * dy2),
3737
+ shortlen = sqrt(dx * dx + dy * dy),
3738
+ flatness_squared = longlen * longlen - shortlen * shortlen;
3739
+ if (n > 16) {
3740
+ return;
3741
+ }
3742
+
3743
+ if (flatness_squared > objspace_flatness_squared) {
3744
+ var x01 = (x0 + x1) / 2,
3745
+ y01 = (y0 + y1) / 2,
3746
+ x12 = (x1 + x2) / 2,
3747
+ y12 = (y1 + y2) / 2,
3748
+ x23 = (x2 + x3) / 2,
3749
+ y23 = (y2 + y3) / 2,
3750
+ xa = (x01 + x12) / 2,
3751
+ ya = (y01 + y12) / 2,
3752
+ xb = (x12 + x23) / 2,
3753
+ yb = (y12 + y23) / 2,
3754
+ mx = (xa + xb) / 2,
3755
+ my = (ya + yb) / 2;
3756
+
3757
+ stbtt__tesselate_cubic(points, x0, y0, x01, y01, xa, ya, mx, my,
3758
+ objspace_flatness_squared, n + 1);
3759
+ stbtt__tesselate_cubic(points, mx, my, xb, yb, x23, y23, x3, y3,
3760
+ objspace_flatness_squared, n + 1);
3761
+ } else {
3762
+ points.push({ x:x3, y:y3 });
3763
+ }
3764
+ }
3765
+
3766
+ //static stbtt__point *stbtt_FlattenCurves(stbtt_vertex * vertices, int num_verts,
3767
+ // float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata)
3768
+ function stbtt_FlattenCurves(vertices, objspace_flatness, contour_lengths) {
3769
+ var points = [],
3770
+ objspace_flatness_squared = objspace_flatness * objspace_flatness,
3771
+ n = -1, start = 0,
3772
+ x = 0, y = 0;
3773
+ for (var i = 0, nverts = vertices.length; i < nverts; ++i) {
3774
+ switch (vertices[i].type) {
3775
+ case STBTT_vmove:
3776
+ if (n >= 0) {
3777
+ contour_lengths[n] = points.length - start;
3778
+ }
3779
+ ++n;
3780
+ start = points.length;
3781
+ x = vertices[i].x, y = vertices[i].y;
3782
+ points.push({ x:x, y:y });
3783
+ break;
3784
+ case STBTT_vline:
3785
+ x = vertices[i].x, y = vertices[i].y;
3786
+ points.push({ x:x, y:y });
3787
+ break;
3788
+ case STBTT_vcurve:
3789
+ stbtt__tesselate_curve(points, x, y, vertices[i].cx, vertices[i].cy,
3790
+ vertices[i].x, vertices[i].y, objspace_flatness_squared, 0);
3791
+ x = vertices[i].x, y = vertices[i].y;
3792
+ break;
3793
+ case STBTT_vcubic:
3794
+ stbtt__tesselate_cubic(points, x, y, vertices[i].cx, vertices[i].cy,
3795
+ vertices[i].cx1, vertices[i].cy1, vertices[i].x, vertices[i].y,
3796
+ objspace_flatness_squared, 0);
3797
+ x = vertices[i].x, y = vertices[i].y;
3798
+ break;
3799
+ }
3800
+ }
3801
+ contour_lengths[n] = points.length - start;
3802
+
3803
+ //console.log("--cl(" + (n+1) + '):');
3804
+ //for (var i = 0; i <= n; i++) {
3805
+ // console.log(" %d", contour_lengths[i]);
3806
+ //}
3807
+ //console.log("\n--pts(" + points.length + '):');
3808
+ //for (var i = 0; i < points.length; i++) {
3809
+ // var pt = points[i];
3810
+ // console.log(i + ': ' + pt.x + ',' + pt.y);
3811
+ //}
3812
+
3813
+ return points;
3814
+ }
3815
+
3816
+ //extern void stbtt_Rasterize(stbtt__bitmap * result, float flatness_in_pixels,
3817
+ // stbtt_vertex * vertices, int num_verts, float scale_x,
3818
+ // float scale_y, float shift_x, float shift_y, int x_off,
3819
+ // int y_off, int invert, void *userdata)
3820
+ function stbtt_Rasterize(result, flatness_in_pixels, vertices, scale_x, scale_y, shift_x, shift_y,
3821
+ x_off, y_off, invert) {
3822
+ x_off |= 0, y_off |= 0;
3823
+ var scale = scale_x > scale_y ? scale_y : scale_x,
3824
+ wcount = [],
3825
+ windings = stbtt_FlattenCurves(vertices, flatness_in_pixels / scale, wcount);
3826
+ if (windings) {
3827
+ stbtt__rasterize(result, windings, wcount, scale_x, scale_y,
3828
+ shift_x, shift_y, x_off, y_off, invert);
3829
+ }
3830
+ }
3831
+
3832
+ //extern void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo * info,
3833
+ // unsigned char *output, int out_w, int out_h,
3834
+ // int out_stride, float scale_x, float scale_y,
3835
+ // float shift_x, float shift_y, int glyph)
3836
+ function stbtt_MakeGlyphBitmapSubpixel(info, buffer, out_w, out_h, out_stride,
3837
+ scale_x, scale_y, shift_x, shift_y, glyph) {
3838
+ var vertices = stbtt_GetGlyphShape(info, glyph);
3839
+ var gbm = {};
3840
+ var rect = stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y);
3841
+ gbm.pixels = buffer;
3842
+ gbm.w = out_w|0;
3843
+ gbm.h = out_h|0;
3844
+ gbm.stride = out_stride|0;
3845
+
3846
+ if (gbm.w && gbm.h) {
3847
+ stbtt_Rasterize(gbm, 0.35, vertices, scale_x, scale_y, shift_x, shift_y, rect.x0, rect.y0, 1);
3848
+ }
3849
+ }
3850
+
3851
+ //extern void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo * info,
3852
+ // unsigned char *output, int out_w,
3853
+ // int out_h, int out_stride, float scale_x,
3854
+ // float scale_y, float shift_x,
3855
+ // float shift_y, int codepoint)
3856
+ function stbtt_MakeCodepointBitmapSubpixel(info, buffer, out_w, out_h, out_stride,
3857
+ scale_x, scale_y, shift_x, shift_y, codepoint) {
3858
+ stbtt_MakeGlyphBitmapSubpixel(info, buffer, out_w, out_h, out_stride,
3859
+ scale_x, scale_y, shift_x, shift_y,
3860
+ stbtt_FindGlyphIndex(info, codepoint));
3861
+ }
3862
+
3863
+ //extern int stbtt_InitFont(stbtt_fontinfo * info, const unsigned char *data, int offset)
3864
+ function stbtt_InitFont(font, data, offset) {
3865
+ return stbtt_InitFont_internal(font, data, offset);
3866
+ }
3867
+
3868
+
3869
+ function InitFont(data) {
3870
+ var font = {};
3871
+ if (!stbtt_InitFont_internal(font, data, 0)) {
3872
+ return null;
3873
+ }
3874
+
3875
+ var vm = stbtt_GetFontVMetrics(font);
3876
+
3877
+ font.ascent = vm.ascent;
3878
+ font.descent = vm.descent;
3879
+ font.linegap = vm.linegap;
3880
+
3881
+ return font;
3882
+ }
3883
+
3884
+ function GetGlyph(font, codepoint, size_x, size_y) {
3885
+ size_y = size_y || size_x;
3886
+ var scale_x = size_x / font.ascent;
3887
+ var scale_y = size_y / font.ascent;
3888
+
3889
+ var glyph = stbtt_FindGlyphIndex(font, codepoint);
3890
+ if (!glyph && codepoint) {
3891
+ return null;
3892
+ }
3893
+
3894
+ var vertices = stbtt_GetGlyphShape(font, glyph);
3895
+ var rect = stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y, 0, 0);
3896
+ var width = rect.x1 - rect.x0;
3897
+ var height = rect.y1 - rect.y0;
3898
+ var pixels = null;
3899
+
3900
+ if (width && height) {
3901
+ var gbm = {
3902
+ pixels : (pixels = new Uint8Array(width * height)),
3903
+ w : width,
3904
+ h : height,
3905
+ stride : width,
3906
+ }
3907
+ stbtt_Rasterize(gbm, 0.35, vertices, scale_x, scale_y, 0, 0, rect.x0, rect.y0, 1);
3908
+ }
3909
+
3910
+ var hmetrics = stbtt_GetGlyphHMetrics(font, glyph);
3911
+ return {
3912
+ glyph:glyph, pixels:pixels, width:width, height:height, top:-rect.y0, left:rect.x0,
3913
+ advance:floor(hmetrics.advanceWidth * scale_x),
3914
+ }
3915
+ }
3916
+ function GetPaths(font, codepoint, size_x, size_y) {
3917
+ size_y = size_y || size_x;
3918
+ var scale_x = size_x / font.ascent;
3919
+ var scale_y = size_y / font.ascent;
3920
+
3921
+ var glyph = stbtt_FindGlyphIndex(font, codepoint);
3922
+ if (!glyph && codepoint) {
3923
+ return null;
3924
+ }
3925
+ var vertices = stbtt_GetGlyphShape(font, glyph);
3926
+ var hmetrics = stbtt_GetGlyphHMetrics(font, glyph);
3927
+
3928
+ // The hmetrics just give us advance. We need ascent and descent as well.
3929
+ var ascent = 0;
3930
+ var descent = 0;
3931
+
3932
+ // Convert to SVG notation
3933
+ var paths = [];
3934
+ if (vertices) {
3935
+ for (var i = 0, l = vertices.length; i < l; i++) {
3936
+ var v = vertices[i];
3937
+ var path;
3938
+ if (v.type == STBTT_vmove) {
3939
+ path = { type:'M', x:v.x * scale_x, y:v.y * scale_y };
3940
+ } else if (v.type == STBTT_vline) {
3941
+ path = { type:'L', x:v.x * scale_x, y:v.y * scale_y };
3942
+ } else if (v.type == STBTT_vcurve) {
3943
+ path = { type:'Q', x:v.x * scale_x, y:v.y * scale_y,
3944
+ cx:v.cx * scale_x, cy:v.cy * scale_y };
3945
+ } else if (v.type == STBTT_vcubic) {
3946
+ path = { type:'C', x:v.x * scale_x, y:v.y * scale_y,
3947
+ cx1:v.cx * scale_x, cy1:v.cy * scale_y,
3948
+ cx2:v.cx1 * scale_x, cy2:v.cy1 * scale_y };
3949
+ } else {
3950
+ continue;
3951
+ }
3952
+ if (path.y > ascent) ascent = path.y;
3953
+ if (path.y < descent) descent = path.y;
3954
+ paths.push(path);
3955
+ }
3956
+ }
3957
+
3958
+ // Add the glyph metrics to the returned array.
3959
+ paths.advance = hmetrics.advanceWidth * scale_x;
3960
+ paths.ascent = ascent;
3961
+ paths.descent = descent;
3962
+ return paths;
3963
+ }
3964
+
3965
+
3966
+ // exports
3967
+ return {
3968
+ InitFont: InitFont,
3969
+ GetGlyph: GetGlyph,
3970
+ GetPaths: GetPaths,
3971
+ }
3972
+
3973
+ })();
3974
+ function toUint8Array(data) {
3975
+ if (typeof data == "string") {
3976
+ var binary = /[^A-Za-z0-9+\/=\s]/.test(data);
3977
+ var bstr = binary ? data : atob(data),
3978
+ len = bstr.length,
3979
+ bytes = new Uint8Array(len);
3980
+ for (var i = 0; i < len; i++) {
3981
+ bytes[i] = bstr.charCodeAt(i);
3982
+ }
3983
+ return bytes;
3984
+ } else if (data instanceof Uint8Array) {
3985
+ return data;
3986
+ } else if (data instanceof ArrayBuffer) {
3987
+ return new Uint8Array(data);
3988
+ }
3989
+ throw new ReferenceError("data must be a binary or base64 encoded string or Uint8Array");
3990
+ }
3991
+
3992
+ FontLib.loadFont("OCR-A", 100, 100, "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");
3993
+ FontLib.loadFont("OCR-B", 96, 100, "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");
3994
+
3995
+ export function datamatrix(opts,dwg) { return _ToAny(bwipp_datamatrix,opts,dwg); };
3996
+ export function qrcode(opts,dwg) { return _ToAny(bwipp_qrcode,opts,dwg); };
3997
+ export function raw(bcid, text, options) { return ToRaw(bcid, text, options)};
3998
+ export { ToCanvas as toCanvas, ToSVG as toSVG, Render as render, LoadFont as loadFont,
3999
+ DrawingCanvas as drawingCanvas, DrawingSVG as drawingSVG,
4000
+ BWIPJS_VERSION, BWIPP_VERSION,
4001
+ };
4002
+ export default {
4003
+ toCanvas:ToCanvas, toSVG:ToSVG, render:Render, raw:ToRaw,
4004
+ drawingCanvas:DrawingCanvas, drawingSVG:DrawingSVG,
4005
+ fixupOptions:FixupOptions, loadFont:LoadFont, FontLib, BWIPJS_VERSION, BWIPP_VERSION,
4006
+ };