""" Generate a demo image for README.md showing font family switching feature. Creates a side-by-side comparison of the same content rendered in Sans, Serif, and Monospace fonts. """ 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, ImageDraw, ImageFont def create_demo_content(): """Create concise demo content that fits nicely on a small page""" blocks = [] # Title title_font = Font.from_family(BundledFont.SANS, font_size=28, weight=FontWeight.BOLD) title = Heading(level=HeadingLevel.H1, style=title_font) for word in "The Adventure Begins".split(): title.add_word(Word(word, title_font)) blocks.append(title) # Paragraph body_font = Font.from_family(BundledFont.SANS, font_size=14) para = Paragraph(body_font) text = ( "In the quiet village of Millbrook, young Emma discovered an ancient map " "hidden in her grandmother's attic. The parchment revealed a mysterious " "forest path marked with symbols she had never seen before. With courage " "in her heart and the map in her pocket, she set out at dawn to uncover " "the secrets that lay beyond the old oak trees." ) for word in text.split(): para.add_word(Word(word, body_font)) blocks.append(para) return blocks def render_with_font_family(blocks, page_size, font_family, family_name): """Render a page with a specific font family""" manager = create_ereader_manager( blocks, page_size, document_id=f"demo_{family_name.lower()}" ) # Set font family (None means original/default) manager.set_font_family(font_family) # Get the first page page = manager.get_current_page() return page.render() def create_comparison_image(): """Create a side-by-side comparison of all three font families""" # Page size for each panel page_width = 400 page_height = 300 # Create demo content print("Creating demo content...") blocks = create_demo_content() # Render with each font family print("Rendering with Sans font...") sans_image = render_with_font_family( blocks, (page_width, page_height), BundledFont.SANS, "Sans" ) print("Rendering with Serif font...") serif_image = render_with_font_family( blocks, (page_width, page_height), BundledFont.SERIF, "Serif" ) print("Rendering with Monospace font...") mono_image = render_with_font_family( blocks, (page_width, page_height), BundledFont.MONOSPACE, "Monospace" ) # Create a composite image with all three side by side spacing = 20 label_height = 30 total_width = page_width * 3 + spacing * 4 total_height = page_height + label_height + spacing * 2 composite = Image.new('RGB', (total_width, total_height), color='#f5f5f5') # Paste the three images x_positions = [ spacing, spacing * 2 + page_width, spacing * 3 + page_width * 2 ] for img, x_pos in zip([sans_image, serif_image, mono_image], x_positions): composite.paste(img, (x_pos, label_height + spacing)) # Add labels draw = ImageDraw.Draw(composite) # Try to use a nice font, fallback to default if not available try: label_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 20) except: label_font = ImageFont.load_default() labels = ["Sans-Serif", "Serif", "Monospace"] for label, x_pos in zip(labels, x_positions): # Calculate text position to center it bbox = draw.textbbox((0, 0), label, font=label_font) text_width = bbox[2] - bbox[0] text_x = x_pos + (page_width - text_width) // 2 draw.text((text_x, 5), label, fill='#333333', font=label_font) # Save the image output_path = "docs/images/font_family_switching.png" composite.save(output_path, quality=95) print(f"\nāœ“ Saved demo image to: {output_path}") print(f" Image size: {total_width}x{total_height}") return output_path def create_single_vertical_comparison(): """Create a vertical comparison that's better for README""" # Page size for each panel page_width = 700 page_height = 280 # Create demo content print("\nCreating vertical comparison for README...") blocks = create_demo_content() # Render with each font family print(" Rendering Sans...") sans_image = render_with_font_family( blocks, (page_width, page_height), BundledFont.SANS, "Sans" ) print(" Rendering Serif...") serif_image = render_with_font_family( blocks, (page_width, page_height), BundledFont.SERIF, "Serif" ) print(" Rendering Monospace...") mono_image = render_with_font_family( blocks, (page_width, page_height), BundledFont.MONOSPACE, "Monospace" ) # Create a composite image stacked vertically spacing = 15 label_width = 120 total_width = page_width + label_width + spacing * 2 total_height = page_height * 3 + spacing * 4 composite = Image.new('RGB', (total_width, total_height), color='#ffffff') # Add a subtle border draw = ImageDraw.Draw(composite) draw.rectangle([(0, 0), (total_width-1, total_height-1)], outline='#e0e0e0', width=1) # Paste the three images vertically y_positions = [ spacing, spacing * 2 + page_height, spacing * 3 + page_height * 2 ] images_data = [ (sans_image, "Sans-Serif", "#4A90E2"), (serif_image, "Serif", "#E94B3C"), (mono_image, "Monospace", "#50C878") ] # Try to use a nice font try: label_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 16) small_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 11) except: label_font = ImageFont.load_default() small_font = ImageFont.load_default() for (img, label, color), y_pos in zip(images_data, y_positions): # Paste the page image composite.paste(img, (label_width + spacing, y_pos)) # Draw label background draw.rectangle( [(spacing, y_pos + 10), (label_width, y_pos + 40)], fill=color ) # Draw label text draw.text( (spacing + 10, y_pos + 17), label, fill='#ffffff', font=label_font ) # Draw font description descriptions = { "Sans-Serif": "Clean & Modern", "Serif": "Classic & Formal", "Monospace": "Code & Technical" } draw.text( (spacing + 5, y_pos + 50), descriptions[label], fill='#666666', font=small_font ) # Save the image output_path = "docs/images/font_family_switching_vertical.png" composite.save(output_path, quality=95) print(f" āœ“ Saved: {output_path}") print(f" Size: {total_width}x{total_height}") return output_path if __name__ == "__main__": print("=" * 70) print("Generating README Demo Images") print("=" * 70) # Create both versions horizontal_path = create_comparison_image() vertical_path = create_single_vertical_comparison() print("\n" + "=" * 70) print("Demo images generated successfully!") print("=" * 70) print(f"\nHorizontal comparison: {horizontal_path}") print(f"Vertical comparison: {vertical_path}") print("\nRecommended for README: vertical version") print("\nMarkdown snippet:") print("```markdown") print("![Font Family Switching](docs/images/font_family_switching_vertical.png)") print("```") print()