From 2b8f1dc3d74c7ee59304832e4044ea90d81dfbd6 Mon Sep 17 00:00:00 2001 From: Bjorn Winckler Date: Tue, 6 Jan 2009 21:41:47 +0100 Subject: [PATCH] Don't load default font in Vim (faster startup) Loading and unloading a font can take a substantial amount of time so this cuts down on the startup time. --- src/MacVim/MMBackend.h | 6 +- src/MacVim/MMBackend.m | 52 +++++++---------- src/MacVim/MMVimController.m | 10 +++- src/MacVim/gui_macvim.m | 136 +++++++++++++++++++++---------------------- src/gui.h | 7 ++- 5 files changed, 103 insertions(+), 108 deletions(-) diff --git a/src/MacVim/MMBackend.h b/src/MacVim/MMBackend.h index e0dd8555..b2368e89 100644 --- a/src/MacVim/MMBackend.h +++ b/src/MacVim/MMBackend.h @@ -41,8 +41,7 @@ NSMutableDictionary *clientProxyDict; NSMutableDictionary *serverReplyDict; NSString *alternateServerName; - ATSFontContainerRef fontContainerRef; - NSFont *oldWideFont; + GuiFont oldWideFont; BOOL isTerminating; BOOL waitForAck; int initialWindowLayout; @@ -95,8 +94,7 @@ - (void)setScrollbarPosition:(int)pos length:(int)len identifier:(long)ident; - (void)setScrollbarThumbValue:(long)val size:(long)size max:(long)max identifier:(long)ident; -- (void)setFont:(NSFont *)font; -- (void)setWideFont:(NSFont *)font; +- (void)setFont:(GuiFont)font wide:(BOOL)wide; - (void)executeActionWithName:(NSString *)name; - (void)setMouseShape:(int)shape; - (void)setBlinkWait:(int)wait on:(int)on off:(int)off; diff --git a/src/MacVim/MMBackend.m b/src/MacVim/MMBackend.m index a5321801..b4f1c288 100644 --- a/src/MacVim/MMBackend.m +++ b/src/MacVim/MMBackend.m @@ -77,6 +77,9 @@ static NSString *MMSymlinkWarningString = "\ta symlink, then your MacVim.app bundle is incomplete.\n\n"; +extern GuiFont gui_mch_retain_font(GuiFont font); + + @interface NSString (MMServerNameCompare) - (NSComparisonResult)serverNameCompare:(NSString *)string; @@ -138,8 +141,6 @@ static NSString *MMSymlinkWarningString = self = [super init]; if (!self) return nil; - fontContainerRef = loadFonts(); - outputQueue = [[NSMutableArray alloc] init]; inputQueue = [[NSMutableArray alloc] init]; drawData = [[NSMutableData alloc] initWithCapacity:1024]; @@ -173,7 +174,7 @@ static NSString *MMSymlinkWarningString = //NSLog(@"%@ %s", [self className], _cmd); [[NSNotificationCenter defaultCenter] removeObserver:self]; - [oldWideFont release]; oldWideFont = nil; + gui_mch_free_font(oldWideFont); oldWideFont = NOFONT; [blinkTimer release]; blinkTimer = nil; [alternateServerName release]; alternateServerName = nil; [serverReplyDict release]; serverReplyDict = nil; @@ -485,10 +486,10 @@ static NSString *MMSymlinkWarningString = if ([drawData length] > 0) { // HACK! Detect changes to 'guifontwide'. - if (gui.wide_font != (GuiFont)oldWideFont) { - [oldWideFont release]; - oldWideFont = [(NSFont*)gui.wide_font retain]; - [self setWideFont:oldWideFont]; + if (gui.wide_font != oldWideFont) { + gui_mch_free_font(oldWideFont); + oldWideFont = gui_mch_retain_font(gui.wide_font); + [self setFont:oldWideFont wide:YES]; } int type = SetCursorPosDrawType; @@ -593,11 +594,6 @@ static NSString *MMSymlinkWarningString = [[NSConnection defaultConnection] invalidate]; #endif - if (fontContainerRef) { - ATSFontDeactivate(fontContainerRef, NULL, kATSOptionFlagsDefault); - fontContainerRef = 0; - } - usleep(MMExitProcessDelay); } @@ -834,35 +830,27 @@ static NSString *MMSymlinkWarningString = [self queueMessage:SetScrollbarThumbMsgID data:data]; } -- (void)setFont:(NSFont *)font +- (void)setFont:(GuiFont)font wide:(BOOL)wide { - NSString *fontName = [font displayName]; - float size = [font pointSize]; - int len = [fontName lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - if (len > 0) { - NSMutableData *data = [NSMutableData data]; - - [data appendBytes:&size length:sizeof(float)]; - [data appendBytes:&len length:sizeof(int)]; - [data appendBytes:[fontName UTF8String] length:len]; - - [self queueMessage:SetFontMsgID data:data]; + NSString *fontName = (NSString *)font; + float size = 0; + NSArray *components = [fontName componentsSeparatedByString:@":"]; + if ([components count] == 2) { + size = [[components lastObject] floatValue]; + fontName = [components objectAtIndex:0]; } -} -- (void)setWideFont:(NSFont *)font -{ - NSString *fontName = [font displayName]; - float size = [font pointSize]; int len = [fontName lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; NSMutableData *data = [NSMutableData data]; - [data appendBytes:&size length:sizeof(float)]; [data appendBytes:&len length:sizeof(int)]; + if (len > 0) [data appendBytes:[fontName UTF8String] length:len]; + else if (!wide) + return; // Only the wide font can be set to nothing - [self queueMessage:SetWideFontMsgID data:data]; + [self queueMessage:(wide ? SetWideFontMsgID : SetFontMsgID) data:data]; } - (void)executeActionWithName:(NSString *)name @@ -2139,7 +2127,7 @@ static NSString *MMSymlinkWarningString = bytes += sizeof(unsigned); // len not used NSMutableString *name = [NSMutableString stringWithUTF8String:bytes]; - [name appendString:[NSString stringWithFormat:@":h%.2f", pointSize]]; + [name appendString:[NSString stringWithFormat:@":h%d", (int)pointSize]]; char_u *s = (char_u*)[name UTF8String]; #ifdef FEAT_MBYTE diff --git a/src/MacVim/MMVimController.m b/src/MacVim/MMVimController.m index db94b73b..be3d28c8 100644 --- a/src/MacVim/MMVimController.m +++ b/src/MacVim/MMVimController.m @@ -859,10 +859,14 @@ static BOOL isUnsafeMessage(int msgid); initWithBytes:(void*)bytes length:len encoding:NSUTF8StringEncoding]; NSFont *font = [NSFont fontWithName:name size:size]; + if (!font) { + // This should never happen, but if e.g. the default font was + // missing from the app bundle we might end up here. + NSLog(@"WARNING: Can't set font %@, using Cocoa default", name); + font = [NSFont userFixedPitchFontOfSize:0]; + } - if (font) - [windowController setFont:font]; - + [windowController setFont:font]; [name release]; } else if (SetWideFontMsgID == msgid) { const void *bytes = [data bytes]; diff --git a/src/MacVim/gui_macvim.m b/src/MacVim/gui_macvim.m index 896f9fd0..138c859c 100644 --- a/src/MacVim/gui_macvim.m +++ b/src/MacVim/gui_macvim.m @@ -22,13 +22,13 @@ // NOTE: The default font is bundled with the application. static NSString *MMDefaultFontName = @"DejaVu Sans Mono"; -static float MMDefaultFontSize = 12.0f; -static float MMMinFontSize = 6.0f; -static float MMMaxFontSize = 100.0f; +static int MMDefaultFontSize = 12; +static int MMMinFontSize = 6; +static int MMMaxFontSize = 100; static BOOL gui_mch_init_has_finished = NO; -static NSFont *gui_macvim_font_with_name(char_u *name); +static GuiFont gui_macvim_font_with_name(char_u *name); static int specialKeyToNSKey(int key); static int vimModMaskToEventModifierFlags(int mods); @@ -897,11 +897,18 @@ gui_mch_free_font(font) { if (font != NOFONT) { //NSLog(@"gui_mch_free_font(font=0x%x)", font); - [(NSFont*)font release]; + [(id)font release]; } } + GuiFont +gui_mch_retain_font(GuiFont font) +{ + return (GuiFont)[(id)font retain]; +} + + /* * Get a font structure for highlighting. */ @@ -911,9 +918,9 @@ gui_mch_get_font(char_u *name, int giveErrorIfMissing) //NSLog(@"gui_mch_get_font(name=%s, giveErrorIfMissing=%d)", name, // giveErrorIfMissing); - NSFont *font = gui_macvim_font_with_name(name); - if (font) - return (GuiFont)[font retain]; + GuiFont font = gui_macvim_font_with_name(name); + if (font != NOFONT) + return font; if (giveErrorIfMissing) EMSG2(_(e_font), name); @@ -925,14 +932,12 @@ gui_mch_get_font(char_u *name, int giveErrorIfMissing) #if defined(FEAT_EVAL) || defined(PROTO) /* * Return the name of font "font" in allocated memory. - * Don't know how to get the actual name, thus use the provided name. + * TODO: use 'font' instead of 'name'? */ char_u * gui_mch_get_fontname(GuiFont font, char_u *name) { - if (name == NULL) - return NULL; - return vim_strsave(name); + return name ? vim_strsave(name) : NULL; } #endif @@ -952,24 +957,24 @@ gui_mch_init_font(char_u *font_name, int fontset) return FAIL; } - NSFont *font = gui_macvim_font_with_name(font_name); - if (font) { - [(NSFont*)gui.norm_font release]; - gui.norm_font = (GuiFont)[font retain]; + GuiFont font = gui_macvim_font_with_name(font_name); + if (font == NOFONT) + return FAIL; - // NOTE: MacVim keeps separate track of the normal and wide fonts. - // Unless the user changes 'guifontwide' manually, they are based on - // the same (normal) font. Also note that each time the normal font is - // set, the advancement may change so the wide font needs to be updated - // as well (so that it is always twice the width of the normal font). - [[MMBackend sharedInstance] setFont:font]; - [[MMBackend sharedInstance] setWideFont: - (NOFONT == gui.wide_font ? font : (NSFont*)gui.wide_font)]; + gui_mch_free_font(gui.norm_font); + gui.norm_font = font; - return OK; - } + // NOTE: MacVim keeps separate track of the normal and wide fonts. + // Unless the user changes 'guifontwide' manually, they are based on + // the same (normal) font. Also note that each time the normal font is + // set, the advancement may change so the wide font needs to be updated + // as well (so that it is always twice the width of the normal font). + [[MMBackend sharedInstance] setFont:font wide:NO]; + [[MMBackend sharedInstance] setFont:(NOFONT != gui.wide_font ? gui.wide_font + : font) + wide:YES]; - return FAIL; + return OK; } @@ -983,63 +988,58 @@ gui_mch_set_font(GuiFont font) } - NSFont * +/* + * Return GuiFont in allocated memory. The caller must free it using + * gui_mch_free_font(). + */ + GuiFont gui_macvim_font_with_name(char_u *name) { - NSFont *font = nil; - NSString *fontName = MMDefaultFontName; - float size = MMDefaultFontSize; - BOOL parseFailed = NO; + if (!name) + return (GuiFont)[[NSString alloc] initWithFormat:@"%@:%d", + MMDefaultFontName, MMDefaultFontSize]; -#ifdef FEAT_MBYTE - name = CONVERT_TO_UTF8(name); -#endif + NSString *fontName = [NSString stringWithVimString:name]; + int size = MMDefaultFontSize; + BOOL parseFailed = NO; - if (name) { - fontName = [NSString stringWithUTF8String:(char*)name]; - - NSArray *components = [fontName componentsSeparatedByString:@":"]; - if ([components count] == 2) { - NSString *sizeString = [components lastObject]; - if ([sizeString length] > 0 - && [sizeString characterAtIndex:0] == 'h') { - sizeString = [sizeString substringFromIndex:1]; - if ([sizeString length] > 0) { - size = [sizeString floatValue]; - fontName = [components objectAtIndex:0]; - } - } else { - parseFailed = YES; + NSArray *components = [fontName componentsSeparatedByString:@":"]; + if ([components count] == 2) { + NSString *sizeString = [components lastObject]; + if ([sizeString length] > 0 + && [sizeString characterAtIndex:0] == 'h') { + sizeString = [sizeString substringFromIndex:1]; + if ([sizeString length] > 0) { + size = (int)round([sizeString floatValue]); + fontName = [components objectAtIndex:0]; } - } else if ([components count] > 2) { + } else { parseFailed = YES; } + } else if ([components count] > 2) { + parseFailed = YES; + } - if (!parseFailed) { - // Replace underscores with spaces. - fontName = [[fontName componentsSeparatedByString:@"_"] - componentsJoinedByString:@" "]; - } + if (!parseFailed) { + // Replace underscores with spaces. + fontName = [[fontName componentsSeparatedByString:@"_"] + componentsJoinedByString:@" "]; } if (!parseFailed && [fontName length] > 0) { if (size < MMMinFontSize) size = MMMinFontSize; if (size > MMMaxFontSize) size = MMMaxFontSize; - font = [NSFont fontWithName:fontName size:size]; - - if (!font && MMDefaultFontName == fontName) { - // If for some reason the MacVim default font is not in the app - // bundle, then fall back on the system default font. - font = [NSFont userFixedPitchFontOfSize:0]; - } + // If the default font is requested we don't check if NSFont can load + // it since the font most likely isn't loaded anyway (it may only be + // available to the MacVim binary). If it is not the default font we + // ask NSFont if it can load it. + if ([fontName isEqualToString:MMDefaultFontName] + || [NSFont fontWithName:fontName size:size]) + return [[NSString alloc] initWithFormat:@"%@:%d", fontName, size]; } -#ifdef FEAT_MBYTE - CONVERT_TO_UTF8_FREE(name); -#endif - - return font; + return NOFONT; } // -- Scrollbars ------------------------------------------------------------ diff --git a/src/gui.h b/src/gui.h index 8cb349ae..af0319fa 100644 --- a/src/gui.h +++ b/src/gui.h @@ -235,7 +235,12 @@ typedef long guicolor_T; /* handle for a GUI color; for X11 this should displays there is a tiny chance this is an actual color */ -#ifdef FEAT_GUI_GTK +#if defined(FEAT_GUI_MACVIM) + typedef void *GuiFont; + typedef void *GuiFontset; +# define NOFONT (GuiFont)NULL +# define NOFONTSET (GuiFontset)NULL +#elif defined(FEAT_GUI_GTK) # ifdef HAVE_GTK2 typedef PangoFontDescription *GuiFont; /* handle for a GUI font */ typedef PangoFontDescription *GuiFontset; /* handle for a GUI fontset */ -- 2.11.4.GIT