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