Платформа

Рендеринг CJK: консистентные шрифты на всех платформах

Как работать с шрифтовыми средами для китайского, японского и корейского языков для согласованного вывода профилей на разных платформах и локалях.

Документация

Нужна поддерживаемая продуктовая документация?

У этой статьи есть соответствующая страница в центре документации. Используйте docs для каноничного сценария настройки, актуальных флагов и долгосрочной справки.

Введение

Рендеринг текста на китайском, японском и корейском языках (CJK) является одним из наиболее платформозависимых аспектов поведения браузера. Каждая операционная система поставляется с разными CJK-шрифтами, разными цепочками подстановки и разными движками рендеринга, которые дают визуально различающийся вывод. Windows использует Microsoft YaHei для упрощённого китайского, Meiryo для японского и Malgun Gothic для корейского. macOS использует PingFang для китайского, Hiragino Sans для японского и Apple SD Gothic для корейского. В дистрибутивах Linux обычно применяются семейства Noto Sans CJK или WenQuanYi.

Эти различия важны для отпечатков браузера, поскольку доступность шрифтов и результат рендеринга являются сильными платформенными сигналами. Профили BotBrowser фиксируют полную шрифтовую среду исходной системы, обеспечивая согласованный рендеринг CJK-текста независимо от ОС хоста и установленных на нём шрифтов.

Влияние на приватность: почему CJK-шрифты важны

Снятие отпечатков шрифтов - один из самых надёжных методов определения платформы и конфигурации браузера. Запрашивая доступность определённых шрифтов через CSS или Canvas-операции, системы отслеживания могут определить операционную систему, языковую конфигурацию и даже конкретные установленные программы.

CJK-шрифты особенно показательны, потому что:

  • Они крупные и платформозависимые. Шрифты Windows CJK недоступны на macOS или Linux, и наоборот.
  • Системы с поддержкой CJK имеют десятки дополнительных шрифтов по сравнению с установками только для западных языков, что делает список шрифтов сильным отличительным сигналом.
  • Результат рендеринга шрифтов (фактический вид текста на уровне пикселей) измеримо различается между DirectWrite (Windows), Core Text (macOS) и FreeType (Linux), даже когда используется одно и то же имя семейства шрифтов.

Для исследований приватности, нацеленных на рынки CJK, точные шрифтовые среды критически важны. Браузер, заявляющий себя как система Windows в Китае, но без Microsoft YaHei или SimSun, создаёт очевидное несоответствие. Аналогично, профиль macOS для Японии без Hiragino Sans не пройдёт проверки согласованности шрифтов.

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

Техническая база

Семейства CJK-шрифтов по платформам

Шрифты Windows CJK включают:

  • Упрощённый китайский: Microsoft YaHei, SimSun, SimHei, FangSong, KaiTi, NSimSun
  • Традиционный китайский: Microsoft JhengHei, MingLiU, PMingLiU
  • Японский: Yu Gothic, Meiryo, MS Gothic, MS Mincho, MS PGothic
  • Корейский: Malgun Gothic, Batang, Dotum, Gulim, Gungsuh

Шрифты macOS CJK включают:

  • Упрощённый китайский: PingFang SC, STHeiti, STSong, STKaiti, STFangsong
  • Традиционный китайский: PingFang TC, PingFang HK, LiSong Pro
  • Японский: Hiragino Sans, Hiragino Kaku Gothic, Hiragino Mincho
  • Корейский: Apple SD Gothic Neo, AppleMyungjo, Nanum Gothic

Шрифты Linux CJK обычно включают:

  • Все языки: Noto Sans CJK (в вариантах SC, TC, JP, KR), Noto Serif CJK
  • Китайский: WenQuanYi Micro Hei, WenQuanYi Zen Hei
  • Японский: IPAGothic, IPAMincho, Takao Gothic
  • Корейский: UnBatang, UnDotum

Цепочки подстановки шрифтов

Когда веб-страница указывает шрифт, который недоступен, браузер следует цепочке подстановки. Эта цепочка зависит от платформы:

  • В Windows подстановка для китайского текста обычно идёт к Microsoft YaHei, затем к SimSun
  • В macOS подстановка идёт к PingFang SC, затем к STHeiti
  • В Linux подстановка идёт к семействам Noto Sans CJK или WenQuanYi

Конкретное поведение подстановки является сигналом для снятия отпечатков. Если страница указывает font-family: "NonExistent Font", sans-serif, отрисованный текст будет выглядеть по-разному на каждой платформе, потому что итоговый подставляемый шрифт отличается.

Метрики и рендеринг шрифтов

Помимо доступности, CJK-шрифты дают разные метрики:

  • Ширина глифов: ширина отдельных символов различается между семействами шрифтов
  • Высота строки: междустрочный интервал по умолчанию отличается у разных CJK-шрифтов
  • Кернинг и интервалы: правила расстановки символов различаются между японской, китайской и корейской типографическими традициями
  • Хинтинг: пиксельный рендеринг символов при малых размерах зависит от таблиц хинтинга шрифта и движка рендеринга

Эти метрики влияют на расчёты макета, которые в свою очередь влияют на getBoundingClientRect(), getComputedStyle() и другие API измерения, используемые системами отслеживания.

Распространённые подходы и их ограничения

Установка CJK-шрифтов на хосте

Самый прямой подход - установить CJK-шрифты целевой платформы на хост-систему. Для Linux-сервера это означает установку основных шрифтов Microsoft, пакетов CJK-шрифтов или ручное добавление файлов шрифтов. Однако:

  • Это изменяет доступность шрифтов на уровне ОС, затрагивая все экземпляры браузера, а не только конкретные профили
  • Одновременная установка CJK-шрифтов Windows и macOS создаёт список шрифтов, не соответствующий ни одной реальной платформе
  • Рендеринг шрифтов по-прежнему использует движок хост-системы (FreeType в Linux), а не движок исходной платформы
  • Управление установками шрифтов на нескольких серверах добавляет операционную сложность

Внедрение веб-шрифтов

Некоторые подходы внедряют веб-шрифты через CSS для подмены системных шрифтов. Это позволяет контролировать визуальное отображение текста, но не влияет на запросы перечисления шрифтов. Тесты обнаружения шрифтов на JavaScript определяют доступность шрифта, измеряя изменения ширины текста при указании шрифта. Внедрённые веб-шрифты отображаются при рендеринге, но могут некорректно регистрироваться при таких проверках перечисления.

Расширения для подмены шрифтов

Расширения браузера, перехватывающие вызовы API, связанных со шрифтами, могут изменять сообщаемый список шрифтов. Однако они не могут изменить фактический результат рендеринга. Если сообщаемый список шрифтов говорит, что Microsoft YaHei доступен, но фактический рендеринг использует FreeType с другим шрифтом, несоответствие можно измерить через рендеринг текста на Canvas.

Подход BotBrowser

Профили BotBrowser фиксируют полную шрифтовую среду исходной системы. Это включает доступность шрифтов, характеристики рендеринга и метрики. Когда CJK-профиль загружается на любой ОС хоста, сигналы, связанные со шрифтами, точно соответствуют зафиксированной среде.

Шрифтовая среда на основе профиля

Каждый профиль несёт:

  • Полный список доступных шрифтов исходной системы
  • Метрики шрифтов, соответствующие движку рендеринга источника
  • Характеристики рендеринга текста Canvas с исходной платформы
  • Поведение подстановки шрифтов CSS, соответствующее исходной ОС

Это означает, что профиль Windows с китайской локалью корректно сообщает Microsoft YaHei, SimSun и другие CJK-шрифты Windows независимо от того, какие шрифты установлены на хосте.

Параметры настройки шрифтов

BotBrowser предоставляет флаг --bot-config-fonts для управления поведением шрифтов:

