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

Support setting a default font #6480

Closed
guoquan opened this issue Aug 5, 2022 · 6 comments · Fixed by #6484
Closed

Support setting a default font #6480

guoquan opened this issue Aug 5, 2022 · 6 comments · Fixed by #6484

Comments

@guoquan
Copy link

guoquan commented Aug 5, 2022

What did you do?

Was printing CJK characters to an image but got an AttributeError. No doubt the default font wasn't supporting such characters.

What did you expect to happen?

Understand I can use Unicode-friendly fonts everytime I do text(). However, can I somehow change the default font so that I won't need to change everywhere in my program text() with a font?

What actually happened?

Checking the docs there's PIL.ImageFont.load_default() to

Load a “better than nothing” default font.
Well, it is very clear.
But can I provide some "better than nothing" default for my own use?

What are your OS, Python and Pillow versions?

  • OS: Ubuntu
  • Python: 3.8.13
  • Pillow: 9.2.0
from PIL import Image, ImageDraw

im = Image.new("RGB", (400, 300))
draw = ImageDraw.Draw(im)
draw.text((10, 10), "你好")

im.show()

It gives:

AttributeError: 'ImageFont' object has no attribute 'getmask2'
@radarhere radarhere added the Fonts label Aug 5, 2022
@radarhere radarhere changed the title Feature request: support setting a default font Support setting a default font Aug 5, 2022
@radarhere
Copy link
Member

If you're looking for an immediate solution, you could patch Pillow. Using one of our test fonts,

from PIL import ImageFont
ImageFont.load_default = lambda: ImageFont.truetype("Tests/fonts/NotoSansJP-Regular.otf")

In context,

from PIL import Image, ImageDraw, ImageFont
ImageFont.load_default = lambda: ImageFont.truetype("Tests/fonts/NotoSansJP-Regular.otf")

im = Image.new("RGB", (400, 300))
draw = ImageDraw.Draw(im)
draw.text((10, 10), "你好")

im.show()

@guoquan
Copy link
Author

guoquan commented Aug 5, 2022

Awesome! I am practicing an identical workaround.
However, patching load_default to set default isn't something we want to write in the documentation.
Looking forward to a consistent and reliable interface to handle this.

@radarhere
Copy link
Member

What do you think of this interface for setting a default font?

from PIL import ImageDraw, ImageFont
ImageDraw.ImageDraw.font = ImageFont.truetype("Tests/fonts/FreeMono.ttf", 120)

I've created PR #6484 with this change.

@guoquan
Copy link
Author

guoquan commented Aug 8, 2022

Looks good, but why does it go under ImageDraw rather than ImageFont?
Is ImageFont.load_default used somewhere else where we want flexibility over consistency?

@nulano
Copy link
Contributor

nulano commented Aug 8, 2022

You can already set the default font on a per-ImageDraw instance basis, e.g.

from PIL import Image, ImageDraw, ImageFont

im = Image.new("RGB", (400, 300))
draw = ImageDraw.Draw(im)
draw.font = ImageFont.truetype("Tests/fonts/NotoSansJP-Regular.otf")
draw.text((10, 10), "你好")

im.show()

This is currently undocumented, but I wouldn't expect it to be removed without a deprecation notice. Perhaps just documenting this field would be good enough for you?

@radarhere's PR adds the option to set a default value globally for all ImageDraw instances without an explicit font set.

ImageFont.load_default isn't used anywhere else (except for a small number of tests), but despite being a function, it can be treated sort of like a getter for a constant. The function contains a base64 encoded font file that it simply loads and returns every time you call it. I would therefore find it strange to change its behaviour by adding a set_default function.

@guoquan
Copy link
Author

guoquan commented Aug 9, 2022

Yeah, the constant constraint makes sense to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants