Commit 8a535c50 by 高淑倩

modify: 条形码

parent a1a97872
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -398,4 +398,5 @@ var PATTERNS = [ ...@@ -398,4 +398,5 @@ var PATTERNS = [
[2, 1, 1, 2, 1, 4, 0, 0], // 104 [2, 1, 1, 2, 1, 4, 0, 0], // 104
[2, 1, 1, 2, 3, 2, 0, 0], // 105 [2, 1, 1, 2, 3, 2, 0, 0], // 105
[2, 3, 3, 1, 1, 1, 2, 0] // 106 [2, 3, 3, 1, 1, 1, 2, 0] // 106
] ]
\ No newline at end of file
var QR = (function () { var QR = (function () {
// alignment pattern // alignment pattern
var adelta = [ var adelta = [
0, 11, 15, 19, 23, 27, 31, // force 1 pat 0, 11, 15, 19, 23, 27, 31, // force 1 pat
16, 18, 20, 22, 24, 26, 28, 20, 22, 24, 24, 26, 28, 28, 22, 24, 24, 16, 18, 20, 22, 24, 26, 28, 20, 22, 24, 24, 26, 28, 28, 22, 24, 24,
26, 26, 28, 28, 24, 24, 26, 26, 26, 28, 28, 24, 26, 26, 26, 28, 28 26, 26, 28, 28, 24, 24, 26, 26, 26, 28, 28, 24, 26, 26, 26, 28, 28
];
// version block
var vpat = [
0xc94, 0x5bc, 0xa99, 0x4d3, 0xbf6, 0x762, 0x847, 0x60d,
0x928, 0xb78, 0x45d, 0xa17, 0x532, 0x9a6, 0x683, 0x8c9,
0x7ec, 0xec4, 0x1e1, 0xfab, 0x08e, 0xc1a, 0x33f, 0xd75,
0x250, 0x9d5, 0x6f0, 0x8ba, 0x79f, 0xb0b, 0x42e, 0xa64,
0x541, 0xc69
]; ];
// version block // final format bits with mask: level << 3 | mask
var vpat = [ var fmtword = [
0xc94, 0x5bc, 0xa99, 0x4d3, 0xbf6, 0x762, 0x847, 0x60d, 0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976, //L
0x928, 0xb78, 0x45d, 0xa17, 0x532, 0x9a6, 0x683, 0x8c9, 0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0, //M
0x7ec, 0xec4, 0x1e1, 0xfab, 0x08e, 0xc1a, 0x33f, 0xd75, 0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed, //Q
0x250, 0x9d5, 0x6f0, 0x8ba, 0x79f, 0xb0b, 0x42e, 0xa64, 0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b //H
0x541, 0xc69 ];
];
// 4 per version: number of blocks 1,2; data width; ecc width
// final format bits with mask: level << 3 | mask var eccblocks = [
var fmtword = [ 1, 0, 19, 7, 1, 0, 16, 10, 1, 0, 13, 13, 1, 0, 9, 17,
0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976, //L 1, 0, 34, 10, 1, 0, 28, 16, 1, 0, 22, 22, 1, 0, 16, 28,
0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0, //M 1, 0, 55, 15, 1, 0, 44, 26, 2, 0, 17, 18, 2, 0, 13, 22,
0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed, //Q 1, 0, 80, 20, 2, 0, 32, 18, 2, 0, 24, 26, 4, 0, 9, 16,
0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b //H 1, 0, 108, 26, 2, 0, 43, 24, 2, 2, 15, 18, 2, 2, 11, 22,
]; 2, 0, 68, 18, 4, 0, 27, 16, 4, 0, 19, 24, 4, 0, 15, 28,
2, 0, 78, 20, 4, 0, 31, 18, 2, 4, 14, 18, 4, 1, 13, 26,
// 4 per version: number of blocks 1,2; data width; ecc width 2, 0, 97, 24, 2, 2, 38, 22, 4, 2, 18, 22, 4, 2, 14, 26,
var eccblocks = [ 2, 0, 116, 30, 3, 2, 36, 22, 4, 4, 16, 20, 4, 4, 12, 24,
1, 0, 19, 7, 1, 0, 16, 10, 1, 0, 13, 13, 1, 0, 9, 17, 2, 2, 68, 18, 4, 1, 43, 26, 6, 2, 19, 24, 6, 2, 15, 28,
1, 0, 34, 10, 1, 0, 28, 16, 1, 0, 22, 22, 1, 0, 16, 28, 4, 0, 81, 20, 1, 4, 50, 30, 4, 4, 22, 28, 3, 8, 12, 24,
1, 0, 55, 15, 1, 0, 44, 26, 2, 0, 17, 18, 2, 0, 13, 22, 2, 2, 92, 24, 6, 2, 36, 22, 4, 6, 20, 26, 7, 4, 14, 28,
1, 0, 80, 20, 2, 0, 32, 18, 2, 0, 24, 26, 4, 0, 9, 16, 4, 0, 107, 26, 8, 1, 37, 22, 8, 4, 20, 24, 12, 4, 11, 22,
1, 0, 108, 26, 2, 0, 43, 24, 2, 2, 15, 18, 2, 2, 11, 22, 3, 1, 115, 30, 4, 5, 40, 24, 11, 5, 16, 20, 11, 5, 12, 24,
2, 0, 68, 18, 4, 0, 27, 16, 4, 0, 19, 24, 4, 0, 15, 28, 5, 1, 87, 22, 5, 5, 41, 24, 5, 7, 24, 30, 11, 7, 12, 24,
2, 0, 78, 20, 4, 0, 31, 18, 2, 4, 14, 18, 4, 1, 13, 26, 5, 1, 98, 24, 7, 3, 45, 28, 15, 2, 19, 24, 3, 13, 15, 30,
2, 0, 97, 24, 2, 2, 38, 22, 4, 2, 18, 22, 4, 2, 14, 26, 1, 5, 107, 28, 10, 1, 46, 28, 1, 15, 22, 28, 2, 17, 14, 28,
2, 0, 116, 30, 3, 2, 36, 22, 4, 4, 16, 20, 4, 4, 12, 24, 5, 1, 120, 30, 9, 4, 43, 26, 17, 1, 22, 28, 2, 19, 14, 28,
2, 2, 68, 18, 4, 1, 43, 26, 6, 2, 19, 24, 6, 2, 15, 28, 3, 4, 113, 28, 3, 11, 44, 26, 17, 4, 21, 26, 9, 16, 13, 26,
4, 0, 81, 20, 1, 4, 50, 30, 4, 4, 22, 28, 3, 8, 12, 24, 3, 5, 107, 28, 3, 13, 41, 26, 15, 5, 24, 30, 15, 10, 15, 28,
2, 2, 92, 24, 6, 2, 36, 22, 4, 6, 20, 26, 7, 4, 14, 28, 4, 4, 116, 28, 17, 0, 42, 26, 17, 6, 22, 28, 19, 6, 16, 30,
4, 0, 107, 26, 8, 1, 37, 22, 8, 4, 20, 24, 12, 4, 11, 22, 2, 7, 111, 28, 17, 0, 46, 28, 7, 16, 24, 30, 34, 0, 13, 24,
3, 1, 115, 30, 4, 5, 40, 24, 11, 5, 16, 20, 11, 5, 12, 24, 4, 5, 121, 30, 4, 14, 47, 28, 11, 14, 24, 30, 16, 14, 15, 30,
5, 1, 87, 22, 5, 5, 41, 24, 5, 7, 24, 30, 11, 7, 12, 24, 6, 4, 117, 30, 6, 14, 45, 28, 11, 16, 24, 30, 30, 2, 16, 30,
5, 1, 98, 24, 7, 3, 45, 28, 15, 2, 19, 24, 3, 13, 15, 30, 8, 4, 106, 26, 8, 13, 47, 28, 7, 22, 24, 30, 22, 13, 15, 30,
1, 5, 107, 28, 10, 1, 46, 28, 1, 15, 22, 28, 2, 17, 14, 28, 10, 2, 114, 28, 19, 4, 46, 28, 28, 6, 22, 28, 33, 4, 16, 30,
5, 1, 120, 30, 9, 4, 43, 26, 17, 1, 22, 28, 2, 19, 14, 28, 8, 4, 122, 30, 22, 3, 45, 28, 8, 26, 23, 30, 12, 28, 15, 30,
3, 4, 113, 28, 3, 11, 44, 26, 17, 4, 21, 26, 9, 16, 13, 26, 3, 10, 117, 30, 3, 23, 45, 28, 4, 31, 24, 30, 11, 31, 15, 30,
3, 5, 107, 28, 3, 13, 41, 26, 15, 5, 24, 30, 15, 10, 15, 28, 7, 7, 116, 30, 21, 7, 45, 28, 1, 37, 23, 30, 19, 26, 15, 30,
4, 4, 116, 28, 17, 0, 42, 26, 17, 6, 22, 28, 19, 6, 16, 30, 5, 10, 115, 30, 19, 10, 47, 28, 15, 25, 24, 30, 23, 25, 15, 30,
2, 7, 111, 28, 17, 0, 46, 28, 7, 16, 24, 30, 34, 0, 13, 24, 13, 3, 115, 30, 2, 29, 46, 28, 42, 1, 24, 30, 23, 28, 15, 30,
4, 5, 121, 30, 4, 14, 47, 28, 11, 14, 24, 30, 16, 14, 15, 30, 17, 0, 115, 30, 10, 23, 46, 28, 10, 35, 24, 30, 19, 35, 15, 30,
6, 4, 117, 30, 6, 14, 45, 28, 11, 16, 24, 30, 30, 2, 16, 30, 17, 1, 115, 30, 14, 21, 46, 28, 29, 19, 24, 30, 11, 46, 15, 30,
8, 4, 106, 26, 8, 13, 47, 28, 7, 22, 24, 30, 22, 13, 15, 30, 13, 6, 115, 30, 14, 23, 46, 28, 44, 7, 24, 30, 59, 1, 16, 30,
10, 2, 114, 28, 19, 4, 46, 28, 28, 6, 22, 28, 33, 4, 16, 30, 12, 7, 121, 30, 12, 26, 47, 28, 39, 14, 24, 30, 22, 41, 15, 30,
8, 4, 122, 30, 22, 3, 45, 28, 8, 26, 23, 30, 12, 28, 15, 30, 6, 14, 121, 30, 6, 34, 47, 28, 46, 10, 24, 30, 2, 64, 15, 30,
3, 10, 117, 30, 3, 23, 45, 28, 4, 31, 24, 30, 11, 31, 15, 30, 17, 4, 122, 30, 29, 14, 46, 28, 49, 10, 24, 30, 24, 46, 15, 30,
7, 7, 116, 30, 21, 7, 45, 28, 1, 37, 23, 30, 19, 26, 15, 30, 4, 18, 122, 30, 13, 32, 46, 28, 48, 14, 24, 30, 42, 32, 15, 30,
5, 10, 115, 30, 19, 10, 47, 28, 15, 25, 24, 30, 23, 25, 15, 30, 20, 4, 117, 30, 40, 7, 47, 28, 43, 22, 24, 30, 10, 67, 15, 30,
13, 3, 115, 30, 2, 29, 46, 28, 42, 1, 24, 30, 23, 28, 15, 30, 19, 6, 118, 30, 18, 31, 47, 28, 34, 34, 24, 30, 20, 61, 15, 30
17, 0, 115, 30, 10, 23, 46, 28, 10, 35, 24, 30, 19, 35, 15, 30, ];
17, 1, 115, 30, 14, 21, 46, 28, 29, 19, 24, 30, 11, 46, 15, 30,
13, 6, 115, 30, 14, 23, 46, 28, 44, 7, 24, 30, 59, 1, 16, 30, // Galois field log table
12, 7, 121, 30, 12, 26, 47, 28, 39, 14, 24, 30, 22, 41, 15, 30, var glog = [
6, 14, 121, 30, 6, 34, 47, 28, 46, 10, 24, 30, 2, 64, 15, 30, 0xff, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
17, 4, 122, 30, 29, 14, 46, 28, 49, 10, 24, 30, 24, 46, 15, 30, 0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
4, 18, 122, 30, 13, 32, 46, 28, 48, 14, 24, 30, 42, 32, 15, 30, 0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
20, 4, 117, 30, 40, 7, 47, 28, 43, 22, 24, 30, 10, 67, 15, 30, 0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
19, 6, 118, 30, 18, 31, 47, 28, 34, 34, 24, 30, 20, 61, 15, 30 0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd, 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
]; 0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
// Galois field log table 0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
var glog = [ 0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
0xff, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b, 0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71, 0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45, 0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e, 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6, 0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd, 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88, 0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40, 0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51, 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d, 0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf
0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57, ];
0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e, // Galios field exponent table
0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61, var gexp = [
0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e, 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6, 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a, 0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51, 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7, 0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
]; 0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
// Galios field exponent table 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
var gexp = [ 0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26, 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23, 0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1, 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0, 0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2, 0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce, 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x00
0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc, ];
0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73, // Working buffers:
0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff, // data input and ecc append, image working buffer, fixed part of image, run lengths for badness
0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41, var strinbuf=[], eccbuf=[], qrframe=[], framask=[], rlens=[];
0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6, // Control values - width is based on version, last 4 are from table.
0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09, var version, width, neccblk1, neccblk2, datablkw, eccblkwid;
0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16, var ecclevel = 2;
0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x00 // set bit to indicate cell in qrframe is immutable. symmetric around diagonal
]; function setmask(x, y)
{
// Working buffers: var bt;
// data input and ecc append, image working buffer, fixed part of image, run lengths for badness if (x > y) {
var strinbuf=[], eccbuf=[], qrframe=[], framask=[], rlens=[]; bt = x;
// Control values - width is based on version, last 4 are from table. x = y;
var version, width, neccblk1, neccblk2, datablkw, eccblkwid; y = bt;
var ecclevel = 2; }
// set bit to indicate cell in qrframe is immutable. symmetric around diagonal // y*y = 1+3+5...
function setmask(x, y) bt = y;
{ bt *= y;
var bt; bt += y;
if (x > y) { bt >>= 1;
bt = x; bt += x;
x = y; framask[bt] = 1;
y = bt; }
}
// y*y = 1+3+5... // enter alignment pattern - black to qrframe, white to mask (later black frame merged to mask)
bt = y; function putalign(x, y)
bt *= y; {
bt += y; var j;
bt >>= 1;
bt += x; qrframe[x + width * y] = 1;
framask[bt] = 1; for (j = -2; j < 2; j++) {
} qrframe[(x + j) + width * (y - 2)] = 1;
qrframe[(x - 2) + width * (y + j + 1)] = 1;
// enter alignment pattern - black to qrframe, white to mask (later black frame merged to mask) qrframe[(x + 2) + width * (y + j)] = 1;
function putalign(x, y) qrframe[(x + j + 1) + width * (y + 2)] = 1;
{ }
var j; for (j = 0; j < 2; j++) {
setmask(x - 1, y + j);
qrframe[x + width * y] = 1; setmask(x + 1, y - j);
for (j = -2; j < 2; j++) { setmask(x - j, y - 1);
qrframe[(x + j) + width * (y - 2)] = 1; setmask(x + j, y + 1);
qrframe[(x - 2) + width * (y + j + 1)] = 1; }
qrframe[(x + 2) + width * (y + j)] = 1; }
qrframe[(x + j + 1) + width * (y + 2)] = 1;
} //========================================================================
for (j = 0; j < 2; j++) { // Reed Solomon error correction
setmask(x - 1, y + j); // exponentiation mod N
setmask(x + 1, y - j); function modnn(x)
setmask(x - j, y - 1); {
setmask(x + j, y + 1); while (x >= 255) {
} x -= 255;
} x = (x >> 8) + (x & 255);
}
//======================================================================== return x;
// Reed Solomon error correction }
// exponentiation mod N
function modnn(x) var genpoly = [];
{
while (x >= 255) { // Calculate and append ECC data to data block. Block is in strinbuf, indexes to buffers given.
x -= 255; function appendrs(data, dlen, ecbuf, eclen)
x = (x >> 8) + (x & 255); {
} var i, j, fb;
return x;
} for (i = 0; i < eclen; i++)
strinbuf[ecbuf + i] = 0;
var genpoly = []; for (i = 0; i < dlen; i++) {
fb = glog[strinbuf[data + i] ^ strinbuf[ecbuf]];
// Calculate and append ECC data to data block. Block is in strinbuf, indexes to buffers given. if (fb != 255) /* fb term is non-zero */
function appendrs(data, dlen, ecbuf, eclen) for (j = 1; j < eclen; j++)
{ strinbuf[ecbuf + j - 1] = strinbuf[ecbuf + j] ^ gexp[modnn(fb + genpoly[eclen - j])];
var i, j, fb; else
for( j = ecbuf ; j < ecbuf + eclen; j++ )
for (i = 0; i < eclen; i++) strinbuf[j] = strinbuf[j + 1];
strinbuf[ecbuf + i] = 0; strinbuf[ ecbuf + eclen - 1] = fb == 255 ? 0 : gexp[modnn(fb + genpoly[0])];
for (i = 0; i < dlen; i++) { }
fb = glog[strinbuf[data + i] ^ strinbuf[ecbuf]]; }
if (fb != 255) /* fb term is non-zero */
for (j = 1; j < eclen; j++) //========================================================================
strinbuf[ecbuf + j - 1] = strinbuf[ecbuf + j] ^ gexp[modnn(fb + genpoly[eclen - j])]; // Frame data insert following the path rules
else
for( j = ecbuf ; j < ecbuf + eclen; j++ ) // check mask - since symmetrical use half.
strinbuf[j] = strinbuf[j + 1]; function ismasked(x, y)
strinbuf[ ecbuf + eclen - 1] = fb == 255 ? 0 : gexp[modnn(fb + genpoly[0])]; {
} var bt;
} if (x > y) {
bt = x;
//======================================================================== x = y;
// Frame data insert following the path rules y = bt;
}
// check mask - since symmetrical use half. bt = y;
function ismasked(x, y) bt += y * y;
{ bt >>= 1;
var bt; bt += x;
if (x > y) { return framask[bt];
bt = x; }
x = y;
y = bt; //========================================================================
} // Apply the selected mask out of the 8.
bt = y; function applymask(m)
bt += y * y; {
bt >>= 1; var x, y, r3x, r3y;
bt += x;
return framask[bt]; switch (m) {
} case 0:
for (y = 0; y < width; y++)
//======================================================================== for (x = 0; x < width; x++)
// Apply the selected mask out of the 8. if (!((x + y) & 1) && !ismasked(x, y))
function applymask(m) qrframe[x + y * width] ^= 1;
{ break;
var x, y, r3x, r3y; case 1:
for (y = 0; y < width; y++)
switch (m) { for (x = 0; x < width; x++)
case 0: if (!(y & 1) && !ismasked(x, y))
for (y = 0; y < width; y++) qrframe[x + y * width] ^= 1;
for (x = 0; x < width; x++) break;
if (!((x + y) & 1) && !ismasked(x, y)) case 2:
qrframe[x + y * width] ^= 1; for (y = 0; y < width; y++)
break; for (r3x = 0, x = 0; x < width; x++, r3x++) {
case 1: if (r3x == 3)
for (y = 0; y < width; y++) r3x = 0;
for (x = 0; x < width; x++) if (!r3x && !ismasked(x, y))
if (!(y & 1) && !ismasked(x, y)) qrframe[x + y * width] ^= 1;
qrframe[x + y * width] ^= 1; }
break; break;
case 2: case 3:
for (y = 0; y < width; y++) for (r3y = 0, y = 0; y < width; y++, r3y++) {
for (r3x = 0, x = 0; x < width; x++, r3x++) { if (r3y == 3)
if (r3x == 3) r3y = 0;
r3x = 0; for (r3x = r3y, x = 0; x < width; x++, r3x++) {
if (!r3x && !ismasked(x, y)) if (r3x == 3)
qrframe[x + y * width] ^= 1; r3x = 0;
} if (!r3x && !ismasked(x, y))
break; qrframe[x + y * width] ^= 1;
case 3: }
for (r3y = 0, y = 0; y < width; y++, r3y++) { }
if (r3y == 3) break;
r3y = 0; case 4:
for (r3x = r3y, x = 0; x < width; x++, r3x++) { for (y = 0; y < width; y++)
if (r3x == 3) for (r3x = 0, r3y = ((y >> 1) & 1), x = 0; x < width; x++, r3x++) {
r3x = 0; if (r3x == 3) {
if (!r3x && !ismasked(x, y)) r3x = 0;
qrframe[x + y * width] ^= 1; r3y = !r3y;
} }
} if (!r3y && !ismasked(x, y))
break; qrframe[x + y * width] ^= 1;
case 4: }
for (y = 0; y < width; y++) break;
for (r3x = 0, r3y = ((y >> 1) & 1), x = 0; x < width; x++, r3x++) { case 5:
if (r3x == 3) { for (r3y = 0, y = 0; y < width; y++, r3y++) {
r3x = 0; if (r3y == 3)
r3y = !r3y; r3y = 0;
} for (r3x = 0, x = 0; x < width; x++, r3x++) {
if (!r3y && !ismasked(x, y)) if (r3x == 3)
qrframe[x + y * width] ^= 1; r3x = 0;
} if (!((x & y & 1) + !(!r3x | !r3y)) && !ismasked(x, y))
break; qrframe[x + y * width] ^= 1;
case 5: }
for (r3y = 0, y = 0; y < width; y++, r3y++) { }
if (r3y == 3) break;
r3y = 0; case 6:
for (r3x = 0, x = 0; x < width; x++, r3x++) { for (r3y = 0, y = 0; y < width; y++, r3y++) {
if (r3x == 3) if (r3y == 3)
r3x = 0; r3y = 0;
if (!((x & y & 1) + !(!r3x | !r3y)) && !ismasked(x, y)) for (r3x = 0, x = 0; x < width; x++, r3x++) {
qrframe[x + y * width] ^= 1; if (r3x == 3)
} r3x = 0;
} if (!(((x & y & 1) + (r3x && (r3x == r3y))) & 1) && !ismasked(x, y))
break; qrframe[x + y * width] ^= 1;
case 6: }
for (r3y = 0, y = 0; y < width; y++, r3y++) { }
if (r3y == 3) break;
r3y = 0; case 7:
for (r3x = 0, x = 0; x < width; x++, r3x++) { for (r3y = 0, y = 0; y < width; y++, r3y++) {
if (r3x == 3) if (r3y == 3)
r3x = 0; r3y = 0;
if (!(((x & y & 1) + (r3x && (r3x == r3y))) & 1) && !ismasked(x, y)) for (r3x = 0, x = 0; x < width; x++, r3x++) {
qrframe[x + y * width] ^= 1; if (r3x == 3)
} r3x = 0;
} if (!(((r3x && (r3x == r3y)) + ((x + y) & 1)) & 1) && !ismasked(x, y))
break; qrframe[x + y * width] ^= 1;
case 7: }
for (r3y = 0, y = 0; y < width; y++, r3y++) { }
if (r3y == 3) break;
r3y = 0; }
for (r3x = 0, x = 0; x < width; x++, r3x++) { return;
if (r3x == 3) }
r3x = 0;
if (!(((r3x && (r3x == r3y)) + ((x + y) & 1)) & 1) && !ismasked(x, y)) // Badness coefficients.
qrframe[x + y * width] ^= 1; var N1 = 3, N2 = 3, N3 = 40, N4 = 10;
}
} // Using the table of the length of each run, calculate the amount of bad image
break; // - long runs or those that look like finders; called twice, once each for X and Y
} function badruns(length)
return; {
} var i;
var runsbad = 0;
// Badness coefficients. for (i = 0; i <= length; i++)
var N1 = 3, N2 = 3, N3 = 40, N4 = 10; if (rlens[i] >= 5)
runsbad += N1 + rlens[i] - 5;
// Using the table of the length of each run, calculate the amount of bad image // BwBBBwB as in finder
// - long runs or those that look like finders; called twice, once each for X and Y for (i = 3; i < length - 1; i += 2)
function badruns(length) if (rlens[i - 2] == rlens[i + 2]
{ && rlens[i + 2] == rlens[i - 1]
var i; && rlens[i - 1] == rlens[i + 1]
var runsbad = 0; && rlens[i - 1] * 3 == rlens[i]
for (i = 0; i <= length; i++) // white around the black pattern? Not part of spec
if (rlens[i] >= 5) && (rlens[i - 3] == 0 // beginning
runsbad += N1 + rlens[i] - 5; || i + 3 > length // end
// BwBBBwB as in finder || rlens[i - 3] * 3 >= rlens[i] * 4 || rlens[i + 3] * 3 >= rlens[i] * 4)
for (i = 3; i < length - 1; i += 2) )
if (rlens[i - 2] == rlens[i + 2] runsbad += N3;
&& rlens[i + 2] == rlens[i - 1] return runsbad;
&& rlens[i - 1] == rlens[i + 1] }
&& rlens[i - 1] * 3 == rlens[i]
// white around the black pattern? Not part of spec // Calculate how bad the masked image is - blocks, imbalance, runs, or finders.
&& (rlens[i - 3] == 0 // beginning function badcheck()
|| i + 3 > length // end {
|| rlens[i - 3] * 3 >= rlens[i] * 4 || rlens[i + 3] * 3 >= rlens[i] * 4) var x, y, h, b, b1;
) var thisbad = 0;
runsbad += N3; var bw = 0;
return runsbad;
} // blocks of same color.
for (y = 0; y < width - 1; y++)
// Calculate how bad the masked image is - blocks, imbalance, runs, or finders. for (x = 0; x < width - 1; x++)
function badcheck() if ((qrframe[x + width * y] && qrframe[(x + 1) + width * y]
{ && qrframe[x + width * (y + 1)] && qrframe[(x + 1) + width * (y + 1)]) // all black
var x, y, h, b, b1; || !(qrframe[x + width * y] || qrframe[(x + 1) + width * y]
var thisbad = 0; || qrframe[x + width * (y + 1)] || qrframe[(x + 1) + width * (y + 1)])) // all white
var bw = 0; thisbad += N2;
// blocks of same color. // X runs
for (y = 0; y < width - 1; y++) for (y = 0; y < width; y++) {
for (x = 0; x < width - 1; x++) rlens[0] = 0;
if ((qrframe[x + width * y] && qrframe[(x + 1) + width * y] for (h = b = x = 0; x < width; x++) {
&& qrframe[x + width * (y + 1)] && qrframe[(x + 1) + width * (y + 1)]) // all black if ((b1 = qrframe[x + width * y]) == b)
|| !(qrframe[x + width * y] || qrframe[(x + 1) + width * y] rlens[h]++;
|| qrframe[x + width * (y + 1)] || qrframe[(x + 1) + width * (y + 1)])) // all white else
thisbad += N2; rlens[++h] = 1;
b = b1;
// X runs bw += b ? 1 : -1;
for (y = 0; y < width; y++) { }
rlens[0] = 0; thisbad += badruns(h);
for (h = b = x = 0; x < width; x++) { }
if ((b1 = qrframe[x + width * y]) == b)
rlens[h]++; // black/white imbalance
else if (bw < 0)
rlens[++h] = 1; bw = -bw;
b = b1;
bw += b ? 1 : -1; var big = bw;
} var count = 0;
thisbad += badruns(h); big += big << 2;
} big <<= 1;
while (big > width * width)
// black/white imbalance big -= width * width, count++;
if (bw < 0) thisbad += count * N4;
bw = -bw;
// Y runs
var big = bw; for (x = 0; x < width; x++) {
var count = 0; rlens[0] = 0;
big += big << 2; for (h = b = y = 0; y < width; y++) {
big <<= 1; if ((b1 = qrframe[x + width * y]) == b)
while (big > width * width) rlens[h]++;
big -= width * width, count++; else
thisbad += count * N4; rlens[++h] = 1;
b = b1;
// Y runs }
for (x = 0; x < width; x++) { thisbad += badruns(h);
rlens[0] = 0; }
for (h = b = y = 0; y < width; y++) { return thisbad;
if ((b1 = qrframe[x + width * y]) == b) }
rlens[h]++;
else function genframe(instring)
rlens[++h] = 1; {
b = b1; var x, y, k, t, v, i, j, m;
}
thisbad += badruns(h); // find the smallest version that fits the string
} t = instring.length;
return thisbad; version = 0;
} do {
version++;
function genframe(instring) k = (ecclevel - 1) * 4 + (version - 1) * 16;
{ neccblk1 = eccblocks[k++];
var x, y, k, t, v, i, j, m; neccblk2 = eccblocks[k++];
datablkw = eccblocks[k++];
// find the smallest version that fits the string eccblkwid = eccblocks[k];
t = instring.length; k = datablkw * (neccblk1 + neccblk2) + neccblk2 - 3 + (version <= 9);
version = 0; if (t <= k)
do { break;
version++; } while (version < 40);
k = (ecclevel - 1) * 4 + (version - 1) * 16;
neccblk1 = eccblocks[k++]; // FIXME - insure that it fits insted of being truncated
neccblk2 = eccblocks[k++]; width = 17 + 4 * version;
datablkw = eccblocks[k++];
eccblkwid = eccblocks[k]; // allocate, clear and setup data structures
k = datablkw * (neccblk1 + neccblk2) + neccblk2 - 3 + (version <= 9); v = datablkw + (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2;
if (t <= k) for( t = 0; t < v; t++ )
break; eccbuf[t] = 0;
} while (version < 40); strinbuf = instring.slice(0);
// FIXME - insure that it fits insted of being truncated for( t = 0; t < width * width; t++ )
width = 17 + 4 * version; qrframe[t] = 0;
// allocate, clear and setup data structures for( t = 0 ; t < (width * (width + 1) + 1) / 2; t++)
v = datablkw + (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2; framask[t] = 0;
for( t = 0; t < v; t++ )
eccbuf[t] = 0; // insert finders - black to frame, white to mask
strinbuf = instring.slice(0); for (t = 0; t < 3; t++) {
k = 0;
for( t = 0; t < width * width; t++ ) y = 0;
qrframe[t] = 0; if (t == 1)
k = (width - 7);
for( t = 0 ; t < (width * (width + 1) + 1) / 2; t++) if (t == 2)
framask[t] = 0; y = (width - 7);
qrframe[(y + 3) + width * (k + 3)] = 1;
// insert finders - black to frame, white to mask for (x = 0; x < 6; x++) {
for (t = 0; t < 3; t++) { qrframe[(y + x) + width * k] = 1;
k = 0; qrframe[y + width * (k + x + 1)] = 1;
y = 0; qrframe[(y + 6) + width * (k + x)] = 1;
if (t == 1) qrframe[(y + x + 1) + width * (k + 6)] = 1;
k = (width - 7); }
if (t == 2) for (x = 1; x < 5; x++) {
y = (width - 7); setmask(y + x, k + 1);
qrframe[(y + 3) + width * (k + 3)] = 1; setmask(y + 1, k + x + 1);
for (x = 0; x < 6; x++) { setmask(y + 5, k + x);
qrframe[(y + x) + width * k] = 1; setmask(y + x + 1, k + 5);
qrframe[y + width * (k + x + 1)] = 1; }
qrframe[(y + 6) + width * (k + x)] = 1; for (x = 2; x < 4; x++) {
qrframe[(y + x + 1) + width * (k + 6)] = 1; qrframe[(y + x) + width * (k + 2)] = 1;
} qrframe[(y + 2) + width * (k + x + 1)] = 1;
for (x = 1; x < 5; x++) { qrframe[(y + 4) + width * (k + x)] = 1;
setmask(y + x, k + 1); qrframe[(y + x + 1) + width * (k + 4)] = 1;
setmask(y + 1, k + x + 1); }
setmask(y + 5, k + x); }
setmask(y + x + 1, k + 5);
} // alignment blocks
for (x = 2; x < 4; x++) { if (version > 1) {
qrframe[(y + x) + width * (k + 2)] = 1; t = adelta[version];
qrframe[(y + 2) + width * (k + x + 1)] = 1; y = width - 7;
qrframe[(y + 4) + width * (k + x)] = 1; for (;;) {
qrframe[(y + x + 1) + width * (k + 4)] = 1; x = width - 7;
} while (x > t - 3) {
} putalign(x, y);
if (x < t)
// alignment blocks break;
if (version > 1) { x -= t;
t = adelta[version]; }
y = width - 7; if (y <= t + 9)
for (;;) { break;
x = width - 7; y -= t;
while (x > t - 3) { putalign(6, y);
putalign(x, y); putalign(y, 6);
if (x < t) }
break; }
x -= t;
} // single black
if (y <= t + 9) qrframe[8 + width * (width - 8)] = 1;
break;
y -= t; // timing gap - mask only
putalign(6, y); for (y = 0; y < 7; y++) {
putalign(y, 6); setmask(7, y);
} setmask(width - 8, y);
} setmask(7, y + width - 7);
}
// single black for (x = 0; x < 8; x++) {
qrframe[8 + width * (width - 8)] = 1; setmask(x, 7);
setmask(x + width - 8, 7);
// timing gap - mask only setmask(x, width - 8);
for (y = 0; y < 7; y++) { }
setmask(7, y);
setmask(width - 8, y); // reserve mask-format area
setmask(7, y + width - 7); for (x = 0; x < 9; x++)
} setmask(x, 8);
for (x = 0; x < 8; x++) { for (x = 0; x < 8; x++) {
setmask(x, 7); setmask(x + width - 8, 8);
setmask(x + width - 8, 7); setmask(8, x);
setmask(x, width - 8); }
} for (y = 0; y < 7; y++)
setmask(8, y + width - 7);
// reserve mask-format area
for (x = 0; x < 9; x++) // timing row/col
setmask(x, 8); for (x = 0; x < width - 14; x++)
for (x = 0; x < 8; x++) { if (x & 1) {
setmask(x + width - 8, 8); setmask(8 + x, 6);
setmask(8, x); setmask(6, 8 + x);
} }
for (y = 0; y < 7; y++) else {
setmask(8, y + width - 7); qrframe[(8 + x) + width * 6] = 1;
qrframe[6 + width * (8 + x)] = 1;
// timing row/col }
for (x = 0; x < width - 14; x++)
if (x & 1) { // version block
setmask(8 + x, 6); if (version > 6) {
setmask(6, 8 + x); t = vpat[version - 7];
} k = 17;
else { for (x = 0; x < 6; x++)
qrframe[(8 + x) + width * 6] = 1; for (y = 0; y < 3; y++, k--)
qrframe[6 + width * (8 + x)] = 1; if (1 & (k > 11 ? version >> (k - 12) : t >> k)) {
} qrframe[(5 - x) + width * (2 - y + width - 11)] = 1;
qrframe[(2 - y + width - 11) + width * (5 - x)] = 1;
// version block }
if (version > 6) { else {
t = vpat[version - 7]; setmask(5 - x, 2 - y + width - 11);
k = 17; setmask(2 - y + width - 11, 5 - x);
for (x = 0; x < 6; x++) }
for (y = 0; y < 3; y++, k--) }
if (1 & (k > 11 ? version >> (k - 12) : t >> k)) {
qrframe[(5 - x) + width * (2 - y + width - 11)] = 1; // sync mask bits - only set above for white spaces, so add in black bits
qrframe[(2 - y + width - 11) + width * (5 - x)] = 1; for (y = 0; y < width; y++)
} for (x = 0; x <= y; x++)
else { if (qrframe[x + width * y])
setmask(5 - x, 2 - y + width - 11); setmask(x, y);
setmask(2 - y + width - 11, 5 - x);
} // convert string to bitstream
} // 8 bit data to QR-coded 8 bit data (numeric or alphanum, or kanji not supported)
v = strinbuf.length;
// sync mask bits - only set above for white spaces, so add in black bits
for (y = 0; y < width; y++) // string to array
for (x = 0; x <= y; x++) for( i = 0 ; i < v; i++ )
if (qrframe[x + width * y]) eccbuf[i] = strinbuf.charCodeAt(i);
setmask(x, y); strinbuf = eccbuf.slice(0);
// convert string to bitstream // calculate max string length
// 8 bit data to QR-coded 8 bit data (numeric or alphanum, or kanji not supported) x = datablkw * (neccblk1 + neccblk2) + neccblk2;
v = strinbuf.length; if (v >= x - 2) {
v = x - 2;
// string to array if (version > 9)
for( i = 0 ; i < v; i++ ) v--;
eccbuf[i] = strinbuf.charCodeAt(i); }
strinbuf = eccbuf.slice(0);
// shift and repack to insert length prefix
// calculate max string length i = v;
x = datablkw * (neccblk1 + neccblk2) + neccblk2; if (version > 9) {
if (v >= x - 2) { strinbuf[i + 2] = 0;
v = x - 2; strinbuf[i + 3] = 0;
if (version > 9) while (i--) {
v--; t = strinbuf[i];
} strinbuf[i + 3] |= 255 & (t << 4);
strinbuf[i + 2] = t >> 4;
// shift and repack to insert length prefix }
i = v; strinbuf[2] |= 255 & (v << 4);
if (version > 9) { strinbuf[1] = v >> 4;
strinbuf[i + 2] = 0; strinbuf[0] = 0x40 | (v >> 12);
strinbuf[i + 3] = 0; }
while (i--) { else {
t = strinbuf[i]; strinbuf[i + 1] = 0;
strinbuf[i + 3] |= 255 & (t << 4); strinbuf[i + 2] = 0;
strinbuf[i + 2] = t >> 4; while (i--) {
} t = strinbuf[i];
strinbuf[2] |= 255 & (v << 4); strinbuf[i + 2] |= 255 & (t << 4);
strinbuf[1] = v >> 4; strinbuf[i + 1] = t >> 4;
strinbuf[0] = 0x40 | (v >> 12); }
} strinbuf[1] |= 255 & (v << 4);
else { strinbuf[0] = 0x40 | (v >> 4);
strinbuf[i + 1] = 0; }
strinbuf[i + 2] = 0; // fill to end with pad pattern
while (i--) { i = v + 3 - (version < 10);
t = strinbuf[i]; while (i < x) {
strinbuf[i + 2] |= 255 & (t << 4); strinbuf[i++] = 0xec;
strinbuf[i + 1] = t >> 4; // buffer has room if (i == x) break;
} strinbuf[i++] = 0x11;
strinbuf[1] |= 255 & (v << 4); }
strinbuf[0] = 0x40 | (v >> 4);
} // calculate and append ECC
// fill to end with pad pattern
i = v + 3 - (version < 10); // calculate generator polynomial
while (i < x) { genpoly[0] = 1;
strinbuf[i++] = 0xec; for (i = 0; i < eccblkwid; i++) {
// buffer has room if (i == x) break; genpoly[i + 1] = 1;
strinbuf[i++] = 0x11; for (j = i; j > 0; j--)
} genpoly[j] = genpoly[j]
? genpoly[j - 1] ^ gexp[modnn(glog[genpoly[j]] + i)] : genpoly[j - 1];
// calculate and append ECC genpoly[0] = gexp[modnn(glog[genpoly[0]] + i)];
}
// calculate generator polynomial for (i = 0; i <= eccblkwid; i++)
genpoly[0] = 1; genpoly[i] = glog[genpoly[i]]; // use logs for genpoly[] to save calc step
for (i = 0; i < eccblkwid; i++) {
genpoly[i + 1] = 1; // append ecc to data buffer
for (j = i; j > 0; j--) k = x;
genpoly[j] = genpoly[j] y = 0;
? genpoly[j - 1] ^ gexp[modnn(glog[genpoly[j]] + i)] : genpoly[j - 1]; for (i = 0; i < neccblk1; i++) {
genpoly[0] = gexp[modnn(glog[genpoly[0]] + i)]; appendrs(y, datablkw, k, eccblkwid);
} y += datablkw;
for (i = 0; i <= eccblkwid; i++) k += eccblkwid;
genpoly[i] = glog[genpoly[i]]; // use logs for genpoly[] to save calc step }
for (i = 0; i < neccblk2; i++) {
// append ecc to data buffer appendrs(y, datablkw + 1, k, eccblkwid);
k = x; y += datablkw + 1;
y = 0; k += eccblkwid;
for (i = 0; i < neccblk1; i++) { }
appendrs(y, datablkw, k, eccblkwid); // interleave blocks
y += datablkw; y = 0;
k += eccblkwid; for (i = 0; i < datablkw; i++) {
} for (j = 0; j < neccblk1; j++)
for (i = 0; i < neccblk2; i++) { eccbuf[y++] = strinbuf[i + j * datablkw];
appendrs(y, datablkw + 1, k, eccblkwid); for (j = 0; j < neccblk2; j++)
y += datablkw + 1; eccbuf[y++] = strinbuf[(neccblk1 * datablkw) + i + (j * (datablkw + 1))];
k += eccblkwid; }
} for (j = 0; j < neccblk2; j++)
// interleave blocks eccbuf[y++] = strinbuf[(neccblk1 * datablkw) + i + (j * (datablkw + 1))];
y = 0; for (i = 0; i < eccblkwid; i++)
for (i = 0; i < datablkw; i++) { for (j = 0; j < neccblk1 + neccblk2; j++)
for (j = 0; j < neccblk1; j++) eccbuf[y++] = strinbuf[x + i + j * eccblkwid];
eccbuf[y++] = strinbuf[i + j * datablkw]; strinbuf = eccbuf;
for (j = 0; j < neccblk2; j++)
eccbuf[y++] = strinbuf[(neccblk1 * datablkw) + i + (j * (datablkw + 1))]; // pack bits into frame avoiding masked area.
} x = y = width - 1;
for (j = 0; j < neccblk2; j++) k = v = 1; // up, minus
eccbuf[y++] = strinbuf[(neccblk1 * datablkw) + i + (j * (datablkw + 1))]; /* inteleaved data and ecc codes */
for (i = 0; i < eccblkwid; i++) m = (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2;
for (j = 0; j < neccblk1 + neccblk2; j++) for (i = 0; i < m; i++) {
eccbuf[y++] = strinbuf[x + i + j * eccblkwid]; t = strinbuf[i];
strinbuf = eccbuf; for (j = 0; j < 8; j++, t <<= 1) {
if (0x80 & t)
// pack bits into frame avoiding masked area. qrframe[x + width * y] = 1;
x = y = width - 1; do { // find next fill position
k = v = 1; // up, minus if (v)
/* inteleaved data and ecc codes */ x--;
m = (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2; else {
for (i = 0; i < m; i++) { x++;
t = strinbuf[i]; if (k) {
for (j = 0; j < 8; j++, t <<= 1) { if (y != 0)
if (0x80 & t) y--;
qrframe[x + width * y] = 1; else {
do { // find next fill position x -= 2;
if (v) k = !k;
x--; if (x == 6) {
else { x--;
x++; y = 9;
if (k) { }
if (y != 0) }
y--; }
else { else {
x -= 2; if (y != width - 1)
k = !k; y++;
if (x == 6) { else {
x--; x -= 2;
y = 9; k = !k;
} if (x == 6) {
} x--;
} y -= 8;
else { }
if (y != width - 1) }
y++; }
else { }
x -= 2; v = !v;
k = !k; } while (ismasked(x, y));
if (x == 6) { }
x--; }
y -= 8;
} // save pre-mask copy of frame
} strinbuf = qrframe.slice(0);
} t = 0; // best
} y = 30000; // demerit
v = !v; // for instead of while since in original arduino code
} while (ismasked(x, y)); // if an early mask was "good enough" it wouldn't try for a better one
} // since they get more complex and take longer.
} for (k = 0; k < 8; k++) {
applymask(k); // returns black-white imbalance
// save pre-mask copy of frame x = badcheck();
strinbuf = qrframe.slice(0); if (x < y) { // current mask better than previous best?
t = 0; // best y = x;
y = 30000; // demerit t = k;
// for instead of while since in original arduino code }
// if an early mask was "good enough" it wouldn't try for a better one if (t == 7)
// since they get more complex and take longer. break; // don't increment i to a void redoing mask
for (k = 0; k < 8; k++) { qrframe = strinbuf.slice(0); // reset for next pass
applymask(k); // returns black-white imbalance }
x = badcheck(); if (t != k) // redo best mask - none good enough, last wasn't t
if (x < y) { // current mask better than previous best? applymask(t);
y = x;
t = k; // add in final mask/ecclevel bytes
} y = fmtword[t + ((ecclevel - 1) << 3)];
if (t == 7) // low byte
break; // don't increment i to a void redoing mask for (k = 0; k < 8; k++, y >>= 1)
qrframe = strinbuf.slice(0); // reset for next pass if (y & 1) {
} qrframe[(width - 1 - k) + width * 8] = 1;
if (t != k) // redo best mask - none good enough, last wasn't t if (k < 6)
applymask(t); qrframe[8 + width * k] = 1;
else
// add in final mask/ecclevel bytes qrframe[8 + width * (k + 1)] = 1;
y = fmtword[t + ((ecclevel - 1) << 3)]; }
// low byte // high byte
for (k = 0; k < 8; k++, y >>= 1) for (k = 0; k < 7; k++, y >>= 1)
if (y & 1) { if (y & 1) {
qrframe[(width - 1 - k) + width * 8] = 1; qrframe[8 + width * (width - 7 + k)] = 1;
if (k < 6) if (k)
qrframe[8 + width * k] = 1; qrframe[(6 - k) + width * 8] = 1;
else else
qrframe[8 + width * (k + 1)] = 1; qrframe[7 + width * 8] = 1;
} }
// high byte
for (k = 0; k < 7; k++, y >>= 1) // return image
if (y & 1) { return qrframe;
qrframe[8 + width * (width - 7 + k)] = 1; }
if (k)
qrframe[(6 - k) + width * 8] = 1; var _canvas = null,
else _size = null;
qrframe[7 + width * 8] = 1;
} var api = {
// return image get ecclevel () {
return qrframe; return ecclevel;
} },
var _canvas = null, set ecclevel (val) {
_size = null; ecclevel = val;
},
var api = {
get size () {
get ecclevel () { return _size;
return ecclevel; },
},
set size (val) {
set ecclevel (val) { _size = val
ecclevel = val; },
},
get canvas () {
get size () { return _canvas;
return _size; },
},
set canvas (el) {
set size (val) { _canvas = el;
_size = val },
},
getFrame: function (string) {
get canvas () { return genframe(string);
return _canvas; },
},
draw: function (string, canvas, size, ecc) {
set canvas (el) {
_canvas = el; ecclevel = ecc || ecclevel;
}, canvas = canvas || _canvas;
getFrame: function (string) { if (!canvas) {
return genframe(string); console.warn('No canvas provided to draw QR code in!')
}, return;
}
draw: function (string, canvas, size, ecc) {
size = size || _size || Math.min(canvas.width, canvas.height);
ecclevel = ecc || ecclevel;
canvas = canvas || _canvas; var frame = genframe(string),
ctx = canvas.ctx,
if (!canvas) { px = Math.round(size / (width + 8));
console.warn('No canvas provided to draw QR code in!')
return; var roundedSize = px * (width + 8),
} offset = Math.floor((size - roundedSize) / 2);
size = size || _size || Math.min(canvas.width, canvas.height); size = roundedSize;
var frame = genframe(string), ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx = canvas.ctx, ctx.setFillStyle('#000000');
px = Math.round(size / (width + 8));
for (var i = 0; i < width; i++) {
var roundedSize = px * (width + 8), for (var j = 0; j < width; j++) {
offset = Math.floor((size - roundedSize) / 2); if (frame[j * width + i]) {
ctx.fillRect(px * (4 + i) + offset, px * (4 + j) + offset, px, px);
size = roundedSize; }
}
ctx.clearRect(0, 0, canvas.width, canvas.height); }
ctx.setFillStyle('#000000'); ctx.draw();
}
for (var i = 0; i < width; i++) { }
for (var j = 0; j < width; j++) {
if (frame[j * width + i]) { module.exports = {
ctx.fillRect(px * (4 + i) + offset, px * (4 + j) + offset, px, px); api: api
} }
}
}
ctx.draw();
}
}
module.exports = {
api: api
}
})() })()
\ No newline at end of file
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# http://editorconfig.org
root = true
[*]
# Change these settings to your own preference
indent_style = space
indent_size = 4
# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
env:
es6: true
node: true
extends: 'eslint:recommended'
parserOptions:
sourceType: module
rules:
indent:
- error
- 4
linebreak-style:
- error
- windows
quotes:
- error
- single
semi:
- error
- never
no-console: 0
no-unused-vars: 0
# Automatically normalize line endings for all text-based files
# http://git-scm.com/docs/gitattributes#_end_of_line_conversion
* text=auto
# For the following file types, normalize line endings to LF on
# checkin and prevent conversion to CRLF when they are checked out
# (this is required in order to prevent newline related issues like,
# for example, after the build script is run)
.* text eol=lf
*.css text eol=lf
*.html text eol=lf
*.jade text eol=lf
*.js text eol=lf
*.json text eol=lf
*.less text eol=lf
*.scss text eol=lf
*.md text eol=lf
*.sh text eol=lf
*.txt text eol=lf
*.xml text eol=lf
# Include your project-specific ignores in this file
# Read about how to use .gitignore: https://help.github.com/articles/ignoring-files
build
node_modules
ncp-debug.log
npm-debug.log
# Generated by https://www.gitignore.io
### SublimeText ###
# cache files for sublime text
*.tmlanguage.cache
*.tmPreferences.cache
*.stTheme.cache
# workspace files are user-specific
*.sublime-workspace
# project files should be checked into the repository, unless a significant
# proportion of contributors will probably not be using SublimeText
*.sublime-project
# sftp configuration file
sftp-config.json
### Windows ###
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
### OSX ###
.DS_Store
.AppleDouble
.LSOverride
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Node ###
# Logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
language: node_js
node_js:
- "6"
MIT License
Copyright (c) 2016 Alsey DAI (zamber@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
\ No newline at end of file
# wxbarcode
微信小程序生成条码和二维码模块。
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![NPM](https://nodei.co/npm/wxbarcode.png?compact=true)](https://nodei.co/npm/wxbarcode/)
## 效果
![截图](https://raw.githubusercontent.com/alsey/wxbarcode/master/capture.png)
## 安装
```bash
$ npm install wxbarcode
```
## 使用方法
```js
import wxbarcode from 'wxbarcode'
wxbarcode.barcode('barcode', '1234567890123456789', 680, 200);
wxbarcode.qrcode('qrcode', '1234567890123456789', 420, 420);
```
### 条形码
函数名:barcode
函数原型:barcode(id, code, width, height)
参数:
- id: wxml文件中的 Canvas ID
- code: 用于生成条形码的字符串
- width: 生成的条形码宽度,单位 rpx
- height: 生成的条形码高度,单位 rpx
### 二维码
函数名:qrcode
函数原型:qrcode(id, code, width, height)
参数:
- id: wxml文件中的 Canvas ID
- code: 用于生成二维码的字符串
- width: 生成的二维码宽度,单位 rpx
- height: 生成的二维码高度,单位 rpx
## 例子
请参考`demo`文件夹下代码。
## License
[MIT](LICENSE)
[npm-image]: https://badge.fury.io/js/wxbarcode.svg
[npm-url]: https://npmjs.org/package/wxbarcode
[downloads-image]: https://img.shields.io/npm/dm/wxbarcode.svg
[downloads-url]: https://npmjs.org/package/wxbarcode
//app.js
App({})
\ No newline at end of file
{
"pages":[
"pages/index/index"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#439057",
"navigationBarTitleText": "条码、二维码演示程序",
"navigationBarTextStyle":"white"
}
}
//index.js
var wxbarcode = require('../../utils/index.js');
Page({
data: {
code: '1234567890123456789'
},
onLoad: function() {
wxbarcode.barcode('barcode', '1234567890123456789', 680, 200);
wxbarcode.qrcode('qrcode', '1234567890123456789', 420, 420);
}
})
<!--index.wxml-->
<view class="container page">
<view class="panel">
<view class="header">
</view>
<view class="barcode">
<view class="barnum">{{code}}</view>
<canvas canvas-id="barcode" />
</view>
<view class="qrcode">
<canvas canvas-id="qrcode" />
</view>
</view>
</view>
/**index.wxss**/
page {
background-color: #439057;
}
.page {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.container {
padding-bottom: 10rpx;
}
.panel {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: stretch;
box-sizing: border-box;
width: 710rpx;
margin-top: 40rpx;
border-radius: 10rpx;
background-color: #fff;
}
.header {
height: 140rpx;
background-color: #f0f0f0;
border-radius: 10rpx 10rpx 0 0;
}
.barcode {
display: flex;
height: 320rpx;
flex-direction: column;
justify-content: center;
align-items: center;
}
.barnum {
width: 670rpx;
height: 100rpx;
line-height: 100rpx;
font-size: 38rpx;
font-weight: bold;
text-align: center;
letter-spacing: 10rpx;
white-space: nowrap;
}
.barcode > canvas {
width: 680rpx;
height: 200rpx;
}
.qrcode {
height: 420rpx;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: center;
}
.qrcode > canvas {
width: 420rpx;
height: 420rpx;
}
var CHAR_TILDE = 126;
var CODE_FNC1 = 102;
var SET_STARTA = 103;
var SET_STARTB = 104;
var SET_STARTC = 105;
var SET_SHIFT = 98;
var SET_CODEA = 101;
var SET_CODEB = 100;
var SET_STOP = 106;
var REPLACE_CODES = {
CHAR_TILDE: CODE_FNC1 //~ corresponds to FNC1 in GS1-128 standard
}
var CODESET = {
ANY: 1,
AB: 2,
A: 3,
B: 4,
C: 5
};
function getBytes(str) {
var bytes = [];
for (var i = 0; i < str.length; i++) {
bytes.push(str.charCodeAt(i));
}
return bytes;
}
exports.code128 = function (ctx, text, width, height) {
width = parseInt(width);
height = parseInt(height);
var codes = stringToCode128(text);
var g = new Graphics(ctx, width, height);
var barWeight = g.area.width / ((codes.length - 3) * 11 + 35);
var x = g.area.left;
var y = g.area.top;
for (var i = 0; i < codes.length; i++) {
var c = codes[i];
//two bars at a time: 1 black and 1 white
for (var bar = 0; bar < 8; bar += 2) {
var barW = PATTERNS[c][bar] * barWeight;
// var barH = height - y - this.border;
var barH = height - y;
var spcW = PATTERNS[c][bar + 1] * barWeight;
//no need to draw if 0 width
if (barW > 0) {
g.fillFgRect(x, y, barW, barH);
}
x += barW + spcW;
}
}
ctx.draw();
}
function stringToCode128(text) {
var barc = {
currcs: CODESET.C
};
var bytes = getBytes(text);
//decide starting codeset
var index = bytes[0] == CHAR_TILDE ? 1 : 0;
var csa1 = bytes.length > 0 ? codeSetAllowedFor(bytes[index++]) : CODESET.AB;
var csa2 = bytes.length > 0 ? codeSetAllowedFor(bytes[index++]) : CODESET.AB;
barc.currcs = getBestStartSet(csa1, csa2);
barc.currcs = perhapsCodeC(bytes, barc.currcs);
//if no codeset changes this will end up with bytes.length+3
//start, checksum and stop
var codes = new Array();
switch (barc.currcs) {
case CODESET.A:
codes.push(SET_STARTA);
break;
case CODESET.B:
codes.push(SET_STARTB);
break;
default:
codes.push(SET_STARTC);
break;
}
for (var i = 0; i < bytes.length; i++) {
var b1 = bytes[i]; //get the first of a pair
//should we translate/replace
if (b1 in REPLACE_CODES) {
codes.push(REPLACE_CODES[b1]);
i++ //jump to next
b1 = bytes[i];
}
//get the next in the pair if possible
var b2 = bytes.length > (i + 1) ? bytes[i + 1] : -1;
codes = codes.concat(codesForChar(b1, b2, barc.currcs));
//code C takes 2 chars each time
if (barc.currcs == CODESET.C) i++;
}
//calculate checksum according to Code 128 standards
var checksum = codes[0];
for (var weight = 1; weight < codes.length; weight++) {
checksum += (weight * codes[weight]);
}
codes.push(checksum % 103);
codes.push(SET_STOP);
//encoding should now be complete
return codes;
function getBestStartSet(csa1, csa2) {
//tries to figure out the best codeset
//to start with to get the most compact code
var vote = 0;
vote += csa1 == CODESET.A ? 1 : 0;
vote += csa1 == CODESET.B ? -1 : 0;
vote += csa2 == CODESET.A ? 1 : 0;
vote += csa2 == CODESET.B ? -1 : 0;
//tie goes to B due to my own predudices
return vote > 0 ? CODESET.A : CODESET.B;
}
function perhapsCodeC(bytes, codeset) {
for (var i = 0; i < bytes.length; i++) {
var b = bytes[i]
if ((b < 48 || b > 57) && b != CHAR_TILDE)
return codeset;
}
return CODESET.C;
}
//chr1 is current byte
//chr2 is the next byte to process. looks ahead.
function codesForChar(chr1, chr2, currcs) {
var result = [];
var shifter = -1;
if (charCompatible(chr1, currcs)) {
if (currcs == CODESET.C) {
if (chr2 == -1) {
shifter = SET_CODEB;
currcs = CODESET.B;
}
else if ((chr2 != -1) && !charCompatible(chr2, currcs)) {
//need to check ahead as well
if (charCompatible(chr2, CODESET.A)) {
shifter = SET_CODEA;
currcs = CODESET.A;
}
else {
shifter = SET_CODEB;
currcs = CODESET.B;
}
}
}
}
else {
//if there is a next char AND that next char is also not compatible
if ((chr2 != -1) && !charCompatible(chr2, currcs)) {
//need to switch code sets
switch (currcs) {
case CODESET.A:
shifter = SET_CODEB;
currcs = CODESET.B;
break;
case CODESET.B:
shifter = SET_CODEA;
currcs = CODESET.A;
break;
}
}
else {
//no need to shift code sets, a temporary SHIFT will suffice
shifter = SET_SHIFT;
}
}
//ok some type of shift is nessecary
if (shifter != -1) {
result.push(shifter);
result.push(codeValue(chr2));
}
else {
if (currcs == CODESET.C) {
//include next as well
result.push(codeValue(chr1, chr2));
}
else {
result.push(codeValue(chr1));
}
}
barc.currcs = currcs;
return result;
}
}
//reduce the ascii code to fit into the Code128 char table
function codeValue(chr1, chr2) {
if (typeof chr2 == "undefined") {
return chr1 >= 32 ? chr1 - 32 : chr1 + 64;
}
else {
return parseInt(String.fromCharCode(chr1) + String.fromCharCode(chr2));
}
}
function charCompatible(chr, codeset) {
var csa = codeSetAllowedFor(chr);
if (csa == CODESET.ANY) return true;
//if we need to change from current
if (csa == CODESET.AB) return true;
if (csa == CODESET.A && codeset == CODESET.A) return true;
if (csa == CODESET.B && codeset == CODESET.B) return true;
return false;
}
function codeSetAllowedFor(chr) {
if (chr >= 48 && chr <= 57) {
//0-9
return CODESET.ANY;
}
else if (chr >= 32 && chr <= 95) {
//0-9 A-Z
return CODESET.AB;
}
else {
//if non printable
return chr < 32 ? CODESET.A : CODESET.B;
}
}
var Graphics = function(ctx, width, height) {
this.width = width;
this.height = height;
this.quiet = Math.round(this.width / 40);
this.border_size = 0;
this.padding_width = 0;
this.area = {
width : width - this.padding_width * 2 - this.quiet * 2,
height: height - this.border_size * 2,
top : this.border_size - 4,
left : this.padding_width + this.quiet
};
this.ctx = ctx;
this.fg = "#000000";
this.bg = "#ffffff";
// fill background
this.fillBgRect(0,0, width, height);
// fill center to create border
this.fillBgRect(0, this.border_size, width, height - this.border_size * 2);
}
//use native color
Graphics.prototype._fillRect = function(x, y, width, height, color) {
this.ctx.setFillStyle(color)
this.ctx.fillRect(x, y, width, height)
}
Graphics.prototype.fillFgRect = function(x,y, width, height) {
this._fillRect(x, y, width, height, this.fg);
}
Graphics.prototype.fillBgRect = function(x,y, width, height) {
this._fillRect(x, y, width, height, this.bg);
}
var PATTERNS = [
[2, 1, 2, 2, 2, 2, 0, 0], // 0
[2, 2, 2, 1, 2, 2, 0, 0], // 1
[2, 2, 2, 2, 2, 1, 0, 0], // 2
[1, 2, 1, 2, 2, 3, 0, 0], // 3
[1, 2, 1, 3, 2, 2, 0, 0], // 4
[1, 3, 1, 2, 2, 2, 0, 0], // 5
[1, 2, 2, 2, 1, 3, 0, 0], // 6
[1, 2, 2, 3, 1, 2, 0, 0], // 7
[1, 3, 2, 2, 1, 2, 0, 0], // 8
[2, 2, 1, 2, 1, 3, 0, 0], // 9
[2, 2, 1, 3, 1, 2, 0, 0], // 10
[2, 3, 1, 2, 1, 2, 0, 0], // 11
[1, 1, 2, 2, 3, 2, 0, 0], // 12
[1, 2, 2, 1, 3, 2, 0, 0], // 13
[1, 2, 2, 2, 3, 1, 0, 0], // 14
[1, 1, 3, 2, 2, 2, 0, 0], // 15
[1, 2, 3, 1, 2, 2, 0, 0], // 16
[1, 2, 3, 2, 2, 1, 0, 0], // 17
[2, 2, 3, 2, 1, 1, 0, 0], // 18
[2, 2, 1, 1, 3, 2, 0, 0], // 19
[2, 2, 1, 2, 3, 1, 0, 0], // 20
[2, 1, 3, 2, 1, 2, 0, 0], // 21
[2, 2, 3, 1, 1, 2, 0, 0], // 22
[3, 1, 2, 1, 3, 1, 0, 0], // 23
[3, 1, 1, 2, 2, 2, 0, 0], // 24
[3, 2, 1, 1, 2, 2, 0, 0], // 25
[3, 2, 1, 2, 2, 1, 0, 0], // 26
[3, 1, 2, 2, 1, 2, 0, 0], // 27
[3, 2, 2, 1, 1, 2, 0, 0], // 28
[3, 2, 2, 2, 1, 1, 0, 0], // 29
[2, 1, 2, 1, 2, 3, 0, 0], // 30
[2, 1, 2, 3, 2, 1, 0, 0], // 31
[2, 3, 2, 1, 2, 1, 0, 0], // 32
[1, 1, 1, 3, 2, 3, 0, 0], // 33
[1, 3, 1, 1, 2, 3, 0, 0], // 34
[1, 3, 1, 3, 2, 1, 0, 0], // 35
[1, 1, 2, 3, 1, 3, 0, 0], // 36
[1, 3, 2, 1, 1, 3, 0, 0], // 37
[1, 3, 2, 3, 1, 1, 0, 0], // 38
[2, 1, 1, 3, 1, 3, 0, 0], // 39
[2, 3, 1, 1, 1, 3, 0, 0], // 40
[2, 3, 1, 3, 1, 1, 0, 0], // 41
[1, 1, 2, 1, 3, 3, 0, 0], // 42
[1, 1, 2, 3, 3, 1, 0, 0], // 43
[1, 3, 2, 1, 3, 1, 0, 0], // 44
[1, 1, 3, 1, 2, 3, 0, 0], // 45
[1, 1, 3, 3, 2, 1, 0, 0], // 46
[1, 3, 3, 1, 2, 1, 0, 0], // 47
[3, 1, 3, 1, 2, 1, 0, 0], // 48
[2, 1, 1, 3, 3, 1, 0, 0], // 49
[2, 3, 1, 1, 3, 1, 0, 0], // 50
[2, 1, 3, 1, 1, 3, 0, 0], // 51
[2, 1, 3, 3, 1, 1, 0, 0], // 52
[2, 1, 3, 1, 3, 1, 0, 0], // 53
[3, 1, 1, 1, 2, 3, 0, 0], // 54
[3, 1, 1, 3, 2, 1, 0, 0], // 55
[3, 3, 1, 1, 2, 1, 0, 0], // 56
[3, 1, 2, 1, 1, 3, 0, 0], // 57
[3, 1, 2, 3, 1, 1, 0, 0], // 58
[3, 3, 2, 1, 1, 1, 0, 0], // 59
[3, 1, 4, 1, 1, 1, 0, 0], // 60
[2, 2, 1, 4, 1, 1, 0, 0], // 61
[4, 3, 1, 1, 1, 1, 0, 0], // 62
[1, 1, 1, 2, 2, 4, 0, 0], // 63
[1, 1, 1, 4, 2, 2, 0, 0], // 64
[1, 2, 1, 1, 2, 4, 0, 0], // 65
[1, 2, 1, 4, 2, 1, 0, 0], // 66
[1, 4, 1, 1, 2, 2, 0, 0], // 67
[1, 4, 1, 2, 2, 1, 0, 0], // 68
[1, 1, 2, 2, 1, 4, 0, 0], // 69
[1, 1, 2, 4, 1, 2, 0, 0], // 70
[1, 2, 2, 1, 1, 4, 0, 0], // 71
[1, 2, 2, 4, 1, 1, 0, 0], // 72
[1, 4, 2, 1, 1, 2, 0, 0], // 73
[1, 4, 2, 2, 1, 1, 0, 0], // 74
[2, 4, 1, 2, 1, 1, 0, 0], // 75
[2, 2, 1, 1, 1, 4, 0, 0], // 76
[4, 1, 3, 1, 1, 1, 0, 0], // 77
[2, 4, 1, 1, 1, 2, 0, 0], // 78
[1, 3, 4, 1, 1, 1, 0, 0], // 79
[1, 1, 1, 2, 4, 2, 0, 0], // 80
[1, 2, 1, 1, 4, 2, 0, 0], // 81
[1, 2, 1, 2, 4, 1, 0, 0], // 82
[1, 1, 4, 2, 1, 2, 0, 0], // 83
[1, 2, 4, 1, 1, 2, 0, 0], // 84
[1, 2, 4, 2, 1, 1, 0, 0], // 85
[4, 1, 1, 2, 1, 2, 0, 0], // 86
[4, 2, 1, 1, 1, 2, 0, 0], // 87
[4, 2, 1, 2, 1, 1, 0, 0], // 88
[2, 1, 2, 1, 4, 1, 0, 0], // 89
[2, 1, 4, 1, 2, 1, 0, 0], // 90
[4, 1, 2, 1, 2, 1, 0, 0], // 91
[1, 1, 1, 1, 4, 3, 0, 0], // 92
[1, 1, 1, 3, 4, 1, 0, 0], // 93
[1, 3, 1, 1, 4, 1, 0, 0], // 94
[1, 1, 4, 1, 1, 3, 0, 0], // 95
[1, 1, 4, 3, 1, 1, 0, 0], // 96
[4, 1, 1, 1, 1, 3, 0, 0], // 97
[4, 1, 1, 3, 1, 1, 0, 0], // 98
[1, 1, 3, 1, 4, 1, 0, 0], // 99
[1, 1, 4, 1, 3, 1, 0, 0], // 100
[3, 1, 1, 1, 4, 1, 0, 0], // 101
[4, 1, 1, 1, 3, 1, 0, 0], // 102
[2, 1, 1, 4, 1, 2, 0, 0], // 103
[2, 1, 1, 2, 1, 4, 0, 0], // 104
[2, 1, 1, 2, 3, 2, 0, 0], // 105
[2, 3, 3, 1, 1, 1, 2, 0] // 106
]
var barcode = require('./barcode');
var qrcode = require('./qrcode');
function convert_length(length) {
return Math.round(wx.getSystemInfoSync().windowWidth * length / 750);
}
function barc(id, code, width, height) {
barcode.code128(wx.createCanvasContext(id), code, convert_length(width), convert_length(height))
}
function qrc(id, code, width, height) {
qrcode.api.draw(code, {
ctx: wx.createCanvasContext(id),
width: convert_length(width),
height: convert_length(height)
})
}
module.exports = {
barcode: barc,
qrcode: qrc
}
\ No newline at end of file
var QR = (function () {
// alignment pattern
var adelta = [
0, 11, 15, 19, 23, 27, 31, // force 1 pat
16, 18, 20, 22, 24, 26, 28, 20, 22, 24, 24, 26, 28, 28, 22, 24, 24,
26, 26, 28, 28, 24, 24, 26, 26, 26, 28, 28, 24, 26, 26, 26, 28, 28
];
// version block
var vpat = [
0xc94, 0x5bc, 0xa99, 0x4d3, 0xbf6, 0x762, 0x847, 0x60d,
0x928, 0xb78, 0x45d, 0xa17, 0x532, 0x9a6, 0x683, 0x8c9,
0x7ec, 0xec4, 0x1e1, 0xfab, 0x08e, 0xc1a, 0x33f, 0xd75,
0x250, 0x9d5, 0x6f0, 0x8ba, 0x79f, 0xb0b, 0x42e, 0xa64,
0x541, 0xc69
];
// final format bits with mask: level << 3 | mask
var fmtword = [
0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976, //L
0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0, //M
0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed, //Q
0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b //H
];
// 4 per version: number of blocks 1,2; data width; ecc width
var eccblocks = [
1, 0, 19, 7, 1, 0, 16, 10, 1, 0, 13, 13, 1, 0, 9, 17,
1, 0, 34, 10, 1, 0, 28, 16, 1, 0, 22, 22, 1, 0, 16, 28,
1, 0, 55, 15, 1, 0, 44, 26, 2, 0, 17, 18, 2, 0, 13, 22,
1, 0, 80, 20, 2, 0, 32, 18, 2, 0, 24, 26, 4, 0, 9, 16,
1, 0, 108, 26, 2, 0, 43, 24, 2, 2, 15, 18, 2, 2, 11, 22,
2, 0, 68, 18, 4, 0, 27, 16, 4, 0, 19, 24, 4, 0, 15, 28,
2, 0, 78, 20, 4, 0, 31, 18, 2, 4, 14, 18, 4, 1, 13, 26,
2, 0, 97, 24, 2, 2, 38, 22, 4, 2, 18, 22, 4, 2, 14, 26,
2, 0, 116, 30, 3, 2, 36, 22, 4, 4, 16, 20, 4, 4, 12, 24,
2, 2, 68, 18, 4, 1, 43, 26, 6, 2, 19, 24, 6, 2, 15, 28,
4, 0, 81, 20, 1, 4, 50, 30, 4, 4, 22, 28, 3, 8, 12, 24,
2, 2, 92, 24, 6, 2, 36, 22, 4, 6, 20, 26, 7, 4, 14, 28,
4, 0, 107, 26, 8, 1, 37, 22, 8, 4, 20, 24, 12, 4, 11, 22,
3, 1, 115, 30, 4, 5, 40, 24, 11, 5, 16, 20, 11, 5, 12, 24,
5, 1, 87, 22, 5, 5, 41, 24, 5, 7, 24, 30, 11, 7, 12, 24,
5, 1, 98, 24, 7, 3, 45, 28, 15, 2, 19, 24, 3, 13, 15, 30,
1, 5, 107, 28, 10, 1, 46, 28, 1, 15, 22, 28, 2, 17, 14, 28,
5, 1, 120, 30, 9, 4, 43, 26, 17, 1, 22, 28, 2, 19, 14, 28,
3, 4, 113, 28, 3, 11, 44, 26, 17, 4, 21, 26, 9, 16, 13, 26,
3, 5, 107, 28, 3, 13, 41, 26, 15, 5, 24, 30, 15, 10, 15, 28,
4, 4, 116, 28, 17, 0, 42, 26, 17, 6, 22, 28, 19, 6, 16, 30,
2, 7, 111, 28, 17, 0, 46, 28, 7, 16, 24, 30, 34, 0, 13, 24,
4, 5, 121, 30, 4, 14, 47, 28, 11, 14, 24, 30, 16, 14, 15, 30,
6, 4, 117, 30, 6, 14, 45, 28, 11, 16, 24, 30, 30, 2, 16, 30,
8, 4, 106, 26, 8, 13, 47, 28, 7, 22, 24, 30, 22, 13, 15, 30,
10, 2, 114, 28, 19, 4, 46, 28, 28, 6, 22, 28, 33, 4, 16, 30,
8, 4, 122, 30, 22, 3, 45, 28, 8, 26, 23, 30, 12, 28, 15, 30,
3, 10, 117, 30, 3, 23, 45, 28, 4, 31, 24, 30, 11, 31, 15, 30,
7, 7, 116, 30, 21, 7, 45, 28, 1, 37, 23, 30, 19, 26, 15, 30,
5, 10, 115, 30, 19, 10, 47, 28, 15, 25, 24, 30, 23, 25, 15, 30,
13, 3, 115, 30, 2, 29, 46, 28, 42, 1, 24, 30, 23, 28, 15, 30,
17, 0, 115, 30, 10, 23, 46, 28, 10, 35, 24, 30, 19, 35, 15, 30,
17, 1, 115, 30, 14, 21, 46, 28, 29, 19, 24, 30, 11, 46, 15, 30,
13, 6, 115, 30, 14, 23, 46, 28, 44, 7, 24, 30, 59, 1, 16, 30,
12, 7, 121, 30, 12, 26, 47, 28, 39, 14, 24, 30, 22, 41, 15, 30,
6, 14, 121, 30, 6, 34, 47, 28, 46, 10, 24, 30, 2, 64, 15, 30,
17, 4, 122, 30, 29, 14, 46, 28, 49, 10, 24, 30, 24, 46, 15, 30,
4, 18, 122, 30, 13, 32, 46, 28, 48, 14, 24, 30, 42, 32, 15, 30,
20, 4, 117, 30, 40, 7, 47, 28, 43, 22, 24, 30, 10, 67, 15, 30,
19, 6, 118, 30, 18, 31, 47, 28, 34, 34, 24, 30, 20, 61, 15, 30
];
// Galois field log table
var glog = [
0xff, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd, 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e, 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51, 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf
];
// Galios field exponent table
var gexp = [
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x00
];
// Working buffers:
// data input and ecc append, image working buffer, fixed part of image, run lengths for badness
var strinbuf=[], eccbuf=[], qrframe=[], framask=[], rlens=[];
// Control values - width is based on version, last 4 are from table.
var version, width, neccblk1, neccblk2, datablkw, eccblkwid;
var ecclevel = 2;
// set bit to indicate cell in qrframe is immutable. symmetric around diagonal
function setmask(x, y)
{
var bt;
if (x > y) {
bt = x;
x = y;
y = bt;
}
// y*y = 1+3+5...
bt = y;
bt *= y;
bt += y;
bt >>= 1;
bt += x;
framask[bt] = 1;
}
// enter alignment pattern - black to qrframe, white to mask (later black frame merged to mask)
function putalign(x, y)
{
var j;
qrframe[x + width * y] = 1;
for (j = -2; j < 2; j++) {
qrframe[(x + j) + width * (y - 2)] = 1;
qrframe[(x - 2) + width * (y + j + 1)] = 1;
qrframe[(x + 2) + width * (y + j)] = 1;
qrframe[(x + j + 1) + width * (y + 2)] = 1;
}
for (j = 0; j < 2; j++) {
setmask(x - 1, y + j);
setmask(x + 1, y - j);
setmask(x - j, y - 1);
setmask(x + j, y + 1);
}
}
//========================================================================
// Reed Solomon error correction
// exponentiation mod N
function modnn(x)
{
while (x >= 255) {
x -= 255;
x = (x >> 8) + (x & 255);
}
return x;
}
var genpoly = [];
// Calculate and append ECC data to data block. Block is in strinbuf, indexes to buffers given.
function appendrs(data, dlen, ecbuf, eclen)
{
var i, j, fb;
for (i = 0; i < eclen; i++)
strinbuf[ecbuf + i] = 0;
for (i = 0; i < dlen; i++) {
fb = glog[strinbuf[data + i] ^ strinbuf[ecbuf]];
if (fb != 255) /* fb term is non-zero */
for (j = 1; j < eclen; j++)
strinbuf[ecbuf + j - 1] = strinbuf[ecbuf + j] ^ gexp[modnn(fb + genpoly[eclen - j])];
else
for( j = ecbuf ; j < ecbuf + eclen; j++ )
strinbuf[j] = strinbuf[j + 1];
strinbuf[ ecbuf + eclen - 1] = fb == 255 ? 0 : gexp[modnn(fb + genpoly[0])];
}
}
//========================================================================
// Frame data insert following the path rules
// check mask - since symmetrical use half.
function ismasked(x, y)
{
var bt;
if (x > y) {
bt = x;
x = y;
y = bt;
}
bt = y;
bt += y * y;
bt >>= 1;
bt += x;
return framask[bt];
}
//========================================================================
// Apply the selected mask out of the 8.
function applymask(m)
{
var x, y, r3x, r3y;
switch (m) {
case 0:
for (y = 0; y < width; y++)
for (x = 0; x < width; x++)
if (!((x + y) & 1) && !ismasked(x, y))
qrframe[x + y * width] ^= 1;
break;
case 1:
for (y = 0; y < width; y++)
for (x = 0; x < width; x++)
if (!(y & 1) && !ismasked(x, y))
qrframe[x + y * width] ^= 1;
break;
case 2:
for (y = 0; y < width; y++)
for (r3x = 0, x = 0; x < width; x++, r3x++) {
if (r3x == 3)
r3x = 0;
if (!r3x && !ismasked(x, y))
qrframe[x + y * width] ^= 1;
}
break;
case 3:
for (r3y = 0, y = 0; y < width; y++, r3y++) {
if (r3y == 3)
r3y = 0;
for (r3x = r3y, x = 0; x < width; x++, r3x++) {
if (r3x == 3)
r3x = 0;
if (!r3x && !ismasked(x, y))
qrframe[x + y * width] ^= 1;
}
}
break;
case 4:
for (y = 0; y < width; y++)
for (r3x = 0, r3y = ((y >> 1) & 1), x = 0; x < width; x++, r3x++) {
if (r3x == 3) {
r3x = 0;
r3y = !r3y;
}
if (!r3y && !ismasked(x, y))
qrframe[x + y * width] ^= 1;
}
break;
case 5:
for (r3y = 0, y = 0; y < width; y++, r3y++) {
if (r3y == 3)
r3y = 0;
for (r3x = 0, x = 0; x < width; x++, r3x++) {
if (r3x == 3)
r3x = 0;
if (!((x & y & 1) + !(!r3x | !r3y)) && !ismasked(x, y))
qrframe[x + y * width] ^= 1;
}
}
break;
case 6:
for (r3y = 0, y = 0; y < width; y++, r3y++) {
if (r3y == 3)
r3y = 0;
for (r3x = 0, x = 0; x < width; x++, r3x++) {
if (r3x == 3)
r3x = 0;
if (!(((x & y & 1) + (r3x && (r3x == r3y))) & 1) && !ismasked(x, y))
qrframe[x + y * width] ^= 1;
}
}
break;
case 7:
for (r3y = 0, y = 0; y < width; y++, r3y++) {
if (r3y == 3)
r3y = 0;
for (r3x = 0, x = 0; x < width; x++, r3x++) {
if (r3x == 3)
r3x = 0;
if (!(((r3x && (r3x == r3y)) + ((x + y) & 1)) & 1) && !ismasked(x, y))
qrframe[x + y * width] ^= 1;
}
}
break;
}
return;
}
// Badness coefficients.
var N1 = 3, N2 = 3, N3 = 40, N4 = 10;
// Using the table of the length of each run, calculate the amount of bad image
// - long runs or those that look like finders; called twice, once each for X and Y
function badruns(length)
{
var i;
var runsbad = 0;
for (i = 0; i <= length; i++)
if (rlens[i] >= 5)
runsbad += N1 + rlens[i] - 5;
// BwBBBwB as in finder
for (i = 3; i < length - 1; i += 2)
if (rlens[i - 2] == rlens[i + 2]
&& rlens[i + 2] == rlens[i - 1]
&& rlens[i - 1] == rlens[i + 1]
&& rlens[i - 1] * 3 == rlens[i]
// white around the black pattern? Not part of spec
&& (rlens[i - 3] == 0 // beginning
|| i + 3 > length // end
|| rlens[i - 3] * 3 >= rlens[i] * 4 || rlens[i + 3] * 3 >= rlens[i] * 4)
)
runsbad += N3;
return runsbad;
}
// Calculate how bad the masked image is - blocks, imbalance, runs, or finders.
function badcheck()
{
var x, y, h, b, b1;
var thisbad = 0;
var bw = 0;
// blocks of same color.
for (y = 0; y < width - 1; y++)
for (x = 0; x < width - 1; x++)
if ((qrframe[x + width * y] && qrframe[(x + 1) + width * y]
&& qrframe[x + width * (y + 1)] && qrframe[(x + 1) + width * (y + 1)]) // all black
|| !(qrframe[x + width * y] || qrframe[(x + 1) + width * y]
|| qrframe[x + width * (y + 1)] || qrframe[(x + 1) + width * (y + 1)])) // all white
thisbad += N2;
// X runs
for (y = 0; y < width; y++) {
rlens[0] = 0;
for (h = b = x = 0; x < width; x++) {
if ((b1 = qrframe[x + width * y]) == b)
rlens[h]++;
else
rlens[++h] = 1;
b = b1;
bw += b ? 1 : -1;
}
thisbad += badruns(h);
}
// black/white imbalance
if (bw < 0)
bw = -bw;
var big = bw;
var count = 0;
big += big << 2;
big <<= 1;
while (big > width * width)
big -= width * width, count++;
thisbad += count * N4;
// Y runs
for (x = 0; x < width; x++) {
rlens[0] = 0;
for (h = b = y = 0; y < width; y++) {
if ((b1 = qrframe[x + width * y]) == b)
rlens[h]++;
else
rlens[++h] = 1;
b = b1;
}
thisbad += badruns(h);
}
return thisbad;
}
function genframe(instring)
{
var x, y, k, t, v, i, j, m;
// find the smallest version that fits the string
t = instring.length;
version = 0;
do {
version++;
k = (ecclevel - 1) * 4 + (version - 1) * 16;
neccblk1 = eccblocks[k++];
neccblk2 = eccblocks[k++];
datablkw = eccblocks[k++];
eccblkwid = eccblocks[k];
k = datablkw * (neccblk1 + neccblk2) + neccblk2 - 3 + (version <= 9);
if (t <= k)
break;
} while (version < 40);
// FIXME - insure that it fits insted of being truncated
width = 17 + 4 * version;
// allocate, clear and setup data structures
v = datablkw + (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2;
for( t = 0; t < v; t++ )
eccbuf[t] = 0;
strinbuf = instring.slice(0);
for( t = 0; t < width * width; t++ )
qrframe[t] = 0;
for( t = 0 ; t < (width * (width + 1) + 1) / 2; t++)
framask[t] = 0;
// insert finders - black to frame, white to mask
for (t = 0; t < 3; t++) {
k = 0;
y = 0;
if (t == 1)
k = (width - 7);
if (t == 2)
y = (width - 7);
qrframe[(y + 3) + width * (k + 3)] = 1;
for (x = 0; x < 6; x++) {
qrframe[(y + x) + width * k] = 1;
qrframe[y + width * (k + x + 1)] = 1;
qrframe[(y + 6) + width * (k + x)] = 1;
qrframe[(y + x + 1) + width * (k + 6)] = 1;
}
for (x = 1; x < 5; x++) {
setmask(y + x, k + 1);
setmask(y + 1, k + x + 1);
setmask(y + 5, k + x);
setmask(y + x + 1, k + 5);
}
for (x = 2; x < 4; x++) {
qrframe[(y + x) + width * (k + 2)] = 1;
qrframe[(y + 2) + width * (k + x + 1)] = 1;
qrframe[(y + 4) + width * (k + x)] = 1;
qrframe[(y + x + 1) + width * (k + 4)] = 1;
}
}
// alignment blocks
if (version > 1) {
t = adelta[version];
y = width - 7;
for (;;) {
x = width - 7;
while (x > t - 3) {
putalign(x, y);
if (x < t)
break;
x -= t;
}
if (y <= t + 9)
break;
y -= t;
putalign(6, y);
putalign(y, 6);
}
}
// single black
qrframe[8 + width * (width - 8)] = 1;
// timing gap - mask only
for (y = 0; y < 7; y++) {
setmask(7, y);
setmask(width - 8, y);
setmask(7, y + width - 7);
}
for (x = 0; x < 8; x++) {
setmask(x, 7);
setmask(x + width - 8, 7);
setmask(x, width - 8);
}
// reserve mask-format area
for (x = 0; x < 9; x++)
setmask(x, 8);
for (x = 0; x < 8; x++) {
setmask(x + width - 8, 8);
setmask(8, x);
}
for (y = 0; y < 7; y++)
setmask(8, y + width - 7);
// timing row/col
for (x = 0; x < width - 14; x++)
if (x & 1) {
setmask(8 + x, 6);
setmask(6, 8 + x);
}
else {
qrframe[(8 + x) + width * 6] = 1;
qrframe[6 + width * (8 + x)] = 1;
}
// version block
if (version > 6) {
t = vpat[version - 7];
k = 17;
for (x = 0; x < 6; x++)
for (y = 0; y < 3; y++, k--)
if (1 & (k > 11 ? version >> (k - 12) : t >> k)) {
qrframe[(5 - x) + width * (2 - y + width - 11)] = 1;
qrframe[(2 - y + width - 11) + width * (5 - x)] = 1;
}
else {
setmask(5 - x, 2 - y + width - 11);
setmask(2 - y + width - 11, 5 - x);
}
}
// sync mask bits - only set above for white spaces, so add in black bits
for (y = 0; y < width; y++)
for (x = 0; x <= y; x++)
if (qrframe[x + width * y])
setmask(x, y);
// convert string to bitstream
// 8 bit data to QR-coded 8 bit data (numeric or alphanum, or kanji not supported)
v = strinbuf.length;
// string to array
for( i = 0 ; i < v; i++ )
eccbuf[i] = strinbuf.charCodeAt(i);
strinbuf = eccbuf.slice(0);
// calculate max string length
x = datablkw * (neccblk1 + neccblk2) + neccblk2;
if (v >= x - 2) {
v = x - 2;
if (version > 9)
v--;
}
// shift and repack to insert length prefix
i = v;
if (version > 9) {
strinbuf[i + 2] = 0;
strinbuf[i + 3] = 0;
while (i--) {
t = strinbuf[i];
strinbuf[i + 3] |= 255 & (t << 4);
strinbuf[i + 2] = t >> 4;
}
strinbuf[2] |= 255 & (v << 4);
strinbuf[1] = v >> 4;
strinbuf[0] = 0x40 | (v >> 12);
}
else {
strinbuf[i + 1] = 0;
strinbuf[i + 2] = 0;
while (i--) {
t = strinbuf[i];
strinbuf[i + 2] |= 255 & (t << 4);
strinbuf[i + 1] = t >> 4;
}
strinbuf[1] |= 255 & (v << 4);
strinbuf[0] = 0x40 | (v >> 4);
}
// fill to end with pad pattern
i = v + 3 - (version < 10);
while (i < x) {
strinbuf[i++] = 0xec;
// buffer has room if (i == x) break;
strinbuf[i++] = 0x11;
}
// calculate and append ECC
// calculate generator polynomial
genpoly[0] = 1;
for (i = 0; i < eccblkwid; i++) {
genpoly[i + 1] = 1;
for (j = i; j > 0; j--)
genpoly[j] = genpoly[j]
? genpoly[j - 1] ^ gexp[modnn(glog[genpoly[j]] + i)] : genpoly[j - 1];
genpoly[0] = gexp[modnn(glog[genpoly[0]] + i)];
}
for (i = 0; i <= eccblkwid; i++)
genpoly[i] = glog[genpoly[i]]; // use logs for genpoly[] to save calc step
// append ecc to data buffer
k = x;
y = 0;
for (i = 0; i < neccblk1; i++) {
appendrs(y, datablkw, k, eccblkwid);
y += datablkw;
k += eccblkwid;
}
for (i = 0; i < neccblk2; i++) {
appendrs(y, datablkw + 1, k, eccblkwid);
y += datablkw + 1;
k += eccblkwid;
}
// interleave blocks
y = 0;
for (i = 0; i < datablkw; i++) {
for (j = 0; j < neccblk1; j++)
eccbuf[y++] = strinbuf[i + j * datablkw];
for (j = 0; j < neccblk2; j++)
eccbuf[y++] = strinbuf[(neccblk1 * datablkw) + i + (j * (datablkw + 1))];
}
for (j = 0; j < neccblk2; j++)
eccbuf[y++] = strinbuf[(neccblk1 * datablkw) + i + (j * (datablkw + 1))];
for (i = 0; i < eccblkwid; i++)
for (j = 0; j < neccblk1 + neccblk2; j++)
eccbuf[y++] = strinbuf[x + i + j * eccblkwid];
strinbuf = eccbuf;
// pack bits into frame avoiding masked area.
x = y = width - 1;
k = v = 1; // up, minus
/* inteleaved data and ecc codes */
m = (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2;
for (i = 0; i < m; i++) {
t = strinbuf[i];
for (j = 0; j < 8; j++, t <<= 1) {
if (0x80 & t)
qrframe[x + width * y] = 1;
do { // find next fill position
if (v)
x--;
else {
x++;
if (k) {
if (y != 0)
y--;
else {
x -= 2;
k = !k;
if (x == 6) {
x--;
y = 9;
}
}
}
else {
if (y != width - 1)
y++;
else {
x -= 2;
k = !k;
if (x == 6) {
x--;
y -= 8;
}
}
}
}
v = !v;
} while (ismasked(x, y));
}
}
// save pre-mask copy of frame
strinbuf = qrframe.slice(0);
t = 0; // best
y = 30000; // demerit
// for instead of while since in original arduino code
// if an early mask was "good enough" it wouldn't try for a better one
// since they get more complex and take longer.
for (k = 0; k < 8; k++) {
applymask(k); // returns black-white imbalance
x = badcheck();
if (x < y) { // current mask better than previous best?
y = x;
t = k;
}
if (t == 7)
break; // don't increment i to a void redoing mask
qrframe = strinbuf.slice(0); // reset for next pass
}
if (t != k) // redo best mask - none good enough, last wasn't t
applymask(t);
// add in final mask/ecclevel bytes
y = fmtword[t + ((ecclevel - 1) << 3)];
// low byte
for (k = 0; k < 8; k++, y >>= 1)
if (y & 1) {
qrframe[(width - 1 - k) + width * 8] = 1;
if (k < 6)
qrframe[8 + width * k] = 1;
else
qrframe[8 + width * (k + 1)] = 1;
}
// high byte
for (k = 0; k < 7; k++, y >>= 1)
if (y & 1) {
qrframe[8 + width * (width - 7 + k)] = 1;
if (k)
qrframe[(6 - k) + width * 8] = 1;
else
qrframe[7 + width * 8] = 1;
}
// return image
return qrframe;
}
var _canvas = null,
_size = null;
var api = {
get ecclevel () {
return ecclevel;
},
set ecclevel (val) {
ecclevel = val;
},
get size () {
return _size;
},
set size (val) {
_size = val
},
get canvas () {
return _canvas;
},
set canvas (el) {
_canvas = el;
},
getFrame: function (string) {
return genframe(string);
},
draw: function (string, canvas, size, ecc) {
ecclevel = ecc || ecclevel;
canvas = canvas || _canvas;
if (!canvas) {
console.warn('No canvas provided to draw QR code in!')
return;
}
size = size || _size || Math.min(canvas.width, canvas.height);
var frame = genframe(string),
ctx = canvas.ctx,
px = Math.round(size / (width + 8));
var roundedSize = px * (width + 8),
offset = Math.floor((size - roundedSize) / 2);
size = roundedSize;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.setFillStyle('#000000');
for (var i = 0; i < width; i++) {
for (var j = 0; j < width; j++) {
if (frame[j * width + i]) {
ctx.fillRect(px * (4 + i) + offset, px * (4 + j) + offset, px, px);
}
}
}
ctx.draw();
}
}
module.exports = {
api: api
}
})()
\ No newline at end of file
module.exports = require('./demo/utils')
\ No newline at end of file
{
"_from": "wxbarcode",
"_id": "wxbarcode@1.0.2",
"_inBundle": false,
"_integrity": "sha1-zgLjSP8AYwHZIBd21sn1rZATFLU=",
"_location": "/wxbarcode",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "wxbarcode",
"name": "wxbarcode",
"escapedName": "wxbarcode",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/wxbarcode/-/wxbarcode-1.0.2.tgz",
"_shasum": "ce02e348ff006301d9201776d6c9f5ad901314b5",
"_spec": "wxbarcode",
"_where": "F:\\code\\7-Eleven\\src",
"author": {
"name": "Alsey",
"url": "zamber@gmail.com"
},
"bugs": {
"url": "https://github.com/alsey/wxbarcode/issues"
},
"bundleDependencies": false,
"dependencies": {},
"deprecated": false,
"description": "微信小程序条码、二维码生成模块",
"devDependencies": {},
"homepage": "https://github.com/alsey/wxbarcode#readme",
"keywords": [
"wechat",
"weixin",
"wxapp",
"barcode",
"qrcode",
"微信",
"微信小程序",
"条码",
"二维码"
],
"license": "MIT",
"main": "index.js",
"name": "wxbarcode",
"repository": {
"type": "git",
"url": "git+https://github.com/alsey/wxbarcode.git"
},
"scripts": {},
"version": "1.0.2"
}
...@@ -5,7 +5,6 @@ const utils = require('../../utils/util') ...@@ -5,7 +5,6 @@ const utils = require('../../utils/util')
const envInfo = require('../../config/index').envInfo const envInfo = require('../../config/index').envInfo
var wxbarcode = require('../../codeUtils/index.js'); var wxbarcode = require('../../codeUtils/index.js');
wxService.page({ wxService.page({
/** /**
* 页面的初始数据 * 页面的初始数据
...@@ -18,7 +17,23 @@ wxService.page({ ...@@ -18,7 +17,23 @@ wxService.page({
* 生命周期函数--监听页面显示 * 生命周期函数--监听页面显示
*/ */
onShow: function () { onShow: function () {
// Promise.JsBarcode("#imgcode", "123", {
// format: "CODE39",//选择要使用的条形码类型
// width:3,//设置条之间的宽度
// height:100,//高度
// displayValue:true,//是否在条形码下方显示文字
// text:"456",//覆盖显示的文本
// fontOptions:"bold italic",//使文字加粗体或变斜体
// font:"fantasy",//设置文本的字体
// textAlign:"left",//设置文本的水平对齐方式
// textPosition:"top",//设置文本的垂直位置
// textMargin:5,//设置条形码和文本之间的间距
// fontSize:15,//设置文本的大小
// background:"#eee",//设置条形码的背景
// lineColor:"#2196f3",//设置条和文本的颜色。
// margin:15//设置条形码周围的空白边距
// });
wxbarcode.barcode('barcode', '1234567890123456789', 700, 150); wxbarcode.barcode('barcode', '1234567890123456789', 700, 150);
......
...@@ -13,7 +13,9 @@ ...@@ -13,7 +13,9 @@
<view class='qr-code'> <view class='qr-code'>
<view class='top-code'>987876786</view> <view class='top-code'>987876786</view>
<view class='code-img'> <view class='code-img'>
<canvas canvas-id="barcode" /> <canvas canvas-id="barcode" />
<!--<img id="imgcode" /> -->
</view> </view>
<view class='bottom-code'>987868</view> <view class='bottom-code'>987868</view>
</view> </view>
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
} }
.code-img{ .code-img{
margin-top: 30rpx; margin-top: 30rpx;
margin-left: 5px;
} }
.bottom-code{ .bottom-code{
font-size: 40rpx; font-size: 40rpx;
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
"list": [] "list": []
}, },
"miniprogram": { "miniprogram": {
"current": 11, "current": 7,
"list": [ "list": [
{ {
"id": -1, "id": -1,
...@@ -82,8 +82,8 @@ ...@@ -82,8 +82,8 @@
"query": "id=579702812007600128" "query": "id=579702812007600128"
}, },
{ {
"id": -1, "id": 7,
"name": "welvcom", "name": "welcome",
"pathName": "pages/welcome/welcome", "pathName": "pages/welcome/welcome",
"query": "" "query": ""
}, },
...@@ -108,7 +108,8 @@ ...@@ -108,7 +108,8 @@
{ {
"id": -1, "id": -1,
"name": "激活领卡回调页面", "name": "激活领卡回调页面",
"pathName": "pages/activateCard/activateCardCallback" "pathName": "pages/activateCard/activateCardCallback",
"query": ""
} }
] ]
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment