From 21a79fea6555b094deb710f76b63afd2e08498b6 Mon Sep 17 00:00:00 2001 From: Joe Cheng Date: Wed, 23 Mar 2011 12:57:00 -0700 Subject: [PATCH 1/2] Respect full width property of all East Asian characters Common Japanese punctuation (comma, period) was being treated as half-width, causing cursor positioning to be off. The new code is comprehensive for code points in the Basic Multilingual Plane. See https://gist.github.com/883802 for the script I used to generate the code. --- lib/ace/edit_session.js | 65 ++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index 6c33c449..a296b694 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -962,14 +962,8 @@ var EditSession = function(text, mode) { else if(c == 32) { arr.push(SPACE); } - // CJK characters - else if ( - c >= 0x3040 && c <= 0x309F || // Hiragana - c >= 0x30A0 && c <= 0x30FF || // Katakana - c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs - c >= 0xF900 && c <= 0xFAFF || - c >= 0x3400 && c <= 0x4DBF - ) { + // full width characters + else if (isFullWidth(c)) { arr.push(CHAR, CHAR_EXT); } else { arr.push(CHAR); @@ -995,14 +989,8 @@ var EditSession = function(text, mode) { if (c == 9) { screenColumn += tabSize; } - // CJK characters - else if ( - c >= 0x3040 && c <= 0x309F || // Hiragana - c >= 0x30A0 && c <= 0x30FF || // Katakana - c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs - c >= 0xF900 && c <= 0xFAFF || - c >= 0x3400 && c <= 0x4DBF - ) { + // full width characters + else if (isFullWidth(c)) { screenColumn += 2; } else { screenColumn += 1; @@ -1149,14 +1137,8 @@ var EditSession = function(text, mode) { docColumn -= 1; } } - // CJK characters - else if ( - c >= 0x3040 && c <= 0x309F || // Hiragana - c >= 0x30A0 && c <= 0x30FF || // Katakana - c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs - c >= 0xF900 && c <= 0xFAFF || - c >= 0x3400 && c <= 0x4DBF - ) { + // full width characters + else if (isFullWidth(c)) { if (remaining >= 2) { remaining -= 2; } else { @@ -1292,6 +1274,41 @@ var EditSession = function(text, mode) { } return screenRows; } + + function isFullWidth(c) { + return c >= 0x1100 && c <= 0x115F || + c >= 0x11A3 && c <= 0x11A7 || + c >= 0x11FA && c <= 0x11FF || + c >= 0x2329 && c <= 0x232A || + c >= 0x2E80 && c <= 0x2E99 || + c >= 0x2E9B && c <= 0x2EF3 || + c >= 0x2F00 && c <= 0x2FD5 || + c >= 0x2FF0 && c <= 0x2FFB || + c >= 0x3000 && c <= 0x303E || + c >= 0x3041 && c <= 0x3096 || + c >= 0x3099 && c <= 0x30FF || + c >= 0x3105 && c <= 0x312D || + c >= 0x3131 && c <= 0x318E || + c >= 0x3190 && c <= 0x31BA || + c >= 0x31C0 && c <= 0x31E3 || + c >= 0x31F0 && c <= 0x321E || + c >= 0x3220 && c <= 0x3247 || + c >= 0x3250 && c <= 0x32FE || + c >= 0x3300 && c <= 0x4DBF || + c >= 0x4E00 && c <= 0xA48C || + c >= 0xA490 && c <= 0xA4C6 || + c >= 0xA960 && c <= 0xA97C || + c >= 0xAC00 && c <= 0xD7A3 || + c >= 0xD7B0 && c <= 0xD7C6 || + c >= 0xD7CB && c <= 0xD7FB || + c >= 0xF900 && c <= 0xFAFF || + c >= 0xFE10 && c <= 0xFE19 || + c >= 0xFE30 && c <= 0xFE52 || + c >= 0xFE54 && c <= 0xFE66 || + c >= 0xFE68 && c <= 0xFE6B || + c >= 0xFF01 && c <= 0xFF60 || + c >= 0xFFE0 && c <= 0xFFE6; + } }).call(EditSession.prototype); From 7fa4d37f57bf306f10c2ed3f06eda156c4d54a12 Mon Sep 17 00:00:00 2001 From: Joe Cheng Date: Wed, 23 Mar 2011 13:17:19 -0700 Subject: [PATCH 2/2] All full width characters should be styled with double character width --- lib/ace/layer/text.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js index 43f24baa..f6991792 100644 --- a/lib/ace/layer/text.js +++ b/lib/ace/layer/text.js @@ -303,9 +303,10 @@ var Text = function(parentEl) { .replace(/" + c + "" - }); + .replace(/[\u1100-\u115F]|[\u11A3-\u11A7]|[\u11FA-\u11FF]|[\u2329-\u232A]|[\u2E80-\u2E99]|[\u2E9B-\u2EF3]|[\u2F00-\u2FD5]|[\u2FF0-\u2FFB]|[\u3000-\u303E]|[\u3041-\u3096]|[\u3099-\u30FF]|[\u3105-\u312D]|[\u3131-\u318E]|[\u3190-\u31BA]|[\u31C0-\u31E3]|[\u31F0-\u321E]|[\u3220-\u3247]|[\u3250-\u32FE]|[\u3300-\u4DBF]|[\u4E00-\uA48C]|[\uA490-\uA4C6]|[\uA960-\uA97C]|[\uAC00-\uD7A3]|[\uD7B0-\uD7C6]|[\uD7CB-\uD7FB]|[\uF900-\uFAFF]|[\uFE10-\uFE19]|[\uFE30-\uFE52]|[\uFE54-\uFE66]|[\uFE68-\uFE6B]|[\uFF01-\uFF60]|[\uFFE0-\uFFE6]/g, + function(c) { + return "" + c + "" + }); if (!_self.$textToken[token.type]) { var classes = "ace_" + token.type.replace(/\./g, " ace_");