如何在Xcode 9中禁用字体平滑?

Des*_*ume 34 ide iphone xcode ios xcode9

我有一个很好的编程字体Deccy,只有在Xcode中禁用字体平滑(抗锯齿)才能看起来很好.使用Xcode 8,以下方法可以解决问题:

defaults write com.apple.dt.Xcode NSFontDefaultScreenFontSubstitutionEnabled -bool YES
defaults write com.apple.dt.Xcode AppleAntiAliasingThreshold 24
Run Code Online (Sandbox Code Playgroud)

但这不再适用于Xcode 9.

是否可以在Xcode 9中禁用字体平滑?

s4y*_*s4y 5

恶作剧管理?

这是我的Xcode 9的截图,Deccy在13pt:

文字看起来很清晰,边缘没有模糊.

我相信以上就是你想要的.这是股票Xcode显示相同的文件:

尽管字体的设计具有清晰的像素边界,但它在这里看起来很模糊,就像通过太多小时编程的阴霾看到的那样.

但是怎么样?

我深深探索了一种无创的方式来实现这一目标,并且失败了.据我所知,Xcode 9中的文本渲染路径非常刻意地打开字体平滑.

在继续之前,请向Apple提交功能请求.它只需要几分钟,这是你最好的答案,可以在具有良好安全本能和紧张的心血管系统的人面前讨论:

https://bugreport.apple.com/

我写了一个Xcode插件.您可能听说Xcode 9使用代码签名限制来禁止加载插件.这是事实,但是一些小牛队继续按下,今晚我们和他们一起骑车.

第一步

有一个工具,update_xcode_plugins.您可以使用它从您的Xcode副本中删除代码签名,并使用它来捆绑加载限制:

$ gem install update_xcode_plugins
$ update_xcode_plugins --unsign
Run Code Online (Sandbox Code Playgroud)

如果你改变主意,你可以这样做以恢复(签名副本,我认为?)签名的Xcode:

$ update_xcode_plugins --restore
Run Code Online (Sandbox Code Playgroud)

第二步

还有另一种工具,恶魔岛.它是Xcode的插件管理器.我选择安装它是因为它提供了一个插件,为插件提供项目模板.我按照这些说明安装恶魔岛,归结为:

$ git clone https://github.com/alcatraz/Alcatraz.git
$ cd Alcatraz
$ xcodebuild
Run Code Online (Sandbox Code Playgroud)

我启动了Xcode,点击对话框警告我有关新插件的信息,然后使用新添加的Window> Package Manager来安装"Xcode Plugin"模板.

第三步

我用这个模板制作了一个项目.

在我写这篇文章时,"Xcode插件"模板尚未更新以支持Xcode 9.不用担心.我运行此命令来获取Xcode 9的兼容性UUID:

$ defaults read /Applications/Xcode.app/Contents/Info DVTPlugInCompatibilityUUID
Run Code Online (Sandbox Code Playgroud)

我访问了我的新项目的Info.plist并将UUID添加到DVTPlugInCompatibilityUUIDs数组中.

然后,我链接SourceEditor.framework到我的项目.这是一个两步的过程:

  1. 访问目标的构建设置.将其添加到框架搜索路径:

    /Applications/Xcode.app/Contents/SharedFrameworks/
    
    Run Code Online (Sandbox Code Playgroud)
  2. 访问目标的构建阶段.添加一个新的"Link Binary With Libraries"阶段.点击加号.导航到上面的目录(您只需/按键,然后粘贴路径)并选择SourceEditor.framework.它应该出现在列表中.该项目仍应建立.

然后,我使我的插件.mm文件看起来像这样(我删除了.h文件,这个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
Run Code Online (Sandbox Code Playgroud)

...我认为gotos添加了字符.基本上,它只是定义了一个函数,它接受CGContextRef和关闭文本抗锯齿.然后,它覆盖SourceEditor框架内的函数的开头,该框架通常配置抗锯齿设置 - 不再需要它 - 而是跳转到我们的函数.它以令人难以置信的不安全方式完成所有这些工作,因此如果出现问题,Xcode可能会礼貌地崩溃.

构建并运行项目,自动安装插件.接受添加你的插件,就是这样.

现在怎么办?

如果这里的任何东西不起作用,因为我搞砸了,请告诉我.我打算自己将它转换成Alcatraz插件,但是你或其他任何人都可以免费提供信用(在向Apple提交功能请求之后).

快乐的黑客!