Terminal.appがダメなのでiTermをいじる – 2
エンコーディング/ロカール判定をまともにしてみた。[2007-11-06改訂]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
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… 続きを読む »