Skip to content
Merged

V2 #1

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Resources/Hangul_2.pdf
Binary file not shown.
1 change: 1 addition & 0 deletions Sources/DKSTHangul.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

@property (nonatomic, assign) BOOL moaJjikiEnabled;
@property (nonatomic, assign) BOOL fullCharacterDelete;
@property (nonatomic, assign) BOOL oldHangulEnabled;


@end
116 changes: 101 additions & 15 deletions Sources/DKSTHangul.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@ @interface DKSTHangul () {
NSMutableString *_buffer;
NSMutableString *_completed;
}

// Old Hangul Choseongs
#define CHOSEONG_YESIEUNG 0x114C // Yesieung (ㆁ)
#define CHOSEONG_SSANGIEUNG 0x1147 // SsangIeung (ㆀ) - Shift+D
#define CHOSEONG_PANSIOT 0x1140 // Bansiot (ㅿ)
#define CHOSEONG_YEORINHIEUH 0x1159 // Yeorinhieuh (ㆆ)
#define CHOSEONG_KAPYEOUNPHIEUP 0x1157 // KapyeounPhieup (ㆄ)
#define CHOSEONG_SG 0x112D // Sios-Kiyeok (ㅺ)
#define CHOSEONG_BS 0x112F // Sios-Tikeut (ㅼ)
#define CHOSEONG_BJ 0x1132 // Sios-Pieup (ㅽ)

// Old Hangul Jungseongs
#define JUNGSEONG_ARAEAE 0x11A1

@end

