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