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

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 abc 

31import base64 

32import os 

33import sys 

34import warnings 

35from enum import IntEnum 

36from io import BytesIO 

37from types import ModuleType 

38from typing import IO, Any, BinaryIO, TypedDict, cast 

39 

40from . import Image 

41from ._typing import StrOrBytesPath 

42from ._util import DeferredError, is_path 

43 

44TYPE_CHECKING = False 

45if TYPE_CHECKING: 

46 from . import ImageFile 

47 from ._imaging import ImagingFont 

48 from ._imagingft import Font 

49 

50 

51class Axis(TypedDict): 

52 minimum: int | None 

53 default: int | None 

54 maximum: int | None 

55 name: bytes | None 

56 

57 

58class Layout(IntEnum): 

59 BASIC = 0 

60 RAQM = 1 

61 

62 

63MAX_STRING_LENGTH = 1_000_000 

64 

65 

66core: ModuleType | DeferredError 

67try: 

68 from . import _imagingft as core 

69except ImportError as ex: 

70 core = DeferredError.new(ex) 

71 

72 

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

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

75 msg = "too many characters in string" 

76 raise ValueError(msg) 

77 

78 

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

80 

81# -------------------------------------------------------------------- 

82# Font metrics format: 

83# "PILfont" LF 

84# fontdescriptor LF 

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

86# "DATA" LF 

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

88# 

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

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

91# position according to dx, dy. 

92# -------------------------------------------------------------------- 

93 

94 

95class BaseImageFont(abc.ABC): 

96 """Used by ImageDraw and ImageText""" 

97 

98 @abc.abstractmethod 

