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

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

139 

140 # read PILfont metrics 

141 data = file.read(256 * 20) 

142 

143 # check image 

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

145 msg = "invalid font image mode" 

146 raise TypeError(msg) 

147 

148 image.load() 

149 

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

151 

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. 

157 

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``. 

160 

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. 

166 

167 .. versionadded:: 1.1.5 

168 

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) 

175 

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. 

181 

182 .. versionadded:: 9.2.0 

183 

184 :param text: Text to render. 

185 

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 

191 

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. 

198 

199 .. versionadded:: 9.2.0 

200 """ 

201 _string_length_check(text) 

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

203 return width 

204 

205 

206## 

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

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

209 

210 

211class FreeTypeFont: 

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

213 

214 font: Font 

215 font_bytes: bytes 

216 

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 

226 

227 if isinstance(core, DeferredError): 

228 raise core.ex 

229 

230 if size <= 0: 

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

232 raise ValueError(msg) 

233 

234 self.path = font 

235 self.size = size 

236 self.index = index 

237 self.encoding = encoding 

238 

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

240 layout_engine = Layout.BASIC 

241 if core.HAVE_RAQM: 

242 layout_engine = Layout.RAQM 

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

244 warnings.warn( 

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

246 "Falling back to basic layout." 

247 ) 

248 layout_engine = Layout.BASIC 

249 

250 self.layout_engine = layout_engine 

251 

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

253 self.font_bytes = f.read() 

254 self.font = core.getfont( 

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

256 ) 

257 

258 if is_path(font): 

259 font = os.fspath(font) 

260 if sys.platform == "win32": 

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

262 try: 

263 font_bytes_path.decode("ascii") 

264 except UnicodeDecodeError: 

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

266 # So load it into memory first 

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

268 load_from_bytes(f) 

269 return 

270 self.font = core.getfont( 

271 font, size, index, encoding, layout_engine=layout_engine 

272 ) 

273 else: 

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

275 

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

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

278 

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

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

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

282 

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

284 """ 

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

286 (e.g. Bold) 

287 """ 

288 return self.font.family, self.font.style 

289 

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

291 """ 

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

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

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

295 """ 

296 return self.font.ascent, self.font.descent 

297 

298 def getlength( 

299 self, 

300 text: str | bytes, 

301 mode: str = "", 

302 direction: str | None = None, 

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

304 language: str | None = None, 

305 ) -> float: 

306 """ 

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

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

309 

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

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

312 e.g. when using italics or accents. 

313 

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

315 

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

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

318 character and subtract its length. 

319 

320 For example, instead of :: 

321 

322 hello = font.getlength("Hello") 

323 world = font.getlength("World") 

324 hello_world = hello + world # not adjusted for kerning 

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

326 

327 use :: 

328 

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

330 world = font.getlength("World") 

331 hello_world = hello + world # adjusted for kerning 

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

333 

334 or disable kerning with (requires libraqm) :: 

335 

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

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

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

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

340 

341 .. versionadded:: 8.0.0 

342 

343 :param text: Text to measure. 

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

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

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

347 C-level implementations. 

348 

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

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

351 Requires libraqm. 

352 

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

354 layout. This is usually used to turn on optional 

355 font features that are not enabled by default, 

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

357 used to turn off default font features for 

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

359 to disable kerning. To get all supported 

360 features, see 

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

362 Requires libraqm. 

363 

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

365 different glyph shapes or ligatures. This parameter tells 

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

367 correct substitutions as appropriate, if available. 

