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

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

286 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, features 

40from ._typing import StrOrBytesPath 

41from ._util import DeferredError, is_path 

42 

43TYPE_CHECKING = False 

44if TYPE_CHECKING: 

45 from . import ImageFile 

46 from ._imaging import ImagingFont 

47 from ._imagingft import Font 

48 

49 

50class Axis(TypedDict): 

51 minimum: int | None 

52 default: int | None 

53 maximum: int | None 

54 name: bytes | None 

55 

56 

57class Layout(IntEnum): 

58 BASIC = 0 

59 RAQM = 1 

60 

61 

62MAX_STRING_LENGTH = 1_000_000 

63 

64 

65core: ModuleType | DeferredError 

66try: 

67 from . import _imagingft as core 

68except ImportError as ex: 

69 core = DeferredError.new(ex) 

70 

71 

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

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

74 msg = "too many characters in string" 

75 raise ValueError(msg) 

76 

77 

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

79 

80# -------------------------------------------------------------------- 

81# Font metrics format: 

82# "PILfont" LF 

83# fontdescriptor LF 

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

85# "DATA" LF 

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

87# 

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

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

90# position according to dx, dy. 

91# -------------------------------------------------------------------- 

92 

93 

94class ImageFont: 

95 """PIL font wrapper""" 

96 

97 font: ImagingFont 

98 

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

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

101 image: ImageFile.ImageFile | None = None 

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

103 

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

105 if image: 

106 image.close() 

107 try: 

108 fullname = root + ext 

109 image = Image.open(fullname) 

110 except Exception: 

111 pass 

112 else: 

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

114 break 

115 else: 

116 if image: 

117 image.close() 

118 

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

120 raise OSError(msg) 

121 

122 self.file = fullname 

123 

124 self._load_pilfont_data(fp, image) 

125 image.close() 

126 

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

128 # read PILfont header 

129 if file.readline() != b"PILfont\n": 

130 msg = "Not a PILfont file" 

131 raise SyntaxError(msg) 

132 file.readline().split(b";") 

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

134 while True: 

135 s = file.readline() 

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

137 break 

138 self.info.append(s) 

139 

140 # read PILfont metrics 

141 data = file.read(256 * 20) 

142 

143 # check image 

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

145 msg = "invalid font image mode" 

146 raise TypeError(msg) 

147 

148 image.load() 

149 

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

151 

152 def getmask( 

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

154 ) -> Image.core.ImagingCore: 

155 """ 

156 Create a bitmap for the text. 

157 

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

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

160 

161 :param text: Text to render. 

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

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

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

165 C-level implementations. 

166 

167 .. versionadded:: 1.1.5 

168 

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

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

171 """ 

172 _string_length_check(text) 

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

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

175 

