Skip to content

Commit

Permalink
issue#28 encoding mode support (Numeric, Alphanumeric, Kanji).
Browse files Browse the repository at this point in the history
  • Loading branch information
kazuhikoarase committed Jan 4, 2017
1 parent db5dfc3 commit 1067b0a
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 11 deletions.
9 changes: 5 additions & 4 deletions js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ Overwrite this function to encode using a multibyte charset.

###QRCode

####addData(data) => <code>void</code>
####addData(data, mode) => <code>void</code>
Add a data to encode.

| Param | Type | Description |
| -------| ------------------- | ---------------- |
| data | <code>string</code> | string to encode |
| Param | Type | Description |
| -------| ------------------- | ---------------------------------------------------------- |
| data | <code>string</code> | string to encode |
| mode | <code>string</code> | Mode ('Numeric', 'Alphanumeric', 'Byte'(default), 'Kanji') |

####make() => <code>void</code>
Make a QR Code.
Expand Down
2 changes: 1 addition & 1 deletion js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "qrcode-generator",
"version": "1.0.7",
"version": "1.1.0",
"description": "QR Code Generator implementation in JavaScript.",
"author": "Kazuhiko Arase",
"main": "qrcode.js",
Expand Down
2 changes: 1 addition & 1 deletion js/qrcode.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface QRCodeFactory {
}

