How to disable font smoothing in Xcode 9? How to disable font smoothing in Xcode 9? ios ios

How to disable font smoothing in Xcode 9?


Mischief managed?

Here's a screenshot of my Xcode 9 with Deccy at 13pt:

The text appears crisp, with no blurred edges.

I believe the above is what you want. Here's stock Xcode displaying the same file:

Though the font was designed with crisp pixel boundaries, it appears here, blurred, as if seen through the haze of one too many hours programming.

But how?

I probed deep for a noninvasive way to accomplish this, and failed. As far as I can tell, the text rendering path in Xcode 9 very deliberately turns on font smoothing.

Before going any further, please file a feature request with Apple. It only takes a few minutes, and it's your best hope for an answer that that can be discussed in front of those with sound security instincts and strained cardiovasculature:

https://bugreport.apple.com/

I wrote an Xcode plugin. You might have heard that Xcode 9 uses code signing restrictions to forbid the loading of plugins. This is true, but a few mavericks press on, and tonight we ride with them.

Step one

There is a tool, update_xcode_plugins. You can use it to strip the code signature from your copy of Xcode, and with it the bundle-loading restriction:

$ gem install update_xcode_plugins$ update_xcode_plugins --unsign

If you change your mind, you can do this to revert to (a backup copy, I think?) of signed Xcode:

$ update_xcode_plugins --restore

Step two

There is another tool, Alcatraz. It's a plugin manager for Xcode. I chose to install it because it provides a plugin which provides a project template for plugins. I followed these instructions to install Alcatraz, which boil down to this:

$ git clone https://github.com/alcatraz/Alcatraz.git$ cd Alcatraz$ xcodebuild

I launched Xcode, clicked through the dialog warning me about the new plugin, and then used the newly-added Window > Package Manager to install the "Xcode Plugin" template.

Step three

I made a project with this template.

As I write this, the "Xcode Plugin" template hasn't been updated to support Xcode 9. No worries. I ran this command to grab Xcode 9's compatibility UUID:

$ defaults read /Applications/Xcode.app/Contents/Info DVTPlugInCompatibilityUUID

I visited my new project's Info.plist and added that UUID to the DVTPlugInCompatibilityUUIDs array.

Then, I linked SourceEditor.framework into my project. That was a two-step process:

  1. Visit the target's Build Settings. Add this to Framework Search Paths:

    /Applications/Xcode.app/Contents/SharedFrameworks/
  2. Visit the target's Build Phases. Add a new "Link Binary With Libraries" phase. Hit the plus. Navigate to the directory above (you can just press the / key and then paste the path in) and choose SourceEditor.framework. It should appear in the list. The project should still build.

Then, I made my plugin's .mm file look like this (I deleted the .h file, it's unneeded for this PoC):

#import <AppKit/AppKit.h>#include <dlfcn.h>extern void CGContextSetAllowsFontAntialiasing(CGContextRef, BOOL);static void hooked_sourceEditorSetFontSmoothingStyle(CGContextRef ctx) {    CGContextSetAllowsFontAntialiasing(ctx, NO);}@interface NoAA : NSObject@end@implementation NoAA+ (void)pluginDidLoad:(NSBundle *)plugin{    NSArray *allowedLoaders = [plugin objectForInfoDictionaryKey:@"me.delisa.XcodePluginBase.AllowedLoaders"];    if (![allowedLoaders containsObject:[[NSBundle mainBundle] bundleIdentifier]])        return;    Class cls = NSClassFromString(@"SourceEditorScrollView");    NSBundle* bundle = [NSBundle bundleForClass:cls];    void *handle = dlopen(bundle.executablePath.fileSystemRepresentation, RTLD_NOW);    if (!handle)        return;    uint8_t* set_font_smoothing_fn = dlsym(handle, "sourceEditorSetFontSmoothingStyle");    if (!set_font_smoothing_fn)        goto fin;    void* set_font_smoothing_fn_page = (void*)((long)set_font_smoothing_fn & -PAGE_SIZE);    if (mprotect(set_font_smoothing_fn_page, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC))        goto fin;    set_font_smoothing_fn[0] = 0xe9; // jmp    uint32_t* jmp_arg = (uint32_t*)(set_font_smoothing_fn + 1);    *jmp_arg = (uint32_t)((long)hooked_sourceEditorSetFontSmoothingStyle - (long)(jmp_arg + 1));    mprotect(set_font_smoothing_fn_page, PAGE_SIZE, PROT_READ | PROT_EXEC);fin:    dlclose(handle);}@end

…I think the gotos add character. Basically, it just defines a function that takes a CGContextRef and turns off text antialiasing for it. Then, it overwrites the beginning of a function inside the SourceEditor framework which ordinarily configures antialiasing settings — don't need that anymore — to jump to our function instead. It does all of this in an incredibly unsafe way, so if something goes wrong, Xcode may politely crash.

Build and run the project, which automatically installs the plugin. Accept the addition of your plugin, and that's that.

What now?

If anything here doesn't work because I messed up, let me know. I'm not planning to roll this into an Alcatraz plugin myself, but you or anyone else should free to do so with credit (after filing a feature request with Apple).

Happy hacking!


If you 'live' in XCode and need a crisp rendering of this TrueType font, then editing XCode application defaults with PrefEdit.app, or defaults write com.apple.dt.Xcode.* has no effect.

Default rendering

Thinking outside the box you might be interested in the following to achieve crispyness all-over your Mac.

Since the Deccy font is best viewed at 12pt, it makes sense to raise the AppleAntiAliasingThreshold in the global domain to 13, the default for this setting is 4.
You can also suggest no AppleFontSmoothing.

defaults write -g AppleFontSmoothing -int 0 defaults write -g AppleAntiAliasingThreshold -int 13

In addition to these tweaks a bit more can be achieved in the Accessibility Preference pane in System Preferences: The Display has 2 checkmarks that you should try: 'Differentiate without color', and 'Increase contrast'.

contrast rendering

"Beauty is in the eye of the beholder", I hope this helps.


Here are alternative steps that might work for you.

  1. Try to find the com.apple.dt.Xcode.plist file under Macintosh HD/Library/Preferences.
  2. Copy the file to desktop
  3. Open file and add NSFontDefaultScreenFontSubstitutionEnabled to (Boolean)YES
  4. add AppleAntiAliasingThreshold to (Number)24
  5. Replace this file with preference file
  6. Restart the system and Xcode

Note: For safer side keep backup of the original file.