xl-public-utils 1.0.2 → 1.0.4

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