Back to Blog
Platform

CJK Font Rendering in Browser Profiles: Chinese, Japanese, Korean

How to handle Chinese, Japanese, and Korean font environments for consistent profile output across different platforms and locales.

Introduction

Chinese, Japanese, and Korean (CJK) text rendering is one of the most platform-specific aspects of browser behavior. Each operating system ships with different CJK fonts, different fallback chains, and different rendering engines that produce visibly different output. Windows uses Microsoft YaHei for simplified Chinese, Meiryo for Japanese, and Malgun Gothic for Korean. macOS uses PingFang for Chinese, Hiragino Sans for Japanese, and Apple SD Gothic for Korean. Linux distributions commonly rely on Noto Sans CJK or WenQuanYi families.

These differences matter for browser fingerprinting because font availability and rendering output are strong platform signals. BotBrowser profiles capture the complete font environment from the source system, ensuring that CJK text renders consistently regardless of the host OS and regardless of which fonts are locally installed.

Privacy Impact: Why CJK Fonts Matter

Font fingerprinting is one of the most reliable methods for identifying a browser's platform and configuration. By querying the availability of specific fonts through CSS or Canvas operations, tracking systems can determine the operating system, language configuration, and even specific software installations.

CJK fonts are particularly revealing because:

  • They are large and platform-specific. Windows CJK fonts are not available on macOS or Linux, and vice versa.
  • CJK-capable systems have dozens of additional fonts compared to Western-only installations, making the font list a strong distinguishing signal.
  • Font rendering output (the actual pixel-level appearance of text) differs measurably between DirectWrite (Windows), Core Text (macOS), and FreeType (Linux), even when the same font family name is used.

For privacy research targeting CJK markets, accurate font environments are essential. A browser claiming to be a Windows system running in China but missing Microsoft YaHei or SimSun presents an obvious inconsistency. Similarly, a macOS profile targeting Japan without Hiragino Sans would fail font-based consistency checks.

For multi-account management serving CJK regions, each identity needs a font environment that matches its supposed platform and locale combination.

Technical Background

CJK Font Families by Platform

Windows CJK fonts include:

  • Simplified Chinese: Microsoft YaHei, SimSun, SimHei, FangSong, KaiTi, NSimSun
  • Traditional Chinese: Microsoft JhengHei, MingLiU, PMingLiU
  • Japanese: Yu Gothic, Meiryo, MS Gothic, MS Mincho, MS PGothic
  • Korean: Malgun Gothic, Batang, Dotum, Gulim, Gungsuh

macOS CJK fonts include:

  • Simplified Chinese: PingFang SC, STHeiti, STSong, STKaiti, STFangsong
  • Traditional Chinese: PingFang TC, PingFang HK, LiSong Pro
  • Japanese: Hiragino Sans, Hiragino Kaku Gothic, Hiragino Mincho
  • Korean: Apple SD Gothic Neo, AppleMyungjo, Nanum Gothic

Linux CJK fonts commonly include:

  • All languages: Noto Sans CJK (in SC, TC, JP, KR variants), Noto Serif CJK
  • Chinese: WenQuanYi Micro Hei, WenQuanYi Zen Hei
  • Japanese: IPAGothic, IPAMincho, Takao Gothic
  • Korean: UnBatang, UnDotum

Font Fallback Chains

When a webpage specifies a font that is not available, the browser follows a fallback chain. This chain is platform-specific:

  • On Windows, the fallback for Chinese text typically goes to Microsoft YaHei, then SimSun
  • On macOS, it falls back to PingFang SC, then STHeiti
  • On Linux, it falls back to Noto Sans CJK or WenQuanYi families

The specific fallback behavior is a fingerprinting signal. If the page specifies font-family: "NonExistent Font", sans-serif, the rendered text will look different on each platform because the ultimate fallback font differs.

Font Metrics and Rendering

Beyond just font availability, CJK fonts produce different metrics:

  • Glyph widths: The width of individual characters varies between font families
  • Line height: Default line spacing differs between CJK fonts
  • Kerning and spacing: Character spacing rules differ between Japanese, Chinese, and Korean typographic conventions
  • Hinting: The pixel-level rendering of characters at small sizes depends on the font's hinting tables and the rendering engine

These metrics affect layout calculations, which in turn affect getBoundingClientRect(), getComputedStyle(), and other measurement APIs that tracking systems use.

Common Approaches and Their Limitations

Installing CJK Fonts on the Host

The most direct approach is installing the target platform's CJK fonts on your host system. For a Linux server, this means installing Microsoft core fonts, CJK font packages, or manually adding font files. However:

  • This changes font availability at the OS level, affecting all browser instances, not just specific profiles
  • Having both Windows and macOS CJK fonts installed simultaneously creates a font list that matches no real platform
  • Font rendering still uses the host system's rendering engine (FreeType on Linux), not the source platform's engine
  • Managing font installations across multiple servers adds operational complexity

Web Font Injection

