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

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

288 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 

30__lazy_modules__ = {"base64", "io", "types", "warnings"} 

31 

32import abc 

33import base64 

34import os 

35import sys 

36import warnings 

37from enum import IntEnum 

38from io import BytesIO 

39from types import ModuleType 

40from typing import TypedDict, cast 

41 

42from . import Image 

43from ._util import DeferredError, is_path 

44 

45TYPE_CHECKING = False 

46if TYPE_CHECKING: 

47 from typing import IO, Any, BinaryIO, NotRequired 

48 

49 from . import ImageFile 

50 from ._imaging import ImagingFont 

51 from ._imagingft import Font 

52 from ._typing import StrOrBytesPath 

53 

54 

55class Axis(TypedDict): 

56 minimum: int | None 

57 default: int | None 

58 maximum: int | None 

59 name: NotRequired[bytes] 

60 

61 

62class Layout(IntEnum): 

63 BASIC = 0 

64 RAQM = 1 

65 

66 

67MAX_STRING_LENGTH = 1_000_000 

68 

69 

70core: ModuleType | DeferredError 

71try: 

72 from . import _imagingft as core 

73except ImportError as ex: 

74 core = DeferredError.new(ex) 

75 

76 

77def _string_length_check(text: str | bytes | bytearray) -> None: 

78 if MAX_STRING_LENGTH is not None and len(text) > MAX_STRING_LENGTH: 

79 msg = "too many characters in string" 

80 raise ValueError(msg) 

81 

82 

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

84 

85# -------------------------------------------------------------------- 

86# Font metrics format: 

87# "PILfont" LF 

88# fontdescriptor LF 

89# (optional) key=value... LF 

90# "DATA" LF 

91# binary data: 256*10*2 bytes (dx, dy, dstbox, srcbox) 

92# 

93# To place a character, cut out srcbox and paste at dstbox, 

94# relative to the character position. Then move the character 

95# position according to dx, dy. 

96# -------------------------------------------------------------------- 

97 

98 

99class BaseImageFont(abc.ABC): 

100 """Used by ImageDraw and ImageText""" 

101 

102 @abc.abstractmethod 

