-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Description
When rendering with TrueType fonts on Windows, Unicode code points outside the 16-bit range are rendered as a pair of unknown characters (usually a box with a question mark). I suspect this is caused by one of the following lines:
Line 322 in 36db534
| Py_UNICODE* p = PyUnicode_AS_UNICODE(string); |
Line 363 in 36db534
| Py_UNICODE *text = PyUnicode_AS_UNICODE(string); |
According to Python docs, Py_UNICODE is a typedef for wchar_t, which is 16-bit on Windows, but typically 32-bit on Linux. The docs suggest using the type Py_UCS4 and function PyUnicode_AsUCS4Copy (introduced in Python 3.3).
https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_AsUCS4Copy
I would attempt changing this myself, but I'm not sure how to compile native Python libraries from source.
Code to reproduce:
import sys
from PIL import Image, ImageDraw, ImageFont
size = int(sys.argv[2]) if len(sys.argv) >= 3 else 48
fontname = sys.argv[1] if len(sys.argv) >= 2 else 'Symbola.ttf'
font = ImageFont.truetype(fontname, size=size)
text = ''' Unicode pictogram test:
Letters: P H BUS
Sans-serif: 𝗣 𝗛 𝗕𝗨𝗦
Crosses: † ✝
Amenity: 🚻 🖂 ⛲ ⛹ 🎓 🎒
Entertainment: 🎨 🎡 🎢 🎜 🎬 🎭 🎰 🎲
Sport: 🎳 🎾 🏓 🏸 🚩
Restaurants: 🍽 🍴 🍵 🍶 🍷 🍺 🍾
Transport: ⛽ 🚂 🚁 🚃 🚋 🚌 🚖 🛪
'''.splitlines()
image = Image.new('RGB', (1000, 600), '#fff')
draw = ImageDraw.Draw(image, 'RGBA')
for i, line in enumerate(text):
draw.text((0, i * size), line, fill='#000', font=font)
image.save(fontname + '.png')
Font used: https://www.fontspace.com/unicode-fonts-for-ancient-scripts/symbola

