# 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](docs/images/font_family_switching_vertical.png) *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 ```python 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:** ```python # 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:** ```python 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](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](examples/generate_readme_font_demo.py) to create comparison images: ```bash 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](pyWebLayout/assets/fonts/DEJAVU_README.md).