pyWebLayout/FONT_SWITCHING_FEATURE.md
2025-11-12 12:03:27 +00:00

4.5 KiB

Dynamic Font Family Switching

The pyWebLayout ereader now supports dynamic font family switching, allowing readers to change fonts on-the-fly without losing their reading position.

Visual Demo

Font Family Switching

The same content rendered in Sans-Serif, Serif, and Monospace fonts

Features

  • Three Bundled Font Families: Sans-Serif (DejaVu Sans), Serif (DejaVu Serif), and Monospace (DejaVu Sans Mono)
  • Dynamic Switching: Change fonts instantly during reading
  • Position Preservation: Your reading position is maintained across font changes
  • Attribute Preservation: Bold, italic, size, and color are preserved when switching families
  • Automatic Cache Management: Intelligent cache invalidation ensures optimal performance

Usage

from pyWebLayout.style.fonts import BundledFont
from pyWebLayout.layout.ereader_manager import create_ereader_manager

# Create an ereader instance
manager = create_ereader_manager(blocks, page_size=(600, 800))

# Switch to serif font
manager.set_font_family(BundledFont.SERIF)
page = manager.get_current_page()

# Switch to monospace font
manager.set_font_family(BundledFont.MONOSPACE)
page = manager.get_current_page()

# Restore original fonts
manager.set_font_family(None)
page = manager.get_current_page()

# Query current font family
current_family = manager.get_font_family()  # Returns BundledFont or None

API Reference

EreaderLayoutManager Methods

set_font_family(family: Optional[BundledFont]) -> Page

Change the font family and re-render the current page.

Parameters:

  • family: Font family to use (BundledFont.SANS, BundledFont.SERIF, BundledFont.MONOSPACE, or None for original fonts)

Returns:

  • Re-rendered page with the new font family

Example:

# Switch to serif
page = manager.set_font_family(BundledFont.SERIF)

# Restore original fonts
page = manager.set_font_family(None)

get_font_family() -> Optional[BundledFont]

Get the current font family override.

Returns:

  • Current font family (BundledFont.SANS, BundledFont.SERIF, BundledFont.MONOSPACE) or None if using original fonts

Example:

family = manager.get_font_family()
if family:
    print(f"Currently using: {family.value}")
else:
    print("Using original fonts")

Font Families

Sans-Serif (BundledFont.SANS)

  • Font: DejaVu Sans
  • Best for: Screen reading, modern interfaces
  • Characteristics: Clean, legible, no decorative strokes

Serif (BundledFont.SERIF)

  • Font: DejaVu Serif
  • Best for: Long-form reading, formal documents
  • Characteristics: Traditional, classic appearance with decorative strokes

Monospace (BundledFont.MONOSPACE)

  • Font: DejaVu Sans Mono
  • Best for: Code, technical documentation
  • Characteristics: Fixed-width characters, uniform spacing

Examples

Complete Demo

See examples/11_font_family_switching_demo.py for a full demonstration including:

  • Creating ereader content
  • Switching between font families
  • Navigating with different fonts
  • Position tracking across font changes

Generate README Images

Run examples/generate_readme_font_demo.py to create comparison images:

python examples/generate_readme_font_demo.py

Implementation Details

The font family switching is implemented using a hybrid approach that combines:

  1. FontFamilyOverride class: Manages font preferences at render time
  2. Font transformation pipeline: Intercepts and transforms Font objects during rendering
  3. Intelligent caching: Automatic cache invalidation when font family changes
  4. Backward compatibility: Works with existing Font-based content without migration

This approach provides:

  • No breaking changes to existing code
  • Instant font switching without document recreation
  • Preservation of font attributes (weight, style, size, color)
  • Optimal performance with intelligent buffering

Technical Notes

  • Font family changes invalidate the page buffer cache
  • Reading position is preserved using the abstract document structure
  • Background rendering adapts to the new font family automatically
  • All three bundled fonts are included in the package (license: Bitstream Vera / Public Domain)

License

The bundled DejaVu fonts are free and open source under the Bitstream Vera License.