ImageFont.py 43 KB

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