Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/PIL/ImageFont.py: 37%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

275 statements  

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# 

27 

28from __future__ import annotations 

29 

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 

38 

39from . import Image 

40from ._typing import StrOrBytesPath 

41from ._util import DeferredError, is_path 

42 

43TYPE_CHECKING = False 

44if TYPE_CHECKING: 

45 from . import ImageFile 

46 from ._imaging import ImagingFont 

47 from ._imagingft import Font 

48 

49 

50class Axis(TypedDict): 

51 minimum: int | None 

52 default: int | None 

53 maximum: int | None 

54 name: bytes | None 

55 

56 

57class Layout(IntEnum): 

58 BASIC = 0 

59 RAQM = 1 

60 

61 

62MAX_STRING_LENGTH = 1_000_000 

63 

64 

65core: ModuleType | DeferredError 

66try: 

67 from . import _imagingft as core 

68except ImportError as ex: 

69 core = DeferredError.new(ex) 

70 

71 

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) 

76 

77 

78# FIXME: add support for pilfont2 format (see FontFile.py) 

79 

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# -------------------------------------------------------------------- 

92 

93 

94class ImageFont: 

95 """PIL font wrapper""" 

96 

97 font: ImagingFont 

98 

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] 

103 

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() 

118 

119 msg = f"cannot find glyph data file {root}.{{gif|pbm|png}}" 

120 raise OSError(msg) 

121 

122 self.file = fullname 

123 

124 self._load_pilfont_data(fp, image) 

125 image.close() 

126 

127 def _load_pilfont_data(self, file: IO[bytes], image: Image.Image) -> None: 

128 # check image 

129 if image.mode not in ("1", "L"): 

130 image.close() 

131 

132 msg = "invalid font image mode" 

133 raise TypeError(msg) 

134 

135 # read PILfont header 

136 if file.read(8) != b"PILfont\n": 

137 image.close() 

138 

139 msg = "Not a PILfont file" 

140 raise SyntaxError(msg) 

141 file.readline() 

142 self.info = [] # FIXME: should be a dictionary 

143 while True: 

144 s = file.readline() 

145 if not s or s == b"DATA\n": 

146 break 

147 self.info.append(s) 

148 

149 # read PILfont metrics 

150 data = file.read(256 * 20) 

151 

152 self._load(image, data) 

153 

154 def _load(self, image: Image.Image, data: bytes) -> None: 

155 image.load() 

156 

157 self.font = Image.core.font(image.im, data) 

158 

159 def getmask( 

160 self, text: str | bytes, mode: str = "", *args: Any, **kwargs: Any 

161 ) -> Image.core.ImagingCore: 

162 """ 

163 Create a bitmap for the text. 

164 

165 If the font uses antialiasing, the bitmap should have mode ``L`` and use a 

166 maximum value of 255. Otherwise, it should have mode ``1``. 

167 

168 :param text: Text to render. 

169 :param mode: Used by some graphics drivers to indicate what mode the 

170 driver prefers; if empty, the renderer may return either 

171 mode. Note that the mode is always a string, to simplify 

172 C-level implementations. 

173 

174 .. versionadded:: 1.1.5 

175 

176 :return: An internal PIL storage memory instance as defined by the 

177 :py:mod:`PIL.Image.core` interface module. 

178 """ 

179 _string_length_check(text) 

180 Image._decompression_bomb_check(self.font.getsize(text)) 

181 return self.font.getmask(text, mode) 

182 

183 def getbbox( 

184 self, text: str | bytes | bytearray, *args: Any, **kwargs: Any 

185 ) -> tuple[int, int, int, int]: 

186 """ 

187 Returns bounding box (in pixels) of given text. 

188 

189 .. versionadded:: 9.2.0 

190 

191 :param text: Text to render. 

192 

193 :return: ``(left, top, right, bottom)`` bounding box 

194 """ 

195 _string_length_check(text) 

196 width, height = self.font.getsize(text) 

197 return 0, 0, width, height 

198 

199 def getlength( 

200 self, text: str | bytes | bytearray, *args: Any, **kwargs: Any 

201 ) -> int: 

202 """ 

203 Returns length (in pixels) of given text. 

204 This is the amount by which following text should be offset. 

205 

206 .. versionadded:: 9.2.0 

207 """ 

208 _string_length_check(text) 

209 width, height = self.font.getsize(text) 

210 return width 

211 

212 

213## 

214# Wrapper for FreeType fonts. Application code should use the 

215# <b>truetype</b> factory function to create font objects. 

216 

217 

218class FreeTypeFont: 

219 """FreeType font wrapper (requires _imagingft service)""" 

220 

221 font: Font 

222 font_bytes: bytes 

223 

224 def __init__( 

225 self, 

226 font: StrOrBytesPath | BinaryIO, 

227 size: float = 10, 

228 index: int = 0, 

229 encoding: str = "", 

230 layout_engine: Layout | None = None, 

231 ) -> None: 

232 # FIXME: use service provider instead 

233 

234 if isinstance(core, DeferredError): 

235 raise core.ex 

236 

237 if size <= 0: 

238 msg = f"font size must be greater than 0, not {size}" 

239 raise ValueError(msg) 

240 

241 self.path = font 

242 self.size = size 

243 self.index = index 

244 self.encoding = encoding 

245 

246 if layout_engine not in (Layout.BASIC, Layout.RAQM): 

247 layout_engine = Layout.BASIC 

248 if core.HAVE_RAQM: 

249 layout_engine = Layout.RAQM 

250 elif layout_engine == Layout.RAQM and not core.HAVE_RAQM: 

251 warnings.warn( 

252 "Raqm layout was requested, but Raqm is not available. " 

253 "Falling back to basic layout." 

254 ) 

255 layout_engine = Layout.BASIC 

256 

257 self.layout_engine = layout_engine 

258 

259 def load_from_bytes(f: IO[bytes]) -> None: 

260 self.font_bytes = f.read() 

261 self.font = core.getfont( 

262 "", size, index, encoding, self.font_bytes, layout_engine 

263 ) 

264 

265 if is_path(font): 

266 font = os.fspath(font) 

267 if sys.platform == "win32": 

268 font_bytes_path = font if isinstance(font, bytes) else font.encode() 

269 try: 

270 font_bytes_path.decode("ascii") 

271 except UnicodeDecodeError: 

272 # FreeType cannot load fonts with non-ASCII characters on Windows 

273 # So load it into memory first 

274 with open(font, "rb") as f: 

275 load_from_bytes(f) 

276 return 

277 self.font = core.getfont( 

278 font, size, index, encoding, layout_engine=layout_engine 

279 ) 

280 else: 

281 load_from_bytes(cast(IO[bytes], font)) 

282 

283 def __getstate__(self) -> list[Any]: 

284 return [self.path, self.size, self.index, self.encoding, self.layout_engine] 

285 

286 def __setstate__(self, state: list[Any]) -> None: 

287 path, size, index, encoding, layout_engine = state 

288 FreeTypeFont.__init__(self, path, size, index, encoding, layout_engine) 

289 

290 def getname(self) -> tuple[str | None, str | None]: 

291 """ 

292 :return: A tuple of the font family (e.g. Helvetica) and the font style 

293 (e.g. Bold) 

294 """ 

295 return self.font.family, self.font.style 

296 

297 def getmetrics(self) -> tuple[int, int]: 

298 """ 

299 :return: A tuple of the font ascent (the distance from the baseline to 

300 the highest outline point) and descent (the distance from the 

301 baseline to the lowest outline point, a negative value) 

302 """ 

303 return self.font.ascent, self.font.descent 

304 

305 def getlength( 

306 self, 

307 text: str | bytes, 

308 mode: str = "", 

309 direction: str | None = None, 

310 features: list[str] | None = None, 

311 language: str | None = None, 

312 ) -> float: 

313 """ 

314 Returns length (in pixels with 1/64 precision) of given text when rendered 

315 in font with provided direction, features, and language. 

316 

317 This is the amount by which following text should be offset. 

318 Text bounding box may extend past the length in some fonts, 

319 e.g. when using italics or accents. 

320 

321 The result is returned as a float; it is a whole number if using basic layout. 

322 

323 Note that the sum of two lengths may not equal the length of a concatenated 

324 string due to kerning. If you need to adjust for kerning, include the following 

325 character and subtract its length. 

326 

327 For example, instead of :: 

328 

329 hello = font.getlength("Hello") 

330 world = font.getlength("World") 

331 hello_world = hello + world # not adjusted for kerning 

332 assert hello_world == font.getlength("HelloWorld") # may fail 

333 

334 use :: 

335 

336 hello = font.getlength("HelloW") - font.getlength("W") # adjusted for kerning 

337 world = font.getlength("World") 

338 hello_world = hello + world # adjusted for kerning 

339 assert hello_world == font.getlength("HelloWorld") # True 

340 

341 or disable kerning with (requires libraqm) :: 

342 

343 hello = draw.textlength("Hello", font, features=["-kern"]) 

344 world = draw.textlength("World", font, features=["-kern"]) 

345 hello_world = hello + world # kerning is disabled, no need to adjust 

346 assert hello_world == draw.textlength("HelloWorld", font, features=["-kern"]) 

347 

348 .. versionadded:: 8.0.0 

349 

350 :param text: Text to measure. 

351 :param mode: Used by some graphics drivers to indicate what mode the 

352 driver prefers; if empty, the renderer may return either 

353 mode. Note that the mode is always a string, to simplify 

354 C-level implementations. 

355 

356 :param direction: Direction of the text. It can be 'rtl' (right to 

357 left), 'ltr' (left to right) or 'ttb' (top to bottom). 

358 Requires libraqm. 

359 

360 :param features: A list of OpenType font features to be used during text 

361 layout. This is usually used to turn on optional 

362 font features that are not enabled by default, 

363 for example 'dlig' or 'ss01', but can be also 

364 used to turn off default font features for 

365 example '-liga' to disable ligatures or '-kern' 

366 to disable kerning. To get all supported 

367 features, see 

368 https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist 

369 Requires libraqm. 

370 

371 :param language: Language of the text. Different languages may use 

372 different glyph shapes or ligatures. This parameter tells 

373 the font which language the text is in, and to apply the 

374 correct substitutions as appropriate, if available. 

375 It should be a `BCP 47 language code 

376 <https://www.w3.org/International/articles/language-tags/>`_ 

377 Requires libraqm. 

378 

379 :return: Either width for horizontal text, or height for vertical text. 

380 """ 

381 _string_length_check(text) 

382 return self.font.getlength(text, mode, direction, features, language) / 64 

383 

384 def getbbox( 

385 self, 

386 text: str | bytes, 

387 mode: str = "", 

388 direction: str | None = None, 

389 features: list[str] | None = None, 

390 language: str | None = None, 

391 stroke_width: float = 0, 

392 anchor: str | None = None, 

393 ) -> tuple[float, float, float, float]: 

394 """ 

395 Returns bounding box (in pixels) of given text relative to given anchor 

396 when rendered in font with provided direction, features, and language. 

397 

398 Use :py:meth:`getlength()` to get the offset of following text with 

399 1/64 pixel precision. The bounding box includes extra margins for 

400 some fonts, e.g. italics or accents. 

401 

402 .. versionadded:: 8.0.0 

403 

404 :param text: Text to render. 

405 :param mode: Used by some graphics drivers to indicate what mode the 

406 driver prefers; if empty, the renderer may return either 

407 mode. Note that the mode is always a string, to simplify 

408 C-level implementations. 

409 

410 :param direction: Direction of the text. It can be 'rtl' (right to 

411 left), 'ltr' (left to right) or 'ttb' (top to bottom). 

412 Requires libraqm. 

413 

414 :param features: A list of OpenType font features to be used during text 

415 layout. This is usually used to turn on optional 

416 font features that are not enabled by default, 

417 for example 'dlig' or 'ss01', but can be also 

418 used to turn off default font features for 

419 example '-liga' to disable ligatures or '-kern' 

420 to disable kerning. To get all supported 

421 features, see 

422 https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist 

423 Requires libraqm. 

424 

425 :param language: Language of the text. Different languages may use 

426 different glyph shapes or ligatures. This parameter tells 

427 the font which language the text is in, and to apply the 

428 correct substitutions as appropriate, if available. 

429 It should be a `BCP 47 language code 

430 <https://www.w3.org/International/articles/language-tags/>`_ 

431 Requires libraqm. 

432 

433 :param stroke_width: The width of the text stroke. 

434 

435 :param anchor: The text anchor alignment. Determines the relative location of 

436 the anchor to the text. The default alignment is top left, 

437 specifically ``la`` for horizontal text and ``lt`` for 

438 vertical text. See :ref:`text-anchors` for details. 

439 

440 :return: ``(left, top, right, bottom)`` bounding box 

441 """ 

442 _string_length_check(text) 

443 size, offset = self.font.getsize( 

444 text, mode, direction, features, language, anchor 

445 ) 

446 left, top = offset[0] - stroke_width, offset[1] - stroke_width 

447 width, height = size[0] + 2 * stroke_width, size[1] + 2 * stroke_width 

448 return left, top, left + width, top + height 

449 

450 def getmask( 

451 self, 

452 text: str | bytes, 

453 mode: str = "", 

454 direction: str | None = None, 

455 features: list[str] | None = None, 

456 language: str | None = None, 

457 stroke_width: float = 0, 

458 anchor: str | None = None, 

459 ink: int = 0, 

460 start: tuple[float, float] | None = None, 

461 ) -> Image.core.ImagingCore: 

462 """ 

463 Create a bitmap for the text. 

464 

465 If the font uses antialiasing, the bitmap should have mode ``L`` and use a 

466 maximum value of 255. If the font has embedded color data, the bitmap 

467 should have mode ``RGBA``. Otherwise, it should have mode ``1``. 

468 

469 :param text: Text to render. 

470 :param mode: Used by some graphics drivers to indicate what mode the 

471 driver prefers; if empty, the renderer may return either 

472 mode. Note that the mode is always a string, to simplify 

473 C-level implementations. 

474 

475 .. versionadded:: 1.1.5 

476 

477 :param direction: Direction of the text. It can be 'rtl' (right to 

478 left), 'ltr' (left to right) or 'ttb' (top to bottom). 

479 Requires libraqm. 

480 

481 .. versionadded:: 4.2.0 

482 

483 :param features: A list of OpenType font features to be used during text 

484 layout. This is usually used to turn on optional 

485 font features that are not enabled by default, 

486 for example 'dlig' or 'ss01', but can be also 

487 used to turn off default font features for 

488 example '-liga' to disable ligatures or '-kern' 

489 to disable kerning. To get all supported 

490 features, see 

491 https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist 

492 Requires libraqm. 

493 

494 .. versionadded:: 4.2.0 

495 

496 :param language: Language of the text. Different languages may use 

497 different glyph shapes or ligatures. This parameter tells 

498 the font which language the text is in, and to apply the 

499 correct substitutions as appropriate, if available. 

500 It should be a `BCP 47 language code 

501 <https://www.w3.org/International/articles/language-tags/>`_ 

502 Requires libraqm. 

503 

504 .. versionadded:: 6.0.0 

505 

506 :param stroke_width: The width of the text stroke. 

507 

508 .. versionadded:: 6.2.0 

509 

510 :param anchor: The text anchor alignment. Determines the relative location of 

511 the anchor to the text. The default alignment is top left, 

512 specifically ``la`` for horizontal text and ``lt`` for 

513 vertical text. See :ref:`text-anchors` for details. 

514 

515 .. versionadded:: 8.0.0 

516 

517 :param ink: Foreground ink for rendering in RGBA mode. 

518 

519 .. versionadded:: 8.0.0 

520 

521 :param start: Tuple of horizontal and vertical offset, as text may render 

522 differently when starting at fractional coordinates. 

523 

524 .. versionadded:: 9.4.0 

525 

526 :return: An internal PIL storage memory instance as defined by the 

527 :py:mod:`PIL.Image.core` interface module. 

528 """ 

529 return self.getmask2( 

530 text, 

531 mode, 

532 direction=direction, 

533 features=features, 

534 language=language, 

535 stroke_width=stroke_width, 

536 anchor=anchor, 

537 ink=ink, 

538 start=start, 

539 )[0] 

540 

541 def getmask2( 

542 self, 

543 text: str | bytes, 

544 mode: str = "", 

545 direction: str | None = None, 

546 features: list[str] | None = None, 

547 language: str | None = None, 

548 stroke_width: float = 0, 

549 anchor: str | None = None, 

550 ink: int = 0, 

551 start: tuple[float, float] | None = None, 

552 *args: Any, 

553 **kwargs: Any, 

554 ) -> tuple[Image.core.ImagingCore, tuple[int, int]]: 

555 """ 

556 Create a bitmap for the text. 

557 

558 If the font uses antialiasing, the bitmap should have mode ``L`` and use a 

559 maximum value of 255. If the font has embedded color data, the bitmap 

560 should have mode ``RGBA``. Otherwise, it should have mode ``1``. 

561 

562 :param text: Text to render. 

563 :param mode: Used by some graphics drivers to indicate what mode the 

564 driver prefers; if empty, the renderer may return either 

565 mode. Note that the mode is always a string, to simplify 

566 C-level implementations. 

567 

568 .. versionadded:: 1.1.5 

569 

570 :param direction: Direction of the text. It can be 'rtl' (right to 

571 left), 'ltr' (left to right) or 'ttb' (top to bottom). 

572 Requires libraqm. 

573 

574 .. versionadded:: 4.2.0 

575 

576 :param features: A list of OpenType font features to be used during text 

577 layout. This is usually used to turn on optional 

578 font features that are not enabled by default, 

579 for example 'dlig' or 'ss01', but can be also 

580 used to turn off default font features for 

581 example '-liga' to disable ligatures or '-kern' 

582 to disable kerning. To get all supported 

583 features, see 

584 https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist 

585 Requires libraqm. 

586 

587 .. versionadded:: 4.2.0 

588 

589 :param language: Language of the text. Different languages may use 

590 different glyph shapes or ligatures. This parameter tells 

591 the font which language the text is in, and to apply the 

592 correct substitutions as appropriate, if available. 

593 It should be a `BCP 47 language code 

594 <https://www.w3.org/International/articles/language-tags/>`_ 

595 Requires libraqm. 

596 

597 .. versionadded:: 6.0.0 

598 

599 :param stroke_width: The width of the text stroke. 

600 

601 .. versionadded:: 6.2.0 

602 

603 :param anchor: The text anchor alignment. Determines the relative location of 

604 the anchor to the text. The default alignment is top left, 

605 specifically ``la`` for horizontal text and ``lt`` for 

606 vertical text. See :ref:`text-anchors` for details. 

607 

608 .. versionadded:: 8.0.0 

609 

610 :param ink: Foreground ink for rendering in RGBA mode. 

611 

612 .. versionadded:: 8.0.0 

613 

614 :param start: Tuple of horizontal and vertical offset, as text may render 

615 differently when starting at fractional coordinates. 

616 

617 .. versionadded:: 9.4.0 

618 

619 :return: A tuple of an internal PIL storage memory instance as defined by the 

620 :py:mod:`PIL.Image.core` interface module, and the text offset, the 

621 gap between the starting coordinate and the first marking 

622 """ 

623 _string_length_check(text) 

624 if start is None: 

625 start = (0, 0) 

626 

627 def fill(width: int, height: int) -> Image.core.ImagingCore: 

628 size = (width, height) 

629 Image._decompression_bomb_check(size) 

630 return Image.core.fill("RGBA" if mode == "RGBA" else "L", size) 

631 

632 return self.font.render( 

633 text, 

634 fill, 

635 mode, 

636 direction, 

637 features, 

638 language, 

639 stroke_width, 

640 kwargs.get("stroke_filled", False), 

641 anchor, 

642 ink, 

643 start, 

644 ) 

645 

646 def font_variant( 

647 self, 

648 font: StrOrBytesPath | BinaryIO | None = None, 

649 size: float | None = None, 

650 index: int | None = None, 

651 encoding: str | None = None, 

652 layout_engine: Layout | None = None, 

653 ) -> FreeTypeFont: 

654 """ 

655 Create a copy of this FreeTypeFont object, 

656 using any specified arguments to override the settings. 

657 

658 Parameters are identical to the parameters used to initialize this 

659 object. 

660 

661 :return: A FreeTypeFont object. 

662 """ 

663 if font is None: 

664 try: 

665 font = BytesIO(self.font_bytes) 

666 except AttributeError: 

667 font = self.path 

668 return FreeTypeFont( 

669 font=font, 

670 size=self.size if size is None else size, 

671 index=self.index if index is None else index, 

672 encoding=self.encoding if encoding is None else encoding, 

673 layout_engine=layout_engine or self.layout_engine, 

674 ) 

675 

676 def get_variation_names(self) -> list[bytes]: 

677 """ 

678 :returns: A list of the named styles in a variation font. 

679 :exception OSError: If the font is not a variation font. 

680 """ 

681 names = [] 

682 for name in self.font.getvarnames(): 

683 name = name.replace(b"\x00", b"") 

684 if name not in names: 

685 names.append(name) 

686 return names 

687 

688 def set_variation_by_name(self, name: str | bytes) -> None: 

689 """ 

690 :param name: The name of the style. 

691 :exception OSError: If the font is not a variation font. 

692 """ 

693 names = self.get_variation_names() 

694 if not isinstance(name, bytes): 

695 name = name.encode() 

696 index = names.index(name) + 1 

697 

698 if index == getattr(self, "_last_variation_index", None): 

699 # When the same name is set twice in a row, 

700 # there is an 'unknown freetype error' 

701 # https://savannah.nongnu.org/bugs/?56186 

702 return 

703 self._last_variation_index = index 

704 

705 self.font.setvarname(index) 

706 

707 def get_variation_axes(self) -> list[Axis]: 

708 """ 

709 :returns: A list of the axes in a variation font. 

710 :exception OSError: If the font is not a variation font. 

711 """ 

712 axes = self.font.getvaraxes() 

713 for axis in axes: 

714 if axis["name"]: 

715 axis["name"] = axis["name"].replace(b"\x00", b"") 

716 return axes 

717 

718 def set_variation_by_axes(self, axes: list[float]) -> None: 

719 """ 

720 :param axes: A list of values for each axis. 

721 :exception OSError: If the font is not a variation font. 

722 """ 

723 self.font.setvaraxes(axes) 

724 

725 

726class TransposedFont: 

727 """Wrapper for writing rotated or mirrored text""" 

728 

729 def __init__( 

730 self, font: ImageFont | FreeTypeFont, orientation: Image.Transpose | None = None 

731 ): 

732 """ 

733 Wrapper that creates a transposed font from any existing font 

734 object. 

735 

736 :param font: A font object. 

737 :param orientation: An optional orientation. If given, this should 

738 be one of Image.Transpose.FLIP_LEFT_RIGHT, Image.Transpose.FLIP_TOP_BOTTOM, 

739 Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_180, or 

740 Image.Transpose.ROTATE_270. 

741 """ 

742 self.font = font 

743 self.orientation = orientation # any 'transpose' argument, or None 

744 

745 def getmask( 

746 self, text: str | bytes, mode: str = "", *args: Any, **kwargs: Any 

747 ) -> Image.core.ImagingCore: 

748 im = self.font.getmask(text, mode, *args, **kwargs) 

749 if self.orientation is not None: 

750 return im.transpose(self.orientation) 

751 return im 

752 

753 def getbbox( 

754 self, text: str | bytes, *args: Any, **kwargs: Any 

755 ) -> tuple[int, int, float, float]: 

756 # TransposedFont doesn't support getmask2, move top-left point to (0, 0) 

757 # this has no effect on ImageFont and simulates anchor="lt" for FreeTypeFont 

758 left, top, right, bottom = self.font.getbbox(text, *args, **kwargs) 

759 width = right - left 

760 height = bottom - top 

761 if self.orientation in (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270): 

762 return 0, 0, height, width 

763 return 0, 0, width, height 

764 

765 def getlength(self, text: str | bytes, *args: Any, **kwargs: Any) -> float: 

766 if self.orientation in (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270): 

767 msg = "text length is undefined for text rotated by 90 or 270 degrees" 

768 raise ValueError(msg) 

769 return self.font.getlength(text, *args, **kwargs) 

770 

771 

772def load(filename: str) -> ImageFont: 

773 """ 

774 Load a font file. This function loads a font object from the given 

775 bitmap font file, and returns the corresponding font object. For loading TrueType 

776 or OpenType fonts instead, see :py:func:`~PIL.ImageFont.truetype`. 

777 

778 :param filename: Name of font file. 

779 :return: A font object. 

780 :exception OSError: If the file could not be read. 

781 """ 

782 f = ImageFont() 

783 f._load_pilfont(filename) 

784 return f 

785 

786 

787def truetype( 

788 font: StrOrBytesPath | BinaryIO, 

789 size: float = 10, 

790 index: int = 0, 

791 encoding: str = "", 

792 layout_engine: Layout | None = None, 

793) -> FreeTypeFont: 

794 """ 

795 Load a TrueType or OpenType font from a file or file-like object, 

796 and create a font object. This function loads a font object from the given 

797 file or file-like object, and creates a font object for a font of the given 

798 size. For loading bitmap fonts instead, see :py:func:`~PIL.ImageFont.load` 

799 and :py:func:`~PIL.ImageFont.load_path`. 

800 

801 Pillow uses FreeType to open font files. On Windows, be aware that FreeType 

802 will keep the file open as long as the FreeTypeFont object exists. Windows 

803 limits the number of files that can be open in C at once to 512, so if many 

804 fonts are opened simultaneously and that limit is approached, an 

805 ``OSError`` may be thrown, reporting that FreeType "cannot open resource". 

806 A workaround would be to copy the file(s) into memory, and open that instead. 

807 

808 This function requires the _imagingft service. 

809 

810 :param font: A filename or file-like object containing a TrueType font. 

811 If the file is not found in this filename, the loader may also 

812 search in other directories, such as: 

813 

814 * The :file:`fonts/` directory on Windows, 

815 * :file:`/Library/Fonts/`, :file:`/System/Library/Fonts/` 

816 and :file:`~/Library/Fonts/` on macOS. 

817 * :file:`~/.local/share/fonts`, :file:`/usr/local/share/fonts`, 

818 and :file:`/usr/share/fonts` on Linux; or those specified by 

819 the ``XDG_DATA_HOME`` and ``XDG_DATA_DIRS`` environment variables 

820 for user-installed and system-wide fonts, respectively. 

821 

822 :param size: The requested size, in pixels. 

823 :param index: Which font face to load (default is first available face). 

824 :param encoding: Which font encoding to use (default is Unicode). Possible 

825 encodings include (see the FreeType documentation for more 

826 information): 

827 

828 * "unic" (Unicode) 

829 * "symb" (Microsoft Symbol) 

830 * "ADOB" (Adobe Standard) 

831 * "ADBE" (Adobe Expert) 

832 * "ADBC" (Adobe Custom) 

833 * "armn" (Apple Roman) 

834 * "sjis" (Shift JIS) 

835 * "gb " (PRC) 

836 * "big5" 

837 * "wans" (Extended Wansung) 

838 * "joha" (Johab) 

839 * "lat1" (Latin-1) 

840 

841 This specifies the character set to use. It does not alter the 

842 encoding of any text provided in subsequent operations. 

843 :param layout_engine: Which layout engine to use, if available: 

844 :attr:`.ImageFont.Layout.BASIC` or :attr:`.ImageFont.Layout.RAQM`. 

845 If it is available, Raqm layout will be used by default. 

846 Otherwise, basic layout will be used. 

847 

848 Raqm layout is recommended for all non-English text. If Raqm layout 

849 is not required, basic layout will have better performance. 

850 

851 You can check support for Raqm layout using 

852 :py:func:`PIL.features.check_feature` with ``feature="raqm"``. 

853 

854 .. versionadded:: 4.2.0 

855 :return: A font object. 

856 :exception OSError: If the file could not be read. 

857 :exception ValueError: If the font size is not greater than zero. 

858 """ 

859 

860 def freetype(font: StrOrBytesPath | BinaryIO) -> FreeTypeFont: 

861 return FreeTypeFont(font, size, index, encoding, layout_engine) 

862 

863 try: 

864 return freetype(font) 

865 except OSError: 

866 if not is_path(font): 

867 raise 

868 ttf_filename = os.path.basename(font) 

869 

870 dirs = [] 

871 if sys.platform == "win32": 

872 # check the windows font repository 

873 # NOTE: must use uppercase WINDIR, to work around bugs in 

874 # 1.5.2's os.environ.get() 

875 windir = os.environ.get("WINDIR") 

876 if windir: 

877 dirs.append(os.path.join(windir, "fonts")) 

878 elif sys.platform in ("linux", "linux2"): 

879 data_home = os.environ.get("XDG_DATA_HOME") 

880 if not data_home: 

881 # The freedesktop spec defines the following default directory for 

882 # when XDG_DATA_HOME is unset or empty. This user-level directory 

883 # takes precedence over system-level directories. 

884 data_home = os.path.expanduser("~/.local/share") 

885 xdg_dirs = [data_home] 

886 

887 data_dirs = os.environ.get("XDG_DATA_DIRS") 

888 if not data_dirs: 

889 # Similarly, defaults are defined for the system-level directories 

890 data_dirs = "/usr/local/share:/usr/share" 

891 xdg_dirs += data_dirs.split(":") 

892 

893 dirs += [os.path.join(xdg_dir, "fonts") for xdg_dir in xdg_dirs] 

894 elif sys.platform == "darwin": 

895 dirs += [ 

896 "/Library/Fonts", 

897 "/System/Library/Fonts", 

898 os.path.expanduser("~/Library/Fonts"), 

899 ] 

900 

901 ext = os.path.splitext(ttf_filename)[1] 

902 first_font_with_a_different_extension = None 

903 for directory in dirs: 

904 for walkroot, walkdir, walkfilenames in os.walk(directory): 

905 for walkfilename in walkfilenames: 

906 if ext and walkfilename == ttf_filename: 

907 return freetype(os.path.join(walkroot, walkfilename)) 

908 elif not ext and os.path.splitext(walkfilename)[0] == ttf_filename: 

909 fontpath = os.path.join(walkroot, walkfilename) 

910 if os.path.splitext(fontpath)[1] == ".ttf": 

911 return freetype(fontpath) 

912 if not ext and first_font_with_a_different_extension is None: 

913 first_font_with_a_different_extension = fontpath 

914 if first_font_with_a_different_extension: 

915 return freetype(first_font_with_a_different_extension) 

916 raise 

917 

918 

919def load_path(filename: str | bytes) -> ImageFont: 

920 """ 

921 Load font file. Same as :py:func:`~PIL.ImageFont.load`, but searches for a 

922 bitmap font along the Python path. 

923 

924 :param filename: Name of font file. 

925 :return: A font object. 

926 :exception OSError: If the file could not be read. 

927 """ 

928 if not isinstance(filename, str): 

929 filename = filename.decode("utf-8") 

930 for directory in sys.path: 

931 try: 

932 return load(os.path.join(directory, filename)) 

933 except OSError: 

934 pass 

935 msg = f'cannot find font file "{filename}" in sys.path' 

936 if os.path.exists(filename): 

937 msg += f', did you mean ImageFont.load("{filename}") instead?' 

938 

939 raise OSError(msg) 

940 

941 

942def load_default_imagefont() -> ImageFont: 

943 f = ImageFont() 

944 f._load_pilfont_data( 

945 # courB08 

946 BytesIO(base64.b64decode(b""" 

947UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

948AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

949AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

950AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

951AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

952AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

953AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

954AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

955AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

956AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

957AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

958AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA 

959BgAAAAH/+gADAAAAAQAAAAMABgAGAAAAAf/6AAT//QADAAAABgADAAYAAAAA//kABQABAAYAAAAL 

960AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA 

961AAAbAAYABgAAAAH/+QAE//wAGwAAAB4AAwAGAAAAAf/5AAQAAQAeAAAAIQAIAAYAAAAB//kABAAB 

962ACEAAAAkAAgABgAAAAD/+QAE//0AJAAAACgABAAGAAAAAP/6AAX//wAoAAAALQAFAAYAAAAB//8A 

963BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB 

964//kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA 

965AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH 

966AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA 

967ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv 

968AAAAcQAEAAYAAAAA//wAAwACAHEAAAB0AAYABgAAAAD/+gAE//8AdAAAAHgABQAGAAAAAP/7AAT/ 

969/gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5 

970AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA 

971AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG 

972AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA 

973BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA 

974AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA 

9752AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF 

976AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA//// 

977+gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA 

978////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA 

979BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv 

980AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA 

981AAE9AAEABgAAAAH/+QAE//wBPQAAAUAAAwAGAAAAAP/7AAYAAAFAAAABRgAFAAYAAP////kABQAA 

982AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA 

983BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP// 

984//kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA 

985AP////kABgAAAXcAAAF+AAcABgAAAAD/+QAGAAABfgAAAYQABwAGAAD////7AAUAAAGEAAABigAF 

986AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB 

987mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn 

988AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA 

989AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7 

990AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA 

991Av/6AAMAAQHdAAAB3gAHAAYAAAAA//kABAABAd4AAAHiAAgABgAAAAD/+wAF//0B4gAAAecAAgAA 

992AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

993AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

994AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

995AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

996AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

997AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

998AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

999AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1000AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1001AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1002AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1003AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB 

1004//sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA 

1005AAAA//oABf//AfQAAAH5AAUABgAAAAD/+QAGAAAB+QAAAf8ABwAGAAAAAv/5AAMAAgH/AAACAAAJ 

1006AAYAAAAA//kABQABAgAAAAIFAAgABgAAAAH/+gAE//sCBQAAAggAAQAGAAAAAP/5AAYAAAIIAAAC 

1007DgAHAAYAAAAB//kABf/+Ag4AAAISAAUABgAA////+wAGAAACEgAAAhkABQAGAAAAAP/7AAX//gIZ 

1008AAACHgADAAYAAAAA//wABf/9Ah4AAAIjAAEABgAAAAD/+QAHAAACIwAAAioABwAGAAAAAP/6AAT/ 

1009+wIqAAACLgABAAYAAAAA//kABP/8Ai4AAAIyAAMABgAAAAD/+gAFAAACMgAAAjcABgAGAAAAAf/5 

1010AAT//QI3AAACOgAEAAYAAAAB//kABP/9AjoAAAI9AAQABgAAAAL/+QAE//sCPQAAAj8AAgAGAAD/ 

1011///7AAYAAgI/AAACRgAHAAYAAAAA//kABgABAkYAAAJMAAgABgAAAAH//AAD//0CTAAAAk4AAQAG 

1012AAAAAf//AAQAAgJOAAACUQADAAYAAAAB//kABP/9AlEAAAJUAAQABgAAAAH/+QAF//4CVAAAAlgA 

1013BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA 

1014Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC 

1015eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG 

1016AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA//// 

1017+gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA 

1018////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA 

1019BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT 

1020AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A 

1021AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA 

1022Au4AAALzAAkABgAAAAD/9wAFAAAC8wAAAvgACQAGAAAAAP/4AAUAAAL4AAAC/QAIAAYAAAAA//oA 

1023Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP// 

1024//cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA 

1025AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ 

1026AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA 

1027LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5 

1028AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA 

1029AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5 

1030AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA 

1031AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG 

1032AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA 

1033EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK 

1034AJsAEQAGAAAAAP/6AAX//wCbAAoAoAAPAAYAAAAA//oABQABAKAACgClABEABgAA////+AAGAAAA 

1035pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG 

1036AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA//// 

1037+QAGAAIAzgAKANUAEw== 

1038""")), 

1039 Image.open(BytesIO(base64.b64decode(b""" 

1040iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u 

1041Mc4b7vuds/xzjz5/3/7u/n9vMe7vnfH/9++vPn/xyf5zhxzjt8GHw8+2d83u8x27199/nxuQ6Od9 

1042M43/5z2I+9n9ZtmDBwMQECDRQw/eQIQohJXxpBCNVE6QCCAAAAD//wBlAJr/AgALyj1t/wINwq0g 

1043LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F 

1044IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA 

1045Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791 

1046NAADfcoIDyP44K/jv4Y63/Z+t98Ovt+ub4T48LAAAAD//wBlAJr/AuplMlADJAAAAGuAphWpqhMx 

1047in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9 

1048SjdavWA8ePHeBIKB//81/83ndznOaXx379wAAAD//wBlAJr/AqDxW+D3AABAAbUh/QMnbQag/gAY 

1049AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt 

1050y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG 

1051ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY 

1052lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H 

1053/Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3 

1054AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47 

1055c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/ 

1056/yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw 

1057pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv 

1058oJodAAAAAP//Yqo/83+dxePWlxl3npsel9lvLfPcqlE9725C+acfVLMEAAAA//9i+s9gwCoaaGMR 

1059evta/58PTEWzr21hufPjA8N+qlnBwAAAAAD//2JiWLci5v1+HmFXDqcnULE/MxgYGBj+f6CaJQAA 

1060AAD//2Ji2FrkY3iYpYC5qDeGgeEMAwPDvwQBBoYvcTwOVLMEAAAA//9isDBgkP///0EOg9z35v// 

1061Gc/eeW7BwPj5+QGZhANUswMAAAD//2JgqGBgYGBgqEMXlvhMPUsAAAAA//8iYDd1AAAAAP//AwDR 

1062w7IkEbzhVQAAAABJRU5ErkJggg== 

1063"""))), 

1064 ) 

1065 return f 

1066 

1067 

1068def load_default(size: float | None = None) -> FreeTypeFont | ImageFont: 

1069 """If FreeType support is available, load a version of Aileron Regular, 

1070 https://dotcolon.net/fonts/aileron, with a more limited character set. 

1071 

1072 Otherwise, load a "better than nothing" font. 

1073 

1074 .. versionadded:: 1.1.4 

1075 

1076 :param size: The font size of Aileron Regular. 

1077 

1078 .. versionadded:: 10.1.0 

1079 

1080 :return: A font object. 

1081 """ 

1082 if isinstance(core, ModuleType) or size is not None: 

1083 return truetype( 

1084 BytesIO(base64.b64decode(b""" 

1085AAEAAAAPAIAAAwBwRkZUTYwDlUAAADFoAAAAHEdERUYAqADnAAAo8AAAACRHUE9ThhmITwAAKfgAA 

1086AduR1NVQnHxefoAACkUAAAA4k9TLzJovoHLAAABeAAAAGBjbWFw5lFQMQAAA6gAAAGqZ2FzcP//AA 

1087MAACjoAAAACGdseWYmRXoPAAAGQAAAHfhoZWFkE18ayQAAAPwAAAA2aGhlYQboArEAAAE0AAAAJGh 

1088tdHjjERZ8AAAB2AAAAdBsb2NhuOexrgAABVQAAADqbWF4cAC7AEYAAAFYAAAAIG5hbWUr+h5lAAAk 

1089OAAAA6Jwb3N0D3oPTQAAJ9wAAAEKAAEAAAABGhxJDqIhXw889QALA+gAAAAA0Bqf2QAAAADhCh2h/ 

10902r/LgOxAyAAAAAIAAIAAAAAAAAAAQAAA8r/GgAAA7j/av9qA7EAAQAAAAAAAAAAAAAAAAAAAHQAAQ 

1091AAAHQAQwAFAAAAAAACAAAAAQABAAAAQAAAAAAAAAADAfoBkAAFAAgCigJYAAAASwKKAlgAAAFeADI 

1092BPgAAAAAFAAAAAAAAAAAAAAcAAAAAAAAAAAAAAABVS1dOAEAAIPsCAwL/GgDIA8oA5iAAAJMAAAAA 

1093AhICsgAAACAAAwH0AAAAAAAAAU0AAADYAAAA8gA5AVMAVgJEAEYCRAA1AuQAKQKOAEAAsAArATsAZ 

1094AE7AB4CMABVAkQAUADc/+EBEgAgANwAJQEv//sCRAApAkQAggJEADwCRAAtAkQAIQJEADkCRAArAk 

1095QAMgJEACwCRAAxANwAJQDc/+ECRABnAkQAUAJEAEQB8wAjA1QANgJ/AB0CcwBkArsALwLFAGQCSwB 

1096kAjcAZALGAC8C2gBkAQgAZAIgADcCYQBkAj8AZANiAGQCzgBkAuEALwJWAGQC3QAvAmsAZAJJADQC 

1097ZAAiAqoAXgJuACADuAAaAnEAGQJFABMCTwAuATMAYgEv//sBJwAiAkQAUAH0ADIBLAApAhMAJAJjA 

1098EoCEQAeAmcAHgIlAB4BIgAVAmcAHgJRAEoA7gA+AOn/8wIKAEoA9wBGA1cASgJRAEoCSgAeAmMASg 

1099JnAB4BSgBKAcsAGAE5ABQCUABCAgIAAQMRAAEB4v/6AgEAAQHOABQBLwBAAPoAYAEvACECRABNA0Y 

1100AJAItAHgBKgAcAkQAUAEsAHQAygAgAi0AOQD3ADYA9wAWAaEANgGhABYCbAAlAYMAeAGDADkA6/9q 

1101AhsAFAIKABUB/QAVAAAAAwAAAAMAAAAcAAEAAAAAAKQAAwABAAAAHAAEAIgAAAAeABAAAwAOAH4Aq 

1102QCrALEAtAC3ALsgGSAdICYgOiBEISL7Av//AAAAIACpAKsAsAC0ALcAuyAYIBwgJiA5IEQhIvsB// 

1103//4/+5/7j/tP+y/7D/reBR4E/gR+A14CzfTwVxAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1104AAAAAAAEGAAABAAAAAAAAAAECAAAAAgAAAAAAAAAAAAAAAAAAAAEAAAMEBQYHCAkKCwwNDg8QERIT 

1105FBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMT 

1106U5PUFFSU1RVVldYWVpbXF1eX2BhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQAAA 

1107AAAAAAYnFmAAAAAABlAAAAAAAAAAAAAAAAAAAAAAAAAAAAY2htAAAAAAAAAABrbGlqAAAAAHAAbm9 

1108ycwBnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmACYAJgAmAD4AUgCCAMoBCgFO 

1109AVwBcgGIAaYBvAHKAdYB6AH2AgwCIAJKAogCpgLWAw4DIgNkA5wDugPUA+gD/AQQBEYEogS8BPoFJ 

1110gVSBWoFgAWwBcoF1gX6BhQGJAZMBmgGiga0BuIHGgdUB2YHkAeiB8AH3AfyCAoIHAgqCDoITghcCG 

1111oIogjSCPoJKglYCXwJwgnqCgIKKApACl4Klgq8CtwLDAs8C1YLjAuyC9oL7gwMDCYMSAxgDKAMrAz 

1112qDQoNTA1mDYQNoA2uDcAN2g3oDfYODA4iDkoOXA5sDnoOnA7EDvwAAAAFAAAAAAH0ArwAAwAGAAkA 

1113DAAPAAAxESERAxMhExcRASELARETAfT6qv6syKr+jgFUqsiqArz9RAGLAP/+1P8B/v3VAP8BLP4CA 

1114P8AAgA5//IAuQKyAAMACwAANyMDMwIyFhQGIiY0oE4MZk84JCQ4JLQB/v3AJDgkJDgAAgBWAeUBPA 

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 

1160vArIACwAAJRUhESEVIRUhFSEVAi/+NQHB/pUBTf6zRkYCskbwRvAAAAABAGQAAAIlArIACQAAExUh 

1161FSERIxEhFboBQ/69VgHBAmzwRv7KArJGAAAAAAEAL//yAo8CwAAfAAABMxEjNQcGIyImNTQ2MzIWH 

1162wEjJyYjIgYVFBYzMjY1IwGP90wfPnWTprSSf48LAVYCIqJofHllVG+hAU3+s3hARsicn8uAagoKpq 

1163N/gaN1XAAAAAEAZAAAAowCsgALAAABESMRIREjETMRIRECjFb+hFZWAXwCsv1OAS7+0gKy/sQBPAA 

1164AAAABAGQAAAC6ArIAAwAAMyMRM7pWVgKyAAABADf/8gHoArIAEwAAAREUBw4BIyImLwEzFxYzMjc2 

1165NREB6AIFcGpgbQIBVgIHfXQKAQKy/lYxIltob2EpKYyEFD0BpwAAAAABAGQAAAJ0ArIACwAACQEjA 

1166wcVIxEzEQEzATsBJ3ntQlZWAVVlAWH+nwEnR+ACsv6RAW8AAQBkAAACLwKyAAUAACUVIREzEQIv/j 

1167VWRkYCsv2UAAABAGQAAAMUArIAFAAAAREjETQ3BgcDIwMmJxYVESMRMxsBAxRWAiMxemx8NxsCVo7 

1168MywKy/U4BY7ZLco7+nAFmoFxLtP6dArL9lwJpAAAAAAEAZAAAAoACsgANAAAhIwEWFREjETMBJjUR 

1169MwKAhP67A1aEAUUDVAJeeov+pwKy/aJ5jAFZAAAAAgAv//ICuwLAAAkAEwAAEiAWFRQGICY1NBIyN 

1170jU0JiIGFRTbATSsrP7MrNrYenrYegLAxaKhxsahov47nIeIm5uIhwACAGQAAAJHArIADgAYAAABHg 

1171EVFAYHBisBESMRMzITNjQnJisBETMyAZRUX2VOHzuAVtY7GlxcGDWIiDUCrgtnVlVpCgT+5gKy/rU 

1172V1BUF/vgAAAACAC//zAK9AsAAEgAcAAAlFhcHJiMiBwYjIiY1NDYgFhUUJRQWMjY1NCYiBgI9PUMx 

1173UDcfKh8omqysATSs/dR62Hp62HpICTg7NgkHxqGixcWitbWHnJyHiJubAAIAZAAAAlgCsgAXACMAA 

1174CUWFyMmJyYnJisBESMRMzIXHgEVFAYHFiUzMjc+ATU0JyYrAQIqDCJfGQwNWhAhglbiOx9QXEY1Tv 

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 

1250gQAAwABBAkADAAuAkwATgBvACAAUgBpAGcAaAB0AHMAIABSAGUAcwBlAHIAdgBlAGQALgAATm8gUm 

1251lnaHRzIFJlc2VydmVkLgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAUgBlAGcAdQBsAGEAcgAAUmV 

1252ndWxhcgAAMQAuADEAMAAyADsAVQBLAFcATgA7AEEAaQBsAGUAcgBvAG4ALQBSAGUAZwB1AGwAYQBy 

1253AAAxLjEwMjtVS1dOO0FpbGVyb24tUmVndWxhcgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAVgBlA 

1254HIAcwBpAG8AbgAgADEALgAxADAAMgA7AFAAUwAgADAAMAAxAC4AMQAwADIAOwBoAG8AdABjAG8Abg 

1255B2ACAAMQAuADAALgA3ADAAOwBtAGEAawBlAG8AdABmAC4AbABpAGIAMgAuADUALgA1ADgAMwAyADk 

1256AAFZlcnNpb24gMS4xMDI7UFMgMDAxLjEwMjtob3Rjb252IDEuMC43MDttYWtlb3RmLmxpYjIuNS41 

1257ODMyOQAAQQBpAGwAZQByAG8AbgAtAFIAZQBnAHUAbABhAHIAAEFpbGVyb24tUmVndWxhcgAAUwBvA 

1258HIAYQAgAFMAYQBnAGEAbgBvAABTb3JhIFNhZ2FubwAAUwBvAHIAYQAgAFMAYQBnAGEAbgBvAABTb3 

1259JhIFNhZ2FubwAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBsAG8AbgAuAG4AZQB0AAB 

1260odHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBs 

1261AG8AbgAuAG4AZQB0AABodHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAAAACAAAAAAAA/4MAMgAAAAAAA 

1262AAAAAAAAAAAAAAAAAAAAHQAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATAB 

1263QAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAA 

1264xADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0A 

1265TgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAIsAqQCDAJMAjQDDAKoAtgC3A 

1266LQAtQCrAL4AvwC8AIwAwADBAAAAAAAB//8AAgABAAAADAAAABwAAAACAAIAAwBxAAEAcgBzAAIABA 

1267AAAAIAAAABAAAACgBMAGYAAkRGTFQADmxhdG4AGgAEAAAAAP//AAEAAAAWAANDQVQgAB5NT0wgABZ 

1268ST00gABYAAP//AAEAAAAA//8AAgAAAAEAAmxpZ2EADmxvY2wAFAAAAAEAAQAAAAEAAAACAAYAEAAG 

1269AAAAAgASADQABAAAAAEATAADAAAAAgAQABYAAQAcAAAAAQABAE8AAQABAGcAAQABAE8AAwAAAAIAE 

1270AAWAAEAHAAAAAEAAQAvAAEAAQBnAAEAAQAvAAEAGgABAAgAAgAGAAwAcwACAE8AcgACAEwAAQABAE 

1271kAAAABAAAACgBGAGAAAkRGTFQADmxhdG4AHAAEAAAAAP//AAIAAAABABYAA0NBVCAAFk1PTCAAFlJ 

1272PTSAAFgAA//8AAgAAAAEAAmNwc3AADmtlcm4AFAAAAAEAAAAAAAEAAQACAAYADgABAAAAAQASAAIA 

1273AAACAB4ANgABAAoABQAFAAoAAgABACQAPQAAAAEAEgAEAAAAAQAMAAEAOP/nAAEAAQAkAAIGigAEA 

1274AAFJAXKABoAGQAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1275AAAAD/sv+4/+z/7v/MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1276AAAAAAAD/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9T/6AAAAAD/8QAA 

1277ABD/vQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7gAAAAAAAAAAAAAAAAAA//MAA 

1278AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAP/5AAAAAAAAAA 

1279AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gAAD/4AAAAAAAAAAAAAAAAAA 

1280AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//L/9AAAAAAAAAAAAAAAAAAAAAAA 

1281AAAAAAAAAAAA/+gAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1282AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAAAAA 

1283AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/mAAAAAAAAAAAAAAAAAAD 

1284/4gAA//AAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+AAAAAAAAP/OAAAAAAAAAAAAAAAA 

1285AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zv/qAAAAAP/0AAAACAAAAAAAAAAAAAAAAAAAAAAAA 

1286AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/ZAAD/egAA/1kAAAAA/5D/rgAAAAAAAAAAAA 

1287AAAAAAAAAAAAAAAAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1288AAAAAAAAAAAAAAAAAAAD/8AAA/7b/8P+wAAD/8P/E/98AAAAA/8P/+P/0//oAAAAAAAAAAAAA//gA 

1289AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+AAAAAAAAAAAAAAA 

1290AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/w//C/9MAAP/SAAD/9wAAAAAAAA 

1291AAAAAAAAAAAAAAAAAAAAAAAAAAAAD/yAAA/+kAAAAA//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1292AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9wAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1293AAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1294AAAAAAAAP/cAAAAAAAAAAAAAAAA/7YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1295AAAAAAAAAAAAAAAAAAAAAAAAAAAP/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6AAAAAAAAAA 

1296AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAkAFAAEAAAAAQACwAAABcA 

1297BgAAAAAAAAAIAA4AAAAAAAsAEgAAAAAAAAATABkAAwANAAAAAQAJAAAAAAAAAAAAAAAAAAAAGAAAA 

1298AAABwAAAAAAAAAAAAAAFQAFAAAAAAAYABgAAAAUAAAACgAAAAwAAgAPABEAFgAAAAAAAAAAAAAAAA 

1299AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAEAEQBdAAYAAAAAAAAAAAAAAAAAAAAAAAA 

1300AAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAcAAAAAAAAABwAAAAAACAAAAAAAAAAAAAcAAAAHAAAAEwAJ 

1301ABUADgAPAAAACwAQAAAAAAAAAAAAAAAAAAUAGAACAAIAAgAAAAIAGAAXAAAAGAAAABYAFgACABYAA 

1302gAWAAAAEQADAAoAFAAMAA0ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAEgAGAAEAHgAkAC 

1303YAJwApACoALQAuAC8AMgAzADcAOAA5ADoAPAA9AEUASABOAE8AUgBTAFUAVwBZAFoAWwBcAF0AcwA 

1304AAAAAAQAAAADa3tfFAAAAANAan9kAAAAA4QodoQ== 

1305""")), 

1306 10 if size is None else size, 

1307 layout_engine=Layout.BASIC, 

1308 ) 

1309 return load_default_imagefont()