Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/PIL/ImageFont.py: 37%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#
2# The Python Imaging Library.
3# $Id$
4#
5# PIL raster font management
6#
7# History:
8# 1996-08-07 fl created (experimental)
9# 1997-08-25 fl minor adjustments to handle fonts from pilfont 0.3
10# 1999-02-06 fl rewrote most font management stuff in C
11# 1999-03-17 fl take pth files into account in load_path (from Richard Jones)
12# 2001-02-17 fl added freetype support
13# 2001-05-09 fl added TransposedFont wrapper class
14# 2002-03-04 fl make sure we have a "L" or "1" font
15# 2002-12-04 fl skip non-directory entries in the system path
16# 2003-04-29 fl add embedded default font
17# 2003-09-27 fl added support for truetype charmap encodings
18#
19# Todo:
20# Adapt to PILFONT2 format (16-bit fonts, compressed, single file)
21#
22# Copyright (c) 1997-2003 by Secret Labs AB
23# Copyright (c) 1996-2003 by Fredrik Lundh
24#
25# See the README file for information on usage and redistribution.
26#
28from __future__ import annotations
30import base64
31import os
32import sys
33import warnings
34from enum import IntEnum
35from io import BytesIO
36from types import ModuleType
37from typing import IO, Any, BinaryIO, TypedDict, cast
39from . import Image
40from ._typing import StrOrBytesPath
41from ._util import DeferredError, is_path
43TYPE_CHECKING = False
44if TYPE_CHECKING:
45 from . import ImageFile
46 from ._imaging import ImagingFont
47 from ._imagingft import Font
50class Axis(TypedDict):
51 minimum: int | None
52 default: int | None
53 maximum: int | None
54 name: bytes | None
57class Layout(IntEnum):
58 BASIC = 0
59 RAQM = 1
62MAX_STRING_LENGTH = 1_000_000
65core: ModuleType | DeferredError
66try:
67 from . import _imagingft as core
68except ImportError as ex:
69 core = DeferredError.new(ex)
72def _string_length_check(text: str | bytes | bytearray) -> None:
73 if MAX_STRING_LENGTH is not None and len(text) > MAX_STRING_LENGTH:
74 msg = "too many characters in string"
75 raise ValueError(msg)
78# FIXME: add support for pilfont2 format (see FontFile.py)
80# --------------------------------------------------------------------
81# Font metrics format:
82# "PILfont" LF
83# fontdescriptor LF
84# (optional) key=value... LF
85# "DATA" LF
86# binary data: 256*10*2 bytes (dx, dy, dstbox, srcbox)
87#
88# To place a character, cut out srcbox and paste at dstbox,
89# relative to the character position. Then move the character
90# position according to dx, dy.
91# --------------------------------------------------------------------
94class ImageFont:
95 """PIL font wrapper"""
97 font: ImagingFont
99 def _load_pilfont(self, filename: str) -> None:
100 with open(filename, "rb") as fp:
101 image: ImageFile.ImageFile | None = None
102 root = os.path.splitext(filename)[0]
104 for ext in (".png", ".gif", ".pbm"):
105 if image:
106 image.close()
107 try:
108 fullname = root + ext
109 image = Image.open(fullname)
110 except Exception:
111 pass
112 else:
113 if image and image.mode in ("1", "L"):
114 break
115 else:
116 if image:
117 image.close()
119 msg = f"cannot find glyph data file {root}.{{gif|pbm|png}}"
120 raise OSError(msg)
122 self.file = fullname
124 self._load_pilfont_data(fp, image)
125 image.close()
127 def _load_pilfont_data(self, file: IO[bytes], image: Image.Image) -> None:
128 # check image
129 if image.mode not in ("1", "L"):
130 image.close()
132 msg = "invalid font image mode"
133 raise TypeError(msg)
135 # read PILfont header
136 if file.read(8) != b"PILfont\n":
137 image.close()
139 msg = "Not a PILfont file"
140 raise SyntaxError(msg)
141 file.readline()
142 self.info = [] # FIXME: should be a dictionary
143 while True:
144 s = file.readline()
145 if not s or s == b"DATA\n":
146 break
147 self.info.append(s)
149 # read PILfont metrics
150 data = file.read(256 * 20)
152 self._load(image, data)
154 def _load(self, image: Image.Image, data: bytes) -> None:
155 image.load()
157 self.font = Image.core.font(image.im, data)
159 def getmask(
160 self, text: str | bytes, mode: str = "", *args: Any, **kwargs: Any
161 ) -> Image.core.ImagingCore:
162 """
163 Create a bitmap for the text.
165 If the font uses antialiasing, the bitmap should have mode ``L`` and use a
166 maximum value of 255. Otherwise, it should have mode ``1``.
168 :param text: Text to render.
169 :param mode: Used by some graphics drivers to indicate what mode the
170 driver prefers; if empty, the renderer may return either
171 mode. Note that the mode is always a string, to simplify
172 C-level implementations.
174 .. versionadded:: 1.1.5
176 :return: An internal PIL storage memory instance as defined by the
177 :py:mod:`PIL.Image.core` interface module.
178 """
179 _string_length_check(text)
180 Image._decompression_bomb_check(self.font.getsize(text))
181 return self.font.getmask(text, mode)
183 def getbbox(
184 self, text: str | bytes | bytearray, *args: Any, **kwargs: Any
185 ) -> tuple[int, int, int, int]:
186 """
187 Returns bounding box (in pixels) of given text.
189 .. versionadded:: 9.2.0
191 :param text: Text to render.
193 :return: ``(left, top, right, bottom)`` bounding box
194 """
195 _string_length_check(text)
196 width, height = self.font.getsize(text)
197 return 0, 0, width, height
199 def getlength(
200 self, text: str | bytes | bytearray, *args: Any, **kwargs: Any
201 ) -> int:
202 """
203 Returns length (in pixels) of given text.
204 This is the amount by which following text should be offset.
206 .. versionadded:: 9.2.0
207 """
208 _string_length_check(text)
209 width, height = self.font.getsize(text)
210 return width
213##
214# Wrapper for FreeType fonts. Application code should use the
215# <b>truetype</b> factory function to create font objects.
218class FreeTypeFont:
219 """FreeType font wrapper (requires _imagingft service)"""
221 font: Font
222 font_bytes: bytes
224 def __init__(
225 self,
226 font: StrOrBytesPath | BinaryIO,
227 size: float = 10,
228 index: int = 0,
229 encoding: str = "",
230 layout_engine: Layout | None = None,
231 ) -> None:
232 # FIXME: use service provider instead
234 if isinstance(core, DeferredError):
235 raise core.ex
237 if size <= 0:
238 msg = f"font size must be greater than 0, not {size}"
239 raise ValueError(msg)
241 self.path = font
242 self.size = size
243 self.index = index
244 self.encoding = encoding
246 if layout_engine not in (Layout.BASIC, Layout.RAQM):
247 layout_engine = Layout.BASIC
248 if core.HAVE_RAQM:
249 layout_engine = Layout.RAQM
250 elif layout_engine == Layout.RAQM and not core.HAVE_RAQM:
251 warnings.warn(
252 "Raqm layout was requested, but Raqm is not available. "
253 "Falling back to basic layout."
254 )
255 layout_engine = Layout.BASIC
257 self.layout_engine = layout_engine
259 def load_from_bytes(f: IO[bytes]) -> None:
260 self.font_bytes = f.read()
261 self.font = core.getfont(
262 "", size, index, encoding, self.font_bytes, layout_engine
263 )
265 if is_path(font):
266 font = os.fspath(font)
267 if sys.platform == "win32":
268 font_bytes_path = font if isinstance(font, bytes) else font.encode()
269 try:
270 font_bytes_path.decode("ascii")
271 except UnicodeDecodeError:
272 # FreeType cannot load fonts with non-ASCII characters on Windows
273 # So load it into memory first
274 with open(font, "rb") as f:
275 load_from_bytes(f)
276 return
277 self.font = core.getfont(
278 font, size, index, encoding, layout_engine=layout_engine
279 )
280 else:
281 load_from_bytes(cast(IO[bytes], font))
283 def __getstate__(self) -> list[Any]:
284 return [self.path, self.size, self.index, self.encoding, self.layout_engine]
286 def __setstate__(self, state: list[Any]) -> None:
287 path, size, index, encoding, layout_engine = state
288 FreeTypeFont.__init__(self, path, size, index, encoding, layout_engine)
290 def getname(self) -> tuple[str | None, str | None]:
291 """
292 :return: A tuple of the font family (e.g. Helvetica) and the font style
293 (e.g. Bold)
294 """
295 return self.font.family, self.font.style
297 def getmetrics(self) -> tuple[int, int]:
298 """
299 :return: A tuple of the font ascent (the distance from the baseline to
300 the highest outline point) and descent (the distance from the
301 baseline to the lowest outline point, a negative value)
302 """
303 return self.font.ascent, self.font.descent
305 def getlength(
306 self,
307 text: str | bytes,
308 mode: str = "",
309 direction: str | None = None,
310 features: list[str] | None = None,
311 language: str | None = None,
312 ) -> float:
313 """
314 Returns length (in pixels with 1/64 precision) of given text when rendered
315 in font with provided direction, features, and language.
317 This is the amount by which following text should be offset.
318 Text bounding box may extend past the length in some fonts,
319 e.g. when using italics or accents.
321 The result is returned as a float; it is a whole number if using basic layout.
323 Note that the sum of two lengths may not equal the length of a concatenated
324 string due to kerning. If you need to adjust for kerning, include the following
325 character and subtract its length.
327 For example, instead of ::
329 hello = font.getlength("Hello")
330 world = font.getlength("World")
331 hello_world = hello + world # not adjusted for kerning
332 assert hello_world == font.getlength("HelloWorld") # may fail
334 use ::
336 hello = font.getlength("HelloW") - font.getlength("W") # adjusted for kerning
337 world = font.getlength("World")
338 hello_world = hello + world # adjusted for kerning
339 assert hello_world == font.getlength("HelloWorld") # True
341 or disable kerning with (requires libraqm) ::
343 hello = draw.textlength("Hello", font, features=["-kern"])
344 world = draw.textlength("World", font, features=["-kern"])
345 hello_world = hello + world # kerning is disabled, no need to adjust
346 assert hello_world == draw.textlength("HelloWorld", font, features=["-kern"])
348 .. versionadded:: 8.0.0
350 :param text: Text to measure.
351 :param mode: Used by some graphics drivers to indicate what mode the
352 driver prefers; if empty, the renderer may return either
353 mode. Note that the mode is always a string, to simplify
354 C-level implementations.
356 :param direction: Direction of the text. It can be 'rtl' (right to
357 left), 'ltr' (left to right) or 'ttb' (top to bottom).
358 Requires libraqm.
360 :param features: A list of OpenType font features to be used during text
361 layout. This is usually used to turn on optional
362 font features that are not enabled by default,
363 for example 'dlig' or 'ss01', but can be also
364 used to turn off default font features for
365 example '-liga' to disable ligatures or '-kern'
366 to disable kerning. To get all supported
367 features, see
368 https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist
369 Requires libraqm.
371 :param language: Language of the text. Different languages may use
372 different glyph shapes or ligatures. This parameter tells
373 the font which language the text is in, and to apply the
374 correct substitutions as appropriate, if available.
375 It should be a `BCP 47 language code
376 <https://www.w3.org/International/articles/language-tags/>`_
377 Requires libraqm.
379 :return: Either width for horizontal text, or height for vertical text.
380 """
381 _string_length_check(text)
382 return self.font.getlength(text, mode, direction, features, language) / 64
384 def getbbox(
385 self,
386 text: str | bytes,
387 mode: str = "",
388 direction: str | None = None,
389 features: list[str] | None = None,
390 language: str | None = None,
391 stroke_width: float = 0,
392 anchor: str | None = None,
393 ) -> tuple[float, float, float, float]:
394 """
395 Returns bounding box (in pixels) of given text relative to given anchor
396 when rendered in font with provided direction, features, and language.
398 Use :py:meth:`getlength()` to get the offset of following text with
399 1/64 pixel precision. The bounding box includes extra margins for
400 some fonts, e.g. italics or accents.
402 .. versionadded:: 8.0.0
404 :param text: Text to render.
405 :param mode: Used by some graphics drivers to indicate what mode the
406 driver prefers; if empty, the renderer may return either
407 mode. Note that the mode is always a string, to simplify
408 C-level implementations.
410 :param direction: Direction of the text. It can be 'rtl' (right to
411 left), 'ltr' (left to right) or 'ttb' (top to bottom).
412 Requires libraqm.
414 :param features: A list of OpenType font features to be used during text
415 layout. This is usually used to turn on optional
416 font features that are not enabled by default,
417 for example 'dlig' or 'ss01', but can be also
418 used to turn off default font features for
419 example '-liga' to disable ligatures or '-kern'
420 to disable kerning. To get all supported
421 features, see
422 https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist
423 Requires libraqm.
425 :param language: Language of the text. Different languages may use
426 different glyph shapes or ligatures. This parameter tells
427 the font which language the text is in, and to apply the
428 correct substitutions as appropriate, if available.
429 It should be a `BCP 47 language code
430 <https://www.w3.org/International/articles/language-tags/>`_
431 Requires libraqm.
433 :param stroke_width: The width of the text stroke.
435 :param anchor: The text anchor alignment. Determines the relative location of
436 the anchor to the text. The default alignment is top left,
437 specifically ``la`` for horizontal text and ``lt`` for
438 vertical text. See :ref:`text-anchors` for details.
440 :return: ``(left, top, right, bottom)`` bounding box
441 """
442 _string_length_check(text)
443 size, offset = self.font.getsize(
444 text, mode, direction, features, language, anchor
445 )
446 left, top = offset[0] - stroke_width, offset[1] - stroke_width
447 width, height = size[0] + 2 * stroke_width, size[1] + 2 * stroke_width
448 return left, top, left + width, top + height
450 def getmask(
451 self,
452 text: str | bytes,
453 mode: str = "",
454 direction: str | None = None,
455 features: list[str] | None = None,
456 language: str | None = None,
457 stroke_width: float = 0,
458 anchor: str | None = None,
459 ink: int = 0,
460 start: tuple[float, float] | None = None,
461 ) -> Image.core.ImagingCore:
462 """
463 Create a bitmap for the text.
465 If the font uses antialiasing, the bitmap should have mode ``L`` and use a
466 maximum value of 255. If the font has embedded color data, the bitmap
467 should have mode ``RGBA``. Otherwise, it should have mode ``1``.
469 :param text: Text to render.
470 :param mode: Used by some graphics drivers to indicate what mode the
471 driver prefers; if empty, the renderer may return either
472 mode. Note that the mode is always a string, to simplify
473 C-level implementations.
475 .. versionadded:: 1.1.5
477 :param direction: Direction of the text. It can be 'rtl' (right to
478 left), 'ltr' (left to right) or 'ttb' (top to bottom).
479 Requires libraqm.
481 .. versionadded:: 4.2.0
483 :param features: A list of OpenType font features to be used during text
484 layout. This is usually used to turn on optional
485 font features that are not enabled by default,
486 for example 'dlig' or 'ss01', but can be also
487 used to turn off default font features for
488 example '-liga' to disable ligatures or '-kern'
489 to disable kerning. To get all supported
490 features, see
491 https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist
492 Requires libraqm.
494 .. versionadded:: 4.2.0
496 :param language: Language of the text. Different languages may use
497 different glyph shapes or ligatures. This parameter tells
498 the font which language the text is in, and to apply the
499 correct substitutions as appropriate, if available.
500 It should be a `BCP 47 language code
501 <https://www.w3.org/International/articles/language-tags/>`_
502 Requires libraqm.
504 .. versionadded:: 6.0.0
506 :param stroke_width: The width of the text stroke.
508 .. versionadded:: 6.2.0
510 :param anchor: The text anchor alignment. Determines the relative location of
511 the anchor to the text. The default alignment is top left,
512 specifically ``la`` for horizontal text and ``lt`` for
513 vertical text. See :ref:`text-anchors` for details.
515 .. versionadded:: 8.0.0
517 :param ink: Foreground ink for rendering in RGBA mode.
519 .. versionadded:: 8.0.0
521 :param start: Tuple of horizontal and vertical offset, as text may render
522 differently when starting at fractional coordinates.
524 .. versionadded:: 9.4.0
526 :return: An internal PIL storage memory instance as defined by the
527 :py:mod:`PIL.Image.core` interface module.
528 """
529 return self.getmask2(
530 text,
531 mode,
532 direction=direction,
533 features=features,
534 language=language,
535 stroke_width=stroke_width,
536 anchor=anchor,
537 ink=ink,
538 start=start,
539 )[0]
541 def getmask2(
542 self,
543 text: str | bytes,
544 mode: str = "",
545 direction: str | None = None,
546 features: list[str] | None = None,
547 language: str | None = None,
548 stroke_width: float = 0,
549 anchor: str | None = None,
550 ink: int = 0,
551 start: tuple[float, float] | None = None,
552 *args: Any,
553 **kwargs: Any,
554 ) -> tuple[Image.core.ImagingCore, tuple[int, int]]:
555 """
556 Create a bitmap for the text.
558 If the font uses antialiasing, the bitmap should have mode ``L`` and use a
559 maximum value of 255. If the font has embedded color data, the bitmap
560 should have mode ``RGBA``. Otherwise, it should have mode ``1``.
562 :param text: Text to render.
563 :param mode: Used by some graphics drivers to indicate what mode the
564 driver prefers; if empty, the renderer may return either
565 mode. Note that the mode is always a string, to simplify
566 C-level implementations.
568 .. versionadded:: 1.1.5
570 :param direction: Direction of the text. It can be 'rtl' (right to
571 left), 'ltr' (left to right) or 'ttb' (top to bottom).
572 Requires libraqm.
574 .. versionadded:: 4.2.0
576 :param features: A list of OpenType font features to be used during text
577 layout. This is usually used to turn on optional
578 font features that are not enabled by default,
579 for example 'dlig' or 'ss01', but can be also
580 used to turn off default font features for
581 example '-liga' to disable ligatures or '-kern'
582 to disable kerning. To get all supported
583 features, see
584 https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist
585 Requires libraqm.
587 .. versionadded:: 4.2.0
589 :param language: Language of the text. Different languages may use
590 different glyph shapes or ligatures. This parameter tells
591 the font which language the text is in, and to apply the
592 correct substitutions as appropriate, if available.
593 It should be a `BCP 47 language code
594 <https://www.w3.org/International/articles/language-tags/>`_
595 Requires libraqm.
597 .. versionadded:: 6.0.0
599 :param stroke_width: The width of the text stroke.
601 .. versionadded:: 6.2.0
603 :param anchor: The text anchor alignment. Determines the relative location of
604 the anchor to the text. The default alignment is top left,
605 specifically ``la`` for horizontal text and ``lt`` for
606 vertical text. See :ref:`text-anchors` for details.
608 .. versionadded:: 8.0.0
610 :param ink: Foreground ink for rendering in RGBA mode.
612 .. versionadded:: 8.0.0
614 :param start: Tuple of horizontal and vertical offset, as text may render
615 differently when starting at fractional coordinates.
617 .. versionadded:: 9.4.0
619 :return: A tuple of an internal PIL storage memory instance as defined by the
620 :py:mod:`PIL.Image.core` interface module, and the text offset, the
621 gap between the starting coordinate and the first marking
622 """
623 _string_length_check(text)
624 if start is None:
625 start = (0, 0)
627 def fill(width: int, height: int) -> Image.core.ImagingCore:
628 size = (width, height)
629 Image._decompression_bomb_check(size)
630 return Image.core.fill("RGBA" if mode == "RGBA" else "L", size)
632 return self.font.render(
633 text,
634 fill,
635 mode,
636 direction,
637 features,
638 language,
639 stroke_width,
640 kwargs.get("stroke_filled", False),
641 anchor,
642 ink,
643 start,
644 )
646 def font_variant(
647 self,
648 font: StrOrBytesPath | BinaryIO | None = None,
649 size: float | None = None,
650 index: int | None = None,
651 encoding: str | None = None,
652 layout_engine: Layout | None = None,
653 ) -> FreeTypeFont:
654 """
655 Create a copy of this FreeTypeFont object,
656 using any specified arguments to override the settings.
658 Parameters are identical to the parameters used to initialize this
659 object.
661 :return: A FreeTypeFont object.
662 """
663 if font is None:
664 try:
665 font = BytesIO(self.font_bytes)
666 except AttributeError:
667 font = self.path
668 return FreeTypeFont(
669 font=font,
670 size=self.size if size is None else size,
671 index=self.index if index is None else index,
672 encoding=self.encoding if encoding is None else encoding,
673 layout_engine=layout_engine or self.layout_engine,
674 )
676 def get_variation_names(self) -> list[bytes]:
677 """
678 :returns: A list of the named styles in a variation font.
679 :exception OSError: If the font is not a variation font.
680 """
681 names = []
682 for name in self.font.getvarnames():
683 name = name.replace(b"\x00", b"")
684 if name not in names:
685 names.append(name)
686 return names
688 def set_variation_by_name(self, name: str | bytes) -> None:
689 """
690 :param name: The name of the style.
691 :exception OSError: If the font is not a variation font.
692 """
693 names = self.get_variation_names()
694 if not isinstance(name, bytes):
695 name = name.encode()
696 index = names.index(name) + 1
698 if index == getattr(self, "_last_variation_index", None):
699 # When the same name is set twice in a row,
700 # there is an 'unknown freetype error'
701 # https://savannah.nongnu.org/bugs/?56186
702 return
703 self._last_variation_index = index
705 self.font.setvarname(index)
707 def get_variation_axes(self) -> list[Axis]:
708 """
709 :returns: A list of the axes in a variation font.
710 :exception OSError: If the font is not a variation font.
711 """
712 axes = self.font.getvaraxes()
713 for axis in axes:
714 if axis["name"]:
715 axis["name"] = axis["name"].replace(b"\x00", b"")
716 return axes
718 def set_variation_by_axes(self, axes: list[float]) -> None:
719 """
720 :param axes: A list of values for each axis.
721 :exception OSError: If the font is not a variation font.
722 """
723 self.font.setvaraxes(axes)
726class TransposedFont:
727 """Wrapper for writing rotated or mirrored text"""
729 def __init__(
730 self, font: ImageFont | FreeTypeFont, orientation: Image.Transpose | None = None
731 ):
732 """
733 Wrapper that creates a transposed font from any existing font
734 object.
736 :param font: A font object.
737 :param orientation: An optional orientation. If given, this should
738 be one of Image.Transpose.FLIP_LEFT_RIGHT, Image.Transpose.FLIP_TOP_BOTTOM,
739 Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_180, or
740 Image.Transpose.ROTATE_270.
741 """
742 self.font = font
743 self.orientation = orientation # any 'transpose' argument, or None
745 def getmask(
746 self, text: str | bytes, mode: str = "", *args: Any, **kwargs: Any
747 ) -> Image.core.ImagingCore:
748 im = self.font.getmask(text, mode, *args, **kwargs)
749 if self.orientation is not None:
750 return im.transpose(self.orientation)
751 return im
753 def getbbox(
754 self, text: str | bytes, *args: Any, **kwargs: Any
755 ) -> tuple[int, int, float, float]:
756 # TransposedFont doesn't support getmask2, move top-left point to (0, 0)
757 # this has no effect on ImageFont and simulates anchor="lt" for FreeTypeFont
758 left, top, right, bottom = self.font.getbbox(text, *args, **kwargs)
759 width = right - left
760 height = bottom - top
761 if self.orientation in (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270):
762 return 0, 0, height, width
763 return 0, 0, width, height
765 def getlength(self, text: str | bytes, *args: Any, **kwargs: Any) -> float:
766 if self.orientation in (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270):
767 msg = "text length is undefined for text rotated by 90 or 270 degrees"
768 raise ValueError(msg)
769 return self.font.getlength(text, *args, **kwargs)
772def load(filename: str) -> ImageFont:
773 """
774 Load a font file. This function loads a font object from the given
775 bitmap font file, and returns the corresponding font object. For loading TrueType
776 or OpenType fonts instead, see :py:func:`~PIL.ImageFont.truetype`.
778 :param filename: Name of font file.
779 :return: A font object.
780 :exception OSError: If the file could not be read.
781 """
782 f = ImageFont()
783 f._load_pilfont(filename)
784 return f
787def truetype(
788 font: StrOrBytesPath | BinaryIO,
789 size: float = 10,
790 index: int = 0,
791 encoding: str = "",
792 layout_engine: Layout | None = None,
793) -> FreeTypeFont:
794 """
795 Load a TrueType or OpenType font from a file or file-like object,
796 and create a font object. This function loads a font object from the given
797 file or file-like object, and creates a font object for a font of the given
798 size. For loading bitmap fonts instead, see :py:func:`~PIL.ImageFont.load`
799 and :py:func:`~PIL.ImageFont.load_path`.
801 Pillow uses FreeType to open font files. On Windows, be aware that FreeType
802 will keep the file open as long as the FreeTypeFont object exists. Windows
803 limits the number of files that can be open in C at once to 512, so if many
804 fonts are opened simultaneously and that limit is approached, an
805 ``OSError`` may be thrown, reporting that FreeType "cannot open resource".
806 A workaround would be to copy the file(s) into memory, and open that instead.
808 This function requires the _imagingft service.
810 :param font: A filename or file-like object containing a TrueType font.
811 If the file is not found in this filename, the loader may also
812 search in other directories, such as:
814 * The :file:`fonts/` directory on Windows,
815 * :file:`/Library/Fonts/`, :file:`/System/Library/Fonts/`
816 and :file:`~/Library/Fonts/` on macOS.
817 * :file:`~/.local/share/fonts`, :file:`/usr/local/share/fonts`,
818 and :file:`/usr/share/fonts` on Linux; or those specified by
819 the ``XDG_DATA_HOME`` and ``XDG_DATA_DIRS`` environment variables
820 for user-installed and system-wide fonts, respectively.
822 :param size: The requested size, in pixels.
823 :param index: Which font face to load (default is first available face).
824 :param encoding: Which font encoding to use (default is Unicode). Possible
825 encodings include (see the FreeType documentation for more
826 information):
828 * "unic" (Unicode)
829 * "symb" (Microsoft Symbol)
830 * "ADOB" (Adobe Standard)
831 * "ADBE" (Adobe Expert)
832 * "ADBC" (Adobe Custom)
833 * "armn" (Apple Roman)
834 * "sjis" (Shift JIS)
835 * "gb " (PRC)
836 * "big5"
837 * "wans" (Extended Wansung)
838 * "joha" (Johab)
839 * "lat1" (Latin-1)
841 This specifies the character set to use. It does not alter the
842 encoding of any text provided in subsequent operations.
843 :param layout_engine: Which layout engine to use, if available:
844 :attr:`.ImageFont.Layout.BASIC` or :attr:`.ImageFont.Layout.RAQM`.
845 If it is available, Raqm layout will be used by default.
846 Otherwise, basic layout will be used.
848 Raqm layout is recommended for all non-English text. If Raqm layout
849 is not required, basic layout will have better performance.
851 You can check support for Raqm layout using
852 :py:func:`PIL.features.check_feature` with ``feature="raqm"``.
854 .. versionadded:: 4.2.0
855 :return: A font object.
856 :exception OSError: If the file could not be read.
857 :exception ValueError: If the font size is not greater than zero.
858 """
860 def freetype(font: StrOrBytesPath | BinaryIO) -> FreeTypeFont:
861 return FreeTypeFont(font, size, index, encoding, layout_engine)
863 try:
864 return freetype(font)
865 except OSError:
866 if not is_path(font):
867 raise
868 ttf_filename = os.path.basename(font)
870 dirs = []
871 if sys.platform == "win32":
872 # check the windows font repository
873 # NOTE: must use uppercase WINDIR, to work around bugs in
874 # 1.5.2's os.environ.get()
875 windir = os.environ.get("WINDIR")
876 if windir:
877 dirs.append(os.path.join(windir, "fonts"))
878 elif sys.platform in ("linux", "linux2"):
879 data_home = os.environ.get("XDG_DATA_HOME")
880 if not data_home:
881 # The freedesktop spec defines the following default directory for
882 # when XDG_DATA_HOME is unset or empty. This user-level directory
883 # takes precedence over system-level directories.
884 data_home = os.path.expanduser("~/.local/share")
885 xdg_dirs = [data_home]
887 data_dirs = os.environ.get("XDG_DATA_DIRS")
888 if not data_dirs:
889 # Similarly, defaults are defined for the system-level directories
890 data_dirs = "/usr/local/share:/usr/share"
891 xdg_dirs += data_dirs.split(":")
893 dirs += [os.path.join(xdg_dir, "fonts") for xdg_dir in xdg_dirs]
894 elif sys.platform == "darwin":
895 dirs += [
896 "/Library/Fonts",
897 "/System/Library/Fonts",
898 os.path.expanduser("~/Library/Fonts"),
899 ]
901 ext = os.path.splitext(ttf_filename)[1]
902 first_font_with_a_different_extension = None
903 for directory in dirs:
904 for walkroot, walkdir, walkfilenames in os.walk(directory):
905 for walkfilename in walkfilenames:
906 if ext and walkfilename == ttf_filename:
907 return freetype(os.path.join(walkroot, walkfilename))
908 elif not ext and os.path.splitext(walkfilename)[0] == ttf_filename:
909 fontpath = os.path.join(walkroot, walkfilename)
910 if os.path.splitext(fontpath)[1] == ".ttf":
911 return freetype(fontpath)
912 if not ext and first_font_with_a_different_extension is None:
913 first_font_with_a_different_extension = fontpath
914 if first_font_with_a_different_extension:
915 return freetype(first_font_with_a_different_extension)
916 raise
919def load_path(filename: str | bytes) -> ImageFont:
920 """
921 Load font file. Same as :py:func:`~PIL.ImageFont.load`, but searches for a
922 bitmap font along the Python path.
924 :param filename: Name of font file.
925 :return: A font object.
926 :exception OSError: If the file could not be read.
927 """
928 if not isinstance(filename, str):
929 filename = filename.decode("utf-8")
930 for directory in sys.path:
931 try:
932 return load(os.path.join(directory, filename))
933 except OSError:
934 pass
935 msg = f'cannot find font file "{filename}" in sys.path'
936 if os.path.exists(filename):
937 msg += f', did you mean ImageFont.load("{filename}") instead?'
939 raise OSError(msg)
942def load_default_imagefont() -> ImageFont:
943 f = ImageFont()
944 f._load_pilfont_data(
945 # courB08
946 BytesIO(base64.b64decode(b"""
947UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
948AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
949AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
950AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
951AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
952AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
953AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
954AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
955AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
956AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
957AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
958AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA
959BgAAAAH/+gADAAAAAQAAAAMABgAGAAAAAf/6AAT//QADAAAABgADAAYAAAAA//kABQABAAYAAAAL
960AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA
961AAAbAAYABgAAAAH/+QAE//wAGwAAAB4AAwAGAAAAAf/5AAQAAQAeAAAAIQAIAAYAAAAB//kABAAB
962ACEAAAAkAAgABgAAAAD/+QAE//0AJAAAACgABAAGAAAAAP/6AAX//wAoAAAALQAFAAYAAAAB//8A
963BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB
964//kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA
965AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH
966AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA
967ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv
968AAAAcQAEAAYAAAAA//wAAwACAHEAAAB0AAYABgAAAAD/+gAE//8AdAAAAHgABQAGAAAAAP/7AAT/
969/gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5
970AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA
971AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG
972AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA
973BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA
974AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA
9752AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF
976AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA////
977+gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA
978////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA
979BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv
980AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA
981AAE9AAEABgAAAAH/+QAE//wBPQAAAUAAAwAGAAAAAP/7AAYAAAFAAAABRgAFAAYAAP////kABQAA
982AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA
983BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP//
984//kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA
985AP////kABgAAAXcAAAF+AAcABgAAAAD/+QAGAAABfgAAAYQABwAGAAD////7AAUAAAGEAAABigAF
986AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB
987mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn
988AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA
989AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7
990AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA
991Av/6AAMAAQHdAAAB3gAHAAYAAAAA//kABAABAd4AAAHiAAgABgAAAAD/+wAF//0B4gAAAecAAgAA
992AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
993AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
994AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
995AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
996AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
997AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
998AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
999AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1000AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1001AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1002AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1003AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB
1004//sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA
1005AAAA//oABf//AfQAAAH5AAUABgAAAAD/+QAGAAAB+QAAAf8ABwAGAAAAAv/5AAMAAgH/AAACAAAJ
1006AAYAAAAA//kABQABAgAAAAIFAAgABgAAAAH/+gAE//sCBQAAAggAAQAGAAAAAP/5AAYAAAIIAAAC
1007DgAHAAYAAAAB//kABf/+Ag4AAAISAAUABgAA////+wAGAAACEgAAAhkABQAGAAAAAP/7AAX//gIZ
1008AAACHgADAAYAAAAA//wABf/9Ah4AAAIjAAEABgAAAAD/+QAHAAACIwAAAioABwAGAAAAAP/6AAT/
1009+wIqAAACLgABAAYAAAAA//kABP/8Ai4AAAIyAAMABgAAAAD/+gAFAAACMgAAAjcABgAGAAAAAf/5
1010AAT//QI3AAACOgAEAAYAAAAB//kABP/9AjoAAAI9AAQABgAAAAL/+QAE//sCPQAAAj8AAgAGAAD/
1011///7AAYAAgI/AAACRgAHAAYAAAAA//kABgABAkYAAAJMAAgABgAAAAH//AAD//0CTAAAAk4AAQAG
1012AAAAAf//AAQAAgJOAAACUQADAAYAAAAB//kABP/9AlEAAAJUAAQABgAAAAH/+QAF//4CVAAAAlgA
1013BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA
1014Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC
1015eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG
1016AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA////
1017+gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA
1018////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA
1019BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT
1020AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A
1021AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA
1022Au4AAALzAAkABgAAAAD/9wAFAAAC8wAAAvgACQAGAAAAAP/4AAUAAAL4AAAC/QAIAAYAAAAA//oA
1023Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP//
1024//cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA
1025AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ
1026AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA
1027LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5
1028AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA
1029AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5
1030AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA
1031AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG
1032AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA
1033EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK
1034AJsAEQAGAAAAAP/6AAX//wCbAAoAoAAPAAYAAAAA//oABQABAKAACgClABEABgAA////+AAGAAAA
1035pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG
1036AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA////
1037+QAGAAIAzgAKANUAEw==
1038""")),
1039 Image.open(BytesIO(base64.b64decode(b"""
1040iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u
1041Mc4b7vuds/xzjz5/3/7u/n9vMe7vnfH/9++vPn/xyf5zhxzjt8GHw8+2d83u8x27199/nxuQ6Od9
1042M43/5z2I+9n9ZtmDBwMQECDRQw/eQIQohJXxpBCNVE6QCCAAAAD//wBlAJr/AgALyj1t/wINwq0g
1043LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F
1044IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA
1045Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791
1046NAADfcoIDyP44K/jv4Y63/Z+t98Ovt+ub4T48LAAAAD//wBlAJr/AuplMlADJAAAAGuAphWpqhMx
1047in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9
1048SjdavWA8ePHeBIKB//81/83ndznOaXx379wAAAD//wBlAJr/AqDxW+D3AABAAbUh/QMnbQag/gAY
1049AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt
1050y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG
1051ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY
1052lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H
1053/Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3
1054AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47
1055c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/
1056/yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw
1057pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv
1058oJodAAAAAP//Yqo/83+dxePWlxl3npsel9lvLfPcqlE9725C+acfVLMEAAAA//9i+s9gwCoaaGMR
1059evta/58PTEWzr21hufPjA8N+qlnBwAAAAAD//2JiWLci5v1+HmFXDqcnULE/MxgYGBj+f6CaJQAA
1060AAD//2Ji2FrkY3iYpYC5qDeGgeEMAwPDvwQBBoYvcTwOVLMEAAAA//9isDBgkP///0EOg9z35v//
1061Gc/eeW7BwPj5+QGZhANUswMAAAD//2JgqGBgYGBgqEMXlvhMPUsAAAAA//8iYDd1AAAAAP//AwDR
1062w7IkEbzhVQAAAABJRU5ErkJggg==
1063"""))),
1064 )
1065 return f
1068def load_default(size: float | None = None) -> FreeTypeFont | ImageFont:
1069 """If FreeType support is available, load a version of Aileron Regular,
1070 https://dotcolon.net/fonts/aileron, with a more limited character set.
1072 Otherwise, load a "better than nothing" font.
1074 .. versionadded:: 1.1.4
1076 :param size: The font size of Aileron Regular.
1078 .. versionadded:: 10.1.0
1080 :return: A font object.
1081 """
1082 if isinstance(core, ModuleType) or size is not None:
1083 return truetype(
1084 BytesIO(base64.b64decode(b"""
1085AAEAAAAPAIAAAwBwRkZUTYwDlUAAADFoAAAAHEdERUYAqADnAAAo8AAAACRHUE9ThhmITwAAKfgAA
1086AduR1NVQnHxefoAACkUAAAA4k9TLzJovoHLAAABeAAAAGBjbWFw5lFQMQAAA6gAAAGqZ2FzcP//AA
1087MAACjoAAAACGdseWYmRXoPAAAGQAAAHfhoZWFkE18ayQAAAPwAAAA2aGhlYQboArEAAAE0AAAAJGh
1088tdHjjERZ8AAAB2AAAAdBsb2NhuOexrgAABVQAAADqbWF4cAC7AEYAAAFYAAAAIG5hbWUr+h5lAAAk
1089OAAAA6Jwb3N0D3oPTQAAJ9wAAAEKAAEAAAABGhxJDqIhXw889QALA+gAAAAA0Bqf2QAAAADhCh2h/
10902r/LgOxAyAAAAAIAAIAAAAAAAAAAQAAA8r/GgAAA7j/av9qA7EAAQAAAAAAAAAAAAAAAAAAAHQAAQ
1091AAAHQAQwAFAAAAAAACAAAAAQABAAAAQAAAAAAAAAADAfoBkAAFAAgCigJYAAAASwKKAlgAAAFeADI
1092BPgAAAAAFAAAAAAAAAAAAAAcAAAAAAAAAAAAAAABVS1dOAEAAIPsCAwL/GgDIA8oA5iAAAJMAAAAA
1093AhICsgAAACAAAwH0AAAAAAAAAU0AAADYAAAA8gA5AVMAVgJEAEYCRAA1AuQAKQKOAEAAsAArATsAZ
1094AE7AB4CMABVAkQAUADc/+EBEgAgANwAJQEv//sCRAApAkQAggJEADwCRAAtAkQAIQJEADkCRAArAk
1095QAMgJEACwCRAAxANwAJQDc/+ECRABnAkQAUAJEAEQB8wAjA1QANgJ/AB0CcwBkArsALwLFAGQCSwB
1096kAjcAZALGAC8C2gBkAQgAZAIgADcCYQBkAj8AZANiAGQCzgBkAuEALwJWAGQC3QAvAmsAZAJJADQC
1097ZAAiAqoAXgJuACADuAAaAnEAGQJFABMCTwAuATMAYgEv//sBJwAiAkQAUAH0ADIBLAApAhMAJAJjA
1098EoCEQAeAmcAHgIlAB4BIgAVAmcAHgJRAEoA7gA+AOn/8wIKAEoA9wBGA1cASgJRAEoCSgAeAmMASg
1099JnAB4BSgBKAcsAGAE5ABQCUABCAgIAAQMRAAEB4v/6AgEAAQHOABQBLwBAAPoAYAEvACECRABNA0Y
1100AJAItAHgBKgAcAkQAUAEsAHQAygAgAi0AOQD3ADYA9wAWAaEANgGhABYCbAAlAYMAeAGDADkA6/9q
1101AhsAFAIKABUB/QAVAAAAAwAAAAMAAAAcAAEAAAAAAKQAAwABAAAAHAAEAIgAAAAeABAAAwAOAH4Aq
1102QCrALEAtAC3ALsgGSAdICYgOiBEISL7Av//AAAAIACpAKsAsAC0ALcAuyAYIBwgJiA5IEQhIvsB//
1103//4/+5/7j/tP+y/7D/reBR4E/gR+A14CzfTwVxAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1104AAAAAAAEGAAABAAAAAAAAAAECAAAAAgAAAAAAAAAAAAAAAAAAAAEAAAMEBQYHCAkKCwwNDg8QERIT
1105FBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMT
1106U5PUFFSU1RVVldYWVpbXF1eX2BhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQAAA
1107AAAAAAYnFmAAAAAABlAAAAAAAAAAAAAAAAAAAAAAAAAAAAY2htAAAAAAAAAABrbGlqAAAAAHAAbm9
1108ycwBnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmACYAJgAmAD4AUgCCAMoBCgFO
1109AVwBcgGIAaYBvAHKAdYB6AH2AgwCIAJKAogCpgLWAw4DIgNkA5wDugPUA+gD/AQQBEYEogS8BPoFJ
1110gVSBWoFgAWwBcoF1gX6BhQGJAZMBmgGiga0BuIHGgdUB2YHkAeiB8AH3AfyCAoIHAgqCDoITghcCG
1111oIogjSCPoJKglYCXwJwgnqCgIKKApACl4Klgq8CtwLDAs8C1YLjAuyC9oL7gwMDCYMSAxgDKAMrAz
1112qDQoNTA1mDYQNoA2uDcAN2g3oDfYODA4iDkoOXA5sDnoOnA7EDvwAAAAFAAAAAAH0ArwAAwAGAAkA
1113DAAPAAAxESERAxMhExcRASELARETAfT6qv6syKr+jgFUqsiqArz9RAGLAP/+1P8B/v3VAP8BLP4CA
1114P8AAgA5//IAuQKyAAMACwAANyMDMwIyFhQGIiY0oE4MZk84JCQ4JLQB/v3AJDgkJDgAAgBWAeUBPA
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
1160vArIACwAAJRUhESEVIRUhFSEVAi/+NQHB/pUBTf6zRkYCskbwRvAAAAABAGQAAAIlArIACQAAExUh
1161FSERIxEhFboBQ/69VgHBAmzwRv7KArJGAAAAAAEAL//yAo8CwAAfAAABMxEjNQcGIyImNTQ2MzIWH
1162wEjJyYjIgYVFBYzMjY1IwGP90wfPnWTprSSf48LAVYCIqJofHllVG+hAU3+s3hARsicn8uAagoKpq
1163N/gaN1XAAAAAEAZAAAAowCsgALAAABESMRIREjETMRIRECjFb+hFZWAXwCsv1OAS7+0gKy/sQBPAA
1164AAAABAGQAAAC6ArIAAwAAMyMRM7pWVgKyAAABADf/8gHoArIAEwAAAREUBw4BIyImLwEzFxYzMjc2
1165NREB6AIFcGpgbQIBVgIHfXQKAQKy/lYxIltob2EpKYyEFD0BpwAAAAABAGQAAAJ0ArIACwAACQEjA
1166wcVIxEzEQEzATsBJ3ntQlZWAVVlAWH+nwEnR+ACsv6RAW8AAQBkAAACLwKyAAUAACUVIREzEQIv/j
1167VWRkYCsv2UAAABAGQAAAMUArIAFAAAAREjETQ3BgcDIwMmJxYVESMRMxsBAxRWAiMxemx8NxsCVo7
1168MywKy/U4BY7ZLco7+nAFmoFxLtP6dArL9lwJpAAAAAAEAZAAAAoACsgANAAAhIwEWFREjETMBJjUR
1169MwKAhP67A1aEAUUDVAJeeov+pwKy/aJ5jAFZAAAAAgAv//ICuwLAAAkAEwAAEiAWFRQGICY1NBIyN
1170jU0JiIGFRTbATSsrP7MrNrYenrYegLAxaKhxsahov47nIeIm5uIhwACAGQAAAJHArIADgAYAAABHg
1171EVFAYHBisBESMRMzITNjQnJisBETMyAZRUX2VOHzuAVtY7GlxcGDWIiDUCrgtnVlVpCgT+5gKy/rU
1172V1BUF/vgAAAACAC//zAK9AsAAEgAcAAAlFhcHJiMiBwYjIiY1NDYgFhUUJRQWMjY1NCYiBgI9PUMx
1173UDcfKh8omqysATSs/dR62Hp62HpICTg7NgkHxqGixcWitbWHnJyHiJubAAIAZAAAAlgCsgAXACMAA
1174CUWFyMmJyYnJisBESMRMzIXHgEVFAYHFiUzMjc+ATU0JyYrAQIqDCJfGQwNWhAhglbiOx9QXEY1Tv
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
1250gQAAwABBAkADAAuAkwATgBvACAAUgBpAGcAaAB0AHMAIABSAGUAcwBlAHIAdgBlAGQALgAATm8gUm
1251lnaHRzIFJlc2VydmVkLgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAUgBlAGcAdQBsAGEAcgAAUmV
1252ndWxhcgAAMQAuADEAMAAyADsAVQBLAFcATgA7AEEAaQBsAGUAcgBvAG4ALQBSAGUAZwB1AGwAYQBy
1253AAAxLjEwMjtVS1dOO0FpbGVyb24tUmVndWxhcgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAVgBlA
1254HIAcwBpAG8AbgAgADEALgAxADAAMgA7AFAAUwAgADAAMAAxAC4AMQAwADIAOwBoAG8AdABjAG8Abg
1255B2ACAAMQAuADAALgA3ADAAOwBtAGEAawBlAG8AdABmAC4AbABpAGIAMgAuADUALgA1ADgAMwAyADk
1256AAFZlcnNpb24gMS4xMDI7UFMgMDAxLjEwMjtob3Rjb252IDEuMC43MDttYWtlb3RmLmxpYjIuNS41
1257ODMyOQAAQQBpAGwAZQByAG8AbgAtAFIAZQBnAHUAbABhAHIAAEFpbGVyb24tUmVndWxhcgAAUwBvA
1258HIAYQAgAFMAYQBnAGEAbgBvAABTb3JhIFNhZ2FubwAAUwBvAHIAYQAgAFMAYQBnAGEAbgBvAABTb3
1259JhIFNhZ2FubwAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBsAG8AbgAuAG4AZQB0AAB
1260odHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBs
1261AG8AbgAuAG4AZQB0AABodHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAAAACAAAAAAAA/4MAMgAAAAAAA
1262AAAAAAAAAAAAAAAAAAAAHQAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATAB
1263QAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAA
1264xADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0A
1265TgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAIsAqQCDAJMAjQDDAKoAtgC3A
1266LQAtQCrAL4AvwC8AIwAwADBAAAAAAAB//8AAgABAAAADAAAABwAAAACAAIAAwBxAAEAcgBzAAIABA
1267AAAAIAAAABAAAACgBMAGYAAkRGTFQADmxhdG4AGgAEAAAAAP//AAEAAAAWAANDQVQgAB5NT0wgABZ
1268ST00gABYAAP//AAEAAAAA//8AAgAAAAEAAmxpZ2EADmxvY2wAFAAAAAEAAQAAAAEAAAACAAYAEAAG
1269AAAAAgASADQABAAAAAEATAADAAAAAgAQABYAAQAcAAAAAQABAE8AAQABAGcAAQABAE8AAwAAAAIAE
1270AAWAAEAHAAAAAEAAQAvAAEAAQBnAAEAAQAvAAEAGgABAAgAAgAGAAwAcwACAE8AcgACAEwAAQABAE
1271kAAAABAAAACgBGAGAAAkRGTFQADmxhdG4AHAAEAAAAAP//AAIAAAABABYAA0NBVCAAFk1PTCAAFlJ
1272PTSAAFgAA//8AAgAAAAEAAmNwc3AADmtlcm4AFAAAAAEAAAAAAAEAAQACAAYADgABAAAAAQASAAIA
1273AAACAB4ANgABAAoABQAFAAoAAgABACQAPQAAAAEAEgAEAAAAAQAMAAEAOP/nAAEAAQAkAAIGigAEA
1274AAFJAXKABoAGQAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1275AAAAD/sv+4/+z/7v/MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1276AAAAAAAD/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9T/6AAAAAD/8QAA
1277ABD/vQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7gAAAAAAAAAAAAAAAAAA//MAA
1278AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAP/5AAAAAAAAAA
1279AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gAAD/4AAAAAAAAAAAAAAAAAA
1280AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//L/9AAAAAAAAAAAAAAAAAAAAAAA
1281AAAAAAAAAAAA/+gAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1282AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAAAAA
1283AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/mAAAAAAAAAAAAAAAAAAD
1284/4gAA//AAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+AAAAAAAAP/OAAAAAAAAAAAAAAAA
1285AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zv/qAAAAAP/0AAAACAAAAAAAAAAAAAAAAAAAAAAAA
1286AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/ZAAD/egAA/1kAAAAA/5D/rgAAAAAAAAAAAA
1287AAAAAAAAAAAAAAAAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1288AAAAAAAAAAAAAAAAAAAD/8AAA/7b/8P+wAAD/8P/E/98AAAAA/8P/+P/0//oAAAAAAAAAAAAA//gA
1289AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+AAAAAAAAAAAAAAA
1290AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/w//C/9MAAP/SAAD/9wAAAAAAAA
1291AAAAAAAAAAAAAAAAAAAAAAAAAAAAD/yAAA/+kAAAAA//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1292AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9wAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1293AAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1294AAAAAAAAP/cAAAAAAAAAAAAAAAA/7YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1295AAAAAAAAAAAAAAAAAAAAAAAAAAAP/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6AAAAAAAAAA
1296AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAkAFAAEAAAAAQACwAAABcA
1297BgAAAAAAAAAIAA4AAAAAAAsAEgAAAAAAAAATABkAAwANAAAAAQAJAAAAAAAAAAAAAAAAAAAAGAAAA
1298AAABwAAAAAAAAAAAAAAFQAFAAAAAAAYABgAAAAUAAAACgAAAAwAAgAPABEAFgAAAAAAAAAAAAAAAA
1299AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAEAEQBdAAYAAAAAAAAAAAAAAAAAAAAAAAA
1300AAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAcAAAAAAAAABwAAAAAACAAAAAAAAAAAAAcAAAAHAAAAEwAJ
1301ABUADgAPAAAACwAQAAAAAAAAAAAAAAAAAAUAGAACAAIAAgAAAAIAGAAXAAAAGAAAABYAFgACABYAA
1302gAWAAAAEQADAAoAFAAMAA0ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAEgAGAAEAHgAkAC
1303YAJwApACoALQAuAC8AMgAzADcAOAA5ADoAPAA9AEUASABOAE8AUgBTAFUAVwBZAFoAWwBcAF0AcwA
1304AAAAAAQAAAADa3tfFAAAAANAan9kAAAAA4QodoQ==
1305""")),
1306 10 if size is None else size,
1307 layout_engine=Layout.BASIC,
1308 )
1309 return load_default_imagefont()