103 def getbbox( 

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

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

106 pass 

107 

108 @abc.abstractmethod 

109 def getmask( 

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

111 ) -> Image.core.ImagingCore: 

112 pass 

113 

114 @abc.abstractmethod 

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

116 pass 

117 

118 

119class ImageFont(BaseImageFont): 

120 """PIL font wrapper""" 

121 

122 font: ImagingFont 

123 

124 def _load_pilfont(self, filename: str) -> None: 

125 with open(filename, "rb") as fp: 

126 image: ImageFile.ImageFile | None = None 

127 root = os.path.splitext(filename)[0] 

128 

129 for ext in (".png", ".gif", ".pbm"): 

130 if image: 

131 image.close() 

132 try: 

133 fullname = root + ext 

134 image = Image.open(fullname) 

135 except Exception: 

136 pass 

137 else: 

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

139 break 

140 else: 

141 if image: 

142 image.close() 

143 

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

145 raise OSError(msg) 

146 

147 self.file = fullname 

148 

149 self._load_pilfont_data(fp, image) 

150 image.close() 

151 

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

153 # check image 

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

155 image.close() 

156 

157 msg = "invalid font image mode" 

158 raise TypeError(msg) 

159 

160 # read PILfont header 

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

162 image.close() 

163 

164 msg = "Not a PILfont file" 

165 raise SyntaxError(msg) 

166 file.readline() 

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

168 while True: 

169 s = file.readline() 

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

171 break 

172 self.info.append(s) 

173 

174 # read PILfont metrics 

175 data = file.read(256 * 20) 

176 

177 self._load(image, data) 

178 

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

180 image.load() 

181 

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

183 

184 def getmask( 

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

186 ) -> Image.core.ImagingCore: 

187 """ 

188 Create a bitmap for the text. 

189 

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

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

192 

193 :param text: Text to render. 

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

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

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

197 C-level implementations. 

198 

199 .. versionadded:: 1.1.5 

200 

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

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

203 """ 

204 _string_length_check(text) 

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

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

207 

208 def getbbox( 

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

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

211 """ 

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

213 

214 .. versionadded:: 9.2.0 

215 

216 :param text: Text to render. 

217 

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

219 """ 

220 _string_length_check(text) 

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

222 return 0, 0, width, height 

223 

224 def getlength( 

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

226 ) -> int: 

227 """ 

228 Returns length (in pixels) of given text. 

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

230 

231 .. versionadded:: 9.2.0 

232 """ 

233 _string_length_check(text) 

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

235 return width 

236 

237 

238## 

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

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

241 

242 

243class FreeTypeFont(BaseImageFont): 

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

245 

246 font: Font 

247 font_bytes: bytes 

248 

249 def __init__( 

250 self, 

251 font: StrOrBytesPath | BinaryIO, 

252 size: float = 10, 

253 index: int = 0, 

254 encoding: str = "", 

255 layout_engine: Layout | None = None, 

256 ) -> None: 

257 # FIXME: use service provider instead 

258 

259 if isinstance(core, DeferredError): 

260 raise core.ex 

261 

262 if size <= 0: 

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

264 raise ValueError(msg) 

265 

266 self.path = font 

267 self.size = size 

268 self.index = index 

269 self.encoding = encoding 

270 

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

272 layout_engine = Layout.BASIC 

273 if core.HAVE_RAQM: 

274 layout_engine = Layout.RAQM 

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

276 warnings.warn( 

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

278 "Falling back to basic layout." 

279 ) 

280 layout_engine = Layout.BASIC 

281 

282 self.layout_engine = layout_engine 

283 

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

285 self.font_bytes = f.read() 

286 self.font = core.getfont( 

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

288 ) 

289 

290 if is_path(font): 

291 font = os.fspath(font) 

292 if sys.platform == "win32": 

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

294 try: 

295 font_bytes_path.decode("ascii") 

296 except UnicodeDecodeError: 

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

298 # So load it into memory first 

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

300 load_from_bytes(f) 

301 return 

302 self.font = core.getfont( 

303 font, size, index, encoding, layout_engine=layout_engine 

304 ) 

305 else: 

306 load_from_bytes(cast("IO[bytes]", font)) 

307 

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

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

310 

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

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

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

314 

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

316 """ 

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

318 (e.g. Bold) 

319 """ 

320 return self.font.family, self.font.style 

321 

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

323 """ 

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

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

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

327 """ 

328 return self.font.ascent, self.font.descent 

329 

330 def getlength( 

331 self, 

332 text: str | bytes, 

333 mode: str = "", 

334 direction: str | None = None, 

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

336 language: str | None = None, 

337 ) -> float: 

338 """ 

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

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

341 

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

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

344 e.g. when using italics or accents. 

345 

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

347 

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

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

350 character and subtract its length. 

351 

352 For example, instead of :: 

353 

354 hello = font.getlength("Hello") 

355 world = font.getlength("World") 

356 hello_world = hello + world # not adjusted for kerning 

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

358 

359 use :: 

360 

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

362 world = font.getlength("World") 

363 hello_world = hello + world # adjusted for kerning 

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

365 

366 or disable kerning with (requires libraqm) :: 

367 

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

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

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

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

372 

373 .. versionadded:: 8.0.0 

374 

375 :param text: Text to measure. 

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

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

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

379 C-level implementations. 

380 

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

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

383 Requires libraqm. 

384 

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

386 layout. This is usually used to turn on optional 

387 font features that are not enabled by default, 

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

389 used to turn off default font features for 

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

391 to disable kerning. To get all supported 

392 features, see 

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

394 Requires libraqm. 

395 

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

397 different glyph shapes or ligatures. This parameter tells 

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

399 correct substitutions as appropriate, if available. 

400 It should be a `BCP 47 language code 

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

402 Requires libraqm. 

403 

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

405 """ 

406 _string_length_check(text) 

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

408 

409 def getbbox( 

410 self, 

411 text: str | bytes | bytearray, 

412 mode: str = "", 

413 direction: str | None = None, 

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

415 language: str | None = None, 

416 stroke_width: float = 0, 

417 anchor: str | None = None, 

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

419 """ 

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

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

422 

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

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

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

426 

427 .. versionadded:: 8.0.0 

428 

429 :param text: Text to render. 

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

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

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

433 C-level implementations. 

434 

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

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

437 Requires libraqm. 

438 

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

440 layout. This is usually used to turn on optional 

441 font features that are not enabled by default, 

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

443 used to turn off default font features for 

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

445 to disable kerning. To get all supported 

446 features, see 

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

448 Requires libraqm. 

449 

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

451 different glyph shapes or ligatures. This parameter tells 

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

453 correct substitutions as appropriate, if available. 

454 It should be a `BCP 47 language code 

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

456 Requires libraqm. 

457 

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

459 

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

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

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

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

464 

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

466 """ 

467 _string_length_check(text) 

468 size, offset = self.font.getsize( 

469 text, mode, direction, features, language, anchor 

470 ) 

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

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

473 return left, top, left + width, top + height 

474 

475 def getmask( 

476 self, 

477 text: str | bytes, 

478 mode: str = "", 

479 direction: str | None = None, 

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

481 language: str | None = None, 

482 stroke_width: float = 0, 

483 anchor: str | None = None, 

484 ink: int = 0, 

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

486 ) -> Image.core.ImagingCore: 

487 """ 

488 Create a bitmap for the text. 

489 

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

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

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

493 

494 :param text: Text to render. 

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

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

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

498 C-level implementations. 

499 

500 .. versionadded:: 1.1.5 

501 

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

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

504 Requires libraqm. 

505 

506 .. versionadded:: 4.2.0 

507 

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

509 layout. This is usually used to turn on optional 

510 font features that are not enabled by default, 

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

512 used to turn off default font features for 

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

514 to disable kerning. To get all supported 

515 features, see 

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

517 Requires libraqm. 

518 

519 .. versionadded:: 4.2.0 

520 

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

522 different glyph shapes or ligatures. This parameter tells 

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

524 correct substitutions as appropriate, if available. 

525 It should be a `BCP 47 language code 

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

527 Requires libraqm. 

528 

529 .. versionadded:: 6.0.0 

530 

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

532 

533 .. versionadded:: 6.2.0 

534 

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

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

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

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

539 

540 .. versionadded:: 8.0.0 

541 

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

543 

544 .. versionadded:: 8.0.0 

545 

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

547 differently when starting at fractional coordinates. 

548 

549 .. versionadded:: 9.4.0 

550 

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

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

553 """ 

554 return self.getmask2( 

555 text, 

556 mode, 

557 direction=direction, 

558 features=features, 

559 language=language, 

560 stroke_width=stroke_width, 

561 anchor=anchor, 

562 ink=ink, 

563 start=start, 

564 )[0] 

565 

566 def getmask2( 

567 self, 

568 text: str | bytes, 

569 mode: str = "", 

570 direction: str | None = None, 

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

572 language: str | None = None, 

573 stroke_width: float = 0, 

574 anchor: str | None = None, 

575 ink: int = 0, 

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

577 *args: Any, 

578 **kwargs: Any, 

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

580 """ 

581 Create a bitmap for the text. 

582 

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

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

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

586 

587 :param text: Text to render. 

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

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

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

591 C-level implementations. 

592 

593 .. versionadded:: 1.1.5 

594 

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

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

597 Requires libraqm. 

598 

599 .. versionadded:: 4.2.0 

600 

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

602 layout. This is usually used to turn on optional 

603 font features that are not enabled by default, 

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

605 used to turn off default font features for 

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

607 to disable kerning. To get all supported 

608 features, see 

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

610 Requires libraqm. 

611 

612 .. versionadded:: 4.2.0 

613 

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

615 different glyph shapes or ligatures. This parameter tells 

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

617 correct substitutions as appropriate, if available. 

618 It should be a `BCP 47 language code 

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

620 Requires libraqm. 

621 

622 .. versionadded:: 6.0.0 

623 

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

625 

626 .. versionadded:: 6.2.0 

627 

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

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

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

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

632 

633 .. versionadded:: 8.0.0 

634 

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

636 

637 .. versionadded:: 8.0.0 

638 

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

640 differently when starting at fractional coordinates. 

641 

642 .. versionadded:: 9.4.0 

643 

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

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

646 gap between the starting coordinate and the first marking 

647 """ 

648 _string_length_check(text) 

649 if start is None: 

650 start = (0, 0) 

651 

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

653 size = (width, height) 

654 Image._decompression_bomb_check(size) 

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

656 

657 return self.font.render( 

658 text, 

659 fill, 

660 mode, 

661 direction, 

662 features, 

663 language, 

664 stroke_width, 

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

666 anchor, 

667 ink, 

668 start, 

669 ) 

670 

671 def font_variant( 

672 self, 

673 font: StrOrBytesPath | BinaryIO | None = None, 

674 size: float | None = None, 

675 index: int | None = None, 

676 encoding: str | None = None, 

677 layout_engine: Layout | None = None, 

678 ) -> FreeTypeFont: 

679 """ 

680 Create a copy of this FreeTypeFont object, 

681 using any specified arguments to override the settings. 

682 

683 Parameters are identical to the parameters used to initialize this 

684 object. 

685 

686 :return: A FreeTypeFont object. 

687 """ 

688 if font is None: 

689 try: 

690 font = BytesIO(self.font_bytes) 

691 except AttributeError: 

692 font = self.path 

693 return FreeTypeFont( 

694 font=font, 

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

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

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

698 layout_engine=layout_engine or self.layout_engine, 

699 ) 

700 

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

702 """ 

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

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

705 """ 

706 names = [] 

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

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

709 if name not in names: 

710 names.append(name) 

711 return names 

712 

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

714 """ 

715 :param name: The name of the style. 

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

717 """ 

718 names = self.get_variation_names() 

719 if not isinstance(name, bytes): 

720 name = name.encode() 

721 index = names.index(name) + 1 

722 

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

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

725 # there is an 'unknown freetype error' 

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

727 return 

728 self._last_variation_index = index 

729 

730 self.font.setvarname(index) 

731 

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

733 """ 

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

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

736 """ 

737 axes = self.font.getvaraxes() 

738 for axis in axes: 

739 if "name" in axis: 

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

741 return axes 

742 

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

744 """ 

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

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

747 """ 

748 self.font.setvaraxes(axes) 

749 

750 

751class TransposedFont(BaseImageFont): 

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

753 

754 def __init__( 

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

756 ): 

757 """ 

758 Wrapper that creates a transposed font from any existing font 

759 object. 

760 

761 :param font: A font object. 

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

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

764 Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_180, or 

765 Image.Transpose.ROTATE_270. 

766 """ 

767 self.font = font 

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

769 

770 def getmask( 

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

772 ) -> Image.core.ImagingCore: 

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

774 if self.orientation is not None: 

775 return im.transpose(self.orientation) 

776 return im 

777 

778 def getbbox( 

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

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

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

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

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

784 width = right - left 

785 height = bottom - top 

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

787 return 0, 0, height, width 

788 return 0, 0, width, height 

789 

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

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

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

793 raise ValueError(msg) 

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

795 

796 

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

798 """ 

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

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

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

802 

803 :param filename: Name of font file. 

804 :return: A font object. 

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

806 """ 

807 f = ImageFont() 

808 f._load_pilfont(filename) 

809 return f 

810 

811 

812def truetype( 

813 font: StrOrBytesPath | BinaryIO, 

814 size: float = 10, 

815 index: int = 0, 

816 encoding: str = "", 

817 layout_engine: Layout | None = None, 

818) -> FreeTypeFont: 

819 """ 

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

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

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

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

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

825 

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

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

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

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

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

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

832 

833 This function requires the _imagingft service. 

834 

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

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

837 search in other directories, such as: 

838 

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

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

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

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

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

844 the ``XDG_DATA_HOME`` and ``XDG_DATA_DIRS`` environment variables 

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

846 

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

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

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

850 encodings include (see the FreeType documentation for more 

851 information): 

852 

853 * "unic" (Unicode) 

854 * "symb" (Microsoft Symbol) 

855 * "ADOB" (Adobe Standard) 

856 * "ADBE" (Adobe Expert) 

857 * "ADBC" (Adobe Custom) 

858 * "armn" (Apple Roman) 

859 * "sjis" (Shift JIS) 

860 * "gb " (PRC) 

861 * "big5" 

862 * "wans" (Extended Wansung) 

863 * "joha" (Johab) 

864 * "lat1" (Latin-1) 

865 

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

867 encoding of any text provided in subsequent operations. 

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

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

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

871 Otherwise, basic layout will be used. 

872 

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

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

875 

876 You can check support for Raqm layout using 

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

878 

879 .. versionadded:: 4.2.0 

880 :return: A font object. 

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

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

883 """ 

884 

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

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

887 

888 try: 

889 return freetype(font) 

890 except OSError: 

891 if not is_path(font): 

892 raise 

893 ttf_filename = os.path.basename(font) 

894 

895 dirs = [] 

896 if sys.platform == "win32": 

897 # check the windows font repository 

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

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

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

901 if windir: 

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

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

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

905 if not data_home: 

906 # The freedesktop spec defines the following default directory for 

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

908 # takes precedence over system-level directories. 

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

910 xdg_dirs = [data_home] 

911 

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

913 if not data_dirs: 

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

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

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

917 

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

919 elif sys.platform == "darwin": 

920 dirs += [ 

921 "/Library/Fonts", 

922 "/System/Library/Fonts", 

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

924 ] 

925 

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

927 first_font_with_a_different_extension = None 

928 for directory in dirs: 

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

930 for walkfilename in walkfilenames: 

931 if ext and walkfilename == ttf_filename: 

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

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

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

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

936 return freetype(fontpath) 

937 if not ext and first_font_with_a_different_extension is None: 

938 first_font_with_a_different_extension = fontpath 

939 if first_font_with_a_different_extension: 

940 return freetype(first_font_with_a_different_extension) 

941 raise 

942 

943 

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

945 """ 

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

947 bitmap font along the Python path. 

948 

949 :param filename: Name of font file. 

950 :return: A font object. 

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

952 """ 

953 if not isinstance(filename, str): 

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

955 for directory in sys.path: 

956 try: 

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

958 except OSError: 

959 pass 

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

961 if os.path.exists(filename): 

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

963 

964 raise OSError(msg) 

965 

966 

967def load_default_imagefont() -> ImageFont: 

968 f = ImageFont() 

969 f._load_pilfont_data( 

970 # courB08 

971 BytesIO(base64.b64decode(b""" 

972UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

973AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

974AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

975AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

976AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

977AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

978AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

979AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

980AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

981AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

982AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

983AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA 

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

985AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA 

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

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

988BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB 

989//kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA 

990AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH 

991AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA 

992ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv 

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

994/gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5 

995AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA 

996AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG 

997AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA 

998BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA 

999AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA 

10002AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF 

1001AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA//// 

1002+gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA 

1003////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA 

1004BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv 

1005AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA 

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

1007AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA 

1008BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP// 

1009//kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA 

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

1011AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB 

1012mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn 

1013AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA 

1014AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7 

1015AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA 

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

1017AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1018AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1019AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1020AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1021AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1022AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1023AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1024AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1025AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1026AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1027AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1028AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB 

1029//sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA 

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

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

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

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

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

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

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

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

1038BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA 

1039Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC 

1040eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG 

1041AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA//// 

1042+gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA 

1043////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA 

1044BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT 

1045AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A 

1046AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA 

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

1048Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP// 

1049//cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA 

1050AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ 

1051AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA 

1052LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5 

1053AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA 

1054AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5 

1055AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA 

1056AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG 

1057AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA 

1058EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK 

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

1060pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG 

1061AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA//// 

1062+QAGAAIAzgAKANUAEw== 

1063""")), 

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

1065iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u 

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

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

1068LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F 

1069IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA 

1070Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791 

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

1072in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9 

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

1074AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt 

1075y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG 

1076ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY 

1077lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H 

1078/Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3 

1079AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47 

1080c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/ 

1081/yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw 

1082pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv 

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

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

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

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

1087w7IkEbzhVQAAAABJRU5ErkJggg== 

1088"""))), 

1089 ) 

1090 return f 

1091 

1092 

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

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

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

1096 

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

1098 

1099 .. versionadded:: 1.1.4 

1100 

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

1102 

1103 .. versionadded:: 10.1.0 

1104 

1105 :return: A font object. 

1106 """ 

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

1108 return truetype( 

1109 BytesIO(base64.b64decode(b""" 

1110AAEAAAAPAIAAAwBwRkZUTYwDlUAAADFoAAAAHEdERUYAqADnAAAo8AAAACRHUE9ThhmITwAAKfgAA 

1111AduR1NVQnHxefoAACkUAAAA4k9TLzJovoHLAAABeAAAAGBjbWFw5lFQMQAAA6gAAAGqZ2FzcP//AA 

1112MAACjoAAAACGdseWYmRXoPAAAGQAAAHfhoZWFkE18ayQAAAPwAAAA2aGhlYQboArEAAAE0AAAAJGh 

1113tdHjjERZ8AAAB2AAAAdBsb2NhuOexrgAABVQAAADqbWF4cAC7AEYAAAFYAAAAIG5hbWUr+h5lAAAk 

1114OAAAA6Jwb3N0D3oPTQAAJ9wAAAEKAAEAAAABGhxJDqIhXw889QALA+gAAAAA0Bqf2QAAAADhCh2h/ 

11152r/LgOxAyAAAAAIAAIAAAAAAAAAAQAAA8r/GgAAA7j/av9qA7EAAQAAAAAAAAAAAAAAAAAAAHQAAQ 

1116AAAHQAQwAFAAAAAAACAAAAAQABAAAAQAAAAAAAAAADAfoBkAAFAAgCigJYAAAASwKKAlgAAAFeADI 

1117BPgAAAAAFAAAAAAAAAAAAAAcAAAAAAAAAAAAAAABVS1dOAEAAIPsCAwL/GgDIA8oA5iAAAJMAAAAA 

1118AhICsgAAACAAAwH0AAAAAAAAAU0AAADYAAAA8gA5AVMAVgJEAEYCRAA1AuQAKQKOAEAAsAArATsAZ 

1119AE7AB4CMABVAkQAUADc/+EBEgAgANwAJQEv//sCRAApAkQAggJEADwCRAAtAkQAIQJEADkCRAArAk 

1120QAMgJEACwCRAAxANwAJQDc/+ECRABnAkQAUAJEAEQB8wAjA1QANgJ/AB0CcwBkArsALwLFAGQCSwB 

1121kAjcAZALGAC8C2gBkAQgAZAIgADcCYQBkAj8AZANiAGQCzgBkAuEALwJWAGQC3QAvAmsAZAJJADQC 

1122ZAAiAqoAXgJuACADuAAaAnEAGQJFABMCTwAuATMAYgEv//sBJwAiAkQAUAH0ADIBLAApAhMAJAJjA 

1123EoCEQAeAmcAHgIlAB4BIgAVAmcAHgJRAEoA7gA+AOn/8wIKAEoA9wBGA1cASgJRAEoCSgAeAmMASg 

1124JnAB4BSgBKAcsAGAE5ABQCUABCAgIAAQMRAAEB4v/6AgEAAQHOABQBLwBAAPoAYAEvACECRABNA0Y 

1125AJAItAHgBKgAcAkQAUAEsAHQAygAgAi0AOQD3ADYA9wAWAaEANgGhABYCbAAlAYMAeAGDADkA6/9q 

1126AhsAFAIKABUB/QAVAAAAAwAAAAMAAAAcAAEAAAAAAKQAAwABAAAAHAAEAIgAAAAeABAAAwAOAH4Aq 

1127QCrALEAtAC3ALsgGSAdICYgOiBEISL7Av//AAAAIACpAKsAsAC0ALcAuyAYIBwgJiA5IEQhIvsB// 

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

1129AAAAAAAEGAAABAAAAAAAAAAECAAAAAgAAAAAAAAAAAAAAAAAAAAEAAAMEBQYHCAkKCwwNDg8QERIT 

1130FBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMT 

1131U5PUFFSU1RVVldYWVpbXF1eX2BhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQAAA 

1132AAAAAAYnFmAAAAAABlAAAAAAAAAAAAAAAAAAAAAAAAAAAAY2htAAAAAAAAAABrbGlqAAAAAHAAbm9 

1133ycwBnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmACYAJgAmAD4AUgCCAMoBCgFO 

1134AVwBcgGIAaYBvAHKAdYB6AH2AgwCIAJKAogCpgLWAw4DIgNkA5wDugPUA+gD/AQQBEYEogS8BPoFJ 

1135gVSBWoFgAWwBcoF1gX6BhQGJAZMBmgGiga0BuIHGgdUB2YHkAeiB8AH3AfyCAoIHAgqCDoITghcCG 

1136oIogjSCPoJKglYCXwJwgnqCgIKKApACl4Klgq8CtwLDAs8C1YLjAuyC9oL7gwMDCYMSAxgDKAMrAz 

1137qDQoNTA1mDYQNoA2uDcAN2g3oDfYODA4iDkoOXA5sDnoOnA7EDvwAAAAFAAAAAAH0ArwAAwAGAAkA 

1138DAAPAAAxESERAxMhExcRASELARETAfT6qv6syKr+jgFUqsiqArz9RAGLAP/+1P8B/v3VAP8BLP4CA 

1139P8AAgA5//IAuQKyAAMACwAANyMDMwIyFhQGIiY0oE4MZk84JCQ4JLQB/v3AJDgkJDgAAgBWAeUBPA 

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 

1185vArIACwAAJRUhESEVIRUhFSEVAi/+NQHB/pUBTf6zRkYCskbwRvAAAAABAGQAAAIlArIACQAAExUh 

1186FSERIxEhFboBQ/69VgHBAmzwRv7KArJGAAAAAAEAL//yAo8CwAAfAAABMxEjNQcGIyImNTQ2MzIWH 

1187wEjJyYjIgYVFBYzMjY1IwGP90wfPnWTprSSf48LAVYCIqJofHllVG+hAU3+s3hARsicn8uAagoKpq 

1188N/gaN1XAAAAAEAZAAAAowCsgALAAABESMRIREjETMRIRECjFb+hFZWAXwCsv1OAS7+0gKy/sQBPAA 

1189AAAABAGQAAAC6ArIAAwAAMyMRM7pWVgKyAAABADf/8gHoArIAEwAAAREUBw4BIyImLwEzFxYzMjc2 

1190NREB6AIFcGpgbQIBVgIHfXQKAQKy/lYxIltob2EpKYyEFD0BpwAAAAABAGQAAAJ0ArIACwAACQEjA 

1191wcVIxEzEQEzATsBJ3ntQlZWAVVlAWH+nwEnR+ACsv6RAW8AAQBkAAACLwKyAAUAACUVIREzEQIv/j 

1192VWRkYCsv2UAAABAGQAAAMUArIAFAAAAREjETQ3BgcDIwMmJxYVESMRMxsBAxRWAiMxemx8NxsCVo7 

1193MywKy/U4BY7ZLco7+nAFmoFxLtP6dArL9lwJpAAAAAAEAZAAAAoACsgANAAAhIwEWFREjETMBJjUR 

1194MwKAhP67A1aEAUUDVAJeeov+pwKy/aJ5jAFZAAAAAgAv//ICuwLAAAkAEwAAEiAWFRQGICY1NBIyN 

1195jU0JiIGFRTbATSsrP7MrNrYenrYegLAxaKhxsahov47nIeIm5uIhwACAGQAAAJHArIADgAYAAABHg 

1196EVFAYHBisBESMRMzITNjQnJisBETMyAZRUX2VOHzuAVtY7GlxcGDWIiDUCrgtnVlVpCgT+5gKy/rU 

1197V1BUF/vgAAAACAC//zAK9AsAAEgAcAAAlFhcHJiMiBwYjIiY1NDYgFhUUJRQWMjY1NCYiBgI9PUMx 

1198UDcfKh8omqysATSs/dR62Hp62HpICTg7NgkHxqGixcWitbWHnJyHiJubAAIAZAAAAlgCsgAXACMAA 

1199CUWFyMmJyYnJisBESMRMzIXHgEVFAYHFiUzMjc+ATU0JyYrAQIqDCJfGQwNWhAhglbiOx9QXEY1Tv 

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 

1275gQAAwABBAkADAAuAkwATgBvACAAUgBpAGcAaAB0AHMAIABSAGUAcwBlAHIAdgBlAGQALgAATm8gUm 

1276lnaHRzIFJlc2VydmVkLgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAUgBlAGcAdQBsAGEAcgAAUmV 

1277ndWxhcgAAMQAuADEAMAAyADsAVQBLAFcATgA7AEEAaQBsAGUAcgBvAG4ALQBSAGUAZwB1AGwAYQBy 

1278AAAxLjEwMjtVS1dOO0FpbGVyb24tUmVndWxhcgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAVgBlA 

1279HIAcwBpAG8AbgAgADEALgAxADAAMgA7AFAAUwAgADAAMAAxAC4AMQAwADIAOwBoAG8AdABjAG8Abg 

1280B2ACAAMQAuADAALgA3ADAAOwBtAGEAawBlAG8AdABmAC4AbABpAGIAMgAuADUALgA1ADgAMwAyADk 

1281AAFZlcnNpb24gMS4xMDI7UFMgMDAxLjEwMjtob3Rjb252IDEuMC43MDttYWtlb3RmLmxpYjIuNS41 

1282ODMyOQAAQQBpAGwAZQByAG8AbgAtAFIAZQBnAHUAbABhAHIAAEFpbGVyb24tUmVndWxhcgAAUwBvA 

1283HIAYQAgAFMAYQBnAGEAbgBvAABTb3JhIFNhZ2FubwAAUwBvAHIAYQAgAFMAYQBnAGEAbgBvAABTb3 

1284JhIFNhZ2FubwAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBsAG8AbgAuAG4AZQB0AAB 

1285odHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBs 

1286AG8AbgAuAG4AZQB0AABodHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAAAACAAAAAAAA/4MAMgAAAAAAA 

1287AAAAAAAAAAAAAAAAAAAAHQAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATAB 

1288QAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAA 

1289xADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0A 

1290TgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAIsAqQCDAJMAjQDDAKoAtgC3A 

1291LQAtQCrAL4AvwC8AIwAwADBAAAAAAAB//8AAgABAAAADAAAABwAAAACAAIAAwBxAAEAcgBzAAIABA 

1292AAAAIAAAABAAAACgBMAGYAAkRGTFQADmxhdG4AGgAEAAAAAP//AAEAAAAWAANDQVQgAB5NT0wgABZ 

1293ST00gABYAAP//AAEAAAAA//8AAgAAAAEAAmxpZ2EADmxvY2wAFAAAAAEAAQAAAAEAAAACAAYAEAAG 

1294AAAAAgASADQABAAAAAEATAADAAAAAgAQABYAAQAcAAAAAQABAE8AAQABAGcAAQABAE8AAwAAAAIAE 

1295AAWAAEAHAAAAAEAAQAvAAEAAQBnAAEAAQAvAAEAGgABAAgAAgAGAAwAcwACAE8AcgACAEwAAQABAE 

1296kAAAABAAAACgBGAGAAAkRGTFQADmxhdG4AHAAEAAAAAP//AAIAAAABABYAA0NBVCAAFk1PTCAAFlJ 

1297PTSAAFgAA//8AAgAAAAEAAmNwc3AADmtlcm4AFAAAAAEAAAAAAAEAAQACAAYADgABAAAAAQASAAIA 

1298AAACAB4ANgABAAoABQAFAAoAAgABACQAPQAAAAEAEgAEAAAAAQAMAAEAOP/nAAEAAQAkAAIGigAEA 

1299AAFJAXKABoAGQAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

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

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

1302ABD/vQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7gAAAAAAAAAAAAAAAAAA//MAA 

1303AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAP/5AAAAAAAAAA 

1304AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gAAD/4AAAAAAAAAAAAAAAAAA 

1305AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//L/9AAAAAAAAAAAAAAAAAAAAAAA 

1306AAAAAAAAAAAA/+gAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1307AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAAAAA 

1308AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/mAAAAAAAAAAAAAAAAAAD 

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

1310AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zv/qAAAAAP/0AAAACAAAAAAAAAAAAAAAAAAAAAAAA 

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

1312AAAAAAAAAAAAAAAAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

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

1314AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+AAAAAAAAAAAAAAA 

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

1316AAAAAAAAAAAAAAAAAAAAAAAAAAAAD/yAAA/+kAAAAA//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1317AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9wAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1318AAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1319AAAAAAAAP/cAAAAAAAAAAAAAAAA/7YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1320AAAAAAAAAAAAAAAAAAAAAAAAAAAP/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6AAAAAAAAAA 

1321AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAkAFAAEAAAAAQACwAAABcA 

1322BgAAAAAAAAAIAA4AAAAAAAsAEgAAAAAAAAATABkAAwANAAAAAQAJAAAAAAAAAAAAAAAAAAAAGAAAA 

1323AAABwAAAAAAAAAAAAAAFQAFAAAAAAAYABgAAAAUAAAACgAAAAwAAgAPABEAFgAAAAAAAAAAAAAAAA 

1324AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAEAEQBdAAYAAAAAAAAAAAAAAAAAAAAAAAA 

1325AAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAcAAAAAAAAABwAAAAAACAAAAAAAAAAAAAcAAAAHAAAAEwAJ 

1326ABUADgAPAAAACwAQAAAAAAAAAAAAAAAAAAUAGAACAAIAAgAAAAIAGAAXAAAAGAAAABYAFgACABYAA 

1327gAWAAAAEQADAAoAFAAMAA0ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAEgAGAAEAHgAkAC 

1328YAJwApACoALQAuAC8AMgAzADcAOAA5ADoAPAA9AEUASABOAE8AUgBTAFUAVwBZAFoAWwBcAF0AcwA 

1329AAAAAAQAAAADa3tfFAAAAANAan9kAAAAA4QodoQ== 

1330""")), 

1331 10 if size is None else size, 

1332 layout_engine=Layout.BASIC, 

1333 ) 

1334 return load_default_imagefont()