99 def getbbox( 

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

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

102 pass 

103 

104 @abc.abstractmethod 

105 def getmask( 

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

107 ) -> Image.core.ImagingCore: 

108 pass 

109 

110 @abc.abstractmethod 

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

112 pass 

113 

114 

115class ImageFont(BaseImageFont): 

116 """PIL font wrapper""" 

117 

118 font: ImagingFont 

119 

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

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

122 image: ImageFile.ImageFile | None = None 

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

124 

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

126 if image: 

127 image.close() 

128 try: 

129 fullname = root + ext 

130 image = Image.open(fullname) 

131 except Exception: 

132 pass 

133 else: 

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

135 break 

136 else: 

137 if image: 

138 image.close() 

139 

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

141 raise OSError(msg) 

142 

143 self.file = fullname 

144 

145 self._load_pilfont_data(fp, image) 

146 image.close() 

147 

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

149 # check image 

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

151 image.close() 

152 

153 msg = "invalid font image mode" 

154 raise TypeError(msg) 

155 

156 # read PILfont header 

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

158 image.close() 

159 

160 msg = "Not a PILfont file" 

161 raise SyntaxError(msg) 

162 file.readline() 

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

164 while True: 

165 s = file.readline() 

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

167 break 

168 self.info.append(s) 

169 

170 # read PILfont metrics 

171 data = file.read(256 * 20) 

172 

173 self._load(image, data) 

174 

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

176 image.load() 

177 

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

179 

180 def getmask( 

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

182 ) -> Image.core.ImagingCore: 

183 """ 

184 Create a bitmap for the text. 

185 

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

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

188 

189 :param text: Text to render. 

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

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

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

193 C-level implementations. 

194 

195 .. versionadded:: 1.1.5 

196 

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

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

199 """ 

200 _string_length_check(text) 

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

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

203 

204 def getbbox( 

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

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

207 """ 

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

209 

210 .. versionadded:: 9.2.0 

211 

212 :param text: Text to render. 

213 

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

215 """ 

216 _string_length_check(text) 

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

218 return 0, 0, width, height 

219 

220 def getlength( 

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

222 ) -> int: 

223 """ 

224 Returns length (in pixels) of given text. 

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

226 

227 .. versionadded:: 9.2.0 

228 """ 

229 _string_length_check(text) 

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

231 return width 

232 

233 

234## 

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

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

237 

238 

239class FreeTypeFont(BaseImageFont): 

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

241 

242 font: Font 

243 font_bytes: bytes 

244 

245 def __init__( 

246 self, 

247 font: StrOrBytesPath | BinaryIO, 

248 size: float = 10, 

249 index: int = 0, 

250 encoding: str = "", 

251 layout_engine: Layout | None = None, 

252 ) -> None: 

253 # FIXME: use service provider instead 

254 

255 if isinstance(core, DeferredError): 

256 raise core.ex 

257 

258 if size <= 0: 

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

260 raise ValueError(msg) 

261 

262 self.path = font 

263 self.size = size 

264 self.index = index 

265 self.encoding = encoding 

266 

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

268 layout_engine = Layout.BASIC 

269 if core.HAVE_RAQM: 

270 layout_engine = Layout.RAQM 

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

272 warnings.warn( 

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

274 "Falling back to basic layout." 

275 ) 

276 layout_engine = Layout.BASIC 

277 

278 self.layout_engine = layout_engine 

279 

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

281 self.font_bytes = f.read() 

282 self.font = core.getfont( 

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

284 ) 

285 

286 if is_path(font): 

287 font = os.fspath(font) 

288 if sys.platform == "win32": 

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

290 try: 

291 font_bytes_path.decode("ascii") 

292 except UnicodeDecodeError: 

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

294 # So load it into memory first 

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

296 load_from_bytes(f) 

297 return 

298 self.font = core.getfont( 

299 font, size, index, encoding, layout_engine=layout_engine 

300 ) 

301 else: 

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

303 

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

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

306 

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

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

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

310 

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

312 """ 

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

314 (e.g. Bold) 

315 """ 

316 return self.font.family, self.font.style 

317 

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

319 """ 

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

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

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

323 """ 

324 return self.font.ascent, self.font.descent 

325 

326 def getlength( 

327 self, 

328 text: str | bytes, 

329 mode: str = "", 

330 direction: str | None = None, 

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

332 language: str | None = None, 

333 ) -> float: 

334 """ 

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

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

337 

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

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

340 e.g. when using italics or accents. 

341 

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

343 

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

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

346 character and subtract its length. 

347 

348 For example, instead of :: 

349 

350 hello = font.getlength("Hello") 

351 world = font.getlength("World") 

352 hello_world = hello + world # not adjusted for kerning 

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

354 

355 use :: 

356 

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

358 world = font.getlength("World") 

359 hello_world = hello + world # adjusted for kerning 

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

361 

362 or disable kerning with (requires libraqm) :: 

363 

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

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

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

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

368 

369 .. versionadded:: 8.0.0 

370 

371 :param text: Text to measure. 

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

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

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

375 C-level implementations. 

376 

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

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

379 Requires libraqm. 

380 

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

382 layout. This is usually used to turn on optional 

383 font features that are not enabled by default, 

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

385 used to turn off default font features for 

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

387 to disable kerning. To get all supported 

388 features, see 

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

390 Requires libraqm. 

391 

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

393 different glyph shapes or ligatures. This parameter tells 

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

395 correct substitutions as appropriate, if available. 

396 It should be a `BCP 47 language code 

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

398 Requires libraqm. 

399 

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

401 """ 

402 _string_length_check(text) 

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

404 

405 def getbbox( 

406 self, 

407 text: str | bytes | bytearray, 

408 mode: str = "", 

409 direction: str | None = None, 

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

411 language: str | None = None, 

412 stroke_width: float = 0, 

413 anchor: str | None = None, 

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

415 """ 

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

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

418 

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

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

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

422 

423 .. versionadded:: 8.0.0 

424 

425 :param text: Text to render. 

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

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

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

429 C-level implementations. 

430 

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

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

433 Requires libraqm. 

434 

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

436 layout. This is usually used to turn on optional 

437 font features that are not enabled by default, 

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

439 used to turn off default font features for 

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

441 to disable kerning. To get all supported 

442 features, see 

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

444 Requires libraqm. 

445 

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

447 different glyph shapes or ligatures. This parameter tells 

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

449 correct substitutions as appropriate, if available. 

450 It should be a `BCP 47 language code 

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

452 Requires libraqm. 

453 

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

455 

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

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

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

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

460 

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

462 """ 

463 _string_length_check(text) 

464 size, offset = self.font.getsize( 

465 text, mode, direction, features, language, anchor 

466 ) 

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

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

469 return left, top, left + width, top + height 

470 

471 def getmask( 

472 self, 

473 text: str | bytes, 

474 mode: str = "", 

475 direction: str | None = None, 

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

477 language: str | None = None, 

478 stroke_width: float = 0, 

479 anchor: str | None = None, 

480 ink: int = 0, 

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

482 ) -> Image.core.ImagingCore: 

483 """ 

484 Create a bitmap for the text. 

485 

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

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

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

489 

490 :param text: Text to render. 

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

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

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

494 C-level implementations. 

495 

496 .. versionadded:: 1.1.5 

497 

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

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

500 Requires libraqm. 

501 

502 .. versionadded:: 4.2.0 

503 

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

505 layout. This is usually used to turn on optional 

506 font features that are not enabled by default, 

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

508 used to turn off default font features for 

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

510 to disable kerning. To get all supported 

511 features, see 

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

513 Requires libraqm. 

514 

515 .. versionadded:: 4.2.0 

516 

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

518 different glyph shapes or ligatures. This parameter tells 

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

520 correct substitutions as appropriate, if available. 

521 It should be a `BCP 47 language code 

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

523 Requires libraqm. 

524 

525 .. versionadded:: 6.0.0 

526 

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

528 

529 .. versionadded:: 6.2.0 

530 

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

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

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

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

535 

536 .. versionadded:: 8.0.0 

537 

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

539 

540 .. versionadded:: 8.0.0 

541 

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

543 differently when starting at fractional coordinates. 

544 

545 .. versionadded:: 9.4.0 

546 

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

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

549 """ 

550 return self.getmask2( 

551 text, 

552 mode, 

553 direction=direction, 

554 features=features, 

555 language=language, 

556 stroke_width=stroke_width, 

557 anchor=anchor, 

558 ink=ink, 

559 start=start, 

560 )[0] 

561 

562 def getmask2( 

563 self, 

564 text: str | bytes, 

565 mode: str = "", 

566 direction: str | None = None, 

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

568 language: str | None = None, 

569 stroke_width: float = 0, 

570 anchor: str | None = None, 

571 ink: int = 0, 

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

573 *args: Any, 

574 **kwargs: Any, 

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

576 """ 

577 Create a bitmap for the text. 

578 

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

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

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

582 

583 :param text: Text to render. 

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

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

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

587 C-level implementations. 

588 

589 .. versionadded:: 1.1.5 

590 

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

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

593 Requires libraqm. 

594 

595 .. versionadded:: 4.2.0 

596 

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

598 layout. This is usually used to turn on optional 

599 font features that are not enabled by default, 

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

601 used to turn off default font features for 

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

603 to disable kerning. To get all supported 

604 features, see 

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

606 Requires libraqm. 

607 

608 .. versionadded:: 4.2.0 

609 

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

611 different glyph shapes or ligatures. This parameter tells 

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

613 correct substitutions as appropriate, if available. 

614 It should be a `BCP 47 language code 

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

616 Requires libraqm. 

617 

618 .. versionadded:: 6.0.0 

619 

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

621 

622 .. versionadded:: 6.2.0 

623 

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

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

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

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

628 

629 .. versionadded:: 8.0.0 

630 

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

632 

633 .. versionadded:: 8.0.0 

634 

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

636 differently when starting at fractional coordinates. 

637 

638 .. versionadded:: 9.4.0 

639 

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

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

642 gap between the starting coordinate and the first marking 

643 """ 

644 _string_length_check(text) 

645 if start is None: 

646 start = (0, 0) 

647 

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

649 size = (width, height) 

650 Image._decompression_bomb_check(size) 

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

652 

653 return self.font.render( 

654 text, 

655 fill, 

656 mode, 

657 direction, 

658 features, 

659 language, 

660 stroke_width, 

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

662 anchor, 

663 ink, 

664 start, 

665 ) 

666 

667 def font_variant( 

668 self, 

669 font: StrOrBytesPath | BinaryIO | None = None, 

670 size: float | None = None, 

671 index: int | None = None, 

672 encoding: str | None = None, 

673 layout_engine: Layout | None = None, 

674 ) -> FreeTypeFont: 

675 """ 

676 Create a copy of this FreeTypeFont object, 

677 using any specified arguments to override the settings. 

678 

679 Parameters are identical to the parameters used to initialize this 

680 object. 

681 

682 :return: A FreeTypeFont object. 

683 """ 

684 if font is None: 

685 try: 

686 font = BytesIO(self.font_bytes) 

687 except AttributeError: 

688 font = self.path 

689 return FreeTypeFont( 

690 font=font, 

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

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

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

694 layout_engine=layout_engine or self.layout_engine, 

695 ) 

696 

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

698 """ 

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

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

701 """ 

702 names = [] 

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

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

705 if name not in names: 

706 names.append(name) 

707 return names 

708 

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

710 """ 

711 :param name: The name of the style. 

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

713 """ 

714 names = self.get_variation_names() 

715 if not isinstance(name, bytes): 

716 name = name.encode() 

717 index = names.index(name) + 1 

718 

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

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

721 # there is an 'unknown freetype error' 

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

723 return 

724 self._last_variation_index = index 

725 

726 self.font.setvarname(index) 

727 

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

729 """ 

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

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

732 """ 

733 axes = self.font.getvaraxes() 

734 for axis in axes: 

735 if axis["name"]: 

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

737 return axes 

738 

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

740 """ 

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

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

743 """ 

744 self.font.setvaraxes(axes) 

745 

746 

747class TransposedFont(BaseImageFont): 

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

749 

750 def __init__( 

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

752 ): 

753 """ 

754 Wrapper that creates a transposed font from any existing font 

755 object. 

756 

757 :param font: A font object. 

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

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

760 Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_180, or 

761 Image.Transpose.ROTATE_270. 

762 """ 

763 self.font = font 

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

765 

766 def getmask( 

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

768 ) -> Image.core.ImagingCore: 

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

770 if self.orientation is not None: 

771 return im.transpose(self.orientation) 

772 return im 

773 

774 def getbbox( 

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

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

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

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

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

780 width = right - left 

781 height = bottom - top 

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

783 return 0, 0, height, width 

784 return 0, 0, width, height 

785 

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

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

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

789 raise ValueError(msg) 

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

791 

792 

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

794 """ 

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

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

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

798 

799 :param filename: Name of font file. 

800 :return: A font object. 

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

802 """ 

803 f = ImageFont() 

804 f._load_pilfont(filename) 

805 return f 

806 

807 

808def truetype( 

809 font: StrOrBytesPath | BinaryIO, 

810 size: float = 10, 

811 index: int = 0, 

812 encoding: str = "", 

813 layout_engine: Layout | None = None, 

814) -> FreeTypeFont: 

815 """ 

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

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

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

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

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

821 

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

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

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

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

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

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

828 

829 This function requires the _imagingft service. 

830 

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

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

833 search in other directories, such as: 

834 

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

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

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

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

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

840 the ``XDG_DATA_HOME`` and ``XDG_DATA_DIRS`` environment variables 

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

842 

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

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

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

846 encodings include (see the FreeType documentation for more 

847 information): 

848 

849 * "unic" (Unicode) 

850 * "symb" (Microsoft Symbol) 

851 * "ADOB" (Adobe Standard) 

852 * "ADBE" (Adobe Expert) 

853 * "ADBC" (Adobe Custom) 

854 * "armn" (Apple Roman) 

855 * "sjis" (Shift JIS) 

856 * "gb " (PRC) 

857 * "big5" 

858 * "wans" (Extended Wansung) 

859 * "joha" (Johab) 

860 * "lat1" (Latin-1) 

861 

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

863 encoding of any text provided in subsequent operations. 

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

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

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

867 Otherwise, basic layout will be used. 

868 

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

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

871 

872 You can check support for Raqm layout using 

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

874 

875 .. versionadded:: 4.2.0 

876 :return: A font object. 

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

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

879 """ 

880 

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

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

883 

884 try: 

885 return freetype(font) 

886 except OSError: 

887 if not is_path(font): 

888 raise 

889 ttf_filename = os.path.basename(font) 

890 

891 dirs = [] 

892 if sys.platform == "win32": 

893 # check the windows font repository 

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

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

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

897 if windir: 

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

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

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

901 if not data_home: 

902 # The freedesktop spec defines the following default directory for 

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

904 # takes precedence over system-level directories. 

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

906 xdg_dirs = [data_home] 

907 

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

909 if not data_dirs: 

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

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

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

913 

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

915 elif sys.platform == "darwin": 

916 dirs += [ 

917 "/Library/Fonts", 

918 "/System/Library/Fonts", 

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

920 ] 

921 

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

923 first_font_with_a_different_extension = None 

924 for directory in dirs: 

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

926 for walkfilename in walkfilenames: 

927 if ext and walkfilename == ttf_filename: 

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

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

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

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

932 return freetype(fontpath) 

933 if not ext and first_font_with_a_different_extension is None: 

934 first_font_with_a_different_extension = fontpath 

935 if first_font_with_a_different_extension: 

936 return freetype(first_font_with_a_different_extension) 

937 raise 

938 

939 

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

941 """ 

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

943 bitmap font along the Python path. 

944 

945 :param filename: Name of font file. 

946 :return: A font object. 

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

948 """ 

949 if not isinstance(filename, str): 

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

951 for directory in sys.path: 

952 try: 

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

954 except OSError: # noqa: PERF203 

955 pass 

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

957 if os.path.exists(filename): 

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

959 

960 raise OSError(msg) 

961 

962 

963def load_default_imagefont() -> ImageFont: 

964 f = ImageFont() 

965 f._load_pilfont_data( 

966 # courB08 

967 BytesIO(base64.b64decode(b""" 

968UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

969AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

970AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

971AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

972AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

973AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

974AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

975AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

976AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

977AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

978AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

979AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA 

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

981AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA 

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

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

984BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB 

985//kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA 

986AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH 

987AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA 

988ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv 

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

990/gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5 

991AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA 

992AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG 

993AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA 

994BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA 

995AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA 

9962AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF 

997AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA//// 

998+gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA 

999////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA 

1000BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv 

1001AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA 

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

1003AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA 

1004BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP// 

1005//kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA 

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

1007AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB 

1008mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn 

1009AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA 

1010AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7 

1011AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA 

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

1013AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1014AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1015AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1016AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1017AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1018AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1019AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1020AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1021AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1022AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1023AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1024AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB 

1025//sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA 

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

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

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

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

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

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

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

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

1034BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA 

1035Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC 

1036eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG 

1037AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA//// 

1038+gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA 

1039////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA 

1040BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT 

1041AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A 

1042AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA 

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

1044Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP// 

1045//cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA 

1046AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ 

1047AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA 

1048LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5 

1049AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA 

1050AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5 

1051AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA 

1052AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG 

1053AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA 

1054EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK 

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

1056pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG 

1057AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA//// 

1058+QAGAAIAzgAKANUAEw== 

1059""")), 

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

1061iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u 

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

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

1064LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F 

1065IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA 

1066Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791 

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

1068in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9 

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

1070AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt 

1071y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG 

1072ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY 

1073lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H 

1074/Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3 

1075AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47 

1076c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/ 

1077/yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw 

1078pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv 

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

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

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

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

1083w7IkEbzhVQAAAABJRU5ErkJggg== 

1084"""))), 

1085 ) 

1086 return f 

1087 

1088 

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

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

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

1092 

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

1094 

1095 .. versionadded:: 1.1.4 

1096 

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

1098 

1099 .. versionadded:: 10.1.0 

1100 

1101 :return: A font object. 

1102 """ 

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

1104 return truetype( 

1105 BytesIO(base64.b64decode(b""" 

1106AAEAAAAPAIAAAwBwRkZUTYwDlUAAADFoAAAAHEdERUYAqADnAAAo8AAAACRHUE9ThhmITwAAKfgAA 

1107AduR1NVQnHxefoAACkUAAAA4k9TLzJovoHLAAABeAAAAGBjbWFw5lFQMQAAA6gAAAGqZ2FzcP//AA 

1108MAACjoAAAACGdseWYmRXoPAAAGQAAAHfhoZWFkE18ayQAAAPwAAAA2aGhlYQboArEAAAE0AAAAJGh 

1109tdHjjERZ8AAAB2AAAAdBsb2NhuOexrgAABVQAAADqbWF4cAC7AEYAAAFYAAAAIG5hbWUr+h5lAAAk 

1110OAAAA6Jwb3N0D3oPTQAAJ9wAAAEKAAEAAAABGhxJDqIhXw889QALA+gAAAAA0Bqf2QAAAADhCh2h/ 

11112r/LgOxAyAAAAAIAAIAAAAAAAAAAQAAA8r/GgAAA7j/av9qA7EAAQAAAAAAAAAAAAAAAAAAAHQAAQ 

1112AAAHQAQwAFAAAAAAACAAAAAQABAAAAQAAAAAAAAAADAfoBkAAFAAgCigJYAAAASwKKAlgAAAFeADI 

1113BPgAAAAAFAAAAAAAAAAAAAAcAAAAAAAAAAAAAAABVS1dOAEAAIPsCAwL/GgDIA8oA5iAAAJMAAAAA 

1114AhICsgAAACAAAwH0AAAAAAAAAU0AAADYAAAA8gA5AVMAVgJEAEYCRAA1AuQAKQKOAEAAsAArATsAZ 

1115AE7AB4CMABVAkQAUADc/+EBEgAgANwAJQEv//sCRAApAkQAggJEADwCRAAtAkQAIQJEADkCRAArAk 

1116QAMgJEACwCRAAxANwAJQDc/+ECRABnAkQAUAJEAEQB8wAjA1QANgJ/AB0CcwBkArsALwLFAGQCSwB 

1117kAjcAZALGAC8C2gBkAQgAZAIgADcCYQBkAj8AZANiAGQCzgBkAuEALwJWAGQC3QAvAmsAZAJJADQC 

1118ZAAiAqoAXgJuACADuAAaAnEAGQJFABMCTwAuATMAYgEv//sBJwAiAkQAUAH0ADIBLAApAhMAJAJjA 

1119EoCEQAeAmcAHgIlAB4BIgAVAmcAHgJRAEoA7gA+AOn/8wIKAEoA9wBGA1cASgJRAEoCSgAeAmMASg 

1120JnAB4BSgBKAcsAGAE5ABQCUABCAgIAAQMRAAEB4v/6AgEAAQHOABQBLwBAAPoAYAEvACECRABNA0Y 

1121AJAItAHgBKgAcAkQAUAEsAHQAygAgAi0AOQD3ADYA9wAWAaEANgGhABYCbAAlAYMAeAGDADkA6/9q 

1122AhsAFAIKABUB/QAVAAAAAwAAAAMAAAAcAAEAAAAAAKQAAwABAAAAHAAEAIgAAAAeABAAAwAOAH4Aq 

1123QCrALEAtAC3ALsgGSAdICYgOiBEISL7Av//AAAAIACpAKsAsAC0ALcAuyAYIBwgJiA5IEQhIvsB// 

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

1125AAAAAAAEGAAABAAAAAAAAAAECAAAAAgAAAAAAAAAAAAAAAAAAAAEAAAMEBQYHCAkKCwwNDg8QERIT 

1126FBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMT 

1127U5PUFFSU1RVVldYWVpbXF1eX2BhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQAAA 

1128AAAAAAYnFmAAAAAABlAAAAAAAAAAAAAAAAAAAAAAAAAAAAY2htAAAAAAAAAABrbGlqAAAAAHAAbm9 

1129ycwBnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmACYAJgAmAD4AUgCCAMoBCgFO 

1130AVwBcgGIAaYBvAHKAdYB6AH2AgwCIAJKAogCpgLWAw4DIgNkA5wDugPUA+gD/AQQBEYEogS8BPoFJ 

1131gVSBWoFgAWwBcoF1gX6BhQGJAZMBmgGiga0BuIHGgdUB2YHkAeiB8AH3AfyCAoIHAgqCDoITghcCG 

1132oIogjSCPoJKglYCXwJwgnqCgIKKApACl4Klgq8CtwLDAs8C1YLjAuyC9oL7gwMDCYMSAxgDKAMrAz 

1133qDQoNTA1mDYQNoA2uDcAN2g3oDfYODA4iDkoOXA5sDnoOnA7EDvwAAAAFAAAAAAH0ArwAAwAGAAkA 

1134DAAPAAAxESERAxMhExcRASELARETAfT6qv6syKr+jgFUqsiqArz9RAGLAP/+1P8B/v3VAP8BLP4CA 

1135P8AAgA5//IAuQKyAAMACwAANyMDMwIyFhQGIiY0oE4MZk84JCQ4JLQB/v3AJDgkJDgAAgBWAeUBPA 

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 

1181vArIACwAAJRUhESEVIRUhFSEVAi/+NQHB/pUBTf6zRkYCskbwRvAAAAABAGQAAAIlArIACQAAExUh 

1182FSERIxEhFboBQ/69VgHBAmzwRv7KArJGAAAAAAEAL//yAo8CwAAfAAABMxEjNQcGIyImNTQ2MzIWH 

1183wEjJyYjIgYVFBYzMjY1IwGP90wfPnWTprSSf48LAVYCIqJofHllVG+hAU3+s3hARsicn8uAagoKpq 

1184N/gaN1XAAAAAEAZAAAAowCsgALAAABESMRIREjETMRIRECjFb+hFZWAXwCsv1OAS7+0gKy/sQBPAA 

1185AAAABAGQAAAC6ArIAAwAAMyMRM7pWVgKyAAABADf/8gHoArIAEwAAAREUBw4BIyImLwEzFxYzMjc2 

1186NREB6AIFcGpgbQIBVgIHfXQKAQKy/lYxIltob2EpKYyEFD0BpwAAAAABAGQAAAJ0ArIACwAACQEjA 

1187wcVIxEzEQEzATsBJ3ntQlZWAVVlAWH+nwEnR+ACsv6RAW8AAQBkAAACLwKyAAUAACUVIREzEQIv/j 

1188VWRkYCsv2UAAABAGQAAAMUArIAFAAAAREjETQ3BgcDIwMmJxYVESMRMxsBAxRWAiMxemx8NxsCVo7 

1189MywKy/U4BY7ZLco7+nAFmoFxLtP6dArL9lwJpAAAAAAEAZAAAAoACsgANAAAhIwEWFREjETMBJjUR 

1190MwKAhP67A1aEAUUDVAJeeov+pwKy/aJ5jAFZAAAAAgAv//ICuwLAAAkAEwAAEiAWFRQGICY1NBIyN 

1191jU0JiIGFRTbATSsrP7MrNrYenrYegLAxaKhxsahov47nIeIm5uIhwACAGQAAAJHArIADgAYAAABHg 

1192EVFAYHBisBESMRMzITNjQnJisBETMyAZRUX2VOHzuAVtY7GlxcGDWIiDUCrgtnVlVpCgT+5gKy/rU 

1193V1BUF/vgAAAACAC//zAK9AsAAEgAcAAAlFhcHJiMiBwYjIiY1NDYgFhUUJRQWMjY1NCYiBgI9PUMx 

1194UDcfKh8omqysATSs/dR62Hp62HpICTg7NgkHxqGixcWitbWHnJyHiJubAAIAZAAAAlgCsgAXACMAA 

1195CUWFyMmJyYnJisBESMRMzIXHgEVFAYHFiUzMjc+ATU0JyYrAQIqDCJfGQwNWhAhglbiOx9QXEY1Tv 

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 

1271gQAAwABBAkADAAuAkwATgBvACAAUgBpAGcAaAB0AHMAIABSAGUAcwBlAHIAdgBlAGQALgAATm8gUm 

1272lnaHRzIFJlc2VydmVkLgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAUgBlAGcAdQBsAGEAcgAAUmV 

1273ndWxhcgAAMQAuADEAMAAyADsAVQBLAFcATgA7AEEAaQBsAGUAcgBvAG4ALQBSAGUAZwB1AGwAYQBy 

1274AAAxLjEwMjtVS1dOO0FpbGVyb24tUmVndWxhcgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAVgBlA 

1275HIAcwBpAG8AbgAgADEALgAxADAAMgA7AFAAUwAgADAAMAAxAC4AMQAwADIAOwBoAG8AdABjAG8Abg 

1276B2ACAAMQAuADAALgA3ADAAOwBtAGEAawBlAG8AdABmAC4AbABpAGIAMgAuADUALgA1ADgAMwAyADk 

1277AAFZlcnNpb24gMS4xMDI7UFMgMDAxLjEwMjtob3Rjb252IDEuMC43MDttYWtlb3RmLmxpYjIuNS41 

1278ODMyOQAAQQBpAGwAZQByAG8AbgAtAFIAZQBnAHUAbABhAHIAAEFpbGVyb24tUmVndWxhcgAAUwBvA 

1279HIAYQAgAFMAYQBnAGEAbgBvAABTb3JhIFNhZ2FubwAAUwBvAHIAYQAgAFMAYQBnAGEAbgBvAABTb3 

1280JhIFNhZ2FubwAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBsAG8AbgAuAG4AZQB0AAB 

1281odHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBs 

1282AG8AbgAuAG4AZQB0AABodHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAAAACAAAAAAAA/4MAMgAAAAAAA 

1283AAAAAAAAAAAAAAAAAAAAHQAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATAB 

1284QAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAA 

1285xADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0A 

1286TgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAIsAqQCDAJMAjQDDAKoAtgC3A 

1287LQAtQCrAL4AvwC8AIwAwADBAAAAAAAB//8AAgABAAAADAAAABwAAAACAAIAAwBxAAEAcgBzAAIABA 

1288AAAAIAAAABAAAACgBMAGYAAkRGTFQADmxhdG4AGgAEAAAAAP//AAEAAAAWAANDQVQgAB5NT0wgABZ 

1289ST00gABYAAP//AAEAAAAA//8AAgAAAAEAAmxpZ2EADmxvY2wAFAAAAAEAAQAAAAEAAAACAAYAEAAG 

1290AAAAAgASADQABAAAAAEATAADAAAAAgAQABYAAQAcAAAAAQABAE8AAQABAGcAAQABAE8AAwAAAAIAE 

1291AAWAAEAHAAAAAEAAQAvAAEAAQBnAAEAAQAvAAEAGgABAAgAAgAGAAwAcwACAE8AcgACAEwAAQABAE 

1292kAAAABAAAACgBGAGAAAkRGTFQADmxhdG4AHAAEAAAAAP//AAIAAAABABYAA0NBVCAAFk1PTCAAFlJ 

1293PTSAAFgAA//8AAgAAAAEAAmNwc3AADmtlcm4AFAAAAAEAAAAAAAEAAQACAAYADgABAAAAAQASAAIA 

1294AAACAB4ANgABAAoABQAFAAoAAgABACQAPQAAAAEAEgAEAAAAAQAMAAEAOP/nAAEAAQAkAAIGigAEA 

1295AAFJAXKABoAGQAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

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

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

1298ABD/vQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7gAAAAAAAAAAAAAAAAAA//MAA 

1299AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAP/5AAAAAAAAAA 

1300AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gAAD/4AAAAAAAAAAAAAAAAAA 

1301AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//L/9AAAAAAAAAAAAAAAAAAAAAAA 

1302AAAAAAAAAAAA/+gAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1303AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAAAAA 

1304AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/mAAAAAAAAAAAAAAAAAAD 

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

1306AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zv/qAAAAAP/0AAAACAAAAAAAAAAAAAAAAAAAAAAAA 

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

1308AAAAAAAAAAAAAAAAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

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

1310AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+AAAAAAAAAAAAAAA 

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

1312AAAAAAAAAAAAAAAAAAAAAAAAAAAAD/yAAA/+kAAAAA//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1313AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9wAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1314AAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1315AAAAAAAAP/cAAAAAAAAAAAAAAAA/7YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

1316AAAAAAAAAAAAAAAAAAAAAAAAAAAP/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6AAAAAAAAAA 

1317AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAkAFAAEAAAAAQACwAAABcA 

1318BgAAAAAAAAAIAA4AAAAAAAsAEgAAAAAAAAATABkAAwANAAAAAQAJAAAAAAAAAAAAAAAAAAAAGAAAA 

1319AAABwAAAAAAAAAAAAAAFQAFAAAAAAAYABgAAAAUAAAACgAAAAwAAgAPABEAFgAAAAAAAAAAAAAAAA 

1320AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAEAEQBdAAYAAAAAAAAAAAAAAAAAAAAAAAA 

1321AAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAcAAAAAAAAABwAAAAAACAAAAAAAAAAAAAcAAAAHAAAAEwAJ 

1322ABUADgAPAAAACwAQAAAAAAAAAAAAAAAAAAUAGAACAAIAAgAAAAIAGAAXAAAAGAAAABYAFgACABYAA 

1323gAWAAAAEQADAAoAFAAMAA0ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAEgAGAAEAHgAkAC 

1324YAJwApACoALQAuAC8AMgAzADcAOAA5ADoAPAA9AEUASABOAE8AUgBTAFUAVwBZAFoAWwBcAF0AcwA 

1325AAAAAAQAAAADa3tfFAAAAANAan9kAAAAA4QodoQ== 

1326""")), 

1327 10 if size is None else size, 

1328 layout_engine=Layout.BASIC, 

1329 ) 

1330 return load_default_imagefont()