368 It should be a `BCP 47 language code 

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

370 Requires libraqm. 

371 

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

373 """ 

374 _string_length_check(text) 

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

376 

377 def getbbox( 

378 self, 

379 text: str | bytes, 

380 mode: str = "", 

381 direction: str | None = None, 

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

383 language: str | None = None, 

384 stroke_width: float = 0, 

385 anchor: str | None = None, 

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

387 """ 

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

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

390 

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

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

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

394 

395 .. versionadded:: 8.0.0 

396 

397 :param text: Text to render. 

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

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

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

401 C-level implementations. 

402 

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

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

405 Requires libraqm. 

406 

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

408 layout. This is usually used to turn on optional 

409 font features that are not enabled by default, 

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

411 used to turn off default font features for 

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

413 to disable kerning. To get all supported 

414 features, see 

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

416 Requires libraqm. 

417 

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

419 different glyph shapes or ligatures. This parameter tells 

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

421 correct substitutions as appropriate, if available. 

422 It should be a `BCP 47 language code 

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

424 Requires libraqm. 

425 

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

427 

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

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

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

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

432 

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

434 """ 

435 _string_length_check(text) 

436 size, offset = self.font.getsize( 

437 text, mode, direction, features, language, anchor 

438 ) 

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

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

441 return left, top, left + width, top + height 

442 

443 def getmask( 

444 self, 

445 text: str | bytes, 

446 mode: str = "", 

447 direction: str | None = None, 

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

449 language: str | None = None, 

450 stroke_width: float = 0, 

451 anchor: str | None = None, 

452 ink: int = 0, 

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

454 ) -> Image.core.ImagingCore: 

455 """ 

456 Create a bitmap for the text. 

457 

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

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

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

461 

462 :param text: Text to render. 

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

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

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

466 C-level implementations. 

467 

468 .. versionadded:: 1.1.5 

469 

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

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

472 Requires libraqm. 

473 

474 .. versionadded:: 4.2.0 

475 

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

477 layout. This is usually used to turn on optional 

478 font features that are not enabled by default, 

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

480 used to turn off default font features for 

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

482 to disable kerning. To get all supported 

483 features, see 

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

485 Requires libraqm. 

486 

487 .. versionadded:: 4.2.0 

488 

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

490 different glyph shapes or ligatures. This parameter tells 

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

492 correct substitutions as appropriate, if available. 

493 It should be a `BCP 47 language code 

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

495 Requires libraqm. 

496 

497 .. versionadded:: 6.0.0 

498 

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

500 

501 .. versionadded:: 6.2.0 

502 

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

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

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

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

507 

508 .. versionadded:: 8.0.0 

509 

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

511 

512 .. versionadded:: 8.0.0 

513 

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

515 differently when starting at fractional coordinates. 

516 

517 .. versionadded:: 9.4.0 

518 

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

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

521 """ 

522 return self.getmask2( 

523 text, 

524 mode, 

525 direction=direction, 

526 features=features, 

527 language=language, 

528 stroke_width=stroke_width, 

529 anchor=anchor, 

530 ink=ink, 

531 start=start, 

532 )[0] 

533 

534 def getmask2( 

535 self, 

536 text: str | bytes, 

537 mode: str = "", 

538 direction: str | None = None, 

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

540 language: str | None = None, 

541 stroke_width: float = 0, 

542 anchor: str | None = None, 

543 ink: int = 0, 

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

545 *args: Any, 

546 **kwargs: Any, 

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

548 """ 

549 Create a bitmap for the text. 

550 

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

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

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

554 

555 :param text: Text to render. 

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

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

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

559 C-level implementations. 

560 

561 .. versionadded:: 1.1.5 

562 

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

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

565 Requires libraqm. 

566 

567 .. versionadded:: 4.2.0 

568 

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

570 layout. This is usually used to turn on optional 

571 font features that are not enabled by default, 

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

573 used to turn off default font features for 

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

575 to disable kerning. To get all supported 

576 features, see 

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

578 Requires libraqm. 

579 

580 .. versionadded:: 4.2.0 

581 

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

583 different glyph shapes or ligatures. This parameter tells 

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

585 correct substitutions as appropriate, if available. 

586 It should be a `BCP 47 language code 

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

588 Requires libraqm. 

589 

