エンコーディング/ロカール判定をまともにしてみた。[2007-11-06改訂](download)
Index: NSStringITerm.m
===================================================================
RCS file: /cvsroot/iterm/iTerm/NSStringITerm.m,v
retrieving revision 1.8
diff -u -r1.8 NSStringITerm.m
--- NSStringITerm.m 13 Nov 2006 08:01:04 -0000 1.8
+++ NSStringITerm.m 6 Nov 2007 09:24:28 -0000
@@ -294,9 +294,92 @@
return [NSString stringWithFormat:@"%d", num];
}
++ (BOOL)isCJKEncoding:(NSStringEncoding)encoding
+{
+ static NSMutableDictionary *isEncodingCJK = nil; // cache for encoding to isCJK mapping
+ static NSStringEncoding previousEncoding = 1; // ASCII
+ static BOOL isCJK = NO;
+ NSNumber *key, *val;
+ const char *lang;
+
+ if (encoding == previousEncoding) {
+ //NSLog(@"encoding[0x%08lx] is %s, again", encoding, isCJK ? "CJK" : "not CJK");
+ return isCJK;
+ }
+
+ previousEncoding = encoding;
+
+ key = [NSNumber numberWithUnsignedInt:encoding];
+
+ if (isEncodingCJK == nil) {
+ isEncodingCJK = [[NSMutableDictionary alloc] init];
+ }
+ else {
+ val = [isEncodingCJK objectForKey:key];
+
+ if (val != nil) {
+ isCJK = [val boolValue];
+ //NSLog(@"encoding[0x%08lx] is %s, IIRC", encoding, isCJK ? "CJK" : "not CJK");
+ return isCJK;
+ }
+ }
+
+ switch (encoding) {
+ // Simplified Chinese
+ case 0x80000019: // Mac
+ case 0x80000421: // Windows
+ case 0x80000631: // GBK
+ case 0x80000632: // GB 18030
+ case 0x80000930: // EUC
+ // Traditional Chinese
+ case 0x80000002: // Mac
+ case 0x80000423: // Windows
+ case 0x80000931: // EUC
+ case 0x80000A03: // Big5
+ case 0x80000A06: // Big5 HKSCS
+ // Japanese
+ case 0x00000003: // EUC
+ case 0x00000008: // Windows
+ case 0x00000015: // ISO-2022-JP
+ case 0x80000001: // Mac
+ case 0x80000628: // Shift JIS X0213
+ case 0x80000A01: // Shift JIS
+ // Korean
+ case 0x80000003: // Mac
+ case 0x80000422: // Windows
+ case 0x80000840: // ISO-2022-KR
+ case 0x80000940: // EUC
+ isCJK = YES;
+ //NSLog(@"0x%08lx is known to be %s", encoding, isCJK ? "CJK" : "not CJK");
+ break;
+
+ case 0x00000004: // UTF-8
+ isCJK = ((lang = getenv("LC_ALL")) != NULL ||
+ (lang = getenv("LC_CTYPE")) != NULL ||
+ (lang = getenv("LANG")) != NULL) &&
+ strlen(lang) >= 3 &&
+ (!strncmp(lang, "ja_", 3) ||
+ !strncmp(lang, "kr_", 3) ||
+ !strncmp(lang, "zh_", 3));
+ //NSLog(@"locale[%s] looks %s", lang, isCJK ? "CJK" : "not CJK");
+ break;
+
+ default:
+ isCJK = NO;
+ //NSLog(@"encoding[0x%08lx] is not known to be CJK", encoding);
+ break;
+ }
+
+ // Store in cache
+ val = [NSNumber numberWithBool:isCJK];
+ [isEncodingCJK setObject:val forKey:key];
+
+ return isCJK;
+}
+
+ (BOOL)isDoubleWidthCharacter:(unichar)unicode encoding:(NSStringEncoding) e
{
- if (unicode <= 0xa0 || (unicode>0x452 && unicode <0x200f))
+ if (unicode <= 0xa0 || (unicode>0x452 && unicode <0x1100))
return NO;
/*
unicode character width check
@@ -325,11 +408,7 @@
/* Ambiguous ones */
- if ((e)==0x80000019||(e)==0x80000421||(e)==0x80000631||(e)==0x80000632||(e)==0x80000930 || //GB
- (e)==0x80000002||(e)==0x80000423||(e)==0x80000931||(e)==0x80000a03||(e)==0x80000a06 || //BIG5
- (e)==0x80000001||(e)==0x8||(e)==0x15 || //JP
- (e)==0x80000628||(e)==0x80000a01 || //SJIS
- (e)==0x80000422||(e)==0x80000003||(e)==0x80000840||(e)==0x80000940) //KR
+ if ([self isCJKEncoding:e])
{
if ((unicode >=0xfe00 && unicode <=0xfe0f) ||
(unicode >=0x2776 && unicode <=0x277f) ||
これならsubmit可能か。ただ、描画部分でASCII/non-ASCIIフォントの選択を誤るのでまだ不完全。また時間が取れたら見ます。
あと、下線が倍幅に対応していない。(download)
Index: PTYTextView.m
===================================================================
RCS file: /cvsroot/iterm/iTerm/PTYTextView.m,v
retrieving revision 1.307
diff -u -r1.307 PTYTextView.m
--- PTYTextView.m 17 Jun 2007 01:56:31 -0000 1.307
+++ PTYTextView.m 6 Nov 2007 02:07:04 -0000
@@ -963,7 +963,7 @@
//draw underline
if (theLine[j].fg_color & UNDER_MASK && theLine[j].ch) {
[[self colorForCode:(fgcode & 0x1ff)] set];
- NSRectFill(NSMakeRect(curX,curY-2,charWidth,1));
+ NSRectFill(NSMakeRect(curX,curY-2,double_width?charWidth*2:charWidth,1));
}
}
}
ほかにも、あんまり致命的ではないが特定のケースでカーソル移動によって文字の右半分が欠けたりする。まあ、ソースがあるからいつか捕まえて直せるだろう。Terminal.appもソースを公開してほしいね。
Categories : Tech
No Comment