From 81a64f5848676778cd76d1291a8af1fe562b556f Mon Sep 17 00:00:00 2001 From: Kazuki Sakamoto Date: Thu, 5 Nov 2015 09:17:46 -0800 Subject: [PATCH] =?UTF-8?q?Support=20Emoji=F0=9F=90=B1=20#65?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/MacVim/MMCoreTextView.m | 62 +++++++++++++++++++++++++++++-------- src/mbyte.c | 12 +++---- 2 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/MacVim/MMCoreTextView.m b/src/MacVim/MMCoreTextView.m index 8d73a5044c..e36ebb88c0 100644 --- a/src/MacVim/MMCoreTextView.m +++ b/src/MacVim/MMCoreTextView.m @@ -317,7 +317,18 @@ defaultAdvanceForFont(NSFont *font) // NOTE: No need to set point size etc. since this is taken from the // regular font when drawing. [fontWide release]; - fontWide = [newFont retain]; + + // Use 'Apple Color Emoji' font for rendering emoji + CGFloat size = [newFont pointSize]; + NSFontDescriptor *emojiDesc = [NSFontDescriptor + fontDescriptorWithName:@"Apple Color Emoji" size:size]; + NSFontDescriptor *newFontDesc = [newFont fontDescriptor]; + NSDictionary *attrs = [NSDictionary + dictionaryWithObject:[NSArray arrayWithObject:newFontDesc] + forKey:NSFontCascadeListAttribute]; + NSFontDescriptor *desc = + [emojiDesc fontDescriptorByAddingAttributes:attrs]; + fontWide = [[NSFont fontWithDescriptor:desc size:size] retain]; } } @@ -1028,6 +1039,22 @@ lookupFont(NSMutableArray *fontCache, const unichar *chars, UniCharCount count, return newFontRef; } + static UniCharCount +gatherGlyphs(CGGlyph glyphs[], UniCharCount count) +{ + // Gather scattered glyphs that was happended by Surrogate pair chars + UniCharCount glyphCount = 0; + NSUInteger pos = 0; + NSUInteger i; + for (i = 0; i < count; ++i) { + if (glyphs[i] != 0) { + ++glyphCount; + glyphs[pos++] = glyphs[i]; + } + } + return glyphCount; +} + static void ligatureGlyphsForChars(const unichar *chars, CGGlyph *glyphs, CGPoint *positions, UniCharCount *length, CTFontRef font ) { @@ -1093,15 +1120,13 @@ recurseDraw(const unichar *chars, CGGlyph *glyphs, CGPoint *positions, { if (CTFontGetGlyphsForCharacters(fontRef, chars, glyphs, length)) { // All chars were mapped to glyphs, so draw all at once and return. + length = gatherGlyphs(glyphs, length); if (useLigatures) { memset(glyphs, 0, sizeof(CGGlyph) * length); ligatureGlyphsForChars(chars, glyphs, positions, &length, fontRef); } - CGFontRef cgFontRef = CTFontCopyGraphicsFont(fontRef, NULL); - CGContextSetFont(context, cgFontRef); - CGContextShowGlyphsAtPositions(context, glyphs, positions, length); - CGFontRelease(cgFontRef); + CTFontDrawGlyphs(fontRef, glyphs, positions, length, context); return; } @@ -1113,23 +1138,34 @@ recurseDraw(const unichar *chars, CGGlyph *glyphs, CGPoint *positions, // Draw as many consecutive glyphs as possible in the current font // (if a glyph is 0 that means it does not exist in the current // font). + BOOL surrogatePair = NO; while (*g && g < glyphsEnd) { - ++g; - ++c; + if (CFStringIsSurrogateHighCharacter(*c)) { + surrogatePair = YES; + g += 2; + c += 2; + } else { + ++g; + ++c; + } ++p; } int count = g-glyphs; - CGFontRef cgFontRef = CTFontCopyGraphicsFont(fontRef, NULL); - CGContextSetFont(context, cgFontRef); - CGContextShowGlyphsAtPositions(context, glyphs, positions, count); - CGFontRelease(cgFontRef); + if (surrogatePair) + count = gatherGlyphs(glyphs, count); + CTFontDrawGlyphs(fontRef, glyphs, positions, count, context); } else { // Skip past as many consecutive chars as possible which cannot be // drawn in the current font. while (0 == *g && g < glyphsEnd) { - ++g; - ++c; + if (CFStringIsSurrogateHighCharacter(*c)) { + g += 2; + c += 2; + } else { + ++g; + ++c; + } ++p; } diff --git a/src/mbyte.c b/src/mbyte.c index fbec5706cd..e8caf48019 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -1244,8 +1244,10 @@ utf_char2cells(c) static struct interval doublewidth[] = { {0x1100, 0x115f}, - {0x2329, 0x232a}, - {0x2e80, 0x2e99}, + {0x2300, 0x23ff}, + {0x2700, 0x27bf}, + {0x2b00, 0x2bff}, + {0x2e00, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb}, @@ -1271,11 +1273,7 @@ utf_char2cells(c) {0xfe68, 0xfe6b}, {0xff01, 0xff60}, {0xffe0, 0xffe6}, - {0x1b000, 0x1b001}, - {0x1f200, 0x1f202}, - {0x1f210, 0x1f23a}, - {0x1f240, 0x1f248}, - {0x1f250, 0x1f251}, + {0x10000, 0x1fffd}, {0x20000, 0x2fffd}, {0x30000, 0x3fffd} };