Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add font thumbnail preview support #307

Merged
merged 11 commits into from
Jul 19, 2024

Conversation

Thesacraft
Copy link
Collaborator

I added simple font thumbnail previews for .ttf, .otf and .woff files like it was requested in issue #304 . Currently there are three text sizes (10,12,15) that i selected. I stacked the sample text in the different font sizes next to each other and tried to dynamically fit them next to each other. I am open to changing how the text alignment works and other changes. At the moment it looks like this:
font support
font_support_2

@Thesacraft
Copy link
Collaborator Author

I added a bit of information about the font as requested:
grafik
I could not find how to get the weight of the font, if someone knows how to do that let me know.

@olipra
Copy link

olipra commented Jul 2, 2024

This is a very good start! Already miles better than the file icon thumbnail. I'm just wondering whether it's worth aligning the text vertically instead of horizontally, and I'm also wondering if displaying the font in different sizes actually is worth it considering the small space it has to fit it. It's less of a problem for the bigger preview but it makes fonts in thumbnails hard to recognize, and I guess the thumbnail and preview can't show two different things. Otherwise it would make more sense for the thumbnail to only show "Aa" or something like that.

@Thesacraft
Copy link
Collaborator Author

I changed it in the way you described here is the result:
grafik
I also adjusted the font sizes to 12,15,20

@olipra
Copy link

olipra commented Jul 3, 2024

This looks perfect to me! This is gonna be a life-changing feature for me and hopefully other type enthusiasts haha 🙌 Also thank you for taking my feature request in consideration and working on it!

@CyanVoxel CyanVoxel added Type: Enhancement New feature or request Type: UI/UX User interface and/or user experience labels Jul 3, 2024
@CyanVoxel CyanVoxel self-assigned this Jul 3, 2024
@CyanVoxel CyanVoxel added this to the Alpha 9.4 milestone Jul 19, 2024
Copy link
Member

@CyanVoxel CyanVoxel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing work on this! I'm really happy with how this has come out. I've just got a few suggestions that come down to adding dynamic scaling with different preview resolutions and a couple extra file types.

Thank you so much for working on this!

Comment on lines 21 to 30
if draw.textlength(text, font=font) > 256:
# print(draw.textlength(text, font=font))
for i in range(
int(len(text) / int(draw.textlength(text, font=font)) * 256) - 2,
0,
-1,
):
if draw.textlength(text[:i], font=font) < 256:
# print(len(text))
# print(i)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to use width variable instead of hardcoded values (plus remove print comments)

Suggested change
if draw.textlength(text, font=font) > 256:
# print(draw.textlength(text, font=font))
for i in range(
int(len(text) / int(draw.textlength(text, font=font)) * 256) - 2,
0,
-1,
):
if draw.textlength(text[:i], font=font) < 256:
# print(len(text))
# print(i)
if draw.textlength(text, font=font) > width:
for i in range(
int(len(text) / int(draw.textlength(text, font=font)) * width) - 2,
0,
-1,
):
if draw.textlength(text[:i], font=font) < width:
return i

i = 0
last_i = 0
while wrap_line(text[i:], font=font, width=width, draw=draw) > 0:
i = wrap_line(text[i:], font=font, draw=draw) + last_i
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass width variable to wrap_line

Suggested change
i = wrap_line(text[i:], font=font, draw=draw) + last_i
i = wrap_line(text[i:], font=font, width=width, draw=draw) + last_i

FONT_SAMPLE_TEXT: str = (
"""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?@$%(){}[]"""
)
FONT_SAMPLE_SIZES: list[int] = [12, 15, 20]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slight adjustment to font sample sizes to show more difference between them

Suggested change
FONT_SAMPLE_SIZES: list[int] = [12, 15, 20]
FONT_SAMPLE_SIZES: list[int] = [10, 15, 20]

@@ -107,6 +112,7 @@
]
PROGRAM_TYPES: list[str] = [".exe", ".app"]
SHORTCUT_TYPES: list[str] = [".lnk", ".desktop", ".url"]
FONT_TYPES: list[str] = [".ttf", ".otf", ".woff"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add .ttc and .woff2 file extensions to the constants list (I haven't personally verified .woff2 but .ttc seems to work fine)

Suggested change
FONT_TYPES: list[str] = [".ttf", ".otf", ".woff"]
FONT_TYPES: list[str] = [".ttf", ".ttc", ".otf", ".woff", ".woff2"]

Comment on lines 194 to 210
if gradient:
# handles small thumbnails
bg = Image.new("RGB", (256, 256), color="#1e1e1e")
draw = ImageDraw.Draw(bg)
font = ImageFont.truetype(_filepath, size=170)
draw.text((10, 0), "Aa", font=font)
else:
# handles big thumbnails and renders a sample text in multiple font sizes
bg = Image.new("RGB", (256, 256), color="#1e1e1e")
draw = ImageDraw.Draw(bg)
lines_of_padding = 2
y_offset = 0

for font_size in FONT_SAMPLE_SIZES:
font = ImageFont.truetype(_filepath, size=font_size)
text_wrapped: str = wrap_full_text(
FONT_SAMPLE_TEXT, font=font, draw=draw
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use native preview sizes with dynamic scaling

Suggested change
if gradient:
# handles small thumbnails
bg = Image.new("RGB", (256, 256), color="#1e1e1e")
draw = ImageDraw.Draw(bg)
font = ImageFont.truetype(_filepath, size=170)
draw.text((10, 0), "Aa", font=font)
else:
# handles big thumbnails and renders a sample text in multiple font sizes
bg = Image.new("RGB", (256, 256), color="#1e1e1e")
draw = ImageDraw.Draw(bg)
lines_of_padding = 2
y_offset = 0
for font_size in FONT_SAMPLE_SIZES:
font = ImageFont.truetype(_filepath, size=font_size)
text_wrapped: str = wrap_full_text(
FONT_SAMPLE_TEXT, font=font, draw=draw
# 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
]
if gradient:
# handles small thumbnails
bg = Image.new("RGB", (adj_size, adj_size), color="#1e1e1e")
draw = ImageDraw.Draw(bg)
font = ImageFont.truetype(
_filepath, size=math.ceil(adj_size * 0.65)
)
draw.text((10, 0), "Aa", font=font)
else:
# handles big thumbnails and renders a sample text in multiple font 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

@CyanVoxel CyanVoxel added the Status: Mergeable The code is ready to be merged label Jul 19, 2024
@CyanVoxel CyanVoxel changed the base branch from main to Alpha-v9.4 July 19, 2024 14:20
@CyanVoxel CyanVoxel merged commit e463635 into TagStudioDev:Alpha-v9.4 Jul 19, 2024
4 checks passed
CarterPillow pushed a commit to CarterPillow/TagStudio that referenced this pull request Sep 7, 2024
* Add font thumbnail preview support

* Add multiple font sizes to thumbnail

* Ruff reformat

* Ruff reformat

* Added Metadata to info

* Change the way thumbnails are structured

* Small performance improvement

* changed Metadata display structure

* added copyright notice to added file

* fix(ui): dynamically scale font previews; add .woff2, .ttc

---------

Co-authored-by: Travis Abendshien <[email protected]>
CyanVoxel added a commit that referenced this pull request Sep 22, 2024
Ports the following thumbnail and related PRs from the `Alpha-v9.4` branch to `main` (v9.5+):
- (#273) Blender thumbnail support
- (#307) Add font thumbnail preview support
- (#331) refactor: move type constants to new media classes
- (#390) feat(ui): expanded thumbnail and preview features
- (#370) ui: "open in explorer" action follows os name
- (#373) feat(ui): preview support for source engine files
- (#274) Refactor video_player.py (Fix #270)
- (#430) feat(ui): show file creation/modified dates + restyle path label
- (#471) fix(ui): use default audio icon if ffmpeg is absent
- (#472) fix(ui): use birthtime for creation time on mac & win

Co-Authored-By: Ethnogeny <[email protected]>
Co-Authored-By: Theasacraft <[email protected]>
Co-Authored-By: SupKittyMeow <[email protected]>
Co-Authored-By: EJ Stinson <[email protected]>
Co-Authored-By: Sean Krueger <[email protected]>
CyanVoxel added a commit that referenced this pull request Oct 7, 2024
* feat: port v9.4 thumbnail + related feats to v9.5

Ports the following thumbnail and related PRs from the `Alpha-v9.4` branch to `main` (v9.5+):
- (#273) Blender thumbnail support
- (#307) Add font thumbnail preview support
- (#331) refactor: move type constants to new media classes
- (#390) feat(ui): expanded thumbnail and preview features
- (#370) ui: "open in explorer" action follows os name
- (#373) feat(ui): preview support for source engine files
- (#274) Refactor video_player.py (Fix #270)
- (#430) feat(ui): show file creation/modified dates + restyle path label
- (#471) fix(ui): use default audio icon if ffmpeg is absent
- (#472) fix(ui): use birthtime for creation time on mac & win

Co-Authored-By: Ethnogeny <[email protected]>
Co-Authored-By: Theasacraft <[email protected]>
Co-Authored-By: SupKittyMeow <[email protected]>
Co-Authored-By: EJ Stinson <[email protected]>
Co-Authored-By: Sean Krueger <[email protected]>

* remove vscode exceptions from `.gitignore`

* delete .vscode directory

* style: format for `ruff check`

* fix(tests): update `test_update_widgets_not_selected` test

* remove Send2Trash dependency

* refactor: use dataclass for MediaCateogry

* refactor: use enums for UI colors

* docs: add file docstring for silent_Popen

* refactor: replace logger with structlog

* use early return inside `ResourceManager.get()`

* add `is_ext_in_category()` method to `MediaCategory`

Add method to check if an extension is a member of a given MediaCategory.

* style: fix docstring style, missing type hints, rename `afm`

* fix: use structlog vars in logging

* refactor: move platform-dependent strings to PlatformStrings

* refactor: move `parents[2]` path to variable

* fix: undo logger regressions

---------

Co-authored-by: Ethnogeny <[email protected]>
Co-authored-by: Theasacraft <[email protected]>
Co-authored-by: SupKittyMeow <[email protected]>
Co-authored-by: EJ Stinson <[email protected]>
Co-authored-by: Sean Krueger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Mergeable The code is ready to be merged Type: Enhancement New feature or request Type: UI/UX User interface and/or user experience
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants