You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

480 lines
21 KiB

4 years ago
  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. from . import Image
  28. from ._util import isDirectory, isPath, py3
  29. import os
  30. import sys
  31. LAYOUT_BASIC = 0
  32. LAYOUT_RAQM = 1
  33. class _imagingft_not_installed(object):
  34. # module placeholder
  35. def __getattr__(self, id):
  36. raise ImportError("The _imagingft C module is not installed")
  37. try:
  38. from . import _imagingft as core
  39. except ImportError:
  40. core = _imagingft_not_installed()
  41. # FIXME: add support for pilfont2 format (see FontFile.py)
  42. # --------------------------------------------------------------------
  43. # Font metrics format:
  44. # "PILfont" LF
  45. # fontdescriptor LF
  46. # (optional) key=value... LF
  47. # "DATA" LF
  48. # binary data: 256*10*2 bytes (dx, dy, dstbox, srcbox)
  49. #
  50. # To place a character, cut out srcbox and paste at dstbox,
  51. # relative to the character position. Then move the character
  52. # position according to dx, dy.
  53. # --------------------------------------------------------------------
  54. class ImageFont(object):
  55. "PIL font wrapper"
  56. def _load_pilfont(self, filename):
  57. with open(filename, "rb") as fp:
  58. for ext in (".png", ".gif", ".pbm"):
  59. try:
  60. fullname = os.path.splitext(filename)[0] + ext
  61. image = Image.open(fullname)
  62. except:
  63. pass
  64. else:
  65. if image and image.mode in ("1", "L"):
  66. break
  67. else:
  68. raise IOError("cannot find glyph data file")
  69. self.file = fullname
  70. return self._load_pilfont_data(fp, image)
  71. def _load_pilfont_data(self, file, image):
  72. # read PILfont header
  73. if file.readline() != b"PILfont\n":
  74. raise SyntaxError("Not a PILfont file")
  75. file.readline().split(b";")
  76. self.info = [] # FIXME: should be a dictionary
  77. while True:
  78. s = file.readline()
  79. if not s or s == b"DATA\n":
  80. break
  81. self.info.append(s)
  82. # read PILfont metrics
  83. data = file.read(256*20)
  84. # check image
  85. if image.mode not in ("1", "L"):
  86. raise TypeError("invalid font image mode")
  87. image.load()
  88. self.font = Image.core.font(image.im, data)
  89. def getsize(self, text, *args, **kwargs):
  90. return self.font.getsize(text)
  91. def getmask(self, text, mode="", *args, **kwargs):
  92. return self.font.getmask(text, mode)
  93. ##
  94. # Wrapper for FreeType fonts. Application code should use the
  95. # <b>truetype</b> factory function to create font objects.
  96. class FreeTypeFont(object):
  97. "FreeType font wrapper (requires _imagingft service)"
  98. def __init__(self, font=None, size=10, index=0, encoding="",
  99. layout_engine=None):
  100. # FIXME: use service provider instead
  101. self.path = font
  102. self.size = size
  103. self.index = index
  104. self.encoding = encoding
  105. if layout_engine not in (LAYOUT_BASIC, LAYOUT_RAQM):
  106. layout_engine = LAYOUT_BASIC
  107. if core.HAVE_RAQM:
  108. layout_engine = LAYOUT_RAQM
  109. if layout_engine == LAYOUT_RAQM and not core.HAVE_RAQM:
  110. layout_engine = LAYOUT_BASIC
  111. self.layout_engine = layout_engine
  112. if isPath(font):
  113. self.font = core.getfont(font, size, index, encoding,
  114. layout_engine=layout_engine)
  115. else:
  116. self.font_bytes = font.read()
  117. self.font = core.getfont(
  118. "", size, index, encoding, self.font_bytes, layout_engine)
  119. def _multiline_split(self, text):
  120. split_character = "\n" if isinstance(text, str) else b"\n"
  121. return text.split(split_character)
  122. def getname(self):
  123. return self.font.family, self.font.style
  124. def getmetrics(self):
  125. return self.font.ascent, self.font.descent
  126. def getsize(self, text, direction=None, features=None):
  127. size, offset = self.font.getsize(text, direction, features)
  128. return (size[0] + offset[0], size[1] + offset[1])
  129. def getsize_multiline(self, text, direction=None,
  130. spacing=4, features=None):
  131. max_width = 0
  132. lines = self._multiline_split(text)
  133. line_spacing = self.getsize('A')[1] + spacing
  134. for line in lines:
  135. line_width, line_height = self.getsize(line, direction, features)
  136. max_width = max(max_width, line_width)
  137. return max_width, len(lines)*line_spacing - spacing
  138. def getoffset(self, text):
  139. return self.font.getsize(text)[1]
  140. def getmask(self, text, mode="", direction=None, features=None):
  141. return self.getmask2(text, mode, direction=direction,
  142. features=features)[0]
  143. def getmask2(self, text, mode="", fill=Image.core.fill, direction=None,
  144. features=None, *args, **kwargs):
  145. size, offset = self.font.getsize(text, direction, features)
  146. im = fill("L", size, 0)
  147. self.font.render(text, im.id, mode == "1", direction, features)
  148. return im, offset
  149. def font_variant(self, font=None, size=None, index=None, encoding=None,
  150. layout_engine=None):
  151. """
  152. Create a copy of this FreeTypeFont object,
  153. using any specified arguments to override the settings.
  154. Parameters are identical to the parameters used to initialize this
  155. object.
  156. :return: A FreeTypeFont object.
  157. """
  158. return FreeTypeFont(
  159. font=self.path if font is None else font,
  160. size=self.size if size is None else size,
  161. index=self.index if index is None else index,
  162. encoding=self.encoding if encoding is None else encoding,
  163. layout_engine=self.layout_engine if layout_engine is None else layout_engine
  164. )
  165. class TransposedFont(object):
  166. "Wrapper for writing rotated or mirrored text"
  167. def __init__(self, font, orientation=None):
  168. """
  169. Wrapper that creates a transposed font from any existing font
  170. object.
  171. :param font: A font object.
  172. :param orientation: An optional orientation. If given, this should
  173. be one of Image.FLIP_LEFT_RIGHT, Image.FLIP_TOP_BOTTOM,
  174. Image.ROTATE_90, Image.ROTATE_180, or Image.ROTATE_270.
  175. """
  176. self.font = font
  177. self.orientation = orientation # any 'transpose' argument, or None
  178. def getsize(self, text, *args, **kwargs):
  179. w, h = self.font.getsize(text)
  180. if self.orientation in (Image.ROTATE_90, Image.ROTATE_270):
  181. return h, w
  182. return w, h
  183. def getmask(self, text, mode="", *args, **kwargs):
  184. im = self.font.getmask(text, mode, *args, **kwargs)
  185. if self.orientation is not None:
  186. return im.transpose(self.orientation)
  187. return im
  188. def load(filename):
  189. """
  190. Load a font file. This function loads a font object from the given
  191. bitmap font file, and returns the corresponding font object.
  192. :param filename: Name of font file.
  193. :return: A font object.
  194. :exception IOError: If the file could not be read.
  195. """
  196. f = ImageFont()
  197. f._load_pilfont(filename)
  198. return f
  199. def truetype(font=None, size=10, index=0, encoding="",
  200. layout_engine=None):
  201. """
  202. Load a TrueType or OpenType font from a file or file-like object,
  203. and create a font object.
  204. This function loads a font object from the given file or file-like
  205. object, and creates a font object for a font of the given size.
  206. This function requires the _imagingft service.
  207. :param font: A filename or file-like object containing a TrueType font.
  208. Under Windows, if the file is not found in this filename,
  209. the loader also looks in Windows :file:`fonts/` directory.
  210. :param size: The requested size, in points.
  211. :param index: Which font face to load (default is first available face).
  212. :param encoding: Which font encoding to use (default is Unicode). Common
  213. encodings are "unic" (Unicode), "symb" (Microsoft
  214. Symbol), "ADOB" (Adobe Standard), "ADBE" (Adobe Expert),
  215. and "armn" (Apple Roman). See the FreeType documentation
  216. for more information.
  217. :param layout_engine: Which layout engine to use, if available:
  218. `ImageFont.LAYOUT_BASIC` or `ImageFont.LAYOUT_RAQM`.
  219. :return: A font object.
  220. :exception IOError: If the file could not be read.
  221. """
  222. try:
  223. return FreeTypeFont(font, size, index, encoding, layout_engine)
  224. except IOError:
  225. ttf_filename = os.path.basename(font)
  226. dirs = []
  227. if sys.platform == "win32":
  228. # check the windows font repository
  229. # NOTE: must use uppercase WINDIR, to work around bugs in
  230. # 1.5.2's os.environ.get()
  231. windir = os.environ.get("WINDIR")
  232. if windir:
  233. dirs.append(os.path.join(windir, "fonts"))
  234. elif sys.platform in ('linux', 'linux2'):
  235. lindirs = os.environ.get("XDG_DATA_DIRS", "")
  236. if not lindirs:
  237. # According to the freedesktop spec, XDG_DATA_DIRS should
  238. # default to /usr/share
  239. lindirs = '/usr/share'
  240. dirs += [os.path.join(lindir, "fonts")
  241. for lindir in lindirs.split(":")]
  242. elif sys.platform == 'darwin':
  243. dirs += ['/Library/Fonts', '/System/Library/Fonts',
  244. os.path.expanduser('~/Library/Fonts')]
  245. ext = os.path.splitext(ttf_filename)[1]
  246. first_font_with_a_different_extension = None
  247. for directory in dirs:
  248. for walkroot, walkdir, walkfilenames in os.walk(directory):
  249. for walkfilename in walkfilenames:
  250. if ext and walkfilename == ttf_filename:
  251. fontpath = os.path.join(walkroot, walkfilename)
  252. return FreeTypeFont(fontpath, size, index,
  253. encoding, layout_engine)
  254. elif (not ext and
  255. os.path.splitext(walkfilename)[0] == ttf_filename):
  256. fontpath = os.path.join(walkroot, walkfilename)
  257. if os.path.splitext(fontpath)[1] == '.ttf':
  258. return FreeTypeFont(fontpath, size, index,
  259. encoding, layout_engine)
  260. if not ext \
  261. and first_font_with_a_different_extension is None:
  262. first_font_with_a_different_extension = fontpath
  263. if first_font_with_a_different_extension:
  264. return FreeTypeFont(first_font_with_a_different_extension, size,
  265. index, encoding, layout_engine)
  266. raise
  267. def load_path(filename):
  268. """
  269. Load font file. Same as :py:func:`~PIL.ImageFont.load`, but searches for a
  270. bitmap font along the Python path.
  271. :param filename: Name of font file.
  272. :return: A font object.
  273. :exception IOError: If the file could not be read.
  274. """
  275. for directory in sys.path:
  276. if isDirectory(directory):
  277. if not isinstance(filename, str):
  278. if py3:
  279. filename = filename.decode("utf-8")
  280. else:
  281. filename = filename.encode("utf-8")
  282. try:
  283. return load(os.path.join(directory, filename))
  284. except IOError:
  285. pass
  286. raise IOError("cannot find font file")
  287. def load_default():
  288. """Load a "better than nothing" default font.
  289. .. versionadded:: 1.1.4
  290. :return: A font object.
  291. """
  292. from io import BytesIO
  293. import base64
  294. f = ImageFont()
  295. f._load_pilfont_data(
  296. # courB08
  297. BytesIO(base64.b64decode(b'''
  298. UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  299. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  300. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  301. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  302. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  303. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  304. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  305. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  306. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  307. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  308. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  309. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA
  310. BgAAAAH/+gADAAAAAQAAAAMABgAGAAAAAf/6AAT//QADAAAABgADAAYAAAAA//kABQABAAYAAAAL
  311. AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA
  312. AAAbAAYABgAAAAH/+QAE//wAGwAAAB4AAwAGAAAAAf/5AAQAAQAeAAAAIQAIAAYAAAAB//kABAAB
  313. ACEAAAAkAAgABgAAAAD/+QAE//0AJAAAACgABAAGAAAAAP/6AAX//wAoAAAALQAFAAYAAAAB//8A
  314. BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB
  315. //kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA
  316. AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH
  317. AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA
  318. ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv
  319. AAAAcQAEAAYAAAAA//wAAwACAHEAAAB0AAYABgAAAAD/+gAE//8AdAAAAHgABQAGAAAAAP/7AAT/
  320. /gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5
  321. AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA
  322. AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG
  323. AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA
  324. BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA
  325. AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA
  326. 2AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF
  327. AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA////
  328. +gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA
  329. ////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA
  330. BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv
  331. AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA
  332. AAE9AAEABgAAAAH/+QAE//wBPQAAAUAAAwAGAAAAAP/7AAYAAAFAAAABRgAFAAYAAP////kABQAA
  333. AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA
  334. BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP//
  335. //kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA
  336. AP////kABgAAAXcAAAF+AAcABgAAAAD/+QAGAAABfgAAAYQABwAGAAD////7AAUAAAGEAAABigAF
  337. AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB
  338. mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn
  339. AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA
  340. AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7
  341. AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA
  342. Av/6AAMAAQHdAAAB3gAHAAYAAAAA//kABAABAd4AAAHiAAgABgAAAAD/+wAF//0B4gAAAecAAgAA
  343. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  344. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  345. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  346. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  347. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  348. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  349. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  350. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  351. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  352. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  353. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  354. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB
  355. //sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA
  356. AAAA//oABf//AfQAAAH5AAUABgAAAAD/+QAGAAAB+QAAAf8ABwAGAAAAAv/5AAMAAgH/AAACAAAJ
  357. AAYAAAAA//kABQABAgAAAAIFAAgABgAAAAH/+gAE//sCBQAAAggAAQAGAAAAAP/5AAYAAAIIAAAC
  358. DgAHAAYAAAAB//kABf/+Ag4AAAISAAUABgAA////+wAGAAACEgAAAhkABQAGAAAAAP/7AAX//gIZ
  359. AAACHgADAAYAAAAA//wABf/9Ah4AAAIjAAEABgAAAAD/+QAHAAACIwAAAioABwAGAAAAAP/6AAT/
  360. +wIqAAACLgABAAYAAAAA//kABP/8Ai4AAAIyAAMABgAAAAD/+gAFAAACMgAAAjcABgAGAAAAAf/5
  361. AAT//QI3AAACOgAEAAYAAAAB//kABP/9AjoAAAI9AAQABgAAAAL/+QAE//sCPQAAAj8AAgAGAAD/
  362. ///7AAYAAgI/AAACRgAHAAYAAAAA//kABgABAkYAAAJMAAgABgAAAAH//AAD//0CTAAAAk4AAQAG
  363. AAAAAf//AAQAAgJOAAACUQADAAYAAAAB//kABP/9AlEAAAJUAAQABgAAAAH/+QAF//4CVAAAAlgA
  364. BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA
  365. Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC
  366. eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG
  367. AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA////
  368. +gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA
  369. ////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA
  370. BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT
  371. AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A
  372. AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA
  373. Au4AAALzAAkABgAAAAD/9wAFAAAC8wAAAvgACQAGAAAAAP/4AAUAAAL4AAAC/QAIAAYAAAAA//oA
  374. Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP//
  375. //cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA
  376. AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ
  377. AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA
  378. LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5
  379. AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA
  380. AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5
  381. AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA
  382. AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG
  383. AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA
  384. EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK
  385. AJsAEQAGAAAAAP/6AAX//wCbAAoAoAAPAAYAAAAA//oABQABAKAACgClABEABgAA////+AAGAAAA
  386. pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG
  387. AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA////
  388. +QAGAAIAzgAKANUAEw==
  389. ''')), Image.open(BytesIO(base64.b64decode(b'''
  390. iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u
  391. Mc4b7vuds/xzjz5/3/7u/n9vMe7vnfH/9++vPn/xyf5zhxzjt8GHw8+2d83u8x27199/nxuQ6Od9
  392. M43/5z2I+9n9ZtmDBwMQECDRQw/eQIQohJXxpBCNVE6QCCAAAAD//wBlAJr/AgALyj1t/wINwq0g
  393. LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F
  394. IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA
  395. Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791
  396. NAADfcoIDyP44K/jv4Y63/Z+t98Ovt+ub4T48LAAAAD//wBlAJr/AuplMlADJAAAAGuAphWpqhMx
  397. in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9
  398. SjdavWA8ePHeBIKB//81/83ndznOaXx379wAAAD//wBlAJr/AqDxW+D3AABAAbUh/QMnbQag/gAY
  399. AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt
  400. y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG
  401. ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY
  402. lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H
  403. /Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3
  404. AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47
  405. c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/
  406. /yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw
  407. pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv
  408. oJodAAAAAP//Yqo/83+dxePWlxl3npsel9lvLfPcqlE9725C+acfVLMEAAAA//9i+s9gwCoaaGMR
  409. evta/58PTEWzr21hufPjA8N+qlnBwAAAAAD//2JiWLci5v1+HmFXDqcnULE/MxgYGBj+f6CaJQAA
  410. AAD//2Ji2FrkY3iYpYC5qDeGgeEMAwPDvwQBBoYvcTwOVLMEAAAA//9isDBgkP///0EOg9z35v//
  411. Gc/eeW7BwPj5+QGZhANUswMAAAD//2JgqGBgYGBgqEMXlvhMPUsAAAAA//8iYDd1AAAAAP//AwDR
  412. w7IkEbzhVQAAAABJRU5ErkJggg==
  413. '''))))
  414. return f