Open ian4hu opened 8 years ago
I'm not sure how to implement this but I'd love to! I'm open to any help that can be offered to see if we can support such characters or if it is even possible within the QR code specs.
ISO-8859-1 specification supports UTF-8 encoding by using the byte-mode. The qrcode.js project supports UTF-8 mode. I would take some time on making it work in this library.
My QR Code generator library has full Unicode support, including emoji / astral planes. Have a look at qrcodegen.js#L881.
Convert text first, solved my problem.
function utf16to8(str) {
var out, i, len, c;
out = "";
len = str.length;
for(i = 0; i < len; i++) {
c = str.charCodeAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i);
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
}
return out;
}
@wolfiesonfire Your code doesn't translate UTF-16 surrogate pairs into proper UTF-8 sequences. So any characters above U+FFFF will be broken. Also, your code needlessly escapes U+0000, resulting in illegal over-long UTF-8.
@nayuki Thanks for explain, i see the problem now.
correct code, that supports cyrillic & emojy would look like this:
function utf32to8 (str) {
var out, i, len, c;
out = "";
len = str.length;
var codeAt = str.codePointAt || str.charCodeAt; // IE 11 doesn't have codePointAt
for (i = 0; i < len; i++) {
c = codeAt.call(str, i);
if (c >= 0x10000) {
out += String.fromCharCode(0xF0 | ((c >> 18) & 0x07));
out += String.fromCharCode(0x80 | ((c >> 12) & 0x3F));
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
else if (c >= 0x0800) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
else if (c >= 0x0080) {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
else
out += str.charAt(i);
if (str.charCodeAt(i) != c)
i++;
}
return out;
}
P.S. issue with IE fixed
I have use Qrious like
qrious.value='Greeting from 中国'
but when I scanned it, there only the 'Greeting from ' left, the non-ascii charactor is lost.Is there a way to keep the non-ascii?