mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-11 15:37:29 +02:00
Add basic support for CoreText ligatures.
(cherry picked from commit 1497587763)
This commit is contained in:
committed by
Douglas Drumond
parent
186c34883d
commit
e5adcec141
+321
-1719
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -208,6 +208,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
[NSNumber numberWithBool:NO], MMNoFontSubstitutionKey,
|
||||
[NSNumber numberWithBool:YES], MMLoginShellKey,
|
||||
[NSNumber numberWithInt:2], MMRendererKey,
|
||||
[NSNumber numberWithBool:NO], MMRendererLigaturesSupportKey,
|
||||
[NSNumber numberWithInt:MMUntitledWindowAlways],
|
||||
MMUntitledWindowKey,
|
||||
[NSNumber numberWithBool:NO], MMTexturedWindowKey,
|
||||
@@ -1225,6 +1226,30 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
[self rebuildPreloadCache];
|
||||
}
|
||||
|
||||
- (IBAction)ligaturesButtonClicked:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Toggle CoreText ligatures");
|
||||
BOOL enable = ([sender state] == NSOnState);
|
||||
|
||||
if (enable) {
|
||||
}
|
||||
|
||||
// Update the user default MMRendererLigaturesSupport and synchronize the
|
||||
// change so that any new Vim process will pick up on the changed setting.
|
||||
CFPreferencesSetAppValue(
|
||||
(CFStringRef)MMRendererLigaturesSupportKey,
|
||||
(CFPropertyListRef)[NSNumber numberWithBool:enable],
|
||||
kCFPreferencesCurrentApplication);
|
||||
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
|
||||
|
||||
ASLogInfo(@"Use ligatures=%ld", enable);
|
||||
|
||||
// This action is called when the user clicks the "enable support for ligatures"
|
||||
// button in the advanced preferences pane.
|
||||
[self rebuildPreloadCache];
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)loginShellButtonClicked:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Toggle login shell option");
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
float fontDescent;
|
||||
BOOL antialias;
|
||||
BOOL useLigatures;
|
||||
NSMutableArray *drawData;
|
||||
|
||||
MMTextViewHelper *helper;
|
||||
|
||||
@@ -132,6 +132,17 @@ defaultAdvanceForFont(NSFont *font)
|
||||
[self registerForDraggedTypes:[NSArray arrayWithObjects:
|
||||
NSFilenamesPboardType, NSStringPboardType, nil]];
|
||||
|
||||
// Check if ligatures should be used or not
|
||||
{
|
||||
Boolean val;
|
||||
Boolean keyValid;
|
||||
val = CFPreferencesGetAppBooleanValue((CFStringRef)MMRendererLigaturesSupportKey,
|
||||
kCFPreferencesCurrentApplication,
|
||||
&keyValid);
|
||||
|
||||
useLigatures = NO;
|
||||
if(keyValid) { useLigatures = val; }
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -1017,14 +1028,67 @@ lookupFont(NSMutableArray *fontCache, const unichar *chars, UniCharCount count,
|
||||
return newFontRef;
|
||||
}
|
||||
|
||||
static void
|
||||
ligatureGlyphsForChars(const unichar *chars, CGGlyph *glyphs, UniCharCount *length, CTFontRef font )
|
||||
{
|
||||
/* CoreText has no simple wait of retrieving a ligature for a set of UniChars.
|
||||
* The way proposed on the CoreText ML is to convert the text to an attributed
|
||||
* string, create a CTLine from it and retrieve the Glyphs from the CTRuns in it.
|
||||
*/
|
||||
NSString *text = [NSString stringWithCharacters:chars
|
||||
length:*length];
|
||||
|
||||
NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
(id)font, kCTFontAttributeName,
|
||||
// 2 - full ligatures including rare
|
||||
[NSNumber numberWithInteger: 2], kCTLigatureAttributeName,
|
||||
nil
|
||||
];
|
||||
|
||||
NSAttributedString *attrText = [[NSAttributedString alloc] initWithString:text
|
||||
attributes:attrs];
|
||||
|
||||
CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)attrText);
|
||||
|
||||
UniCharCount offset = 0;
|
||||
NSArray *glyphRuns = (NSArray*)CTLineGetGlyphRuns(line);
|
||||
|
||||
for (id item in glyphRuns) {
|
||||
CTRunRef run = (CTRunRef)item;
|
||||
CFIndex count = CTRunGetGlyphCount(run);
|
||||
|
||||
if(count > 0) {
|
||||
if(count - offset > *length) {
|
||||
count = (*length) - offset;
|
||||
}
|
||||
}
|
||||
|
||||
CFRange range = CFRangeMake(0, count);
|
||||
CTRunGetGlyphs(run, range, &glyphs[offset]);
|
||||
|
||||
offset += count;
|
||||
if(offset >= *length) {
|
||||
// don't copy more glyphs then there is space for
|
||||
break;
|
||||
}
|
||||
}
|
||||
// as ligatures combine characters it is required to adjust the
|
||||
// original length value
|
||||
*length = offset;
|
||||
}
|
||||
|
||||
static void
|
||||
recurseDraw(const unichar *chars, CGGlyph *glyphs, CGPoint *positions,
|
||||
UniCharCount length, CGContextRef context, CTFontRef fontRef,
|
||||
NSMutableArray *fontCache)
|
||||
NSMutableArray *fontCache, BOOL useLigatures)
|
||||
{
|
||||
|
||||
if (CTFontGetGlyphsForCharacters(fontRef, chars, glyphs, length)) {
|
||||
// All chars were mapped to glyphs, so draw all at once and return.
|
||||
if (useLigatures) {
|
||||
memset(glyphs, 0, sizeof(CGGlyph) * length);
|
||||
ligatureGlyphsForChars(chars, glyphs, &length, fontRef);
|
||||
}
|
||||
|
||||
CGFontRef cgFontRef = CTFontCopyGraphicsFont(fontRef, NULL);
|
||||
CGContextSetFont(context, cgFontRef);
|
||||
CGContextShowGlyphsAtPositions(context, glyphs, positions, length);
|
||||
@@ -1077,7 +1141,7 @@ recurseDraw(const unichar *chars, CGGlyph *glyphs, CGPoint *positions,
|
||||
}
|
||||
|
||||
recurseDraw(chars, glyphs, positions, attemptedCount, context,
|
||||
fallback, fontCache);
|
||||
fallback, fontCache, useLigatures);
|
||||
|
||||
// If only a portion of the invalid range was rendered above,
|
||||
// the remaining range needs to be attempted by subsequent
|
||||
@@ -1201,7 +1265,7 @@ recurseDraw(const unichar *chars, CGGlyph *glyphs, CGPoint *positions,
|
||||
}
|
||||
|
||||
CGContextSetTextPosition(context, x, y+fontDescent);
|
||||
recurseDraw(chars, glyphs, positions, length, context, fontRef, fontCache);
|
||||
recurseDraw(chars, glyphs, positions, length, context, fontRef, fontCache, useLigatures);
|
||||
|
||||
CFRelease(fontRef);
|
||||
CGContextRestoreGState(context);
|
||||
|
||||
@@ -275,6 +275,7 @@ extern NSString *MMNoWindowKey;
|
||||
extern NSString *MMAutosaveRowsKey;
|
||||
extern NSString *MMAutosaveColumnsKey;
|
||||
extern NSString *MMRendererKey;
|
||||
extern NSString *MMRendererLigaturesSupportKey;
|
||||
|
||||
enum {
|
||||
MMRendererDefault = 0,
|
||||
|
||||
@@ -117,6 +117,7 @@ NSString *MMNoWindowKey = @"MMNoWindow";
|
||||
NSString *MMAutosaveRowsKey = @"MMAutosaveRows";
|
||||
NSString *MMAutosaveColumnsKey = @"MMAutosaveColumns";
|
||||
NSString *MMRendererKey = @"MMRenderer";
|
||||
NSString *MMRendererLigaturesSupportKey = @"MMRendererLigaturesSupport";
|
||||
|
||||
// Vim find pasteboard type (string contains Vim regex patterns)
|
||||
NSString *VimFindPboardType = @"VimFindPboardType";
|
||||
|
||||
Reference in New Issue
Block a user