auto flake and corrections
This commit is contained in:
@@ -9,15 +9,13 @@ This module provides the concrete rendering classes for tables, including:
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import Tuple, List, Optional, Dict
|
||||
import numpy as np
|
||||
from PIL import Image, ImageDraw
|
||||
from dataclasses import dataclass
|
||||
|
||||
from pyWebLayout.core.base import Renderable, Queriable
|
||||
from pyWebLayout.core.base import Renderable
|
||||
from pyWebLayout.concrete.box import Box
|
||||
from pyWebLayout.abstract.block import Table, TableRow, TableCell, Paragraph, Heading, Image as AbstractImage
|
||||
from pyWebLayout.abstract.interactive_image import InteractiveImage
|
||||
from pyWebLayout.style import Font, Alignment
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -49,8 +47,15 @@ class TableCellRenderer(Box):
|
||||
Supports paragraphs, headings, images, and links within cells.
|
||||
"""
|
||||
|
||||
def __init__(self, cell: TableCell, origin: Tuple[int, int], size: Tuple[int, int],
|
||||
draw: ImageDraw.Draw, style: TableStyle, is_header_section: bool = False,
|
||||
def __init__(self,
|
||||
cell: TableCell,
|
||||
origin: Tuple[int,
|
||||
int],
|
||||
size: Tuple[int,
|
||||
int],
|
||||
draw: ImageDraw.Draw,
|
||||
style: TableStyle,
|
||||
is_header_section: bool = False,
|
||||
canvas: Optional[Image.Image] = None):
|
||||
"""
|
||||
Initialize a table cell renderer.
|
||||
@@ -111,17 +116,20 @@ class TableCellRenderer(Box):
|
||||
# Get font
|
||||
try:
|
||||
if self._is_header_section and self._style.header_text_bold:
|
||||
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 12)
|
||||
font = ImageFont.truetype(
|
||||
"/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 12)
|
||||
else:
|
||||
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 12)
|
||||
except:
|
||||
font = ImageFont.truetype(
|
||||
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 12)
|
||||
except BaseException:
|
||||
font = ImageFont.load_default()
|
||||
|
||||
# Render each block in the cell
|
||||
for block in self._cell.blocks():
|
||||
if isinstance(block, AbstractImage):
|
||||
# Render image
|
||||
current_y = self._render_image_in_cell(block, x, current_y, width, height - (current_y - y))
|
||||
current_y = self._render_image_in_cell(
|
||||
block, x, current_y, width, height - (current_y - y))
|
||||
elif isinstance(block, (Paragraph, Heading)):
|
||||
# Extract and render text
|
||||
words = []
|
||||
@@ -137,7 +145,8 @@ class TableCellRenderer(Box):
|
||||
if words:
|
||||
text = " ".join(words)
|
||||
if current_y <= y + height - 15:
|
||||
self._draw.text((x + 2, current_y), text, fill=(0, 0, 0), font=font)
|
||||
self._draw.text((x + 2, current_y), text,
|
||||
fill=(0, 0, 0), font=font)
|
||||
current_y += 16
|
||||
|
||||
if current_y > y + height - 10: # Don't overflow cell
|
||||
@@ -145,10 +154,18 @@ class TableCellRenderer(Box):
|
||||
|
||||
# If no structured content, try to get any text representation
|
||||
if current_y == y + 2 and hasattr(self._cell, '_text_content'):
|
||||
self._draw.text((x + 2, current_y), self._cell._text_content, fill=(0, 0, 0), font=font)
|
||||
self._draw.text(
|
||||
(x + 2,
|
||||
current_y),
|
||||
self._cell._text_content,
|
||||
fill=(
|
||||
0,
|
||||
0,
|
||||
0),
|
||||
font=font)
|
||||
|
||||
def _render_image_in_cell(self, image_block: AbstractImage, x: int, y: int,
|
||||
max_width: int, max_height: int) -> int:
|
||||
max_width: int, max_height: int) -> int:
|
||||
"""
|
||||
Render an image block inside a table cell.
|
||||
|
||||
@@ -181,7 +198,8 @@ class TableCellRenderer(Box):
|
||||
# Use more of the cell space for images
|
||||
img_width, img_height = img.size
|
||||
scale_w = max_width / img_width if img_width > max_width else 1
|
||||
scale_h = (max_height - 10) / img_height if img_height > (max_height - 10) else 1
|
||||
scale_h = (max_height - 10) / \
|
||||
img_height if img_height > (max_height - 10) else 1
|
||||
scale = min(scale_w, scale_h, 1.0) # Don't upscale
|
||||
|
||||
new_width = int(img_width * scale)
|
||||
@@ -210,8 +228,9 @@ class TableCellRenderer(Box):
|
||||
# Draw image indicator text
|
||||
from PIL import ImageFont
|
||||
try:
|
||||
small_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 9)
|
||||
except:
|
||||
small_font = ImageFont.truetype(
|
||||
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 9)
|
||||
except BaseException:
|
||||
small_font = ImageFont.load_default()
|
||||
|
||||
text = f"[Image: {new_width}x{new_height}]"
|
||||
@@ -219,7 +238,9 @@ class TableCellRenderer(Box):
|
||||
text_width = bbox[2] - bbox[0]
|
||||
text_x = img_x + (new_width - text_width) // 2
|
||||
text_y = y + (new_height - 12) // 2
|
||||
self._draw.text((text_x, text_y), text, fill=(100, 100, 100), font=small_font)
|
||||
self._draw.text(
|
||||
(text_x, text_y), text, fill=(
|
||||
100, 100, 100), font=small_font)
|
||||
|
||||
# Set bounds on InteractiveImage objects for tap detection
|
||||
if isinstance(image_block, InteractiveImage):
|
||||
@@ -230,7 +251,7 @@ class TableCellRenderer(Box):
|
||||
|
||||
return y + new_height + 5 # Add some spacing after image
|
||||
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
# If image loading fails, just return current position
|
||||
return y + 20
|
||||
|
||||
@@ -240,9 +261,15 @@ class TableRowRenderer(Box):
|
||||
Renders a single table row containing multiple cells.
|
||||
"""
|
||||
|
||||
def __init__(self, row: TableRow, origin: Tuple[int, int],
|
||||
column_widths: List[int], row_height: int,
|
||||
draw: ImageDraw.Draw, style: TableStyle, is_header_section: bool = False,
|
||||
def __init__(self,
|
||||
row: TableRow,
|
||||
origin: Tuple[int,
|
||||
int],
|
||||
column_widths: List[int],
|
||||
row_height: int,
|
||||
draw: ImageDraw.Draw,
|
||||
style: TableStyle,
|
||||
is_header_section: bool = False,
|
||||
canvas: Optional[Image.Image] = None):
|
||||
"""
|
||||
Initialize a table row renderer.
|
||||
@@ -309,9 +336,14 @@ class TableRenderer(Box):
|
||||
Handles layout calculation, row/cell placement, and overall table structure.
|
||||
"""
|
||||
|
||||
def __init__(self, table: Table, origin: Tuple[int, int],
|
||||
available_width: int, draw: ImageDraw.Draw,
|
||||
style: Optional[TableStyle] = None, canvas: Optional[Image.Image] = None):
|
||||
def __init__(self,
|
||||
table: Table,
|
||||
origin: Tuple[int,
|
||||
int],
|
||||
available_width: int,
|
||||
draw: ImageDraw.Draw,
|
||||
style: Optional[TableStyle] = None,
|
||||
canvas: Optional[Image.Image] = None):
|
||||
"""
|
||||
Initialize a table renderer.
|
||||
|
||||
@@ -331,8 +363,10 @@ class TableRenderer(Box):
|
||||
|
||||
# Calculate table dimensions
|
||||
self._column_widths, self._row_heights = self._calculate_dimensions()
|
||||
total_width = sum(self._column_widths) + self._style.border_width * (len(self._column_widths) + 1)
|
||||
total_height = sum(self._row_heights.values()) + self._style.border_width * (len(self._row_heights) + 1)
|
||||
total_width = sum(self._column_widths) + \
|
||||
self._style.border_width * (len(self._column_widths) + 1)
|
||||
total_height = sum(self._row_heights.values()) + \
|
||||
self._style.border_width * (len(self._row_heights) + 1)
|
||||
|
||||
super().__init__(origin, (total_width, total_height))
|
||||
self._row_renderers: List[TableRowRenderer] = []
|
||||
@@ -362,7 +396,8 @@ class TableRenderer(Box):
|
||||
column_widths = [column_width] * num_columns
|
||||
|
||||
# Calculate row heights
|
||||
header_height = 35 if any(1 for section, _ in all_rows if section == "header") else 0
|
||||
header_height = 35 if any(1 for section,
|
||||
_ in all_rows if section == "header") else 0
|
||||
|
||||
# Check if any body rows contain images - if so, use larger height
|
||||
body_height = 30
|
||||
@@ -375,7 +410,8 @@ class TableRenderer(Box):
|
||||
body_height = max(body_height, 120)
|
||||
break
|
||||
|
||||
footer_height = 30 if any(1 for section, _ in all_rows if section == "footer") else 0
|
||||
footer_height = 30 if any(1 for section,
|
||||
_ in all_rows if section == "footer") else 0
|
||||
|
||||
row_heights = {
|
||||
"header": header_height,
|
||||
@@ -428,8 +464,9 @@ class TableRenderer(Box):
|
||||
from PIL import ImageFont
|
||||
|
||||
try:
|
||||
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 13)
|
||||
except:
|
||||
font = ImageFont.truetype(
|
||||
"/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 13)
|
||||
except BaseException:
|
||||
font = ImageFont.load_default()
|
||||
|
||||
# Center the caption
|
||||
|
||||
Reference in New Issue
Block a user