# Использовать встроенную шрифтовую среду профиля (по умолчанию)
--bot-config-fonts=profile

# Использовать шрифты профиля с дополнительными подставляемыми шрифтами
--bot-config-fonts=expand

# Использовать реальные шрифты хост-системы
--bot-config-fonts=real

Режим profile по умолчанию обеспечивает полную согласованность с зафиксированной средой. Режим expand добавляет подставляемые шрифты для обработки крайних случаев, когда набор шрифтов профиля не включает определённый символ. Режим real использует фактические шрифты хост-системы, что полезно для тестирования или когда нужно поведение шрифтов хоста.

Согласованность рендеринга

BotBrowser контролирует не только доступность шрифтов, но и то, как текст отрисовывается. Рендеринг текста Canvas и операции измерения текста дают вывод, согласованный с исходной платформой профиля. Это охватывает как визуальное отображение, так и программные метрики (ограничивающие рамки, ширины текста), на которые полагается снятие отпечатков шрифтов.

Настройка и использование

Китайская локаль (упрощённый)

chrome --bot-profile="/profiles/win11-zh-cn.enc" \
       --bot-config-locale=zh-CN \
       --bot-config-languages=zh-CN,zh,en \
       --bot-config-timezone=Asia/Shanghai

Японская локаль

chrome --bot-profile="/profiles/win11-ja.enc" \
       --bot-config-locale=ja-JP \
       --bot-config-languages=ja,en \
       --bot-config-timezone=Asia/Tokyo

Корейская локаль

chrome --bot-profile="/profiles/win11-ko.enc" \
       --bot-config-locale=ko-KR \
       --bot-config-languages=ko,en \
       --bot-config-timezone=Asia/Seoul

Пример Playwright с CJK-профилем

const { chromium } = require('playwright-core');

(async () => {
  const browser = await chromium.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/profiles/win11-zh-cn.enc',
      '--bot-config-locale=zh-CN',
      '--bot-config-languages=zh-CN,zh,en',
      '--bot-config-timezone=Asia/Shanghai',
    ],
    headless: true,
  });

  const context = await browser.newContext();
  const page = await context.newPage();
  await page.goto('https://www.baidu.com');

  // Проверка рендеринга CJK-шрифтов
  const fontCheck = await page.evaluate(() => {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    ctx.font = '16px "Microsoft YaHei"';
    const width = ctx.measureText('\u4F60\u597D').width; // «Привет» на китайском
    return { width, font: ctx.font };
  });
  console.log('CJK font check:', fontCheck);
  await browser.close();
})();

Полная CJK-идентичность

chrome --bot-profile="/profiles/win11-zh-cn.enc" \
       --bot-config-locale=zh-CN \
       --bot-config-languages=zh-CN,zh,en \
       --bot-config-timezone=Asia/Shanghai \
       --proxy-server=socks5://user:pass@cn-proxy:1080 \
       --bot-inject-random-history \
       --bot-bookmarks='[{"title":"\u767E\u5EA6","type":"url","url":"https://www.baidu.com"},{"title":"\u6DD8\u5B9D","type":"url","url":"https://www.taobao.com"}]'

Проверка

Проверьте обработку CJK-шрифтов, протестировав доступность шрифтов и рендеринг:

const page = await context.newPage();
await page.goto('about:blank');

const cjkVerification = await page.evaluate(() => {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');

  // Тест доступности шрифтов через сравнение ширины рендеринга
  const testFonts = [
    'Microsoft YaHei', 'SimSun', 'SimHei',      // Windows CN
    'PingFang SC', 'STHeiti',                     // macOS CN
    'Meiryo', 'Yu Gothic', 'MS Gothic',          // Windows JP
    'Hiragino Sans',                              // macOS JP
    'Malgun Gothic',                              // Windows KR
  ];

  const results = {};
  const fallbackWidth = (() => {
    ctx.font = '16px monospace';
    return ctx.measureText('\u4F60\u597D').width;
  })();

  for (const font of testFonts) {
    ctx.font = `16px "${font}", monospace`;
    const width = ctx.measureText('\u4F60\u597D').width;
    results[font] = width !== fallbackWidth;
  }

  return results;
});

