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