@implementation DKSTHangul
Expand All @@ -37,7 +51,31 @@ - (void)reset {

- (NSString *)composedString {
if (_cho == 0 && _jung == 0 && _jong == 0) return @"";
return [NSString stringWithFormat:@"%C", [self currentSyllable]];
unichar s = [self currentSyllable];
if (s != 0) return [NSString stringWithFormat:@"%C", s];

// Archaic / Non-combinable case: Use raw Jamo (0x11xx) instead of compatibility (0x31xx)
// to allow OS rendering to form a cluster.
NSMutableString *res = [NSMutableString string];
if (_cho) [res appendFormat:@"%C", _cho];
if (_jung) [res appendFormat:@"%C", _jung];
if (_jong) [res appendFormat:@"%C", _jong];
return res;
}

- (void)flush {
if (_cho == 0 && _jung == 0 && _jong == 0) return;

unichar s = [self currentSyllable];
if (s != 0) {
[_completed appendFormat:@"%C", s];
} else {
// Archaic / Non-combinable case
if (_cho) [_completed appendFormat:@"%C", _cho];
if (_jung) [_completed appendFormat:@"%C", _jung];
if (_jong) [_completed appendFormat:@"%C", _jong];
}
_cho = 0; _jung = 0; _jong = 0;
}

- (NSString *)commitString {
Expand All @@ -47,11 +85,18 @@ - (NSString *)commitString {
}

// Check types
- (BOOL)isCho:(unichar)c { return c >= 0x1100 && c <= 0x1112; }
- (BOOL)isJung:(unichar)c { return c >= 0x1161 && c <= 0x1175; }
- (BOOL)isJong:(unichar)c { return (c >= 0x11A8 && c <= 0x11C2); }
// Updated ranges for Old Hangul
- (BOOL)isCho:(unichar)c { return (c >= 0x1100 && c <= 0x115F); } // Expanded
- (BOOL)isJung:(unichar)c { return (c >= 0x1161 && c <= 0x11A7); } // Expanded
- (BOOL)isJong:(unichar)c { return (c >= 0x11A8 && c <= 0x11FF); } // Expanded

- (unichar)mapFromChar:(unichar)c {
// Old Hangul Overrides for Shift+D/Shift+G
if (self.oldHangulEnabled) {
if (c == 'D') return CHOSEONG_SSANGIEUNG; // ㆀ
if (c == 'G') return CHOSEONG_KAPYEOUNPHIEUP; // ㆄ
}

switch(c) {
case 'q': return 0x1107; case 'Q': return 0x1108; // ㅂ, ㅃ
case 'w': return 0x110c; case 'W': return 0x110d; // ㅈ, ㅉ
Expand Down Expand Up @@ -86,6 +131,28 @@ - (unichar)mapFromChar:(unichar)c {
return 0;
}

- (unichar)combineCho:(unichar)a second:(unichar)b {
if (!self.oldHangulEnabled) return 0;

// ㅇ + ㅇ = ㆁ (Yesieung)
if (a == 0x110B && b == 0x110B) return CHOSEONG_YESIEUNG;
// ㅅ + ㅅ = ㅿ (Bansiot)
if (a == 0x1109 && b == 0x1109) return CHOSEONG_PANSIOT;
// ㅎ + ㅎ = ㆆ (Yeorinhieuh)
if (a == 0x1112 && b == 0x1112) return CHOSEONG_YEORINHIEUH;

// ㄱ + ㅅ = ㅺ (Sg)
if (a == 0x1100 && b == 0x1109) return CHOSEONG_SG;
// ㅂ + ㅅ = ㅼ (Bs)
if (a == 0x1107 && b == 0x1109) return CHOSEONG_BS;
// ㅂ + ㅈ = ㅽ (Bj)
if (a == 0x1107 && b == 0x110C) return CHOSEONG_BJ;

return 0;
}



- (unichar)currentSyllable {
if (_cho == 0 && _jung == 0 && _jong == 0) return 0;

Expand Down Expand Up @@ -135,6 +202,8 @@ - (unichar)compatibilityJamo:(unichar)u {
};
return map[u - 0x1161];
}

if (u == 0x119E) return 0x318D; // Araea
return u;
}

Expand All @@ -145,6 +214,8 @@ - (int)choIndex:(unichar)c {

- (int)jungIndex:(unichar)c {
if (c >= 0x1161 && c <= 0x1175) return c - 0x1161;
// Araea is not part of modern syllable block (U+AC00-U+D7A3),
// but we support it as an independent jamo for now.
return -1;
}

Expand Down Expand Up @@ -210,8 +281,7 @@ - (BOOL)processCode:(NSInteger)keyCode modifiers:(NSUInteger)flags

if (hangul == 0) {
if (_cho || _jung || _jong) {
[_completed appendFormat:@"%C", [self currentSyllable]];
_cho = 0; _jung = 0; _jong = 0;
[self flush];
}
return NO;
}
Expand All @@ -221,9 +291,15 @@ - (BOOL)processCode:(NSInteger)keyCode modifiers:(NSUInteger)flags
// State: Cho only or Empty
if (_cho == 0) { _cho = hangul; }
else {
// Flush prev Cho, start new
[_completed appendFormat:@"%C", [self compatibilityJamo:_cho]];
_cho = hangul;
// Try Combine Cho (Old Hangul)
unichar compound = [self combineCho:_cho second:hangul];
if (compound) {
_cho = compound;
} else {
// Flush prev Cho, start new
[_completed appendFormat:@"%C", [self compatibilityJamo:_cho]];
_cho = hangul;
}
}
} else {
// Already have Jung.
Expand All @@ -235,7 +311,7 @@ - (BOOL)processCode:(NSInteger)keyCode modifiers:(NSUInteger)flags
return YES;
} else {
// Moa-jjiki Disabled: Flush Jung, start new Cho
[_completed appendFormat:@"%C", [self currentSyllable]];
[self flush];
_cho = hangul; _jung = 0; _jong = 0;
return YES;
}
Expand All @@ -246,8 +322,11 @@ - (BOOL)processCode:(NSInteger)keyCode modifiers:(NSUInteger)flags
if (asJong) {
_jong = asJong;
} else {
// Start new syllable
[_completed appendFormat:@"%C", [self currentSyllable]];
// Not a valid Jongseong. Maybe combined Cho (Old Hangul)?
// But we already have Jung, so it's a new Syllable unless Old Hangul allows Cho+Jung+Cho?
// No, Cho+Jung+Cho structure isn't standard. It must be Jongseong or new Syllable.
// If it's not a valid Jongseong, it's a new syllable.
[self flush];
_cho = hangul; _jung = 0; _jong = 0;
}
} else { // Cho+Jung+Jong
Expand All @@ -257,7 +336,7 @@ - (BOOL)processCode:(NSInteger)keyCode modifiers:(NSUInteger)flags
_jong = compound;
} else {
// Flush, start new
[_completed appendFormat:@"%C", [self currentSyllable]];
[self flush];
_cho = hangul; _jung = 0; _jong = 0;
}
}
Expand All @@ -271,12 +350,12 @@ - (BOOL)processCode:(NSInteger)keyCode modifiers:(NSUInteger)flags
if (j2) {
_jong = j1;
unichar nextCho = [self jongToCho:j2];
[_completed appendFormat:@"%C", [self currentSyllable]];
[self flush];
_cho = nextCho; _jung = hangul; _jong = 0;
} else {
unichar nextCho = [self jongToCho:_jong];
_jong = 0;
[_completed appendFormat:@"%C", [self currentSyllable]];
[self flush];
_cho = nextCho; _jung = hangul; _jong = 0;
}
} else if (_jung) {
Expand Down Expand Up @@ -386,6 +465,12 @@ - (unichar)combineJung:(unichar)a second:(unichar)b {
if (a == 0x116e && b == 0x1166) return 0x1170; // ㅞ
if (a == 0x116e && b == 0x1175) return 0x1171; // ㅟ
if (a == 0x1173 && b == 0x1175) return 0x1174; // ㅢ

// Araea (Optional)
if (self.oldHangulEnabled) {
if (a == 0x1161 && b == 0x1161) return 0x119E; // ㅏ + ㅏ = ᆞ (Araea)
}

return 0;
}

Expand All @@ -399,6 +484,7 @@ - (void)splitJung:(unichar)c first:(unichar*)j1 second:(unichar*)j2 {
case 0x1170: *j1 = 0x116e; *j2 = 0x1166; break; // ㅞ
case 0x1171: *j1 = 0x116e; *j2 = 0x1175; break; // ㅟ
case 0x1174: *j1 = 0x1173; *j2 = 0x1175; break; // ㅢ
case 0x119E: *j1 = 0x1161; *j2 = 0x1161; break; // ᆞ -> ㅏ + ㅏ
}
}

