Friday, August 14, 2015

An Xcode Plug-in for Unsmoothed Text

Mike Ash:

Major trouble started when I got a retina display for my Mac Pro. I use it side by side with a normal non-retina display. Stuff that benefits from font smoothing, like web pages, e-mail, documentation, and cat pictures go on the retina display. Code goes on the regular display. However, the mere presence of the retina display made Xcode insist on font smoothing all over again, and the usual remedies were powerless.

I decided I’d have to get some code into Xcode and hack it from within. I thought about code injection using something like mach_inject or simply abusing lldb, but it turns out that Xcode has a built-in plugin mechanism that works well for this. It’s undocumented and not officially supported, but it’s not too hard to use.

[…]

The final and most annoying required key is DVTPlugInCompatibilityUUIDs. This is set to an array of strings. Each string is the UUID of an Xcode version that the plugin is compatible with. Each Xcode version has its own compatibility UUID. If your plugin doesn’t have the right UUID in its list, Xcode will refuse to load it.

[…]

Put this code in +load and our override now runs every time an NSTextView is drawn in Xcode.

What magic code goes in the override, though? With the surrounding code in place, it provides an excellent environment for experimentation. I tried CoreGraphics calls to disable font smoothing, I messed about with fonts, and various other things. I finally discovered that the magic incantation was to enable the use of screen fonts:

[[self layoutManager] setUsesScreenFonts: YES];

I’ve wanted something like this for a long time. Fortunately, NSTextView is not written in Swift, so it can be swizzled.

1 Comment RSS · Twitter

[…] the normal system preferences for controlling font smoothing. Lately, I’ve been using a plug-in to work around this. Xcode 8 has a new editor extensions feature but won’t load old-style […]

Leave a Comment