590 .. versionadded:: 6.0.0 

591 

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

593 

594 .. versionadded:: 6.2.0 

595 

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

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

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

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

600 

601 .. versionadded:: 8.0.0 

602 

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

604 

605 .. versionadded:: 8.0.0 

606 

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

608 differently when starting at fractional coordinates. 

609 

610 .. versionadded:: 9.4.0 

611 

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

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

614 gap between the starting coordinate and the first marking 

615 """ 

616 _string_length_check(text) 

617 if start is None: 

618 start = (0, 0) 

619 

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

621 size = (width, height) 

622 Image._decompression_bomb_check(size) 

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

624 

625 return self.font.render( 

626 text, 

627 fill, 

628 mode, 

629 direction, 

630 features, 

631 language, 

632 stroke_width, 

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

634 anchor, 

635 ink, 

636 start, 

637 ) 

638 

639 def font_variant( 

640 self, 

641 font: StrOrBytesPath | BinaryIO | None = None, 

642 size: float | None = None, 

643 index: int | None = None, 

644 encoding: str | None = None, 

645 layout_engine: Layout | None = None, 

646 ) -> FreeTypeFont: 

647 """ 

648 Create a copy of this FreeTypeFont object, 

649 using any specified arguments to override the settings. 

650 

651 Parameters are identical to the parameters used to initialize this 

652 object. 

653 

654 :return: A FreeTypeFont object. 

655 """ 

656 if font is None: 

657 try: 

658 font = BytesIO(self.font_bytes) 

659 except AttributeError: 

660 font = self.path 

661 return FreeTypeFont( 

662 font=font, 

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

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

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

666 layout_engine=layout_engine or self.layout_engine, 

667 ) 

668 

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

670 """ 

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

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

673 """ 

674 names = self.font.getvarnames() 

675 return [name.replace(b"\x00", b"") for name in names] 

676 

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

678 """ 

679 :param name: The name of the style. 

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

681 """ 

682 names = self.get_variation_names() 

683 if not isinstance(name, bytes): 

684 name = name.encode() 

685 index = names.index(name) + 1 

686 

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

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

689 # there is an 'unknown freetype error' 

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

691 return 

692 self._last_variation_index = index 

693 

694 self.font.setvarname(index) 

695 

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

697 """ 

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

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

700 """ 

701 axes = self.font.getvaraxes() 

702 for axis in axes: 

703 if axis["name"]: 

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

705 return axes 

706 

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

708 """ 

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

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

711 """ 

712 self.font.setvaraxes(axes) 

713 

714 

715class TransposedFont: 

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

717 

718 def __init__( 

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

720 ): 

721 """ 

722 Wrapper that creates a transposed font from any existing font 

723 object. 

724 

725 :param font: A font object. 

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

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

728 Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_180, or 

729 Image.Transpose.ROTATE_270. 

730 """ 

731 self.font = font 

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

733 

734 def getmask( 

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

736 ) -> Image.core.ImagingCore: 

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

738 if self.orientation is not None: 

739 return im.transpose(self.orientation) 

740 return im 

741 

742 def getbbox( 

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

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

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

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

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

748 width = right - left 

749 height = bottom - top 

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

751 return 0, 0, height, width 

752 return 0, 0, width, height 

753 

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

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

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

757 raise ValueError(msg) 

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

759 

760 

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

762 """ 

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

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

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

766 

767 :param filename: Name of font file. 

768 :return: A font object. 

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

770 """ 

771 f = ImageFont() 

772 f._load_pilfont(filename) 

773 return f 

774 

775 

776def truetype( 

777 font: StrOrBytesPath | BinaryIO, 

778 size: float = 10, 

779 index: int = 0, 

780 encoding: str = "", 

781 layout_engine: Layout | None = None, 

782) -> FreeTypeFont: 

783 """ 

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

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

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

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

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

789 

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

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

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

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

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

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

