Ответ 1
Неверное управление?
Вот скриншот моего Xcode 9 с Deccy в 13pt:
Я считаю, что это то, что вы хотите. Здесь Xcode содержит один и тот же файл:
Но как?
Я глубоко задумался о неинвазивном способе выполнить это и провалился. Насколько я могу судить, путь визуализации текста в Xcode 9 очень интенсивно включает сглаживание шрифтов.
Прежде чем идти дальше, пожалуйста, напишите запрос функции с Apple. Это займет всего несколько минут, и это лучшая надежда на ответ, который можно обсудить перед теми, у кого есть надежные инстинкты безопасности и напряженная кардиоваскуляризация:
Я написал плагин Xcode. Возможно, вы слышали, что Xcode 9 использует ограничения подписи кода, чтобы запретить загрузку плагинов. Это правда, но некоторые маверики нажимают, и сегодня вечером мы катаемся с ними.
Шаг первый
Есть инструмент, update_xcode_plugins. Вы можете использовать его для разметки подписи кода из вашей копии Xcode, а вместе с ней и ограничения на загрузку:
$ gem install update_xcode_plugins
$ update_xcode_plugins --unsign
Если вы передумаете, вы можете сделать это, чтобы вернуться к (резервной копии, я думаю?) подписанного Xcode:
$ update_xcode_plugins --restore
Шаг второй
Есть еще один инструмент, Alcatraz. Это менеджер плагинов для Xcode. Я решил установить его, потому что он предоставляет плагин, который предоставляет шаблон проекта для плагинов. Я выполнил эти инструкции, чтобы установить Alcatraz, что сводится к следующему:
$ git clone https://github.com/alcatraz/Alcatraz.git
$ cd Alcatraz
$ xcodebuild
Я запустил Xcode, щелкнув по диалогу, предупреждая меня о новом плагине, а затем использовал недавно добавленное окно > Менеджер пакетов для установки шаблона "Xcode Plugin".
Шаг третий
Я создал проект с этим шаблоном.
Как я пишу это, шаблон "Xcode Plugin" не обновлен для поддержки Xcode 9. Не беспокойтесь. Я выполнил эту команду, чтобы захватить UUID совместимости Xcode 9:
$ defaults read /Applications/Xcode.app/Contents/Info DVTPlugInCompatibilityUUID
Я посетил мой новый проект Info.plist и добавил, что UUID в массив DVTPlugInCompatibilityUUIDs
.
Затем я связал SourceEditor.framework
с моим проектом. Это был двухэтапный процесс:
-
Посетите целевые настройки сборки. Добавьте это в пути поиска Framework:
/Applications/Xcode.app/Contents/SharedFrameworks/
-
Перейдите на целевую фазу сборки. Добавьте новую фазу "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).
Счастливый взлом!