@flowaccount/pdfmake 1.0.5 → 1.0.6-staging.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/qrEnc.js CHANGED
@@ -1,791 +1,791 @@
1
- /*eslint no-unused-vars: ["error", {"args": "none"}]*/
2
- /*eslint no-redeclare: "off"*/
3
-
4
- 'use strict';
5
- /* qr.js -- QR code generator in Javascript (revision 2011-01-19)
6
- * Written by Kang Seonghoon <public+qrjs@mearie.org>.
7
- *
8
- * This source code is in the public domain; if your jurisdiction does not
9
- * recognize the public domain the terms of Creative Commons CC0 license
10
- * apply. In the other words, you can always do what you want.
11
- */
12
-
13
-
14
- // per-version information (cf. JIS X 0510:2004 pp. 30--36, 71)
15
- //
16
- // [0]: the degree of generator polynomial by ECC levels
17
- // [1]: # of code blocks by ECC levels
18
- // [2]: left-top positions of alignment patterns
19
- //
20
- // the number in this table (in particular, [0]) does not exactly match with
21
- // the numbers in the specficiation. see augumenteccs below for the reason.
22
- var VERSIONS = [
23
- null,
24
- [[10, 7, 17, 13], [1, 1, 1, 1], []],
25
- [[16, 10, 28, 22], [1, 1, 1, 1], [4, 16]],
26
- [[26, 15, 22, 18], [1, 1, 2, 2], [4, 20]],
27
- [[18, 20, 16, 26], [2, 1, 4, 2], [4, 24]],
28
- [[24, 26, 22, 18], [2, 1, 4, 4], [4, 28]],
29
- [[16, 18, 28, 24], [4, 2, 4, 4], [4, 32]],
30
- [[18, 20, 26, 18], [4, 2, 5, 6], [4, 20, 36]],
31
- [[22, 24, 26, 22], [4, 2, 6, 6], [4, 22, 40]],
32
- [[22, 30, 24, 20], [5, 2, 8, 8], [4, 24, 44]],
33
- [[26, 18, 28, 24], [5, 4, 8, 8], [4, 26, 48]],
34
- [[30, 20, 24, 28], [5, 4, 11, 8], [4, 28, 52]],
35
- [[22, 24, 28, 26], [8, 4, 11, 10], [4, 30, 56]],
36
- [[22, 26, 22, 24], [9, 4, 16, 12], [4, 32, 60]],
37
- [[24, 30, 24, 20], [9, 4, 16, 16], [4, 24, 44, 64]],
38
- [[24, 22, 24, 30], [10, 6, 18, 12], [4, 24, 46, 68]],
39
- [[28, 24, 30, 24], [10, 6, 16, 17], [4, 24, 48, 72]],
40
- [[28, 28, 28, 28], [11, 6, 19, 16], [4, 28, 52, 76]],
41
- [[26, 30, 28, 28], [13, 6, 21, 18], [4, 28, 54, 80]],
42
- [[26, 28, 26, 26], [14, 7, 25, 21], [4, 28, 56, 84]],
43
- [[26, 28, 28, 30], [16, 8, 25, 20], [4, 32, 60, 88]],
44
- [[26, 28, 30, 28], [17, 8, 25, 23], [4, 26, 48, 70, 92]],
45
- [[28, 28, 24, 30], [17, 9, 34, 23], [4, 24, 48, 72, 96]],
46
- [[28, 30, 30, 30], [18, 9, 30, 25], [4, 28, 52, 76, 100]],
47
- [[28, 30, 30, 30], [20, 10, 32, 27], [4, 26, 52, 78, 104]],
48
- [[28, 26, 30, 30], [21, 12, 35, 29], [4, 30, 56, 82, 108]],
49
- [[28, 28, 30, 28], [23, 12, 37, 34], [4, 28, 56, 84, 112]],
50
- [[28, 30, 30, 30], [25, 12, 40, 34], [4, 32, 60, 88, 116]],
51
- [[28, 30, 30, 30], [26, 13, 42, 35], [4, 24, 48, 72, 96, 120]],
52
- [[28, 30, 30, 30], [28, 14, 45, 38], [4, 28, 52, 76, 100, 124]],
53
- [[28, 30, 30, 30], [29, 15, 48, 40], [4, 24, 50, 76, 102, 128]],
54
- [[28, 30, 30, 30], [31, 16, 51, 43], [4, 28, 54, 80, 106, 132]],
55
- [[28, 30, 30, 30], [33, 17, 54, 45], [4, 32, 58, 84, 110, 136]],
56
- [[28, 30, 30, 30], [35, 18, 57, 48], [4, 28, 56, 84, 112, 140]],
57
- [[28, 30, 30, 30], [37, 19, 60, 51], [4, 32, 60, 88, 116, 144]],
58
- [[28, 30, 30, 30], [38, 19, 63, 53], [4, 28, 52, 76, 100, 124, 148]],
59
- [[28, 30, 30, 30], [40, 20, 66, 56], [4, 22, 48, 74, 100, 126, 152]],
60
- [[28, 30, 30, 30], [43, 21, 70, 59], [4, 26, 52, 78, 104, 130, 156]],
61
- [[28, 30, 30, 30], [45, 22, 74, 62], [4, 30, 56, 82, 108, 134, 160]],
62
- [[28, 30, 30, 30], [47, 24, 77, 65], [4, 24, 52, 80, 108, 136, 164]],
63
- [[28, 30, 30, 30], [49, 25, 81, 68], [4, 28, 56, 84, 112, 140, 168]]];
64
-
65
- // mode constants (cf. Table 2 in JIS X 0510:2004 p. 16)
66
- var MODE_TERMINATOR = 0;
67
- var MODE_NUMERIC = 1, MODE_ALPHANUMERIC = 2, MODE_OCTET = 4, MODE_KANJI = 8;
68
-
69
- // validation regexps
70
- var NUMERIC_REGEXP = /^\d*$/;
71
- var ALPHANUMERIC_REGEXP = /^[A-Za-z0-9 $%*+\-./:]*$/;
72
- var ALPHANUMERIC_OUT_REGEXP = /^[A-Z0-9 $%*+\-./:]*$/;
73
-
74
- // ECC levels (cf. Table 22 in JIS X 0510:2004 p. 45)
75
- var ECCLEVEL_L = 1, ECCLEVEL_M = 0, ECCLEVEL_Q = 3, ECCLEVEL_H = 2;
76
-
77
- // GF(2^8)-to-integer mapping with a reducing polynomial x^8+x^4+x^3+x^2+1
78
- // invariant: GF256_MAP[GF256_INVMAP[i]] == i for all i in [1,256)
79
- var GF256_MAP = [], GF256_INVMAP = [-1];
80
- for (var i = 0, v = 1; i < 255; ++i) {
81
- GF256_MAP.push(v);
82
- GF256_INVMAP[v] = i;
83
- v = (v * 2) ^ (v >= 128 ? 0x11d : 0);
84
- }
85
-
86
- // generator polynomials up to degree 30
87
- // (should match with polynomials in JIS X 0510:2004 Appendix A)
88
- //
89
- // generator polynomial of degree K is product of (x-\alpha^0), (x-\alpha^1),
90
- // ..., (x-\alpha^(K-1)). by convention, we omit the K-th coefficient (always 1)
91
- // from the result; also other coefficients are written in terms of the exponent
92
- // to \alpha to avoid the redundant calculation. (see also calculateecc below.)
93
- var GF256_GENPOLY = [[]];
94
- for (var i = 0; i < 30; ++i) {
95
- var prevpoly = GF256_GENPOLY[i], poly = [];
96
- for (var j = 0; j <= i; ++j) {
97
- var a = (j < i ? GF256_MAP[prevpoly[j]] : 0);
98
- var b = GF256_MAP[(i + (prevpoly[j - 1] || 0)) % 255];
99
- poly.push(GF256_INVMAP[a ^ b]);
100
- }
101
- GF256_GENPOLY.push(poly);
102
- }
103
-
104
- // alphanumeric character mapping (cf. Table 5 in JIS X 0510:2004 p. 19)
105
- var ALPHANUMERIC_MAP = {};
106
- for (var i = 0; i < 45; ++i) {
107
- ALPHANUMERIC_MAP['0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:'.charAt(i)] = i;
108
- }
109
-
110
- // mask functions in terms of row # and column #
111
- // (cf. Table 20 in JIS X 0510:2004 p. 42)
112
- /*jshint unused: false */
113
- var MASKFUNCS = [
114
- function (i, j) {
115
- return (i + j) % 2 === 0;
116
- },
117
- function (i, j) {
118
- return i % 2 === 0;
119
- },
120
- function (i, j) {
121
- return j % 3 === 0;
122
- },
123
- function (i, j) {
124
- return (i + j) % 3 === 0;
125
- },
126
- function (i, j) {
127
- return (((i / 2) | 0) + ((j / 3) | 0)) % 2 === 0;
128
- },
129
- function (i, j) {
130
- return (i * j) % 2 + (i * j) % 3 === 0;
131
- },
132
- function (i, j) {
133
- return ((i * j) % 2 + (i * j) % 3) % 2 === 0;
134
- },
135
- function (i, j) {
136
- return ((i + j) % 2 + (i * j) % 3) % 2 === 0;
137
- }];
138
-
139
- // returns true when the version information has to be embeded.
140
- var needsverinfo = function (ver) {
141
- return ver > 6;
142
- };
143
-
144
- // returns the size of entire QR code for given version.
145
- var getsizebyver = function (ver) {
146
- return 4 * ver + 17;
147
- };
148
-
149
- // returns the number of bits available for code words in this version.
150
- var nfullbits = function (ver) {
151
- /*
152
- * |<--------------- n --------------->|
153
- * | |<----- n-17 ---->| |
154
- * +-------+ ///+-------+ ----
155
- * | | ///| | ^
156
- * | 9x9 | @@@@@ ///| 9x8 | |
157
- * | | # # # @5x5@ # # # | | |
158
- * +-------+ @@@@@ +-------+ |
159
- * # ---|
160
- * ^ |
161
- * # |
162
- * @@@@@ @@@@@ @@@@@ | n
163
- * @5x5@ @5x5@ @5x5@ n-17
164
- * @@@@@ @@@@@ @@@@@ | |
165
- * # | |
166
- * ////// v |
167
- * //////# ---|
168
- * +-------+ @@@@@ @@@@@ |
169
- * | | @5x5@ @5x5@ |
170
- * | 8x9 | @@@@@ @@@@@ |
171
- * | | v
172
- * +-------+ ----
173
- *
174
- * when the entire code has n^2 modules and there are m^2-3 alignment
175
- * patterns, we have:
176
- * - 225 (= 9x9 + 9x8 + 8x9) modules for finder patterns and
177
- * format information;
178
- * - 2n-34 (= 2(n-17)) modules for timing patterns;
179
- * - 36 (= 3x6 + 6x3) modules for version information, if any;
180
- * - 25m^2-75 (= (m^2-3)(5x5)) modules for alignment patterns
181
- * if any, but 10m-20 (= 2(m-2)x5) of them overlaps with
182
- * timing patterns.
183
- */
184
- var v = VERSIONS[ver];
185
- var nbits = 16 * ver * ver + 128 * ver + 64; // finder, timing and format info.
186
- if (needsverinfo(ver))
187
- nbits -= 36; // version information
188
- if (v[2].length) { // alignment patterns
189
- nbits -= 25 * v[2].length * v[2].length - 10 * v[2].length - 55;
190
- }
191
- return nbits;
192
- };
193
-
194
- // returns the number of bits available for data portions (i.e. excludes ECC
195
- // bits but includes mode and length bits) in this version and ECC level.
196
- var ndatabits = function (ver, ecclevel) {
197
- var nbits = nfullbits(ver) & ~7; // no sub-octet code words
198
- var v = VERSIONS[ver];
199
- nbits -= 8 * v[0][ecclevel] * v[1][ecclevel]; // ecc bits
200
- return nbits;
201
- };
202
-
203
- // returns the number of bits required for the length of data.
204
- // (cf. Table 3 in JIS X 0510:2004 p. 16)
205
- var ndatalenbits = function (ver, mode) {
206
- switch (mode) {
207
- case MODE_NUMERIC:
208
- return (ver < 10 ? 10 : ver < 27 ? 12 : 14);
209
- case MODE_ALPHANUMERIC:
210
- return (ver < 10 ? 9 : ver < 27 ? 11 : 13);
211
- case MODE_OCTET:
212
- return (ver < 10 ? 8 : 16);
213
- case MODE_KANJI:
214
- return (ver < 10 ? 8 : ver < 27 ? 10 : 12);
215
- }
216
- };
217
-
218
- // returns the maximum length of data possible in given configuration.
219
- var getmaxdatalen = function (ver, mode, ecclevel) {
220
- var nbits = ndatabits(ver, ecclevel) - 4 - ndatalenbits(ver, mode); // 4 for mode bits
221
- switch (mode) {
222
- case MODE_NUMERIC:
223
- return ((nbits / 10) | 0) * 3 + (nbits % 10 < 4 ? 0 : nbits % 10 < 7 ? 1 : 2);
224
- case MODE_ALPHANUMERIC:
225
- return ((nbits / 11) | 0) * 2 + (nbits % 11 < 6 ? 0 : 1);
226
- case MODE_OCTET:
227
- return (nbits / 8) | 0;
228
- case MODE_KANJI:
229
- return (nbits / 13) | 0;
230
- }
231
- };
232
-
233
- // checks if the given data can be encoded in given mode, and returns
234
- // the converted data for the further processing if possible. otherwise
235
- // returns null.
236
- //
237
- // this function does not check the length of data; it is a duty of
238
- // encode function below (as it depends on the version and ECC level too).
239
- var validatedata = function (mode, data) {
240
- switch (mode) {
241
- case MODE_NUMERIC:
242
- if (!data.match(NUMERIC_REGEXP))
243
- return null;
244
- return data;
245
-
246
- case MODE_ALPHANUMERIC:
247
- if (!data.match(ALPHANUMERIC_REGEXP))
248
- return null;
249
- return data.toUpperCase();
250
-
251
- case MODE_OCTET:
252
- if (typeof data === 'string') { // encode as utf-8 string
253
- var newdata = [];
254
- for (var i = 0; i < data.length; ++i) {
255
- var ch = data.charCodeAt(i);
256
- if (ch < 0x80) {
257
- newdata.push(ch);
258
- } else if (ch < 0x800) {
259
- newdata.push(0xc0 | (ch >> 6),
260
- 0x80 | (ch & 0x3f));
261
- } else if (ch < 0x10000) {
262
- newdata.push(0xe0 | (ch >> 12),
263
- 0x80 | ((ch >> 6) & 0x3f),
264
- 0x80 | (ch & 0x3f));
265
- } else {
266
- newdata.push(0xf0 | (ch >> 18),
267
- 0x80 | ((ch >> 12) & 0x3f),
268
- 0x80 | ((ch >> 6) & 0x3f),
269
- 0x80 | (ch & 0x3f));
270
- }
271
- }
272
- return newdata;
273
- } else {
274
- return data;
275
- }
276
- }
277
- };
278
-
279
- // returns the code words (sans ECC bits) for given data and configurations.
280
- // requires data to be preprocessed by validatedata. no length check is
281
- // performed, and everything has to be checked before calling this function.
282
- var encode = function (ver, mode, data, maxbuflen) {
283
- var buf = [];
284
- var bits = 0, remaining = 8;
285
- var datalen = data.length;
286
-
287
- // this function is intentionally no-op when n=0.
288
- var pack = function (x, n) {
289
- if (n >= remaining) {
290
- buf.push(bits | (x >> (n -= remaining)));
291
- while (n >= 8)
292
- buf.push((x >> (n -= 8)) & 255);
293
- bits = 0;
294
- remaining = 8;
295
- }
296
- if (n > 0)
297
- bits |= (x & ((1 << n) - 1)) << (remaining -= n);
298
- };
299
-
300
- var nlenbits = ndatalenbits(ver, mode);
301
- pack(mode, 4);
302
- pack(datalen, nlenbits);
303
-
304
- switch (mode) {
305
- case MODE_NUMERIC:
306
- for (var i = 2; i < datalen; i += 3) {
307
- pack(parseInt(data.substring(i - 2, i + 1), 10), 10);
308
- }
309
- pack(parseInt(data.substring(i - 2), 10), [0, 4, 7][datalen % 3]);
310
- break;
311
-
312
- case MODE_ALPHANUMERIC:
313
- for (var i = 1; i < datalen; i += 2) {
314
- pack(ALPHANUMERIC_MAP[data.charAt(i - 1)] * 45 +
315
- ALPHANUMERIC_MAP[data.charAt(i)], 11);
316
- }
317
- if (datalen % 2 == 1) {
318
- pack(ALPHANUMERIC_MAP[data.charAt(i - 1)], 6);
319
- }
320
- break;
321
-
322
- case MODE_OCTET:
323
- for (var i = 0; i < datalen; ++i) {
324
- pack(data[i], 8);
325
- }
326
- break;
327
- }
328
-
329
- // final bits. it is possible that adding terminator causes the buffer
330
- // to overflow, but then the buffer truncated to the maximum size will
331
- // be valid as the truncated terminator mode bits and padding is
332
- // identical in appearance (cf. JIS X 0510:2004 sec 8.4.8).
333
- pack(MODE_TERMINATOR, 4);
334
- if (remaining < 8)
335
- buf.push(bits);
336
-
337
- // the padding to fill up the remaining space. we should not add any
338
- // words when the overflow already occurred.
339
- while (buf.length + 1 < maxbuflen)
340
- buf.push(0xec, 0x11);
341
- if (buf.length < maxbuflen)
342
- buf.push(0xec);
343
- return buf;
344
- };
345
-
346
- // calculates ECC code words for given code words and generator polynomial.
347
- //
348
- // this is quite similar to CRC calculation as both Reed-Solomon and CRC use
349
- // the certain kind of cyclic codes, which is effectively the division of
350
- // zero-augumented polynomial by the generator polynomial. the only difference
351
- // is that Reed-Solomon uses GF(2^8), instead of CRC's GF(2), and Reed-Solomon
352
- // uses the different generator polynomial than CRC's.
353
- var calculateecc = function (poly, genpoly) {
354
- var modulus = poly.slice(0);
355
- var polylen = poly.length, genpolylen = genpoly.length;
356
- for (var i = 0; i < genpolylen; ++i)
357
- modulus.push(0);
358
- for (var i = 0; i < polylen; ) {
359
- var quotient = GF256_INVMAP[modulus[i++]];
360
- if (quotient >= 0) {
361
- for (var j = 0; j < genpolylen; ++j) {
362
- modulus[i + j] ^= GF256_MAP[(quotient + genpoly[j]) % 255];
363
- }
364
- }
365
- }
366
- return modulus.slice(polylen);
367
- };
368
-
369
- // auguments ECC code words to given code words. the resulting words are
370
- // ready to be encoded in the matrix.
371
- //
372
- // the much of actual augumenting procedure follows JIS X 0510:2004 sec 8.7.
373
- // the code is simplified using the fact that the size of each code & ECC
374
- // blocks is almost same; for example, when we have 4 blocks and 46 data words
375
- // the number of code words in those blocks are 11, 11, 12, 12 respectively.
376
- var augumenteccs = function (poly, nblocks, genpoly) {
377
- var subsizes = [];
378
- var subsize = (poly.length / nblocks) | 0, subsize0 = 0;
379
- var pivot = nblocks - poly.length % nblocks;
380
- for (var i = 0; i < pivot; ++i) {
381
- subsizes.push(subsize0);
382
- subsize0 += subsize;
383
- }
384
- for (var i = pivot; i < nblocks; ++i) {
385
- subsizes.push(subsize0);
386
- subsize0 += subsize + 1;
387
- }
388
- subsizes.push(subsize0);
389
-
390
- var eccs = [];
391
- for (var i = 0; i < nblocks; ++i) {
392
- eccs.push(calculateecc(poly.slice(subsizes[i], subsizes[i + 1]), genpoly));
393
- }
394
-
395
- var result = [];
396
- var nitemsperblock = (poly.length / nblocks) | 0;
397
- for (var i = 0; i < nitemsperblock; ++i) {
398
- for (var j = 0; j < nblocks; ++j) {
399
- result.push(poly[subsizes[j] + i]);
400
- }
401
- }
402
- for (var j = pivot; j < nblocks; ++j) {
403
- result.push(poly[subsizes[j + 1] - 1]);
404
- }
405
- for (var i = 0; i < genpoly.length; ++i) {
406
- for (var j = 0; j < nblocks; ++j) {
407
- result.push(eccs[j][i]);
408
- }
409
- }
410
- return result;
411
- };
412
-
413
- // auguments BCH(p+q,q) code to the polynomial over GF(2), given the proper
414
- // genpoly. the both input and output are in binary numbers, and unlike
415
- // calculateecc genpoly should include the 1 bit for the highest degree.
416
- //
417
- // actual polynomials used for this procedure are as follows:
418
- // - p=10, q=5, genpoly=x^10+x^8+x^5+x^4+x^2+x+1 (JIS X 0510:2004 Appendix C)
419
- // - p=18, q=6, genpoly=x^12+x^11+x^10+x^9+x^8+x^5+x^2+1 (ibid. Appendix D)
420
- var augumentbch = function (poly, p, genpoly, q) {
421
- var modulus = poly << q;
422
- for (var i = p - 1; i >= 0; --i) {
423
- if ((modulus >> (q + i)) & 1)
424
- modulus ^= genpoly << i;
425
- }
426
- return (poly << q) | modulus;
427
- };
428
-
429
- // creates the base matrix for given version. it returns two matrices, one of
430
- // them is the actual one and the another represents the "reserved" portion
431
- // (e.g. finder and timing patterns) of the matrix.
432
- //
433
- // some entries in the matrix may be undefined, rather than 0 or 1. this is
434
- // intentional (no initialization needed!), and putdata below will fill
435
- // the remaining ones.
436
- var makebasematrix = function (ver) {
437
- var v = VERSIONS[ver], n = getsizebyver(ver);
438
- var matrix = [], reserved = [];
439
- for (var i = 0; i < n; ++i) {
440
- matrix.push([]);
441
- reserved.push([]);
442
- }
443
-
444
- var blit = function (y, x, h, w, bits) {
445
- for (var i = 0; i < h; ++i) {
446
- for (var j = 0; j < w; ++j) {
447
- matrix[y + i][x + j] = (bits[i] >> j) & 1;
448
- reserved[y + i][x + j] = 1;
449
- }
450
- }
451
- };
452
-
453
- // finder patterns and a part of timing patterns
454
- // will also mark the format information area (not yet written) as reserved.
455
- blit(0, 0, 9, 9, [0x7f, 0x41, 0x5d, 0x5d, 0x5d, 0x41, 0x17f, 0x00, 0x40]);
456
- blit(n - 8, 0, 8, 9, [0x100, 0x7f, 0x41, 0x5d, 0x5d, 0x5d, 0x41, 0x7f]);
457
- blit(0, n - 8, 9, 8, [0xfe, 0x82, 0xba, 0xba, 0xba, 0x82, 0xfe, 0x00, 0x00]);
458
-
459
- // the rest of timing patterns
460
- for (var i = 9; i < n - 8; ++i) {
461
- matrix[6][i] = matrix[i][6] = ~i & 1;
462
- reserved[6][i] = reserved[i][6] = 1;
463
- }
464
-
465
- // alignment patterns
466
- var aligns = v[2], m = aligns.length;
467
- for (var i = 0; i < m; ++i) {
468
- var minj = (i === 0 || i === m - 1 ? 1 : 0), maxj = (i === 0 ? m - 1 : m);
469
- for (var j = minj; j < maxj; ++j) {
470
- blit(aligns[i], aligns[j], 5, 5, [0x1f, 0x11, 0x15, 0x11, 0x1f]);
471
- }
472
- }
473
-
474
- // version information
475
- if (needsverinfo(ver)) {
476
- var code = augumentbch(ver, 6, 0x1f25, 12);
477
- var k = 0;
478
- for (var i = 0; i < 6; ++i) {
479
- for (var j = 0; j < 3; ++j) {
480
- matrix[i][(n - 11) + j] = matrix[(n - 11) + j][i] = (code >> k++) & 1;
481
- reserved[i][(n - 11) + j] = reserved[(n - 11) + j][i] = 1;
482
- }
483
- }
484
- }
485
-
486
- return {matrix: matrix, reserved: reserved};
487
- };
488
-
489
- // fills the data portion (i.e. unmarked in reserved) of the matrix with given
490
- // code words. the size of code words should be no more than available bits,
491
- // and remaining bits are padded to 0 (cf. JIS X 0510:2004 sec 8.7.3).
492
- var putdata = function (matrix, reserved, buf) {
493
- var n = matrix.length;
494
- var k = 0, dir = -1;
495
- for (var i = n - 1; i >= 0; i -= 2) {
496
- if (i == 6)
497
- --i; // skip the entire timing pattern column
498
- var jj = (dir < 0 ? n - 1 : 0);
499
- for (var j = 0; j < n; ++j) {
500
- for (var ii = i; ii > i - 2; --ii) {
501
- if (!reserved[jj][ii]) {
502
- // may overflow, but (undefined >> x)
503
- // is 0 so it will auto-pad to zero.
504
- matrix[jj][ii] = (buf[k >> 3] >> (~k & 7)) & 1;
505
- ++k;
506
- }
507
- }
508
- jj += dir;
509
- }
510
- dir = -dir;
511
- }
512
- return matrix;
513
- };
514
-
515
- // XOR-masks the data portion of the matrix. repeating the call with the same
516
- // arguments will revert the prior call (convenient in the matrix evaluation).
517
- var maskdata = function (matrix, reserved, mask) {
518
- var maskf = MASKFUNCS[mask];
519
- var n = matrix.length;
520
- for (var i = 0; i < n; ++i) {
521
- for (var j = 0; j < n; ++j) {
522
- if (!reserved[i][j])
523
- matrix[i][j] ^= maskf(i, j);
524
- }
525
- }
526
- return matrix;
527
- };
528
-
529
- // puts the format information.
530
- var putformatinfo = function (matrix, reserved, ecclevel, mask) {
531
- var n = matrix.length;
532
- var code = augumentbch((ecclevel << 3) | mask, 5, 0x537, 10) ^ 0x5412;
533
- for (var i = 0; i < 15; ++i) {
534
- var r = [0, 1, 2, 3, 4, 5, 7, 8, n - 7, n - 6, n - 5, n - 4, n - 3, n - 2, n - 1][i];
535
- var c = [n - 1, n - 2, n - 3, n - 4, n - 5, n - 6, n - 7, n - 8, 7, 5, 4, 3, 2, 1, 0][i];
536
- matrix[r][8] = matrix[8][c] = (code >> i) & 1;
537
- // we don't have to mark those bits reserved; always done
538
- // in makebasematrix above.
539
- }
540
- return matrix;
541
- };
542
-
543
- // evaluates the resulting matrix and returns the score (lower is better).
544
- // (cf. JIS X 0510:2004 sec 8.8.2)
545
- //
546
- // the evaluation procedure tries to avoid the problematic patterns naturally
547
- // occuring from the original matrix. for example, it penaltizes the patterns
548
- // which just look like the finder pattern which will confuse the decoder.
549
- // we choose the mask which results in the lowest score among 8 possible ones.
550
- //
551
- // note: zxing seems to use the same procedure and in many cases its choice
552
- // agrees to ours, but sometimes it does not. practically it doesn't matter.
553
- var evaluatematrix = function (matrix) {
554
- // N1+(k-5) points for each consecutive row of k same-colored modules,
555
- // where k >= 5. no overlapping row counts.
556
- var PENALTY_CONSECUTIVE = 3;
557
- // N2 points for each 2x2 block of same-colored modules.
558
- // overlapping block does count.
559
- var PENALTY_TWOBYTWO = 3;
560
- // N3 points for each pattern with >4W:1B:1W:3B:1W:1B or
561
- // 1B:1W:3B:1W:1B:>4W, or their multiples (e.g. highly unlikely,
562
- // but 13W:3B:3W:9B:3W:3B counts).
563
- var PENALTY_FINDERLIKE = 40;
564
- // N4*k points for every (5*k)% deviation from 50% black density.
565
- // i.e. k=1 for 55~60% and 40~45%, k=2 for 60~65% and 35~40%, etc.
566
- var PENALTY_DENSITY = 10;
567
-
568
- var evaluategroup = function (groups) { // assumes [W,B,W,B,W,...,B,W]
569
- var score = 0;
570
- for (var i = 0; i < groups.length; ++i) {
571
- if (groups[i] >= 5)
572
- score += PENALTY_CONSECUTIVE + (groups[i] - 5);
573
- }
574
- for (var i = 5; i < groups.length; i += 2) {
575
- var p = groups[i];
576
- if (groups[i - 1] == p && groups[i - 2] == 3 * p && groups[i - 3] == p &&
577
- groups[i - 4] == p && (groups[i - 5] >= 4 * p || groups[i + 1] >= 4 * p)) {
578
- // this part differs from zxing...
579
- score += PENALTY_FINDERLIKE;
580
- }
581
- }
582
- return score;
583
- };
584
-
585
- var n = matrix.length;
586
- var score = 0, nblacks = 0;
587
- for (var i = 0; i < n; ++i) {
588
- var row = matrix[i];
589
- var groups;
590
-
591
- // evaluate the current row
592
- groups = [0]; // the first empty group of white
593
- for (var j = 0; j < n; ) {
594
- var k;
595
- for (k = 0; j < n && row[j]; ++k)
596
- ++j;
597
- groups.push(k);
598
- for (k = 0; j < n && !row[j]; ++k)
599
- ++j;
600
- groups.push(k);
601
- }
602
- score += evaluategroup(groups);
603
-
604
- // evaluate the current column
605
- groups = [0];
606
- for (var j = 0; j < n; ) {
607
- var k;
608
- for (k = 0; j < n && matrix[j][i]; ++k)
609
- ++j;
610
- groups.push(k);
611
- for (k = 0; j < n && !matrix[j][i]; ++k)
612
- ++j;
613
- groups.push(k);
614
- }
615
- score += evaluategroup(groups);
616
-
617
- // check the 2x2 box and calculate the density
618
- var nextrow = matrix[i + 1] || [];
619
- nblacks += row[0];
620
- for (var j = 1; j < n; ++j) {
621
- var p = row[j];
622
- nblacks += p;
623
- // at least comparison with next row should be strict...
624
- if (row[j - 1] == p && nextrow[j] === p && nextrow[j - 1] === p) {
625
- score += PENALTY_TWOBYTWO;
626
- }
627
- }
628
- }
629
-
630
- score += PENALTY_DENSITY * ((Math.abs(nblacks / n / n - 0.5) / 0.05) | 0);
631
- return score;
632
- };
633
-
634
- // returns the fully encoded QR code matrix which contains given data.
635
- // it also chooses the best mask automatically when mask is -1.
636
- var generate = function (data, ver, mode, ecclevel, mask) {
637
- var v = VERSIONS[ver];
638
- var buf = encode(ver, mode, data, ndatabits(ver, ecclevel) >> 3);
639
- buf = augumenteccs(buf, v[1][ecclevel], GF256_GENPOLY[v[0][ecclevel]]);
640
-
641
- var result = makebasematrix(ver);
642
- var matrix = result.matrix, reserved = result.reserved;
643
- putdata(matrix, reserved, buf);
644
-
645
- if (mask < 0) {
646
- // find the best mask
647
- maskdata(matrix, reserved, 0);
648
- putformatinfo(matrix, reserved, ecclevel, 0);
649
- var bestmask = 0, bestscore = evaluatematrix(matrix);
650
- maskdata(matrix, reserved, 0);
651
- for (mask = 1; mask < 8; ++mask) {
652
- maskdata(matrix, reserved, mask);
653
- putformatinfo(matrix, reserved, ecclevel, mask);
654
- var score = evaluatematrix(matrix);
655
- if (bestscore > score) {
656
- bestscore = score;
657
- bestmask = mask;
658
- }
659
- maskdata(matrix, reserved, mask);
660
- }
661
- mask = bestmask;
662
- }
663
-
664
- maskdata(matrix, reserved, mask);
665
- putformatinfo(matrix, reserved, ecclevel, mask);
666
- return matrix;
667
- };
668
-
669
- // the public interface is trivial; the options available are as follows:
670
- //
671
- // - version: an integer in [1,40]. when omitted (or -1) the smallest possible
672
- // version is chosen.
673
- // - mode: one of 'numeric', 'alphanumeric', 'octet'. when omitted the smallest
674
- // possible mode is chosen.
675
- // - eccLevel: one of 'L', 'M', 'Q', 'H'. defaults to 'L'.
676
- // - mask: an integer in [0,7]. when omitted (or -1) the best mask is chosen.
677
- //
678
-
679
- function generateFrame(data, options) {
680
- var MODES = {'numeric': MODE_NUMERIC, 'alphanumeric': MODE_ALPHANUMERIC,
681
- 'octet': MODE_OCTET};
682
- var ECCLEVELS = {'L': ECCLEVEL_L, 'M': ECCLEVEL_M, 'Q': ECCLEVEL_Q,
683
- 'H': ECCLEVEL_H};
684
-
685
- options = options || {};
686
- var ver = options.version || -1;
687
- var ecclevel = ECCLEVELS[(options.eccLevel || 'L').toUpperCase()];
688
- var mode = options.mode ? MODES[options.mode.toLowerCase()] : -1;
689
- var mask = 'mask' in options ? options.mask : -1;
690
-
691
- if (mode < 0) {
692
- if (typeof data === 'string') {
693
- if (data.match(NUMERIC_REGEXP)) {
694
- mode = MODE_NUMERIC;
695
- } else if (data.match(ALPHANUMERIC_OUT_REGEXP)) {
696
- // while encode supports case-insensitive encoding, we restrict the data to be uppercased when auto-selecting the mode.
697
- mode = MODE_ALPHANUMERIC;
698
- } else {
699
- mode = MODE_OCTET;
700
- }
701
- } else {
702
- mode = MODE_OCTET;
703
- }
704
- } else if (!(mode == MODE_NUMERIC || mode == MODE_ALPHANUMERIC ||
705
- mode == MODE_OCTET)) {
706
- throw 'invalid or unsupported mode';
707
- }
708
-
709
- data = validatedata(mode, data);
710
- if (data === null)
711
- throw 'invalid data format';
712
-
713
- if (ecclevel < 0 || ecclevel > 3)
714
- throw 'invalid ECC level';
715
-
716
- if (ver < 0) {
717
- for (ver = 1; ver <= 40; ++ver) {
718
- if (data.length <= getmaxdatalen(ver, mode, ecclevel))
719
- break;
720
- }
721
- if (ver > 40)
722
- throw 'too large data for the Qr format';
723
- } else if (ver < 1 || ver > 40) {
724
- throw 'invalid Qr version! should be between 1 and 40';
725
- }
726
-
727
- if (mask != -1 && (mask < 0 || mask > 8))
728
- throw 'invalid mask';
729
- //console.log('version:', ver, 'mode:', mode, 'ECC:', ecclevel, 'mask:', mask )
730
- return generate(data, ver, mode, ecclevel, mask);
731
- }
732
-
733
-
734
- // options
735
- // - modulesize: a number. this is a size of each modules in pixels, and
736
- // defaults to 5px.
737
- // - margin: a number. this is a size of margin in *modules*, and defaults to
738
- // 4 (white modules). the specficiation mandates the margin no less than 4
739
- // modules, so it is better not to alter this value unless you know what
740
- // you're doing.
741
- function buildCanvas(data, options) {
742
-
743
- var canvas = [];
744
- var background = options.background || '#fff';
745
- var foreground = options.foreground || '#000';
746
- var padding = options.padding || 0;
747
- //var margin = options.margin || 4;
748
- var matrix = generateFrame(data, options);
749
- var n = matrix.length;
750
- var modSize = Math.floor(options.fit ? options.fit / n : 5);
751
- var size = (n * modSize) + (modSize * padding * 2);
752
- var paddingXY = modSize * padding;
753
-
754
- canvas.push({
755
- type: 'rect',
756
- x: 0, y: 0, w: size, h: size, lineWidth: 0, color: background
757
- });
758
-
759
- for (var i = 0; i < n; ++i) {
760
- for (var j = 0; j < n; ++j) {
761
- if (matrix[i][j]) {
762
- canvas.push({
763
- type: 'rect',
764
- x: modSize * j + paddingXY,
765
- y: modSize * i + paddingXY,
766
- w: modSize,
767
- h: modSize,
768
- lineWidth: 0,
769
- color: foreground
770
- });
771
- }
772
- }
773
- }
774
-
775
- return {
776
- canvas: canvas,
777
- size: size
778
- };
779
-
780
- }
781
-
782
- function measure(node) {
783
- var cd = buildCanvas(node.qr, node);
784
- node._canvas = cd.canvas;
785
- node._width = node._height = node._minWidth = node._maxWidth = node._minHeight = node._maxHeight = cd.size;
786
- return node;
787
- }
788
-
789
- module.exports = {
790
- measure: measure
1
+ /*eslint no-unused-vars: ["error", {"args": "none"}]*/
2
+ /*eslint no-redeclare: "off"*/
3
+
4
+ 'use strict';
5
+ /* qr.js -- QR code generator in Javascript (revision 2011-01-19)
6
+ * Written by Kang Seonghoon <public+qrjs@mearie.org>.
7
+ *
8
+ * This source code is in the public domain; if your jurisdiction does not
9
+ * recognize the public domain the terms of Creative Commons CC0 license
10
+ * apply. In the other words, you can always do what you want.
11
+ */
12
+
13
+
14
+ // per-version information (cf. JIS X 0510:2004 pp. 30--36, 71)
15
+ //
16
+ // [0]: the degree of generator polynomial by ECC levels
17
+ // [1]: # of code blocks by ECC levels
18
+ // [2]: left-top positions of alignment patterns
19
+ //
20
+ // the number in this table (in particular, [0]) does not exactly match with
21
+ // the numbers in the specficiation. see augumenteccs below for the reason.
22
+ var VERSIONS = [
23
+ null,
24
+ [[10, 7, 17, 13], [1, 1, 1, 1], []],
25
+ [[16, 10, 28, 22], [1, 1, 1, 1], [4, 16]],
26
+ [[26, 15, 22, 18], [1, 1, 2, 2], [4, 20]],
27
+ [[18, 20, 16, 26], [2, 1, 4, 2], [4, 24]],
28
+ [[24, 26, 22, 18], [2, 1, 4, 4], [4, 28]],
29
+ [[16, 18, 28, 24], [4, 2, 4, 4], [4, 32]],
30
+ [[18, 20, 26, 18], [4, 2, 5, 6], [4, 20, 36]],
31
+ [[22, 24, 26, 22], [4, 2, 6, 6], [4, 22, 40]],
32
+ [[22, 30, 24, 20], [5, 2, 8, 8], [4, 24, 44]],
33
+ [[26, 18, 28, 24], [5, 4, 8, 8], [4, 26, 48]],
34
+ [[30, 20, 24, 28], [5, 4, 11, 8], [4, 28, 52]],
35
+ [[22, 24, 28, 26], [8, 4, 11, 10], [4, 30, 56]],
36
+ [[22, 26, 22, 24], [9, 4, 16, 12], [4, 32, 60]],
37
+ [[24, 30, 24, 20], [9, 4, 16, 16], [4, 24, 44, 64]],
38
+ [[24, 22, 24, 30], [10, 6, 18, 12], [4, 24, 46, 68]],
39
+ [[28, 24, 30, 24], [10, 6, 16, 17], [4, 24, 48, 72]],
40
+ [[28, 28, 28, 28], [11, 6, 19, 16], [4, 28, 52, 76]],
41
+ [[26, 30, 28, 28], [13, 6, 21, 18], [4, 28, 54, 80]],
42
+ [[26, 28, 26, 26], [14, 7, 25, 21], [4, 28, 56, 84]],
43
+ [[26, 28, 28, 30], [16, 8, 25, 20], [4, 32, 60, 88]],
44
+ [[26, 28, 30, 28], [17, 8, 25, 23], [4, 26, 48, 70, 92]],
45
+ [[28, 28, 24, 30], [17, 9, 34, 23], [4, 24, 48, 72, 96]],
46
+ [[28, 30, 30, 30], [18, 9, 30, 25], [4, 28, 52, 76, 100]],
47
+ [[28, 30, 30, 30], [20, 10, 32, 27], [4, 26, 52, 78, 104]],
48
+ [[28, 26, 30, 30], [21, 12, 35, 29], [4, 30, 56, 82, 108]],
49
+ [[28, 28, 30, 28], [23, 12, 37, 34], [4, 28, 56, 84, 112]],
50
+ [[28, 30, 30, 30], [25, 12, 40, 34], [4, 32, 60, 88, 116]],
51
+ [[28, 30, 30, 30], [26, 13, 42, 35], [4, 24, 48, 72, 96, 120]],
52
+ [[28, 30, 30, 30], [28, 14, 45, 38], [4, 28, 52, 76, 100, 124]],
53
+ [[28, 30, 30, 30], [29, 15, 48, 40], [4, 24, 50, 76, 102, 128]],
54
+ [[28, 30, 30, 30], [31, 16, 51, 43], [4, 28, 54, 80, 106, 132]],
55
+ [[28, 30, 30, 30], [33, 17, 54, 45], [4, 32, 58, 84, 110, 136]],
56
+ [[28, 30, 30, 30], [35, 18, 57, 48], [4, 28, 56, 84, 112, 140]],
57
+ [[28, 30, 30, 30], [37, 19, 60, 51], [4, 32, 60, 88, 116, 144]],
58
+ [[28, 30, 30, 30], [38, 19, 63, 53], [4, 28, 52, 76, 100, 124, 148]],
59
+ [[28, 30, 30, 30], [40, 20, 66, 56], [4, 22, 48, 74, 100, 126, 152]],
60
+ [[28, 30, 30, 30], [43, 21, 70, 59], [4, 26, 52, 78, 104, 130, 156]],
61
+ [[28, 30, 30, 30], [45, 22, 74, 62], [4, 30, 56, 82, 108, 134, 160]],
62
+ [[28, 30, 30, 30], [47, 24, 77, 65], [4, 24, 52, 80, 108, 136, 164]],
63
+ [[28, 30, 30, 30], [49, 25, 81, 68], [4, 28, 56, 84, 112, 140, 168]]];
64
+
65
+ // mode constants (cf. Table 2 in JIS X 0510:2004 p. 16)
66
+ var MODE_TERMINATOR = 0;
67
+ var MODE_NUMERIC = 1, MODE_ALPHANUMERIC = 2, MODE_OCTET = 4, MODE_KANJI = 8;
68
+
69
+ // validation regexps
70
+ var NUMERIC_REGEXP = /^\d*$/;
71
+ var ALPHANUMERIC_REGEXP = /^[A-Za-z0-9 $%*+\-./:]*$/;
72
+ var ALPHANUMERIC_OUT_REGEXP = /^[A-Z0-9 $%*+\-./:]*$/;
73
+
74
+ // ECC levels (cf. Table 22 in JIS X 0510:2004 p. 45)
75
+ var ECCLEVEL_L = 1, ECCLEVEL_M = 0, ECCLEVEL_Q = 3, ECCLEVEL_H = 2;
76
+
77
+ // GF(2^8)-to-integer mapping with a reducing polynomial x^8+x^4+x^3+x^2+1
78
+ // invariant: GF256_MAP[GF256_INVMAP[i]] == i for all i in [1,256)
79
+ var GF256_MAP = [], GF256_INVMAP = [-1];
80
+ for (var i = 0, v = 1; i < 255; ++i) {
81
+ GF256_MAP.push(v);
82
+ GF256_INVMAP[v] = i;
83
+ v = (v * 2) ^ (v >= 128 ? 0x11d : 0);
84
+ }
85
+
86
+ // generator polynomials up to degree 30
87
+ // (should match with polynomials in JIS X 0510:2004 Appendix A)
88
+ //
89
+ // generator polynomial of degree K is product of (x-\alpha^0), (x-\alpha^1),
90
+ // ..., (x-\alpha^(K-1)). by convention, we omit the K-th coefficient (always 1)
91
+ // from the result; also other coefficients are written in terms of the exponent
92
+ // to \alpha to avoid the redundant calculation. (see also calculateecc below.)
93
+ var GF256_GENPOLY = [[]];
94
+ for (var i = 0; i < 30; ++i) {
95
+ var prevpoly = GF256_GENPOLY[i], poly = [];
96
+ for (var j = 0; j <= i; ++j) {
97
+ var a = (j < i ? GF256_MAP[prevpoly[j]] : 0);
98
+ var b = GF256_MAP[(i + (prevpoly[j - 1] || 0)) % 255];
99
+ poly.push(GF256_INVMAP[a ^ b]);
100
+ }
101
+ GF256_GENPOLY.push(poly);
102
+ }
103
+
104
+ // alphanumeric character mapping (cf. Table 5 in JIS X 0510:2004 p. 19)
105
+ var ALPHANUMERIC_MAP = {};
106
+ for (var i = 0; i < 45; ++i) {
107
+ ALPHANUMERIC_MAP['0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:'.charAt(i)] = i;
108
+ }
109
+
110
+ // mask functions in terms of row # and column #
111
+ // (cf. Table 20 in JIS X 0510:2004 p. 42)
112
+ /*jshint unused: false */
113
+ var MASKFUNCS = [
114
+ function (i, j) {
115
+ return (i + j) % 2 === 0;
116
+ },
117
+ function (i, j) {
118
+ return i % 2 === 0;
119
+ },
120
+ function (i, j) {
121
+ return j % 3 === 0;
122
+ },
123
+ function (i, j) {
124
+ return (i + j) % 3 === 0;
125
+ },
126
+ function (i, j) {
127
+ return (((i / 2) | 0) + ((j / 3) | 0)) % 2 === 0;
128
+ },
129
+ function (i, j) {
130
+ return (i * j) % 2 + (i * j) % 3 === 0;
131
+ },
132
+ function (i, j) {
133
+ return ((i * j) % 2 + (i * j) % 3) % 2 === 0;
134
+ },
135
+ function (i, j) {
136
+ return ((i + j) % 2 + (i * j) % 3) % 2 === 0;
137
+ }];
138
+
139
+ // returns true when the version information has to be embeded.
140
+ var needsverinfo = function (ver) {
141
+ return ver > 6;
142
+ };
143
+
144
+ // returns the size of entire QR code for given version.
145
+ var getsizebyver = function (ver) {
146
+ return 4 * ver + 17;
147
+ };
148
+
149
+ // returns the number of bits available for code words in this version.
150
+ var nfullbits = function (ver) {
151
+ /*
152
+ * |<--------------- n --------------->|
153
+ * | |<----- n-17 ---->| |
154
+ * +-------+ ///+-------+ ----
155
+ * | | ///| | ^
156
+ * | 9x9 | @@@@@ ///| 9x8 | |
157
+ * | | # # # @5x5@ # # # | | |
158
+ * +-------+ @@@@@ +-------+ |
159
+ * # ---|
160
+ * ^ |
161
+ * # |
162
+ * @@@@@ @@@@@ @@@@@ | n
163
+ * @5x5@ @5x5@ @5x5@ n-17
164
+ * @@@@@ @@@@@ @@@@@ | |
165
+ * # | |
166
+ * ////// v |
167
+ * //////# ---|
168
+ * +-------+ @@@@@ @@@@@ |
169
+ * | | @5x5@ @5x5@ |
170
+ * | 8x9 | @@@@@ @@@@@ |
171
+ * | | v
172
+ * +-------+ ----
173
+ *
174
+ * when the entire code has n^2 modules and there are m^2-3 alignment
175
+ * patterns, we have:
176
+ * - 225 (= 9x9 + 9x8 + 8x9) modules for finder patterns and
177
+ * format information;
178
+ * - 2n-34 (= 2(n-17)) modules for timing patterns;
179
+ * - 36 (= 3x6 + 6x3) modules for version information, if any;
180
+ * - 25m^2-75 (= (m^2-3)(5x5)) modules for alignment patterns
181
+ * if any, but 10m-20 (= 2(m-2)x5) of them overlaps with
182
+ * timing patterns.
183
+ */
184
+ var v = VERSIONS[ver];
185
+ var nbits = 16 * ver * ver + 128 * ver + 64; // finder, timing and format info.
186
+ if (needsverinfo(ver))
187
+ nbits -= 36; // version information
188
+ if (v[2].length) { // alignment patterns
189
+ nbits -= 25 * v[2].length * v[2].length - 10 * v[2].length - 55;
190
+ }
191
+ return nbits;
192
+ };
193
+
194
+ // returns the number of bits available for data portions (i.e. excludes ECC
195
+ // bits but includes mode and length bits) in this version and ECC level.
196
+ var ndatabits = function (ver, ecclevel) {
197
+ var nbits = nfullbits(ver) & ~7; // no sub-octet code words
198
+ var v = VERSIONS[ver];
199
+ nbits -= 8 * v[0][ecclevel] * v[1][ecclevel]; // ecc bits
200
+ return nbits;
201
+ };
202
+
203
+ // returns the number of bits required for the length of data.
204
+ // (cf. Table 3 in JIS X 0510:2004 p. 16)
205
+ var ndatalenbits = function (ver, mode) {
206
+ switch (mode) {
207
+ case MODE_NUMERIC:
208
+ return (ver < 10 ? 10 : ver < 27 ? 12 : 14);
209
+ case MODE_ALPHANUMERIC:
210
+ return (ver < 10 ? 9 : ver < 27 ? 11 : 13);
211
+ case MODE_OCTET:
212
+ return (ver < 10 ? 8 : 16);
213
+ case MODE_KANJI:
214
+ return (ver < 10 ? 8 : ver < 27 ? 10 : 12);
215
+ }
216
+ };
217
+
218
+ // returns the maximum length of data possible in given configuration.
219
+ var getmaxdatalen = function (ver, mode, ecclevel) {
220
+ var nbits = ndatabits(ver, ecclevel) - 4 - ndatalenbits(ver, mode); // 4 for mode bits
221
+ switch (mode) {
222
+ case MODE_NUMERIC:
223
+ return ((nbits / 10) | 0) * 3 + (nbits % 10 < 4 ? 0 : nbits % 10 < 7 ? 1 : 2);
224
+ case MODE_ALPHANUMERIC:
225
+ return ((nbits / 11) | 0) * 2 + (nbits % 11 < 6 ? 0 : 1);
226
+ case MODE_OCTET:
227
+ return (nbits / 8) | 0;
228
+ case MODE_KANJI:
229
+ return (nbits / 13) | 0;
230
+ }
231
+ };
232
+
233
+ // checks if the given data can be encoded in given mode, and returns
234
+ // the converted data for the further processing if possible. otherwise
235
+ // returns null.
236
+ //
237
+ // this function does not check the length of data; it is a duty of
238
+ // encode function below (as it depends on the version and ECC level too).
239
+ var validatedata = function (mode, data) {
240
+ switch (mode) {
241
+ case MODE_NUMERIC:
242
+ if (!data.match(NUMERIC_REGEXP))
243
+ return null;
244
+ return data;
245
+
246
+ case MODE_ALPHANUMERIC:
247
+ if (!data.match(ALPHANUMERIC_REGEXP))
248
+ return null;
249
+ return data.toUpperCase();
250
+
251
+ case MODE_OCTET:
252
+ if (typeof data === 'string') { // encode as utf-8 string
253
+ var newdata = [];
254
+ for (var i = 0; i < data.length; ++i) {
255
+ var ch = data.charCodeAt(i);
256
+ if (ch < 0x80) {
257
+ newdata.push(ch);
258
+ } else if (ch < 0x800) {
259
+ newdata.push(0xc0 | (ch >> 6),
260
+ 0x80 | (ch & 0x3f));
261
+ } else if (ch < 0x10000) {
262
+ newdata.push(0xe0 | (ch >> 12),
263
+ 0x80 | ((ch >> 6) & 0x3f),
264
+ 0x80 | (ch & 0x3f));
265
+ } else {
266
+ newdata.push(0xf0 | (ch >> 18),
267
+ 0x80 | ((ch >> 12) & 0x3f),
268
+ 0x80 | ((ch >> 6) & 0x3f),
269
+ 0x80 | (ch & 0x3f));
270
+ }
271
+ }
272
+ return newdata;
273
+ } else {
274
+ return data;
275
+ }
276
+ }
277
+ };
278
+
279
+ // returns the code words (sans ECC bits) for given data and configurations.
280
+ // requires data to be preprocessed by validatedata. no length check is
281
+ // performed, and everything has to be checked before calling this function.
282
+ var encode = function (ver, mode, data, maxbuflen) {
283
+ var buf = [];
284
+ var bits = 0, remaining = 8;
285
+ var datalen = data.length;
286
+
287
+ // this function is intentionally no-op when n=0.
288
+ var pack = function (x, n) {
289
+ if (n >= remaining) {
290
+ buf.push(bits | (x >> (n -= remaining)));
291
+ while (n >= 8)
292
+ buf.push((x >> (n -= 8)) & 255);
293
+ bits = 0;
294
+ remaining = 8;
295
+ }
296
+ if (n > 0)
297
+ bits |= (x & ((1 << n) - 1)) << (remaining -= n);
298
+ };
299
+
300
+ var nlenbits = ndatalenbits(ver, mode);
301
+ pack(mode, 4);
302
+ pack(datalen, nlenbits);
303
+
304
+ switch (mode) {
305
+ case MODE_NUMERIC:
306
+ for (var i = 2; i < datalen; i += 3) {
307
+ pack(parseInt(data.substring(i - 2, i + 1), 10), 10);
308
+ }
309
+ pack(parseInt(data.substring(i - 2), 10), [0, 4, 7][datalen % 3]);
310
+ break;
311
+
312
+ case MODE_ALPHANUMERIC:
313
+ for (var i = 1; i < datalen; i += 2) {
314
+ pack(ALPHANUMERIC_MAP[data.charAt(i - 1)] * 45 +
315
+ ALPHANUMERIC_MAP[data.charAt(i)], 11);
316
+ }
317
+ if (datalen % 2 == 1) {
318
+ pack(ALPHANUMERIC_MAP[data.charAt(i - 1)], 6);
319
+ }
320
+ break;
321
+
322
+ case MODE_OCTET:
323
+ for (var i = 0; i < datalen; ++i) {
324
+ pack(data[i], 8);
325
+ }
326
+ break;
327
+ }
328
+
329
+ // final bits. it is possible that adding terminator causes the buffer
330
+ // to overflow, but then the buffer truncated to the maximum size will
331
+ // be valid as the truncated terminator mode bits and padding is
332
+ // identical in appearance (cf. JIS X 0510:2004 sec 8.4.8).
333
+ pack(MODE_TERMINATOR, 4);
334
+ if (remaining < 8)
335
+ buf.push(bits);
336
+
337
+ // the padding to fill up the remaining space. we should not add any
338
+ // words when the overflow already occurred.
339
+ while (buf.length + 1 < maxbuflen)
340
+ buf.push(0xec, 0x11);
341
+ if (buf.length < maxbuflen)
342
+ buf.push(0xec);
343
+ return buf;
344
+ };
345
+
346
+ // calculates ECC code words for given code words and generator polynomial.
347
+ //
348
+ // this is quite similar to CRC calculation as both Reed-Solomon and CRC use
349
+ // the certain kind of cyclic codes, which is effectively the division of
350
+ // zero-augumented polynomial by the generator polynomial. the only difference
351
+ // is that Reed-Solomon uses GF(2^8), instead of CRC's GF(2), and Reed-Solomon
352
+ // uses the different generator polynomial than CRC's.
353
+ var calculateecc = function (poly, genpoly) {
354
+ var modulus = poly.slice(0);
355
+ var polylen = poly.length, genpolylen = genpoly.length;
356
+ for (var i = 0; i < genpolylen; ++i)
357
+ modulus.push(0);
358
+ for (var i = 0; i < polylen; ) {
359
+ var quotient = GF256_INVMAP[modulus[i++]];
360
+ if (quotient >= 0) {
361
+ for (var j = 0; j < genpolylen; ++j) {
362
+ modulus[i + j] ^= GF256_MAP[(quotient + genpoly[j]) % 255];
363
+ }
364
+ }
365
+ }
366
+ return modulus.slice(polylen);
367
+ };
368
+
369
+ // auguments ECC code words to given code words. the resulting words are
370
+ // ready to be encoded in the matrix.
371
+ //
372
+ // the much of actual augumenting procedure follows JIS X 0510:2004 sec 8.7.
373
+ // the code is simplified using the fact that the size of each code & ECC
374
+ // blocks is almost same; for example, when we have 4 blocks and 46 data words
375
+ // the number of code words in those blocks are 11, 11, 12, 12 respectively.
376
+ var augumenteccs = function (poly, nblocks, genpoly) {
377
+ var subsizes = [];
378
+ var subsize = (poly.length / nblocks) | 0, subsize0 = 0;
379
+ var pivot = nblocks - poly.length % nblocks;
380
+ for (var i = 0; i < pivot; ++i) {
381
+ subsizes.push(subsize0);
382
+ subsize0 += subsize;
383
+ }
384
+ for (var i = pivot; i < nblocks; ++i) {
385
+ subsizes.push(subsize0);
386
+ subsize0 += subsize + 1;
387
+ }
388
+ subsizes.push(subsize0);
389
+
390
+ var eccs = [];
391
+ for (var i = 0; i < nblocks; ++i) {
392
+ eccs.push(calculateecc(poly.slice(subsizes[i], subsizes[i + 1]), genpoly));
393
+ }
394
+
395
+ var result = [];
396
+ var nitemsperblock = (poly.length / nblocks) | 0;
397
+ for (var i = 0; i < nitemsperblock; ++i) {
398
+ for (var j = 0; j < nblocks; ++j) {
399
+ result.push(poly[subsizes[j] + i]);
400
+ }
401
+ }
402
+ for (var j = pivot; j < nblocks; ++j) {
403
+ result.push(poly[subsizes[j + 1] - 1]);
404
+ }
405
+ for (var i = 0; i < genpoly.length; ++i) {
406
+ for (var j = 0; j < nblocks; ++j) {
407
+ result.push(eccs[j][i]);
408
+ }
409
+ }
410
+ return result;
411
+ };
412
+
413
+ // auguments BCH(p+q,q) code to the polynomial over GF(2), given the proper
414
+ // genpoly. the both input and output are in binary numbers, and unlike
415
+ // calculateecc genpoly should include the 1 bit for the highest degree.
416
+ //
417
+ // actual polynomials used for this procedure are as follows:
418
+ // - p=10, q=5, genpoly=x^10+x^8+x^5+x^4+x^2+x+1 (JIS X 0510:2004 Appendix C)
419
+ // - p=18, q=6, genpoly=x^12+x^11+x^10+x^9+x^8+x^5+x^2+1 (ibid. Appendix D)
420
+ var augumentbch = function (poly, p, genpoly, q) {
421
+ var modulus = poly << q;
422
+ for (var i = p - 1; i >= 0; --i) {
423
+ if ((modulus >> (q + i)) & 1)
424
+ modulus ^= genpoly << i;
425
+ }
426
+ return (poly << q) | modulus;
427
+ };
428
+
429
+ // creates the base matrix for given version. it returns two matrices, one of
430
+ // them is the actual one and the another represents the "reserved" portion
431
+ // (e.g. finder and timing patterns) of the matrix.
432
+ //
433
+ // some entries in the matrix may be undefined, rather than 0 or 1. this is
434
+ // intentional (no initialization needed!), and putdata below will fill
435
+ // the remaining ones.
436
+ var makebasematrix = function (ver) {
437
+ var v = VERSIONS[ver], n = getsizebyver(ver);
438
+ var matrix = [], reserved = [];
439
+ for (var i = 0; i < n; ++i) {
440
+ matrix.push([]);
441
+ reserved.push([]);
442
+ }
443
+
444
+ var blit = function (y, x, h, w, bits) {
445
+ for (var i = 0; i < h; ++i) {
446
+ for (var j = 0; j < w; ++j) {
447
+ matrix[y + i][x + j] = (bits[i] >> j) & 1;
448
+ reserved[y + i][x + j] = 1;
449
+ }
450
+ }
451
+ };
452
+
453
+ // finder patterns and a part of timing patterns
454
+ // will also mark the format information area (not yet written) as reserved.
455
+ blit(0, 0, 9, 9, [0x7f, 0x41, 0x5d, 0x5d, 0x5d, 0x41, 0x17f, 0x00, 0x40]);
456
+ blit(n - 8, 0, 8, 9, [0x100, 0x7f, 0x41, 0x5d, 0x5d, 0x5d, 0x41, 0x7f]);
457
+ blit(0, n - 8, 9, 8, [0xfe, 0x82, 0xba, 0xba, 0xba, 0x82, 0xfe, 0x00, 0x00]);
458
+
459
+ // the rest of timing patterns
460
+ for (var i = 9; i < n - 8; ++i) {
461
+ matrix[6][i] = matrix[i][6] = ~i & 1;
462
+ reserved[6][i] = reserved[i][6] = 1;
463
+ }
464
+
465
+ // alignment patterns
466
+ var aligns = v[2], m = aligns.length;
467
+ for (var i = 0; i < m; ++i) {
468
+ var minj = (i === 0 || i === m - 1 ? 1 : 0), maxj = (i === 0 ? m - 1 : m);
469
+ for (var j = minj; j < maxj; ++j) {
470
+ blit(aligns[i], aligns[j], 5, 5, [0x1f, 0x11, 0x15, 0x11, 0x1f]);
471
+ }
472
+ }
473
+
474
+ // version information
475
+ if (needsverinfo(ver)) {
476
+ var code = augumentbch(ver, 6, 0x1f25, 12);
477
+ var k = 0;
478
+ for (var i = 0; i < 6; ++i) {
479
+ for (var j = 0; j < 3; ++j) {
480
+ matrix[i][(n - 11) + j] = matrix[(n - 11) + j][i] = (code >> k++) & 1;
481
+ reserved[i][(n - 11) + j] = reserved[(n - 11) + j][i] = 1;
482
+ }
483
+ }
484
+ }
485
+
486
+ return {matrix: matrix, reserved: reserved};
487
+ };
488
+
489
+ // fills the data portion (i.e. unmarked in reserved) of the matrix with given
490
+ // code words. the size of code words should be no more than available bits,
491
+ // and remaining bits are padded to 0 (cf. JIS X 0510:2004 sec 8.7.3).
492
+ var putdata = function (matrix, reserved, buf) {
493
+ var n = matrix.length;
494
+ var k = 0, dir = -1;
495
+ for (var i = n - 1; i >= 0; i -= 2) {
496
+ if (i == 6)
497
+ --i; // skip the entire timing pattern column
498
+ var jj = (dir < 0 ? n - 1 : 0);
499
+ for (var j = 0; j < n; ++j) {
500
+ for (var ii = i; ii > i - 2; --ii) {
501
+ if (!reserved[jj][ii]) {
502
+ // may overflow, but (undefined >> x)
503
+ // is 0 so it will auto-pad to zero.
504
+ matrix[jj][ii] = (buf[k >> 3] >> (~k & 7)) & 1;
505
+ ++k;
506
+ }
507
+ }
508
+ jj += dir;
509
+ }
510
+ dir = -dir;
511
+ }
512
+ return matrix;
513
+ };
514
+
515
+ // XOR-masks the data portion of the matrix. repeating the call with the same
516
+ // arguments will revert the prior call (convenient in the matrix evaluation).
517
+ var maskdata = function (matrix, reserved, mask) {
518
+ var maskf = MASKFUNCS[mask];
519
+ var n = matrix.length;
520
+ for (var i = 0; i < n; ++i) {
521
+ for (var j = 0; j < n; ++j) {
522
+ if (!reserved[i][j])
523
+ matrix[i][j] ^= maskf(i, j);
524
+ }
525
+ }
526
+ return matrix;
527
+ };
528
+
529
+ // puts the format information.
530
+ var putformatinfo = function (matrix, reserved, ecclevel, mask) {
531
+ var n = matrix.length;
532
+ var code = augumentbch((ecclevel << 3) | mask, 5, 0x537, 10) ^ 0x5412;
533
+ for (var i = 0; i < 15; ++i) {
534
+ var r = [0, 1, 2, 3, 4, 5, 7, 8, n - 7, n - 6, n - 5, n - 4, n - 3, n - 2, n - 1][i];
535
+ var c = [n - 1, n - 2, n - 3, n - 4, n - 5, n - 6, n - 7, n - 8, 7, 5, 4, 3, 2, 1, 0][i];
536
+ matrix[r][8] = matrix[8][c] = (code >> i) & 1;
537
+ // we don't have to mark those bits reserved; always done
538
+ // in makebasematrix above.
539
+ }
540
+ return matrix;
541
+ };
542
+
543
+ // evaluates the resulting matrix and returns the score (lower is better).
544
+ // (cf. JIS X 0510:2004 sec 8.8.2)
545
+ //
546
+ // the evaluation procedure tries to avoid the problematic patterns naturally
547
+ // occuring from the original matrix. for example, it penaltizes the patterns
548
+ // which just look like the finder pattern which will confuse the decoder.
549
+ // we choose the mask which results in the lowest score among 8 possible ones.
550
+ //
551
+ // note: zxing seems to use the same procedure and in many cases its choice
552
+ // agrees to ours, but sometimes it does not. practically it doesn't matter.
553
+ var evaluatematrix = function (matrix) {
554
+ // N1+(k-5) points for each consecutive row of k same-colored modules,
555
+ // where k >= 5. no overlapping row counts.
556
+ var PENALTY_CONSECUTIVE = 3;
557
+ // N2 points for each 2x2 block of same-colored modules.
558
+ // overlapping block does count.
559
+ var PENALTY_TWOBYTWO = 3;
560
+ // N3 points for each pattern with >4W:1B:1W:3B:1W:1B or
561
+ // 1B:1W:3B:1W:1B:>4W, or their multiples (e.g. highly unlikely,
562
+ // but 13W:3B:3W:9B:3W:3B counts).
563
+ var PENALTY_FINDERLIKE = 40;
564
+ // N4*k points for every (5*k)% deviation from 50% black density.
565
+ // i.e. k=1 for 55~60% and 40~45%, k=2 for 60~65% and 35~40%, etc.
566
+ var PENALTY_DENSITY = 10;
567
+
568
+ var evaluategroup = function (groups) { // assumes [W,B,W,B,W,...,B,W]
569
+ var score = 0;
570
+ for (var i = 0; i < groups.length; ++i) {
571
+ if (groups[i] >= 5)
572
+ score += PENALTY_CONSECUTIVE + (groups[i] - 5);
573
+ }
574
+ for (var i = 5; i < groups.length; i += 2) {
575
+ var p = groups[i];
576
+ if (groups[i - 1] == p && groups[i - 2] == 3 * p && groups[i - 3] == p &&
577
+ groups[i - 4] == p && (groups[i - 5] >= 4 * p || groups[i + 1] >= 4 * p)) {
578
+ // this part differs from zxing...
579
+ score += PENALTY_FINDERLIKE;
580
+ }
581
+ }
582
+ return score;
583
+ };
584
+
585
+ var n = matrix.length;
586
+ var score = 0, nblacks = 0;
587
+ for (var i = 0; i < n; ++i) {
588
+ var row = matrix[i];
589
+ var groups;
590
+
591
+ // evaluate the current row
592
+ groups = [0]; // the first empty group of white
593
+ for (var j = 0; j < n; ) {
594
+ var k;
595
+ for (k = 0; j < n && row[j]; ++k)
596
+ ++j;
597
+ groups.push(k);
598
+ for (k = 0; j < n && !row[j]; ++k)
599
+ ++j;
600
+ groups.push(k);
601
+ }
602
+ score += evaluategroup(groups);
603
+
604
+ // evaluate the current column
605
+ groups = [0];
606
+ for (var j = 0; j < n; ) {
607
+ var k;
608
+ for (k = 0; j < n && matrix[j][i]; ++k)
609
+ ++j;
610
+ groups.push(k);
611
+ for (k = 0; j < n && !matrix[j][i]; ++k)
612
+ ++j;
613
+ groups.push(k);
614
+ }
615
+ score += evaluategroup(groups);
616
+
617
+ // check the 2x2 box and calculate the density
618
+ var nextrow = matrix[i + 1] || [];
619
+ nblacks += row[0];
620
+ for (var j = 1; j < n; ++j) {
621
+ var p = row[j];
622
+ nblacks += p;
623
+ // at least comparison with next row should be strict...
624
+ if (row[j - 1] == p && nextrow[j] === p && nextrow[j - 1] === p) {
625
+ score += PENALTY_TWOBYTWO;
626
+ }
627
+ }
628
+ }
629
+
630
+ score += PENALTY_DENSITY * ((Math.abs(nblacks / n / n - 0.5) / 0.05) | 0);
631
+ return score;
632
+ };
633
+
634
+ // returns the fully encoded QR code matrix which contains given data.
635
+ // it also chooses the best mask automatically when mask is -1.
636
+ var generate = function (data, ver, mode, ecclevel, mask) {
637
+ var v = VERSIONS[ver];
638
+ var buf = encode(ver, mode, data, ndatabits(ver, ecclevel) >> 3);
639
+ buf = augumenteccs(buf, v[1][ecclevel], GF256_GENPOLY[v[0][ecclevel]]);
640
+
641
+ var result = makebasematrix(ver);
642
+ var matrix = result.matrix, reserved = result.reserved;
643
+ putdata(matrix, reserved, buf);
644
+
645
+ if (mask < 0) {
646
+ // find the best mask
647
+ maskdata(matrix, reserved, 0);
648
+ putformatinfo(matrix, reserved, ecclevel, 0);
649
+ var bestmask = 0, bestscore = evaluatematrix(matrix);
650
+ maskdata(matrix, reserved, 0);
651
+ for (mask = 1; mask < 8; ++mask) {
652
+ maskdata(matrix, reserved, mask);
653
+ putformatinfo(matrix, reserved, ecclevel, mask);
654
+ var score = evaluatematrix(matrix);
655
+ if (bestscore > score) {
656
+ bestscore = score;
657
+ bestmask = mask;
658
+ }
659
+ maskdata(matrix, reserved, mask);
660
+ }
661
+ mask = bestmask;
662
+ }
663
+
664
+ maskdata(matrix, reserved, mask);
665
+ putformatinfo(matrix, reserved, ecclevel, mask);
666
+ return matrix;
667
+ };
668
+
669
+ // the public interface is trivial; the options available are as follows:
670
+ //
671
+ // - version: an integer in [1,40]. when omitted (or -1) the smallest possible
672
+ // version is chosen.
673
+ // - mode: one of 'numeric', 'alphanumeric', 'octet'. when omitted the smallest
674
+ // possible mode is chosen.
675
+ // - eccLevel: one of 'L', 'M', 'Q', 'H'. defaults to 'L'.
676
+ // - mask: an integer in [0,7]. when omitted (or -1) the best mask is chosen.
677
+ //
678
+
679
+ function generateFrame(data, options) {
680
+ var MODES = {'numeric': MODE_NUMERIC, 'alphanumeric': MODE_ALPHANUMERIC,
681
+ 'octet': MODE_OCTET};
682
+ var ECCLEVELS = {'L': ECCLEVEL_L, 'M': ECCLEVEL_M, 'Q': ECCLEVEL_Q,
683
+ 'H': ECCLEVEL_H};
684
+
685
+ options = options || {};
686
+ var ver = options.version || -1;
687
+ var ecclevel = ECCLEVELS[(options.eccLevel || 'L').toUpperCase()];
688
+ var mode = options.mode ? MODES[options.mode.toLowerCase()] : -1;
689
+ var mask = 'mask' in options ? options.mask : -1;
690
+
691
+ if (mode < 0) {
692
+ if (typeof data === 'string') {
693
+ if (data.match(NUMERIC_REGEXP)) {
694
+ mode = MODE_NUMERIC;
695
+ } else if (data.match(ALPHANUMERIC_OUT_REGEXP)) {
696
+ // while encode supports case-insensitive encoding, we restrict the data to be uppercased when auto-selecting the mode.
697
+ mode = MODE_ALPHANUMERIC;
698
+ } else {
699
+ mode = MODE_OCTET;
700
+ }
701
+ } else {
702
+ mode = MODE_OCTET;
703
+ }
704
+ } else if (!(mode == MODE_NUMERIC || mode == MODE_ALPHANUMERIC ||
705
+ mode == MODE_OCTET)) {
706
+ throw 'invalid or unsupported mode';
707
+ }
708
+
709
+ data = validatedata(mode, data);
710
+ if (data === null)
711
+ throw 'invalid data format';
712
+
713
+ if (ecclevel < 0 || ecclevel > 3)
714
+ throw 'invalid ECC level';
715
+
716
+ if (ver < 0) {
717
+ for (ver = 1; ver <= 40; ++ver) {
718
+ if (data.length <= getmaxdatalen(ver, mode, ecclevel))
719
+ break;
720
+ }
721
+ if (ver > 40)
722
+ throw 'too large data for the Qr format';
723
+ } else if (ver < 1 || ver > 40) {
724
+ throw 'invalid Qr version! should be between 1 and 40';
725
+ }
726
+
727
+ if (mask != -1 && (mask < 0 || mask > 8))
728
+ throw 'invalid mask';
729
+ //console.log('version:', ver, 'mode:', mode, 'ECC:', ecclevel, 'mask:', mask )
730
+ return generate(data, ver, mode, ecclevel, mask);
731
+ }
732
+
733
+
734
+ // options
735
+ // - modulesize: a number. this is a size of each modules in pixels, and
736
+ // defaults to 5px.
737
+ // - margin: a number. this is a size of margin in *modules*, and defaults to
738
+ // 4 (white modules). the specficiation mandates the margin no less than 4
739
+ // modules, so it is better not to alter this value unless you know what
740
+ // you're doing.
741
+ function buildCanvas(data, options) {
742
+
743
+ var canvas = [];
744
+ var background = options.background || '#fff';
745
+ var foreground = options.foreground || '#000';
746
+ var padding = options.padding || 0;
747
+ //var margin = options.margin || 4;
748
+ var matrix = generateFrame(data, options);
749
+ var n = matrix.length;
750
+ var modSize = Math.floor(options.fit ? options.fit / n : 5);
751
+ var size = (n * modSize) + (modSize * padding * 2);
752
+ var paddingXY = modSize * padding;
753
+
754
+ canvas.push({
755
+ type: 'rect',
756
+ x: 0, y: 0, w: size, h: size, lineWidth: 0, color: background
757
+ });
758
+
759
+ for (var i = 0; i < n; ++i) {
760
+ for (var j = 0; j < n; ++j) {
761
+ if (matrix[i][j]) {
762
+ canvas.push({
763
+ type: 'rect',
764
+ x: modSize * j + paddingXY,
765
+ y: modSize * i + paddingXY,
766
+ w: modSize,
767
+ h: modSize,
768
+ lineWidth: 0,
769
+ color: foreground
770
+ });
771
+ }
772
+ }
773
+ }
774
+
775
+ return {
776
+ canvas: canvas,
777
+ size: size
778
+ };
779
+
780
+ }
781
+
782
+ function measure(node) {
783
+ var cd = buildCanvas(node.qr, node);
784
+ node._canvas = cd.canvas;
785
+ node._width = node._height = node._minWidth = node._maxWidth = node._minHeight = node._maxHeight = cd.size;
786
+ return node;
787
+ }
788
+
789
+ module.exports = {
790
+ measure: measure
791
791
  };