@@ -221,6 +221,8 @@ - (id)initWithFrame:(NSRect)frame
221221{
222222 if (!(self = [super initWithFrame: frame]))
223223 return nil ;
224+
225+ forceRefreshFont = NO ;
224226
225227 self.wantsLayer = YES ;
226228
@@ -374,24 +376,57 @@ - (NSRect)rectForColumnsInRange:(NSRange)range
374376
375377- (void )setFont : (NSFont *)newFont
376378{
377- if (!newFont || [font isEqual: newFont])
379+ if (!newFont) {
378380 return ;
381+ }
382+ if (!forceRefreshFont) {
383+ if ([font isEqual: newFont])
384+ return ;
385+ }
386+ forceRefreshFont = NO ;
379387
380- double em = round (defaultAdvanceForFont (newFont));
388+ const double em = round (defaultAdvanceForFont (newFont));
381389
382- float cellWidthMultiplier = [[NSUserDefaults standardUserDefaults ]
390+ const float cellWidthMultiplier = [[NSUserDefaults standardUserDefaults ]
383391 floatForKey: MMCellWidthMultiplierKey];
384392
393+ // Some fonts have non-standard line heights, and historically MacVim has
394+ // chosen to ignore it. Provide the option for the user to choose whether to
395+ // use the font's line height. If not preserving, will create a new font
396+ // from scratch with just name and pt size, which will disard the line
397+ // height information.
398+ //
399+ // Defaults to the new behavior (preserveLineHeight==true) because it's
400+ // simpler and respects the font's design more.
401+ //
402+ // Note: this behavior is somewhat inconsistent across editors and
403+ // terminals. Xcode, for example, seems to be equivalent to
404+ // (preserveLineHeight==true), but other editors/terminals behave
405+ // differently. Xcode respecting the line height is partially the motivation
406+ // for setting that as the default.
407+ const BOOL preserveLineHeight = [[NSUserDefaults standardUserDefaults ]
408+ boolForKey: MMFontPreserveLineSpacingKey];
409+
410+ [font release ];
411+ if (!preserveLineHeight) {
412+ double pt = round ([newFont pointSize ]);
413+
414+ CTFontDescriptorRef desc = CTFontDescriptorCreateWithNameAndSize ((CFStringRef)[newFont fontName ], pt);
415+ CTFontRef fontRef = CTFontCreateWithFontDescriptor (desc, pt, NULL );
416+ CFRelease (desc);
417+
418+ font = (NSFont *)fontRef;
419+ } else {
420+ font = [newFont retain ];
421+ }
422+ fontDescent = ceil (CTFontGetDescent ((CTFontRef)font));
423+
385424 // NOTE! Even though NSFontFixedAdvanceAttribute is a float, it will
386425 // only render at integer sizes. Hence, we restrict the cell width to
387426 // an integer here, otherwise the window width and the actual text
388427 // width will not match.
389428 cellSize.width = columnspace + ceil (em * cellWidthMultiplier);
390- cellSize.height = linespace + defaultLineHeightForFont (newFont);
391-
392- [font release ];
393- font = [newFont retain ];
394- fontDescent = ceil (CTFontGetDescent ((CTFontRef)font));
429+ cellSize.height = linespace + defaultLineHeightForFont (font);
395430
396431 [self clearAll ];
397432 [fontVariants removeAllObjects ];
@@ -414,7 +449,17 @@ - (void)setWideFont:(NSFont *)newFont
414449 [fontVariants removeAllObjects ];
415450 [characterStrings removeAllObjects ];
416451 [characterLines removeAllObjects ];
452+ }
453+
454+ - (void )refreshFonts
455+ {
456+ // Mark force refresh, so that we won't try to use the cached font later.
457+ forceRefreshFont = YES ;
417458
459+ // Go through the standard path of updating fonts by passing the current
460+ // font in. This lets Vim itself knows about the font change and initiates
461+ // the resizing (depends on guioption-k) and redraws.
462+ [self changeFont: NSFontManager .sharedFontManager];
418463}
419464
420465- (NSFont *)font
@@ -893,6 +938,9 @@ - (NSSize)minSize
893938 MMMinRows * cellSize.height + insetSize.height + bot);
894939}
895940
941+ // Called when font panel selection has been made. Send the selected font to
942+ // MMBackend so it would set guifont which will send a message back to MacVim to
943+ // call MMWindowController::setFont.
896944- (void )changeFont : (id )sender
897945{
898946 NSFont *newFont = [sender convertFont: font];
0 commit comments