From f3917b47a7c8060dd9f117aa0e8f1c6b131a52c5 Mon Sep 17 00:00:00 2001 From: mshio Date: Wed, 9 Feb 2011 12:42:00 +0000 Subject: [PATCH] move functions about manipulating unicode (and surrogate pair) to new class git-svn-id: svn+ssh://svn.osdn.net/svnroot/sawarabi-fonts/trunk@17 54a90f34-5e62-402c-8eae-46c47f0b2e07 --- chartool/objective-c/Controller.h | 3 + chartool/objective-c/Controller.m | 58 +++++++++-------- chartool/objective-c/UnicharUtil.h | 22 +++++++ chartool/objective-c/UnicharUtil.m | 76 ++++++++++++++++++++++ .../objective-c/chartool.xcodeproj/project.pbxproj | 6 ++ chartool/objective-c/main.m | 4 +- 6 files changed, 141 insertions(+), 28 deletions(-) create mode 100644 chartool/objective-c/UnicharUtil.h create mode 100644 chartool/objective-c/UnicharUtil.m diff --git a/chartool/objective-c/Controller.h b/chartool/objective-c/Controller.h index c5d7660e..9ec4ff99 100644 --- a/chartool/objective-c/Controller.h +++ b/chartool/objective-c/Controller.h @@ -8,6 +8,7 @@ #import #import "JavaScriptEngine.h" +#import "UnicharUtil.h" @interface Controller : NSObject { IBOutlet NSTextField* searchField; @@ -17,8 +18,10 @@ NSString* currentCharacter; JavaScriptEngine* engine; + UnicharUtil* charUtil; } - (IBAction) search:(id)sender; +- (IBAction) clickScriptButton: (id)sender; - (IBAction) copyGlyphCharacter:(id)sender; @end diff --git a/chartool/objective-c/Controller.m b/chartool/objective-c/Controller.m index 87ee9fb6..9932bdd0 100644 --- a/chartool/objective-c/Controller.m +++ b/chartool/objective-c/Controller.m @@ -13,6 +13,7 @@ - (id) init { currentCharacter = nil; engine = [JavaScriptEngine instance]; + charUtil = [UnicharUtil instance]; return [super init]; } @@ -61,37 +62,37 @@ [glyphView setImage: m]; } -- (NSString*) getUnicharFromText: (NSString*) text withLocation: (int) loc { +- (NSRange) getTargetRangeFrom: (NSString*) text withLocation: (int) loc { unichar ch = [text characterAtIndex: loc]; - + int rlen = 0, llen = 0; - while (rlen <= 4 && ((ch >= '0' && ch <= '9') || - (ch >= 'a' && ch <= 'f') || - (ch >= 'A' && ch <= 'F'))) { + while (rlen <= 4 && [charUtil characterIsHexCharacter: ch]) { rlen++; if (loc + rlen >= [text length]) break; ch = [text characterAtIndex: loc + rlen]; } - if (rlen >=1 && rlen < 5) { - do { - if (loc - llen <= 0) break; + if (rlen >= 1 && rlen < 5) { + while (rlen + llen <= 4 && loc - llen > 0) { + ch = [text characterAtIndex: loc - llen - 1]; + if (! [charUtil characterIsHexCharacter: ch]) break; llen++; - ch = [text characterAtIndex: loc - llen]; - } while (rlen + llen <= 4 && ((ch >= '0' && ch <= '9') || - (ch >= 'a' && ch <= 'f') || - (ch >= 'A' && ch <= 'F'))); - } - if (rlen + llen >= 4 && rlen + llen <= 5) { - char s[rlen + llen + 1]; - for (int i = loc - llen; i < loc + rlen; i++) { - s[i - (loc - llen)] = (char) [text characterAtIndex: i]; } - s[rlen + llen] = '\0'; - int v; - sscanf(s, "%x", &v); - return [[NSString alloc] initWithCharacters: (unichar[]) {v} length: 1]; } - return [text substringWithRange: NSMakeRange(loc, 1)]; + + return NSMakeRange(loc - llen, rlen + llen); +} + +- (NSString*) getCharacterFrom: (NSString*) text withRange: (NSRange) range andLocation: (int) loc { + if (range.length >= 4) { + return [charUtil getUnicharFromCharCode: [text substringWithRange: range]]; + } else { + unichar ch = [text characterAtIndex: range.location]; + BOOL high = [charUtil characterIsHighSurrogate: ch]; + BOOL low = [charUtil characterIsLowSurrogate: ch]; + int p = loc - (low ? 1 : 0); + return [text substringWithRange: + NSMakeRange(p < 0 ? 0 : loc, high || low ? 2 : 1)]; + } } - (IBAction) search: (id) sender { @@ -100,18 +101,23 @@ NSText* editor = [searchField currentEditor]; NSRange r = [editor selectedRange]; - int c = r.location + r.length < [text length] ? r.location + r.length : 0; - NSString* ch = [self getUnicharFromText: text withLocation: c]; + int loc = r.location + r.length < [text length] ? r.location + r.length : 0; + NSRange tr = [self getTargetRangeFrom: text withLocation: loc]; + NSString* ch = [self getCharacterFrom: text withRange: tr andLocation: loc]; currentCharacter = ch; - [editor setSelectedRange: NSMakeRange(c, 1)]; + [editor setSelectedRange: + tr.length < 4 ? NSMakeRange(loc, [ch length]) : NSMakeRange(tr.location, tr.length)]; [self drawOnGlyphView: ch]; - NSString* code = [NSString stringWithFormat: @"%04x", [ch characterAtIndex:0]]; + NSString* code = [charUtil getCharCodeFromUnichar: ch]; [codeField setStringValue: code]; } +- (IBAction) clickScriptButton: (id) sender { +} + - (IBAction) copyGlyphCharacter: (id) sender { if (currentCharacter) { NSPasteboard* cb = [NSPasteboard generalPasteboard]; diff --git a/chartool/objective-c/UnicharUtil.h b/chartool/objective-c/UnicharUtil.h new file mode 100644 index 00000000..9db73e2b --- /dev/null +++ b/chartool/objective-c/UnicharUtil.h @@ -0,0 +1,22 @@ +// +// UnicharUtil.h +// chartool +// +// Created by mshio on 11/02/09. +// Copyright 2011 mshio. All rights reserved. +// + +#import + + +@interface UnicharUtil : NSObject { + +} ++ (UnicharUtil*) instance; +- (NSString*) getUnicharFromCharCode: (NSString*) code; +- (BOOL) characterIsHighSurrogate: (unichar) ch; +- (BOOL) characterIsLowSurrogate: (unichar) ch; +- (BOOL) characterIsHexCharacter: (unichar) ch; +- (NSString*) getCharCodeFromUnichar: (NSString*) ch; + +@end diff --git a/chartool/objective-c/UnicharUtil.m b/chartool/objective-c/UnicharUtil.m new file mode 100644 index 00000000..3995950c --- /dev/null +++ b/chartool/objective-c/UnicharUtil.m @@ -0,0 +1,76 @@ +// +// UnicharUtil.m +// chartool +// +// Created by mshio on 11/02/09. +// Copyright 2011 mshio. All rights reserved. +// + +#include +#import "UnicharUtil.h" + + +@implementation UnicharUtil + ++ (UnicharUtil*) instance { + static UnicharUtil* _instance = nil; + + if (! _instance) { + _instance = [[UnicharUtil alloc] init]; + } + return _instance; +} + +- (NSString*) getUnicharFromCharCode: (NSString*) hexCode { + if (hexCode == nil) return @""; + + // convert NSString into char array + // for making it a parameter of sscanf. + char s[[hexCode length] + 1]; + for (int i = 0; i < [hexCode length]; i++) + s[i] = (char) [hexCode characterAtIndex: i]; + s[[hexCode length]] = '\0'; + + // convert hex string into int. + int v[2] = {0, 0}; + sscanf(s, "%x", &v[0]); + + int len = 1; + if ([hexCode length] == 5) { + int x = v[0] - 0x10000; + v[0] = x / 0x400 + 0xd800; + v[1] = x % 0x400 + 0xdc00; + len = 2; + } + return [[NSString alloc] initWithCharacters: (unichar[]) {v[0], v[1]} length: len]; +} + +- (BOOL) characterIsHighSurrogate: (unichar) ch { + return 0xd800 <= ch && ch <= 0xdbff; +} + +- (BOOL) characterIsLowSurrogate: (unichar) ch { + return 0xdc00 <= ch && ch <= 0xdfff; +} + +- (BOOL) characterIsHexCharacter: (unichar) ch { + return (('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'f') || + ('A' <= ch && ch <= 'F')); +} + +- (NSString*) getCharCodeFromUnichar: (NSString *) ch { + if (ch == nil) return @""; + + NSString* ret; + unichar c0 = [ch characterAtIndex: 0]; + if ([self characterIsHighSurrogate: c0] && [ch length] >= 2) { + unichar c1 = [ch characterAtIndex: 1]; + int t = (c0 - 0xd800) * 0x400 + c1 - 0xdc00 + 0x10000; + ret = [NSString stringWithFormat: @"%05x", t]; + } else { + ret = [NSString stringWithFormat: @"%04x", c0]; + } + return ret; +} + +@end diff --git a/chartool/objective-c/chartool.xcodeproj/project.pbxproj b/chartool/objective-c/chartool.xcodeproj/project.pbxproj index e66fe97d..d3630dc5 100644 --- a/chartool/objective-c/chartool.xcodeproj/project.pbxproj +++ b/chartool/objective-c/chartool.xcodeproj/project.pbxproj @@ -11,6 +11,7 @@ 4940082D12FEAFA90050DD3E /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4940082C12FEAFA90050DD3E /* JavaScriptCore.framework */; }; 4940083112FEAFD90050DD3E /* JavaScriptEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = 4940083012FEAFD90050DD3E /* JavaScriptEngine.m */; }; 49966FED12FD6588004DAD35 /* Controller.m in Sources */ = {isa = PBXBuildFile; fileRef = 49966FEC12FD6588004DAD35 /* Controller.m */; }; + 49D3C86013024AFC00DA507B /* UnicharUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 49D3C85F13024AFC00DA507B /* UnicharUtil.m */; }; 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; @@ -30,6 +31,8 @@ 4940083012FEAFD90050DD3E /* JavaScriptEngine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JavaScriptEngine.m; sourceTree = ""; }; 49966FEB12FD6588004DAD35 /* Controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Controller.h; sourceTree = ""; }; 49966FEC12FD6588004DAD35 /* Controller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Controller.m; sourceTree = ""; }; + 49D3C85E13024AFC00DA507B /* UnicharUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnicharUtil.h; sourceTree = ""; }; + 49D3C85F13024AFC00DA507B /* UnicharUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UnicharUtil.m; sourceTree = ""; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 8D1107320486CEB800E47090 /* chartool.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = chartool.app; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -54,6 +57,8 @@ 49966FEC12FD6588004DAD35 /* Controller.m */, 4940082F12FEAFD90050DD3E /* JavaScriptEngine.h */, 4940083012FEAFD90050DD3E /* JavaScriptEngine.m */, + 49D3C85E13024AFC00DA507B /* UnicharUtil.h */, + 49D3C85F13024AFC00DA507B /* UnicharUtil.m */, ); name = Classes; sourceTree = ""; @@ -190,6 +195,7 @@ 8D11072D0486CEB800E47090 /* main.m in Sources */, 49966FED12FD6588004DAD35 /* Controller.m in Sources */, 4940083112FEAFD90050DD3E /* JavaScriptEngine.m in Sources */, + 49D3C86013024AFC00DA507B /* UnicharUtil.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/chartool/objective-c/main.m b/chartool/objective-c/main.m index 289b6bd0..f0b3ba2d 100644 --- a/chartool/objective-c/main.m +++ b/chartool/objective-c/main.m @@ -2,8 +2,8 @@ // main.m // chartool // -// Created by mshio on 10/06/05. -// Copyright mshio 2010. All rights reserved. +// Created by haru on 10/06/05. +// Copyright __MyCompanyName__ 2010. All rights reserved. // #import -- 2.11.0