796 

797 This function requires the _imagingft service. 

798 

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

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

801 search in other directories, such as: 

802 

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

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

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

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

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

808 the ``XDG_DATA_HOME`` and ``XDG_DATA_DIRS`` environment variables 

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

810 

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

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

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

814 encodings include (see the FreeType documentation for more 

815 information): 

816 

817 * "unic" (Unicode) 

818 * "symb" (Microsoft Symbol) 

819 * "ADOB" (Adobe Standard) 

820 * "ADBE" (Adobe Expert) 

821 * "ADBC" (Adobe Custom) 

822 * "armn" (Apple Roman) 

823 * "sjis" (Shift JIS) 

824 * "gb " (PRC) 

825 * "big5" 

826 * "wans" (Extended Wansung) 

827 * "joha" (Johab) 

828 * "lat1" (Latin-1) 

829 

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

831 encoding of any text provided in subsequent operations. 

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

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

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

835 Otherwise, basic layout will be used. 

836 

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

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

839 

840 You can check support for Raqm layout using 

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

842 

843 .. versionadded:: 4.2.0 

844 :return: A font object. 

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

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

847 """ 

848 

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

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

851 

852 try: 

853 return freetype(font) 

854 except OSError: 

855 if not is_path(font): 

856 raise 

857 ttf_filename = os.path.basename(font) 

858 

859 dirs = [] 

860 if sys.platform == "win32": 

861 # check the windows font repository 

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

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

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

865 if windir: 

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

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

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

869 if not data_home: 

870 # The freedesktop spec defines the following default directory for 

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

872 # takes precedence over system-level directories. 

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

874 xdg_dirs = [data_home] 

875 

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

877 if not data_dirs: 

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

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

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

881 

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

883 elif sys.platform == "darwin": 

884 dirs += [ 

885 "/Library/Fonts", 

886 "/System/Library/Fonts", 

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

888 ] 

889 

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

891 first_font_with_a_different_extension = None 

892 for directory in dirs: 

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

894 for walkfilename in walkfilenames: 

895 if ext and walkfilename == ttf_filename: 

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

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

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

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

900 return freetype(fontpath) 

901 if not ext and first_font_with_a_different_extension is None: 

902 first_font_with_a_different_extension = fontpath 

903 if first_font_with_a_different_extension: 

904 return freetype(first_font_with_a_different_extension) 

905 raise 

906 

907 

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

909 """ 

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

911 bitmap font along the Python path. 

912 

913 :param filename: Name of font file. 

914 :return: A font object. 

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

916 """ 

917 if not isinstance(filename, str): 

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

919 for directory in sys.path: 

920 try: 

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

922 except OSError: 

923 pass 

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

925 if os.path.exists(filename): 

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

927 

928 raise OSError(msg) 

929 

930 

931def load_default_imagefont() -> ImageFont: 

932 f = ImageFont() 

933 f._load_pilfont_data( 

934 # courB08 

935 BytesIO( 

936 base64.b64decode( 

937 b""" 

938UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

939AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

940AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

941AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

942AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

943AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

944AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

945AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

946AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

947AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

948AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

949AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA 

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

951AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA 

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

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

954BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB 

955//kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA 

956AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH 

957AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA 

958ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv 

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

960/gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5 

961AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA 

962AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG 

963AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA 

964BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA 

965AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA 

9662AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF 

967AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA//// 

968+gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA 

969////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA 

970BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv 

971AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA 

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

973AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA 

974BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP// 

975//kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA 

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

977AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB 

978mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn 

979AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA 

980AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7 

981AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA 

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

983AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

984AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

985AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

986AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

987AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

988AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

989AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

990AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

991AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

992AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

993AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

994AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB 

995//sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA 

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

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

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

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

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

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

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

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

1004BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA 

1005Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC 

1006eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG 

1007AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA//// 

1008+gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA 

1009////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA 

1010BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT 

