@@ -132,6 +132,17 @@ - (id)initWithFrame:(NSRect)frame
132
132
[self registerForDraggedTypes: [NSArray arrayWithObjects:
133
133
NSFilenamesPboardType , NSStringPboardType , nil ]];
134
134
135
+ // Check if ligatures should be used or not
136
+ {
137
+ Boolean val;
138
+ Boolean keyValid;
139
+ val = CFPreferencesGetAppBooleanValue ((CFStringRef)MMRendererLigaturesSupportKey,
140
+ kCFPreferencesCurrentApplication ,
141
+ &keyValid);
142
+
143
+ useLigatures = NO ;
144
+ if (keyValid) { useLigatures = val; }
145
+ }
135
146
return self;
136
147
}
137
148
@@ -1017,14 +1028,75 @@ - (void)batchDrawData:(NSData *)data
1017
1028
return newFontRef;
1018
1029
}
1019
1030
1031
+ static void
1032
+ ligatureGlyphsForChars (const unichar *chars, CGGlyph *glyphs, CGPoint *positions, UniCharCount *length, CTFontRef font )
1033
+ {
1034
+ /* CoreText has no simple wait of retrieving a ligature for a set of UniChars.
1035
+ * The way proposed on the CoreText ML is to convert the text to an attributed
1036
+ * string, create a CTLine from it and retrieve the Glyphs from the CTRuns in it.
1037
+ */
1038
+ NSString *text = [NSString stringWithCharacters: chars
1039
+ length: *length];
1040
+
1041
+ NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:
1042
+ (id )font, kCTFontAttributeName ,
1043
+ // 2 - full ligatures including rare
1044
+ [NSNumber numberWithInteger: 2 ], kCTLigatureAttributeName ,
1045
+ nil
1046
+ ];
1047
+
1048
+ NSAttributedString *attrText = [[NSAttributedString alloc ] initWithString: text
1049
+ attributes: attrs];
1050
+
1051
+ CGPoint refPos = positions[0 ];
1052
+
1053
+ CTLineRef line = CTLineCreateWithAttributedString ((CFAttributedStringRef)attrText);
1054
+
1055
+ UniCharCount offset = 0 ;
1056
+ NSArray *glyphRuns = (NSArray *)CTLineGetGlyphRuns (line);
1057
+
1058
+ for (id item in glyphRuns) {
1059
+ CTRunRef run = (CTRunRef)item;
1060
+ CFIndex count = CTRunGetGlyphCount (run);
1061
+
1062
+ if (count > 0 ) {
1063
+ if (count - offset > *length) {
1064
+ count = (*length) - offset;
1065
+ }
1066
+ }
1067
+
1068
+ CFRange range = CFRangeMake (0 , count);
1069
+ CTRunGetGlyphs (run, range, &glyphs[offset]);
1070
+ CTRunGetPositions (run, range, &positions[offset]);
1071
+
1072
+ offset += count;
1073
+ if (offset >= *length) {
1074
+ // don't copy more glyphs then there is space for
1075
+ break ;
1076
+ }
1077
+ }
1078
+ // fixup relative positioning
1079
+ for ( CFIndex i = 0 ; i < offset; ++i ) {
1080
+ positions[i].x += refPos.x ;
1081
+ positions[i].y += refPos.y ;
1082
+ }
1083
+ // as ligatures combine characters it is required to adjust the
1084
+ // original length value
1085
+ *length = offset;
1086
+ }
1087
+
1020
1088
static void
1021
1089
recurseDraw (const unichar *chars, CGGlyph *glyphs, CGPoint *positions,
1022
1090
UniCharCount length, CGContextRef context, CTFontRef fontRef,
1023
- NSMutableArray *fontCache)
1091
+ NSMutableArray *fontCache, BOOL useLigatures )
1024
1092
{
1025
-
1026
1093
if (CTFontGetGlyphsForCharacters (fontRef, chars, glyphs, length)) {
1027
1094
// All chars were mapped to glyphs, so draw all at once and return.
1095
+ if (useLigatures) {
1096
+ memset (glyphs, 0 , sizeof (CGGlyph) * length);
1097
+ ligatureGlyphsForChars (chars, glyphs, positions, &length, fontRef);
1098
+ }
1099
+
1028
1100
CGFontRef cgFontRef = CTFontCopyGraphicsFont (fontRef, NULL );
1029
1101
CGContextSetFont (context, cgFontRef);
1030
1102
CGContextShowGlyphsAtPositions (context, glyphs, positions, length);
@@ -1077,7 +1149,7 @@ - (void)batchDrawData:(NSData *)data
1077
1149
}
1078
1150
1079
1151
recurseDraw (chars, glyphs, positions, attemptedCount, context,
1080
- fallback, fontCache);
1152
+ fallback, fontCache, useLigatures );
1081
1153
1082
1154
// If only a portion of the invalid range was rendered above,
1083
1155
// the remaining range needs to be attempted by subsequent
@@ -1201,7 +1273,7 @@ - (void)drawString:(const UniChar *)chars length:(UniCharCount)length
1201
1273
}
1202
1274
1203
1275
CGContextSetTextPosition (context, x, y+fontDescent);
1204
- recurseDraw (chars, glyphs, positions, length, context, fontRef, fontCache);
1276
+ recurseDraw (chars, glyphs, positions, length, context, fontRef, fontCache, useLigatures );
1205
1277
1206
1278
CFRelease (fontRef);
1207
1279
CGContextRestoreGState (context);
0 commit comments