From ffdfd6ccdf162870439290806dc06583bcc6644d Mon Sep 17 00:00:00 2001 From: Travis Abendshien Date: Fri, 19 Jul 2024 20:25:14 -0700 Subject: [PATCH] fix(ui): large font previews follow app theme --- tagstudio/src/qt/helpers/color_overlay.py | 8 ++-- tagstudio/src/qt/widgets/thumb_renderer.py | 48 ++++++++++++---------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/tagstudio/src/qt/helpers/color_overlay.py b/tagstudio/src/qt/helpers/color_overlay.py index 9bb474c2..c468c2b3 100644 --- a/tagstudio/src/qt/helpers/color_overlay.py +++ b/tagstudio/src/qt/helpers/color_overlay.py @@ -16,18 +16,20 @@ _THEME_DARK_BG: str = "#000000DD" _THEME_LIGHT_BG: str = "#FFFFFF55" -def theme_fg_overlay(image: Image.Image) -> Image.Image: +def theme_fg_overlay(image: Image.Image, use_alpha: bool = True) -> Image.Image: """ Overlay the foreground theme color onto an image. Args: image (Image): The PIL Image object to apply an overlay to. """ + dark_fg: str = _THEME_DARK_FG[:-2] if not use_alpha else _THEME_DARK_FG + light_fg: str = _THEME_LIGHT_FG[:-2] if not use_alpha else _THEME_LIGHT_FG overlay_color = ( - _THEME_DARK_FG + dark_fg if QGuiApplication.styleHints().colorScheme() is Qt.ColorScheme.Dark - else _THEME_LIGHT_FG + else light_fg ) im = Image.new(mode="RGBA", size=image.size, color=overlay_color) diff --git a/tagstudio/src/qt/widgets/thumb_renderer.py b/tagstudio/src/qt/widgets/thumb_renderer.py index e1bd4004..6f2976e4 100644 --- a/tagstudio/src/qt/widgets/thumb_renderer.py +++ b/tagstudio/src/qt/widgets/thumb_renderer.py @@ -232,29 +232,10 @@ class ThumbRenderer(QObject): elif _filepath.suffix.lower() in FONT_TYPES: if gradient: # Handles small thumbnails - image = self._font_preview_small(_filepath, adj_size) + image = self._font_preview_short(_filepath, adj_size) else: # Handles big thumbnails and renders a sample text in multiple font sizes. - # Scale the sample font sizes to the preview image - # resolution,assuming the sizes are tuned for 256px. - scaled_sizes: list[int] = [ - math.floor(x * (adj_size / 256)) for x in FONT_SAMPLE_SIZES - ] - bg = Image.new("RGB", (adj_size, adj_size), color="#1e1e1e") - draw = ImageDraw.Draw(bg) - lines_of_padding = 2 - y_offset = 0 - - for font_size in scaled_sizes: - font = ImageFont.truetype(_filepath, size=font_size) - text_wrapped: str = wrap_full_text( - FONT_SAMPLE_TEXT, font=font, width=adj_size, draw=draw - ) - draw.multiline_text((0, y_offset), text_wrapped, font=font) - y_offset += ( - len(text_wrapped.split("\n")) + lines_of_padding - ) * draw.textbbox((0, 0), "A", font=font)[-1] - image = bg + image = self._font_preview_long(_filepath, adj_size) # Audio ======================================================== elif ext in AUDIO_TYPES: image = self._album_artwork(_filepath, ext) @@ -523,7 +504,7 @@ class ThumbRenderer(QObject): ) return image - def _font_preview_small(self, filepath: Path, size: int) -> Image.Image: + def _font_preview_short(self, filepath: Path, size: int) -> Image.Image: """Renders a small font preview ("Aa") thumbnail from a font file.""" bg = Image.new("RGB", (size, size), color="#000000") raw = Image.new("RGB", (size * 2, size * 2), color="#000000") @@ -573,6 +554,29 @@ class ThumbRenderer(QObject): ) return self._apply_overlay_color(bg, "purple") + def _font_preview_long(self, filepath: Path, size: int) -> Image.Image: + """Renders a large font preview ("Alphabet") thumbnail from a font file.""" + # Scale the sample font sizes to the preview image + # resolution,assuming the sizes are tuned for 256px. + scaled_sizes: list[int] = [ + math.floor(x * (size / 256)) for x in FONT_SAMPLE_SIZES + ] + bg = Image.new("RGBA", (size, size), color="#00000000") + draw = ImageDraw.Draw(bg) + lines_of_padding = 2 + y_offset = 0 + + for font_size in scaled_sizes: + font = ImageFont.truetype(filepath, size=font_size) + text_wrapped: str = wrap_full_text( + FONT_SAMPLE_TEXT, font=font, width=size, draw=draw + ) + draw.multiline_text((0, y_offset), text_wrapped, font=font) + y_offset += ( + len(text_wrapped.split("\n")) + lines_of_padding + ) * draw.textbbox((0, 0), "A", font=font)[-1] + return theme_fg_overlay(bg, use_alpha=False) + def _apply_overlay_color(self, image: Image.Image, color: str) -> Image.Image: """Apply a gradient effect over an an image. Red channel for foreground, green channel for outline, none for background."""