pyWebLayout/examples/01_simple_page_rendering.py
Duncan Tourolle 8b833eef0b
All checks were successful
Python CI / test (push) Successful in 6m46s
more fstring fixes
2025-11-09 00:15:25 +01:00

218 lines
5.6 KiB
Python

#!/usr/bin/env python3
"""
Simple Page Rendering Example
This example demonstrates:
- Creating pages with different styles
- Setting borders, padding, and background colors
- Understanding the page layout system
- Rendering pages to images
This is a foundational example showing the basic Page API.
"""
from pyWebLayout.style.page_style import PageStyle
from pyWebLayout.concrete.page import Page
import sys
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
# Add pyWebLayout to path
sys.path.insert(0, str(Path(__file__).parent.parent))
def draw_placeholder_content(page: Page):
"""Draw some placeholder content directly on the page to visualize the layout."""
if page.draw is None:
# Trigger canvas creation
page.render()
draw = page.draw
# Draw content area boundary (for visualization)
content_x = page.border_size + page.style.padding_left
content_y = page.border_size + page.style.padding_top
content_w = page.content_size[0]
content_h = page.content_size[1]
# Draw a light blue rectangle showing the content area
draw.rectangle(
[content_x, content_y, content_x + content_w, content_y + content_h],
outline=(100, 150, 255),
width=1
)
# Add some text labels
try:
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 12)
except BaseException:
font = ImageFont.load_default()
# Label the areas
draw.text(
(content_x + 10,
content_y + 10),
"Content Area",
fill=(
100,
100,
100),
font=font)
draw.text(
(10, 10), f"Border: {page.border_size}px", fill=(
150, 150, 150), font=font)
draw.text(
(content_x + 10,
content_y + 30),
f"Size: {content_w}x{content_h}",
fill=(
100,
100,
100),
font=font)
def create_example_1():
"""Example 1: Default page style."""
print("\n Creating Example 1: Default style...")
page = Page(size=(400, 300))
draw_placeholder_content(page)
return page
def create_example_2():
"""Example 2: Page with visible borders."""
print(" Creating Example 2: With borders...")
page_style = PageStyle(
border_width=3,
border_color=(255, 100, 100),
padding=(20, 20, 20, 20),
background_color=(255, 250, 250)
)
page = Page(size=(400, 300), style=page_style)
draw_placeholder_content(page)
return page
def create_example_3():
"""Example 3: Page with generous padding."""
print(" Creating Example 3: With padding...")
page_style = PageStyle(
border_width=2,
border_color=(100, 100, 255),
padding=(40, 40, 40, 40),
background_color=(250, 250, 255)
)
page = Page(size=(400, 300), style=page_style)
draw_placeholder_content(page)
return page
def create_example_4():
"""Example 4: Clean, borderless design."""
print(" Creating Example 4: Borderless...")
page_style = PageStyle(
border_width=0,
padding=(30, 30, 30, 30),
background_color=(245, 245, 245)
)
page = Page(size=(400, 300), style=page_style)
draw_placeholder_content(page)
return page
def combine_into_grid(pages, title):
"""Combine multiple pages into a 2x2 grid with title."""
print("\n Combining pages into grid...")
# Render all pages
images = [page.render() for page in pages]
# Grid layout
padding = 20
title_height = 40
cols = 2
rows = 2
# Calculate dimensions
img_width = images[0].size[0]
img_height = images[0].size[1]
total_width = cols * img_width + (cols + 1) * padding
total_height = rows * img_height + (rows + 1) * padding + title_height
# Create combined image
combined = Image.new('RGB', (total_width, total_height), (250, 250, 250))
draw = ImageDraw.Draw(combined)
# Draw title
try:
title_font = ImageFont.truetype(
"/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 20)
except BaseException:
title_font = ImageFont.load_default()
# Center the title
bbox = draw.textbbox((0, 0), title, font=title_font)
text_width = bbox[2] - bbox[0]
title_x = (total_width - text_width) // 2
draw.text((title_x, 10), title, fill=(50, 50, 50), font=title_font)
# Place pages in grid
y_offset = title_height + padding
for row in range(rows):
x_offset = padding
for col in range(cols):
idx = row * cols + col
if idx < len(images):
combined.paste(images[idx], (x_offset, y_offset))
x_offset += img_width + padding
y_offset += img_height + padding
return combined
def main():
"""Demonstrate basic page rendering."""
print("Simple Page Rendering Example")
print("=" * 50)
# Create different page examples
pages = [
create_example_1(),
create_example_2(),
create_example_3(),
create_example_4()
]
# Combine into a single demonstration image
combined_image = combine_into_grid(pages, "Page Styles: Border & Padding Examples")
# Save output
output_dir = Path("docs/images")
output_dir.mkdir(parents=True, exist_ok=True)
output_path = output_dir / "example_01_page_rendering.png"
combined_image.save(output_path)
print("\n✓ Example completed!")
print(f" Output saved to: {output_path}")
print(f" Image size: {combined_image.size[0]}x{combined_image.size[1]} pixels")
print(f" Created {len(pages)} page examples")
return combined_image
if __name__ == "__main__":
main()