Ensure only a single thread tries to render chars at a time
This commit is contained in:
parent
fabdebfd89
commit
ed74f8e467
@ -8,6 +8,7 @@ import re
|
|||||||
import ctypes
|
import ctypes
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
|
from threading import Lock
|
||||||
|
|
||||||
from freetype import (
|
from freetype import (
|
||||||
Face, FT_LOAD_RENDER, FT_LOAD_TARGET_NORMAL, FT_LOAD_TARGET_LIGHT,
|
Face, FT_LOAD_RENDER, FT_LOAD_TARGET_NORMAL, FT_LOAD_TARGET_LIGHT,
|
||||||
@ -111,6 +112,9 @@ def font_units_to_pixels(x, units_per_em, size_in_pts, dpi):
|
|||||||
return int(x * ((size_in_pts * dpi) / (72 * units_per_em)))
|
return int(x * ((size_in_pts * dpi) / (72 * units_per_em)))
|
||||||
|
|
||||||
|
|
||||||
|
freetype_lock = Lock()
|
||||||
|
|
||||||
|
|
||||||
def render_char(text, bold=False, italic=False, size_in_pts=None):
|
def render_char(text, bold=False, italic=False, size_in_pts=None):
|
||||||
# TODO: Handle non-normalizable combining chars. Probably need to use
|
# TODO: Handle non-normalizable combining chars. Probably need to use
|
||||||
# harfbuzz for that
|
# harfbuzz for that
|
||||||
@ -123,27 +127,28 @@ def render_char(text, bold=False, italic=False, size_in_pts=None):
|
|||||||
key = 'bi' if italic else 'bold'
|
key = 'bi' if italic else 'bold'
|
||||||
elif italic:
|
elif italic:
|
||||||
key = 'italic'
|
key = 'italic'
|
||||||
font = current_font_family.get(key) or current_font_family['regular']
|
with freetype_lock:
|
||||||
face = font.face
|
font = current_font_family.get(key) or current_font_family['regular']
|
||||||
if not face.get_char_index(ord(text[0])):
|
face = font.face
|
||||||
face = face_for_char(text[0], bold, italic)
|
if not face.get_char_index(ord(text[0])):
|
||||||
face.set_char_size(width=sz, height=sz, hres=dpi[0], vres=dpi[1])
|
face = face_for_char(text[0], bold, italic)
|
||||||
flags = FT_LOAD_RENDER
|
face.set_char_size(width=sz, height=sz, hres=dpi[0], vres=dpi[1])
|
||||||
if font.hinting:
|
flags = FT_LOAD_RENDER
|
||||||
if font.hintstyle >= 3:
|
if font.hinting:
|
||||||
flags |= FT_LOAD_TARGET_NORMAL
|
if font.hintstyle >= 3:
|
||||||
elif 0 < font.hintstyle < 3:
|
flags |= FT_LOAD_TARGET_NORMAL
|
||||||
flags |= FT_LOAD_TARGET_LIGHT
|
elif 0 < font.hintstyle < 3:
|
||||||
else:
|
flags |= FT_LOAD_TARGET_LIGHT
|
||||||
flags |= FT_LOAD_NO_HINTING
|
else:
|
||||||
face.load_char(text, flags)
|
flags |= FT_LOAD_NO_HINTING
|
||||||
bitmap = face.glyph.bitmap
|
face.load_char(text, flags)
|
||||||
if bitmap.pixel_mode != FT_PIXEL_MODE_GRAY:
|
bitmap = face.glyph.bitmap
|
||||||
raise ValueError(
|
if bitmap.pixel_mode != FT_PIXEL_MODE_GRAY:
|
||||||
'FreeType rendered the glyph for {!r} with an unsupported pixel mode: {}'.format(text, bitmap.pixel_mode))
|
raise ValueError(
|
||||||
m = face.glyph.metrics
|
'FreeType rendered the glyph for {!r} with an unsupported pixel mode: {}'.format(text, bitmap.pixel_mode))
|
||||||
return CharBitmap(bitmap.buffer, min(int(abs(m.horiBearingX) / 64), bitmap.width),
|
m = face.glyph.metrics
|
||||||
min(int(abs(m.horiBearingY) / 64), bitmap.rows), int(m.horiAdvance / 64), bitmap.rows, bitmap.width)
|
return CharBitmap(bitmap.buffer, min(int(abs(m.horiBearingX) / 64), bitmap.width),
|
||||||
|
min(int(abs(m.horiBearingY) / 64), bitmap.rows), int(m.horiAdvance / 64), bitmap.rows, bitmap.width)
|
||||||
|
|
||||||
|
|
||||||
def is_wide_char(bitmap_char):
|
def is_wide_char(bitmap_char):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user