@@ -317,7 +317,18 @@ - (void)setWideFont:(NSFont *)newFont
317317 // NOTE: No need to set point size etc. since this is taken from the
318318 // regular font when drawing.
319319 [fontWide release ];
320- fontWide = [newFont retain ];
320+
321+ // Use 'Apple Color Emoji' font for rendering emoji
322+ CGFloat size = [newFont pointSize ];
323+ NSFontDescriptor *emojiDesc = [NSFontDescriptor
324+ fontDescriptorWithName: @" Apple Color Emoji" size: size];
325+ NSFontDescriptor *newFontDesc = [newFont fontDescriptor ];
326+ NSDictionary *attrs = [NSDictionary
327+ dictionaryWithObject: [NSArray arrayWithObject: newFontDesc]
328+ forKey: NSFontCascadeListAttribute ];
329+ NSFontDescriptor *desc =
330+ [emojiDesc fontDescriptorByAddingAttributes: attrs];
331+ fontWide = [[NSFont fontWithDescriptor: desc size: size] retain ];
321332 }
322333}
323334
@@ -1028,6 +1039,22 @@ - (void)batchDrawData:(NSData *)data
10281039 return newFontRef;
10291040}
10301041
1042+ static UniCharCount
1043+ gatherGlyphs (CGGlyph glyphs[], UniCharCount count)
1044+ {
1045+ // Gather scattered glyphs that was happended by Surrogate pair chars
1046+ UniCharCount glyphCount = 0 ;
1047+ NSUInteger pos = 0 ;
1048+ NSUInteger i;
1049+ for (i = 0 ; i < count; ++i) {
1050+ if (glyphs[i] != 0 ) {
1051+ ++glyphCount;
1052+ glyphs[pos++] = glyphs[i];
1053+ }
1054+ }
1055+ return glyphCount;
1056+ }
1057+
10311058 static void
10321059ligatureGlyphsForChars (const unichar *chars, CGGlyph *glyphs, CGPoint *positions, UniCharCount *length, CTFontRef font )
10331060{
@@ -1093,15 +1120,13 @@ - (void)batchDrawData:(NSData *)data
10931120{
10941121 if (CTFontGetGlyphsForCharacters (fontRef, chars, glyphs, length)) {
10951122 // All chars were mapped to glyphs, so draw all at once and return.
1123+ length = gatherGlyphs (glyphs, length);
10961124 if (useLigatures) {
10971125 memset (glyphs, 0 , sizeof (CGGlyph) * length);
10981126 ligatureGlyphsForChars (chars, glyphs, positions, &length, fontRef);
10991127 }
11001128
1101- CGFontRef cgFontRef = CTFontCopyGraphicsFont (fontRef, NULL );
1102- CGContextSetFont (context, cgFontRef);
1103- CGContextShowGlyphsAtPositions (context, glyphs, positions, length);
1104- CGFontRelease (cgFontRef);
1129+ CTFontDrawGlyphs (fontRef, glyphs, positions, length, context);
11051130 return ;
11061131 }
11071132
@@ -1113,23 +1138,34 @@ - (void)batchDrawData:(NSData *)data
11131138 // Draw as many consecutive glyphs as possible in the current font
11141139 // (if a glyph is 0 that means it does not exist in the current
11151140 // font).
1141+ BOOL surrogatePair = NO ;
11161142 while (*g && g < glyphsEnd) {
1117- ++g;
1118- ++c;
1143+ if (CFStringIsSurrogateHighCharacter (*c)) {
1144+ surrogatePair = YES ;
1145+ g += 2 ;
1146+ c += 2 ;
1147+ } else {
1148+ ++g;
1149+ ++c;
1150+ }
11191151 ++p;
11201152 }
11211153
11221154 int count = g-glyphs;
1123- CGFontRef cgFontRef = CTFontCopyGraphicsFont (fontRef, NULL );
1124- CGContextSetFont (context, cgFontRef);
1125- CGContextShowGlyphsAtPositions (context, glyphs, positions, count);
1126- CGFontRelease (cgFontRef);
1155+ if (surrogatePair)
1156+ count = gatherGlyphs (glyphs, count);
1157+ CTFontDrawGlyphs (fontRef, glyphs, positions, count, context);
11271158 } else {
11281159 // Skip past as many consecutive chars as possible which cannot be
11291160 // drawn in the current font.
11301161 while (0 == *g && g < glyphsEnd) {
1131- ++g;
1132- ++c;
1162+ if (CFStringIsSurrogateHighCharacter (*c)) {
1163+ g += 2 ;
1164+ c += 2 ;
1165+ } else {
1166+ ++g;
1167+ ++c;
1168+ }
11331169 ++p;
11341170 }
11351171
0 commit comments