176 def getbbox( 

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

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

179 """ 

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

181 

182 .. versionadded:: 9.2.0 

183 

184 :param text: Text to render. 

185 

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

187 """ 

188 _string_length_check(text) 

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

190 return 0, 0, width, height 

191 

192 def getlength( 

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

194 ) -> int: 

195 """ 

196 Returns length (in pixels) of given text. 

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

198 

199 .. versionadded:: 9.2.0 

200 """ 

201 _string_length_check(text) 

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

203 return width 

204 

205 

206## 

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

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

209 

210 

211class FreeTypeFont: 

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

213 

214 font: Font 

215 font_bytes: bytes 

216 

217 def __init__( 

218 self, 

219 font: StrOrBytesPath | BinaryIO, 

220 size: float = 10, 

221 index: int = 0, 

222 encoding: str = "", 

223 layout_engine: Layout | None = None, 

224 ) -> None: 

225 # FIXME: use service provider instead 

226 

227 if isinstance(core, DeferredError): 

228 raise core.ex 

229 

230 if size <= 0: 

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

232 raise ValueError(msg) 

233 

234 self.path = font 

235 self.size = size 

236 self.index = index 

237 self.encoding = encoding 

238 

239 try: 

240 from packaging.version import parse as parse_version 

241 except ImportError: 

242 pass 

243 else: 

244 if freetype_version := features.version_module("freetype2"): 

245 if parse_version(freetype_version) < parse_version("2.9.1"): 

246 warnings.warn( 

247 "Support for FreeType 2.9.0 is deprecated and will be removed " 

248 "in Pillow 12 (2025-10-15). Please upgrade to FreeType 2.9.1 " 

249 "or newer, preferably FreeType 2.10.4 which fixes " 

250 "CVE-2020-15999.", 

251 DeprecationWarning, 

252 ) 

253 

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

255 layout_engine = Layout.BASIC 

256 if core.HAVE_RAQM: 

257 layout_engine = Layout.RAQM 

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

259 warnings.warn( 

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

261 "Falling back to basic layout." 

262 ) 

263 layout_engine = Layout.BASIC 

264 

265 self.layout_engine = layout_engine 

266 

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

268 self.font_bytes = f.read() 

269 self.font = core.getfont( 

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

271 ) 

272 

273 if is_path(font): 

274 font = os.fspath(font) 

275 if sys.platform == "win32": 

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

277 try: 

278 font_bytes_path.decode("ascii") 

279 except UnicodeDecodeError: 

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

281 # So load it into memory first 

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

283 load_from_bytes(f) 

284 return 

285 self.font = core.getfont( 

286 font, size, index, encoding, layout_engine=layout_engine 

287 ) 

288 else: 

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

290 

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

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

293 

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

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

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

297 

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

299 """ 

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

301 (e.g. Bold) 

302 """ 

303 return self.font.family, self.font.style 

304 

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

306 """ 

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

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

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

310 """ 

311 return self.font.ascent, self.font.descent 

312 

313 def getlength( 

314 self, 

315 text: str | bytes, 

316 mode: str = "", 

317 direction: str | None = None, 

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

319 language: str | None = None, 

320 ) -> float: 

321 """ 

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

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

324 

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

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

327 e.g. when using italics or accents. 

328 

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

330 

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

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

333 character and subtract its length. 

334 

335 For example, instead of :: 

336 

337 hello = font.getlength("Hello") 

338 world = font.getlength("World") 

339 hello_world = hello + world # not adjusted for kerning 

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

341 

342 use :: 

343 

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

345 world = font.getlength("World") 

346 hello_world = hello + world # adjusted for kerning 

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

348 

349 or disable kerning with (requires libraqm) :: 

350 

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

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

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

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

355 

356 .. versionadded:: 8.0.0 

357 

358 :param text: Text to measure. 

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

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

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

362 C-level implementations. 

363 

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

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

366 Requires libraqm. 

367 

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

369 layout. This is usually used to turn on optional 

370 font features that are not enabled by default, 

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

372 used to turn off default font features for 

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

374 to disable kerning. To get all supported 

375 features, see 

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

377 Requires libraqm. 

378 

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

380 different glyph shapes or ligatures. This parameter tells 

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

382 correct substitutions as appropriate, if available. 

383 It should be a `BCP 47 language code 

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

385 Requires libraqm. 

386 

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

388 """ 

389 _string_length_check(text) 

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

391 

392 def getbbox( 

393 self, 

394 text: str | bytes, 

395 mode: str = "", 

396 direction: str | None = None, 

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

398 language: str | None = None, 

399 stroke_width: float = 0, 

400 anchor: str | None = None, 

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

402 """ 

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

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

405 

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

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

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

409 

410 .. versionadded:: 8.0.0 

411 

412 :param text: Text to render. 

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

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

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

416 C-level implementations. 

417 

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

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

420 Requires libraqm. 

421 

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

423 layout. This is usually used to turn on optional 

424 font features that are not enabled by default, 

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

426 used to turn off default font features for 

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

428 to disable kerning. To get all supported 

429 features, see 

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

431 Requires libraqm. 

432 

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

434 different glyph shapes or ligatures. This parameter tells 

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

436 correct substitutions as appropriate, if available. 

437 It should be a `BCP 47 language code 

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

439 Requires libraqm. 

440 

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

442 

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

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

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

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

447 

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

449 """ 

450 _string_length_check(text) 

451 size, offset = self.font.getsize( 

452 text, mode, direction, features, language, anchor 

453 ) 

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

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

456 return left, top, left + width, top + height 

457 

458 def getmask( 

459 self, 

460 text: str | bytes, 

461 mode: str = "", 

462 direction: str | None = None, 

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

464 language: str | None = None, 

465 stroke_width: float = 0, 

466 anchor: str | None = None, 

467 ink: int = 0, 

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

469 ) -> Image.core.ImagingCore: 

470 """ 

471 Create a bitmap for the text. 

472 

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

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

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

476 

477 :param text: Text to render. 

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

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

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

481 C-level implementations. 

482 

483 .. versionadded:: 1.1.5 

484 

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

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

487 Requires libraqm. 

488 

489 .. versionadded:: 4.2.0 

490 

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

492 layout. This is usually used to turn on optional 

493 font features that are not enabled by default, 

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

495 used to turn off default font features for 

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

497 to disable kerning. To get all supported 

498 features, see 

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

500 Requires libraqm. 

501 

502 .. versionadded:: 4.2.0 

503 

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

505 different glyph shapes or ligatures. This parameter tells 

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

507 correct substitutions as appropriate, if available. 

508 It should be a `BCP 47 language code 

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

510 Requires libraqm. 

511 

512 .. versionadded:: 6.0.0 

513 

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

515 

516 .. versionadded:: 6.2.0 

517 

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

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

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

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

522 

523 .. versionadded:: 8.0.0 

524 

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

526 

527 .. versionadded:: 8.0.0 

528 

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

530 differently when starting at fractional coordinates. 

531 

532 .. versionadded:: 9.4.0 

533 

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

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

536 """ 

537 return self.getmask2( 

538 text, 

539 mode, 

540 direction=direction, 

541 features=features, 

542 language=language, 

543 stroke_width=stroke_width, 

544 anchor=anchor, 

545 ink=ink, 

546 start=start, 

547 )[0] 

548 

549 def getmask2( 

550 self, 

551 text: str | bytes, 

552 mode: str = "", 

553 direction: str | None = None, 

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

555 language: str | None = None, 

556 stroke_width: float = 0, 

557 anchor: str | None = None, 

558 ink: int = 0, 

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

560 *args: Any, 

561 **kwargs: Any, 

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

563 """ 

564 Create a bitmap for the text. 

565 

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

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

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

569 

570 :param text: Text to render. 

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

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

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

574 C-level implementations. 

575 

576 .. versionadded:: 1.1.5 

577 

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

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

580 Requires libraqm. 

581 

582 .. versionadded:: 4.2.0 

583 

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

585 layout. This is usually used to turn on optional 

586 font features that are not enabled by default, 

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

588 used to turn off default font features for 

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

590 to disable kerning. To get all supported 

591 features, see 

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

593 Requires libraqm. 

594 

595 .. versionadded:: 4.2.0 

596 

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

598 different glyph shapes or ligatures. This parameter tells 

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

600 correct substitutions as appropriate, if available. 

601 It should be a `BCP 47 language code 

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

603 Requires libraqm. 

604 

605 .. versionadded:: 6.0.0 

606 

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

608 

609 .. versionadded:: 6.2.0 

610 

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

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

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

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

615 

616 .. versionadded:: 8.0.0 

617 

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

619 

620 .. versionadded:: 8.0.0 

621 

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

623 differently when starting at fractional coordinates. 

624 

625 .. versionadded:: 9.4.0 

626 

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

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

629 gap between the starting coordinate and the first marking 

630 """ 

631 _string_length_check(text) 

632 if start is None: 

633 start = (0, 0) 

634 

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

636 size = (width, height) 

637 Image._decompression_bomb_check(size) 

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

639 

640 return self.font.render( 

641 text, 

642 fill, 

643 mode, 

644 direction, 

645 features, 

646 language, 

647 stroke_width, 

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

649 anchor, 

650 ink, 

651 start, 

652 ) 

653 

654 def font_variant( 

655 self, 

656 font: StrOrBytesPath | BinaryIO | None = None, 

657 size: float | None = None, 

658 index: int | None = None, 

659 encoding: str | None = None, 

660 layout_engine: Layout | None = None, 

661 ) -> FreeTypeFont: 

662 """ 

663 Create a copy of this FreeTypeFont object, 

664 using any specified arguments to override the settings. 

665 

666 Parameters are identical to the parameters used to initialize this 

667 object. 

668 

669 :return: A FreeTypeFont object. 

670 """ 

671 if font is None: 

672 try: 

673 font = BytesIO(self.font_bytes) 

674 except AttributeError: 

675 font = self.path 

676 return FreeTypeFont( 

677 font=font, 

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

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

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

681 layout_engine=layout_engine or self.layout_engine, 

682 ) 

683 

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

685 """ 

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

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

688 """ 

689 try: 

690 names = self.font.getvarnames() 

691 except AttributeError as e: 

692 msg = "FreeType 2.9.1 or greater is required" 

693 raise NotImplementedError(msg) from e 

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

695 

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

697 """ 

698 :param name: The name of the style. 

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

700 """ 

701 names = self.get_variation_names() 

702 if not isinstance(name, bytes): 

703 name = name.encode() 

704 index = names.index(name) + 1 

705 

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

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

708 # there is an 'unknown freetype error' 

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

710 return 

711 self._last_variation_index = index 

712 

713 self.font.setvarname(index) 

714 

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

716 """ 

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

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

719 """ 

720 try: 

721 axes = self.font.getvaraxes() 

722 except AttributeError as e: 

723 msg = "FreeType 2.9.1 or greater is required" 

724 raise NotImplementedError(msg) from e 

725 for axis in axes: 

726 if axis["name"]: 

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

728 return axes 

729 

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

731 """ 

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

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

734 """ 

735 try: 

736 self.font.setvaraxes(axes) 

737 except AttributeError as e: 

738 msg = "FreeType 2.9.1 or greater is required" 

739 raise NotImplementedError(msg) from e 

740 

741 

742class TransposedFont: 

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

744 

745 def __init__( 

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

747 ): 

748 """ 

749 Wrapper that creates a transposed font from any existing font 

750 object. 

751 

752 :param font: A font object. 

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

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

755 Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_180, or 

756 Image.Transpose.ROTATE_270. 

757 """ 

758 self.font = font 

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

760 

761 def getmask( 

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

763 ) -> Image.core.ImagingCore: 

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

765 if self.orientation is not None: 

766 return im.transpose(self.orientation) 

767 return im 

768 

769 def getbbox( 

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

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

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

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

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

775 width = right - left 

776 height = bottom - top 

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

778 return 0, 0, height, width 

779 return 0, 0, width, height 

780 

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

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

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

784 raise ValueError(msg) 

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

786 

787 

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

789 """ 

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

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

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

793 

794 :param filename: Name of font file. 

795 :return: A font object. 

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

797 """ 

798 f = ImageFont() 

799 f._load_pilfont(filename) 

800 return f 

801 

802 

803def truetype( 

804 font: StrOrBytesPath | BinaryIO, 

805 size: float = 10, 

806 index: int = 0, 

807 encoding: str = "", 

808 layout_engine: Layout | None = None, 

809) -> FreeTypeFont: 

810 """ 

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

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

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

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

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

816 

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

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

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

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

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

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

823 

824 This function requires the _imagingft service. 

825 

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

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

828 search in other directories, such as: 

829 

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

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

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

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

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

835 the ``XDG_DATA_HOME`` and ``XDG_DATA_DIRS`` environment variables 

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

837 

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

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

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

841 encodings include (see the FreeType documentation for more 

842 information): 

843 

844 * "unic" (Unicode) 

845 * "symb" (Microsoft Symbol) 

846 * "ADOB" (Adobe Standard) 

847 * "ADBE" (Adobe Expert) 

848 * "ADBC" (Adobe Custom) 

849 * "armn" (Apple Roman) 

850 * "sjis" (Shift JIS) 

851 * "gb " (PRC) 

852 * "big5" 

853 * "wans" (Extended Wansung) 

854 * "joha" (Johab) 

855 * "lat1" (Latin-1) 

856 

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

858 encoding of any text provided in subsequent operations. 

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

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

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

862 Otherwise, basic layout will be used. 

863 

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

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

866 

867 You can check support for Raqm layout using 

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

869 

870 .. versionadded:: 4.2.0 

871 :return: A font object. 

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

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

874 """ 

875 

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

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

878 

879 try: 

880 return freetype(font) 

881 except OSError: 

882 if not is_path(font): 

883 raise 

884 ttf_filename = os.path.basename(font) 

885 

886 dirs = [] 

887 if sys.platform == "win32": 

888 # check the windows font repository 

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

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

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

892 if windir: 

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

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

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

896 if not data_home: 

897 # The freedesktop spec defines the following default directory for 

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

899 # takes precedence over system-level directories. 

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

901 xdg_dirs = [data_home] 

902 

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

904 if not data_dirs: 

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

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

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

908 

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

910 elif sys.platform == "darwin": 

911 dirs += [ 

912 "/Library/Fonts", 

913 "/System/Library/Fonts", 

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

915 ] 

916 

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

918 first_font_with_a_different_extension = None 

919 for directory in dirs: 

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

921 for walkfilename in walkfilenames: 

922 if ext and walkfilename == ttf_filename: 

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

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

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

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

927 return freetype(fontpath) 

928 if not ext and first_font_with_a_different_extension is None: 

929 first_font_with_a_different_extension = fontpath 

930 if first_font_with_a_different_extension: 

931 return freetype(first_font_with_a_different_extension) 

932 raise 

933 

934 

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

936 """ 

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

938 bitmap font along the Python path. 

939 

940 :param filename: Name of font file. 

941 :return: A font object. 

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

943 """ 

944 if not isinstance(filename, str): 

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

946 for directory in sys.path: 

947 try: 

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

949 except OSError: 

950 pass 

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

952 if os.path.exists(filename): 

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

954 

955 raise OSError(msg) 

956 

957 

958def load_default_imagefont() -> ImageFont: 

959 f = ImageFont() 

960 f._load_pilfont_data( 

961 # courB08 

962 BytesIO( 

963 base64.b64decode( 

964 b""" 

965UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

966AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

967AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

968AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

969AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

970AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

971AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

972AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

973AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

974AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

975AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

976AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA 

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

978AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA 

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

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

981BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB 

982//kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA 

983AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH 

984AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA 

985ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv 

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

987/gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5 

988AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA 

989AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG 

990AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA 

991BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA 

992AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA 

9932AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF 

994AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA//// 

995+gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA 

996////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA 

997BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv 

998AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA 

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

1000AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA 

1001BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP// 

1002//kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA 

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

1004AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB 

1005mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn 

1006AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA 

1007AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7 

1008AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA 

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

1010AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1011AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1012AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1013AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1014AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1015AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1016AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1017AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1018AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1019AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1020AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1021AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB 

1022//sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA 

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

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

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

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

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

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

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

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

1031BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA 

1032Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC 

1033eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG 

1034AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA//// 

1035+gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA 

1036////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA 

1037BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT 

1038AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A 

1039AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA 

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

1041Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP// 

1042//cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA 

1043AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ 

1044AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA 

1045LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5 

1046AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA 

1047AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5 

1048AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA 

1049AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG 

1050AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA 

1051EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK 

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

1053pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG 

1054AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA//// 

1055+QAGAAIAzgAKANUAEw== 

1056""" 

1057 ) 

1058 ), 

1059 Image.open( 

1060 BytesIO( 

1061 base64.b64decode( 

1062 b""" 

1063iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u 

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

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

1066LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F 

1067IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA 

1068Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791 

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

1070in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9 

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

1072AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt 

1073y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG 

1074ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY 

1075lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H 

1076/Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3 

1077AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47 

1078c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/ 

1079/yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw 

1080pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv 

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

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

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

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

1085w7IkEbzhVQAAAABJRU5ErkJggg== 

1086""" 

1087 ) 

1088 ) 

1089 ), 

1090 ) 

1091 return f 

1092 

1093 

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

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

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

1097 

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

1099 

1100 .. versionadded:: 1.1.4 

1101 

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

1103 

1104 .. versionadded:: 10.1.0 

1105 

1106 :return: A font object. 

1107 """ 

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

1109 return truetype( 

1110 BytesIO( 

1111 base64.b64decode( 

1112 b""" 

1113AAEAAAAPAIAAAwBwRkZUTYwDlUAAADFoAAAAHEdERUYAqADnAAAo8AAAACRHUE9ThhmITwAAKfgAA 

1114AduR1NVQnHxefoAACkUAAAA4k9TLzJovoHLAAABeAAAAGBjbWFw5lFQMQAAA6gAAAGqZ2FzcP//AA 

1115MAACjoAAAACGdseWYmRXoPAAAGQAAAHfhoZWFkE18ayQAAAPwAAAA2aGhlYQboArEAAAE0AAAAJGh 

1116tdHjjERZ8AAAB2AAAAdBsb2NhuOexrgAABVQAAADqbWF4cAC7AEYAAAFYAAAAIG5hbWUr+h5lAAAk 

1117OAAAA6Jwb3N0D3oPTQAAJ9wAAAEKAAEAAAABGhxJDqIhXw889QALA+gAAAAA0Bqf2QAAAADhCh2h/ 

11182r/LgOxAyAAAAAIAAIAAAAAAAAAAQAAA8r/GgAAA7j/av9qA7EAAQAAAAAAAAAAAAAAAAAAAHQAAQ 

1119AAAHQAQwAFAAAAAAACAAAAAQABAAAAQAAAAAAAAAADAfoBkAAFAAgCigJYAAAASwKKAlgAAAFeADI 

1120BPgAAAAAFAAAAAAAAAAAAAAcAAAAAAAAAAAAAAABVS1dOAEAAIPsCAwL/GgDIA8oA5iAAAJMAAAAA 

1121AhICsgAAACAAAwH0AAAAAAAAAU0AAADYAAAA8gA5AVMAVgJEAEYCRAA1AuQAKQKOAEAAsAArATsAZ 

1122AE7AB4CMABVAkQAUADc/+EBEgAgANwAJQEv//sCRAApAkQAggJEADwCRAAtAkQAIQJEADkCRAArAk 

1123QAMgJEACwCRAAxANwAJQDc/+ECRABnAkQAUAJEAEQB8wAjA1QANgJ/AB0CcwBkArsALwLFAGQCSwB 

1124kAjcAZALGAC8C2gBkAQgAZAIgADcCYQBkAj8AZANiAGQCzgBkAuEALwJWAGQC3QAvAmsAZAJJADQC 

1125ZAAiAqoAXgJuACADuAAaAnEAGQJFABMCTwAuATMAYgEv//sBJwAiAkQAUAH0ADIBLAApAhMAJAJjA 

1126EoCEQAeAmcAHgIlAB4BIgAVAmcAHgJRAEoA7gA+AOn/8wIKAEoA9wBGA1cASgJRAEoCSgAeAmMASg 

1127JnAB4BSgBKAcsAGAE5ABQCUABCAgIAAQMRAAEB4v/6AgEAAQHOABQBLwBAAPoAYAEvACECRABNA0Y 

1128AJAItAHgBKgAcAkQAUAEsAHQAygAgAi0AOQD3ADYA9wAWAaEANgGhABYCbAAlAYMAeAGDADkA6/9q 

1129AhsAFAIKABUB/QAVAAAAAwAAAAMAAAAcAAEAAAAAAKQAAwABAAAAHAAEAIgAAAAeABAAAwAOAH4Aq 

1130QCrALEAtAC3ALsgGSAdICYgOiBEISL7Av//AAAAIACpAKsAsAC0ALcAuyAYIBwgJiA5IEQhIvsB// 

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

1132AAAAAAAEGAAABAAAAAAAAAAECAAAAAgAAAAAAAAAAAAAAAAAAAAEAAAMEBQYHCAkKCwwNDg8QERIT 

1133FBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMT 

1134U5PUFFSU1RVVldYWVpbXF1eX2BhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQAAA 

1135AAAAAAYnFmAAAAAABlAAAAAAAAAAAAAAAAAAAAAAAAAAAAY2htAAAAAAAAAABrbGlqAAAAAHAAbm9 

1136ycwBnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmACYAJgAmAD4AUgCCAMoBCgFO 

1137AVwBcgGIAaYBvAHKAdYB6AH2AgwCIAJKAogCpgLWAw4DIgNkA5wDugPUA+gD/AQQBEYEogS8BPoFJ 

1138gVSBWoFgAWwBcoF1gX6BhQGJAZMBmgGiga0BuIHGgdUB2YHkAeiB8AH3AfyCAoIHAgqCDoITghcCG 

1139oIogjSCPoJKglYCXwJwgnqCgIKKApACl4Klgq8CtwLDAs8C1YLjAuyC9oL7gwMDCYMSAxgDKAMrAz 

1140qDQoNTA1mDYQNoA2uDcAN2g3oDfYODA4iDkoOXA5sDnoOnA7EDvwAAAAFAAAAAAH0ArwAAwAGAAkA 

1141DAAPAAAxESERAxMhExcRASELARETAfT6qv6syKr+jgFUqsiqArz9RAGLAP/+1P8B/v3VAP8BLP4CA 

1142P8AAgA5//IAuQKyAAMACwAANyMDMwIyFhQGIiY0oE4MZk84JCQ4JLQB/v3AJDgkJDgAAgBWAeUBPA 

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 

1188vArIACwAAJRUhESEVIRUhFSEVAi/+NQHB/pUBTf6zRkYCskbwRvAAAAABAGQAAAIlArIACQAAExUh 

1189FSERIxEhFboBQ/69VgHBAmzwRv7KArJGAAAAAAEAL//yAo8CwAAfAAABMxEjNQcGIyImNTQ2MzIWH 

1190wEjJyYjIgYVFBYzMjY1IwGP90wfPnWTprSSf48LAVYCIqJofHllVG+hAU3+s3hARsicn8uAagoKpq 

1191N/gaN1XAAAAAEAZAAAAowCsgALAAABESMRIREjETMRIRECjFb+hFZWAXwCsv1OAS7+0gKy/sQBPAA 

1192AAAABAGQAAAC6ArIAAwAAMyMRM7pWVgKyAAABADf/8gHoArIAEwAAAREUBw4BIyImLwEzFxYzMjc2 

1193NREB6AIFcGpgbQIBVgIHfXQKAQKy/lYxIltob2EpKYyEFD0BpwAAAAABAGQAAAJ0ArIACwAACQEjA 

1194wcVIxEzEQEzATsBJ3ntQlZWAVVlAWH+nwEnR+ACsv6RAW8AAQBkAAACLwKyAAUAACUVIREzEQIv/j 

1195VWRkYCsv2UAAABAGQAAAMUArIAFAAAAREjETQ3BgcDIwMmJxYVESMRMxsBAxRWAiMxemx8NxsCVo7 

1196MywKy/U4BY7ZLco7+nAFmoFxLtP6dArL9lwJpAAAAAAEAZAAAAoACsgANAAAhIwEWFREjETMBJjUR 

1197MwKAhP67A1aEAUUDVAJeeov+pwKy/aJ5jAFZAAAAAgAv//ICuwLAAAkAEwAAEiAWFRQGICY1NBIyN 

1198jU0JiIGFRTbATSsrP7MrNrYenrYegLAxaKhxsahov47nIeIm5uIhwACAGQAAAJHArIADgAYAAABHg 

1199EVFAYHBisBESMRMzITNjQnJisBETMyAZRUX2VOHzuAVtY7GlxcGDWIiDUCrgtnVlVpCgT+5gKy/rU 

1200V1BUF/vgAAAACAC//zAK9AsAAEgAcAAAlFhcHJiMiBwYjIiY1NDYgFhUUJRQWMjY1NCYiBgI9PUMx 

1201UDcfKh8omqysATSs/dR62Hp62HpICTg7NgkHxqGixcWitbWHnJyHiJubAAIAZAAAAlgCsgAXACMAA 

1202CUWFyMmJyYnJisBESMRMzIXHgEVFAYHFiUzMjc+ATU0JyYrAQIqDCJfGQwNWhAhglbiOx9QXEY1Tv 

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 

1278gQAAwABBAkADAAuAkwATgBvACAAUgBpAGcAaAB0AHMAIABSAGUAcwBlAHIAdgBlAGQALgAATm8gUm 

1279lnaHRzIFJlc2VydmVkLgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAUgBlAGcAdQBsAGEAcgAAUmV 

1280ndWxhcgAAMQAuADEAMAAyADsAVQBLAFcATgA7AEEAaQBsAGUAcgBvAG4ALQBSAGUAZwB1AGwAYQBy 

1281AAAxLjEwMjtVS1dOO0FpbGVyb24tUmVndWxhcgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAVgBlA 

1282HIAcwBpAG8AbgAgADEALgAxADAAMgA7AFAAUwAgADAAMAAxAC4AMQAwADIAOwBoAG8AdABjAG8Abg 

1283B2ACAAMQAuADAALgA3ADAAOwBtAGEAawBlAG8AdABmAC4AbABpAGIAMgAuADUALgA1ADgAMwAyADk 

1284AAFZlcnNpb24gMS4xMDI7UFMgMDAxLjEwMjtob3Rjb252IDEuMC43MDttYWtlb3RmLmxpYjIuNS41 

1285ODMyOQAAQQBpAGwAZQByAG8AbgAtAFIAZQBnAHUAbABhAHIAAEFpbGVyb24tUmVndWxhcgAAUwBvA 

1286HIAYQAgAFMAYQBnAGEAbgBvAABTb3JhIFNhZ2FubwAAUwBvAHIAYQAgAFMAYQBnAGEAbgBvAABTb3 

1287JhIFNhZ2FubwAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBsAG8AbgAuAG4AZQB0AAB 

1288odHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBs 

1289AG8AbgAuAG4AZQB0AABodHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAAAACAAAAAAAA/4MAMgAAAAAAA 

1290AAAAAAAAAAAAAAAAAAAAHQAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATAB 

1291QAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAA 

1292xADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0A 

1293TgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAIsAqQCDAJMAjQDDAKoAtgC3A 

1294LQAtQCrAL4AvwC8AIwAwADBAAAAAAAB//8AAgABAAAADAAAABwAAAACAAIAAwBxAAEAcgBzAAIABA 

1295AAAAIAAAABAAAACgBMAGYAAkRGTFQADmxhdG4AGgAEAAAAAP//AAEAAAAWAANDQVQgAB5NT0wgABZ 

1296ST00gABYAAP//AAEAAAAA//8AAgAAAAEAAmxpZ2EADmxvY2wAFAAAAAEAAQAAAAEAAAACAAYAEAAG 

1297AAAAAgASADQABAAAAAEATAADAAAAAgAQABYAAQAcAAAAAQABAE8AAQABAGcAAQABAE8AAwAAAAIAE 

1298AAWAAEAHAAAAAEAAQAvAAEAAQBnAAEAAQAvAAEAGgABAAgAAgAGAAwAcwACAE8AcgACAEwAAQABAE 

1299kAAAABAAAACgBGAGAAAkRGTFQADmxhdG4AHAAEAAAAAP//AAIAAAABABYAA0NBVCAAFk1PTCAAFlJ 

1300PTSAAFgAA//8AAgAAAAEAAmNwc3AADmtlcm4AFAAAAAEAAAAAAAEAAQACAAYADgABAAAAAQASAAIA 

1301AAACAB4ANgABAAoABQAFAAoAAgABACQAPQAAAAEAEgAEAAAAAQAMAAEAOP/nAAEAAQAkAAIGigAEA 

1302AAFJAXKABoAGQAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

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

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

1305ABD/vQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7gAAAAAAAAAAAAAAAAAA//MAA 

1306AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAP/5AAAAAAAAAA 

1307AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gAAD/4AAAAAAAAAAAAAAAAAA 

1308AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//L/9AAAAAAAAAAAAAAAAAAAAAAA 

1309AAAAAAAAAAAA/+gAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1310AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAAAAA 

1311AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/mAAAAAAAAAAAAAAAAAAD 

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

1313AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zv/qAAAAAP/0AAAACAAAAAAAAAAAAAAAAAAAAAAAA 

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

1315AAAAAAAAAAAAAAAAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

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

1317AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+AAAAAAAAAAAAAAA 

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

1319AAAAAAAAAAAAAAAAAAAAAAAAAAAAD/yAAA/+kAAAAA//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1320AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9wAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1321AAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1322AAAAAAAAP/cAAAAAAAAAAAAAAAA/7YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1323AAAAAAAAAAAAAAAAAAAAAAAAAAAP/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6AAAAAAAAAA 

1324AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAkAFAAEAAAAAQACwAAABcA 

1325BgAAAAAAAAAIAA4AAAAAAAsAEgAAAAAAAAATABkAAwANAAAAAQAJAAAAAAAAAAAAAAAAAAAAGAAAA 

1326AAABwAAAAAAAAAAAAAAFQAFAAAAAAAYABgAAAAUAAAACgAAAAwAAgAPABEAFgAAAAAAAAAAAAAAAA 

1327AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAEAEQBdAAYAAAAAAAAAAAAAAAAAAAAAAAA 

1328AAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAcAAAAAAAAABwAAAAAACAAAAAAAAAAAAAcAAAAHAAAAEwAJ 

1329ABUADgAPAAAACwAQAAAAAAAAAAAAAAAAAAUAGAACAAIAAgAAAAIAGAAXAAAAGAAAABYAFgACABYAA 

1330gAWAAAAEQADAAoAFAAMAA0ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAEgAGAAEAHgAkAC 

1331YAJwApACoALQAuAC8AMgAzADcAOAA5ADoAPAA9AEUASABOAE8AUgBTAFUAVwBZAFoAWwBcAF0AcwA 

1332AAAAAAQAAAADa3tfFAAAAANAan9kAAAAA4QodoQ== 

1333""" 

1334 ) 

1335 ), 

1336 10 if size is None else size, 

1337 layout_engine=Layout.BASIC, 

1338 ) 

1339 return load_default_imagefont()