1/** 2 * EasyQRCodeJS 3 * 4 * Cross-browser QRCode generator for pure javascript. Support Dot style, Logo, Background image, Colorful, Title, etc. Support Angular, Vue.js, React framework. (Running with DOM on client side) 5 * 6 * Version 3.4.0 7 * 8 * @author [ [email protected] ] 9 * 10 * @see https://github.com/ushelp/EasyQRCodeJS 11 * @see http://www.easyproject.cn/easyqrcodejs/tryit.html 12 * @see https://github.com/ushelp/EasyQRCodeJS-NodeJS 13 * 14 * Copyright 2017 Ray, EasyProject 15 * Released under the MIT license 16 * 17 * [Support AMD, CMD, CommonJS/Node.js] 18 * 19 */ 20 ;(function() { 21 22 // å¯ç¨ä¸¥æ ¼æ¨¡å¼ 23 "use strict"; 24 25 // èªå®ä¹å±é¨ undefined åé 26 var undefined; 27 28 /** Node.js global æ£æµ. */ 29 var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; 30 31 /** `self` å鿣æµ. */ 32 var freeSelf = typeof self == 'object' && self && self.Object === Object && self; 33 34 /** å ¨å±å¯¹è±¡æ£æµ. */ 35 var root = freeGlobal || freeSelf || Function('return this')(); 36 37 /** `exports` å鿣æµ. */ 38 var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; 39 40 /** `module` å鿣æµ. */ 41 var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; 42 43 var _QRCode = root.QRCode; 44 45 var QRCode; 46 47 function QR8bitByte(data) { 48 this.mode = QRMode.MODE_8BIT_BYTE; 49 this.data = data; 50 this.parsedData = []; 51 52 // Added to support UTF-8 Characters 53 for (var i = 0, l = this.data.length; i < l; i++) { 54 var byteArray = []; 55 var code = this.data.charCodeAt(i); 56 57 if (code > 0x10000) { 58 byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18); 59 byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12); 60 byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6); 61 byteArray[3] = 0x80 | (code & 0x3F); 62 } else if (code > 0x800) { 63 byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12); 64 byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6); 65 byteArray[2] = 0x80 | (code & 0x3F); 66 } else if (code > 0x80) { 67 byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6); 68 byteArray[1] = 0x80 | (code & 0x3F); 69 } else { 70 byteArray[0] = code; 71 } 72 73 this.parsedData.push(byteArray); 74 } 75 76 this.parsedData = Array.prototype.concat.apply([], this.parsedData); 77 78 if (this.parsedData.length != this.data.length) { 79 this.parsedData.unshift(191); 80 this.parsedData.unshift(187); 81 this.parsedData.unshift(239); 82 } 83 } 84 85 QR8bitByte.prototype = { 86 getLength: function(buffer) { 87 return this.parsedData.length; 88 }, 89 write: function(buffer) { 90 for (var i = 0, l = this.parsedData.length; i < l; i++) { 91 buffer.put(this.parsedData[i], 8); 92 } 93 } 94 }; 95 96 function QRCodeModel(typeNumber, errorCorrectLevel) { 97 this.typeNumber = typeNumber; 98 this.errorCorrectLevel = errorCorrectLevel; 99 this.modules = null; 100 this.moduleCount = 0; 101 this.dataCache = null; 102 this.dataList = []; 103 } 104 105 QRCodeModel.prototype = { 106 addData: function(data) { 107 var newData = new QR8bitByte(data); 108 this.dataList.push(newData); 109 this.dataCache = null; 110 }, 111 isDark: function(row, col) { 112 if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) { 113 throw new Error(row + "," + col); 114 } 115 return this.modules[row][col][0]; 116 }, 117 getEye: function(row, col) { 118 if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) { 119 throw new Error(row + "," + col); 120 } 121 122 var block = this.modules[row][col]; // [isDark(ture/false), EyeOuterOrInner(O/I), Position(TL/TR/BL/A) ] 123 124 if (block[1]) { 125 var type = 'P' + block[1] + '_' + block[2]; //PO_TL, PI_TL, PO_TR, PI_TR, PO_BL, PI_BL 126 if (block[2] == 'A') { 127 type = 'A' + block[1]; // AI, AO 128 } 129 130 return { 131 isDark: block[0], 132 type: type 133 }; 134 } else { 135 return null; 136 } 137 }, 138 getModuleCount: function() { 139 return this.moduleCount; 140 }, 141 make: function() { 142 this.makeImpl(false, this.getBestMaskPattern()); 143 }, 144 makeImpl: function(test, maskPattern) { 145 this.moduleCount = this.typeNumber * 4 + 17; 146 this.modules = new Array(this.moduleCount); 147 for (var row = 0; row < this.moduleCount; row++) { 148 this.modules[row] = new Array(this.moduleCount); 149 for (var col = 0; col < this.moduleCount; col++) { 150 this.modules[row][col] = []; // [isDark(ture/false), EyeOuterOrInner(O/I), Position(TL/TR/BL) ] 151 } 152 } 153 this.setupPositionProbePattern(0, 0, 'TL'); // TopLeft, TL 154 this.setupPositionProbePattern(this.moduleCount - 7, 0, 'BL'); // BotoomLeft, BL 155 this.setupPositionProbePattern(0, this.moduleCount - 7, 'TR'); // TopRight, TR 156 this.setupPositionAdjustPattern('A'); // Alignment, A 157 this.setupTimingPattern(); 158 this.setupTypeInfo(test, maskPattern);
159 if (this.typeNumber >= 7) { 160 this.setupTypeNumber(test); 161 } 162 if (this.dataCache == null) { 163 this.dataCache = QRCodeModel.createData(this.typeNumber, this.errorCorrectLevel, this.dataList); 164 } 165 this.mapData(this.dataCache, maskPattern); 166 }, 167 setupPositionProbePattern: function(row, col, posName) { 168 for (var r = -1; r <= 7; r++) { 169 if (row + r <= -1 || this.moduleCount <= row + r) continue; 170 for (var c = -1; c <= 7; c++) { 171 if (col + c <= -1 || this.moduleCount <= col + c) continue; 172 if ((0 <= r && r <= 6 && (c == 0 || c == 6)) || (0 <= c && c <= 6 && (r == 0 || r == 6)) || (2 <= r && r <= 4 && 173 2 <= c && c <= 4)) { 174 this.modules[row + r][col + c][0] = true; 175 176 this.modules[row + r][col + c][2] = posName; // Position 177 if (r == -0 || c == -0 || r == 6 || c == 6) { 178 this.modules[row + r][col + c][1] = 'O'; // Position Outer 179 } else { 180 this.modules[row + r][col + c][1] = 'I'; // Position Inner 181 } 182 } else { 183 this.modules[row + r][col + c][0] = false; 184 } 185 } 186 } 187 }, 188 getBestMaskPattern: function() { 189 var minLostPoint = 0; 190 var pattern = 0; 191 for (var i = 0; i < 8; i++) { 192 this.makeImpl(true, i); 193 var lostPoint = QRUtil.getLostPoint(this); 194 if (i == 0 || minLostPoint > lostPoint) { 195 minLostPoint = lostPoint; 196 pattern = i; 197 } 198 } 199 return pattern; 200 }, 201 createMovieClip: function(target_mc, instance_name, depth) { 202 var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth); 203 var cs = 1; 204 this.make(); 205 for (var row = 0; row < this.modules.length; row++) { 206 var y = row * cs; 207 for (var col = 0; col < this.modules[row].length; col++) { 208 var x = col * cs; 209 var dark = this.modules[row][col][0]; 210 if (dark) { 211 qr_mc.beginFill(0, 100); 212 qr_mc.moveTo(x, y); 213 qr_mc.lineTo(x + cs, y); 214 qr_mc.lineTo(x + cs, y + cs); 215 qr_mc.lineTo(x, y + cs); 216 qr_mc.endFill(); 217 } 218 } 219 } 220 return qr_mc; 221 }, 222 setupTimingPattern: function() { 223 for (var r = 8; r < this.moduleCount - 8; r++) { 224 if (this.modules[r][6][0] != null) { 225 continue; 226 } 227 this.modules[r][6][0] = (r % 2 == 0); 228 } 229 for (var c = 8; c < this.moduleCount - 8; c++) { 230 if (this.modules[6][c][0] != null) { 231 continue; 232 } 233 this.modules[6][c][0] = (c % 2 == 0); 234 } 235 }, 236 setupPositionAdjustPattern: function(posName) { 237 var pos = QRUtil.getPatternPosition(this.typeNumber); 238 for (var i = 0; i < pos.length; i++) { 239 for (var j = 0; j < pos.length; j++) { 240 var row = pos[i]; 241 var col = pos[j]; 242 if (this.modules[row][col][0] != null) { 243 continue; 244 } 245 for (var r = -2; r <= 2; r++) { 246 for (var c = -2; c <= 2; c++) { 247 if (r == -2 || r == 2 || c == -2 || c == 2 || (r == 0 && c == 0)) { 248 this.modules[row + r][col + c][0] = true; 249 this.modules[row + r][col + c][2] = posName; // Position 250 if (r == -2 || c == -2 || r == 2 || c == 2) { 251 this.modules[row + r][col + c][1] = 'O'; // Position Outer 252 } else { 253 this.modules[row + r][col + c][1] = 'I'; // Position Inner 254 } 255 } else { 256 this.modules[row + r][col + c][0] = false; 257 } 258 } 259 } 260 } 261 } 262 }, 263 setupTypeNumber: function(test) { 264 var bits = QRUtil.getBCHTypeNumber(this.typeNumber); 265 for (var i = 0; i < 18; i++) { 266 var mod = (!test && ((bits >> i) & 1) == 1); 267 this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3][0] = mod; 268 } 269 for (var i = 0; i < 18; i++) { 270 var mod = (!test && ((bits >> i) & 1) == 1); 271 this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)][0] = mod; 272 } 273 }, 274 setupTypeInfo: function(test, maskPattern) { 275 var data = (this.errorCorrectLevel << 3) | maskPattern; 276 var bits = QRUtil.getBCHTypeInfo(data); 277 for (var i = 0; i < 15; i++) { 278 var mod = (!test && ((bits >> i) & 1) == 1); 279 if (i < 6) { 280 this.modules[i][8][0] = mod; 281 } else if (i < 8) { 282 this.modules[i + 1][8][0] = mod; 283 } else { 284 this.modules[this.moduleCount - 15 + i][8][0] = mod; 285 } 286 } 287 for (var i = 0; i < 15; i++) { 288 var mod = (!test && ((bits >> i) & 1) == 1); 289 if (i < 8) { 290 this.modules[8][this.moduleCount - i - 1][0] = mod; 291 } else if (i < 9) { 292 this.modules[8][15 - i - 1 + 1][0] = mod; 293 } else { 294 this.modules[8][15 - i - 1][0] = mod; 295 } 296 } 297 this.modules[this.moduleCount - 8][8][0] = (!test); 298 }, 299 mapData: function(data, maskPattern) { 300 var inc = -1; 301 var row = this.moduleCount - 1; 302 var bitIndex = 7; 303 var byteIndex = 0; 304 for (var col = this.moduleCount - 1; col > 0; col -= 2) { 305 if (col == 6) col--; 306 while (true) { 307 for (var c = 0; c < 2; c++) { 308 if (this.modules[row][col - c][0] == null) { 309 var dark = false;
vendor: 18,836 bytes, lines 310-1009
310 if (byteIndex < data.length) { 311 dark = (((data[byteIndex] >>> bitIndex) & 1) == 1); 312 } 313 var mask = QRUtil.getMask(maskPattern, row, col - c); 314 if (mask) { 315 dark = !dark; 316 } 317 this.modules[row][col - c][0] = dark; 318 bitIndex--; 319 if (bitIndex == -1) { 320 byteIndex++; 321 bitIndex = 7; 322 } 323 } 324 } 325 row += inc; 326 if (row < 0 || this.moduleCount <= row) { 327 row -= inc; 328 inc = -inc; 329 break; 330 } 331 } 332 } 333 } 334 }; 335 QRCodeModel.PAD0 = 0xEC; 336 QRCodeModel.PAD1 = 0x11; 337 QRCodeModel.createData = function(typeNumber, errorCorrectLevel, dataList) { 338 var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel); 339 var buffer = new QRBitBuffer(); 340 for (var i = 0; i < dataList.length; i++) { 341 var data = dataList[i]; 342 buffer.put(data.mode, 4); 343 buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber)); 344 data.write(buffer); 345 } 346 var totalDataCount = 0; 347 for (var i = 0; i < rsBlocks.length; i++) { 348 totalDataCount += rsBlocks[i].dataCount; 349 } 350 if (buffer.getLengthInBits() > totalDataCount * 8) { 351 throw new Error("code length overflow. (" + 352 buffer.getLengthInBits() + 353 ">" + 354 totalDataCount * 8 + 355 ")"); 356 } 357 if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) { 358 buffer.put(0, 4); 359 } 360 while (buffer.getLengthInBits() % 8 != 0) { 361 buffer.putBit(false); 362 } 363 while (true) { 364 if (buffer.getLengthInBits() >= totalDataCount * 8) { 365 break; 366 } 367 buffer.put(QRCodeModel.PAD0, 8); 368 if (buffer.getLengthInBits() >= totalDataCount * 8) { 369 break; 370 } 371 buffer.put(QRCodeModel.PAD1, 8); 372 } 373 return QRCodeModel.createBytes(buffer, rsBlocks); 374 }; 375 QRCodeModel.createBytes = function(buffer, rsBlocks) { 376 var offset = 0; 377 var maxDcCount = 0; 378 var maxEcCount = 0; 379 var dcdata = new Array(rsBlocks.length); 380 var ecdata = new Array(rsBlocks.length); 381 for (var r = 0; r < rsBlocks.length; r++) { 382 var dcCount = rsBlocks[r].dataCount; 383 var ecCount = rsBlocks[r].totalCount - dcCount; 384 maxDcCount = Math.max(maxDcCount, dcCount); 385 maxEcCount = Math.max(maxEcCount, ecCount); 386 dcdata[r] = new Array(dcCount); 387 for (var i = 0; i < dcdata[r].length; i++) { 388 dcdata[r][i] = 0xff & buffer.buffer[i + offset]; 389 } 390 offset += dcCount; 391 var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount); 392 var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1); 393 var modPoly = rawPoly.mod(rsPoly); 394 ecdata[r] = new Array(rsPoly.getLength() - 1); 395 for (var i = 0; i < ecdata[r].length; i++) { 396 var modIndex = i + modPoly.getLength() - ecdata[r].length; 397 ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0; 398 } 399 } 400 var totalCodeCount = 0; 401 for (var i = 0; i < rsBlocks.length; i++) { 402 totalCodeCount += rsBlocks[i].totalCount; 403 } 404 var data = new Array(totalCodeCount); 405 var index = 0; 406 for (var i = 0; i < maxDcCount; i++) { 407 for (var r = 0; r < rsBlocks.length; r++) { 408 if (i < dcdata[r].length) { 409 data[index++] = dcdata[r][i]; 410 } 411 } 412 } 413 for (var i = 0; i < maxEcCount; i++) { 414 for (var r = 0; r < rsBlocks.length; r++) { 415 if (i < ecdata[r].length) { 416 data[index++] = ecdata[r][i]; 417 } 418 } 419 } 420 return data; 421 }; 422 var QRMode = { 423 MODE_NUMBER: 1 << 0, 424 MODE_ALPHA_NUM: 1 << 1, 425 MODE_8BIT_BYTE: 1 << 2, 426 MODE_KANJI: 1 << 3 427 }; 428 var QRErrorCorrectLevel = { 429 L: 1, 430 M: 0, 431 Q: 3, 432 H: 2 433 }; 434 var QRMaskPattern = { 435 PATTERN000: 0, 436 PATTERN001: 1, 437 PATTERN010: 2, 438 PATTERN011: 3, 439 PATTERN100: 4, 440 PATTERN101: 5, 441 PATTERN110: 6, 442 PATTERN111: 7 443 }; 444 var QRUtil = { 445 PATTERN_POSITION_TABLE: [ 446 [], 447 [6, 18], 448 [6, 22], 449 [6, 26], 450 [6, 30], 451 [6, 34], 452 [6, 22, 38], 453 [6, 24, 42], 454 [6, 26, 46], 455 [6, 28, 50], 456 [6, 30, 54], 457 [6, 32, 58], 458 [6, 34, 62], 459 [6, 26, 46, 66], 460 [6, 26, 48, 70], 461 [6, 26, 50, 74], 462 [6, 30, 54, 78], 463 [6, 30, 56, 82], 464 [6, 30, 58, 86], 465 [6, 34, 62, 90], 466 [6, 28, 50, 72, 94], 467 [6, 26, 50, 74, 98], 468 [6, 30, 54, 78, 102], 469 [6, 28, 54, 80, 106], 470 [6, 32, 58, 84, 110], 471 [6, 30, 58, 86, 114], 472 [6, 34, 62, 90, 118], 473 [6, 26, 50, 74, 98, 122], 474 [6, 30, 54, 78, 102, 126], 475 [6, 26, 52, 78, 104, 130], 476 [6, 30, 56, 82, 108, 134], 477 [6, 34, 60, 86, 112, 138], 478 [6, 30, 58, 86, 114, 142], 479 [6, 34, 62, 90, 118, 146], 480 [6, 30, 54, 78, 102, 126, 150], 481 [6, 24, 50, 76, 102, 128, 154], 482 [6, 28, 54, 80, 106, 132, 158], 483 [6, 32, 58, 84, 110, 136, 162], 484 [6, 26, 54, 82, 110, 138, 166], 485 [6, 30, 58, 86, 114, 142, 170] 486 ], 487 G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0), 488 G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0), 489 G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1), 490 getBCHTypeInfo: function(data) { 491 var d = data << 10; 492 while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) { 493 d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15))); 494 } 495 return ((data << 10) | d) ^ QRUtil.G15_MASK; 496 }, 497 getBCHTypeNumber: function(data) { 498 var d = data << 12; 499 while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) { 500 d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18))); 501 } 502 return (data << 12) | d; 503 }, 504 getBCHDigit: function(data) { 505 var digit = 0; 506 while (data != 0) { 507 digit++; 508 data >>>= 1; 509 } 510 return digit; 511 }, 512 getPatternPosition: function(typeNumber) { 513 return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]; 514 }, 515 getMask: function(maskPattern, i, j) { 516 switch (maskPattern) { 517 case QRMaskPattern.PATTERN000: 518 return (i + j) % 2 == 0; 519 case QRMaskPattern.PATTERN001: 520 return i % 2 == 0; 521 case QRMaskPattern.PATTERN010: 522 return j % 3 == 0; 523 case QRMaskPattern.PATTERN011: 524 return (i + j) % 3 == 0; 525 case QRMaskPattern.PATTERN100: 526 return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0; 527 case QRMaskPattern.PATTERN101: 528 return (i * j) % 2 + (i * j) % 3 == 0; 529 case QRMaskPattern.PATTERN110: 530 return ((i * j) % 2 + (i * j) % 3) % 2 == 0; 531 case QRMaskPattern.PATTERN111: 532 return ((i * j) % 3 + (i + j) % 2) % 2 == 0; 533 default: 534 throw new Error("bad maskPattern:" + maskPattern); 535 } 536 }, 537 getErrorCorrectPolynomial: function(errorCorrectLength) { 538 var a = new QRPolynomial([1], 0); 539 for (var i = 0; i < errorCorrectLength; i++) { 540 a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0)); 541 } 542 return a; 543 }, 544 getLengthInBits: function(mode, type) { 545 if (1 <= type && type < 10) { 546 switch (mode) { 547 case QRMode.MODE_NUMBER: 548 return 10; 549 case QRMode.MODE_ALPHA_NUM: 550 return 9; 551 case QRMode.MODE_8BIT_BYTE: 552 return 8; 553 case QRMode.MODE_KANJI: 554 return 8; 555 default: 556 throw new Error("mode:" + mode); 557 } 558 } else if (type < 27) { 559 switch (mode) { 560 case QRMode.MODE_NUMBER: 561 return 12; 562 case QRMode.MODE_ALPHA_NUM: 563 return 11; 564 case QRMode.MODE_8BIT_BYTE: 565 return 16; 566 case QRMode.MODE_KANJI: 567 return 10; 568 default: 569 throw new Error("mode:" + mode); 570 } 571 } else if (type < 41) { 572 switch (mode) { 573 case QRMode.MODE_NUMBER: 574 return 14; 575 case QRMode.MODE_ALPHA_NUM: 576 return 13; 577 case QRMode.MODE_8BIT_BYTE: 578 return 16; 579 case QRMode.MODE_KANJI: 580 return 12; 581 default: 582 throw new Error("mode:" + mode); 583 } 584 } else { 585 throw new Error("type:" + type); 586 } 587 }, 588 getLostPoint: function(qrCode) { 589 var moduleCount = qrCode.getModuleCount(); 590 var lostPoint = 0; 591 for (var row = 0; row < moduleCount; row++) { 592 for (var col = 0; col < moduleCount; col++) { 593 var sameCount = 0; 594 var dark = qrCode.isDark(row, col); 595 for (var r = -1; r <= 1; r++) { 596 if (row + r < 0 || moduleCount <= row + r) { 597 continue; 598 } 599 for (var c = -1; c <= 1; c++) { 600 if (col + c < 0 || moduleCount <= col + c) { 601 continue; 602 } 603 if (r == 0 && c == 0) { 604 continue; 605 } 606 if (dark == qrCode.isDark(row + r, col + c)) { 607 sameCount++; 608 } 609 } 610 } 611 if (sameCount > 5) { 612 lostPoint += (3 + sameCount - 5); 613 } 614 } 615 } 616 for (var row = 0; row < moduleCount - 1; row++) { 617 for (var col = 0; col < moduleCount - 1; col++) { 618 var count = 0; 619 if (qrCode.isDark(row, col)) count++; 620 if (qrCode.isDark(row + 1, col)) count++; 621 if (qrCode.isDark(row, col + 1)) count++; 622 if (qrCode.isDark(row + 1, col + 1)) count++; 623 if (count == 0 || count == 4) { 624 lostPoint += 3; 625 } 626 } 627 } 628 for (var row = 0; row < moduleCount; row++) { 629 for (var col = 0; col < moduleCount - 6; col++) { 630 if (qrCode.isDark(row, col) && !qrCode.isDark(row, col + 1) && qrCode.isDark(row, col + 2) && qrCode.isDark( 631 row, 632 col + 3) && qrCode.isDark(row, col + 4) && !qrCode.isDark(row, col + 5) && qrCode.isDark(row, col + 6)) { 633 lostPoint += 40; 634 } 635 } 636 } 637 for (var col = 0; col < moduleCount; col++) { 638 for (var row = 0; row < moduleCount - 6; row++) { 639 if (qrCode.isDark(row, col) && !qrCode.isDark(row + 1, col) && qrCode.isDark(row + 2, col) && qrCode.isDark( 640 row + 641 3, col) && qrCode.isDark(row + 4, col) && !qrCode.isDark(row + 5, col) && qrCode.isDark(row + 6, col)) { 642 lostPoint += 40; 643 } 644 } 645 } 646 var darkCount = 0; 647 for (var col = 0; col < moduleCount; col++) { 648 for (var row = 0; row < moduleCount; row++) { 649 if (qrCode.isDark(row, col)) { 650 darkCount++; 651 } 652 } 653 } 654 var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; 655 lostPoint += ratio * 10; 656 return lostPoint; 657 } 658 }; 659 var QRMath = { 660 glog: function(n) { 661 if (n < 1) { 662 throw new Error("glog(" + n + ")"); 663 } 664 return QRMath.LOG_TABLE[n]; 665 }, 666 gexp: function(n) { 667 while (n < 0) { 668 n += 255; 669 } 670 while (n >= 256) { 671 n -= 255; 672 } 673 return QRMath.EXP_TABLE[n]; 674 }, 675 EXP_TABLE: new Array(256), 676 LOG_TABLE: new Array(256) 677 }; 678 for (var i = 0; i < 8; i++) { 679 QRMath.EXP_TABLE[i] = 1 << i; 680 } 681 for (var i = 8; i < 256; i++) { 682 QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^ QRMath.EXP_TABLE[i - 5] ^ QRMath.EXP_TABLE[i - 6] ^ QRMath.EXP_TABLE[ 683 i - 8]; 684 } 685 for (var i = 0; i < 255; i++) { 686 QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i; 687 } 688 689 function QRPolynomial(num, shift) { 690 if (num.length == undefined) { 691 throw new Error(num.length + "/" + shift); 692 } 693 var offset = 0; 694 while (offset < num.length && num[offset] == 0) { 695 offset++; 696 } 697 this.num = new Array(num.length - offset + shift); 698 for (var i = 0; i < num.length - offset; i++) { 699 this.num[i] = num[i + offset]; 700 } 701 } 702 QRPolynomial.prototype = { 703 get: function(index) { 704 return this.num[index]; 705 }, 706 getLength: function() { 707 return this.num.length; 708 }, 709 multiply: function(e) { 710 var num = new Array(this.getLength() + e.getLength() - 1); 711 for (var i = 0; i < this.getLength(); i++) { 712 for (var j = 0; j < e.getLength(); j++) { 713 num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j))); 714 } 715 } 716 return new QRPolynomial(num, 0); 717 }, 718 mod: function(e) { 719 if (this.getLength() - e.getLength() < 0) { 720 return this; 721 } 722 var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0)); 723 var num = new Array(this.getLength()); 724 for (var i = 0; i < this.getLength(); i++) { 725 num[i] = this.get(i); 726 } 727 for (var i = 0; i < e.getLength(); i++) { 728 num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio); 729 } 730 return new QRPolynomial(num, 0).mod(e); 731 } 732 }; 733 734 function QRRSBlock(totalCount, dataCount) { 735 this.totalCount = totalCount; 736 this.dataCount = dataCount; 737 } 738 QRRSBlock.RS_BLOCK_TABLE = [ 739 [1, 26, 19], 740 [1, 26, 16], 741 [1, 26, 13], 742 [1, 26, 9], 743 [1, 44, 34], 744 [1, 44, 28], 745 [1, 44, 22], 746 [1, 44, 16], 747 [1, 70, 55], 748 [1, 70, 44], 749 [2, 35, 17], 750 [2, 35, 13], 751 [1, 100, 80], 752 [2, 50, 32], 753 [2, 50, 24], 754 [4, 25, 9], 755 [1, 134, 108], 756 [2, 67, 43], 757 [2, 33, 15, 2, 34, 16], 758 [2, 33, 11, 2, 34, 12], 759 [2, 86, 68], 760 [4, 43, 27], 761 [4, 43, 19], 762 [4, 43, 15], 763 [2, 98, 78], 764 [4, 49, 31], 765 [2, 32, 14, 4, 33, 15], 766 [4, 39, 13, 1, 40, 14], 767 [2, 121, 97], 768 [2, 60, 38, 2, 61, 39], 769 [4, 40, 18, 2, 41, 19], 770 [4, 40, 14, 2, 41, 15], 771 [2, 146, 116], 772 [3, 58, 36, 2, 59, 37], 773 [4, 36, 16, 4, 37, 17], 774 [4, 36, 12, 4, 37, 13], 775 [2, 86, 68, 2, 87, 69], 776 [4, 69, 43, 1, 70, 44], 777 [6, 43, 19, 2, 44, 20], 778 [6, 43, 15, 2, 44, 16], 779 [4, 101, 81], 780 [1, 80, 50, 4, 81, 51], 781 [4, 50, 22, 4, 51, 23], 782 [3, 36, 12, 8, 37, 13], 783 [2, 116, 92, 2, 117, 93], 784 [6, 58, 36, 2, 59, 37], 785 [4, 46, 20, 6, 47, 21], 786 [7, 42, 14, 4, 43, 15], 787 [4, 133, 107], 788 [8, 59, 37, 1, 60, 38], 789 [8, 44, 20, 4, 45, 21], 790 [12, 33, 11, 4, 34, 12], 791 [3, 145, 115, 1, 146, 116], 792 [4, 64, 40, 5, 65, 41], 793 [11, 36, 16, 5, 37, 17], 794 [11, 36, 12, 5, 37, 13], 795 [5, 109, 87, 1, 110, 88], 796 [5, 65, 41, 5, 66, 42], 797 [5, 54, 24, 7, 55, 25], 798 [11, 36, 12], 799 [5, 122, 98, 1, 123, 99], 800 [7, 73, 45, 3, 74, 46], 801 [15, 43, 19, 2, 44, 20], 802 [3, 45, 15, 13, 46, 16], 803 [1, 135, 107, 5, 136, 108], 804 [10, 74, 46, 1, 75, 47], 805 [1, 50, 22, 15, 51, 23], 806 [2, 42, 14, 17, 43, 15], 807 [5, 150, 120, 1, 151, 121], 808 [9, 69, 43, 4, 70, 44], 809 [17, 50, 22, 1, 51, 23], 810 [2, 42, 14, 19, 43, 15], 811 [3, 141, 113, 4, 142, 114], 812 [3, 70, 44, 11, 71, 45], 813 [17, 47, 21, 4, 48, 22], 814 [9, 39, 13, 16, 40, 14], 815 [3, 135, 107, 5, 136, 108], 816 [3, 67, 41, 13, 68, 42], 817 [15, 54, 24, 5, 55, 25], 818 [15, 43, 15, 10, 44, 16], 819 [4, 144, 116, 4, 145, 117], 820 [17, 68, 42], 821 [17, 50, 22, 6, 51, 23], 822 [19, 46, 16, 6, 47, 17], 823 [2, 139, 111, 7, 140, 112], 824 [17, 74, 46], 825 [7, 54, 24, 16, 55, 25], 826 [34, 37, 13], 827 [4, 151, 121, 5, 152, 122], 828 [4, 75, 47, 14, 76, 48], 829 [11, 54, 24, 14, 55, 25], 830 [16, 45, 15, 14, 46, 16], 831 [6, 147, 117, 4, 148, 118], 832 [6, 73, 45, 14, 74, 46], 833 [11, 54, 24, 16, 55, 25], 834 [30, 46, 16, 2, 47, 17], 835 [8, 132, 106, 4, 133, 107], 836 [8, 75, 47, 13, 76, 48], 837 [7, 54, 24, 22, 55, 25], 838 [22, 45, 15, 13, 46, 16], 839 [10, 142, 114, 2, 143, 115], 840 [19, 74, 46, 4, 75, 47], 841 [28, 50, 22, 6, 51, 23], 842 [33, 46, 16, 4, 47, 17], 843 [8, 152, 122, 4, 153, 123], 844 [22, 73, 45, 3, 74, 46], 845 [8, 53, 23, 26, 54, 24], 846 [12, 45, 15, 28, 46, 16], 847 [3, 147, 117, 10, 148, 118], 848 [3, 73, 45, 23, 74, 46], 849 [4, 54, 24, 31, 55, 25], 850 [11, 45, 15, 31, 46, 16], 851 [7, 146, 116, 7, 147, 117], 852 [21, 73, 45, 7, 74, 46], 853 [1, 53, 23, 37, 54, 24], 854 [19, 45, 15, 26, 46, 16], 855 [5, 145, 115, 10, 146, 116], 856 [19, 75, 47, 10, 76, 48], 857 [15, 54, 24, 25, 55, 25], 858 [23, 45, 15, 25, 46, 16], 859 [13, 145, 115, 3, 146, 116], 860 [2, 74, 46, 29, 75, 47], 861 [42, 54, 24, 1, 55, 25], 862 [23, 45, 15, 28, 46, 16], 863 [17, 145, 115], 864 [10, 74, 46, 23, 75, 47], 865 [10, 54, 24, 35, 55, 25], 866 [19, 45, 15, 35, 46, 16], 867 [17, 145, 115, 1, 146, 116], 868 [14, 74, 46, 21, 75, 47], 869 [29, 54, 24, 19, 55, 25], 870 [11, 45, 15, 46, 46, 16], 871 [13, 145, 115, 6, 146, 116], 872 [14, 74, 46, 23, 75, 47], 873 [44, 54, 24, 7, 55, 25], 874 [59, 46, 16, 1, 47, 17], 875 [12, 151, 121, 7, 152, 122], 876 [12, 75, 47, 26, 76, 48], 877 [39, 54, 24, 14, 55, 25], 878 [22, 45, 15, 41, 46, 16], 879 [6, 151, 121, 14, 152, 122], 880 [6, 75, 47, 34, 76, 48], 881 [46, 54, 24, 10, 55, 25], 882 [2, 45, 15, 64, 46, 16], 883 [17, 152, 122, 4, 153, 123], 884 [29, 74, 46, 14, 75, 47], 885 [49, 54, 24, 10, 55, 25], 886 [24, 45, 15, 46, 46, 16], 887 [4, 152, 122, 18, 153, 123], 888 [13, 74, 46, 32, 75, 47], 889 [48, 54, 24, 14, 55, 25], 890 [42, 45, 15, 32, 46, 16], 891 [20, 147, 117, 4, 148, 118], 892 [40, 75, 47, 7, 76, 48], 893 [43, 54, 24, 22, 55, 25], 894 [10, 45, 15, 67, 46, 16], 895 [19, 148, 118, 6, 149, 119], 896 [18, 75, 47, 31, 76, 48], 897 [34, 54, 24, 34, 55, 25], 898 [20, 45, 15, 61, 46, 16] 899 ]; 900 QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) { 901 var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel); 902 if (rsBlock == undefined) { 903 throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel); 904 } 905 var length = rsBlock.length / 3; 906 var list = []; 907 for (var i = 0; i < length; i++) { 908 var count = rsBlock[i * 3 + 0]; 909 var totalCount = rsBlock[i * 3 + 1]; 910 var dataCount = rsBlock[i * 3 + 2]; 911 for (var j = 0; j < count; j++) { 912 list.push(new QRRSBlock(totalCount, dataCount)); 913 } 914 } 915 return list; 916 }; 917 QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) { 918 switch (errorCorrectLevel) { 919 case QRErrorCorrectLevel.L: 920 return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]; 921 case QRErrorCorrectLevel.M: 922 return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]; 923 case QRErrorCorrectLevel.Q: 924 return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]; 925 case QRErrorCorrectLevel.H: 926 return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]; 927 default: 928 return undefined; 929 } 930 }; 931 932 function QRBitBuffer() { 933 this.buffer = []; 934 this.length = 0; 935 } 936 QRBitBuffer.prototype = { 937 get: function(index) { 938 var bufIndex = Math.floor(index / 8); 939 return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) == 1; 940 }, 941 put: function(num, length) { 942 for (var i = 0; i < length; i++) { 943 this.putBit(((num >>> (length - i - 1)) & 1) == 1); 944 } 945 }, 946 getLengthInBits: function() { 947 return this.length; 948 }, 949 putBit: function(bit) { 950 var bufIndex = Math.floor(this.length / 8); 951 if (this.buffer.length <= bufIndex) { 952 this.buffer.push(0); 953 } 954 if (bit) { 955 this.buffer[bufIndex] |= (0x80 >>> (this.length % 8)); 956 } 957 this.length++; 958 } 959 }; 960 var QRCodeLimitLength = [ 961 [17, 14, 11, 7], 962 [32, 26, 20, 14], 963 [53, 42, 32, 24], 964 [78, 62, 46, 34], 965 [106, 84, 60, 44], 966 [134, 106, 74, 58], 967 [154, 122, 86, 64], 968 [192, 152, 108, 84], 969 [230, 180, 130, 98], 970 [271, 213, 151, 119], 971 [321, 251, 177, 137], 972 [367, 287, 203, 155], 973 [425, 331, 241, 177], 974 [458, 362, 258, 194], 975 [520, 412, 292, 220], 976 [586, 450, 322, 250], 977 [644, 504, 364, 280], 978 [718, 560, 394, 310], 979 [792, 624, 442, 338], 980 [858, 666, 482, 382], 981 [929, 711, 509, 403], 982 [1003, 779, 565, 439], 983 [1091, 857, 611, 461], 984 [1171, 911, 661, 511], 985 [1273, 997, 715, 535], 986 [1367, 1059, 751, 593], 987 [1465, 1125, 805, 625], 988 [1528, 1190, 868, 658], 989 [1628, 1264, 908, 698], 990 [1732, 1370, 982, 742], 991 [1840, 1452, 1030, 790], 992 [1952, 1538, 1112, 842], 993 [2068, 1628, 1168, 898], 994 [2188, 1722, 1228, 958], 995 [2303, 1809, 1283, 983], 996 [2431, 1911, 1351, 1051], 997 [2563, 1989, 1423, 1093], 998 [2699, 2099, 1499, 1139], 999 [2809, 2213, 1579, 1219], 1000 [2953, 2331, 1663, 1273] 1001 ]; 1002 1003 function _isSupportCanvas() { 1004 return typeof CanvasRenderingContext2D != "undefined"; 1005 } 1006 1007 // android 2.x doesn't support Data-URI spec 1008 function _getAndroid() { 1009 var android = false;
1010 var sAgent = navigator.userAgent; 1011 1012 if (/android/i.test(sAgent)) { // android 1013 android = true; 1014 var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i); 1015 1016 if (aMat && aMat[1]) { 1017 android = parseFloat(aMat[1]); 1018 } 1019 } 1020 1021 return android; 1022 } 1023 1024 var svgDrawer = (function() { 1025 1026 var Drawing = function(el, htOption) { 1027 this._el = el; 1028 this._htOption = htOption; 1029 }; 1030 1031 Drawing.prototype.draw = function(oQRCode) { 1032 var _htOption = this._htOption; 1033 var _el = this._el; 1034 var nCount = oQRCode.getModuleCount(); 1035 var nWidth = Math.floor(_htOption.width / nCount); 1036 var nHeight = Math.floor(_htOption.height / nCount); 1037 1038 this.clear(); 1039 1040 function makeSVG(tag, attrs) { 1041 var el = document.createElementNS('http://www.w3.org/2000/svg', tag); 1042 for (var k in attrs) 1043 if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]); 1044 return el; 1045 } 1046 1047 var svg = makeSVG("svg", { 1048 'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 1049 'width': '100%', 1050 'height': '100%', 1051 'fill': _htOption.colorLight 1052 }); 1053 svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink"); 1054 _el.appendChild(svg); 1055 1056 svg.appendChild(makeSVG("rect", { 1057 "fill": _htOption.colorLight, 1058 "width": "100%", 1059 "height": "100%" 1060 })); 1061 svg.appendChild(makeSVG("rect", { 1062 "fill": _htOption.colorDark, 1063 "width": "1", 1064 "height": "1", 1065 "id": "template" 1066 })); 1067 1068 for (var row = 0; row < nCount; row++) { 1069 for (var col = 0; col < nCount; col++) { 1070 if (oQRCode.isDark(row, col)) { 1071 var child = makeSVG("use", { 1072 "x": String(col), 1073 "y": String(row) 1074 }); 1075 child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template") 1076 svg.appendChild(child); 1077 } 1078 } 1079 } 1080 }; 1081 Drawing.prototype.clear = function() { 1082 while (this._el.hasChildNodes()) 1083 this._el.removeChild(this._el.lastChild); 1084 }; 1085 return Drawing; 1086 })(); 1087 1088 var useSVG = document.documentElement.tagName.toLowerCase() === "svg"; 1089 1090 // Drawing in DOM by using Table tag 1091 var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function() { 1092 var Drawing = function(el, htOption) { 1093 this._el = el; 1094 this._htOption = htOption; 1095 }; 1096 1097 /** 1098 * Draw the QRCode 1099 * 1100 * @param {QRCode} oQRCode 1101 */ 1102 Drawing.prototype.draw = function(oQRCode) { 1103 var _htOption = this._htOption; 1104 var _el = this._el; 1105 var nCount = oQRCode.getModuleCount(); 1106 var nWidth = Math.round(_htOption.width / nCount); 1107 var nHeight = Math.round((_htOption.height - _htOption.titleHeight) / nCount); 1108 1109 this._htOption.width = nWidth * nCount; 1110 this._htOption.height = nHeight * nCount + _htOption.titleHeight; 1111 1112 this._htOption.quietZone = Math.round(this._htOption.quietZone); 1113 1114 1115 var aHTML = []; 1116 1117 var divStyle = ''; 1118 1119 var drawWidth = Math.round(nWidth * _htOption.dotScale); 1120 var drawHeight = Math.round(nHeight * _htOption.dotScale); 1121 if (drawWidth < 4) { 1122 drawWidth = 4; 1123 drawHeight = 4; 1124 } 1125 1126 var nonRequiredColorDark = _htOption.colorDark; 1127 var nonRequiredcolorLight = _htOption.colorLight; 1128 if (_htOption.backgroundImage) { 1129 if (_htOption.autoColor) { 1130 _htOption.colorDark = 1131 "rgba(0, 0, 0, .6);filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr='#99000000', EndColorStr='#99000000');"; 1132 _htOption.colorLight = 1133 "rgba(255, 255, 255, .7);filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr='#B2FFFFFF', EndColorStr='#B2FFFFFF');"; 1134 1135 // _htOption.colorDark="rgba(0, 0, 0, .6)"; 1136 // _htOption.colorLight='rgba(255, 255, 255, .7)'; 1137 } else { 1138 _htOption.colorLight = 'transparent'; 1139 } 1140 1141 1142 var backgroundImageEle = '<div style="display:inline-block; z-index:-10;position:absolute;"><img src="' + 1143 _htOption.backgroundImage + '" widht="' + (_htOption.width + _htOption.quietZone * 2) + '" height="' + ( 1144 _htOption.height + _htOption.quietZone * 2) + '" style="opacity:' + _htOption.backgroundImageAlpha + 1145 ';filter:alpha(opacity=' + (_htOption.backgroundImageAlpha * 100) + '); "/></div>'; 1146 aHTML.push(backgroundImageEle); 1147 } 1148 1149 if (_htOption.quietZone) { 1150 divStyle = 'padding:' + _htOption.quietZone + 'px; display:inline-block; width:' + (_htOption.width + 1151 _htOption.quietZone * 2) + 'px; height:' + (_htOption.width + 1152 _htOption.quietZone * 2) + 'px;background:'+_htOption.quietZoneColor+'; text-align:center;'; 1153 } 1154 aHTML.push('<div style="font-size:0;' + divStyle + '">'); 1155 1156 aHTML.push( 1157 '<table style="font-size:0;border:0;border-collapse:collapse; margin-top:0;" border="0" cellspacing="0" cellspadding="0" align="center" valign="middle">' 1158 ); 1159 aHTML.push('<tr height="' + _htOption.titleHeight + 1160 '" align="center"><td style="border:0;border-collapse:collapse;margin:0;padding:0" colspan="' + nCount + 1161 '">') 1162 if (_htOption.title) { 1163 var c = _htOption.titleColor; 1164 var f = _htOption.titleFont; 1165 aHTML.push('<div style="width:100%;margin-top:' + _htOption.titleTop + 'px;color:' + c + ';font:' + f + 1166 ';
1166background:' + _htOption.titleBackgroundColor + '">' + 1167 _htOption.title + '</div>'); 1168 } 1169 if (_htOption.subTitle) { 1170 aHTML.push('<div style="width:100%;margin-top:' + (_htOption.subTitleTop - _htOption.titleTop) + 'px;color:' + 1171 _htOption.subTitleColor + '; font:' + _htOption.subTitleFont + 1172 '">' + _htOption.subTitle + '</div>'); 1173 } 1174 aHTML.push('</td></tr>') 1175 for (var row = 0; row < nCount; row++) { 1176 aHTML.push('<tr style="border:0; padding:0; margin:0;" height="7">'); 1177 1178 for (var col = 0; col < nCount; col++) { 1179 1180 var bIsDark = oQRCode.isDark(row, col); 1181 1182 var eye = oQRCode.getEye(row, col); // { isDark: true/false, type: PO_TL, PI_TL, PO_TR, PI_TR, PO_BL, PI_BL }; 1183 1184 if (eye) { 1185 // Is eye 1186 bIsDark = eye.isDark; 1187 var type = eye.type; 1188 1189 // PX_XX, PX, colorDark, colorLight 1190 var eyeColorDark = _htOption[type] || _htOption[type.substring(0, 2)] || nonRequiredColorDark; 1191 aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth + 'px;height:' + 1192 nHeight + 'px;">' + 1193 '<span style="width:' + nWidth + 'px;height:' + nHeight + 'px;background-color:' + (bIsDark ? 1194 eyeColorDark : nonRequiredcolorLight) + ';display:inline-block"></span></td>'); 1195 1196 } else { 1197 1198 // Timing Pattern 1199 var nowDarkColor = _htOption.colorDark; 1200 if (row == 6) { 1201 nowDarkColor = _htOption.timing_H || _htOption.timing || nonRequiredColorDark; 1202 aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth + 1203 'px;height:' + 1204 nHeight + 'px;background-color:' + (bIsDark ? nowDarkColor : nonRequiredcolorLight) + 1205 ';"></td>'); 1206 } else if (col == 6) { 1207 nowDarkColor = _htOption.timing_V || _htOption.timing || nonRequiredColorDark; 1208 1209 aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth + 1210 'px;height:' + 1211 nHeight + 'px;background-color:' + (bIsDark ? nowDarkColor : nonRequiredcolorLight) + 1212 ';"></td>'); 1213 1214 } else { 1215 aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth + 1216 'px;height:' + 1217 nHeight + 'px;">' + 1218 '<div style="display:inline-block;width:' + drawWidth + 'px;height:' + drawHeight + 1219 'px;background-color:' + (bIsDark ? nowDarkColor : _htOption.colorLight) + 1220 ';"></div></td>'); 1221 } 1222 1223 1224 1225 1226 } 1227 1228 1229 } 1230 1231 aHTML.push('</tr>'); 1232 } 1233 1234 1235 aHTML.push('</table>'); 1236 aHTML.push('</div>'); 1237 1238 if (_htOption.logo) { 1239 var img = new Image(); 1240 //img.crossOrigin="Anonymous"; 1241 img.src = _htOption.logo; 1242 1243 var imgW = _htOption.width / 3.5; 1244 var imgH = _htOption.height / 3.5; 1245 if (imgW != imgH) { 1246 imgW = imgH; 1247 } 1248 1249 if (_htOption.logoWidth) { 1250 imgW = _htOption.logoWidth; 1251 } 1252 if (_htOption.logoHeight) { 1253 imgH = _htOption.logoHeight; 1254 } 1255 1256 var imgDivStyle = 'position:relative; z-index:1;display:inline-block;top:-' + ((_htOption.height - _htOption.titleHeight) / 1257 2 + imgH / 2 + _htOption.quietZone) + 'px;text-align:center; width:' + imgW + 'px; height:' + imgH + 'px;'; 1258 if (!_htOption.logoBackgroundTransparent) { 1259 imgDivStyle += 'background:' + _htOption.logoBackgroundColor; 1260 } 1261 aHTML.push('<div style="' + imgDivStyle + '"><img src="' + _htOption.logo + '" width="' + imgW + 1262 '" height="' + 1263 imgH + '" style="" /></div>') 1264 } 1265 1266 1267 1268 if (_htOption.onRenderingStart) { 1269 _htOption.onRenderingStart(_htOption) 1270 } 1271 1272 _el.innerHTML = aHTML.join(''); 1273 // Fix the margin values as real size. 1274 var elTable = _el.childNodes[0]; 1275 var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2; 1276 var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2; 1277 if (nLeftMarginTable > 0 && nTopMarginTable > 0) { 1278 elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px"; 1279 } 1280 }; 1281 1282 /** 1283 * Clear the QRCode 1284 */ 1285 Drawing.prototype.clear = function() { 1286 this._el.innerHTML = ''; 1287 }; 1288 1289 return Drawing; 1290 })() : (function() { // Drawing in Canvas 1291 function _onMakeImage() { 1292 //this._elImage.crossOrigin='Anonymous'; 1293 this._elImage.src = this._elCanvas.toDataURL("image/png"); 1294 this._elImage.style.display = "inline"; 1295 this._elCanvas.style.display = "none"; 1296 } 1297 1298 // Android 2.1 bug workaround 1299 // http://code.google.com/p/android/issues/detail?id=5141 1300 if (root._android && root._android <= 2.1) { 1301 var factor = 1 / window.devicePixelRatio; 1302 var drawImage = CanvasRenderingContext2D.prototype.drawImage; 1303 CanvasRenderingContext2D.prototype.drawImage = function(image, sx, sy, sw, sh, dx, dy, dw, dh) {
1304 if (("nodeName" in image) && /img/i.test(image.nodeName)) { 1305 for (var i = arguments.length - 1; i >= 1; i--) { 1306 arguments[i] = arguments[i] * factor; 1307 } 1308 } else if (typeof dw == "undefined") { 1309 arguments[1] *= factor; 1310 arguments[2] *= factor; 1311 arguments[3] *= factor; 1312 arguments[4] *= factor; 1313 } 1314 1315 drawImage.apply(this, arguments); 1316 }; 1317 } 1318 1319 /** 1320 * Check whether the user's browser supports Data URI or not 1321 * 1322 * @private 1323 * @param {Function} fSuccess Occurs if it supports Data URI 1324 * @param {Function} fFail Occurs if it doesn't support Data URI 1325 */ 1326 function _safeSetDataURI(fSuccess, fFail) { 1327 var self = this; 1328 self._fFail = fFail; 1329 self._fSuccess = fSuccess; 1330 1331 // Check it just once 1332 if (self._bSupportDataURI === null) { 1333 var el = document.createElement("img"); 1334 var fOnError = function() { 1335 self._bSupportDataURI = false; 1336 1337 if (self._fFail) { 1338 self._fFail.call(self); 1339 } 1340 }; 1341 var fOnSuccess = function() { 1342 self._bSupportDataURI = true; 1343 1344 if (self._fSuccess) { 1345 self._fSuccess.call(self); 1346 } 1347 }; 1348 1349 el.onabort = fOnError; 1350 el.onerror = fOnError; 1351 el.onload = fOnSuccess; 1352 el.src = 1353 "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data. 1354 return; 1355 } else if (self._bSupportDataURI === true && self._fSuccess) { 1356 self._fSuccess.call(self); 1357 } else if (self._bSupportDataURI === false && self._fFail) { 1358 self._fFail.call(self); 1359 } 1360 }; 1361 1362 /** 1363 * Drawing QRCode by using canvas 1364 * 1365 * @constructor 1366 * @param {HTMLElement} el 1367 * @param {Object} htOption QRCode Options 1368 */ 1369 var Drawing = function(el, htOption) { 1370 this._bIsPainted = false; 1371 this._android = _getAndroid(); 1372 1373 this._htOption = htOption; 1374 this._elCanvas = document.createElement("canvas"); 1375 //this._elCanvas.width = htOption.width; 1376 //this._elCanvas.height = htOption.height; 1377 el.appendChild(this._elCanvas); 1378 this._el = el; 1379 this._oContext = this._elCanvas.getContext("2d"); 1380 this._bIsPainted = false; 1381 this._elImage = document.createElement("img"); 1382 this._elImage.alt = "Scan me!"; 1383 this._elImage.style.display = "none"; 1384 this._el.appendChild(this._elImage); 1385 1386 this._bSupportDataURI = null; 1387 }; 1388 1389 /** 1390 * Draw the QRCode 1391 * 1392 * @param {QRCode} oQRCode 1393 */ 1394 Drawing.prototype.draw = function(oQRCode) { 1395 1396 var _elImage = this._elImage; 1397 var _oContext = this._oContext; 1398 var _htOption = this._htOption; 1399 1400 1401 if (!_htOption.title && !_htOption.subTitle) { 1402 _htOption.height -= _htOption.titleHeight; 1403 _htOption.titleHeight = 0; 1404 } 1405 1406 1407 var nCount = oQRCode.getModuleCount(); 1408 var nWidth = Math.round(_htOption.width / nCount); 1409 var nHeight = Math.round((_htOption.height - _htOption.titleHeight) / nCount); 1410 1411 this._htOption.width = nWidth * nCount; 1412 this._htOption.height = nHeight * nCount + _htOption.titleHeight; 1413 1414 this._htOption.quietZone = Math.round(this._htOption.quietZone); 1415 1416 1417 this._elCanvas.width = this._htOption.width + this._htOption.quietZone * 2; 1418 this._elCanvas.height = this._htOption.height + this._htOption.quietZone * 2; 1419 1420 1421 1422 _elImage.style.display = "none"; 1423 this.clear(); 1424 1425 var t = this; 1426 1427 function drawQuietZoneColor(){ 1428 // top 1429 _oContext.lineWidth = 0; 1430 _oContext.fillStyle = _htOption.quietZoneColor; 1431 _oContext.fillRect(0, 0, t._elCanvas.width, _htOption.quietZone); 1432 // left 1433 _oContext.fillRect(0, _htOption.quietZone, _htOption.quietZone, t._elCanvas.height-_htOption.quietZone*2); 1434 // right 1435 _oContext.fillRect(t._elCanvas.width-_htOption.quietZone, _htOption.quietZone, _htOption.quietZone, t._elCanvas.height-_htOption.quietZone*2); 1436 // bottom 1437 _oContext.fillRect(0, t._elCanvas.height-_htOption.quietZone, t._elCanvas.width, _htOption.quietZone); 1438 } 1439 1440 if (_htOption.backgroundImage) { 1441 1442 // backgroundImage 1443 var bgImg = new Image(); 1444 1445 bgImg.onload = function() { 1446 _oContext.globalAlpha = 1; 1447 1448 _oContext.globalAlpha = _htOption.backgroundImageAlpha; 1449 1450 _oContext.drawImage(bgImg, 0, _htOption.titleHeight, _htOption.width + _htOption.quietZone * 2, _htOption.height + 1451 _htOption.quietZone * 2 - _htOption.titleHeight); 1452 _oContext.globalAlpha = 1; 1453 1454 1455 drawQrcode.call(t, oQRCode); 1456 } 1457 //bgImg.crossOrigin='Anonymous'; 1458 bgImg.src = _htOption.backgroundImage; 1459 // DoSomething 1460 } else { 1461 drawQrcode.call(t, oQRCode); 1462 } 1463
1464 function drawQrcode(oQRCode) { 1465 if (_htOption.onRenderingStart) { 1466 _htOption.onRenderingStart(_htOption) 1467 } 1468 1469 for (var row = 0; row < nCount; row++) { 1470 for (var col = 0; col < nCount; col++) { 1471 var nLeft = col * nWidth + _htOption.quietZone; 1472 var nTop = row * nHeight + _htOption.quietZone; 1473 1474 var bIsDark = oQRCode.isDark(row, col); 1475 1476 var eye = oQRCode.getEye(row, col); // { isDark: true/false, type: PO_TL, PI_TL, PO_TR, PI_TR, PO_BL, PI_BL }; 1477 1478 if (eye) { 1479 // Is eye 1480 bIsDark = eye.isDark; 1481 var type = eye.type; 1482 1483 // PX_XX, PX, colorDark, colorLight 1484 var eyeColorDark = _htOption[type] || _htOption[type.substring(0, 2)] || _htOption.colorDark; 1485 1486 _oContext.lineWidth = 0; 1487 _oContext.strokeStyle = bIsDark ? eyeColorDark : _htOption.colorLight; 1488 _oContext.fillStyle = bIsDark ? eyeColorDark : _htOption.colorLight; 1489 1490 _oContext.fillRect(nLeft, _htOption.titleHeight + nTop, nWidth, nHeight); 1491 1492 } else { 1493 _oContext.lineWidth = 0; 1494 _oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; 1495 _oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; 1496 1497 var nowDotScale = _htOption.dotScale; 1498 if (row == 6) { 1499 // Timing Pattern 1500 nowDotScale = 1; 1501 var timingHColorDark = _htOption.timing_H || _htOption.timing || _htOption.colorDark; 1502 _oContext.fillStyle = bIsDark ? timingHColorDark : _htOption.colorLight; 1503 _oContext.strokeStyle = _oContext.fillStyle; 1504 _oContext.fillRect(nLeft + nWidth * (1 - nowDotScale) / 2, _htOption.titleHeight + nTop + nHeight * (1 - 1505 nowDotScale) / 2, nWidth * nowDotScale, nHeight * nowDotScale); 1506 } else if (col == 6) { 1507 // Timing Pattern 1508 nowDotScale = 1; 1509 var timingVColorDark = _htOption.timing_V || _htOption.timing || _htOption.colorDark; 1510 _oContext.fillStyle = bIsDark ? timingVColorDark : _htOption.colorLight; 1511 _oContext.strokeStyle = _oContext.fillStyle; 1512 _oContext.fillRect(nLeft + nWidth * (1 - nowDotScale) / 2, _htOption.titleHeight + nTop + nHeight * (1 - 1513 nowDotScale) / 2, nWidth * nowDotScale, nHeight * nowDotScale); 1514 } else { 1515 1516 if (_htOption.backgroundImage) { 1517 1518 if (_htOption.autoColor) { 1519 _oContext.strokeStyle = bIsDark ? "rgba(0, 0, 0, .6)" : "rgba(255, 255, 255, .7)"; 1520 _oContext.fillStyle = bIsDark ? "rgba(0, 0, 0, .6)" : "rgba(255, 255, 255, .7)"; 1521 } else { 1522 _oContext.strokeStyle = bIsDark ? _htOption.colorDark : "rgba(0,0,0,0)"; 1523 _oContext.fillStyle = bIsDark ? _htOption.colorDark : "rgba(0,0,0,0)"; 1524 _oContext.strokeStyle = _oContext.fillStyle; 1525 } 1526 _oContext.fillRect(nLeft + nWidth * (1 - nowDotScale) / 2, _htOption.titleHeight + nTop + nHeight * (1 - 1527 nowDotScale) / 2, nWidth * nowDotScale, nHeight * nowDotScale); 1528 } else { 1529 _oContext.strokeStyle = _oContext.fillStyle; 1530 _oContext.fillRect(nLeft + nWidth * (1 - nowDotScale) / 2, _htOption.titleHeight + nTop + nHeight * (1 - 1531 nowDotScale) / 2, nWidth * nowDotScale, nHeight * nowDotScale); 1532 1533 } 1534 } 1535 } 1536 1537 if (_htOption.dotScale != 1 && !eye) { 1538 _oContext.strokeStyle = _htOption.colorLight; 1539 } 1540 1541 } 1542 } 1543 1544 if (_htOption.title) { 1545 1546 _oContext.fillStyle = _htOption.titleBackgroundColor; 1547 _oContext.fillRect(0, 0, this._elCanvas.width, _htOption.titleHeight+_htOption.quietZone); 1548 1549 _oContext.font = _htOption.titleFont; 1550 _oContext.fillStyle = _htOption.titleColor; 1551 _oContext.textAlign = 'center'; 1552 _oContext.fillText(_htOption.title, this._elCanvas.width / 2, +_htOption.quietZone+30); 1553 } 1554 1555 if (_htOption.subTitle) { 1556 _oContext.font = _htOption.subTitleFont; 1557 _oContext.fillStyle = _htOption.subTitleColor; 1558 _oContext.fillText(_htOption.subTitle, this._elCanvas.width / 2, +_htOption.quietZone+60); 1559 } 1560 1561 function genratorImg() { 1562 var imgW = Math.round(_htOption.width / 3.5); 1563 var imgH = Math.round(_htOption.height / 3.5); 1564 if (imgW != imgH) { 1565 imgW = imgH; 1566 } 1567 1568 if (_htOption.logoWidth) { 1569 imgW = Math.round(_htOption.logoWidth); 1570 } 1571 if (_htOption.logoHeight) { 1572 imgH = Math.round(_htOption.logoHeight); 1573 } 1574 1575 1576 // Did Not Use Transparent Logo Image
1577 if (!_htOption.logoBackgroundTransparent) { 1578 //if (!_htOption.logoBackgroundColor) { 1579 //_htOption.logoBackgroundColor = '#ffffff'; 1580 //} 1581 _oContext.fillStyle = _htOption.logoBackgroundColor; 1582 1583 _oContext.fillRect((_htOption.width + _htOption.quietZone * 2 - imgW) / 2, (_htOption.height + _htOption.titleHeight + 1584 _htOption.quietZone * 2 - imgH) / 2, imgW, imgW); 1585 } 1586 1587 _oContext.drawImage(img, (_htOption.width + _htOption.quietZone * 2 - imgW) / 2, (_htOption.height + 1588 _htOption.titleHeight + _htOption.quietZone * 2 - imgH) / 2, imgW, imgH); 1589 if(_htOption.quietZone>0 && _htOption.quietZoneColor){ 1590 drawQuietZoneColor(); 1591 } 1592 _this._bIsPainted = true; 1593 1594 _this.makeImage(); 1595 } 1596 1597 if (_htOption.logo) { 1598 var img = new Image(); 1599 1600 var _this = this; 1601 1602 1603 img.onload = function() { 1604 genratorImg(); 1605 } 1606 1607 img.onerror = function(e) { 1608 console.error(e) 1609 } 1610 1611 //img.crossOrigin="Anonymous"; 1612 img.src = _htOption.logo; 1613 1614 1615 } else { 1616 this._bIsPainted = true; 1617 this.makeImage(); 1618 1619 } 1620 1621 1622 1623 } 1624 1625 }; 1626 1627 /** 1628 * Make the image from Canvas if the browser supports Data URI. 1629 */ 1630 Drawing.prototype.makeImage = function() { 1631 if (this._bIsPainted) { 1632 _safeSetDataURI.call(this, _onMakeImage); 1633 } 1634 }; 1635 1636 /** 1637 * Return whether the QRCode is painted or not 1638 * 1639 * @return {Boolean} 1640 */ 1641 Drawing.prototype.isPainted = function() { 1642 return this._bIsPainted; 1643 }; 1644 1645 /** 1646 * Clear the QRCode 1647 */ 1648 Drawing.prototype.clear = function() { 1649 this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height + 50); 1650 this._bIsPainted = false; 1651 }; 1652 1653 Drawing.prototype.remove = function() { 1654 this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height + 50); 1655 this._bIsPainted = false; 1656 this._el.innerHTML = ''; 1657 }; 1658 1659 1660 1661 /** 1662 * @private 1663 * @param {Number} nNumber 1664 */ 1665 Drawing.prototype.round = function(nNumber) { 1666 if (!nNumber) { 1667 return nNumber; 1668 } 1669 1670 return Math.floor(nNumber * 1000) / 1000; 1671 }; 1672 1673 return Drawing; 1674 })(); 1675 1676 /** 1677 * Get the type by string length 1678 * 1679 * @private 1680 * @param {String} sText 1681 * @param {Number} nCorrectLevel 1682 * @return {Number} type 1683 */ 1684 function _getTypeNumber(sText, nCorrectLevel) { 1685 var nType = 1; 1686 var length = _getUTF8Length(sText); 1687 1688 for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) { 1689 var nLimit = 0; 1690 1691 switch (nCorrectLevel) { 1692 case QRErrorCorrectLevel.L: 1693 nLimit = QRCodeLimitLength[i][0]; 1694 break; 1695 case QRErrorCorrectLevel.M: 1696 nLimit = QRCodeLimitLength[i][1]; 1697 break; 1698 case QRErrorCorrectLevel.Q: 1699 nLimit = QRCodeLimitLength[i][2]; 1700 break; 1701 case QRErrorCorrectLevel.H: 1702 nLimit = QRCodeLimitLength[i][3]; 1703 break; 1704 } 1705 1706 if (length <= nLimit) { 1707 break; 1708 } else { 1709 nType++; 1710 } 1711 } 1712 1713 if (nType > QRCodeLimitLength.length) { 1714 throw new Error("Too long data"); 1715 } 1716 1717 return nType; 1718 } 1719 1720 function _getUTF8Length(sText) { 1721 var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a'); 1722 return replacedText.length + (replacedText.length != sText ? 3 : 0); 1723 } 1724 1725 /** 1726 * @class QRCode 1727 * @constructor 1728 * @example 1729 * new QRCode(document.getElementById("test"), "QRCode"); 1730 * 1731 * @example 1732 * var oQRCode = new QRCode("test", { 1733 * text : "QRCode", 1734 * width : 128, 1735 * height : 128 1736 * }); 1737 * 1738 * oQRCode.clear(); // Clear the QRCode. 1739 * oQRCode.makeCode("QRCode"); // Re-create the QRCode. 1740 * 1741 * @param {HTMLElement|String} el target element or 'id' attribute of element. 1742 * @param {Object|String} vOption 1743 * @param {String} vOption.text QRCode link data 1744 * @param {Number} [vOption.width=256] 1745 * @param {Number} [vOption.height=256] 1746 * @param {String} [vOption.colorDark="#000000"] 1747 * @param {String} [vOption.colorLight="#ffffff"] 1748 * @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H] 1749 */ 1750 QRCode = function(el, vOption) { 1751 this._htOption = { 1752 width: 256, 1753 height: 256, 1754 typeNumber: 4, 1755 colorDark: "#000000", 1756 colorLight: "#ffffff", 1757 correctLevel: QRErrorCorrectLevel.H, 1758 1759 dotScale: 1, // Must be greater than 0, less than or equal to 1. default is 1 1760 1761 quietZone: 0, 1762 quietZoneColor: 'transparent', 1763 1764 title: "", 1765 titleFont: "bold 16px Arial", 1766 titleColor: "#000000",
1767 titleBackgroundColor: "#ffffff", 1768 titleHeight: 0, // Title Height, Include subTitle 1769 titleTop: 30, // draws y coordinates. default is 30 1770 1771 subTitle: "", 1772 subTitleFont: "14px Arial", 1773 subTitleColor: "#4F4F4F", 1774 subTitleTop: 0, // draws y coordinates. default is 0 1775 1776 logo: undefined, 1777 logoWidth: undefined, 1778 logoHeight: undefined, 1779 logoBackgroundColor: '#ffffff', 1780 logoBackgroundTransparent: false, 1781 1782 // === Posotion Pattern(Eye) Color 1783 PO: undefined, // Global Posotion Outer color. if not set, the defaut is `colorDark` 1784 PI: undefined, // Global Posotion Inner color. if not set, the defaut is `colorDark` 1785 PO_TL: undefined, // Posotion Outer - Top Left 1786 PI_TL: undefined, // Posotion Inner - Top Left 1787 PO_TR: undefined, // Posotion Outer - Top Right 1788 PI_TR: undefined, // Posotion Inner - Top Right 1789 PO_BL: undefined, // Posotion Outer - Bottom Left 1790 PI_BL: undefined, // Posotion Inner - Bottom Left 1791 1792 // === Alignment Color 1793 AO: undefined, // Alignment Outer. if not set, the defaut is `colorDark` 1794 AI: undefined, // Alignment Inner. if not set, the defaut is `colorDark` 1795 1796 // === Timing Pattern Color 1797 timing: undefined, // Global Timing color. if not set, the defaut is `colorDark` 1798 timing_H: undefined, // Horizontal timing color 1799 timing_V: undefined, // Vertical timing color 1800 1801 // ==== Backgroud Image 1802 backgroundImage: undefined, // Background Image 1803 backgroundImageAlpha: 1, // Background image transparency, value between 0 and 1. default is 1. 1804 autoColor: false, 1805 1806 // ==== Event Handler 1807 onRenderingStart: undefined 1808 1809 }; 1810 1811 if (typeof vOption === 'string') { 1812 vOption = { 1813 text: vOption 1814 }; 1815 } 1816 1817 // Overwrites options 1818 if (vOption) { 1819 for (var i in vOption) { 1820 this._htOption[i] = vOption[i]; 1821 } 1822 } 1823 1824 if (this._htOption.dotScale < 0 || this._htOption.dotScale > 1) { 1825 console.warn(this._htOption.dotScale + 1826 " , is invalidate, dotScale must greater than 0, less than or equal to 1, now reset to 1. ") 1827 this._htOption.dotScale = 1; 1828 } 1829 if (this._htOption.backgroundImageAlpha < 0 || this._htOption.backgroundImageAlpha > 1) { 1830 console.warn(this._htOption.backgroundImageAlpha + 1831 " , is invalidate, backgroundImageAlpha must between 0 and 1, now reset to 1. ") 1832 this._htOption.backgroundImageAlpha = 1; 1833 } 1834 1835 this._htOption.height = this._htOption.height + this._htOption.titleHeight; 1836 if (typeof el == "string") { 1837 el = document.getElementById(el); 1838 } 1839 1840 if (this._htOption.useSVG) { 1841 Drawing = svgDrawer; 1842 } 1843 1844 this._android = _getAndroid(); 1845 this._el = el; 1846 this._oQRCode = null; 1847 this._oDrawing = new Drawing(this._el, this._htOption); 1848 1849 if (this._htOption.text) { 1850 this.makeCode(this._htOption.text); 1851 } 1852 }; 1853 1854 /** 1855 * Make the QRCode 1856 * 1857 * @param {String} sText link data 1858 */ 1859 QRCode.prototype.makeCode = function(sText) { 1860 1861 this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel); 1862 this._oQRCode.addData(sText); 1863 this._oQRCode.make(); 1864 this._el.title = sText; 1865 this._oDrawing.draw(this._oQRCode); 1866 // this.makeImage(); 1867 }; 1868 1869 /** 1870 * Make the Image from Canvas element 1871 * - It occurs automatically 1872 * - Android below 3 doesn't support Data-URI spec. 1873 * 1874 * @private 1875 */ 1876 QRCode.prototype.makeImage = function() { 1877 if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) { 1878 this._oDrawing.makeImage(); 1879 } 1880 }; 1881 1882 /** 1883 * Clear the QRCode 1884 */ 1885 QRCode.prototype.clear = function() { 1886 this._oDrawing.remove(); 1887 }; 1888 1889 1890 /** 1891 * No Conflict 1892 * @return QRCode object 1893 */ 1894 QRCode.prototype.noConflict = function() { 1895 if (root.QRCode === this) { 1896 root.QRCode = _QRCode; 1897 } 1898 return QRCode; 1899 } 1900 1901 /** 1902 * @name QRCode.CorrectLevel 1903 */ 1904 QRCode.CorrectLevel = QRErrorCorrectLevel; 1905 1906 1907 /*--------------------------------------------------------------------------*/ 1908 // Export QRCode 1909 1910 // AMD & CMD Compatibility 1911 if (typeof define == 'function' && (define.amd || define.cmd)) { 1912 1913 // 1. Define an anonymous module 1914 define([], function() { 1915 return QRCode; 1916 }); 1917 1918 } 1919 // CommonJS Compatibility(include NodeJS) 1920 else if (freeModule) { 1921 // Node.js 1922 (freeModule.exports = QRCode).QRCode = QRCode; 1923 // Other CommonJS 1924 freeExports.QRCode = QRCode; 1925 } else { 1926 // Export Global 1927 root.QRCode = QRCode; 1928 } 1929 1930 1931 1932}.call(this));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.