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