248 lines
7.4 KiB
Python
248 lines
7.4 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Page Layouts Example
|
||
|
||
This example demonstrates different page layout configurations:
|
||
- Various page sizes (small, medium, large)
|
||
- Different aspect ratios (portrait, landscape, square)
|
||
- Border and padding variations
|
||
- Color schemes
|
||
|
||
Shows how the pyWebLayout system handles different page dimensions.
|
||
"""
|
||
|
||
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 add_page_info(page: Page, title: str):
|
||
"""Add informational text to a page showing its properties."""
|
||
if page.draw is None:
|
||
page.render()
|
||
|
||
draw = page.draw
|
||
|
||
try:
|
||
font_large = ImageFont.truetype(
|
||
"/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 14)
|
||
font_small = ImageFont.truetype(
|
||
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 11)
|
||
except BaseException:
|
||
font_large = ImageFont.load_default()
|
||
font_small = ImageFont.load_default()
|
||
|
||
# Title
|
||
content_x = page.border_size + page.style.padding_left + 5
|
||
content_y = page.border_size + page.style.padding_top + 5
|
||
|
||
draw.text((content_x, content_y), title, fill=(40, 40, 40), font=font_large)
|
||
|
||
# Page info
|
||
y = content_y + 25
|
||
info = [
|
||
f"Page: {page.size[0]}×{page.size[1]}px",
|
||
f"Content: {page.content_size[0]}×{page.content_size[1]}px",
|
||
f"Border: {page.border_size}px",
|
||
f"Padding: {page.style.padding}",
|
||
]
|
||
|
||
for line in info:
|
||
draw.text((content_x, y), line, fill=(80, 80, 80), font=font_small)
|
||
y += 16
|
||
|
||
# Draw content area boundary
|
||
cx = page.border_size + page.style.padding_left
|
||
cy = page.border_size + page.style.padding_top
|
||
cw = page.content_size[0]
|
||
ch = page.content_size[1]
|
||
|
||
draw.rectangle(
|
||
[cx, cy, cx + cw, cy + ch],
|
||
outline=(150, 150, 255),
|
||
width=1
|
||
)
|
||
|
||
|
||
def create_layouts():
|
||
"""Create various page layout examples."""
|
||
layouts = []
|
||
|
||
# 1. Small portrait page
|
||
print("\n Creating layout examples...")
|
||
print(" - Small portrait")
|
||
style1 = PageStyle(
|
||
border_width=2,
|
||
border_color=(100, 100, 100),
|
||
padding=(15, 15, 15, 15),
|
||
background_color=(255, 255, 255)
|
||
)
|
||
page1 = Page(size=(300, 400), style=style1)
|
||
add_page_info(page1, "Small Portrait")
|
||
layouts.append(("small_portrait", page1))
|
||
|
||
# 2. Large portrait page
|
||
print(" - Large portrait")
|
||
style2 = PageStyle(
|
||
border_width=3,
|
||
border_color=(150, 100, 100),
|
||
padding=(30, 30, 30, 30),
|
||
background_color=(255, 250, 250)
|
||
)
|
||
page2 = Page(size=(400, 600), style=style2)
|
||
add_page_info(page2, "Large Portrait")
|
||
layouts.append(("large_portrait", page2))
|
||
|
||
# 3. Landscape page
|
||
print(" - Landscape")
|
||
style3 = PageStyle(
|
||
border_width=2,
|
||
border_color=(100, 150, 100),
|
||
padding=(20, 40, 20, 40),
|
||
background_color=(250, 255, 250)
|
||
)
|
||
page3 = Page(size=(600, 350), style=style3)
|
||
add_page_info(page3, "Landscape")
|
||
layouts.append(("landscape", page3))
|
||
|
||
# 4. Square page
|
||
print(" - Square")
|
||
style4 = PageStyle(
|
||
border_width=3,
|
||
border_color=(100, 100, 150),
|
||
padding=(25, 25, 25, 25),
|
||
background_color=(250, 250, 255)
|
||
)
|
||
page4 = Page(size=(400, 400), style=style4)
|
||
add_page_info(page4, "Square")
|
||
layouts.append(("square", page4))
|
||
|
||
# 5. Minimal padding
|
||
print(" - Minimal padding")
|
||
style5 = PageStyle(
|
||
border_width=1,
|
||
border_color=(180, 180, 180),
|
||
padding=(5, 5, 5, 5),
|
||
background_color=(245, 245, 245)
|
||
)
|
||
page5 = Page(size=(350, 300), style=style5)
|
||
add_page_info(page5, "Minimal Padding")
|
||
layouts.append(("minimal", page5))
|
||
|
||
# 6. Generous padding
|
||
print(" - Generous padding")
|
||
style6 = PageStyle(
|
||
border_width=2,
|
||
border_color=(150, 120, 100),
|
||
padding=(50, 50, 50, 50),
|
||
background_color=(255, 250, 245)
|
||
)
|
||
page6 = Page(size=(400, 400), style=style6)
|
||
add_page_info(page6, "Generous Padding")
|
||
layouts.append(("generous", page6))
|
||
|
||
return layouts
|
||
|
||
|
||
def create_layout_showcase(layouts):
|
||
"""Create a showcase image displaying all layouts."""
|
||
print("\n Creating layout showcase...")
|
||
|
||
# Render all pages
|
||
images = [(name, page.render()) for name, page in layouts]
|
||
|
||
# Calculate grid layout (3×2)
|
||
padding = 15
|
||
title_height = 50
|
||
cols = 3
|
||
rows = 2
|
||
|
||
# Find max dimensions for each row/column
|
||
max_widths = []
|
||
for col in range(cols):
|
||
col_images = [images[row * cols + col][1]
|
||
for row in range(rows) if row * cols + col < len(images)]
|
||
if col_images:
|
||
max_widths.append(max(img.size[0] for img in col_images))
|
||
|
||
max_heights = []
|
||
for row in range(rows):
|
||
row_images = [images[row * cols + col][1]
|
||
for col in range(cols) if row * cols + col < len(images)]
|
||
if row_images:
|
||
max_heights.append(max(img.size[1] for img in row_images))
|
||
|
||
# Calculate total size
|
||
total_width = sum(max_widths) + padding * (cols + 1)
|
||
total_height = sum(max_heights) + padding * (rows + 1) + title_height
|
||
|
||
# Create combined image
|
||
combined = Image.new('RGB', (total_width, total_height), (235, 235, 235))
|
||
draw = ImageDraw.Draw(combined)
|
||
|
||
# Add title
|
||
try:
|
||
title_font = ImageFont.truetype(
|
||
"/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 24)
|
||
except BaseException:
|
||
title_font = ImageFont.load_default()
|
||
|
||
title_text = "Page Layout Examples"
|
||
bbox = draw.textbbox((0, 0), title_text, font=title_font)
|
||
text_width = bbox[2] - bbox[0]
|
||
title_x = (total_width - text_width) // 2
|
||
draw.text((title_x, 15), title_text, fill=(50, 50, 50), font=title_font)
|
||
|
||
# Place images 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):
|
||
name, img = images[idx]
|
||
# Center image in its cell
|
||
cell_width = max_widths[col]
|
||
cell_height = max_heights[row]
|
||
img_x = x_offset + (cell_width - img.size[0]) // 2
|
||
img_y = y_offset + (cell_height - img.size[1]) // 2
|
||
combined.paste(img, (img_x, img_y))
|
||
x_offset += max_widths[col] + padding if col < len(max_widths) else 0
|
||
y_offset += max_heights[row] + padding if row < len(max_heights) else 0
|
||
|
||
return combined
|
||
|
||
|
||
def main():
|
||
"""Demonstrate page layout variations."""
|
||
print("Page Layouts Example")
|
||
print("=" * 50)
|
||
|
||
# Create different layouts
|
||
layouts = create_layouts()
|
||
|
||
# Create showcase
|
||
combined_image = create_layout_showcase(layouts)
|
||
|
||
# Save output
|
||
output_dir = Path("docs/images")
|
||
output_dir.mkdir(parents=True, exist_ok=True)
|
||
output_path = output_dir / "example_03_page_layouts.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(layouts)} layout examples")
|
||
|
||
return combined_image
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|