added fotn change API and examples
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
"""
|
||||
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()
|
||||
Reference in New Issue
Block a user