interface QRCode {
addData(data: string) : void;
addData(data: string, mode?: string) : void;
make() : void;
getModuleCount() : number;
isDark(row: number, col: number) : boolean;
Expand Down
206 changes: 204 additions & 2 deletions js/qrcode.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,8 +383,29 @@ var qrcode = function() {
return createBytes(buffer, rsBlocks);
};

_this.addData = function(data) {
var newData = qr8BitByte(data);
_this.addData = function(data, mode) {

mode = mode || 'Byte';

var newData = null;

switch(mode) {
case 'Numeric' :
newData = qrNumber(data);
break;
case 'Alphanumeric' :
newData = qrAlphaNum(data);
break;
case 'Byte' :
newData = qr8BitByte(data);
break;
case 'Kanji' :
newData = qrKanji(data);
break;
default :
throw 'mode:' + mode;
}

_dataList.push(newData);
_dataCache = null;
};
Expand Down Expand Up @@ -1366,6 +1387,126 @@ var qrcode = function() {
return _this;
};

//---------------------------------------------------------------------
// qrNumber
//---------------------------------------------------------------------

var qrNumber = function(data) {

var _mode = QRMode.MODE_NUMBER;
var _data = data;

var _this = {};

_this.getMode = function() {
return _mode;
};

_this.getLength = function(buffer) {
return _data.length;
};

_this.write = function(buffer) {

var data = _data;

var i = 0;

while (i + 2 < data.length) {
buffer.put(strToNum(data.substring(i, i + 3) ), 10);
i += 3;
}

if (i < data.length) {
if (data.length - i == 1) {
buffer.put(strToNum(data.substring(i, i + 1) ), 4);
} else if (data.length - i == 2) {
buffer.put(strToNum(data.substring(i, i + 2) ), 7);
}
}
};

var strToNum = function(s) {
var num = 0;
for (var i = 0; i < s.length; i += 1) {
num = num * 10 + chatToNum(s.charAt(i) );
}
return num;
};

var chatToNum = function(c) {
if ('0' <= c && c <= '9') {
return c.charCodeAt(0) - '0'.charCodeAt(0);
}
throw 'illegal char :' + c;
};

return _this;
};

//---------------------------------------------------------------------
// qrAlphaNum
//---------------------------------------------------------------------

var qrAlphaNum = function(data) {

var _mode = QRMode.MODE_ALPHA_NUM;
var _data = data;

var _this = {};

_this.getMode = function() {
return _mode;
};

_this.getLength = function(buffer) {
return _data.length;
};

_this.write = function(buffer) {

var s = _data;

var i = 0;

while (i + 1 < s.length) {
buffer.put(
getCode(s.charAt(i) ) * 45 +
getCode(s.charAt(i + 1) ), 11);
i += 2;
}

if (i < s.length) {
buffer.put(getCode(s.charAt(i) ), 6);
}
};

var getCode = function(c) {

if ('0' <= c && c <= '9') {
return c.charCodeAt(0) - '0'.charCodeAt(0);
} else if ('A' <= c && c <= 'Z') {
return c.charCodeAt(0) - 'A'.charCodeAt(0) + 10;
} else {
switch (c) {
case ' ' : return 36;
case '$' : return 37;
case '%' : return 38;
case '*' : return 39;
case '+' : return 40;
case '-' : return 41;
case '.' : return 42;
case '/' : return 43;
case ':' : return 44;
default :
throw 'illegal char :' + c;
}
}
};

return _this;
};

//---------------------------------------------------------------------
// qr8BitByte
//---------------------------------------------------------------------
Expand Down Expand Up @@ -1395,6 +1536,67 @@ var qrcode = function() {
return _this;
};

//---------------------------------------------------------------------
// qrKanji
//---------------------------------------------------------------------

var qrKanji = function(data) {

var _mode = QRMode.MODE_KANJI;
var _data = data;
var _bytes = qrcode.stringToBytes(data);

!function(c, code) {
// self test for sjis support.
var test = qrcode.stringToBytes(c);
if (test.length != 2 || ( (test[0] << 8) | test[1]) != code) {
throw 'sjis not supported.';
}
}('\u53cb', 0x9746);

var _this = {};

_this.getMode = function() {
return _mode;
};

_this.getLength = function(buffer) {
return ~~(_bytes.length / 2);
};

_this.write = function(buffer) {

var data = _bytes;

var i = 0;

while (i + 1 < data.length) {

var c = ( (0xff & data[i]) << 8) | (0xff & data[i + 1]);

if (0x8140 <= c && c <= 0x9FFC) {
c -= 0x8140;
} else if (0xE040 <= c && c <= 0xEBBF) {
c -= 0xC140;
} else {
throw 'illegal char at ' + (i + 1) + '/' + c;
}

c = ( (c >>> 8) & 0xff) * 0xC0 + (c & 0xff);

buffer.put(c, 13);

i += 2;
}

if (i < data.length) {
throw 'illegal char at ' + (i + 1);
}
};

return _this;
};

//=====================================================================
// GIF Support etc.
//
Expand Down
7 changes: 7 additions & 0 deletions js/sample.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@
<option value="Q">Q(25%)</option>
<option value="H">H(30%)</option>
</select>
<span>Mode:</span>
<select name="m">
<option value="Numeric">Numeric</option>
<option value="Alphanumeric">Alphanumeric</option>
<option value="Byte" selected>Byte</option>
<option value="Kanji">Kanji</option>
</select>
<br/>
<textarea name="msg" rows="10" cols="40">here comes qr!</textarea>
<br/>
Expand Down
7 changes: 4 additions & 3 deletions js/sample.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ var draw_qrcode = function(text, typeNumber, errorCorrectionLevel) {
document.write(create_qrcode(text, typeNumber, errorCorrectionLevel) );
};

var create_qrcode = function(text, typeNumber, errorCorrectionLevel, table) {
var create_qrcode = function(text, typeNumber, errorCorrectionLevel, mode) {

var qr = qrcode(typeNumber || 4, errorCorrectionLevel || 'M');
qr.addData(text);
qr.addData(text, mode);
qr.make();

// return qr.createTableTag();
Expand All @@ -20,5 +20,6 @@ var update_qrcode = function() {
replace(/^[\s\u3000]+|[\s\u3000]+$/g, '');
var t = form.elements['t'].value;
var e = form.elements['e'].value;
document.getElementById('qr').innerHTML = create_qrcode(text, t, e);
var m = form.elements['m'].value;
document.getElementById('qr').innerHTML = create_qrcode(text, t, e, m);
};

0 comments on commit 1067b0a

Please sign in to comment.