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:
cottongin
2026-04-06 18:58:42 -04:00
parent d6cef67420
commit 9a8b586292
2 changed files with 50 additions and 6 deletions

View File

@@ -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(