Skip to content

CRITICAL: Manim renders 4+ different fonts per page — must enforce single consistent font #4

@jmjava

Description

@jmjava

Problem — this is unacceptable

Manim renders text using multiple different fonts on the same frame with no warning. A single scene can produce output where:

  • The title uses one font
  • Bold text uses a completely different font (Pango falls back to a system default)
  • Bullet icons use yet another font
  • Regular body text uses the font you actually specified

The result looks like a ransom note. Characters have inconsistent kerning, different x-heights, different stroke weights, and different letter spacing — all on the same screen. This is not a cosmetic nit. It makes the output look broken and unprofessional.

Why this happens

Manim's Text class delegates to Pango for font rendering. When you set font="Lato" and weight=BOLD, Pango does NOT guarantee it will use Lato Bold. If it can't find an exact match for that family + weight combination, it silently substitutes a different font face from the system's fallback chain. The substitution varies by:

  • Which weights the font family actually has installed
  • The system's fontconfig priority order
  • Whether the text contains special characters (arrows, bullets, mathematical symbols)
  • Whether the text is being animated (Manim decomposes animated text into submobjects, and each submobject can independently trigger fallback)

There is no error, no warning, no log message. You only discover it by watching the rendered video and noticing that half the text looks like a different typeface.

What we observed in tekton-dag

On a single frame of segment 18:

  • Pillar card labels: rendered in Pango's default serif-like font (broken kerning)
  • Pillar title: rendered in the specified font (correct)
  • Key-value keys with weight=BOLD: rendered in a third font (wider character spacing)
  • Value text without bold: rendered correctly
  • Bullet characters: rendered in yet another font

This means a viewer sees 3-4 visually distinct typefaces on one screen. It looks like the video was assembled from screenshots of different applications.

Requirements for docgen

1. Single font, enforced globally — no exceptions

docgen must guarantee that every single glyph in a generated video uses the same font family. Not "mostly the same". Not "the same unless Pango decides otherwise". The same font, every character, every frame.

  • Text.set_default(font=...) must be called before ANY Text() is constructed
  • docgen validate should extract frames and run OCR font detection to verify visual consistency
  • Ban weight=BOLD — it is the primary trigger for Pango font substitution. Use font size and color for emphasis.

2. Choose a font that Pango actually respects

Not all fonts work equally well with Pango. Testing showed:

Font Regular Bold Verdict
Default (no font set) Broken kerning Worse Never use
Lato OK Broken kerning Avoid bold
Liberation Sans Clean Broken kerning Best option — no bold
DejaVu Sans Clean Acceptable Backup option
  • Default font in docgen.yaml should be Liberation Sans — it's installed on every Linux system (fonts-liberation package), renders cleanly in Pango, and has proper metrics
  • docgen init must verify the font is installed: fc-list "Liberation Sans" — and fail loudly if not
  • Add manim.font to docgen.yaml schema so users can override, but warn that bold will be disabled

3. Never use weight=BOLD anywhere in generated code

  • Auto-scene generator (Design flaw: Manim scene authoring is a manual gap in the pipeline #1) must never emit weight=BOLD
  • SectionScene base class must not use bold
  • docgen validate or docgen lint should scan scenes.py for weight=BOLD and flag it as an error
  • Document in the scene authoring guide: "BOLD weight is banned. Pango silently substitutes fonts when bold is requested. Use font size 18-24pt and color for emphasis."

4. Visual hierarchy without bold

Tested and proven approach from tekton-dag segment 18:

Title:      font_size=36, color=accent_color
Heading:    font_size=24, color=accent_color  
Body:       font_size=16, color=WHITE
Subtitle:   font_size=16, color=GREY_B
Muted:      font_size=15, color=GREY_B
Card label: font_size=15, color=WHITE

Color + size provides clear hierarchy. Bold adds nothing that size doesn't already accomplish, and bold breaks Pango.

5. Fallback character handling

Some characters (arrows , bullets , mathematical symbols ) trigger Pango fallback even with a font set.

  • Replace problematic unicode with ASCII equivalents in auto-generated scenes: -> instead of , - instead of , > instead of
  • OR pre-test each character against the configured font using manimpango and warn if any would trigger fallback
  • Maintain a safe character set list in docgen config

The bar

After this is implemented, a user should be able to run docgen manim && docgen compose && docgen validate and get output where every character on every frame uses the same font. If Pango would substitute even one glyph, docgen should catch it before the video is rendered and tell the user exactly which character is the problem.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions