{"id":11933,"date":"2015-08-14T13:23:03","date_gmt":"2015-08-14T17:23:03","guid":{"rendered":"http:\/\/mjtsai.com\/blog\/?p=11933"},"modified":"2015-08-14T13:23:03","modified_gmt":"2015-08-14T17:23:03","slug":"an-xcode-plug-in-for-unsmoothed-text","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2015\/08\/14\/an-xcode-plug-in-for-unsmoothed-text\/","title":{"rendered":"An Xcode Plug-in for Unsmoothed Text"},"content":{"rendered":"<p><a href=\"https:\/\/www.mikeash.com\/pyblog\/friday-qa-2015-08-14-an-xcode-plugin-for-unsmoothed-text.html\">Mike Ash<\/a>:<\/p>\n<blockquote cite=\"https:\/\/www.mikeash.com\/pyblog\/friday-qa-2015-08-14-an-xcode-plugin-for-unsmoothed-text.html\">\n<p>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.<\/p>\n<p>I decided I&rsquo;d have to get some code into Xcode and hack it from within. I thought about code injection using something like <code>mach_inject<\/code> or simply abusing <code>lldb<\/code>, but it turns out that Xcode has a built-in plugin mechanism that works well for this. It&rsquo;s undocumented and not officially supported, but it&rsquo;s not too hard to use.<\/p>\n<p>[&#8230;]<\/p>\n<p>The final and most annoying required key is <code>DVTPlugInCompatibilityUUIDs<\/code>. 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&rsquo;t have the right UUID in its list, Xcode will refuse to load it.<\/p>\n<p>[&#8230;]<\/p>\n<p>Put this code in <code>+load<\/code> and our override now runs every time an <code>NSTextView<\/code> is drawn in Xcode.<\/p>\n<p>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:<\/p>\n<pre>[[self layoutManager] setUsesScreenFonts: YES];<\/pre>\n<\/blockquote>\n<p>I&rsquo;ve wanted something like this for a <a href=\"http:\/\/mjtsai.com\/blog\/2013\/10\/29\/mavericks-font-smoothing\/\">long<\/a> <a href=\"http:\/\/stackoverflow.com\/questions\/19035411\/disable-xcode-anti-aliasing-text-inside-the-code-editor\">time<\/a>. Fortunately, <code>NSTextView<\/code> is not written in Swift, so it can be swizzled.<\/p>","protected":false},"excerpt":{"rendered":"<p>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 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"","apple_news_api_id":"","apple_news_api_modified_at":"","apple_news_api_revision":"","apple_news_api_share_url":"","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[104,1244,903,966,760,74,71,83,226],"class_list":["post-11933","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-fontsmoothing","tag-haxie","tag-mac-os-x-10-10-yosemite","tag-message-passing","tag-objective-c-runtime","tag-opensource","tag-programming","tag-retina","tag-xcode"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/11933","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=11933"}],"version-history":[{"count":1,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/11933\/revisions"}],"predecessor-version":[{"id":11934,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/11933\/revisions\/11934"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=11933"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=11933"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=11933"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}