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