Skip to content

Use true bold fonts for PDF rendering instead of stroke-based fake bold#335

Merged
jinzhongjia merged 3 commits into
mainfrom
issue-334-check
Jun 24, 2026
Merged

Use true bold fonts for PDF rendering instead of stroke-based fake bold#335
jinzhongjia merged 3 commits into
mainfrom
issue-334-check

Conversation

@jinzhongjia

Copy link
Copy Markdown
Member

Summary

  • Added bold font variants (wght:700) for CJK and Sans fonts to support true bold rendering
  • Replaced stroke-based fake bold (fillThenStroke) with real bold glyphs
  • Solves CJK character overlap and spacing issues caused by outline expansion in fake bold

Technical Details

Previously, bold text was rendered by applying fillThenStroke rendering mode to normal-weight fonts, which expands the glyph outline. This causes problems in CJK text where the expanded strokes eat into inter-character spacing, leading to overlapping or squeezed characters.

This change uses actual bold font files (wght:700) for CJK and Sans fonts:

  • zigcourse-cjk-bold.ttf: Noto Serif SC at weight 700
  • zigcourse-sans-bold.ttf: Inter at weight 700

By using true bold glyphs:

  • getTextWidth() returns the correct advance width for bold fonts
  • Text layout respects actual glyph metrics instead of fake expansion
  • CJK text spacing and line height work correctly, consistent with EPUB rendering
  • Mono font keeps normal weight (no bold variant) since inline code doesn't need bold

Font subsetting reuses the same variable font sources; the fetch cache prevents re-downloading when pinning different weight axes.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request replaces the stroke-based faux bold rendering in PDF generation with real bold fonts (cjk-bold and sans-bold) to prevent character overlapping and spacing issues. The changes involve updating the font build script, loading the new bold font files, and registering them in the PDF renderer. The reviewer suggested optimizing the font loading process in scripts/pdf/main.ts by reading the files in parallel using Promise.all instead of sequentially.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread scripts/pdf/main.ts Outdated
Comment on lines +52 to +60
const fontMono = (
await readFile(path.join(ROOT, "assets/fonts/zigcourse-mono.ttf"))
).toString("base64");
const fontCjkBold = (
await readFile(path.join(ROOT, "assets/fonts/zigcourse-cjk-bold.ttf"))
).toString("base64");
const fontSansBold = (
await readFile(path.join(ROOT, "assets/fonts/zigcourse-sans-bold.ttf"))
).toString("base64");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

These font files are read sequentially using await. Since they are independent I/O operations, we can load them in parallel using Promise.all to improve build performance.

  const [fontMono, fontCjkBold, fontSansBold] = await Promise.all([
    readFile(path.join(ROOT, "assets/fonts/zigcourse-mono.ttf")).then((b) => b.toString("base64")),
    readFile(path.join(ROOT, "assets/fonts/zigcourse-cjk-bold.ttf")).then((b) => b.toString("base64")),
    readFile(path.join(ROOT, "assets/fonts/zigcourse-sans-bold.ttf")).then((b) => b.toString("base64")),
  ]);

采纳 PR #335 review 建议:5 份字体相互独立,用 Promise.all 并行读取,
并抽出 readFontB64 去掉 5 段重复的 readFile().toString() 样板。

@xihale xihale left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

文件必须要 b64 插入是因为要产生 HTML 单文件吗?

@jinzhongjia

Copy link
Copy Markdown
Member Author

是因为要产生 pdf 和 epub

@jinzhongjia

Copy link
Copy Markdown
Member Author

把图片嵌入

@jinzhongjia

Copy link
Copy Markdown
Member Author

这里的 request 你可以不管,ai 自己发起的

用新的竖版书封面(course/.vitepress/epub/cover.png)替换旧的横版插画,
居中并限定宽度展示;简介补上英文副标题与 PDF/EPUB 离线版本说明。
@jinzhongjia jinzhongjia merged commit 936d96d into main Jun 24, 2026
5 checks passed
jinzhongjia added a commit that referenced this pull request Jun 24, 2026
采纳 PR #335 review 建议:5 份字体相互独立,用 Promise.all 并行读取,
并抽出 readFontB64 去掉 5 段重复的 readFile().toString() 样板。
@jinzhongjia jinzhongjia deleted the issue-334-check branch June 24, 2026 08:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants