Обзор FontPack

С помощью javascript возможно получить список шрифтов. Сайт также может получить более подробную информацию о шрифтах, установленных в системе. Сюда входят: список глифов для каждого шрифта, размер глифа и даже форма каждого символа. Многие библиотеки используют информацию о шрифтах для составления отпечатка целевого устройства. Следовательно, если данные шрифтов не будут изменены, качество эмуляции отпечатка будет ниже.

В версии BAS 25.4.0 мы значительно улучшили способ эмуляции шрифтов:

  • Собран список распространенных шрифтов для платформ Windows и Android. Для правильной работы на ПК с BAS необходимо установить FontPack. FontPack установленный в системе также можно использовать с любым скомпилированным скриптом.
  • Дополнен формат отпечатков, теперь он содержит список идентификаторов каждого шрифта.
  • Список идентификаторов для каждого отпечатка используются для поиска файлов шрифтов внутри FontPack. Файлы из FontPack используются вместо или вместе с системными шрифтами.

Данный подход позволяет сделать так, чтобы список шрифтов для каждого профиля выглядеть точно так же, как на устройстве, где был получен отпечаток. Заменяются не только имена шрифтов, но и данные шрифтов, поэтому, например, вы можете использовать шрифты Windows 11 в системе Windows 10. Также возможно эмулировать шрифты Android на платформе Windows.

Как использовать?

Для применения новых изменений вам необходимо скачать и установить дистрибутив FontPack:

Не забудьте запустить install.bat после распаковки.

FontPack устанавливается для всей системы. Это означает, что он будет использоваться для всех экземпляров BAS и всех скриптов, написанных с помощью BAS.

Нужно убедиться, что включен параметр «Использовать пак шрифтов» в действии «Применить отпечаток». Скриншот. Обратите внимание, что вам достаточно просто не выключать этот параметр, потому что он включен по умолчанию.

Убедитесь, что вы используете свежие отпечатки. В отпечатках, собранных до 20 января 2023 года, может отсутствовать необходимая информация.

Как это работает?

На диаграмме ниже показано, как работает изменение шрифтов:

Изменен процесс сбора отпечатков. В предыдущих версиях сохранялся только список семейств шрифтов. Этой информации не всегда достаточно для надежной эмуляции шрифтов, поскольку на разных машинах могут быть установлены разные версии шрифтов. Например, в Windows 10 обычно используется Arial версии 7.00, а в Windows 11 - Arial 7.01. Оба семейства - «Arial», но файлы шрифтов немного отличаются. После обновления мы собираем также список имен шрифтов, а не только семейств шрифтов. Для каждого шрифта система пытается определить файл, который более всего похож на оригинальный. Идентификатор шрифта сохраняется в json-файл отпечатка. Механизм идентификации файла шрифта не всегда точен. Это зависит от того, содержит ли FontPack нужный шрифт. Если шрифт отсутствует в базе, он будет заменен наиболее подходящим. Например, если в базе есть шрифты для Windows 8.1, Windows 10 и Windows 11 и будет осуществляться поиск шрифта Windows 7, результатом будет шрифт для Windows 8.1, так как он наиболее близок к Windows 7. В результате каждый отпечаток будет иметь набор идентификаторов, который может быть использован позже для поиска файлов внутри FontPack.

Вы можете проверить, как работает этот алгоритм, посетив следующую страницу https://data.bablosoft.com/fontid/. Она содержит список имен шрифтов, установленных в вашей системе, вместе с версиями шрифтов и идентификаторами шрифтов.

База содержит большое количество шрифтов, поэтому включить их в дистрибутив BAS затруднительно, иначе это может сильно увеличит его размер. Поэтому пользователь должен установить FontPack отдельно. Это делается один раз для всей системы. После установки его будут автоматически использовать все скрипты и экземпляры BAS. Если FontPack не установлен, BAS все равно будет работать, но без преимуществ точной замены шрифтов, вместо этого это будет использован старый алгоритм.

Каждый раз, когда браузеру нужно отобразить текст, он должен выбрать, какой шрифт использовать. Алгоритм выбора шрифта достаточно сложен, среди прочих могут быть такие ситуации: шрифт или список шрифтов может быть явно объявлен через css, требуемый шрифт может отсутствовать в системе, браузер должен найти редкий символ внутри системных шрифтов и т. д. BAS меняет поведение браузера для всех таких ситуаций, при этом используются следующие правила:

  • Браузер сначала будет искать нужный шрифт в списке шрифтов FontPack.
  • Если требуемый шрифт не будет найден внутри FontPack, поиск будет осуществляться внутри системных шрифтов.
  • Если определенный шрифт отсутствует в отпечатке, он будет заблокирован, даже если он присутствует в системе где запущен BAS или внутри FontPack.

Подводя итог можно сказать, что система попытается найти как можно более близкий шрифт к шрифту, присутствующему в отпечатке, но идеальное совпадение не всегда возможно.

Поддерживаемые платформы

Система рендеринга шрифтов в Chrome имеет много специфичного для платформы кода. Например, в Windows для выбора шрифтов используется DirectWrite, очевидно, что на других платформах этого API нет. Это означает, что даже если список шрифтов и данные шрифта будут одинаковыми, потребуются некоторые дополнительные усилия для эмуляции платформы, отличной от Windows. На данный момент поддерживается только эмуляция платформы Android. Другие операционные системы тоже будут работать с FontPack, но их поведение будет точно таким же, как у Windows.

Вот примеры поведения специфичного для Android, которое эмулируется должным образом:

  • Шрифты по умолчанию. Если на странице присутствует элемент без указания шрифта, он будет отображаться с помощью «Times New Roman» в Windows или «Noto Serif» в Android.
  • Псевдонимы шрифтов Android. При использовании шрифтов на Android с css браузер использует псевдонимы, а не настоящие шрифты, установленные в системе. Например, если на странице есть элемент с семейством шрифтов «Monaco», то текст будет отображаться не семейством шрифтов «Monaco», а его псевдонимом «Droid Sans Mono». На самом деле результаты получения списка семейств шрифтов для Android дают очень ограниченное число, около 15, в то время как в на целевых устройствах обычно гораздо больше шрифтов.
  • Выбор шрифта. Если определенный символ встречается в нескольких шрифтах, разные платформы могут выбирать разные шрифты. Это поведение эмулируется лишь частично.

Другие примеры, которые пока не эмулируются:

  • Если определенный символ будет отображаться внутри canvas, изображение может немного отличаться от исходной платформы. Используйте PerfectCanvas, чтобы решить эту проблему.
  • Некоторые символы могут быть загружены в Windows и не загружены в Android, и наоборот. Это происходит несмотря на то, что данные шрифта полностью идентичны. Пример: символ U+1FAE0.
  • Размеры некоторых символов может незначительно отличаться на разных платформах.

Отладка

Вы можете проверить, установлен ли FontPack на машине пользователя, выполнив следующий код:

native("fontpack","getfontpackpath","")

Если возвращаемая строка не пустая, FontPack установлен. Если нет, вы можете отобразить сообщение для пользователя со ссылкой для скачивания.

Используйте следующую команду, чтобы включить логи:

_settings({"Fingerprints.FontReplacementLogs":"Enable"})!

Они помещаются в файл s/UNIQUE_PROCESS_NAME.fonts.txt и по умолчанию отключены.