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