├── README.md
├── Test
├── index.html
├── launcher
│ ├── egret_loader.js
│ ├── egret_require.js
│ └── game-min.js
└── resource
│ ├── assets
│ ├── bg.jpg
│ └── egret_icon.png
│ ├── config
│ └── description.json
│ └── resource.json
└── qr
├── QR8bitByte.ts
├── QRBitBuffer.ts
├── QRCode.ts
├── QRCodeModel.ts
├── QRErrorCorrectLevel.ts
├── QRMaskPattern.ts
├── QRMath.ts
├── QRMode.ts
├── QRPolynomial.ts
├── QRRSBlock.ts
└── QRUtil.ts
/README.md:
--------------------------------------------------------------------------------
1 | # qrCode
2 | Typescript 二维码生成算法。
3 |
4 | 用法:
5 | egret.Sprite sprite = qr.QRCode.create("http://www.egret.com");
6 |
7 | 说明:
8 | qr.QRCode.create()方法有3个可选参数分别是宽度,高度,颜色.
9 |
--------------------------------------------------------------------------------
/Test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | HelloWorld
6 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
55 |
56 |
--------------------------------------------------------------------------------
/Test/launcher/egret_loader.js:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // Copyright (c) 2014-2015, Egret Technology Inc.
4 | // All rights reserved.
5 | // Redistribution and use in source and binary forms, with or without
6 | // modification, are permitted provided that the following conditions are met:
7 | //
8 | // * Redistributions of source code must retain the above copyright
9 | // notice, this list of conditions and the following disclaimer.
10 | // * Redistributions in binary form must reproduce the above copyright
11 | // notice, this list of conditions and the following disclaimer in the
12 | // documentation and/or other materials provided with the distribution.
13 | // * Neither the name of the Egret nor the
14 | // names of its contributors may be used to endorse or promote products
15 | // derived from this software without specific prior written permission.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
18 | // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 | // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 | // IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
23 | // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 | //////////////////////////////////////////////////////////////////////////////////////
29 |
30 | egret_h5.startGame = function () {
31 | var context = egret.MainContext.instance;
32 | context.touchContext = new egret.HTML5TouchContext();
33 | context.deviceContext = new egret.HTML5DeviceContext();
34 | context.netContext = new egret.HTML5NetContext();
35 |
36 | egret.StageDelegate.getInstance().setDesignSize(480, 800);
37 | context.stage = new egret.Stage();
38 | var scaleMode = egret.MainContext.deviceType == egret.MainContext.DEVICE_MOBILE ? egret.StageScaleMode.SHOW_ALL : egret.StageScaleMode.NO_SCALE;
39 | context.stage.scaleMode = scaleMode;
40 |
41 | //WebGL is a Egret's beta property. It's off by default.
42 | //WebGL是egret的Beta特性,默认关闭
43 | var rendererType = 0;
44 | if (rendererType == 1) {// egret.WebGLUtils.checkCanUseWebGL()) {
45 | console.log("Use WebGL mode");
46 | context.rendererContext = new egret.WebGLRenderer();
47 | }
48 | else {
49 | context.rendererContext = new egret.HTML5CanvasRenderer();
50 | }
51 |
52 | egret.MainContext.instance.rendererContext.texture_scale_factor = 1;
53 | context.run();
54 |
55 | var rootClass;
56 | if (document_class) {
57 | rootClass = egret.getDefinitionByName(document_class);
58 | }
59 | if (rootClass) {
60 | var rootContainer = new rootClass();
61 | if (rootContainer instanceof egret.DisplayObjectContainer) {
62 | context.stage.addChild(rootContainer);
63 | }
64 | else {
65 | throw new Error("Document Class must be the subclass to egret.DisplayObjectContainer!");
66 | }
67 | }
68 | else {
69 | throw new Error("Document Class is not found!");
70 | }
71 |
72 | //处理屏幕大小改变
73 | //implement for screen size change
74 | var resizeTimer = null;
75 | var doResize = function () {
76 | context.stage.changeSize();
77 | resizeTimer = null;
78 | };
79 | window.onresize = function () {
80 | if (resizeTimer == null) {
81 | resizeTimer = setTimeout(doResize, 300);
82 | }
83 | };
84 | };
--------------------------------------------------------------------------------
/Test/launcher/egret_require.js:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////////////////////
2 | //
3 | // Copyright (c) 2014-2015, Egret Technology Inc.
4 | // All rights reserved.
5 | // Redistribution and use in source and binary forms, with or without
6 | // modification, are permitted provided that the following conditions are met:
7 | //
8 | // * Redistributions of source code must retain the above copyright
9 | // notice, this list of conditions and the following disclaimer.
10 | // * Redistributions in binary form must reproduce the above copyright
11 | // notice, this list of conditions and the following disclaimer in the
12 | // documentation and/or other materials provided with the distribution.
13 | // * Neither the name of the Egret nor the
14 | // names of its contributors may be used to endorse or promote products
15 | // derived from this software without specific prior written permission.
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
18 | // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 | // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 | // IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
23 | // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 | //////////////////////////////////////////////////////////////////////////////////////
29 |
30 | egret_h5 = {};
31 |
32 | egret_h5.prefix = "";
33 |
34 | egret_h5.loadScript = function (list, callback) {
35 | var loaded = 0;
36 | var loadNext = function () {
37 | egret_h5.loadSingleScript(egret_h5.prefix + list[loaded], function () {
38 | loaded++;
39 | if (loaded >= list.length) {
40 | callback();
41 | }
42 | else {
43 | loadNext();
44 | }
45 | })
46 | };
47 | loadNext();
48 | };
49 |
50 | egret_h5.loadSingleScript = function (src, callback) {
51 | var s = document.createElement('script');
52 | if (s.hasOwnProperty("async")) {
53 | s.async = false;
54 | }
55 | s.src = src;
56 | s.addEventListener('load', function () {
57 | s.parentNode.removeChild(s);
58 | this.removeEventListener('load', arguments.callee, false);
59 | callback();
60 | }, false);
61 | document.body.appendChild(s);
62 | };
63 |
64 | egret_h5.preloadScript = function (list, prefix) {
65 | if (!egret_h5.preloadList) {
66 | egret_h5.preloadList = [];
67 | }
68 | egret_h5.preloadList = egret_h5.preloadList.concat(list.map(function (item) {
69 | return prefix + item;
70 | }))
71 | };
72 |
73 | egret_h5.startLoading = function () {
74 | var list = egret_h5.preloadList;
75 | egret_h5.loadScript(list, egret_h5.startGame);
76 | };
--------------------------------------------------------------------------------
/Test/resource/assets/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cxh612/qrCode/1891e0c77c30627907e54aefe011a51d9c64340b/Test/resource/assets/bg.jpg
--------------------------------------------------------------------------------
/Test/resource/assets/egret_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cxh612/qrCode/1891e0c77c30627907e54aefe011a51d9c64340b/Test/resource/assets/egret_icon.png
--------------------------------------------------------------------------------
/Test/resource/config/description.json:
--------------------------------------------------------------------------------
1 | [
2 | "Open-source,Free,Multi-platform",
3 | "Push Game Forward",
4 | "HTML5 Game Engine"
5 | ]
--------------------------------------------------------------------------------
/Test/resource/resource.json:
--------------------------------------------------------------------------------
1 | {
2 | "resources": [
3 | {
4 | "name": "bgImage",
5 | "type": "image",
6 | "url": "assets/bg.jpg"
7 | },
8 | {
9 | "name": "egretIcon",
10 | "type": "image",
11 | "url": "assets/egret_icon.png"
12 | },
13 | {
14 | "name": "description",
15 | "type": "json",
16 | "url": "config/description.json"
17 | }
18 | ],
19 | "groups": [
20 | {
21 | "name": "preload",
22 | "keys": "bgImage,egretIcon"
23 | }
24 | ]
25 | }
--------------------------------------------------------------------------------
/qr/QR8bitByte.ts:
--------------------------------------------------------------------------------
1 |
2 | module qr {
3 | export class QR8bitByte {
4 | private mode;
5 | private data ;
6 | private parsedData ;
7 | public constructor(data) {
8 | this.mode = QRMode.MODE_8BIT_BYTE;
9 | this.data = data;
10 | this.parsedData = [];
11 |
12 | // UTF-8
13 | for (var i = 0, l = this.data.length; i < l; i++) {
14 | var byteArray = [];
15 | var code = this.data.charCodeAt(i);
16 |
17 | if (code > 0x10000) {
18 | byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18);
19 | byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12);
20 | byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6);
21 | byteArray[3] = 0x80 | (code & 0x3F);
22 | } else if (code > 0x800) {
23 | byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12);
24 | byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6);
25 | byteArray[2] = 0x80 | (code & 0x3F);
26 | } else if (code > 0x80) {
27 | byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6);
28 | byteArray[1] = 0x80 | (code & 0x3F);
29 | } else {
30 | byteArray[0] = code;
31 | }
32 |
33 | this.parsedData.push(byteArray);
34 | }
35 |
36 | this.parsedData = Array.prototype.concat.apply([], this.parsedData);
37 |
38 | if (this.parsedData.length != this.data.length) {
39 | this.parsedData.unshift(191);
40 | this.parsedData.unshift(187);
41 | this.parsedData.unshift(239);
42 | }
43 | }
44 | public getLength(buffer):number {
45 | return this.parsedData.length;
46 | }
47 | public write(buffer) {
48 | for (var i = 0, l = this.parsedData.length; i < l; i++) {
49 | buffer.put(this.parsedData[i], 8);
50 | }
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/qr/QRBitBuffer.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by qingzhu on 15/7/1.
3 | */
4 | module qr {
5 | export class QRBitBuffer{
6 | public buffer;
7 | public length:number;
8 | public constructor() {
9 | this.buffer = [];
10 | this.length = 0;
11 | }
12 |
13 | public get(index) {
14 | var bufIndex = Math.floor(index / 8);
15 | return (this.buffer[bufIndex] >>> 7 - index % 8 & 1) == 1;
16 | }
17 | public put(num, length) {
18 | for (var i = 0; i < length; i++) this.putBit((num >>> length - i - 1 & 1) == 1);
19 | }
20 | public getLengthInBits() {
21 | return this.length;
22 | }
23 | public putBit(bit) {
24 | var bufIndex = Math.floor(this.length / 8);
25 | this.buffer.length <= bufIndex && this.buffer.push(0), bit && (this.buffer[bufIndex] |= 128 >>> this.length % 8), this.length++;
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/qr/QRCode.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by qingzhu on 15/7/1.
3 | */
4 | module qr {
5 | export class QRCode{
6 | /**
7 | * msg
8 | * width,height 二维码宽度,高度
9 | * color 颜色
10 | * */
11 | public static create(msg:string,color=0, width:number=200,height:number=200,errorCorrectLevel=2):egret.Sprite{
12 | var _htOption = {
13 | width : width,
14 | height : height,
15 | correctLevel : qr.QRErrorCorrectLevel.H,
16 | color:color
17 | };
18 | var _oQRCode = new qr.QRCodeModel(qr.QRUtil._getTypeNumber(msg,_htOption.correctLevel), _htOption.correctLevel);
19 | _oQRCode.addData(msg);
20 | _oQRCode.make();
21 | return QRCode.draw(_oQRCode,_htOption);
22 | }
23 |
24 | public static draw(m:qr.QRCodeModel ,_htOption):egret.Sprite{
25 | var sc:egret.Sprite = new egret.Sprite();
26 | var _htOption = _htOption;
27 | var nCount = m.getModuleCount();
28 | var nWidth = Math.floor(_htOption.width / nCount);
29 | var nHeight = Math.floor(_htOption.height / nCount);
30 |
31 | for (var row = 0; row < nCount; row++) {
32 | for (var col = 0; col < nCount; col++) {
33 | var b =m.isDark(row, col);
34 | if(b){
35 | sc.graphics.beginFill(_htOption.color);
36 | sc.graphics.drawRect(col*nWidth,row*nHeight,nWidth,nHeight);
37 | sc.graphics.endFill();
38 | }
39 | }
40 | }
41 | return sc;
42 | }
43 |
44 | }
45 | }
--------------------------------------------------------------------------------
/qr/QRCodeModel.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by qingzhu on 15/7/1.
3 | */
4 | module qr {
5 | export class QRCodeModel{
6 | public typeNumber:number ;
7 | public errorCorrectLevel ;
8 | public modules = null;
9 | public moduleCount = 0;
10 | public dataCache = null;
11 | public dataList = [];
12 | public constructor(typeNumber, errorCorrectLevel) {
13 | this.typeNumber = typeNumber;
14 | this.errorCorrectLevel = errorCorrectLevel;
15 | this.modules = null;
16 | this.moduleCount = 0;
17 | this.dataCache = null;
18 | this.dataList = [];
19 | }
20 | public addData(data) {
21 | var newData = new QR8bitByte(data);
22 | this.dataList.push(newData), this.dataCache = null;
23 | }
24 | public isDark(row, col) {
25 | if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) throw new Error(row + "," + col);
26 | return this.modules[row][col];
27 | }
28 | public getModuleCount() {
29 | return this.moduleCount;
30 | }
31 | public make() {
32 | this.makeImpl(!1, this.getBestMaskPattern());
33 | }
34 | public makeImpl(test, maskPattern) {
35 | this.moduleCount = this.typeNumber * 4 + 17, this.modules = new Array(this.moduleCount);
36 | for (var row = 0; row < this.moduleCount; row++) {
37 | this.modules[row] = new Array(this.moduleCount);
38 | for (var col = 0; col < this.moduleCount; col++) this.modules[row][col] = null;
39 | }
40 | this.setupPositionProbePattern(0, 0),
41 | this.setupPositionProbePattern(this.moduleCount - 7, 0),
42 | this.setupPositionProbePattern(0, this.moduleCount - 7),
43 | this.setupPositionAdjustPattern(),
44 | this.setupTimingPattern(),
45 | this.setupTypeInfo(test, maskPattern),
46 | this.typeNumber >= 7 && this.setupTypeNumber(test),
47 | this.dataCache == null && (this.dataCache = QRCodeModel.createData(this.typeNumber, this.errorCorrectLevel, this.dataList)), this.mapData(this.dataCache, maskPattern);
48 | }
49 | public setupPositionProbePattern (row, col) {
50 | for (var r = -1; r <= 7; r++) {
51 | if (row + r <= -1 || this.moduleCount <= row + r) continue;
52 | for (var c = -1; c <= 7; c++) {
53 | if (col + c <= -1 || this.moduleCount <= col + c) continue;
54 | 0 <= r && r <= 6 && (c == 0 || c == 6) || 0 <= c && c <= 6 && (r == 0 || r == 6) || 2 <= r && r <= 4 && 2 <= c && c <= 4 ? this.modules[row + r][col + c] = !0 : this.modules[row + r][col + c] = !1;
55 | }
56 | }
57 | }
58 | public getBestMaskPattern() {
59 | var minLostPoint = 0, pattern = 0;
60 | for (var i = 0; i < 8; i++) {
61 | this.makeImpl(!0, i);
62 | var lostPoint = QRUtil.getLostPoint(this);
63 | if (i == 0 || minLostPoint > lostPoint) minLostPoint = lostPoint, pattern = i;
64 | }
65 | return pattern;
66 | }
67 | public createMovieClip(target_mc, instance_name, depth) {
68 | var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth), cs = 1;
69 | this.make();
70 | for (var row = 0; row < this.modules.length; row++) {
71 | var y = row * cs;
72 | for (var col = 0; col < this.modules[row].length; col++) {
73 | var x = col * cs, dark = this.modules[row][col];
74 | dark && (qr_mc.beginFill(0, 100), qr_mc.moveTo(x, y), qr_mc.lineTo(x + cs, y), qr_mc.lineTo(x + cs, y + cs), qr_mc.lineTo(x, y + cs), qr_mc.endFill());
75 | }
76 | }
77 | return qr_mc;
78 | }
79 | public setupTimingPattern() {
80 | for (var r = 8; r < this.moduleCount - 8; r++) {
81 | if (this.modules[r][6] != null) continue;
82 | this.modules[r][6] = r % 2 == 0;
83 | }
84 | for (var c = 8; c < this.moduleCount - 8; c++) {
85 | if (this.modules[6][c] != null) continue;
86 | this.modules[6][c] = c % 2 == 0;
87 | }
88 | }
89 | public setupPositionAdjustPattern() {
90 | var pos = QRUtil.getPatternPosition(this.typeNumber);
91 | for (var i = 0; i < pos.length; i++) for (var j = 0; j < pos.length; j++) {
92 | var row = pos[i], col = pos[j];
93 | if (this.modules[row][col] != null) continue;
94 | for (var r = -2; r <= 2; r++) for (var c = -2; c <= 2; c++) r == -2 || r == 2 || c == -2 || c == 2 || r == 0 && c == 0 ? this.modules[row + r][col + c] = !0 : this.modules[row + r][col + c] = !1;
95 | }
96 | }
97 | public setupTypeNumber(test) {
98 | var bits = QRUtil.getBCHTypeNumber(this.typeNumber);
99 | for (var i = 0; i < 18; i++) {
100 | var mod = !test && (bits >> i & 1) == 1;
101 | this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
102 | }
103 | for (var i = 0; i < 18; i++) {
104 | var mod = !test && (bits >> i & 1) == 1;
105 | this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
106 | }
107 | }
108 | public setupTypeInfo(test, maskPattern) {
109 | var data = this.errorCorrectLevel << 3 | maskPattern, bits = QRUtil.getBCHTypeInfo(data);
110 | for (var i = 0; i < 15; i++) {
111 | var mod = !test && (bits >> i & 1) == 1;
112 | i < 6 ? this.modules[i][8] = mod : i < 8 ? this.modules[i + 1][8] = mod : this.modules[this.moduleCount - 15 + i][8] = mod;
113 | }
114 | for (var i = 0; i < 15; i++) {
115 | var mod = !test && (bits >> i & 1) == 1;
116 | i < 8 ? this.modules[8][this.moduleCount - i - 1] = mod : i < 9 ? this.modules[8][15 - i - 1 + 1] = mod : this.modules[8][15 - i - 1] = mod;
117 | }
118 | this.modules[this.moduleCount - 8][8] = !test;
119 | }
120 | public mapData(data, maskPattern) {
121 | var inc = -1, row = this.moduleCount - 1, bitIndex = 7, byteIndex = 0;
122 | for (var col = this.moduleCount - 1; col > 0; col -= 2) {
123 | col == 6 && col--;
124 | for (;;) {
125 | for (var c = 0; c < 2; c++) if (this.modules[row][col - c] == null) {
126 | var dark = !1;
127 | byteIndex < data.length && (dark = (data[byteIndex] >>> bitIndex & 1) == 1);
128 | var mask = QRUtil.getMask(maskPattern, row, col - c);
129 | mask && (dark = !dark), this.modules[row][col - c] = dark, bitIndex--, bitIndex == -1 && (byteIndex++, bitIndex = 7);
130 | }
131 | row += inc;
132 | if (row < 0 || this.moduleCount <= row) {
133 | row -= inc, inc = -inc;
134 | break;
135 | }
136 | }
137 | }
138 | }
139 | ////
140 | public static PAD0 = 236;
141 | public static PAD1 = 17;
142 | public static createData(typeNumber, errorCorrectLevel, dataList) {
143 | var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel), buffer = new QRBitBuffer;
144 | for (var i = 0; i < dataList.length; i++) {
145 | var data = dataList[i];
146 | buffer.put(data.mode, 4), buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber)), data.write(buffer);
147 | }
148 | var totalDataCount = 0;
149 | for (var i = 0; i < rsBlocks.length; i++) totalDataCount += rsBlocks[i].dataCount;
150 | if (buffer.getLengthInBits() > totalDataCount * 8) throw new Error("code length overflow. (" + buffer.getLengthInBits() + ">" + totalDataCount * 8 + ")");
151 | buffer.getLengthInBits() + 4 <= totalDataCount * 8 && buffer.put(0, 4);
152 | while (buffer.getLengthInBits() % 8 != 0) buffer.putBit(!1);
153 | for (;;) {
154 | if (buffer.getLengthInBits() >= totalDataCount * 8) break;
155 | buffer.put(QRCodeModel.PAD0, 8);
156 | if (buffer.getLengthInBits() >= totalDataCount * 8) break;
157 | buffer.put(QRCodeModel.PAD1, 8);
158 | }
159 | return QRCodeModel.createBytes(buffer, rsBlocks);
160 | }
161 | public static createBytes(buffer, rsBlocks) {
162 | var offset = 0, maxDcCount = 0, maxEcCount = 0, dcdata = new Array(rsBlocks.length), ecdata = new Array(rsBlocks.length);
163 | for (var r = 0; r < rsBlocks.length; r++) {
164 | var dcCount = rsBlocks[r].dataCount, ecCount = rsBlocks[r].totalCount - dcCount;
165 | maxDcCount = Math.max(maxDcCount, dcCount), maxEcCount = Math.max(maxEcCount, ecCount), dcdata[r] = new Array(dcCount);
166 | for (var i = 0; i < dcdata[r].length; i++) dcdata[r][i] = 255 & buffer.buffer[i + offset];
167 | offset += dcCount;
168 | var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount), rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1), modPoly = rawPoly.mod(rsPoly);
169 | ecdata[r] = new Array(rsPoly.getLength() - 1);
170 | for (var i = 0; i < ecdata[r].length; i++) {
171 | var modIndex = i + modPoly.getLength() - ecdata[r].length;
172 | ecdata[r][i] = modIndex >= 0 ? modPoly.get(modIndex) : 0;
173 | }
174 | }
175 | var totalCodeCount = 0;
176 | for (var i = 0; i < rsBlocks.length; i++) totalCodeCount += rsBlocks[i].totalCount;
177 | var data = new Array(totalCodeCount), index = 0;
178 | for (var i = 0; i < maxDcCount; i++) for (var r = 0; r < rsBlocks.length; r++) i < dcdata[r].length && (data[index++] = dcdata[r][i]);
179 | for (var i = 0; i < maxEcCount; i++) for (var r = 0; r < rsBlocks.length; r++) i < ecdata[r].length && (data[index++] = ecdata[r][i]);
180 | return data;
181 | }
182 | }
183 | }
--------------------------------------------------------------------------------
/qr/QRErrorCorrectLevel.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by qingzhu on 15/7/1.
3 | */
4 | module qr {
5 | export class QRErrorCorrectLevel{
6 | public static L:number =1;
7 | public static M:number= 0;
8 | public static Q:number = 3;
9 | public static H:number = 2;
10 | }
11 | }
--------------------------------------------------------------------------------
/qr/QRMaskPattern.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by qingzhu on 15/7/1.
3 | */
4 | module qr {
5 | export class QRMaskPattern{
6 | public static PATTERN000:number = 0;
7 | public static PATTERN001:number = 1;
8 | public static PATTERN010:number = 2;
9 | public static PATTERN011:number = 3;
10 | public static PATTERN100:number = 4;
11 | public static PATTERN101:number = 5;
12 | public static PATTERN110:number = 6;
13 | public static PATTERN111:number = 7;
14 | }
15 | }
--------------------------------------------------------------------------------
/qr/QRMath.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by qingzhu on 15/7/1.
3 | */
4 | module qr {
5 | export class QRMath{
6 | public static isInit:boolean;
7 | public static glog(n) {
8 | if(!QRMath.isInit) {
9 | QRMath.init();
10 | }
11 | if (n < 1) console.log("错误:n="+n);
12 | return QRMath.LOG_TABLE[n];
13 | }
14 | public static gexp(n) {
15 | if(!QRMath.isInit){
16 | QRMath.init();
17 | }
18 | while (n < 0) n += 255;
19 | while (n >= 256) n -= 255;
20 | return QRMath.EXP_TABLE[n];
21 | }
22 | public static EXP_TABLE = new Array(256);
23 | public static LOG_TABLE = new Array(256);
24 |
25 | public static init(){
26 | QRMath.isInit = true;
27 | for (var i = 0; i < 8; i++) QRMath.EXP_TABLE[i] = 1 << i;
28 | for (var i = 8; i < 256; i++) QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^ QRMath.EXP_TABLE[i - 5] ^ QRMath.EXP_TABLE[i - 6] ^ QRMath.EXP_TABLE[i - 8];
29 | for (var i = 0; i < 255; i++) QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/qr/QRMode.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by qingzhu on 15/7/1.
3 | */
4 | module qr {
5 | export class QRMode{
6 | public static MODE_NUMBER= 1;
7 | public static MODE_ALPHA_NUM= 2;
8 | public static MODE_8BIT_BYTE= 4;
9 | public static MODE_KANJI= 8;
10 | }
11 | }
--------------------------------------------------------------------------------
/qr/QRPolynomial.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by qingzhu on 15/7/1.
3 | */
4 | module qr {
5 | export class QRPolynomial{
6 | public num;
7 | public constructor(num, shift) {
8 | if (num.length == undefined) throw new Error(num.length + "/" + shift);
9 | var offset = 0;
10 | while (offset < num.length && num[offset] == 0) offset++;
11 | this.num = new Array(num.length - offset + shift);
12 | for (var i = 0; i < num.length - offset; i++) this.num[i] = num[i + offset];
13 | }
14 |
15 | public get(index) {
16 | return this.num[index];
17 | }
18 | public getLength () {
19 | return this.num.length;
20 | }
21 | public multiply(e) {
22 | var num = new Array(this.getLength() + e.getLength() - 1);
23 | for (var i = 0; i < this.getLength(); i++) for (var j = 0; j < e.getLength(); j++) num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)));
24 | return new QRPolynomial(num, 0);
25 | }
26 | public mod (e) {
27 | if (this.getLength() - e.getLength() < 0) return this;
28 | var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0)), num = new Array(this.getLength());
29 | for (var i = 0; i < this.getLength(); i++) num[i] = this.get(i);
30 | for (var i = 0; i < e.getLength(); i++) num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio);
31 | return (new QRPolynomial(num, 0)).mod(e);
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/qr/QRRSBlock.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by qingzhu on 15/7/1.
3 | */
4 | module qr {
5 | export class QRRSBlock{
6 | public totalCount;
7 | public dataCount;
8 | public constructor(totalCount, dataCount) {
9 | this.totalCount = totalCount;
10 | this.dataCount = dataCount;
11 | }
12 |
13 | public static RS_BLOCK_TABLE = [ [ 1, 26, 19 ], [ 1, 26, 16 ], [ 1, 26, 13 ], [ 1, 26, 9 ], [ 1, 44, 34 ], [ 1, 44, 28 ], [ 1, 44, 22 ], [ 1, 44, 16 ], [ 1, 70, 55 ], [ 1, 70, 44 ], [ 2, 35, 17 ], [ 2, 35, 13 ], [ 1, 100, 80 ], [ 2, 50, 32 ], [ 2, 50, 24 ], [ 4, 25, 9 ], [ 1, 134, 108 ], [ 2, 67, 43 ], [ 2, 33, 15, 2, 34, 16 ], [ 2, 33, 11, 2, 34, 12 ], [ 2, 86, 68 ], [ 4, 43, 27 ], [ 4, 43, 19 ], [ 4, 43, 15 ], [ 2, 98, 78 ], [ 4, 49, 31 ], [ 2, 32, 14, 4, 33, 15 ], [ 4, 39, 13, 1, 40, 14 ], [ 2, 121, 97 ], [ 2, 60, 38, 2, 61, 39 ], [ 4, 40, 18, 2, 41, 19 ], [ 4, 40, 14, 2, 41, 15 ], [ 2, 146, 116 ], [ 3, 58, 36, 2, 59, 37 ], [ 4, 36, 16, 4, 37, 17 ], [ 4, 36, 12, 4, 37, 13 ], [ 2, 86, 68, 2, 87, 69 ], [ 4, 69, 43, 1, 70, 44 ], [ 6, 43, 19, 2, 44, 20 ], [ 6, 43, 15, 2, 44, 16 ], [ 4, 101, 81 ], [ 1, 80, 50, 4, 81, 51 ], [ 4, 50, 22, 4, 51, 23 ], [ 3, 36, 12, 8, 37, 13 ], [ 2, 116, 92, 2, 117, 93 ], [ 6, 58, 36, 2, 59, 37 ], [ 4, 46, 20, 6, 47, 21 ], [ 7, 42, 14, 4, 43, 15 ], [ 4, 133, 107 ], [ 8, 59, 37, 1, 60, 38 ], [ 8, 44, 20, 4, 45, 21 ], [ 12, 33, 11, 4, 34, 12 ], [ 3, 145, 115, 1, 146, 116 ], [ 4, 64, 40, 5, 65, 41 ], [ 11, 36, 16, 5, 37, 17 ], [ 11, 36, 12, 5, 37, 13 ], [ 5, 109, 87, 1, 110, 88 ], [ 5, 65, 41, 5, 66, 42 ], [ 5, 54, 24, 7, 55, 25 ], [ 11, 36, 12 ], [ 5, 122, 98, 1, 123, 99 ], [ 7, 73, 45, 3, 74, 46 ], [ 15, 43, 19, 2, 44, 20 ], [ 3, 45, 15, 13, 46, 16 ], [ 1, 135, 107, 5, 136, 108 ], [ 10, 74, 46, 1, 75, 47 ], [ 1, 50, 22, 15, 51, 23 ], [ 2, 42, 14, 17, 43, 15 ], [ 5, 150, 120, 1, 151, 121 ], [ 9, 69, 43, 4, 70, 44 ], [ 17, 50, 22, 1, 51, 23 ], [ 2, 42, 14, 19, 43, 15 ], [ 3, 141, 113, 4, 142, 114 ], [ 3, 70, 44, 11, 71, 45 ], [ 17, 47, 21, 4, 48, 22 ], [ 9, 39, 13, 16, 40, 14 ], [ 3, 135, 107, 5, 136, 108 ], [ 3, 67, 41, 13, 68, 42 ], [ 15, 54, 24, 5, 55, 25 ], [ 15, 43, 15, 10, 44, 16 ], [ 4, 144, 116, 4, 145, 117 ], [ 17, 68, 42 ], [ 17, 50, 22, 6, 51, 23 ], [ 19, 46, 16, 6, 47, 17 ], [ 2, 139, 111, 7, 140, 112 ], [ 17, 74, 46 ], [ 7, 54, 24, 16, 55, 25 ], [ 34, 37, 13 ], [ 4, 151, 121, 5, 152, 122 ], [ 4, 75, 47, 14, 76, 48 ], [ 11, 54, 24, 14, 55, 25 ], [ 16, 45, 15, 14, 46, 16 ], [ 6, 147, 117, 4, 148, 118 ], [ 6, 73, 45, 14, 74, 46 ], [ 11, 54, 24, 16, 55, 25 ], [ 30, 46, 16, 2, 47, 17 ], [ 8, 132, 106, 4, 133, 107 ], [ 8, 75, 47, 13, 76, 48 ], [ 7, 54, 24, 22, 55, 25 ], [ 22, 45, 15, 13, 46, 16 ], [ 10, 142, 114, 2, 143, 115 ], [ 19, 74, 46, 4, 75, 47 ], [ 28, 50, 22, 6, 51, 23 ], [ 33, 46, 16, 4, 47, 17 ], [ 8, 152, 122, 4, 153, 123 ], [ 22, 73, 45, 3, 74, 46 ], [ 8, 53, 23, 26, 54, 24 ], [ 12, 45, 15, 28, 46, 16 ], [ 3, 147, 117, 10, 148, 118 ], [ 3, 73, 45, 23, 74, 46 ], [ 4, 54, 24, 31, 55, 25 ], [ 11, 45, 15, 31, 46, 16 ], [ 7, 146, 116, 7, 147, 117 ], [ 21, 73, 45, 7, 74, 46 ], [ 1, 53, 23, 37, 54, 24 ], [ 19, 45, 15, 26, 46, 16 ], [ 5, 145, 115, 10, 146, 116 ], [ 19, 75, 47, 10, 76, 48 ], [ 15, 54, 24, 25, 55, 25 ], [ 23, 45, 15, 25, 46, 16 ], [ 13, 145, 115, 3, 146, 116 ], [ 2, 74, 46, 29, 75, 47 ], [ 42, 54, 24, 1, 55, 25 ], [ 23, 45, 15, 28, 46, 16 ], [ 17, 145, 115 ], [ 10, 74, 46, 23, 75, 47 ], [ 10, 54, 24, 35, 55, 25 ], [ 19, 45, 15, 35, 46, 16 ], [ 17, 145, 115, 1, 146, 116 ], [ 14, 74, 46, 21, 75, 47 ], [ 29, 54, 24, 19, 55, 25 ], [ 11, 45, 15, 46, 46, 16 ], [ 13, 145, 115, 6, 146, 116 ], [ 14, 74, 46, 23, 75, 47 ], [ 44, 54, 24, 7, 55, 25 ], [ 59, 46, 16, 1, 47, 17 ], [ 12, 151, 121, 7, 152, 122 ], [ 12, 75, 47, 26, 76, 48 ], [ 39, 54, 24, 14, 55, 25 ], [ 22, 45, 15, 41, 46, 16 ], [ 6, 151, 121, 14, 152, 122 ], [ 6, 75, 47, 34, 76, 48 ], [ 46, 54, 24, 10, 55, 25 ], [ 2, 45, 15, 64, 46, 16 ], [ 17, 152, 122, 4, 153, 123 ], [ 29, 74, 46, 14, 75, 47 ], [ 49, 54, 24, 10, 55, 25 ], [ 24, 45, 15, 46, 46, 16 ], [ 4, 152, 122, 18, 153, 123 ], [ 13, 74, 46, 32, 75, 47 ], [ 48, 54, 24, 14, 55, 25 ], [ 42, 45, 15, 32, 46, 16 ], [ 20, 147, 117, 4, 148, 118 ], [ 40, 75, 47, 7, 76, 48 ], [ 43, 54, 24, 22, 55, 25 ], [ 10, 45, 15, 67, 46, 16 ], [ 19, 148, 118, 6, 149, 119 ], [ 18, 75, 47, 31, 76, 48 ], [ 34, 54, 24, 34, 55, 25 ], [ 20, 45, 15, 61, 46, 16 ] ];
14 | public static getRSBlocks = function(typeNumber, errorCorrectLevel) {
15 |
16 | var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
17 | if (rsBlock == undefined) throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel);
18 | var length = rsBlock.length / 3, list = [];
19 | for (var i = 0; i < length; i++) {
20 | var count = rsBlock[i * 3 + 0], totalCount = rsBlock[i * 3 + 1], dataCount = rsBlock[i * 3 + 2];
21 | for (var j = 0; j < count; j++) list.push(new QRRSBlock(totalCount, dataCount));
22 | }
23 | return list;
24 | }
25 | public static getRsBlockTable = function(typeNumber, errorCorrectLevel) {
26 | switch (errorCorrectLevel) {
27 | case QRErrorCorrectLevel.L:
28 | return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
29 | case QRErrorCorrectLevel.M:
30 | return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
31 | case QRErrorCorrectLevel.Q:
32 | return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
33 | case QRErrorCorrectLevel.H:
34 | return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
35 | default:
36 | return undefined;
37 | }
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/qr/QRUtil.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by qingzhu on 15/7/1.
3 | */
4 | module qr {
5 | export class QRUtil{
6 | public static PATTERN_POSITION_TABLE = [ [], [ 6, 18 ], [ 6, 22 ], [ 6, 26 ], [ 6, 30 ], [ 6, 34 ], [ 6, 22, 38 ], [ 6, 24, 42 ], [ 6, 26, 46 ], [ 6, 28, 50 ], [ 6, 30, 54 ], [ 6, 32, 58 ], [ 6, 34, 62 ], [ 6, 26, 46, 66 ], [ 6, 26, 48, 70 ], [ 6, 26, 50, 74 ], [ 6, 30, 54, 78 ], [ 6, 30, 56, 82 ], [ 6, 30, 58, 86 ], [ 6, 34, 62, 90 ], [ 6, 28, 50, 72, 94 ], [ 6, 26, 50, 74, 98 ], [ 6, 30, 54, 78, 102 ], [ 6, 28, 54, 80, 106 ], [ 6, 32, 58, 84, 110 ], [ 6, 30, 58, 86, 114 ], [ 6, 34, 62, 90, 118 ], [ 6, 26, 50, 74, 98, 122 ], [ 6, 30, 54, 78, 102, 126 ], [ 6, 26, 52, 78, 104, 130 ], [ 6, 30, 56, 82, 108, 134 ], [ 6, 34, 60, 86, 112, 138 ], [ 6, 30, 58, 86, 114, 142 ], [ 6, 34, 62, 90, 118, 146 ], [ 6, 30, 54, 78, 102, 126, 150 ], [ 6, 24, 50, 76, 102, 128, 154 ], [ 6, 28, 54, 80, 106, 132, 158 ], [ 6, 32, 58, 84, 110, 136, 162 ], [ 6, 26, 54, 82, 110, 138, 166 ], [ 6, 30, 58, 86, 114, 142, 170 ] ];
7 | public static G15 = 1335;
8 | public static G18 = 7973;
9 | public static G15_MASK = 21522;
10 | public static getBCHTypeInfo(data) {
11 | var d = data << 10;
12 | while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) d ^= QRUtil.G15 << QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15);
13 | return (data << 10 | d) ^ QRUtil.G15_MASK;
14 | }
15 | public static getBCHTypeNumber(data) {
16 | var d = data << 12;
17 | while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) d ^= QRUtil.G18 << QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18);
18 | return data << 12 | d;
19 | }
20 | public static getBCHDigit(data) {
21 | var digit = 0;
22 | while (data != 0) digit++, data >>>= 1;
23 | return digit;
24 | }
25 | public static getPatternPosition (typeNumber) {
26 | return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
27 | }
28 | public static getMask(maskPattern, i, j) {
29 | switch (maskPattern) {
30 | case QRMaskPattern.PATTERN000:
31 | return (i + j) % 2 == 0;
32 | case QRMaskPattern.PATTERN001:
33 | return i % 2 == 0;
34 | case QRMaskPattern.PATTERN010:
35 | return j % 3 == 0;
36 | case QRMaskPattern.PATTERN011:
37 | return (i + j) % 3 == 0;
38 | case QRMaskPattern.PATTERN100:
39 | return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
40 | case QRMaskPattern.PATTERN101:
41 | return i * j % 2 + i * j % 3 == 0;
42 | case QRMaskPattern.PATTERN110:
43 | return (i * j % 2 + i * j % 3) % 2 == 0;
44 | case QRMaskPattern.PATTERN111:
45 | return (i * j % 3 + (i + j) % 2) % 2 == 0;
46 | default:
47 | throw new Error("bad maskPattern:" + maskPattern);
48 | }
49 | }
50 | public static getErrorCorrectPolynomial(errorCorrectLength) {
51 | var a = new QRPolynomial([ 1 ], 0);
52 | for (var i = 0; i < errorCorrectLength; i++) a = a.multiply(new QRPolynomial([ 1, QRMath.gexp(i) ], 0));
53 | return a;
54 | }
55 | public static getLengthInBits(mode, type) {
56 | if (1 <= type && type < 10) switch (mode) {
57 | case qr.QRMode.MODE_NUMBER:
58 | return 10;
59 | case qr.QRMode.MODE_ALPHA_NUM:
60 | return 9;
61 | case qr.QRMode.MODE_8BIT_BYTE:
62 | return 8;
63 | case qr.QRMode.MODE_KANJI:
64 | return 8;
65 | default:
66 | throw new Error("mode:" + mode);
67 | } else if (type < 27) switch (mode) {
68 | case qr.QRMode.MODE_NUMBER:
69 | return 12;
70 | case qr.QRMode.MODE_ALPHA_NUM:
71 | return 11;
72 | case qr.QRMode.MODE_8BIT_BYTE:
73 | return 16;
74 | case qr.QRMode.MODE_KANJI:
75 | return 10;
76 | default:
77 | throw new Error("mode:" + mode);
78 | } else {
79 | if (!(type < 41)) throw new Error("type:" + type);
80 | switch (mode) {
81 | case QRMode.MODE_NUMBER:
82 | return 14;
83 | case QRMode.MODE_ALPHA_NUM:
84 | return 13;
85 | case QRMode.MODE_8BIT_BYTE:
86 | return 16;
87 | case QRMode.MODE_KANJI:
88 | return 12;
89 | default:
90 | throw new Error("mode:" + mode);
91 | }
92 | }
93 | }
94 | public static getLostPoint(qrCode) {
95 | var moduleCount = qrCode.getModuleCount(), lostPoint = 0;
96 | for (var row = 0; row < moduleCount; row++) for (var col = 0; col < moduleCount; col++) {
97 | var sameCount = 0, dark = qrCode.isDark(row, col);
98 | for (var r = -1; r <= 1; r++) {
99 | if (row + r < 0 || moduleCount <= row + r) continue;
100 | for (var c = -1; c <= 1; c++) {
101 | if (col + c < 0 || moduleCount <= col + c) continue;
102 | if (r == 0 && c == 0) continue;
103 | dark == qrCode.isDark(row + r, col + c) && sameCount++;
104 | }
105 | }
106 | sameCount > 5 && (lostPoint += 3 + sameCount - 5);
107 | }
108 | for (var row = 0; row < moduleCount - 1; row++) for (var col = 0; col < moduleCount - 1; col++) {
109 | var count = 0;
110 | qrCode.isDark(row, col) && count++, qrCode.isDark(row + 1, col) && count++, qrCode.isDark(row, col + 1) && count++, qrCode.isDark(row + 1, col + 1) && count++;
111 | if (count == 0 || count == 4) lostPoint += 3;
112 | }
113 | for (var row = 0; row < moduleCount; row++) for (var col = 0; col < moduleCount - 6; col++) qrCode.isDark(row, col) && !qrCode.isDark(row, col + 1) && qrCode.isDark(row, col + 2) && qrCode.isDark(row, col + 3) && qrCode.isDark(row, col + 4) && !qrCode.isDark(row, col + 5) && qrCode.isDark(row, col + 6) && (lostPoint += 40);
114 | for (var col = 0; col < moduleCount; col++) for (var row = 0; row < moduleCount - 6; row++) qrCode.isDark(row, col) && !qrCode.isDark(row + 1, col) && qrCode.isDark(row + 2, col) && qrCode.isDark(row + 3, col) && qrCode.isDark(row + 4, col) && !qrCode.isDark(row + 5, col) && qrCode.isDark(row + 6, col) && (lostPoint += 40);
115 | var darkCount = 0;
116 | for (var col = 0; col < moduleCount; col++) for (var row = 0; row < moduleCount; row++) qrCode.isDark(row, col) && darkCount++;
117 | var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
118 | return lostPoint += ratio * 10, lostPoint;
119 | }
120 |
121 |
122 | ///////////////////////////
123 | public static QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]];
124 |
125 | public static_isSupportCanvas() {
126 | return typeof CanvasRenderingContext2D != "undefined";
127 | }
128 |
129 | public static _getTypeNumber(sText, nCorrectLevel) {
130 | var nType = 1;
131 | var length =QRUtil._getUTF8Length(sText);
132 |
133 | for (var i = 0, len = QRUtil.QRCodeLimitLength.length; i <= len; i++) {
134 | var nLimit = 0;
135 |
136 | switch (nCorrectLevel) {
137 | case QRErrorCorrectLevel.L :
138 | nLimit = QRUtil.QRCodeLimitLength[i][0];
139 | break;
140 | case QRErrorCorrectLevel.M :
141 | nLimit = QRUtil.QRCodeLimitLength[i][1];
142 | break;
143 | case QRErrorCorrectLevel.Q :
144 | nLimit = QRUtil.QRCodeLimitLength[i][2];
145 | break;
146 | case QRErrorCorrectLevel.H :
147 | nLimit = QRUtil.QRCodeLimitLength[i][3];
148 | break;
149 | }
150 |
151 | if (length <= nLimit) {
152 | break;
153 | } else {
154 | nType++;
155 | }
156 | }
157 |
158 | if (nType > QRUtil.QRCodeLimitLength.length) {
159 | throw new Error("Too long data");
160 | }
161 |
162 | return nType;
163 | }
164 |
165 | public static _getUTF8Length(sText) {
166 | var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a');
167 | return replacedText.length + (replacedText.length != sText ? 3 : 0);
168 | }
169 | }
170 | }
--------------------------------------------------------------------------------