ImageFont.py 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060
  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. import base64
  28. import os
  29. import sys
  30. import warnings
  31. from io import BytesIO
  32. from . import Image, features
  33. from ._util import isDirectory, isPath
  34. LAYOUT_BASIC = 0
  35. LAYOUT_RAQM = 1
  36. class _imagingft_not_installed:
  37. # module placeholder
  38. def __getattr__(self, id):
  39. raise ImportError("The _imagingft C module is not installed")
  40. try:
  41. from . import _imagingft as core
  42. except ImportError:
  43. core = _imagingft_not_installed()
  44. # FIXME: add support for pilfont2 format (see FontFile.py)
  45. # --------------------------------------------------------------------
  46. # Font metrics format:
  47. # "PILfont" LF
  48. # fontdescriptor LF
  49. # (optional) key=value... LF
  50. # "DATA" LF
  51. # binary data: 256*10*2 bytes (dx, dy, dstbox, srcbox)
  52. #
  53. # To place a character, cut out srcbox and paste at dstbox,
  54. # relative to the character position. Then move the character
  55. # position according to dx, dy.
  56. # --------------------------------------------------------------------
  57. class ImageFont:
  58. "PIL font wrapper"
  59. def _load_pilfont(self, filename):
  60. with open(filename, "rb") as fp:
  61. image = None
  62. for ext in (".png", ".gif", ".pbm"):
  63. if image:
  64. image.close()
  65. try:
  66. fullname = os.path.splitext(filename)[0] + ext
  67. image = Image.open(fullname)
  68. except Exception:
  69. pass
  70. else:
  71. if image and image.mode in ("1", "L"):
  72. break
  73. else:
  74. if image:
  75. image.close()
  76. raise OSError("cannot find glyph data file")
  77. self.file = fullname
  78. self._load_pilfont_data(fp, image)
  79. image.close()
  80. def _load_pilfont_data(self, file, image):
  81. # read PILfont header
  82. if file.readline() != b"PILfont\n":
  83. raise SyntaxError("Not a PILfont file")
  84. file.readline().split(b";")
  85. self.info = [] # FIXME: should be a dictionary
  86. while True:
  87. s = file.readline()
  88. if not s or s == b"DATA\n":
  89. break
  90. self.info.append(s)
  91. # read PILfont metrics
  92. data = file.read(256 * 20)
  93. # check image
  94. if image.mode not in ("1", "L"):
  95. raise TypeError("invalid font image mode")
  96. image.load()
  97. self.font = Image.core.font(image.im, data)
  98. def getsize(self, text, *args, **kwargs):
  99. """
  100. Returns width and height (in pixels) of given text.
  101. :param text: Text to measure.
  102. :return: (width, height)
  103. """
  104. return self.font.getsize(text)
  105. def getmask(self, text, mode="", *args, **kwargs):
  106. """
  107. Create a bitmap for the text.
  108. If the font uses antialiasing, the bitmap should have mode ``L`` and use a
  109. maximum value of 255. Otherwise, it should have mode ``1``.
  110. :param text: Text to render.
  111. :param mode: Used by some graphics drivers to indicate what mode the
  112. driver prefers; if empty, the renderer may return either
  113. mode. Note that the mode is always a string, to simplify
  114. C-level implementations.
  115. .. versionadded:: 1.1.5
  116. :return: An internal PIL storage memory instance as defined by the
  117. :py:mod:`PIL.Image.core` interface module.
  118. """
  119. return self.font.getmask(text, mode)
  120. ##
  121. # Wrapper for FreeType fonts. Application code should use the
  122. # <b>truetype</b> factory function to create font objects.
  123. class FreeTypeFont:
  124. "FreeType font wrapper (requires _imagingft service)"
  125. def __init__(self, font=None, size=10, index=0, encoding="", layout_engine=None):
  126. # FIXME: use service provider instead
  127. self.path = font
  128. self.size = size
  129. self.index = index
  130. self.encoding = encoding
  131. try:
  132. from packaging.version import parse as parse_version
  133. except ImportError:
  134. pass
  135. else:
  136. freetype_version = features.version_module("freetype2")
  137. if freetype_version is not None and parse_version(
  138. freetype_version
  139. ) < parse_version("2.8"):
  140. warnings.warn(
  141. "Support for FreeType 2.7 is deprecated and will be removed"
  142. " in Pillow 9 (2022-01-02). Please upgrade to FreeType 2.8 "
  143. "or newer, preferably FreeType 2.10.4 which fixes "
  144. "CVE-2020-15999.",
  145. DeprecationWarning,
  146. )
  147. if layout_engine not in (LAYOUT_BASIC, LAYOUT_RAQM):
  148. layout_engine = LAYOUT_BASIC
  149. if core.HAVE_RAQM:
  150. layout_engine = LAYOUT_RAQM
  151. elif layout_engine == LAYOUT_RAQM and not core.HAVE_RAQM:
  152. layout_engine = LAYOUT_BASIC
  153. self.layout_engine = layout_engine
  154. def load_from_bytes(f):
  155. self.font_bytes = f.read()
  156. self.font = core.getfont(
  157. "", size, index, encoding, self.font_bytes, layout_engine
  158. )
  159. if isPath(font):
  160. if sys.platform == "win32":
  161. font_bytes_path = font if isinstance(font, bytes) else font.encode()
  162. try:
  163. font_bytes_path.decode("ascii")
  164. except UnicodeDecodeError:
  165. # FreeType cannot load fonts with non-ASCII characters on Windows
  166. # So load it into memory first
  167. with open(font, "rb") as f:
  168. load_from_bytes(f)
  169. return
  170. self.font = core.getfont(
  171. font, size, index, encoding, layout_engine=layout_engine
  172. )
  173. else:
  174. load_from_bytes(font)
  175. def _multiline_split(self, text):
  176. split_character = "\n" if isinstance(text, str) else b"\n"
  177. return text.split(split_character)
  178. def getname(self):
  179. """
  180. :return: A tuple of the font family (e.g. Helvetica) and the font style
  181. (e.g. Bold)
  182. """
  183. return self.font.family, self.font.style
  184. def getmetrics(self):
  185. """
  186. :return: A tuple of the font ascent (the distance from the baseline to
  187. the highest outline point) and descent (the distance from the
  188. baseline to the lowest outline point, a negative value)
  189. """
  190. return self.font.ascent, self.font.descent
  191. def getlength(self, text, mode="", direction=None, features=None, language=None):
  192. """
  193. Returns length (in pixels with 1/64 precision) of given text when rendered
  194. in font with provided direction, features, and language.
  195. This is the amount by which following text should be offset.
  196. Text bounding box may extend past the length in some fonts,
  197. e.g. when using italics or accents.
  198. The result is returned as a float; it is a whole number if using basic layout.
  199. Note that the sum of two lengths may not equal the length of a concatenated
  200. string due to kerning. If you need to adjust for kerning, include the following
  201. character and subtract its length.
  202. For example, instead of
  203. .. code-block:: python
  204. hello = font.getlength("Hello")
  205. world = font.getlength("World")
  206. hello_world = hello + world # not adjusted for kerning
  207. assert hello_world == font.getlength("HelloWorld") # may fail
  208. use
  209. .. code-block:: python
  210. hello = font.getlength("HelloW") - font.getlength("W") # adjusted for kerning
  211. world = font.getlength("World")
  212. hello_world = hello + world # adjusted for kerning
  213. assert hello_world == font.getlength("HelloWorld") # True
  214. or disable kerning with (requires libraqm)
  215. .. code-block:: python
  216. hello = draw.textlength("Hello", font, features=["-kern"])
  217. world = draw.textlength("World", font, features=["-kern"])
  218. hello_world = hello + world # kerning is disabled, no need to adjust
  219. assert hello_world == draw.textlength("HelloWorld", font, features=["-kern"])
  220. .. versionadded:: 8.0.0
  221. :param text: Text to measure.
  222. :param mode: Used by some graphics drivers to indicate what mode the
  223. driver prefers; if empty, the renderer may return either
  224. mode. Note that the mode is always a string, to simplify
  225. C-level implementations.
  226. :param direction: Direction of the text. It can be 'rtl' (right to
  227. left), 'ltr' (left to right) or 'ttb' (top to bottom).
  228. Requires libraqm.
  229. :param features: A list of OpenType font features to be used during text
  230. layout. This is usually used to turn on optional
  231. font features that are not enabled by default,
  232. for example 'dlig' or 'ss01', but can be also
  233. used to turn off default font features for
  234. example '-liga' to disable ligatures or '-kern'
  235. to disable kerning. To get all supported
  236. features, see
  237. https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist
  238. Requires libraqm.
  239. :param language: Language of the text. Different languages may use
  240. different glyph shapes or ligatures. This parameter tells
  241. the font which language the text is in, and to apply the
  242. correct substitutions as appropriate, if available.
  243. It should be a `BCP 47 language code
  244. <https://www.w3.org/International/articles/language-tags/>`_
  245. Requires libraqm.
  246. :return: Width for horizontal, height for vertical text.
  247. """
  248. return self.font.getlength(text, mode, direction, features, language) / 64
  249. def getbbox(
  250. self,
  251. text,
  252. mode="",
  253. direction=None,
  254. features=None,
  255. language=None,
  256. stroke_width=0,
  257. anchor=None,
  258. ):
  259. """
  260. Returns bounding box (in pixels) of given text relative to given anchor
  261. when rendered in font with provided direction, features, and language.
  262. Use :py:meth:`getlength()` to get the offset of following text with
  263. 1/64 pixel precision. The bounding box includes extra margins for
  264. some fonts, e.g. italics or accents.
  265. .. versionadded:: 8.0.0
  266. :param text: Text to render.
  267. :param mode: Used by some graphics drivers to indicate what mode the
  268. driver prefers; if empty, the renderer may return either
  269. mode. Note that the mode is always a string, to simplify
  270. C-level implementations.
  271. :param direction: Direction of the text. It can be 'rtl' (right to
  272. left), 'ltr' (left to right) or 'ttb' (top to bottom).
  273. Requires libraqm.
  274. :param features: A list of OpenType font features to be used during text
  275. layout. This is usually used to turn on optional
  276. font features that are not enabled by default,
  277. for example 'dlig' or 'ss01', but can be also
  278. used to turn off default font features for
  279. example '-liga' to disable ligatures or '-kern'
  280. to disable kerning. To get all supported
  281. features, see
  282. https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist
  283. Requires libraqm.
  284. :param language: Language of the text. Different languages may use
  285. different glyph shapes or ligatures. This parameter tells
  286. the font which language the text is in, and to apply the
  287. correct substitutions as appropriate, if available.
  288. It should be a `BCP 47 language code
  289. <https://www.w3.org/International/articles/language-tags/>`_
  290. Requires libraqm.
  291. :param stroke_width: The width of the text stroke.
  292. :param anchor: The text anchor alignment. Determines the relative location of
  293. the anchor to the text. The default alignment is top left.
  294. See :ref:`text-anchors` for valid values.
  295. :return: ``(left, top, right, bottom)`` bounding box
  296. """
  297. size, offset = self.font.getsize(
  298. text, mode, direction, features, language, anchor
  299. )
  300. left, top = offset[0] - stroke_width, offset[1] - stroke_width
  301. width, height = size[0] + 2 * stroke_width, size[1] + 2 * stroke_width
  302. return left, top, left + width, top + height
  303. def getsize(
  304. self, text, direction=None, features=None, language=None, stroke_width=0
  305. ):
  306. """
  307. Returns width and height (in pixels) of given text if rendered in font with
  308. provided direction, features, and language.
  309. Use :py:meth:`getlength()` to measure the offset of following text with
  310. 1/64 pixel precision.
  311. Use :py:meth:`getbbox()` to get the exact bounding box based on an anchor.
  312. .. note:: For historical reasons this function measures text height from
  313. the ascender line instead of the top, see :ref:`text-anchors`.
  314. If you wish to measure text height from the top, it is recommended
  315. to use the bottom value of :meth:`getbbox` with ``anchor='lt'`` instead.
  316. :param text: Text to measure.
  317. :param direction: Direction of the text. It can be 'rtl' (right to
  318. left), 'ltr' (left to right) or 'ttb' (top to bottom).
  319. Requires libraqm.
  320. .. versionadded:: 4.2.0
  321. :param features: A list of OpenType font features to be used during text
  322. layout. This is usually used to turn on optional
  323. font features that are not enabled by default,
  324. for example 'dlig' or 'ss01', but can be also
  325. used to turn off default font features for
  326. example '-liga' to disable ligatures or '-kern'
  327. to disable kerning. To get all supported
  328. features, see
  329. https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist
  330. Requires libraqm.
  331. .. versionadded:: 4.2.0
  332. :param language: Language of the text. Different languages may use
  333. different glyph shapes or ligatures. This parameter tells
  334. the font which language the text is in, and to apply the
  335. correct substitutions as appropriate, if available.
  336. It should be a `BCP 47 language code
  337. <https://www.w3.org/International/articles/language-tags/>`_
  338. Requires libraqm.
  339. .. versionadded:: 6.0.0
  340. :param stroke_width: The width of the text stroke.
  341. .. versionadded:: 6.2.0
  342. :return: (width, height)
  343. """
  344. # vertical offset is added for historical reasons
  345. # see https://github.com/python-pillow/Pillow/pull/4910#discussion_r486682929
  346. size, offset = self.font.getsize(text, "L", direction, features, language)
  347. return (
  348. size[0] + stroke_width * 2,
  349. size[1] + stroke_width * 2 + offset[1],
  350. )
  351. def getsize_multiline(
  352. self,
  353. text,
  354. direction=None,
  355. spacing=4,
  356. features=None,
  357. language=None,
  358. stroke_width=0,
  359. ):
  360. """
  361. Returns width and height (in pixels) of given text if rendered in font
  362. with provided direction, features, and language, while respecting
  363. newline characters.
  364. :param text: Text to measure.
  365. :param direction: Direction of the text. It can be 'rtl' (right to
  366. left), 'ltr' (left to right) or 'ttb' (top to bottom).
  367. Requires libraqm.
  368. :param spacing: The vertical gap between lines, defaulting to 4 pixels.
  369. :param features: A list of OpenType font features to be used during text
  370. layout. This is usually used to turn on optional
  371. font features that are not enabled by default,
  372. for example 'dlig' or 'ss01', but can be also
  373. used to turn off default font features for
  374. example '-liga' to disable ligatures or '-kern'
  375. to disable kerning. To get all supported
  376. features, see
  377. https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist
  378. Requires libraqm.
  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. .. versionadded:: 6.0.0
  387. :param stroke_width: The width of the text stroke.
  388. .. versionadded:: 6.2.0
  389. :return: (width, height)
  390. """
  391. max_width = 0
  392. lines = self._multiline_split(text)
  393. line_spacing = self.getsize("A", stroke_width=stroke_width)[1] + spacing
  394. for line in lines:
  395. line_width, line_height = self.getsize(
  396. line, direction, features, language, stroke_width
  397. )
  398. max_width = max(max_width, line_width)
  399. return max_width, len(lines) * line_spacing - spacing
  400. def getoffset(self, text):
  401. """
  402. Returns the offset of given text. This is the gap between the
  403. starting coordinate and the first marking. Note that this gap is
  404. included in the result of :py:func:`~PIL.ImageFont.FreeTypeFont.getsize`.
  405. :param text: Text to measure.
  406. :return: A tuple of the x and y offset
  407. """
  408. return self.font.getsize(text)[1]
  409. def getmask(
  410. self,
  411. text,
  412. mode="",
  413. direction=None,
  414. features=None,
  415. language=None,
  416. stroke_width=0,
  417. anchor=None,
  418. ink=0,
  419. ):
  420. """
  421. Create a bitmap for the text.
  422. If the font uses antialiasing, the bitmap should have mode ``L`` and use a
  423. maximum value of 255. If the font has embedded color data, the bitmap
  424. should have mode ``RGBA``. Otherwise, it should have mode ``1``.
  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. .. versionadded:: 1.1.5
  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. .. versionadded:: 4.2.0
  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://docs.microsoft.com/en-us/typography/opentype/spec/featurelist
  444. Requires libraqm.
  445. .. versionadded:: 4.2.0
  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. .. versionadded:: 6.0.0
  454. :param stroke_width: The width of the text stroke.
  455. .. versionadded:: 6.2.0
  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. See :ref:`text-anchors` for valid values.
  459. .. versionadded:: 8.0.0
  460. :param ink: Foreground ink for rendering in RGBA mode.
  461. .. versionadded:: 8.0.0
  462. :return: An internal PIL storage memory instance as defined by the
  463. :py:mod:`PIL.Image.core` interface module.
  464. """
  465. return self.getmask2(
  466. text,
  467. mode,
  468. direction=direction,
  469. features=features,
  470. language=language,
  471. stroke_width=stroke_width,
  472. anchor=anchor,
  473. ink=ink,
  474. )[0]
  475. def getmask2(
  476. self,
  477. text,
  478. mode="",
  479. fill=Image.core.fill,
  480. direction=None,
  481. features=None,
  482. language=None,
  483. stroke_width=0,
  484. anchor=None,
  485. ink=0,
  486. *args,
  487. **kwargs,
  488. ):
  489. """
  490. Create a bitmap for the text.
  491. If the font uses antialiasing, the bitmap should have mode ``L`` and use a
  492. maximum value of 255. If the font has embedded color data, the bitmap
  493. should have mode ``RGBA``. Otherwise, it should have mode ``1``.
  494. :param text: Text to render.
  495. :param mode: Used by some graphics drivers to indicate what mode the
  496. driver prefers; if empty, the renderer may return either
  497. mode. Note that the mode is always a string, to simplify
  498. C-level implementations.
  499. .. versionadded:: 1.1.5
  500. :param direction: Direction of the text. It can be 'rtl' (right to
  501. left), 'ltr' (left to right) or 'ttb' (top to bottom).
  502. Requires libraqm.
  503. .. versionadded:: 4.2.0
  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://docs.microsoft.com/en-us/typography/opentype/spec/featurelist
  513. Requires libraqm.
  514. .. versionadded:: 4.2.0
  515. :param language: Language of the text. Different languages may use
  516. different glyph shapes or ligatures. This parameter tells
  517. the font which language the text is in, and to apply the
  518. correct substitutions as appropriate, if available.
  519. It should be a `BCP 47 language code
  520. <https://www.w3.org/International/articles/language-tags/>`_
  521. Requires libraqm.
  522. .. versionadded:: 6.0.0
  523. :param stroke_width: The width of the text stroke.
  524. .. versionadded:: 6.2.0
  525. :param anchor: The text anchor alignment. Determines the relative location of
  526. the anchor to the text. The default alignment is top left.
  527. See :ref:`text-anchors` for valid values.
  528. .. versionadded:: 8.0.0
  529. :param ink: Foreground ink for rendering in RGBA mode.
  530. .. versionadded:: 8.0.0
  531. :return: A tuple of an internal PIL storage memory instance as defined by the
  532. :py:mod:`PIL.Image.core` interface module, and the text offset, the
  533. gap between the starting coordinate and the first marking
  534. """
  535. size, offset = self.font.getsize(
  536. text, mode, direction, features, language, anchor
  537. )
  538. size = size[0] + stroke_width * 2, size[1] + stroke_width * 2
  539. offset = offset[0] - stroke_width, offset[1] - stroke_width
  540. Image._decompression_bomb_check(size)
  541. im = fill("RGBA" if mode == "RGBA" else "L", size, 0)
  542. self.font.render(
  543. text, im.id, mode, direction, features, language, stroke_width, ink
  544. )
  545. return im, offset
  546. def font_variant(
  547. self, font=None, size=None, index=None, encoding=None, layout_engine=None
  548. ):
  549. """
  550. Create a copy of this FreeTypeFont object,
  551. using any specified arguments to override the settings.
  552. Parameters are identical to the parameters used to initialize this
  553. object.
  554. :return: A FreeTypeFont object.
  555. """
  556. return FreeTypeFont(
  557. font=self.path if font is None else font,
  558. size=self.size if size is None else size,
  559. index=self.index if index is None else index,
  560. encoding=self.encoding if encoding is None else encoding,
  561. layout_engine=layout_engine or self.layout_engine,
  562. )
  563. def get_variation_names(self):
  564. """
  565. :returns: A list of the named styles in a variation font.
  566. :exception OSError: If the font is not a variation font.
  567. """
  568. try:
  569. names = self.font.getvarnames()
  570. except AttributeError as e:
  571. raise NotImplementedError("FreeType 2.9.1 or greater is required") from e
  572. return [name.replace(b"\x00", b"") for name in names]
  573. def set_variation_by_name(self, name):
  574. """
  575. :param name: The name of the style.
  576. :exception OSError: If the font is not a variation font.
  577. """
  578. names = self.get_variation_names()
  579. if not isinstance(name, bytes):
  580. name = name.encode()
  581. index = names.index(name)
  582. if index == getattr(self, "_last_variation_index", None):
  583. # When the same name is set twice in a row,
  584. # there is an 'unknown freetype error'
  585. # https://savannah.nongnu.org/bugs/?56186
  586. return
  587. self._last_variation_index = index
  588. self.font.setvarname(index)
  589. def get_variation_axes(self):
  590. """
  591. :returns: A list of the axes in a variation font.
  592. :exception OSError: If the font is not a variation font.
  593. """
  594. try:
  595. axes = self.font.getvaraxes()
  596. except AttributeError as e:
  597. raise NotImplementedError("FreeType 2.9.1 or greater is required") from e
  598. for axis in axes:
  599. axis["name"] = axis["name"].replace(b"\x00", b"")
  600. return axes
  601. def set_variation_by_axes(self, axes):
  602. """
  603. :param axes: A list of values for each axis.
  604. :exception OSError: If the font is not a variation font.
  605. """
  606. try:
  607. self.font.setvaraxes(axes)
  608. except AttributeError as e:
  609. raise NotImplementedError("FreeType 2.9.1 or greater is required") from e
  610. class TransposedFont:
  611. "Wrapper for writing rotated or mirrored text"
  612. def __init__(self, font, orientation=None):
  613. """
  614. Wrapper that creates a transposed font from any existing font
  615. object.
  616. :param font: A font object.
  617. :param orientation: An optional orientation. If given, this should
  618. be one of Image.FLIP_LEFT_RIGHT, Image.FLIP_TOP_BOTTOM,
  619. Image.ROTATE_90, Image.ROTATE_180, or Image.ROTATE_270.
  620. """
  621. self.font = font
  622. self.orientation = orientation # any 'transpose' argument, or None
  623. def getsize(self, text, *args, **kwargs):
  624. w, h = self.font.getsize(text)
  625. if self.orientation in (Image.ROTATE_90, Image.ROTATE_270):
  626. return h, w
  627. return w, h
  628. def getmask(self, text, mode="", *args, **kwargs):
  629. im = self.font.getmask(text, mode, *args, **kwargs)
  630. if self.orientation is not None:
  631. return im.transpose(self.orientation)
  632. return im
  633. def load(filename):
  634. """
  635. Load a font file. This function loads a font object from the given
  636. bitmap font file, and returns the corresponding font object.
  637. :param filename: Name of font file.
  638. :return: A font object.
  639. :exception OSError: If the file could not be read.
  640. """
  641. f = ImageFont()
  642. f._load_pilfont(filename)
  643. return f
  644. def truetype(font=None, size=10, index=0, encoding="", layout_engine=None):
  645. """
  646. Load a TrueType or OpenType font from a file or file-like object,
  647. and create a font object.
  648. This function loads a font object from the given file or file-like
  649. object, and creates a font object for a font of the given size.
  650. Pillow uses FreeType to open font files. If you are opening many fonts
  651. simultaneously on Windows, be aware that Windows limits the number of files
  652. that can be open in C at once to 512. If you approach that limit, an
  653. ``OSError`` may be thrown, reporting that FreeType "cannot open resource".
  654. This function requires the _imagingft service.
  655. :param font: A filename or file-like object containing a TrueType font.
  656. If the file is not found in this filename, the loader may also
  657. search in other directories, such as the :file:`fonts/`
  658. directory on Windows or :file:`/Library/Fonts/`,
  659. :file:`/System/Library/Fonts/` and :file:`~/Library/Fonts/` on
  660. macOS.
  661. :param size: The requested size, in points.
  662. :param index: Which font face to load (default is first available face).
  663. :param encoding: Which font encoding to use (default is Unicode). Possible
  664. encodings include (see the FreeType documentation for more
  665. information):
  666. * "unic" (Unicode)
  667. * "symb" (Microsoft Symbol)
  668. * "ADOB" (Adobe Standard)
  669. * "ADBE" (Adobe Expert)
  670. * "ADBC" (Adobe Custom)
  671. * "armn" (Apple Roman)
  672. * "sjis" (Shift JIS)
  673. * "gb " (PRC)
  674. * "big5"
  675. * "wans" (Extended Wansung)
  676. * "joha" (Johab)
  677. * "lat1" (Latin-1)
  678. This specifies the character set to use. It does not alter the
  679. encoding of any text provided in subsequent operations.
  680. :param layout_engine: Which layout engine to use, if available:
  681. :data:`.ImageFont.LAYOUT_BASIC` or :data:`.ImageFont.LAYOUT_RAQM`.
  682. You can check support for Raqm layout using
  683. :py:func:`PIL.features.check_feature` with ``feature="raqm"``.
  684. .. versionadded:: 4.2.0
  685. :return: A font object.
  686. :exception OSError: If the file could not be read.
  687. """
  688. def freetype(font):
  689. return FreeTypeFont(font, size, index, encoding, layout_engine)
  690. try:
  691. return freetype(font)
  692. except OSError:
  693. if not isPath(font):
  694. raise
  695. ttf_filename = os.path.basename(font)
  696. dirs = []
  697. if sys.platform == "win32":
  698. # check the windows font repository
  699. # NOTE: must use uppercase WINDIR, to work around bugs in
  700. # 1.5.2's os.environ.get()
  701. windir = os.environ.get("WINDIR")
  702. if windir:
  703. dirs.append(os.path.join(windir, "fonts"))
  704. elif sys.platform in ("linux", "linux2"):
  705. lindirs = os.environ.get("XDG_DATA_DIRS", "")
  706. if not lindirs:
  707. # According to the freedesktop spec, XDG_DATA_DIRS should
  708. # default to /usr/share
  709. lindirs = "/usr/share"
  710. dirs += [os.path.join(lindir, "fonts") for lindir in lindirs.split(":")]
  711. elif sys.platform == "darwin":
  712. dirs += [
  713. "/Library/Fonts",
  714. "/System/Library/Fonts",
  715. os.path.expanduser("~/Library/Fonts"),
  716. ]
  717. ext = os.path.splitext(ttf_filename)[1]
  718. first_font_with_a_different_extension = None
  719. for directory in dirs:
  720. for walkroot, walkdir, walkfilenames in os.walk(directory):
  721. for walkfilename in walkfilenames:
  722. if ext and walkfilename == ttf_filename:
  723. return freetype(os.path.join(walkroot, walkfilename))
  724. elif not ext and os.path.splitext(walkfilename)[0] == ttf_filename:
  725. fontpath = os.path.join(walkroot, walkfilename)
  726. if os.path.splitext(fontpath)[1] == ".ttf":
  727. return freetype(fontpath)
  728. if not ext and first_font_with_a_different_extension is None:
  729. first_font_with_a_different_extension = fontpath
  730. if first_font_with_a_different_extension:
  731. return freetype(first_font_with_a_different_extension)
  732. raise
  733. def load_path(filename):
  734. """
  735. Load font file. Same as :py:func:`~PIL.ImageFont.load`, but searches for a
  736. bitmap font along the Python path.
  737. :param filename: Name of font file.
  738. :return: A font object.
  739. :exception OSError: If the file could not be read.
  740. """
  741. for directory in sys.path:
  742. if isDirectory(directory):
  743. if not isinstance(filename, str):
  744. filename = filename.decode("utf-8")
  745. try:
  746. return load(os.path.join(directory, filename))
  747. except OSError:
  748. pass
  749. raise OSError("cannot find font file")
  750. def load_default():
  751. """Load a "better than nothing" default font.
  752. .. versionadded:: 1.1.4
  753. :return: A font object.
  754. """
  755. f = ImageFont()
  756. f._load_pilfont_data(
  757. # courB08
  758. BytesIO(
  759. base64.b64decode(
  760. b"""
  761. UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  762. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  763. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  764. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  765. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  766. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  767. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  768. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  769. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  770. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  771. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  772. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA
  773. BgAAAAH/+gADAAAAAQAAAAMABgAGAAAAAf/6AAT//QADAAAABgADAAYAAAAA//kABQABAAYAAAAL
  774. AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA
  775. AAAbAAYABgAAAAH/+QAE//wAGwAAAB4AAwAGAAAAAf/5AAQAAQAeAAAAIQAIAAYAAAAB//kABAAB
  776. ACEAAAAkAAgABgAAAAD/+QAE//0AJAAAACgABAAGAAAAAP/6AAX//wAoAAAALQAFAAYAAAAB//8A
  777. BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB
  778. //kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA
  779. AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH
  780. AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA
  781. ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv
  782. AAAAcQAEAAYAAAAA//wAAwACAHEAAAB0AAYABgAAAAD/+gAE//8AdAAAAHgABQAGAAAAAP/7AAT/
  783. /gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5
  784. AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA
  785. AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG
  786. AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA
  787. BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA
  788. AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA
  789. 2AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF
  790. AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA////
  791. +gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA
  792. ////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA
  793. BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv
  794. AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA
  795. AAE9AAEABgAAAAH/+QAE//wBPQAAAUAAAwAGAAAAAP/7AAYAAAFAAAABRgAFAAYAAP////kABQAA
  796. AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA
  797. BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP//
  798. //kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA
  799. AP////kABgAAAXcAAAF+AAcABgAAAAD/+QAGAAABfgAAAYQABwAGAAD////7AAUAAAGEAAABigAF
  800. AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB
  801. mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn
  802. AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA
  803. AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7
  804. AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA
  805. Av/6AAMAAQHdAAAB3gAHAAYAAAAA//kABAABAd4AAAHiAAgABgAAAAD/+wAF//0B4gAAAecAAgAA
  806. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  807. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  808. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  809. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  810. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  811. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  812. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  813. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  814. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  815. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  816. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  817. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB
  818. //sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA
  819. AAAA//oABf//AfQAAAH5AAUABgAAAAD/+QAGAAAB+QAAAf8ABwAGAAAAAv/5AAMAAgH/AAACAAAJ
  820. AAYAAAAA//kABQABAgAAAAIFAAgABgAAAAH/+gAE//sCBQAAAggAAQAGAAAAAP/5AAYAAAIIAAAC
  821. DgAHAAYAAAAB//kABf/+Ag4AAAISAAUABgAA////+wAGAAACEgAAAhkABQAGAAAAAP/7AAX//gIZ
  822. AAACHgADAAYAAAAA//wABf/9Ah4AAAIjAAEABgAAAAD/+QAHAAACIwAAAioABwAGAAAAAP/6AAT/
  823. +wIqAAACLgABAAYAAAAA//kABP/8Ai4AAAIyAAMABgAAAAD/+gAFAAACMgAAAjcABgAGAAAAAf/5
  824. AAT//QI3AAACOgAEAAYAAAAB//kABP/9AjoAAAI9AAQABgAAAAL/+QAE//sCPQAAAj8AAgAGAAD/
  825. ///7AAYAAgI/AAACRgAHAAYAAAAA//kABgABAkYAAAJMAAgABgAAAAH//AAD//0CTAAAAk4AAQAG
  826. AAAAAf//AAQAAgJOAAACUQADAAYAAAAB//kABP/9AlEAAAJUAAQABgAAAAH/+QAF//4CVAAAAlgA
  827. BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA
  828. Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC
  829. eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG
  830. AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA////
  831. +gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA
  832. ////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA
  833. BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT
  834. AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A
  835. AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA
  836. Au4AAALzAAkABgAAAAD/9wAFAAAC8wAAAvgACQAGAAAAAP/4AAUAAAL4AAAC/QAIAAYAAAAA//oA
  837. Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP//
  838. //cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA
  839. AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ
  840. AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA
  841. LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5
  842. AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA
  843. AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5
  844. AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA
  845. AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG
  846. AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA
  847. EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK
  848. AJsAEQAGAAAAAP/6AAX//wCbAAoAoAAPAAYAAAAA//oABQABAKAACgClABEABgAA////+AAGAAAA
  849. pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG
  850. AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA////
  851. +QAGAAIAzgAKANUAEw==
  852. """
  853. )
  854. ),
  855. Image.open(
  856. BytesIO(
  857. base64.b64decode(
  858. b"""
  859. iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u
  860. Mc4b7vuds/xzjz5/3/7u/n9vMe7vnfH/9++vPn/xyf5zhxzjt8GHw8+2d83u8x27199/nxuQ6Od9
  861. M43/5z2I+9n9ZtmDBwMQECDRQw/eQIQohJXxpBCNVE6QCCAAAAD//wBlAJr/AgALyj1t/wINwq0g
  862. LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F
  863. IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA
  864. Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791
  865. NAADfcoIDyP44K/jv4Y63/Z+t98Ovt+ub4T48LAAAAD//wBlAJr/AuplMlADJAAAAGuAphWpqhMx
  866. in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9
  867. SjdavWA8ePHeBIKB//81/83ndznOaXx379wAAAD//wBlAJr/AqDxW+D3AABAAbUh/QMnbQag/gAY
  868. AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt
  869. y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG
  870. ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY
  871. lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H
  872. /Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3
  873. AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47
  874. c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/
  875. /yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw
  876. pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv
  877. oJodAAAAAP//Yqo/83+dxePWlxl3npsel9lvLfPcqlE9725C+acfVLMEAAAA//9i+s9gwCoaaGMR
  878. evta/58PTEWzr21hufPjA8N+qlnBwAAAAAD//2JiWLci5v1+HmFXDqcnULE/MxgYGBj+f6CaJQAA
  879. AAD//2Ji2FrkY3iYpYC5qDeGgeEMAwPDvwQBBoYvcTwOVLMEAAAA//9isDBgkP///0EOg9z35v//
  880. Gc/eeW7BwPj5+QGZhANUswMAAAD//2JgqGBgYGBgqEMXlvhMPUsAAAAA//8iYDd1AAAAAP//AwDR
  881. w7IkEbzhVQAAAABJRU5ErkJggg==
  882. """
  883. )
  884. )
  885. ),
  886. )
  887. return f