feat(cover): pixel-width headline truncation and larger font
Replace character-count truncation (45 chars) with Pillow textbbox pixel-width measurement. Bump headline font 14→18, line spacing 22→26. Made-with: Cursor
This commit is contained in:
27
src/cover.py
27
src/cover.py
@@ -70,6 +70,23 @@ def _get_dominant_category(categories: list[str]) -> str:
|
||||
return most_common
|
||||
|
||||
|
||||
def _truncate_to_width(
|
||||
text: str, font: ImageFont.FreeTypeFont, max_width: int
|
||||
) -> str:
|
||||
dummy = PILImage.new("RGBA", (1, 1))
|
||||
draw = ImageDraw.Draw(dummy)
|
||||
bbox = draw.textbbox((0, 0), text, font=font)
|
||||
if (bbox[2] - bbox[0]) <= max_width:
|
||||
return text
|
||||
ellipsis = "\u2026"
|
||||
for i in range(len(text) - 1, 0, -1):
|
||||
candidate = text[:i] + ellipsis
|
||||
bbox = draw.textbbox((0, 0), candidate, font=font)
|
||||
if (bbox[2] - bbox[0]) <= max_width:
|
||||
return candidate
|
||||
return ellipsis
|
||||
|
||||
|
||||
def _draw_text_overlays(
|
||||
draw: ImageDraw.ImageDraw,
|
||||
width: int,
|
||||
@@ -80,7 +97,7 @@ def _draw_text_overlays(
|
||||
) -> None:
|
||||
title_font = _get_font(38)
|
||||
date_font = _get_font(20)
|
||||
headline_font = _get_font(14)
|
||||
headline_font = _get_font(18)
|
||||
|
||||
draw.rectangle([(0, 0), (width, 90)], fill=(0, 0, 0, 204))
|
||||
draw.text(
|
||||
@@ -100,18 +117,18 @@ def _draw_text_overlays(
|
||||
|
||||
if headlines:
|
||||
max_headlines = min(len(headlines), 5)
|
||||
strip_height = 28 + max_headlines * 22
|
||||
strip_height = 28 + max_headlines * 26
|
||||
strip_top = height - strip_height
|
||||
draw.rectangle(
|
||||
[(0, strip_top), (width, height)], fill=(0, 0, 0, 170)
|
||||
)
|
||||
max_width = width - 32
|
||||
y = strip_top + 8
|
||||
for headline in headlines[:max_headlines]:
|
||||
text = f"\u2022 {headline}"
|
||||
if len(text) > 45:
|
||||
text = text[:42] + "..."
|
||||
text = _truncate_to_width(text, headline_font, max_width)
|
||||
draw.text((16, y), text, fill="white", font=headline_font)
|
||||
y += 22
|
||||
y += 26
|
||||
|
||||
|
||||
def generate_programmatic_cover(
|
||||
|
||||
Reference in New Issue
Block a user