241 lines
8.3 KiB
Python
241 lines
8.3 KiB
Python
"""
|
|
Demonstration of dynamic font family switching in the ereader.
|
|
|
|
This example shows how to:
|
|
1. Initialize an ereader with content
|
|
2. Dynamically switch between different font families (Sans, Serif, Monospace)
|
|
3. Maintain reading position across font changes
|
|
4. Use the font family API
|
|
|
|
The ereader manager provides a high-level API for changing fonts on-the-fly
|
|
without losing your place in the document.
|
|
"""
|
|
|
|
from pyWebLayout.abstract import Paragraph, Heading, Word
|
|
from pyWebLayout.abstract.block import HeadingLevel
|
|
from pyWebLayout.style import Font
|
|
from pyWebLayout.style.fonts import BundledFont, FontWeight
|
|
from pyWebLayout.style.page_style import PageStyle
|
|
from pyWebLayout.layout.ereader_manager import create_ereader_manager
|
|
from PIL import Image
|
|
|
|
|
|
def create_sample_content():
|
|
"""Create sample document content with various text styles"""
|
|
blocks = []
|
|
|
|
# Create a default font for the content
|
|
default_font = Font.from_family(BundledFont.SANS, font_size=16)
|
|
heading_font = Font.from_family(BundledFont.SANS, font_size=24, weight=FontWeight.BOLD)
|
|
|
|
# Title
|
|
title = Heading(level=HeadingLevel.H1, style=heading_font)
|
|
for word in "Font Family Switching Demo".split():
|
|
title.add_word(Word(word, heading_font))
|
|
blocks.append(title)
|
|
|
|
# Introduction paragraph
|
|
intro_font = Font.from_family(BundledFont.SANS, font_size=16)
|
|
intro = Paragraph(intro_font)
|
|
intro_text = (
|
|
"This demonstration shows how the ereader can dynamically switch between "
|
|
"different font families while maintaining your reading position. "
|
|
"The three bundled font families (Sans, Serif, and Monospace) can be "
|
|
"changed on-the-fly without recreating the document."
|
|
)
|
|
for word in intro_text.split():
|
|
intro.add_word(Word(word, intro_font))
|
|
blocks.append(intro)
|
|
|
|
# Section 1
|
|
section1_heading = Heading(level=HeadingLevel.H2, style=heading_font)
|
|
for word in "Sans-Serif Font".split():
|
|
section1_heading.add_word(Word(word, heading_font))
|
|
blocks.append(section1_heading)
|
|
|
|
para1 = Paragraph(default_font)
|
|
text1 = (
|
|
"Sans-serif fonts like DejaVu Sans are clean and modern, making them "
|
|
"ideal for screen reading. They lack the decorative strokes (serifs) "
|
|
"found in traditional typefaces, which can improve legibility on digital displays. "
|
|
"Many ereader applications default to sans-serif fonts for this reason."
|
|
)
|
|
for word in text1.split():
|
|
para1.add_word(Word(word, default_font))
|
|
blocks.append(para1)
|
|
|
|
# Section 2
|
|
section2_heading = Heading(level=HeadingLevel.H2, style=heading_font)
|
|
for word in "Serif Font".split():
|
|
section2_heading.add_word(Word(word, heading_font))
|
|
blocks.append(section2_heading)
|
|
|
|
para2 = Paragraph(default_font)
|
|
text2 = (
|
|
"Serif fonts like DejaVu Serif have small decorative strokes at the ends "
|
|
"of letter strokes. These fonts are traditionally used in print media and "
|
|
"can give a more formal, classic appearance. Many readers prefer serif fonts "
|
|
"for long-form reading as they find them easier on the eyes."
|
|
)
|
|
for word in text2.split():
|
|
para2.add_word(Word(word, default_font))
|
|
blocks.append(para2)
|
|
|
|
# Section 3
|
|
section3_heading = Heading(level=HeadingLevel.H2, style=heading_font)
|
|
for word in "Monospace Font".split():
|
|
section3_heading.add_word(Word(word, heading_font))
|
|
blocks.append(section3_heading)
|
|
|
|
para3 = Paragraph(default_font)
|
|
text3 = (
|
|
"Monospace fonts like DejaVu Sans Mono have equal spacing between all characters. "
|
|
"They are commonly used for displaying code, technical documentation, and typewriter-style "
|
|
"text. While less common for general reading, some users prefer the uniform character "
|
|
"spacing for certain types of content."
|
|
)
|
|
for word in text3.split():
|
|
para3.add_word(Word(word, default_font))
|
|
blocks.append(para3)
|
|
|
|
# Final paragraph
|
|
conclusion = Paragraph(default_font)
|
|
conclusion_text = (
|
|
"The ability to switch fonts dynamically is a key feature of modern ereaders. "
|
|
"It allows readers to customize their reading experience based on personal preference, "
|
|
"lighting conditions, and content type. Try switching between the three font families "
|
|
"to see which one you prefer for different types of reading."
|
|
)
|
|
for word in conclusion_text.split():
|
|
conclusion.add_word(Word(word, default_font))
|
|
blocks.append(conclusion)
|
|
|
|
return blocks
|
|
|
|
|
|
def render_pages_with_different_fonts(manager, output_prefix="demo_11"):
|
|
"""Render the same page with different font families"""
|
|
|
|
print("\nRendering pages with different font families...")
|
|
print("=" * 70)
|
|
|
|
font_families = [
|
|
(None, "Original (Sans)"),
|
|
(BundledFont.SERIF, "Serif"),
|
|
(BundledFont.MONOSPACE, "Monospace"),
|
|
(BundledFont.SANS, "Sans (explicit)")
|
|
]
|
|
|
|
images = []
|
|
|
|
for font_family, name in font_families:
|
|
print(f"\nRendering with {name} font...")
|
|
|
|
# Switch font family
|
|
manager.set_font_family(font_family)
|
|
|
|
# Get current page
|
|
page = manager.get_current_page()
|
|
|
|
# Render to image
|
|
image = page.render()
|
|
filename = f"{output_prefix}_{name.lower().replace(' ', '_').replace('(', '').replace(')', '')}.png"
|
|
image.save(filename)
|
|
print(f" Saved: {filename}")
|
|
|
|
images.append((name, image))
|
|
|
|
return images
|
|
|
|
|
|
def demonstrate_font_switching():
|
|
"""Main demonstration function"""
|
|
print("\n")
|
|
print("=" * 70)
|
|
print("Font Family Switching Demonstration")
|
|
print("=" * 70)
|
|
print()
|
|
|
|
# Create sample content
|
|
print("Creating sample document...")
|
|
blocks = create_sample_content()
|
|
print(f" Created {len(blocks)} blocks")
|
|
|
|
# Initialize ereader manager
|
|
print("\nInitializing ereader manager...")
|
|
page_size = (600, 800)
|
|
manager = create_ereader_manager(
|
|
blocks,
|
|
page_size,
|
|
document_id="font_switching_demo"
|
|
)
|
|
print(f" Page size: {page_size[0]}x{page_size[1]}")
|
|
print(f" Initial font family: {manager.get_font_family()}")
|
|
|
|
# Render pages with different fonts
|
|
images = render_pages_with_different_fonts(manager)
|
|
|
|
# Show position info
|
|
print("\nPosition information after font switches:")
|
|
print(" " + "-" * 66)
|
|
pos_info = manager.get_position_info()
|
|
print(f" Current position: Block {pos_info['position']['block_index']}, "
|
|
f"Word {pos_info['position']['word_index']}")
|
|
print(f" Font family: {pos_info['font_family'] or 'Original'}")
|
|
print(f" Font scale: {pos_info['font_scale']}")
|
|
print(f" Reading progress: {pos_info['progress']:.1%}")
|
|
|
|
# Test navigation with font switching
|
|
print("\nTesting navigation with font switching...")
|
|
print(" " + "-" * 66)
|
|
|
|
# Reset to beginning
|
|
manager.jump_to_position(manager.current_position.__class__())
|
|
|
|
# Advance a few pages with serif font
|
|
manager.set_font_family(BundledFont.SERIF)
|
|
print(f" Switched to SERIF font")
|
|
|
|
for i in range(3):
|
|
next_page = manager.next_page()
|
|
if next_page:
|
|
print(f" Page {i+2}: Advanced successfully")
|
|
|
|
# Switch to monospace
|
|
manager.set_font_family(BundledFont.MONOSPACE)
|
|
print(f" Switched to MONOSPACE font")
|
|
current_page = manager.get_current_page()
|
|
print(f" Re-rendered current page with new font")
|
|
|
|
# Go back a page
|
|
prev_page = manager.previous_page()
|
|
if prev_page:
|
|
print(f" Navigated back successfully")
|
|
|
|
# Cache statistics
|
|
print("\nCache statistics:")
|
|
print(" " + "-" * 66)
|
|
stats = manager.get_cache_stats()
|
|
for key, value in stats.items():
|
|
print(f" {key}: {value}")
|
|
|
|
print()
|
|
print("=" * 70)
|
|
print("Demo complete!")
|
|
print()
|
|
print("Key features demonstrated:")
|
|
print(" ✓ Dynamic font family switching (Sans, Serif, Monospace)")
|
|
print(" ✓ Position preservation across font changes")
|
|
print(" ✓ Automatic cache invalidation on font change")
|
|
print(" ✓ Navigation with different fonts")
|
|
print(" ✓ Font family info in position tracking")
|
|
print()
|
|
print("The rendered pages show the same content in different font families.")
|
|
print("Notice how the layout adapts while maintaining readability.")
|
|
print("=" * 70)
|
|
print()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
demonstrate_font_switching()
|