├── 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 | } --------------------------------------------------------------------------------