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

269 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 image.load() 

153 

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

155 

156 def getmask( 

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

158 ) -> Image.core.ImagingCore: 

159 """ 

160 Create a bitmap for the text. 

161 

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

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

164 

165 :param text: Text to render. 

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

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

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

169 C-level implementations. 

170 

171 .. versionadded:: 1.1.5 

172 

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

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

175 """ 

176 _string_length_check(text) 

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

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

179 

180 def getbbox( 

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

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

183 """ 

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

185 

186 .. versionadded:: 9.2.0 

187 

188 :param text: Text to render. 

189 

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

191 """ 

192 _string_length_check(text) 

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

194 return 0, 0, width, height 

195 

196 def getlength( 

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

198 ) -> int: 

199 """ 

200 Returns length (in pixels) of given text. 

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

202 

203 .. versionadded:: 9.2.0 

204 """ 

205 _string_length_check(text) 

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

207 return width 

208 

209 

210## 

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

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

213 

214 

215class FreeTypeFont: 

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

217 

218 font: Font 

219 font_bytes: bytes 

220 

221 def __init__( 

222 self, 

223 font: StrOrBytesPath | BinaryIO, 

224 size: float = 10, 

225 index: int = 0, 

226 encoding: str = "", 

227 layout_engine: Layout | None = None, 

228 ) -> None: 

229 # FIXME: use service provider instead 

230 

231 if isinstance(core, DeferredError): 

232 raise core.ex 

233 

234 if size <= 0: 

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

236 raise ValueError(msg) 

237 

238 self.path = font 

239 self.size = size 

240 self.index = index 

241 self.encoding = encoding 

242 

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

244 layout_engine = Layout.BASIC 

245 if core.HAVE_RAQM: 

246 layout_engine = Layout.RAQM 

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

248 warnings.warn( 

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

250 "Falling back to basic layout." 

251 ) 

252 layout_engine = Layout.BASIC 

253 

254 self.layout_engine = layout_engine 

255 

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

257 self.font_bytes = f.read() 

258 self.font = core.getfont( 

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

260 ) 

261 

262 if is_path(font): 

263 font = os.fspath(font) 

264 if sys.platform == "win32": 

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

266 try: 

267 font_bytes_path.decode("ascii") 

268 except UnicodeDecodeError: 

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

270 # So load it into memory first 

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

272 load_from_bytes(f) 

273 return 

274 self.font = core.getfont( 

275 font, size, index, encoding, layout_engine=layout_engine 

276 ) 

277 else: 

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

279 

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

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

282 

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

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

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

286 

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

288 """ 

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

290 (e.g. Bold) 

291 """ 

292 return self.font.family, self.font.style 

293 

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

295 """ 

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

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

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

299 """ 

300 return self.font.ascent, self.font.descent 

301 

302 def getlength( 

303 self, 

304 text: str | bytes, 

305 mode: str = "", 

306 direction: str | None = None, 

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

308 language: str | None = None, 

309 ) -> float: 

310 """ 

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

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

313 

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

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

316 e.g. when using italics or accents. 

317 

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

319 

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

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

322 character and subtract its length. 

323 

324 For example, instead of :: 

325 

326 hello = font.getlength("Hello") 

327 world = font.getlength("World") 

328 hello_world = hello + world # not adjusted for kerning 

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

330 

331 use :: 

332 

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

334 world = font.getlength("World") 

335 hello_world = hello + world # adjusted for kerning 

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

337 

338 or disable kerning with (requires libraqm) :: 

339 

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

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

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

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

344 

345 .. versionadded:: 8.0.0 

346 

347 :param text: Text to measure. 

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

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

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

351 C-level implementations. 

352 

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

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

355 Requires libraqm. 

356 

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

358 layout. This is usually used to turn on optional 

359 font features that are not enabled by default, 

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

361 used to turn off default font features for 

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

363 to disable kerning. To get all supported 

364 features, see 

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

366 Requires libraqm. 

367 

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

369 different glyph shapes or ligatures. This parameter tells 

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

371 correct substitutions as appropriate, if available. 

372 It should be a `BCP 47 language code 

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

374 Requires libraqm. 

375 

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

377 """ 

378 _string_length_check(text) 

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

380 

381 def getbbox( 

382 self, 

383 text: str | bytes, 

384 mode: str = "", 

385 direction: str | None = None, 

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

387 language: str | None = None, 

388 stroke_width: float = 0, 

389 anchor: str | None = None, 

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

391 """ 

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

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

394 

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

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

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

398 

399 .. versionadded:: 8.0.0 

400 

401 :param text: Text to render. 

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

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

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

405 C-level implementations. 

406 

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

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

409 Requires libraqm. 

410 

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

412 layout. This is usually used to turn on optional 

413 font features that are not enabled by default, 

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

415 used to turn off default font features for 

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

417 to disable kerning. To get all supported 

418 features, see 

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

420 Requires libraqm. 

421 

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

423 different glyph shapes or ligatures. This parameter tells 

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

425 correct substitutions as appropriate, if available. 

426 It should be a `BCP 47 language code 

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

428 Requires libraqm. 

429 

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

431 

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

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

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

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

436 

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

438 """ 

439 _string_length_check(text) 

440 size, offset = self.font.getsize( 

441 text, mode, direction, features, language, anchor 

442 ) 

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

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

445 return left, top, left + width, top + height 

446 

447 def getmask( 

448 self, 

449 text: str | bytes, 

450 mode: str = "", 

451 direction: str | None = None, 

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

453 language: str | None = None, 

454 stroke_width: float = 0, 

455 anchor: str | None = None, 

456 ink: int = 0, 

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

458 ) -> Image.core.ImagingCore: 

459 """ 

460 Create a bitmap for the text. 

461 

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

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

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

465 

466 :param text: Text to render. 

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

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

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

470 C-level implementations. 

471 

472 .. versionadded:: 1.1.5 

473 

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

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

476 Requires libraqm. 

477 

478 .. versionadded:: 4.2.0 

479 

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

481 layout. This is usually used to turn on optional 

482 font features that are not enabled by default, 

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

484 used to turn off default font features for 

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

486 to disable kerning. To get all supported 

487 features, see 

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

489 Requires libraqm. 

490 

491 .. versionadded:: 4.2.0 

492 

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

494 different glyph shapes or ligatures. This parameter tells 

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

496 correct substitutions as appropriate, if available. 

497 It should be a `BCP 47 language code 

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

499 Requires libraqm. 

500 

501 .. versionadded:: 6.0.0 

502 

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

504 

505 .. versionadded:: 6.2.0 

506 

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

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

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

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

511 

512 .. versionadded:: 8.0.0 

513 

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

515 

516 .. versionadded:: 8.0.0 

517 

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

519 differently when starting at fractional coordinates. 

520 

521 .. versionadded:: 9.4.0 

522 

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

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

525 """ 

526 return self.getmask2( 

527 text, 

528 mode, 

529 direction=direction, 

530 features=features, 

531 language=language, 

532 stroke_width=stroke_width, 

533 anchor=anchor, 

534 ink=ink, 

535 start=start, 

536 )[0] 

537 

538 def getmask2( 

539 self, 

540 text: str | bytes, 

541 mode: str = "", 

542 direction: str | None = None, 

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

544 language: str | None = None, 

545 stroke_width: float = 0, 

546 anchor: str | None = None, 

547 ink: int = 0, 

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

549 *args: Any, 

550 **kwargs: Any, 

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

552 """ 

553 Create a bitmap for the text. 

554 

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

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

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

558 

559 :param text: Text to render. 

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

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

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

563 C-level implementations. 

564 

565 .. versionadded:: 1.1.5 

566 

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

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

569 Requires libraqm. 

570 

571 .. versionadded:: 4.2.0 

572 

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

574 layout. This is usually used to turn on optional 

575 font features that are not enabled by default, 

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

577 used to turn off default font features for 

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

579 to disable kerning. To get all supported 

580 features, see 

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

582 Requires libraqm. 

583 

584 .. versionadded:: 4.2.0 

585 

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

587 different glyph shapes or ligatures. This parameter tells 

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

589 correct substitutions as appropriate, if available. 

590 It should be a `BCP 47 language code 

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

592 Requires libraqm. 

593 

594 .. versionadded:: 6.0.0 

595 

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

597 

598 .. versionadded:: 6.2.0 

599 

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

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

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

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

604 

605 .. versionadded:: 8.0.0 

606 

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

608 

609 .. versionadded:: 8.0.0 

610 

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

612 differently when starting at fractional coordinates. 

613 

614 .. versionadded:: 9.4.0 

615 

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

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

618 gap between the starting coordinate and the first marking 

619 """ 

620 _string_length_check(text) 

621 if start is None: 

622 start = (0, 0) 

623 

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

625 size = (width, height) 

626 Image._decompression_bomb_check(size) 

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

628 

629 return self.font.render( 

630 text, 

631 fill, 

632 mode, 

633 direction, 

634 features, 

635 language, 

636 stroke_width, 

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

638 anchor, 

639 ink, 

640 start, 

641 ) 

642 

643 def font_variant( 

644 self, 

645 font: StrOrBytesPath | BinaryIO | None = None, 

646 size: float | None = None, 

647 index: int | None = None, 

648 encoding: str | None = None, 

649 layout_engine: Layout | None = None, 

650 ) -> FreeTypeFont: 

651 """ 

652 Create a copy of this FreeTypeFont object, 

653 using any specified arguments to override the settings. 

654 

655 Parameters are identical to the parameters used to initialize this 

656 object. 

657 

658 :return: A FreeTypeFont object. 

659 """ 

660 if font is None: 

661 try: 

662 font = BytesIO(self.font_bytes) 

663 except AttributeError: 

664 font = self.path 

665 return FreeTypeFont( 

666 font=font, 

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

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

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

670 layout_engine=layout_engine or self.layout_engine, 

671 ) 

672 

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

674 """ 

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

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

677 """ 

678 names = self.font.getvarnames() 

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

680 

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

682 """ 

683 :param name: The name of the style. 

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

685 """ 

686 names = self.get_variation_names() 

687 if not isinstance(name, bytes): 

688 name = name.encode() 

689 index = names.index(name) + 1 

690 

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

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

693 # there is an 'unknown freetype error' 

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

695 return 

696 self._last_variation_index = index 

697 

698 self.font.setvarname(index) 

699 

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

701 """ 

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

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

704 """ 

705 axes = self.font.getvaraxes() 

706 for axis in axes: 

707 if axis["name"]: 

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

709 return axes 

710 

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

712 """ 

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

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

715 """ 

716 self.font.setvaraxes(axes) 

717 

718 

719class TransposedFont: 

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

721 

722 def __init__( 

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

724 ): 

725 """ 

726 Wrapper that creates a transposed font from any existing font 

727 object. 

728 

729 :param font: A font object. 

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

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

732 Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_180, or 

733 Image.Transpose.ROTATE_270. 

734 """ 

735 self.font = font 

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

737 

738 def getmask( 

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

740 ) -> Image.core.ImagingCore: 

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

742 if self.orientation is not None: 

743 return im.transpose(self.orientation) 

744 return im 

745 

746 def getbbox( 

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

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

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

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

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

752 width = right - left 

753 height = bottom - top 

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

755 return 0, 0, height, width 

756 return 0, 0, width, height 

757 

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

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

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

761 raise ValueError(msg) 

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

763 

764 

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

766 """ 

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

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

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

770 

771 :param filename: Name of font file. 

772 :return: A font object. 

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

774 """ 

775 f = ImageFont() 

776 f._load_pilfont(filename) 

777 return f 

778 

779 

780def truetype( 

781 font: StrOrBytesPath | BinaryIO, 

782 size: float = 10, 

783 index: int = 0, 

784 encoding: str = "", 

785 layout_engine: Layout | None = None, 

786) -> FreeTypeFont: 

787 """ 

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

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

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

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

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

793 

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

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

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

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

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

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

800 

801 This function requires the _imagingft service. 

802 

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

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

805 search in other directories, such as: 

806 

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

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

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

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

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

812 the ``XDG_DATA_HOME`` and ``XDG_DATA_DIRS`` environment variables 

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

814 

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

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

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

818 encodings include (see the FreeType documentation for more 

819 information): 

820 

821 * "unic" (Unicode) 

822 * "symb" (Microsoft Symbol) 

823 * "ADOB" (Adobe Standard) 

824 * "ADBE" (Adobe Expert) 

825 * "ADBC" (Adobe Custom) 

826 * "armn" (Apple Roman) 

827 * "sjis" (Shift JIS) 

828 * "gb " (PRC) 

829 * "big5" 

830 * "wans" (Extended Wansung) 

831 * "joha" (Johab) 

832 * "lat1" (Latin-1) 

833 

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

835 encoding of any text provided in subsequent operations. 

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

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

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

839 Otherwise, basic layout will be used. 

840 

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

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

843 

844 You can check support for Raqm layout using 

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

846 

847 .. versionadded:: 4.2.0 

848 :return: A font object. 

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

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

851 """ 

852 

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

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

855 

856 try: 

857 return freetype(font) 

858 except OSError: 

859 if not is_path(font): 

860 raise 

861 ttf_filename = os.path.basename(font) 

862 

863 dirs = [] 

864 if sys.platform == "win32": 

865 # check the windows font repository 

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

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

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

869 if windir: 

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

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

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

873 if not data_home: 

874 # The freedesktop spec defines the following default directory for 

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

876 # takes precedence over system-level directories. 

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

878 xdg_dirs = [data_home] 

879 

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

881 if not data_dirs: 

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

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

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

885 

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

887 elif sys.platform == "darwin": 

888 dirs += [ 

889 "/Library/Fonts", 

890 "/System/Library/Fonts", 

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

892 ] 

893 

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

895 first_font_with_a_different_extension = None 

896 for directory in dirs: 

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

898 for walkfilename in walkfilenames: 

899 if ext and walkfilename == ttf_filename: 

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

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

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

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

904 return freetype(fontpath) 

905 if not ext and first_font_with_a_different_extension is None: 

906 first_font_with_a_different_extension = fontpath 

907 if first_font_with_a_different_extension: 

908 return freetype(first_font_with_a_different_extension) 

909 raise 

910 

911 

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

913 """ 

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

915 bitmap font along the Python path. 

916 

917 :param filename: Name of font file. 

918 :return: A font object. 

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

920 """ 

921 if not isinstance(filename, str): 

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

923 for directory in sys.path: 

924 try: 

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

926 except OSError: 

927 pass 

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

929 if os.path.exists(filename): 

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

931 

932 raise OSError(msg) 

933 

934 

935def load_default_imagefont() -> ImageFont: 

936 f = ImageFont() 

937 f._load_pilfont_data( 

938 # courB08 

939 BytesIO( 

940 base64.b64decode( 

941 b""" 

942UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

943AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

944AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

945AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

946AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

947AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

948AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

949AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

950AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

951AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

952AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

953AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA 

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

955AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA 

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

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

958BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB 

959//kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA 

960AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH 

961AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA 

962ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv 

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

964/gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5 

965AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA 

966AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG 

967AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA 

968BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA 

969AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA 

9702AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF 

971AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA//// 

972+gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA 

973////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA 

974BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv 

975AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA 

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

977AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA 

978BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP// 

979//kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA 

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

981AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB 

982mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn 

983AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA 

984AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7 

985AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA 

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

987AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

988AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

989AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

990AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

991AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

992AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

993AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

994AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

995AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

996AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

997AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

998AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB 

999//sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA 

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

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

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

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

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

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

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

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

1008BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA 

1009Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC 

1010eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG 

1011AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA//// 

1012+gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA 

1013////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA 

1014BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT 

1015AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A 

1016AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA 

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

1018Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP// 

1019//cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA 

1020AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ 

1021AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA 

1022LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5 

1023AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA 

1024AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5 

1025AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA 

1026AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG 

1027AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA 

1028EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK 

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

1030pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG 

1031AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA//// 

1032+QAGAAIAzgAKANUAEw== 

1033""" 

1034 ) 

1035 ), 

1036 Image.open( 

1037 BytesIO( 

1038 base64.b64decode( 

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

1066 ), 

1067 ) 

1068 return f 

1069 

1070 

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

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

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

1074 

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

1076 

1077 .. versionadded:: 1.1.4 

1078 

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

1080 

1081 .. versionadded:: 10.1.0 

1082 

1083 :return: A font object. 

1084 """ 

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

1086 return truetype( 

1087 BytesIO( 

1088 base64.b64decode( 

1089 b""" 

1090AAEAAAAPAIAAAwBwRkZUTYwDlUAAADFoAAAAHEdERUYAqADnAAAo8AAAACRHUE9ThhmITwAAKfgAA 

1091AduR1NVQnHxefoAACkUAAAA4k9TLzJovoHLAAABeAAAAGBjbWFw5lFQMQAAA6gAAAGqZ2FzcP//AA 

1092MAACjoAAAACGdseWYmRXoPAAAGQAAAHfhoZWFkE18ayQAAAPwAAAA2aGhlYQboArEAAAE0AAAAJGh 

1093tdHjjERZ8AAAB2AAAAdBsb2NhuOexrgAABVQAAADqbWF4cAC7AEYAAAFYAAAAIG5hbWUr+h5lAAAk 

1094OAAAA6Jwb3N0D3oPTQAAJ9wAAAEKAAEAAAABGhxJDqIhXw889QALA+gAAAAA0Bqf2QAAAADhCh2h/ 

10952r/LgOxAyAAAAAIAAIAAAAAAAAAAQAAA8r/GgAAA7j/av9qA7EAAQAAAAAAAAAAAAAAAAAAAHQAAQ 

1096AAAHQAQwAFAAAAAAACAAAAAQABAAAAQAAAAAAAAAADAfoBkAAFAAgCigJYAAAASwKKAlgAAAFeADI 

1097BPgAAAAAFAAAAAAAAAAAAAAcAAAAAAAAAAAAAAABVS1dOAEAAIPsCAwL/GgDIA8oA5iAAAJMAAAAA 

1098AhICsgAAACAAAwH0AAAAAAAAAU0AAADYAAAA8gA5AVMAVgJEAEYCRAA1AuQAKQKOAEAAsAArATsAZ 

1099AE7AB4CMABVAkQAUADc/+EBEgAgANwAJQEv//sCRAApAkQAggJEADwCRAAtAkQAIQJEADkCRAArAk 

1100QAMgJEACwCRAAxANwAJQDc/+ECRABnAkQAUAJEAEQB8wAjA1QANgJ/AB0CcwBkArsALwLFAGQCSwB 

1101kAjcAZALGAC8C2gBkAQgAZAIgADcCYQBkAj8AZANiAGQCzgBkAuEALwJWAGQC3QAvAmsAZAJJADQC 

1102ZAAiAqoAXgJuACADuAAaAnEAGQJFABMCTwAuATMAYgEv//sBJwAiAkQAUAH0ADIBLAApAhMAJAJjA 

1103EoCEQAeAmcAHgIlAB4BIgAVAmcAHgJRAEoA7gA+AOn/8wIKAEoA9wBGA1cASgJRAEoCSgAeAmMASg 

1104JnAB4BSgBKAcsAGAE5ABQCUABCAgIAAQMRAAEB4v/6AgEAAQHOABQBLwBAAPoAYAEvACECRABNA0Y 

1105AJAItAHgBKgAcAkQAUAEsAHQAygAgAi0AOQD3ADYA9wAWAaEANgGhABYCbAAlAYMAeAGDADkA6/9q 

1106AhsAFAIKABUB/QAVAAAAAwAAAAMAAAAcAAEAAAAAAKQAAwABAAAAHAAEAIgAAAAeABAAAwAOAH4Aq 

1107QCrALEAtAC3ALsgGSAdICYgOiBEISL7Av//AAAAIACpAKsAsAC0ALcAuyAYIBwgJiA5IEQhIvsB// 

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

1109AAAAAAAEGAAABAAAAAAAAAAECAAAAAgAAAAAAAAAAAAAAAAAAAAEAAAMEBQYHCAkKCwwNDg8QERIT 

1110FBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMT 

1111U5PUFFSU1RVVldYWVpbXF1eX2BhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQAAA 

1112AAAAAAYnFmAAAAAABlAAAAAAAAAAAAAAAAAAAAAAAAAAAAY2htAAAAAAAAAABrbGlqAAAAAHAAbm9 

1113ycwBnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmACYAJgAmAD4AUgCCAMoBCgFO 

1114AVwBcgGIAaYBvAHKAdYB6AH2AgwCIAJKAogCpgLWAw4DIgNkA5wDugPUA+gD/AQQBEYEogS8BPoFJ 

1115gVSBWoFgAWwBcoF1gX6BhQGJAZMBmgGiga0BuIHGgdUB2YHkAeiB8AH3AfyCAoIHAgqCDoITghcCG 

1116oIogjSCPoJKglYCXwJwgnqCgIKKApACl4Klgq8CtwLDAs8C1YLjAuyC9oL7gwMDCYMSAxgDKAMrAz 

1117qDQoNTA1mDYQNoA2uDcAN2g3oDfYODA4iDkoOXA5sDnoOnA7EDvwAAAAFAAAAAAH0ArwAAwAGAAkA 

1118DAAPAAAxESERAxMhExcRASELARETAfT6qv6syKr+jgFUqsiqArz9RAGLAP/+1P8B/v3VAP8BLP4CA 

1119P8AAgA5//IAuQKyAAMACwAANyMDMwIyFhQGIiY0oE4MZk84JCQ4JLQB/v3AJDgkJDgAAgBWAeUBPA 

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 

1165vArIACwAAJRUhESEVIRUhFSEVAi/+NQHB/pUBTf6zRkYCskbwRvAAAAABAGQAAAIlArIACQAAExUh 

1166FSERIxEhFboBQ/69VgHBAmzwRv7KArJGAAAAAAEAL//yAo8CwAAfAAABMxEjNQcGIyImNTQ2MzIWH 

1167wEjJyYjIgYVFBYzMjY1IwGP90wfPnWTprSSf48LAVYCIqJofHllVG+hAU3+s3hARsicn8uAagoKpq 

1168N/gaN1XAAAAAEAZAAAAowCsgALAAABESMRIREjETMRIRECjFb+hFZWAXwCsv1OAS7+0gKy/sQBPAA 

1169AAAABAGQAAAC6ArIAAwAAMyMRM7pWVgKyAAABADf/8gHoArIAEwAAAREUBw4BIyImLwEzFxYzMjc2 

1170NREB6AIFcGpgbQIBVgIHfXQKAQKy/lYxIltob2EpKYyEFD0BpwAAAAABAGQAAAJ0ArIACwAACQEjA 

1171wcVIxEzEQEzATsBJ3ntQlZWAVVlAWH+nwEnR+ACsv6RAW8AAQBkAAACLwKyAAUAACUVIREzEQIv/j 

1172VWRkYCsv2UAAABAGQAAAMUArIAFAAAAREjETQ3BgcDIwMmJxYVESMRMxsBAxRWAiMxemx8NxsCVo7 

1173MywKy/U4BY7ZLco7+nAFmoFxLtP6dArL9lwJpAAAAAAEAZAAAAoACsgANAAAhIwEWFREjETMBJjUR 

1174MwKAhP67A1aEAUUDVAJeeov+pwKy/aJ5jAFZAAAAAgAv//ICuwLAAAkAEwAAEiAWFRQGICY1NBIyN 

1175jU0JiIGFRTbATSsrP7MrNrYenrYegLAxaKhxsahov47nIeIm5uIhwACAGQAAAJHArIADgAYAAABHg 

1176EVFAYHBisBESMRMzITNjQnJisBETMyAZRUX2VOHzuAVtY7GlxcGDWIiDUCrgtnVlVpCgT+5gKy/rU 

1177V1BUF/vgAAAACAC//zAK9AsAAEgAcAAAlFhcHJiMiBwYjIiY1NDYgFhUUJRQWMjY1NCYiBgI9PUMx 

1178UDcfKh8omqysATSs/dR62Hp62HpICTg7NgkHxqGixcWitbWHnJyHiJubAAIAZAAAAlgCsgAXACMAA 

1179CUWFyMmJyYnJisBESMRMzIXHgEVFAYHFiUzMjc+ATU0JyYrAQIqDCJfGQwNWhAhglbiOx9QXEY1Tv 

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 

1255gQAAwABBAkADAAuAkwATgBvACAAUgBpAGcAaAB0AHMAIABSAGUAcwBlAHIAdgBlAGQALgAATm8gUm 

1256lnaHRzIFJlc2VydmVkLgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAUgBlAGcAdQBsAGEAcgAAUmV 

1257ndWxhcgAAMQAuADEAMAAyADsAVQBLAFcATgA7AEEAaQBsAGUAcgBvAG4ALQBSAGUAZwB1AGwAYQBy 

1258AAAxLjEwMjtVS1dOO0FpbGVyb24tUmVndWxhcgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAVgBlA 

1259HIAcwBpAG8AbgAgADEALgAxADAAMgA7AFAAUwAgADAAMAAxAC4AMQAwADIAOwBoAG8AdABjAG8Abg 

1260B2ACAAMQAuADAALgA3ADAAOwBtAGEAawBlAG8AdABmAC4AbABpAGIAMgAuADUALgA1ADgAMwAyADk 

1261AAFZlcnNpb24gMS4xMDI7UFMgMDAxLjEwMjtob3Rjb252IDEuMC43MDttYWtlb3RmLmxpYjIuNS41 

1262ODMyOQAAQQBpAGwAZQByAG8AbgAtAFIAZQBnAHUAbABhAHIAAEFpbGVyb24tUmVndWxhcgAAUwBvA 

1263HIAYQAgAFMAYQBnAGEAbgBvAABTb3JhIFNhZ2FubwAAUwBvAHIAYQAgAFMAYQBnAGEAbgBvAABTb3 

1264JhIFNhZ2FubwAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBsAG8AbgAuAG4AZQB0AAB 

1265odHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBs 

1266AG8AbgAuAG4AZQB0AABodHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAAAACAAAAAAAA/4MAMgAAAAAAA 

1267AAAAAAAAAAAAAAAAAAAAHQAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATAB 

1268QAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAA 

1269xADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0A 

1270TgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAIsAqQCDAJMAjQDDAKoAtgC3A 

1271LQAtQCrAL4AvwC8AIwAwADBAAAAAAAB//8AAgABAAAADAAAABwAAAACAAIAAwBxAAEAcgBzAAIABA 

1272AAAAIAAAABAAAACgBMAGYAAkRGTFQADmxhdG4AGgAEAAAAAP//AAEAAAAWAANDQVQgAB5NT0wgABZ 

1273ST00gABYAAP//AAEAAAAA//8AAgAAAAEAAmxpZ2EADmxvY2wAFAAAAAEAAQAAAAEAAAACAAYAEAAG 

1274AAAAAgASADQABAAAAAEATAADAAAAAgAQABYAAQAcAAAAAQABAE8AAQABAGcAAQABAE8AAwAAAAIAE 

1275AAWAAEAHAAAAAEAAQAvAAEAAQBnAAEAAQAvAAEAGgABAAgAAgAGAAwAcwACAE8AcgACAEwAAQABAE 

1276kAAAABAAAACgBGAGAAAkRGTFQADmxhdG4AHAAEAAAAAP//AAIAAAABABYAA0NBVCAAFk1PTCAAFlJ 

1277PTSAAFgAA//8AAgAAAAEAAmNwc3AADmtlcm4AFAAAAAEAAAAAAAEAAQACAAYADgABAAAAAQASAAIA 

1278AAACAB4ANgABAAoABQAFAAoAAgABACQAPQAAAAEAEgAEAAAAAQAMAAEAOP/nAAEAAQAkAAIGigAEA 

1279AAFJAXKABoAGQAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

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

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

1282ABD/vQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7gAAAAAAAAAAAAAAAAAA//MAA 

1283AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAP/5AAAAAAAAAA 

1284AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gAAD/4AAAAAAAAAAAAAAAAAA 

1285AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//L/9AAAAAAAAAAAAAAAAAAAAAAA 

1286AAAAAAAAAAAA/+gAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1287AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAAAAA 

1288AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/mAAAAAAAAAAAAAAAAAAD 

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

1290AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zv/qAAAAAP/0AAAACAAAAAAAAAAAAAAAAAAAAAAAA 

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

1292AAAAAAAAAAAAAAAAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

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

1294AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+AAAAAAAAAAAAAAA 

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

1296AAAAAAAAAAAAAAAAAAAAAAAAAAAAD/yAAA/+kAAAAA//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1297AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9wAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1298AAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1299AAAAAAAAP/cAAAAAAAAAAAAAAAA/7YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1300AAAAAAAAAAAAAAAAAAAAAAAAAAAP/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6AAAAAAAAAA 

1301AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAkAFAAEAAAAAQACwAAABcA 

1302BgAAAAAAAAAIAA4AAAAAAAsAEgAAAAAAAAATABkAAwANAAAAAQAJAAAAAAAAAAAAAAAAAAAAGAAAA 

1303AAABwAAAAAAAAAAAAAAFQAFAAAAAAAYABgAAAAUAAAACgAAAAwAAgAPABEAFgAAAAAAAAAAAAAAAA 

1304AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAEAEQBdAAYAAAAAAAAAAAAAAAAAAAAAAAA 

1305AAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAcAAAAAAAAABwAAAAAACAAAAAAAAAAAAAcAAAAHAAAAEwAJ 

1306ABUADgAPAAAACwAQAAAAAAAAAAAAAAAAAAUAGAACAAIAAgAAAAIAGAAXAAAAGAAAABYAFgACABYAA 

1307gAWAAAAEQADAAoAFAAMAA0ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAEgAGAAEAHgAkAC 

1308YAJwApACoALQAuAC8AMgAzADcAOAA5ADoAPAA9AEUASABOAE8AUgBTAFUAVwBZAFoAWwBcAF0AcwA 

1309AAAAAAQAAAADa3tfFAAAAANAan9kAAAAA4QodoQ== 

1310""" 

1311 ) 

1312 ), 

1313 10 if size is None else size, 

1314 layout_engine=Layout.BASIC, 

1315 ) 

1316 return load_default_imagefont()