Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/PIL/ImageFont.py: 36%
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 # read PILfont header
129 if file.readline() != b"PILfont\n":
130 msg = "Not a PILfont file"
131 raise SyntaxError(msg)
132 file.readline().split(b";")
133 self.info = [] # FIXME: should be a dictionary
134 while True:
135 s = file.readline()
136 if not s or s == b"DATA\n":
137 break
138 self.info.append(s)
140 # read PILfont metrics
141 data = file.read(256 * 20)
143 # check image
144 if image.mode not in ("1", "L"):
145 msg = "invalid font image mode"
146 raise TypeError(msg)
148 image.load()
150 self.font = Image.core.font(image.im, data)
152 def getmask(
153 self, text: str | bytes, mode: str = "", *args: Any, **kwargs: Any
154 ) -> Image.core.ImagingCore:
155 """
156 Create a bitmap for the text.
158 If the font uses antialiasing, the bitmap should have mode ``L`` and use a
159 maximum value of 255. Otherwise, it should have mode ``1``.
161 :param text: Text to render.
162 :param mode: Used by some graphics drivers to indicate what mode the
163 driver prefers; if empty, the renderer may return either
164 mode. Note that the mode is always a string, to simplify
165 C-level implementations.
167 .. versionadded:: 1.1.5
169 :return: An internal PIL storage memory instance as defined by the
170 :py:mod:`PIL.Image.core` interface module.
171 """
172 _string_length_check(text)
173 Image._decompression_bomb_check(self.font.getsize(text))
174 return self.font.getmask(text, mode)
176 def getbbox(
177 self, text: str | bytes | bytearray, *args: Any, **kwargs: Any
178 ) -> tuple[int, int, int, int]:
179 """
180 Returns bounding box (in pixels) of given text.
182 .. versionadded:: 9.2.0
184 :param text: Text to render.
186 :return: ``(left, top, right, bottom)`` bounding box
187 """
188 _string_length_check(text)
189 width, height = self.font.getsize(text)
190 return 0, 0, width, height
192 def getlength(
193 self, text: str | bytes | bytearray, *args: Any, **kwargs: Any
194 ) -> int:
195 """
196 Returns length (in pixels) of given text.
197 This is the amount by which following text should be offset.
199 .. versionadded:: 9.2.0
200 """
201 _string_length_check(text)
202 width, height = self.font.getsize(text)
203 return width
206##
207# Wrapper for FreeType fonts. Application code should use the
208# <b>truetype</b> factory function to create font objects.
211class FreeTypeFont:
212 """FreeType font wrapper (requires _imagingft service)"""
214 font: Font
215 font_bytes: bytes
217 def __init__(
218 self,
219 font: StrOrBytesPath | BinaryIO,
220 size: float = 10,
221 index: int = 0,
222 encoding: str = "",
223 layout_engine: Layout | None = None,
224 ) -> None:
225 # FIXME: use service provider instead
227 if isinstance(core, DeferredError):
228 raise core.ex
230 if size <= 0:
231 msg = f"font size must be greater than 0, not {size}"
232 raise ValueError(msg)
234 self.path = font
235 self.size = size
236 self.index = index
237 self.encoding = encoding
239 if layout_engine not in (Layout.BASIC, Layout.RAQM):
240 layout_engine = Layout.BASIC
241 if core.HAVE_RAQM:
242 layout_engine = Layout.RAQM
243 elif layout_engine == Layout.RAQM and not core.HAVE_RAQM:
244 warnings.warn(
245 "Raqm layout was requested, but Raqm is not available. "
246 "Falling back to basic layout."
247 )
248 layout_engine = Layout.BASIC
250 self.layout_engine = layout_engine
252 def load_from_bytes(f: IO[bytes]) -> None:
253 self.font_bytes = f.read()
254 self.font = core.getfont(
255 "", size, index, encoding, self.font_bytes, layout_engine
256 )
258 if is_path(font):
259 font = os.fspath(font)
260 if sys.platform == "win32":
261 font_bytes_path = font if isinstance(font, bytes) else font.encode()
262 try:
263 font_bytes_path.decode("ascii")
264 except UnicodeDecodeError:
265 # FreeType cannot load fonts with non-ASCII characters on Windows
266 # So load it into memory first
267 with open(font, "rb") as f:
268 load_from_bytes(f)
269 return
270 self.font = core.getfont(
271 font, size, index, encoding, layout_engine=layout_engine
272 )
273 else:
274 load_from_bytes(cast(IO[bytes], font))
276 def __getstate__(self) -> list[Any]:
277 return [self.path, self.size, self.index, self.encoding, self.layout_engine]
279 def __setstate__(self, state: list[Any]) -> None:
280 path, size, index, encoding, layout_engine = state
281 FreeTypeFont.__init__(self, path, size, index, encoding, layout_engine)
283 def getname(self) -> tuple[str | None, str | None]:
284 """
285 :return: A tuple of the font family (e.g. Helvetica) and the font style
286 (e.g. Bold)
287 """
288 return self.font.family, self.font.style
290 def getmetrics(self) -> tuple[int, int]:
291 """
292 :return: A tuple of the font ascent (the distance from the baseline to
293 the highest outline point) and descent (the distance from the
294 baseline to the lowest outline point, a negative value)
295 """
296 return self.font.ascent, self.font.descent
298 def getlength(
299 self,
300 text: str | bytes,
301 mode: str = "",
302 direction: str | None = None,
303 features: list[str] | None = None,
304 language: str | None = None,
305 ) -> float:
306 """
307 Returns length (in pixels with 1/64 precision) of given text when rendered
308 in font with provided direction, features, and language.
310 This is the amount by which following text should be offset.
311 Text bounding box may extend past the length in some fonts,
312 e.g. when using italics or accents.
314 The result is returned as a float; it is a whole number if using basic layout.
316 Note that the sum of two lengths may not equal the length of a concatenated
317 string due to kerning. If you need to adjust for kerning, include the following
318 character and subtract its length.
320 For example, instead of ::
322 hello = font.getlength("Hello")
323 world = font.getlength("World")
324 hello_world = hello + world # not adjusted for kerning
325 assert hello_world == font.getlength("HelloWorld") # may fail
327 use ::
329 hello = font.getlength("HelloW") - font.getlength("W") # adjusted for kerning
330 world = font.getlength("World")
331 hello_world = hello + world # adjusted for kerning
332 assert hello_world == font.getlength("HelloWorld") # True
334 or disable kerning with (requires libraqm) ::
336 hello = draw.textlength("Hello", font, features=["-kern"])
337 world = draw.textlength("World", font, features=["-kern"])
338 hello_world = hello + world # kerning is disabled, no need to adjust
339 assert hello_world == draw.textlength("HelloWorld", font, features=["-kern"])
341 .. versionadded:: 8.0.0
343 :param text: Text to measure.
344 :param mode: Used by some graphics drivers to indicate what mode the
345 driver prefers; if empty, the renderer may return either
346 mode. Note that the mode is always a string, to simplify
347 C-level implementations.
349 :param direction: Direction of the text. It can be 'rtl' (right to
350 left), 'ltr' (left to right) or 'ttb' (top to bottom).
351 Requires libraqm.
353 :param features: A list of OpenType font features to be used during text
354 layout. This is usually used to turn on optional
355 font features that are not enabled by default,
356 for example 'dlig' or 'ss01', but can be also
357 used to turn off default font features for
358 example '-liga' to disable ligatures or '-kern'
359 to disable kerning. To get all supported
360 features, see
361 https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist
362 Requires libraqm.
364 :param language: Language of the text. Different languages may use
365 different glyph shapes or ligatures. This parameter tells
366 the font which language the text is in, and to apply the
367 correct substitutions as appropriate, if available.
368 It should be a `BCP 47 language code
369 <https://www.w3.org/International/articles/language-tags/>`_
370 Requires libraqm.
372 :return: Either width for horizontal text, or height for vertical text.
373 """
374 _string_length_check(text)
375 return self.font.getlength(text, mode, direction, features, language) / 64
377 def getbbox(
378 self,
379 text: str | bytes,
380 mode: str = "",
381 direction: str | None = None,
382 features: list[str] | None = None,
383 language: str | None = None,
384 stroke_width: float = 0,
385 anchor: str | None = None,
386 ) -> tuple[float, float, float, float]:
387 """
388 Returns bounding box (in pixels) of given text relative to given anchor
389 when rendered in font with provided direction, features, and language.
391 Use :py:meth:`getlength()` to get the offset of following text with
392 1/64 pixel precision. The bounding box includes extra margins for
393 some fonts, e.g. italics or accents.
395 .. versionadded:: 8.0.0
397 :param text: Text to render.
398 :param mode: Used by some graphics drivers to indicate what mode the
399 driver prefers; if empty, the renderer may return either
400 mode. Note that the mode is always a string, to simplify
401 C-level implementations.
403 :param direction: Direction of the text. It can be 'rtl' (right to
404 left), 'ltr' (left to right) or 'ttb' (top to bottom).
405 Requires libraqm.
407 :param features: A list of OpenType font features to be used during text
408 layout. This is usually used to turn on optional
409 font features that are not enabled by default,
410 for example 'dlig' or 'ss01', but can be also
411 used to turn off default font features for
412 example '-liga' to disable ligatures or '-kern'
413 to disable kerning. To get all supported
414 features, see
415 https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist
416 Requires libraqm.
418 :param language: Language of the text. Different languages may use
419 different glyph shapes or ligatures. This parameter tells
420 the font which language the text is in, and to apply the
421 correct substitutions as appropriate, if available.
422 It should be a `BCP 47 language code
423 <https://www.w3.org/International/articles/language-tags/>`_
424 Requires libraqm.
426 :param stroke_width: The width of the text stroke.
428 :param anchor: The text anchor alignment. Determines the relative location of
429 the anchor to the text. The default alignment is top left,
430 specifically ``la`` for horizontal text and ``lt`` for
431 vertical text. See :ref:`text-anchors` for details.
433 :return: ``(left, top, right, bottom)`` bounding box
434 """
435 _string_length_check(text)
436 size, offset = self.font.getsize(
437 text, mode, direction, features, language, anchor
438 )
439 left, top = offset[0] - stroke_width, offset[1] - stroke_width
440 width, height = size[0] + 2 * stroke_width, size[1] + 2 * stroke_width
441 return left, top, left + width, top + height
443 def getmask(
444 self,
445 text: str | bytes,
446 mode: str = "",
447 direction: str | None = None,
448 features: list[str] | None = None,
449 language: str | None = None,
450 stroke_width: float = 0,
451 anchor: str | None = None,
452 ink: int = 0,
453 start: tuple[float, float] | None = None,
454 ) -> Image.core.ImagingCore:
455 """
456 Create a bitmap for the text.
458 If the font uses antialiasing, the bitmap should have mode ``L`` and use a
459 maximum value of 255. If the font has embedded color data, the bitmap
460 should have mode ``RGBA``. Otherwise, it should have mode ``1``.
462 :param text: Text to render.
463 :param mode: Used by some graphics drivers to indicate what mode the
464 driver prefers; if empty, the renderer may return either
465 mode. Note that the mode is always a string, to simplify
466 C-level implementations.
468 .. versionadded:: 1.1.5
470 :param direction: Direction of the text. It can be 'rtl' (right to
471 left), 'ltr' (left to right) or 'ttb' (top to bottom).
472 Requires libraqm.
474 .. versionadded:: 4.2.0
476 :param features: A list of OpenType font features to be used during text
477 layout. This is usually used to turn on optional
478 font features that are not enabled by default,
479 for example 'dlig' or 'ss01', but can be also
480 used to turn off default font features for
481 example '-liga' to disable ligatures or '-kern'
482 to disable kerning. To get all supported
483 features, see
484 https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist
485 Requires libraqm.
487 .. versionadded:: 4.2.0
489 :param language: Language of the text. Different languages may use
490 different glyph shapes or ligatures. This parameter tells
491 the font which language the text is in, and to apply the
492 correct substitutions as appropriate, if available.
493 It should be a `BCP 47 language code
494 <https://www.w3.org/International/articles/language-tags/>`_
495 Requires libraqm.
497 .. versionadded:: 6.0.0
499 :param stroke_width: The width of the text stroke.
501 .. versionadded:: 6.2.0
503 :param anchor: The text anchor alignment. Determines the relative location of
504 the anchor to the text. The default alignment is top left,
505 specifically ``la`` for horizontal text and ``lt`` for
506 vertical text. See :ref:`text-anchors` for details.
508 .. versionadded:: 8.0.0
510 :param ink: Foreground ink for rendering in RGBA mode.
512 .. versionadded:: 8.0.0
514 :param start: Tuple of horizontal and vertical offset, as text may render
515 differently when starting at fractional coordinates.
517 .. versionadded:: 9.4.0
519 :return: An internal PIL storage memory instance as defined by the
520 :py:mod:`PIL.Image.core` interface module.
521 """
522 return self.getmask2(
523 text,
524 mode,
525 direction=direction,
526 features=features,
527 language=language,
528 stroke_width=stroke_width,
529 anchor=anchor,
530 ink=ink,
531 start=start,
532 )[0]
534 def getmask2(
535 self,
536 text: str | bytes,
537 mode: str = "",
538 direction: str | None = None,
539 features: list[str] | None = None,
540 language: str | None = None,
541 stroke_width: float = 0,
542 anchor: str | None = None,
543 ink: int = 0,
544 start: tuple[float, float] | None = None,
545 *args: Any,
546 **kwargs: Any,
547 ) -> tuple[Image.core.ImagingCore, tuple[int, int]]:
548 """
549 Create a bitmap for the text.
551 If the font uses antialiasing, the bitmap should have mode ``L`` and use a
552 maximum value of 255. If the font has embedded color data, the bitmap
553 should have mode ``RGBA``. Otherwise, it should have mode ``1``.
555 :param text: Text to render.
556 :param mode: Used by some graphics drivers to indicate what mode the
557 driver prefers; if empty, the renderer may return either
558 mode. Note that the mode is always a string, to simplify
559 C-level implementations.
561 .. versionadded:: 1.1.5
563 :param direction: Direction of the text. It can be 'rtl' (right to
564 left), 'ltr' (left to right) or 'ttb' (top to bottom).
565 Requires libraqm.
567 .. versionadded:: 4.2.0
569 :param features: A list of OpenType font features to be used during text
570 layout. This is usually used to turn on optional
571 font features that are not enabled by default,
572 for example 'dlig' or 'ss01', but can be also
573 used to turn off default font features for
574 example '-liga' to disable ligatures or '-kern'
575 to disable kerning. To get all supported
576 features, see
577 https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist
578 Requires libraqm.
580 .. versionadded:: 4.2.0
582 :param language: Language of the text. Different languages may use
583 different glyph shapes or ligatures. This parameter tells
584 the font which language the text is in, and to apply the
585 correct substitutions as appropriate, if available.
586 It should be a `BCP 47 language code
587 <https://www.w3.org/International/articles/language-tags/>`_
588 Requires libraqm.
590 .. versionadded:: 6.0.0
592 :param stroke_width: The width of the text stroke.
594 .. versionadded:: 6.2.0
596 :param anchor: The text anchor alignment. Determines the relative location of
597 the anchor to the text. The default alignment is top left,
598 specifically ``la`` for horizontal text and ``lt`` for
599 vertical text. See :ref:`text-anchors` for details.
601 .. versionadded:: 8.0.0
603 :param ink: Foreground ink for rendering in RGBA mode.
605 .. versionadded:: 8.0.0
607 :param start: Tuple of horizontal and vertical offset, as text may render
608 differently when starting at fractional coordinates.
610 .. versionadded:: 9.4.0
612 :return: A tuple of an internal PIL storage memory instance as defined by the
613 :py:mod:`PIL.Image.core` interface module, and the text offset, the
614 gap between the starting coordinate and the first marking
615 """
616 _string_length_check(text)
617 if start is None:
618 start = (0, 0)
620 def fill(width: int, height: int) -> Image.core.ImagingCore:
621 size = (width, height)
622 Image._decompression_bomb_check(size)
623 return Image.core.fill("RGBA" if mode == "RGBA" else "L", size)
625 return self.font.render(
626 text,
627 fill,
628 mode,
629 direction,
630 features,
631 language,
632 stroke_width,
633 kwargs.get("stroke_filled", False),
634 anchor,
635 ink,
636 start,
637 )
639 def font_variant(
640 self,
641 font: StrOrBytesPath | BinaryIO | None = None,
642 size: float | None = None,
643 index: int | None = None,
644 encoding: str | None = None,
645 layout_engine: Layout | None = None,
646 ) -> FreeTypeFont:
647 """
648 Create a copy of this FreeTypeFont object,
649 using any specified arguments to override the settings.
651 Parameters are identical to the parameters used to initialize this
652 object.
654 :return: A FreeTypeFont object.
655 """
656 if font is None:
657 try:
658 font = BytesIO(self.font_bytes)
659 except AttributeError:
660 font = self.path
661 return FreeTypeFont(
662 font=font,
663 size=self.size if size is None else size,
664 index=self.index if index is None else index,
665 encoding=self.encoding if encoding is None else encoding,
666 layout_engine=layout_engine or self.layout_engine,
667 )
669 def get_variation_names(self) -> list[bytes]:
670 """
671 :returns: A list of the named styles in a variation font.
672 :exception OSError: If the font is not a variation font.
673 """
674 try:
675 names = self.font.getvarnames()
676 except AttributeError as e:
677 msg = "FreeType 2.9.1 or greater is required"
678 raise NotImplementedError(msg) from e
679 return [name.replace(b"\x00", b"") for name in names]
681 def set_variation_by_name(self, name: str | bytes) -> None:
682 """
683 :param name: The name of the style.
684 :exception OSError: If the font is not a variation font.
685 """
686 names = self.get_variation_names()
687 if not isinstance(name, bytes):
688 name = name.encode()
689 index = names.index(name) + 1
691 if index == getattr(self, "_last_variation_index", None):
692 # When the same name is set twice in a row,
693 # there is an 'unknown freetype error'
694 # https://savannah.nongnu.org/bugs/?56186
695 return
696 self._last_variation_index = index
698 self.font.setvarname(index)
700 def get_variation_axes(self) -> list[Axis]:
701 """
702 :returns: A list of the axes in a variation font.
703 :exception OSError: If the font is not a variation font.
704 """
705 try:
706 axes = self.font.getvaraxes()
707 except AttributeError as e:
708 msg = "FreeType 2.9.1 or greater is required"
709 raise NotImplementedError(msg) from e
710 for axis in axes:
711 if axis["name"]:
712 axis["name"] = axis["name"].replace(b"\x00", b"")
713 return axes
715 def set_variation_by_axes(self, axes: list[float]) -> None:
716 """
717 :param axes: A list of values for each axis.
718 :exception OSError: If the font is not a variation font.
719 """
720 try:
721 self.font.setvaraxes(axes)
722 except AttributeError as e:
723 msg = "FreeType 2.9.1 or greater is required"
724 raise NotImplementedError(msg) from e
727class TransposedFont:
728 """Wrapper for writing rotated or mirrored text"""
730 def __init__(
731 self, font: ImageFont | FreeTypeFont, orientation: Image.Transpose | None = None
732 ):
733 """
734 Wrapper that creates a transposed font from any existing font
735 object.
737 :param font: A font object.
738 :param orientation: An optional orientation. If given, this should
739 be one of Image.Transpose.FLIP_LEFT_RIGHT, Image.Transpose.FLIP_TOP_BOTTOM,
740 Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_180, or
741 Image.Transpose.ROTATE_270.
742 """
743 self.font = font
744 self.orientation = orientation # any 'transpose' argument, or None
746 def getmask(
747 self, text: str | bytes, mode: str = "", *args: Any, **kwargs: Any
748 ) -> Image.core.ImagingCore:
749 im = self.font.getmask(text, mode, *args, **kwargs)
750 if self.orientation is not None:
751 return im.transpose(self.orientation)
752 return im
754 def getbbox(
755 self, text: str | bytes, *args: Any, **kwargs: Any
756 ) -> tuple[int, int, float, float]:
757 # TransposedFont doesn't support getmask2, move top-left point to (0, 0)
758 # this has no effect on ImageFont and simulates anchor="lt" for FreeTypeFont
759 left, top, right, bottom = self.font.getbbox(text, *args, **kwargs)
760 width = right - left
761 height = bottom - top
762 if self.orientation in (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270):
763 return 0, 0, height, width
764 return 0, 0, width, height
766 def getlength(self, text: str | bytes, *args: Any, **kwargs: Any) -> float:
767 if self.orientation in (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270):
768 msg = "text length is undefined for text rotated by 90 or 270 degrees"
769 raise ValueError(msg)
770 return self.font.getlength(text, *args, **kwargs)
773def load(filename: str) -> ImageFont:
774 """
775 Load a font file. This function loads a font object from the given
776 bitmap font file, and returns the corresponding font object. For loading TrueType
777 or OpenType fonts instead, see :py:func:`~PIL.ImageFont.truetype`.
779 :param filename: Name of font file.
780 :return: A font object.
781 :exception OSError: If the file could not be read.
782 """
783 f = ImageFont()
784 f._load_pilfont(filename)
785 return f
788def truetype(
789 font: StrOrBytesPath | BinaryIO,
790 size: float = 10,
791 index: int = 0,
792 encoding: str = "",
793 layout_engine: Layout | None = None,
794) -> FreeTypeFont:
795 """
796 Load a TrueType or OpenType font from a file or file-like object,
797 and create a font object. This function loads a font object from the given
798 file or file-like object, and creates a font object for a font of the given
799 size. For loading bitmap fonts instead, see :py:func:`~PIL.ImageFont.load`
800 and :py:func:`~PIL.ImageFont.load_path`.
802 Pillow uses FreeType to open font files. On Windows, be aware that FreeType
803 will keep the file open as long as the FreeTypeFont object exists. Windows
804 limits the number of files that can be open in C at once to 512, so if many
805 fonts are opened simultaneously and that limit is approached, an
806 ``OSError`` may be thrown, reporting that FreeType "cannot open resource".
807 A workaround would be to copy the file(s) into memory, and open that instead.
809 This function requires the _imagingft service.
811 :param font: A filename or file-like object containing a TrueType font.
812 If the file is not found in this filename, the loader may also
813 search in other directories, such as:
815 * The :file:`fonts/` directory on Windows,
816 * :file:`/Library/Fonts/`, :file:`/System/Library/Fonts/`
817 and :file:`~/Library/Fonts/` on macOS.
818 * :file:`~/.local/share/fonts`, :file:`/usr/local/share/fonts`,
819 and :file:`/usr/share/fonts` on Linux; or those specified by
820 the ``XDG_DATA_HOME`` and ``XDG_DATA_DIRS`` environment variables
821 for user-installed and system-wide fonts, respectively.
823 :param size: The requested size, in pixels.
824 :param index: Which font face to load (default is first available face).
825 :param encoding: Which font encoding to use (default is Unicode). Possible
826 encodings include (see the FreeType documentation for more
827 information):
829 * "unic" (Unicode)
830 * "symb" (Microsoft Symbol)
831 * "ADOB" (Adobe Standard)
832 * "ADBE" (Adobe Expert)
833 * "ADBC" (Adobe Custom)
834 * "armn" (Apple Roman)
835 * "sjis" (Shift JIS)
836 * "gb " (PRC)
837 * "big5"
838 * "wans" (Extended Wansung)
839 * "joha" (Johab)
840 * "lat1" (Latin-1)
842 This specifies the character set to use. It does not alter the
843 encoding of any text provided in subsequent operations.
844 :param layout_engine: Which layout engine to use, if available:
845 :attr:`.ImageFont.Layout.BASIC` or :attr:`.ImageFont.Layout.RAQM`.
846 If it is available, Raqm layout will be used by default.
847 Otherwise, basic layout will be used.
849 Raqm layout is recommended for all non-English text. If Raqm layout
850 is not required, basic layout will have better performance.
852 You can check support for Raqm layout using
853 :py:func:`PIL.features.check_feature` with ``feature="raqm"``.
855 .. versionadded:: 4.2.0
856 :return: A font object.
857 :exception OSError: If the file could not be read.
858 :exception ValueError: If the font size is not greater than zero.
859 """
861 def freetype(font: StrOrBytesPath | BinaryIO) -> FreeTypeFont:
862 return FreeTypeFont(font, size, index, encoding, layout_engine)
864 try:
865 return freetype(font)
866 except OSError:
867 if not is_path(font):
868 raise
869 ttf_filename = os.path.basename(font)
871 dirs = []
872 if sys.platform == "win32":
873 # check the windows font repository
874 # NOTE: must use uppercase WINDIR, to work around bugs in
875 # 1.5.2's os.environ.get()
876 windir = os.environ.get("WINDIR")
877 if windir:
878 dirs.append(os.path.join(windir, "fonts"))
879 elif sys.platform in ("linux", "linux2"):
880 data_home = os.environ.get("XDG_DATA_HOME")
881 if not data_home:
882 # The freedesktop spec defines the following default directory for
883 # when XDG_DATA_HOME is unset or empty. This user-level directory
884 # takes precedence over system-level directories.
885 data_home = os.path.expanduser("~/.local/share")
886 xdg_dirs = [data_home]
888 data_dirs = os.environ.get("XDG_DATA_DIRS")
889 if not data_dirs:
890 # Similarly, defaults are defined for the system-level directories
891 data_dirs = "/usr/local/share:/usr/share"
892 xdg_dirs += data_dirs.split(":")
894 dirs += [os.path.join(xdg_dir, "fonts") for xdg_dir in xdg_dirs]
895 elif sys.platform == "darwin":
896 dirs += [
897 "/Library/Fonts",
898 "/System/Library/Fonts",
899 os.path.expanduser("~/Library/Fonts"),
900 ]
902 ext = os.path.splitext(ttf_filename)[1]
903 first_font_with_a_different_extension = None
904 for directory in dirs:
905 for walkroot, walkdir, walkfilenames in os.walk(directory):
906 for walkfilename in walkfilenames:
907 if ext and walkfilename == ttf_filename:
908 return freetype(os.path.join(walkroot, walkfilename))
909 elif not ext and os.path.splitext(walkfilename)[0] == ttf_filename:
910 fontpath = os.path.join(walkroot, walkfilename)
911 if os.path.splitext(fontpath)[1] == ".ttf":
912 return freetype(fontpath)
913 if not ext and first_font_with_a_different_extension is None:
914 first_font_with_a_different_extension = fontpath
915 if first_font_with_a_different_extension:
916 return freetype(first_font_with_a_different_extension)
917 raise
920def load_path(filename: str | bytes) -> ImageFont:
921 """
922 Load font file. Same as :py:func:`~PIL.ImageFont.load`, but searches for a
923 bitmap font along the Python path.
925 :param filename: Name of font file.
926 :return: A font object.
927 :exception OSError: If the file could not be read.
928 """
929 if not isinstance(filename, str):
930 filename = filename.decode("utf-8")
931 for directory in sys.path:
932 try:
933 return load(os.path.join(directory, filename))
934 except OSError:
935 pass
936 msg = f'cannot find font file "{filename}" in sys.path'
937 if os.path.exists(filename):
938 msg += f', did you mean ImageFont.load("{filename}") instead?'
940 raise OSError(msg)
943def load_default_imagefont() -> ImageFont:
944 f = ImageFont()
945 f._load_pilfont_data(
946 # courB08
947 BytesIO(
948 base64.b64decode(
949 b"""
950UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
951AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
952AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
953AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
954AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
955AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
956AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
957AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
958AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
959AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
960AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
961AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA
962BgAAAAH/+gADAAAAAQAAAAMABgAGAAAAAf/6AAT//QADAAAABgADAAYAAAAA//kABQABAAYAAAAL
963AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA
964AAAbAAYABgAAAAH/+QAE//wAGwAAAB4AAwAGAAAAAf/5AAQAAQAeAAAAIQAIAAYAAAAB//kABAAB
965ACEAAAAkAAgABgAAAAD/+QAE//0AJAAAACgABAAGAAAAAP/6AAX//wAoAAAALQAFAAYAAAAB//8A
966BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB
967//kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA
968AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH
969AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA
970ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv
971AAAAcQAEAAYAAAAA//wAAwACAHEAAAB0AAYABgAAAAD/+gAE//8AdAAAAHgABQAGAAAAAP/7AAT/
972/gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5
973AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA
974AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG
975AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA
976BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA
977AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA
9782AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF
979AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA////
980+gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA
981////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA
982BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv
983AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA
984AAE9AAEABgAAAAH/+QAE//wBPQAAAUAAAwAGAAAAAP/7AAYAAAFAAAABRgAFAAYAAP////kABQAA
985AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA
986BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP//
987//kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA
988AP////kABgAAAXcAAAF+AAcABgAAAAD/+QAGAAABfgAAAYQABwAGAAD////7AAUAAAGEAAABigAF
989AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB
990mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn
991AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA
992AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7
993AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA
994Av/6AAMAAQHdAAAB3gAHAAYAAAAA//kABAABAd4AAAHiAAgABgAAAAD/+wAF//0B4gAAAecAAgAA
995AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
996AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
997AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
998AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
999AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1000AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1001AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1002AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1003AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1004AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1005AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1006AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB
1007//sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA
1008AAAA//oABf//AfQAAAH5AAUABgAAAAD/+QAGAAAB+QAAAf8ABwAGAAAAAv/5AAMAAgH/AAACAAAJ
1009AAYAAAAA//kABQABAgAAAAIFAAgABgAAAAH/+gAE//sCBQAAAggAAQAGAAAAAP/5AAYAAAIIAAAC
1010DgAHAAYAAAAB//kABf/+Ag4AAAISAAUABgAA////+wAGAAACEgAAAhkABQAGAAAAAP/7AAX//gIZ
1011AAACHgADAAYAAAAA//wABf/9Ah4AAAIjAAEABgAAAAD/+QAHAAACIwAAAioABwAGAAAAAP/6AAT/
1012+wIqAAACLgABAAYAAAAA//kABP/8Ai4AAAIyAAMABgAAAAD/+gAFAAACMgAAAjcABgAGAAAAAf/5
1013AAT//QI3AAACOgAEAAYAAAAB//kABP/9AjoAAAI9AAQABgAAAAL/+QAE//sCPQAAAj8AAgAGAAD/
1014///7AAYAAgI/AAACRgAHAAYAAAAA//kABgABAkYAAAJMAAgABgAAAAH//AAD//0CTAAAAk4AAQAG
1015AAAAAf//AAQAAgJOAAACUQADAAYAAAAB//kABP/9AlEAAAJUAAQABgAAAAH/+QAF//4CVAAAAlgA
1016BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA
1017Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC
1018eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG
1019AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA////
1020+gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA
1021////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA
1022BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT
1023AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A
1024AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA
1025Au4AAALzAAkABgAAAAD/9wAFAAAC8wAAAvgACQAGAAAAAP/4AAUAAAL4AAAC/QAIAAYAAAAA//oA
1026Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP//
1027//cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA
1028AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ
1029AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA
1030LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5
1031AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA
1032AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5
1033AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA
1034AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG
1035AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA
1036EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK
1037AJsAEQAGAAAAAP/6AAX//wCbAAoAoAAPAAYAAAAA//oABQABAKAACgClABEABgAA////+AAGAAAA
1038pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG
1039AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA////
1040+QAGAAIAzgAKANUAEw==
1041"""
1042 )
1043 ),
1044 Image.open(
1045 BytesIO(
1046 base64.b64decode(
1047 b"""
1048iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u
1049Mc4b7vuds/xzjz5/3/7u/n9vMe7vnfH/9++vPn/xyf5zhxzjt8GHw8+2d83u8x27199/nxuQ6Od9
1050M43/5z2I+9n9ZtmDBwMQECDRQw/eQIQohJXxpBCNVE6QCCAAAAD//wBlAJr/AgALyj1t/wINwq0g
1051LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F
1052IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA
1053Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791
1054NAADfcoIDyP44K/jv4Y63/Z+t98Ovt+ub4T48LAAAAD//wBlAJr/AuplMlADJAAAAGuAphWpqhMx
1055in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9
1056SjdavWA8ePHeBIKB//81/83ndznOaXx379wAAAD//wBlAJr/AqDxW+D3AABAAbUh/QMnbQag/gAY
1057AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt
1058y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG
1059ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY
1060lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H
1061/Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3
1062AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47
1063c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/
1064/yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw
1065pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv
1066oJodAAAAAP//Yqo/83+dxePWlxl3npsel9lvLfPcqlE9725C+acfVLMEAAAA//9i+s9gwCoaaGMR
1067evta/58PTEWzr21hufPjA8N+qlnBwAAAAAD//2JiWLci5v1+HmFXDqcnULE/MxgYGBj+f6CaJQAA
1068AAD//2Ji2FrkY3iYpYC5qDeGgeEMAwPDvwQBBoYvcTwOVLMEAAAA//9isDBgkP///0EOg9z35v//
1069Gc/eeW7BwPj5+QGZhANUswMAAAD//2JgqGBgYGBgqEMXlvhMPUsAAAAA//8iYDd1AAAAAP//AwDR
1070w7IkEbzhVQAAAABJRU5ErkJggg==
1071"""
1072 )
1073 )
1074 ),
1075 )
1076 return f
1079def load_default(size: float | None = None) -> FreeTypeFont | ImageFont:
1080 """If FreeType support is available, load a version of Aileron Regular,
1081 https://dotcolon.net/fonts/aileron, with a more limited character set.
1083 Otherwise, load a "better than nothing" font.
1085 .. versionadded:: 1.1.4
1087 :param size: The font size of Aileron Regular.
1089 .. versionadded:: 10.1.0
1091 :return: A font object.
1092 """
1093 if isinstance(core, ModuleType) or size is not None:
1094 return truetype(
1095 BytesIO(
1096 base64.b64decode(
1097 b"""
1098AAEAAAAPAIAAAwBwRkZUTYwDlUAAADFoAAAAHEdERUYAqADnAAAo8AAAACRHUE9ThhmITwAAKfgAA
1099AduR1NVQnHxefoAACkUAAAA4k9TLzJovoHLAAABeAAAAGBjbWFw5lFQMQAAA6gAAAGqZ2FzcP//AA
1100MAACjoAAAACGdseWYmRXoPAAAGQAAAHfhoZWFkE18ayQAAAPwAAAA2aGhlYQboArEAAAE0AAAAJGh
1101tdHjjERZ8AAAB2AAAAdBsb2NhuOexrgAABVQAAADqbWF4cAC7AEYAAAFYAAAAIG5hbWUr+h5lAAAk
1102OAAAA6Jwb3N0D3oPTQAAJ9wAAAEKAAEAAAABGhxJDqIhXw889QALA+gAAAAA0Bqf2QAAAADhCh2h/
11032r/LgOxAyAAAAAIAAIAAAAAAAAAAQAAA8r/GgAAA7j/av9qA7EAAQAAAAAAAAAAAAAAAAAAAHQAAQ
1104AAAHQAQwAFAAAAAAACAAAAAQABAAAAQAAAAAAAAAADAfoBkAAFAAgCigJYAAAASwKKAlgAAAFeADI
1105BPgAAAAAFAAAAAAAAAAAAAAcAAAAAAAAAAAAAAABVS1dOAEAAIPsCAwL/GgDIA8oA5iAAAJMAAAAA
1106AhICsgAAACAAAwH0AAAAAAAAAU0AAADYAAAA8gA5AVMAVgJEAEYCRAA1AuQAKQKOAEAAsAArATsAZ
1107AE7AB4CMABVAkQAUADc/+EBEgAgANwAJQEv//sCRAApAkQAggJEADwCRAAtAkQAIQJEADkCRAArAk
1108QAMgJEACwCRAAxANwAJQDc/+ECRABnAkQAUAJEAEQB8wAjA1QANgJ/AB0CcwBkArsALwLFAGQCSwB
1109kAjcAZALGAC8C2gBkAQgAZAIgADcCYQBkAj8AZANiAGQCzgBkAuEALwJWAGQC3QAvAmsAZAJJADQC
1110ZAAiAqoAXgJuACADuAAaAnEAGQJFABMCTwAuATMAYgEv//sBJwAiAkQAUAH0ADIBLAApAhMAJAJjA
1111EoCEQAeAmcAHgIlAB4BIgAVAmcAHgJRAEoA7gA+AOn/8wIKAEoA9wBGA1cASgJRAEoCSgAeAmMASg
1112JnAB4BSgBKAcsAGAE5ABQCUABCAgIAAQMRAAEB4v/6AgEAAQHOABQBLwBAAPoAYAEvACECRABNA0Y
1113AJAItAHgBKgAcAkQAUAEsAHQAygAgAi0AOQD3ADYA9wAWAaEANgGhABYCbAAlAYMAeAGDADkA6/9q
1114AhsAFAIKABUB/QAVAAAAAwAAAAMAAAAcAAEAAAAAAKQAAwABAAAAHAAEAIgAAAAeABAAAwAOAH4Aq
1115QCrALEAtAC3ALsgGSAdICYgOiBEISL7Av//AAAAIACpAKsAsAC0ALcAuyAYIBwgJiA5IEQhIvsB//
1116//4/+5/7j/tP+y/7D/reBR4E/gR+A14CzfTwVxAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1117AAAAAAAEGAAABAAAAAAAAAAECAAAAAgAAAAAAAAAAAAAAAAAAAAEAAAMEBQYHCAkKCwwNDg8QERIT
1118FBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMT
1119U5PUFFSU1RVVldYWVpbXF1eX2BhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQAAA
1120AAAAAAYnFmAAAAAABlAAAAAAAAAAAAAAAAAAAAAAAAAAAAY2htAAAAAAAAAABrbGlqAAAAAHAAbm9
1121ycwBnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmACYAJgAmAD4AUgCCAMoBCgFO
1122AVwBcgGIAaYBvAHKAdYB6AH2AgwCIAJKAogCpgLWAw4DIgNkA5wDugPUA+gD/AQQBEYEogS8BPoFJ
1123gVSBWoFgAWwBcoF1gX6BhQGJAZMBmgGiga0BuIHGgdUB2YHkAeiB8AH3AfyCAoIHAgqCDoITghcCG
1124oIogjSCPoJKglYCXwJwgnqCgIKKApACl4Klgq8CtwLDAs8C1YLjAuyC9oL7gwMDCYMSAxgDKAMrAz
1125qDQoNTA1mDYQNoA2uDcAN2g3oDfYODA4iDkoOXA5sDnoOnA7EDvwAAAAFAAAAAAH0ArwAAwAGAAkA
1126DAAPAAAxESERAxMhExcRASELARETAfT6qv6syKr+jgFUqsiqArz9RAGLAP/+1P8B/v3VAP8BLP4CA
1127P8AAgA5//IAuQKyAAMACwAANyMDMwIyFhQGIiY0oE4MZk84JCQ4JLQB/v3AJDgkJDgAAgBWAeUBPA
1128LfAAMABwAAEyMnMxcjJzOmRgpagkYKWgHl+vr6AAAAAAIARgAAAf4CsgAbAB8AAAEHMxUjByM3Iwc
1129jNyM1MzcjNTM3MwczNzMHMxUrAQczAZgdZXEvOi9bLzovWmYdZXEvOi9bLzovWp9bHlsBn4w429vb
11302ziMONvb29s4jAAAAAMANf+mAg4DDAAfACYALAAAJRQGBxUjNS4BJzMeARcRLgE0Njc1MxUeARcjJ
1131icVHgEBFBYXNQ4BExU+ATU0Ag5xWDpgcgRcBz41Xl9oVTpVYwpcC1ttXP6cLTQuM5szOrVRZwlOTQ
1132ZqVzZECAEAGlukZAlOTQdrUG8O7iNlAQgxNhDlCDj+8/YGOjReAAAAAAUAKf/yArsCvAAHAAsAFQA
1133dACcAABIyFhQGIiY0EyMBMwQiBhUUFjI2NTQSMhYUBiImNDYiBhUUFjI2NTR5iFBQiFCVVwHAV/5c
1134OiMjOiPmiFBQiFCxOiMjOiMCvFaSVlaS/ZoCsjIzMC80NC8w/uNWklZWkhozMC80NC8wAAAAAgBA/
1135/ICbgLAACIALgAAARUjEQYjIiY1NDY3LgE1NDYzMhcVJiMiBhUUFhcWOwE1MxUFFBYzMjc1IyIHDg
1136ECbmBcYYOOVkg7R4hsQjY4Q0RNRD4SLDxW/pJUXzksPCkUUk0BgUb+zBVUZ0BkDw5RO1huCkULQzp
1137COAMBcHDHRz0J/AIHRQAAAAEAKwHlAIUC3wADAAATIycze0YKWgHl+gAAAAABAGT/sAEXAwwACQAA
1138EzMGEBcjLgE0Nt06dXU6OUBAAwzG/jDGVePs4wAAAAEAHv+wANEDDAAJAAATMx4BFAYHIzYQHjo5Q
1139EA5OnUDDFXj7ONVxgHQAAAAAQBVAFIB2wHbAA4AAAE3FwcXBycHJzcnNxcnMwEtmxOfcTJjYzJxnx
1140ObCj4BKD07KYolmZkliik7PbMAAQBQAFUB9AIlAAsAAAEjFSM1IzUzNTMVMwH0tTq1tTq1AR/Kyjj
1141OzgAAAAAB/+H/iACMAGQABAAANwcjNzOMWlFOXVrS3AAAAQAgAP8A8gE3AAMAABMjNTPy0tIA/zgA
1142AQAl//IApQByAAcAADYyFhQGIiY0STgkJDgkciQ4JCQ4AAAAAf/7/+IBNALQAAMAABcjEzM5Pvs+H
1143gLuAAAAAAIAKf/yAhsCwAADAAcAABIgECA2IBAgKQHy/g5gATL+zgLA/TJEAkYAAAAAAQCCAAABlg
1144KyAAgAAAERIxEHNTc2MwGWVr6SIygCsv1OAldxW1sWAAEAPAAAAg4CwAAZAAA3IRUhNRM+ATU0JiM
1145iDwEjNz4BMzIWFRQGB7kBUv4x+kI2QTt+EAFWAQp8aGVtSl5GRjEA/0RVLzlLmAoKa3FsUkNxXQAA
1146AAEALf/yAhYCwAAqAAABHgEVFAYjIi8BMxceATMyNjU0KwE1MzI2NTQmIyIGDwEjNz4BMzIWFRQGA
1147YxBSZJo2RUBVgEHV0JBUaQREUBUQzc5TQcBVgEKfGhfcEMBbxJbQl1x0AoKRkZHPn9GSD80QUVCCg
1148pfbGBPOlgAAAACACEAAAIkArIACgAPAAAlIxUjNSE1ATMRMyMRBg8BAiRXVv6qAVZWV60dHLCurq4
1149rAdn+QgFLMibzAAABADn/8gIZArIAHQAAATIWFRQGIyIvATMXFjMyNjU0JiMiByMTIRUhBzc2ATNv
1150d5Fl1RQBVgIad0VSTkVhL1IwAYj+vh8rMAHHgGdtgcUKCoFXTU5bYgGRRvAuHQAAAAACACv/8gITA
1151sAAFwAjAAABMhYVFAYjIhE0NjMyFh8BIycmIyIDNzYTMjY1NCYjIgYVFBYBLmp7imr0l3RZdAgBXA
1152IYZ5wKJzU6QVNJSz5SUAHSgWltiQFGxcNlVQoKdv7sPiz+ZF1LTmJbU0lhAAAAAQAyAAACGgKyAAY
1153AAAEVASMBITUCGv6oXAFL/oECsij9dgJsRgAAAAMALP/xAhgCwAAWACAALAAAAR4BFRQGIyImNTQ2
1154Ny4BNTQ2MhYVFAYmIgYVFBYyNjU0AzI2NTQmIyIGFRQWAZQ5S5BmbIpPOjA7ecp5P2F8Q0J8RIVJS
11550pLTEtOAW0TXTxpZ2ZqPF0SE1A3VWVlVTdQ/UU0N0RENzT9/ko+Ok1NOj1LAAIAMf/yAhkCwAAXAC
1156MAAAEyERQGIyImLwEzFxYzMhMHBiMiJjU0NhMyNjU0JiMiBhUUFgEl9Jd0WXQIAVwCGGecCic1SWp
11577imo+UlBAQVNJAsD+usXDZVUKCnYBFD4sgWltif5kW1NJYV1LTmIAAAACACX/8gClAiAABwAPAAAS
1158MhYUBiImNBIyFhQGIiY0STgkJDgkJDgkJDgkAiAkOCQkOP52JDgkJDgAAAAC/+H/iAClAiAABwAMA
1159AASMhYUBiImNBMHIzczSTgkJDgkaFpSTl4CICQ4JCQ4/mba5gAAAQBnAB4B+AH0AAYAAAENARUlNS
1160UB+P6qAVb+bwGRAbCmpkbJRMkAAAIAUAC7AfQBuwADAAcAAAEhNSERITUhAfT+XAGk/lwBpAGDOP8
1161AOAABAEQAHgHVAfQABgAAARUFNS0BNQHV/m8BVv6qAStEyUSmpkYAAAAAAgAj//IB1ALAABgAIAAA
1162ATIWFRQHDgEHIz4BNz4BNTQmIyIGByM+ARIyFhQGIiY0AQRibmktIAJWBSEqNig+NTlHBFoDezQ4J
1163CQ4JALAZ1BjaS03JS1DMD5LLDQ/SUVgcv2yJDgkJDgAAAAAAgA2/5gDFgKYADYAQgAAAQMGFRQzMj
1164Y1NCYjIg4CFRQWMzI2NxcGIyImNTQ+AjMyFhUUBiMiJwcGIyImNTQ2MzIfATcHNzYmIyIGFRQzMjY
1165Cej8EJjJJlnBAfGQ+oHtAhjUYg5OPx0h2k06Os3xRWQsVLjY5VHtdPBwJETcJDyUoOkZEJz8B0f74
1166EQ8kZl6EkTFZjVOLlyknMVm1pmCiaTq4lX6CSCknTVRmmR8wPdYnQzxuSWVGAAIAHQAAAncCsgAHA
1167AoAACUjByMTMxMjATMDAcj+UVz4dO5d/sjPZPT0ArL9TgE6ATQAAAADAGQAAAJMArIAEAAbACcAAA
1168EeARUUBgcGKwERMzIXFhUUJRUzMjc2NTQnJiMTPgE1NCcmKwEVMzIBvkdHZkwiNt7LOSGq/oeFHBt
1169hahIlSTM+cB8Yj5UWAW8QT0VYYgwFArIEF5Fv1eMED2NfDAL93AU+N24PBP0AAAAAAQAv//ICjwLA
1170ABsAAAEyFh8BIycmIyIGFRQWMzI/ATMHDgEjIiY1NDYBdX+PCwFWAiKiaHx5ZaIiAlYBCpWBk6a0A
1171sCAagoKpqN/gaOmCgplhcicn8sAAAIAZAAAAp8CsgAMABkAAAEeARUUBgcGKwERMzITPgE1NCYnJi
1172sBETMyAY59lJp8IzXN0jUVWmdjWRs5d3I4Aq4QqJWUug8EArL9mQ+PeHGHDgX92gAAAAABAGQAAAI
1173vArIACwAAJRUhESEVIRUhFSEVAi/+NQHB/pUBTf6zRkYCskbwRvAAAAABAGQAAAIlArIACQAAExUh
1174FSERIxEhFboBQ/69VgHBAmzwRv7KArJGAAAAAAEAL//yAo8CwAAfAAABMxEjNQcGIyImNTQ2MzIWH
1175wEjJyYjIgYVFBYzMjY1IwGP90wfPnWTprSSf48LAVYCIqJofHllVG+hAU3+s3hARsicn8uAagoKpq
1176N/gaN1XAAAAAEAZAAAAowCsgALAAABESMRIREjETMRIRECjFb+hFZWAXwCsv1OAS7+0gKy/sQBPAA
1177AAAABAGQAAAC6ArIAAwAAMyMRM7pWVgKyAAABADf/8gHoArIAEwAAAREUBw4BIyImLwEzFxYzMjc2
1178NREB6AIFcGpgbQIBVgIHfXQKAQKy/lYxIltob2EpKYyEFD0BpwAAAAABAGQAAAJ0ArIACwAACQEjA
1179wcVIxEzEQEzATsBJ3ntQlZWAVVlAWH+nwEnR+ACsv6RAW8AAQBkAAACLwKyAAUAACUVIREzEQIv/j
1180VWRkYCsv2UAAABAGQAAAMUArIAFAAAAREjETQ3BgcDIwMmJxYVESMRMxsBAxRWAiMxemx8NxsCVo7
1181MywKy/U4BY7ZLco7+nAFmoFxLtP6dArL9lwJpAAAAAAEAZAAAAoACsgANAAAhIwEWFREjETMBJjUR
1182MwKAhP67A1aEAUUDVAJeeov+pwKy/aJ5jAFZAAAAAgAv//ICuwLAAAkAEwAAEiAWFRQGICY1NBIyN
1183jU0JiIGFRTbATSsrP7MrNrYenrYegLAxaKhxsahov47nIeIm5uIhwACAGQAAAJHArIADgAYAAABHg
1184EVFAYHBisBESMRMzITNjQnJisBETMyAZRUX2VOHzuAVtY7GlxcGDWIiDUCrgtnVlVpCgT+5gKy/rU
1185V1BUF/vgAAAACAC//zAK9AsAAEgAcAAAlFhcHJiMiBwYjIiY1NDYgFhUUJRQWMjY1NCYiBgI9PUMx
1186UDcfKh8omqysATSs/dR62Hp62HpICTg7NgkHxqGixcWitbWHnJyHiJubAAIAZAAAAlgCsgAXACMAA
1187CUWFyMmJyYnJisBESMRMzIXHgEVFAYHFiUzMjc+ATU0JyYrAQIqDCJfGQwNWhAhglbiOx9QXEY1Tv
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
1263gQAAwABBAkADAAuAkwATgBvACAAUgBpAGcAaAB0AHMAIABSAGUAcwBlAHIAdgBlAGQALgAATm8gUm
1264lnaHRzIFJlc2VydmVkLgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAUgBlAGcAdQBsAGEAcgAAUmV
1265ndWxhcgAAMQAuADEAMAAyADsAVQBLAFcATgA7AEEAaQBsAGUAcgBvAG4ALQBSAGUAZwB1AGwAYQBy
1266AAAxLjEwMjtVS1dOO0FpbGVyb24tUmVndWxhcgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAVgBlA
1267HIAcwBpAG8AbgAgADEALgAxADAAMgA7AFAAUwAgADAAMAAxAC4AMQAwADIAOwBoAG8AdABjAG8Abg
1268B2ACAAMQAuADAALgA3ADAAOwBtAGEAawBlAG8AdABmAC4AbABpAGIAMgAuADUALgA1ADgAMwAyADk
1269AAFZlcnNpb24gMS4xMDI7UFMgMDAxLjEwMjtob3Rjb252IDEuMC43MDttYWtlb3RmLmxpYjIuNS41
1270ODMyOQAAQQBpAGwAZQByAG8AbgAtAFIAZQBnAHUAbABhAHIAAEFpbGVyb24tUmVndWxhcgAAUwBvA
1271HIAYQAgAFMAYQBnAGEAbgBvAABTb3JhIFNhZ2FubwAAUwBvAHIAYQAgAFMAYQBnAGEAbgBvAABTb3
1272JhIFNhZ2FubwAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBsAG8AbgAuAG4AZQB0AAB
1273odHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBs
1274AG8AbgAuAG4AZQB0AABodHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAAAACAAAAAAAA/4MAMgAAAAAAA
1275AAAAAAAAAAAAAAAAAAAAHQAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATAB
1276QAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAA
1277xADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0A
1278TgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAIsAqQCDAJMAjQDDAKoAtgC3A
1279LQAtQCrAL4AvwC8AIwAwADBAAAAAAAB//8AAgABAAAADAAAABwAAAACAAIAAwBxAAEAcgBzAAIABA
1280AAAAIAAAABAAAACgBMAGYAAkRGTFQADmxhdG4AGgAEAAAAAP//AAEAAAAWAANDQVQgAB5NT0wgABZ
1281ST00gABYAAP//AAEAAAAA//8AAgAAAAEAAmxpZ2EADmxvY2wAFAAAAAEAAQAAAAEAAAACAAYAEAAG
1282AAAAAgASADQABAAAAAEATAADAAAAAgAQABYAAQAcAAAAAQABAE8AAQABAGcAAQABAE8AAwAAAAIAE
1283AAWAAEAHAAAAAEAAQAvAAEAAQBnAAEAAQAvAAEAGgABAAgAAgAGAAwAcwACAE8AcgACAEwAAQABAE
1284kAAAABAAAACgBGAGAAAkRGTFQADmxhdG4AHAAEAAAAAP//AAIAAAABABYAA0NBVCAAFk1PTCAAFlJ
1285PTSAAFgAA//8AAgAAAAEAAmNwc3AADmtlcm4AFAAAAAEAAAAAAAEAAQACAAYADgABAAAAAQASAAIA
1286AAACAB4ANgABAAoABQAFAAoAAgABACQAPQAAAAEAEgAEAAAAAQAMAAEAOP/nAAEAAQAkAAIGigAEA
1287AAFJAXKABoAGQAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1288AAAAD/sv+4/+z/7v/MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1289AAAAAAAD/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9T/6AAAAAD/8QAA
1290ABD/vQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7gAAAAAAAAAAAAAAAAAA//MAA
1291AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAP/5AAAAAAAAAA
1292AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gAAD/4AAAAAAAAAAAAAAAAAA
1293AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//L/9AAAAAAAAAAAAAAAAAAAAAAA
1294AAAAAAAAAAAA/+gAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1295AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAAAAA
1296AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/mAAAAAAAAAAAAAAAAAAD
1297/4gAA//AAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+AAAAAAAAP/OAAAAAAAAAAAAAAAA
1298AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zv/qAAAAAP/0AAAACAAAAAAAAAAAAAAAAAAAAAAAA
1299AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/ZAAD/egAA/1kAAAAA/5D/rgAAAAAAAAAAAA
1300AAAAAAAAAAAAAAAAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1301AAAAAAAAAAAAAAAAAAAD/8AAA/7b/8P+wAAD/8P/E/98AAAAA/8P/+P/0//oAAAAAAAAAAAAA//gA
1302AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+AAAAAAAAAAAAAAA
1303AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/w//C/9MAAP/SAAD/9wAAAAAAAA
1304AAAAAAAAAAAAAAAAAAAAAAAAAAAAD/yAAA/+kAAAAA//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1305AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9wAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1306AAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1307AAAAAAAAP/cAAAAAAAAAAAAAAAA/7YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1308AAAAAAAAAAAAAAAAAAAAAAAAAAAP/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6AAAAAAAAAA
1309AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAkAFAAEAAAAAQACwAAABcA
1310BgAAAAAAAAAIAA4AAAAAAAsAEgAAAAAAAAATABkAAwANAAAAAQAJAAAAAAAAAAAAAAAAAAAAGAAAA
1311AAABwAAAAAAAAAAAAAAFQAFAAAAAAAYABgAAAAUAAAACgAAAAwAAgAPABEAFgAAAAAAAAAAAAAAAA
1312AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAEAEQBdAAYAAAAAAAAAAAAAAAAAAAAAAAA
1313AAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAcAAAAAAAAABwAAAAAACAAAAAAAAAAAAAcAAAAHAAAAEwAJ
1314ABUADgAPAAAACwAQAAAAAAAAAAAAAAAAAAUAGAACAAIAAgAAAAIAGAAXAAAAGAAAABYAFgACABYAA
1315gAWAAAAEQADAAoAFAAMAA0ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAEgAGAAEAHgAkAC
1316YAJwApACoALQAuAC8AMgAzADcAOAA5ADoAPAA9AEUASABOAE8AUgBTAFUAVwBZAFoAWwBcAF0AcwA
1317AAAAAAQAAAADa3tfFAAAAANAan9kAAAAA4QodoQ==
1318"""
1319 )
1320 ),
1321 10 if size is None else size,
1322 layout_engine=Layout.BASIC,
1323 )
1324 return load_default_imagefont()