Some approaches inject web fonts through CSS to override the system fonts. This can control the visual appearance of text but does not affect font enumeration queries. JavaScript-based font detection tests whether a font is available by measuring text width changes when the font is specified. Injected web fonts appear in rendering but may not register correctly in these enumeration checks.

Font Spoofing Extensions

Browser extensions that intercept font-related API calls can modify the reported font list. However, they cannot change the actual rendering output. If the reported font list says Microsoft YaHei is available but the actual rendering uses FreeType with a different font, the inconsistency is measurable through Canvas text rendering.

BotBrowser's Approach

BotBrowser profiles capture the complete font environment from the source system. This includes font availability, rendering characteristics, and metrics. When a CJK profile is loaded on any host OS, the font-related signals match the captured environment exactly.

Profile-Based Font Environment

Each profile carries:

  • The complete list of available fonts from the source system
  • Font metrics that match the source rendering engine
  • Canvas text rendering characteristics from the source platform
  • CSS font fallback behavior matching the source OS

This means a Windows profile with Chinese locale correctly reports Microsoft YaHei, SimSun, and other Windows CJK fonts, regardless of what fonts are installed on the host.

Font Configuration Options

BotBrowser provides the --bot-config-fonts flag to control font behavior:

# Use the profile's embedded font environment (default)
--bot-config-fonts=profile

# Use profile fonts with additional fallback fonts
--bot-config-fonts=expand

# Use the host system's real fonts
--bot-config-fonts=real

The default profile mode ensures complete consistency with the captured environment. The expand mode adds fallback fonts to handle edge cases where the profile's font set does not include a specific character. The real mode uses the host system's actual fonts, which is useful for testing or when you want the host's font behavior.

Rendering Consistency

BotBrowser controls not just font availability but also how text is rendered. Canvas text rendering and text measurement operations produce output consistent with the profile's source platform. This covers both the visual appearance and the programmatic metrics (bounding boxes, text widths) that font fingerprinting relies on.

Configuration and Usage

Chinese Locale (Simplified)

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

Japanese Locale

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

Korean Locale

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

Playwright Example with CJK Profile

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');

  // Verify CJK font rendering
  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; // "Hello" in Chinese
    return { width, font: ctx.font };
  });
  console.log('CJK font check:', fontCheck);
  await browser.close();
})();

Complete CJK Identity

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"}]'

Verification

Verify CJK font handling by checking font availability and rendering:

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');

  // Test font availability through rendering width comparison
  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

Best Practices

  • Use profiles captured from matching locale installations. A Windows profile captured from a Chinese locale installation will include all the CJK fonts that come with that specific Windows configuration.
  • Always pair locale, language, and timezone flags. CJK profiles should include matching --bot-config-locale, --bot-config-languages, and --bot-config-timezone for a complete identity.
  • Use regional proxies. Pair Chinese profiles with Chinese proxies, Japanese profiles with Japanese proxies, and Korean profiles with Korean proxies.
  • Prefer --bot-config-fonts=profile (the default). This ensures the profile's captured font environment is used exactly as captured.
  • Test with CJK-heavy pages. Verify font rendering on pages with substantial CJK content to confirm the font environment is working correctly.

Frequently Asked Questions

Do I need to install CJK fonts on my Linux server?

No. BotBrowser profiles carry the font environment from the source system. The profile determines which fonts are reported as available, regardless of what is installed on the host.

Can I mix CJK and Western fonts in a single profile?

Yes. All profiles include both CJK and Western fonts if they were present on the source system. A Windows profile with Chinese locale includes both Chinese fonts and standard Western fonts like Arial, Segoe UI, and others.

How does the --bot-config-fonts=expand option work?

The expand mode uses the profile's font set as the primary source but adds fallback fonts from the host system. This is useful when encountering characters not covered by the profile's font set, such as rare Unicode symbols or scripts not present in the source system.

Does font rendering in Canvas match the profile platform?

Yes. BotBrowser controls Canvas text rendering at the engine level. Text drawn on Canvas using CJK fonts produces output consistent with the profile's source platform, including anti-aliasing patterns and glyph shapes.

Can I create a profile with both Japanese and Chinese fonts?

Profiles reflect the source system's configuration. A Windows system with both Japanese and Chinese language packs installed will have both sets of fonts in its profile. Use profiles captured from multi-language installations for this use case.

How do I verify that the correct CJK fonts are being used?

Use Canvas text measurement to compare rendering widths between specified CJK fonts and fallback fonts. If the specified font produces a different width than the fallback, the font is available. See the Verification section above for a code example.

Summary

CJK font rendering in BotBrowser is handled through profile-based font environments captured from real systems. Each profile carries the complete font availability and rendering characteristics of its source platform, ensuring consistent CJK text output regardless of the host OS and its locally installed fonts.

For related topics, see Font Fingerprinting for the broader font fingerprinting overview, Cross-Platform Profiles for running profiles across operating systems, and Timezone, Locale, and Language for matching locale settings with CJK profiles.

#cjk#fonts#chinese#japanese#rendering