console.log('CJK font availability:', cjkVerification);
CJK Font Families by Platform Windows CN: Microsoft YaHei CN: SimSun, SimHei JP: Yu Gothic, Meiryo JP: MS Gothic KR: Malgun Gothic KR: Batang, Gulim macOS CN: PingFang SC CN: STHeiti, STSong JP: Hiragino Sans JP: Hiragino Mincho KR: Apple SD Gothic KR: AppleMyungjo Linux All: Noto Sans CJK All: Noto Serif CJK CN: WenQuanYi JP: IPAGothic KR: UnBatang KR: UnDotum

Лучшие практики

  • Используйте профили, снятые с установок с соответствующей локалью. Профиль Windows, снятый с установки с китайской локалью, будет включать все CJK-шрифты, которые входят в эту конкретную конфигурацию Windows.
  • Всегда указывайте флаги локали, языка и часового пояса вместе. CJK-профили должны включать соответствующие --bot-config-locale, --bot-config-languages и --bot-config-timezone для полной идентичности.
  • Используйте региональные прокси. Сочетайте китайские профили с китайскими прокси, японские профили с японскими прокси, корейские профили с корейскими прокси.
  • Предпочитайте --bot-config-fonts=profile (значение по умолчанию). Это гарантирует использование зафиксированной шрифтовой среды профиля в точности как она была снята.
  • Тестируйте на страницах с большим количеством CJK-текста. Проверяйте рендеринг шрифтов на страницах с существенным CJK-контентом для подтверждения корректной работы шрифтовой среды.

Часто задаваемые вопросы

Нужно ли устанавливать CJK-шрифты на Linux-сервер?

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

Можно ли комбинировать CJK и западные шрифты в одном профиле?

Да. Все профили включают и CJK, и западные шрифты, если они присутствовали в исходной системе. Профиль Windows с китайской локалью включает как китайские шрифты, так и стандартные западные шрифты, такие как Arial, Segoe UI и другие.

Как работает опция --bot-config-fonts=expand?

Режим expand использует набор шрифтов профиля как основной источник, но добавляет подставляемые шрифты из хост-системы. Это полезно при обнаружении символов, не покрытых набором шрифтов профиля, таких как редкие символы Unicode или письменности, отсутствующие в исходной системе.

Соответствует ли рендеринг шрифтов в Canvas платформе профиля?

Да. BotBrowser контролирует рендеринг текста Canvas на уровне движка. Текст, отрисованный на Canvas с использованием CJK-шрифтов, даёт результат, согласованный с исходной платформой профиля, включая паттерны сглаживания и формы глифов.

Можно ли создать профиль с японскими и китайскими шрифтами одновременно?

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

Как проверить, что используются правильные CJK-шрифты?

Используйте измерение текста Canvas для сравнения ширины рендеринга между указанными CJK-шрифтами и подставляемыми шрифтами. Если указанный шрифт даёт ширину, отличную от подставляемого, шрифт доступен. Смотрите раздел «Проверка» выше для примера кода.

Итоги

Рендеринг CJK-шрифтов в BotBrowser обеспечивается через шрифтовые среды на основе профилей, снятых с реальных систем. Каждый профиль несёт полную информацию о доступности шрифтов и характеристиках рендеринга своей исходной платформы, обеспечивая согласованный вывод CJK-текста независимо от ОС хоста и установленных на нём шрифтов.

По смежным темам смотрите Отпечатки шрифтов для общего обзора снятия отпечатков шрифтов, Кроссплатформенные профили для запуска профилей на разных операционных системах и Часовой пояс, локаль и язык для согласования настроек локали с CJK-профилями.

#Cjk#Fonts#Chinese#Japanese#Rendering

Переведите BotBrowser из исследований в продакшн

Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.