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

How to disable font smoothing in Xcode 9?

我有一个很棒的编程字体 Deccy,只有在 Xcode 中禁用字体平滑(抗锯齿)后才看起来不错。使用 Xcode 8 以下内容可以解决问题:

defaults write com.apple.dt.Xcode NSFontDefaultScreenFontSubstitutionEnabled -bool YES
defaults write com.apple.dt.Xcode AppleAntiAliasingThreshold 24

但这不再适用于 Xcode 9.

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

以下是可能适合您的备选步骤。

  1. 尝试在 Macintosh HD/Library/Preferences 下找到 com.apple.dt.Xcode.plist 文件。
  2. 将文件复制到桌面
  3. 打开文件并将 NSFontDefaultScreenFontSubstitutionEnabled 添加到 (Boolean)YES
  4. 将 AppleAntiAliasingThreshold 添加到(数字)24
  5. 用首选项文件替换此文件
  6. 重启系统Xcode

注意:为了安全起见,请保留原始文件的备份。

如果您在 XCode 中 'live' 并且需要清晰呈现此 TrueType 字体,则编辑 XCode 应用程序默认使用 PrefEdit.appdefaults write com.apple.dt.Xcode.*没有效果。

跳出框框思考,您可能会对以下内容感兴趣,以在您的 Mac.

中实现松脆

由于 Deccy 字体最好在 12pt 下查看,因此将全局域中的 AppleAntiAliasingThreshold 提高到 13 是有意义的,此设置的默认值为 4.
你也可以建议不要AppleFontSmoothing.

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

除了这些调整之外,还可以在系统偏好设置的 辅助功能偏好设置 窗格中实现更多功能:显示器有 2 个您应该尝试的复选标记:'不带颜色区分',和'增加对比度'。

"Beauty is in the eye of the beholder",希望对您有所帮助。

恶作剧得到解决?

这是我的 Xcode 9 的屏幕截图,Deccy 为 13pt:

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

但是如何呢?

我深入探索了一种非侵入性的方法来实现这一点,但失败了。据我所知,Xcode 9 中的文本渲染路径非常有意地打开了字体平滑。

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/

我写了一个 Xcode 插件。您可能听说过 Xcode 9 使用代码签名限制来禁止加载插件。这是事实,但一些特立独行的人继续前进,今晚我们与他们同行。

第一步

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

$ gem install update_xcode_plugins
$ update_xcode_plugins --unsign

如果您改变主意,可以执行此操作以恢复到(我认为是备份副本?)签名 Xcode:

$ update_xcode_plugins --restore

第二步

还有另一个工具 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 可以安装 Alcatraz,归结为:

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

我启动了 Xcode,点击了警告我有关新插件的对话框,然后使用新添加的 Window > 包管理器来安装 "Xcode Plugin" 模板。

第三步

我用这个模板做了一个项目。

在我撰写本文时,"Xcode Plugin" 模板尚未更新以支持 Xcode 9. 不用担心。我 运行 这个命令来获取 Xcode 9 的兼容性 UUID:

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

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

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

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

    /Applications/Xcode.app/Contents/SharedFrameworks/
    
  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

…我认为 goto 增加了字符。基本上,它只是定义了一个接受 CGContextRef 并为其关闭文本抗锯齿的函数。然后,它会覆盖 SourceEditor 框架内的一个函数的开头,该框架通常配置抗锯齿设置——不再需要了——跳转到我们的函数。它以一种非常不安全的方式执行所有这些操作,因此如果出现问题,Xcode 可能会礼貌地崩溃。

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

现在怎么办?

如果因为我搞砸了这里的任何东西不起作用,请告诉我。我 打算自己将其放入 Alcatraz 插件中,但您或其他任何人都应该免费这样做(在向 Apple 提交功能请求后)。

祝您黑客愉快!