Expand Down
20 changes: 19 additions & 1 deletion Sources/InputController.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ - (id)initWithServer:(IMKServer *)server delegate:(id)delegate client:(id)inputC
[[NSUserDefaults standardUserDefaults] registerDefaults:@{
@"EnableCapsLockSwitch": @NO,
@"EnableMoaJjiki": @YES,
@"EnableOldHangul": @NO,
@"FullCharacterDelete": @NO,
@"EnableCustomShift": @NO
}];
Expand All @@ -36,6 +37,9 @@ - (void)activateServer:(id)sender {
BOOL moaEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"EnableMoaJjiki"];
[engine setMoaJjikiEnabled:moaEnabled];

BOOL oldHangulEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"EnableOldHangul"];
[engine setOldHangulEnabled:oldHangulEnabled];

BOOL fullDelete = [[NSUserDefaults standardUserDefaults] boolForKey:@"FullCharacterDelete"];
[engine setFullCharacterDelete:fullDelete];

Expand Down Expand Up @@ -138,6 +142,13 @@ - (BOOL)handleEvent:(NSEvent *)event client:(id)sender {
default: break;
}

// Old Hangul Bypass for 'd' (ㅇ) and 'g' (ㅎ)
// If Old Hangul is enabled, Shift+D and Shift+G should bypass usage of custom phrase
BOOL oldHangul = [[NSUserDefaults standardUserDefaults] boolForKey:@"EnableOldHangul"];
if (oldHangul && (keyCode == 2 || keyCode == 5)) {
lookupKey = nil; // Skip map lookup
}

if (lookupKey) {
NSDictionary *mappings = [defaults dictionaryForKey:@"DKSTCustomShiftMappings"];
NSString *output = [mappings objectForKey:lookupKey];
Expand Down Expand Up @@ -226,7 +237,14 @@ - (void)setValue:(id)value forTag:(long)tag client:(id)sender {
- (void)showPreferences:(id)sender {
NSString *path = [[NSBundle mainBundle] pathForResource:@"DKSTPreferences" ofType:@"app"];
if (path) {
[[NSWorkspace sharedWorkspace] launchApplication:path];
NSURL *url = [NSURL fileURLWithPath:path];
[[NSWorkspace sharedWorkspace] openApplicationAtURL:url
configuration:[NSWorkspaceOpenConfiguration configuration]
completionHandler:^(NSRunningApplication * _Nullable app, NSError * _Nullable error) {
if (error) {
NSLog(@"DKST: Failed to launch Preferences: %@", error);
}
}];
} else {
NSLog(@"DKST: Could not find Preferences app at %@", path);
}
Expand Down
11 changes: 8 additions & 3 deletions Sources/PreferencesController.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@
@interface PreferencesController : NSWindowController <NSTableViewDataSource, NSTableViewDelegate, NSWindowDelegate> {
IBOutlet NSButton *capsLockSwitchCheckbox;
IBOutlet NSButton *moaJjikiCheckbox;
IBOutlet NSButton *fullDeleteCheckbox;

// New Feature
IBOutlet NSButton *oldHangulCheckbox;
IBOutlet NSButton *customShiftCheckbox;



// Backspace Behavior
IBOutlet NSButton *backspaceJasoRadio;
IBOutlet NSButton *backspaceGulpjaRadio;

IBOutlet NSTableView *mappingsTableView;

NSMutableArray *mappingKeys;
Expand Down
Loading