1011AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A 

1012AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA 

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

1014Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP// 

1015//cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA 

1016AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ 

1017AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA 

1018LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5 

1019AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA 

1020AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5 

1021AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA 

1022AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG 

1023AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA 

1024EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK 

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

1026pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG 

1027AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA//// 

1028+QAGAAIAzgAKANUAEw== 

1029""" 

1030 ) 

1031 ), 

1032 Image.open( 

1033 BytesIO( 

1034 base64.b64decode( 

1035 b""" 

1036iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u 

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

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

1039LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F 

1040IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA 

1041Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791 

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

1043in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9 

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

1045AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt 

1046y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG 

1047ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY 

1048lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H 

1049/Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3 

1050AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47 

1051c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/ 

1052/yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw 

1053pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv 

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

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

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

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

1058w7IkEbzhVQAAAABJRU5ErkJggg== 

1059""" 

1060 ) 

1061 ) 

1062 ), 

1063 ) 

1064 return f 

1065 

1066 

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

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

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

1070 

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

1072 

1073 .. versionadded:: 1.1.4 

1074 

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

1076 

1077 .. versionadded:: 10.1.0 

1078 

1079 :return: A font object. 

1080 """ 

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

1082 return truetype( 

1083 BytesIO( 

1084 base64.b64decode( 

1085 b""" 

1086AAEAAAAPAIAAAwBwRkZUTYwDlUAAADFoAAAAHEdERUYAqADnAAAo8AAAACRHUE9ThhmITwAAKfgAA 

1087AduR1NVQnHxefoAACkUAAAA4k9TLzJovoHLAAABeAAAAGBjbWFw5lFQMQAAA6gAAAGqZ2FzcP//AA 

1088MAACjoAAAACGdseWYmRXoPAAAGQAAAHfhoZWFkE18ayQAAAPwAAAA2aGhlYQboArEAAAE0AAAAJGh 

1089tdHjjERZ8AAAB2AAAAdBsb2NhuOexrgAABVQAAADqbWF4cAC7AEYAAAFYAAAAIG5hbWUr+h5lAAAk 

1090OAAAA6Jwb3N0D3oPTQAAJ9wAAAEKAAEAAAABGhxJDqIhXw889QALA+gAAAAA0Bqf2QAAAADhCh2h/ 

10912r/LgOxAyAAAAAIAAIAAAAAAAAAAQAAA8r/GgAAA7j/av9qA7EAAQAAAAAAAAAAAAAAAAAAAHQAAQ 

1092AAAHQAQwAFAAAAAAACAAAAAQABAAAAQAAAAAAAAAADAfoBkAAFAAgCigJYAAAASwKKAlgAAAFeADI 

1093BPgAAAAAFAAAAAAAAAAAAAAcAAAAAAAAAAAAAAABVS1dOAEAAIPsCAwL/GgDIA8oA5iAAAJMAAAAA 

1094AhICsgAAACAAAwH0AAAAAAAAAU0AAADYAAAA8gA5AVMAVgJEAEYCRAA1AuQAKQKOAEAAsAArATsAZ 

1095AE7AB4CMABVAkQAUADc/+EBEgAgANwAJQEv//sCRAApAkQAggJEADwCRAAtAkQAIQJEADkCRAArAk 

1096QAMgJEACwCRAAxANwAJQDc/+ECRABnAkQAUAJEAEQB8wAjA1QANgJ/AB0CcwBkArsALwLFAGQCSwB 

1097kAjcAZALGAC8C2gBkAQgAZAIgADcCYQBkAj8AZANiAGQCzgBkAuEALwJWAGQC3QAvAmsAZAJJADQC 

1098ZAAiAqoAXgJuACADuAAaAnEAGQJFABMCTwAuATMAYgEv//sBJwAiAkQAUAH0ADIBLAApAhMAJAJjA 

1099EoCEQAeAmcAHgIlAB4BIgAVAmcAHgJRAEoA7gA+AOn/8wIKAEoA9wBGA1cASgJRAEoCSgAeAmMASg 

1100JnAB4BSgBKAcsAGAE5ABQCUABCAgIAAQMRAAEB4v/6AgEAAQHOABQBLwBAAPoAYAEvACECRABNA0Y 

1101AJAItAHgBKgAcAkQAUAEsAHQAygAgAi0AOQD3ADYA9wAWAaEANgGhABYCbAAlAYMAeAGDADkA6/9q 

1102AhsAFAIKABUB/QAVAAAAAwAAAAMAAAAcAAEAAAAAAKQAAwABAAAAHAAEAIgAAAAeABAAAwAOAH4Aq 

1103QCrALEAtAC3ALsgGSAdICYgOiBEISL7Av//AAAAIACpAKsAsAC0ALcAuyAYIBwgJiA5IEQhIvsB// 

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

1105AAAAAAAEGAAABAAAAAAAAAAECAAAAAgAAAAAAAAAAAAAAAAAAAAEAAAMEBQYHCAkKCwwNDg8QERIT 

1106FBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMT 

1107U5PUFFSU1RVVldYWVpbXF1eX2BhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQAAA 

1108AAAAAAYnFmAAAAAABlAAAAAAAAAAAAAAAAAAAAAAAAAAAAY2htAAAAAAAAAABrbGlqAAAAAHAAbm9 

1109ycwBnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmACYAJgAmAD4AUgCCAMoBCgFO 

1110AVwBcgGIAaYBvAHKAdYB6AH2AgwCIAJKAogCpgLWAw4DIgNkA5wDugPUA+gD/AQQBEYEogS8BPoFJ 

1111gVSBWoFgAWwBcoF1gX6BhQGJAZMBmgGiga0BuIHGgdUB2YHkAeiB8AH3AfyCAoIHAgqCDoITghcCG 

1112oIogjSCPoJKglYCXwJwgnqCgIKKApACl4Klgq8CtwLDAs8C1YLjAuyC9oL7gwMDCYMSAxgDKAMrAz 

1113qDQoNTA1mDYQNoA2uDcAN2g3oDfYODA4iDkoOXA5sDnoOnA7EDvwAAAAFAAAAAAH0ArwAAwAGAAkA 

1114DAAPAAAxESERAxMhExcRASELARETAfT6qv6syKr+jgFUqsiqArz9RAGLAP/+1P8B/v3VAP8BLP4CA 

1115P8AAgA5//IAuQKyAAMACwAANyMDMwIyFhQGIiY0oE4MZk84JCQ4JLQB/v3AJDgkJDgAAgBWAeUBPA 

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 

1161vArIACwAAJRUhESEVIRUhFSEVAi/+NQHB/pUBTf6zRkYCskbwRvAAAAABAGQAAAIlArIACQAAExUh 

1162FSERIxEhFboBQ/69VgHBAmzwRv7KArJGAAAAAAEAL//yAo8CwAAfAAABMxEjNQcGIyImNTQ2MzIWH 

1163wEjJyYjIgYVFBYzMjY1IwGP90wfPnWTprSSf48LAVYCIqJofHllVG+hAU3+s3hARsicn8uAagoKpq 

1164N/gaN1XAAAAAEAZAAAAowCsgALAAABESMRIREjETMRIRECjFb+hFZWAXwCsv1OAS7+0gKy/sQBPAA 

1165AAAABAGQAAAC6ArIAAwAAMyMRM7pWVgKyAAABADf/8gHoArIAEwAAAREUBw4BIyImLwEzFxYzMjc2 

1166NREB6AIFcGpgbQIBVgIHfXQKAQKy/lYxIltob2EpKYyEFD0BpwAAAAABAGQAAAJ0ArIACwAACQEjA 

1167wcVIxEzEQEzATsBJ3ntQlZWAVVlAWH+nwEnR+ACsv6RAW8AAQBkAAACLwKyAAUAACUVIREzEQIv/j 

1168VWRkYCsv2UAAABAGQAAAMUArIAFAAAAREjETQ3BgcDIwMmJxYVESMRMxsBAxRWAiMxemx8NxsCVo7 

1169MywKy/U4BY7ZLco7+nAFmoFxLtP6dArL9lwJpAAAAAAEAZAAAAoACsgANAAAhIwEWFREjETMBJjUR 

1170MwKAhP67A1aEAUUDVAJeeov+pwKy/aJ5jAFZAAAAAgAv//ICuwLAAAkAEwAAEiAWFRQGICY1NBIyN 

1171jU0JiIGFRTbATSsrP7MrNrYenrYegLAxaKhxsahov47nIeIm5uIhwACAGQAAAJHArIADgAYAAABHg 

1172EVFAYHBisBESMRMzITNjQnJisBETMyAZRUX2VOHzuAVtY7GlxcGDWIiDUCrgtnVlVpCgT+5gKy/rU 

1173V1BUF/vgAAAACAC//zAK9AsAAEgAcAAAlFhcHJiMiBwYjIiY1NDYgFhUUJRQWMjY1NCYiBgI9PUMx 

1174UDcfKh8omqysATSs/dR62Hp62HpICTg7NgkHxqGixcWitbWHnJyHiJubAAIAZAAAAlgCsgAXACMAA 

1175CUWFyMmJyYnJisBESMRMzIXHgEVFAYHFiUzMjc+ATU0JyYrAQIqDCJfGQwNWhAhglbiOx9QXEY1Tv 

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 

1251gQAAwABBAkADAAuAkwATgBvACAAUgBpAGcAaAB0AHMAIABSAGUAcwBlAHIAdgBlAGQALgAATm8gUm 

1252lnaHRzIFJlc2VydmVkLgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAUgBlAGcAdQBsAGEAcgAAUmV 

1253ndWxhcgAAMQAuADEAMAAyADsAVQBLAFcATgA7AEEAaQBsAGUAcgBvAG4ALQBSAGUAZwB1AGwAYQBy 

1254AAAxLjEwMjtVS1dOO0FpbGVyb24tUmVndWxhcgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAVgBlA 

1255HIAcwBpAG8AbgAgADEALgAxADAAMgA7AFAAUwAgADAAMAAxAC4AMQAwADIAOwBoAG8AdABjAG8Abg 

1256B2ACAAMQAuADAALgA3ADAAOwBtAGEAawBlAG8AdABmAC4AbABpAGIAMgAuADUALgA1ADgAMwAyADk 

1257AAFZlcnNpb24gMS4xMDI7UFMgMDAxLjEwMjtob3Rjb252IDEuMC43MDttYWtlb3RmLmxpYjIuNS41 

1258ODMyOQAAQQBpAGwAZQByAG8AbgAtAFIAZQBnAHUAbABhAHIAAEFpbGVyb24tUmVndWxhcgAAUwBvA 

1259HIAYQAgAFMAYQBnAGEAbgBvAABTb3JhIFNhZ2FubwAAUwBvAHIAYQAgAFMAYQBnAGEAbgBvAABTb3 

1260JhIFNhZ2FubwAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBsAG8AbgAuAG4AZQB0AAB 

1261odHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBs 

1262AG8AbgAuAG4AZQB0AABodHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAAAACAAAAAAAA/4MAMgAAAAAAA 

1263AAAAAAAAAAAAAAAAAAAAHQAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATAB 

1264QAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAA 

1265xADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0A 

1266TgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAIsAqQCDAJMAjQDDAKoAtgC3A 

1267LQAtQCrAL4AvwC8AIwAwADBAAAAAAAB//8AAgABAAAADAAAABwAAAACAAIAAwBxAAEAcgBzAAIABA 

1268AAAAIAAAABAAAACgBMAGYAAkRGTFQADmxhdG4AGgAEAAAAAP//AAEAAAAWAANDQVQgAB5NT0wgABZ 

1269ST00gABYAAP//AAEAAAAA//8AAgAAAAEAAmxpZ2EADmxvY2wAFAAAAAEAAQAAAAEAAAACAAYAEAAG 

1270AAAAAgASADQABAAAAAEATAADAAAAAgAQABYAAQAcAAAAAQABAE8AAQABAGcAAQABAE8AAwAAAAIAE 

1271AAWAAEAHAAAAAEAAQAvAAEAAQBnAAEAAQAvAAEAGgABAAgAAgAGAAwAcwACAE8AcgACAEwAAQABAE 

1272kAAAABAAAACgBGAGAAAkRGTFQADmxhdG4AHAAEAAAAAP//AAIAAAABABYAA0NBVCAAFk1PTCAAFlJ 

1273PTSAAFgAA//8AAgAAAAEAAmNwc3AADmtlcm4AFAAAAAEAAAAAAAEAAQACAAYADgABAAAAAQASAAIA 

1274AAACAB4ANgABAAoABQAFAAoAAgABACQAPQAAAAEAEgAEAAAAAQAMAAEAOP/nAAEAAQAkAAIGigAEA 

1275AAFJAXKABoAGQAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

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

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

1278ABD/vQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7gAAAAAAAAAAAAAAAAAA//MAA 

1279AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAP/5AAAAAAAAAA 

1280AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gAAD/4AAAAAAAAAAAAAAAAAA 

1281AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//L/9AAAAAAAAAAAAAAAAAAAAAAA 

1282AAAAAAAAAAAA/+gAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1283AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAAAAA 

1284AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/mAAAAAAAAAAAAAAAAAAD 

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

1286AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zv/qAAAAAP/0AAAACAAAAAAAAAAAAAAAAAAAAAAAA 

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

1288AAAAAAAAAAAAAAAAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

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

1290AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+AAAAAAAAAAAAAAA 

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

1292AAAAAAAAAAAAAAAAAAAAAAAAAAAAD/yAAA/+kAAAAA//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1293AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9wAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1294AAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1295AAAAAAAAP/cAAAAAAAAAAAAAAAA/7YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1296AAAAAAAAAAAAAAAAAAAAAAAAAAAP/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6AAAAAAAAAA 

1297AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAkAFAAEAAAAAQACwAAABcA 

1298BgAAAAAAAAAIAA4AAAAAAAsAEgAAAAAAAAATABkAAwANAAAAAQAJAAAAAAAAAAAAAAAAAAAAGAAAA 

1299AAABwAAAAAAAAAAAAAAFQAFAAAAAAAYABgAAAAUAAAACgAAAAwAAgAPABEAFgAAAAAAAAAAAAAAAA 

1300AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAEAEQBdAAYAAAAAAAAAAAAAAAAAAAAAAAA 

1301AAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAcAAAAAAAAABwAAAAAACAAAAAAAAAAAAAcAAAAHAAAAEwAJ 

1302ABUADgAPAAAACwAQAAAAAAAAAAAAAAAAAAUAGAACAAIAAgAAAAIAGAAXAAAAGAAAABYAFgACABYAA 

1303gAWAAAAEQADAAoAFAAMAA0ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAEgAGAAEAHgAkAC 

1304YAJwApACoALQAuAC8AMgAzADcAOAA5ADoAPAA9AEUASABOAE8AUgBTAFUAVwBZAFoAWwBcAF0AcwA 

1305AAAAAAQAAAADa3tfFAAAAANAan9kAAAAA4QodoQ== 

1306""" 

1307 ) 

1308 ), 

1309 10 if size is None else size, 

1310 layout_engine=Layout.BASIC, 

1311 ) 

1312 return load_default_imagefont()