mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 18:07:51 +03:00 
			
		
		
		
	This better follows PEP 8 style guide: https://www.python.org/dev/peps/pep-0008/#imports > Imports are always put at the top of the file, just after any module > comments and docstrings, and before module globals and constants. This also avoids duplicate import code within the same file.
		
			
				
	
	
		
			851 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			851 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#
 | 
						|
# The Python Imaging Library.
 | 
						|
# $Id$
 | 
						|
#
 | 
						|
# PIL raster font management
 | 
						|
#
 | 
						|
# History:
 | 
						|
# 1996-08-07 fl   created (experimental)
 | 
						|
# 1997-08-25 fl   minor adjustments to handle fonts from pilfont 0.3
 | 
						|
# 1999-02-06 fl   rewrote most font management stuff in C
 | 
						|
# 1999-03-17 fl   take pth files into account in load_path (from Richard Jones)
 | 
						|
# 2001-02-17 fl   added freetype support
 | 
						|
# 2001-05-09 fl   added TransposedFont wrapper class
 | 
						|
# 2002-03-04 fl   make sure we have a "L" or "1" font
 | 
						|
# 2002-12-04 fl   skip non-directory entries in the system path
 | 
						|
# 2003-04-29 fl   add embedded default font
 | 
						|
# 2003-09-27 fl   added support for truetype charmap encodings
 | 
						|
#
 | 
						|
# Todo:
 | 
						|
# Adapt to PILFONT2 format (16-bit fonts, compressed, single file)
 | 
						|
#
 | 
						|
# Copyright (c) 1997-2003 by Secret Labs AB
 | 
						|
# Copyright (c) 1996-2003 by Fredrik Lundh
 | 
						|
#
 | 
						|
# See the README file for information on usage and redistribution.
 | 
						|
#
 | 
						|
 | 
						|
import base64
 | 
						|
import os
 | 
						|
import sys
 | 
						|
from io import BytesIO
 | 
						|
 | 
						|
from . import Image
 | 
						|
from ._util import isDirectory, isPath, py3
 | 
						|
 | 
						|
LAYOUT_BASIC = 0
 | 
						|
LAYOUT_RAQM = 1
 | 
						|
 | 
						|
 | 
						|
class _imagingft_not_installed(object):
 | 
						|
    # module placeholder
 | 
						|
    def __getattr__(self, id):
 | 
						|
        raise ImportError("The _imagingft C module is not installed")
 | 
						|
 | 
						|
 | 
						|
try:
 | 
						|
    from . import _imagingft as core
 | 
						|
except ImportError:
 | 
						|
    core = _imagingft_not_installed()
 | 
						|
 | 
						|
 | 
						|
# FIXME: add support for pilfont2 format (see FontFile.py)
 | 
						|
 | 
						|
# --------------------------------------------------------------------
 | 
						|
# Font metrics format:
 | 
						|
#       "PILfont" LF
 | 
						|
#       fontdescriptor LF
 | 
						|
#       (optional) key=value... LF
 | 
						|
#       "DATA" LF
 | 
						|
#       binary data: 256*10*2 bytes (dx, dy, dstbox, srcbox)
 | 
						|
#
 | 
						|
# To place a character, cut out srcbox and paste at dstbox,
 | 
						|
# relative to the character position.  Then move the character
 | 
						|
# position according to dx, dy.
 | 
						|
# --------------------------------------------------------------------
 | 
						|
 | 
						|
 | 
						|
class ImageFont(object):
 | 
						|
    "PIL font wrapper"
 | 
						|
 | 
						|
    def _load_pilfont(self, filename):
 | 
						|
 | 
						|
        with open(filename, "rb") as fp:
 | 
						|
            for ext in (".png", ".gif", ".pbm"):
 | 
						|
                try:
 | 
						|
                    fullname = os.path.splitext(filename)[0] + ext
 | 
						|
                    image = Image.open(fullname)
 | 
						|
                except Exception:
 | 
						|
                    pass
 | 
						|
                else:
 | 
						|
                    if image and image.mode in ("1", "L"):
 | 
						|
                        break
 | 
						|
            else:
 | 
						|
                raise IOError("cannot find glyph data file")
 | 
						|
 | 
						|
            self.file = fullname
 | 
						|
 | 
						|
            return self._load_pilfont_data(fp, image)
 | 
						|
 | 
						|
    def _load_pilfont_data(self, file, image):
 | 
						|
 | 
						|
        # read PILfont header
 | 
						|
        if file.readline() != b"PILfont\n":
 | 
						|
            raise SyntaxError("Not a PILfont file")
 | 
						|
        file.readline().split(b";")
 | 
						|
        self.info = []  # FIXME: should be a dictionary
 | 
						|
        while True:
 | 
						|
            s = file.readline()
 | 
						|
            if not s or s == b"DATA\n":
 | 
						|
                break
 | 
						|
            self.info.append(s)
 | 
						|
 | 
						|
        # read PILfont metrics
 | 
						|
        data = file.read(256 * 20)
 | 
						|
 | 
						|
        # check image
 | 
						|
        if image.mode not in ("1", "L"):
 | 
						|
            raise TypeError("invalid font image mode")
 | 
						|
 | 
						|
        image.load()
 | 
						|
 | 
						|
        self.font = Image.core.font(image.im, data)
 | 
						|
 | 
						|
    def getsize(self, text, *args, **kwargs):
 | 
						|
        """
 | 
						|
        Returns width and height (in pixels) of given text.
 | 
						|
 | 
						|
        :param text: Text to measure.
 | 
						|
 | 
						|
        :return: (width, height)
 | 
						|
        """
 | 
						|
        return self.font.getsize(text)
 | 
						|
 | 
						|
    def getmask(self, text, mode="", *args, **kwargs):
 | 
						|
        """
 | 
						|
        Create a bitmap for the text.
 | 
						|
 | 
						|
        If the font uses antialiasing, the bitmap should have mode ``L`` and use a
 | 
						|
        maximum value of 255. Otherwise, it should have mode ``1``.
 | 
						|
 | 
						|
        :param text: Text to render.
 | 
						|
        :param mode: Used by some graphics drivers to indicate what mode the
 | 
						|
                     driver prefers; if empty, the renderer may return either
 | 
						|
                     mode. Note that the mode is always a string, to simplify
 | 
						|
                     C-level implementations.
 | 
						|
 | 
						|
                     .. versionadded:: 1.1.5
 | 
						|
 | 
						|
        :return: An internal PIL storage memory instance as defined by the
 | 
						|
                 :py:mod:`PIL.Image.core` interface module.
 | 
						|
        """
 | 
						|
        return self.font.getmask(text, mode)
 | 
						|
 | 
						|
 | 
						|
##
 | 
						|
# Wrapper for FreeType fonts.  Application code should use the
 | 
						|
# <b>truetype</b> factory function to create font objects.
 | 
						|
 | 
						|
 | 
						|
class FreeTypeFont(object):
 | 
						|
    "FreeType font wrapper (requires _imagingft service)"
 | 
						|
 | 
						|
    def __init__(self, font=None, size=10, index=0, encoding="", layout_engine=None):
 | 
						|
        # FIXME: use service provider instead
 | 
						|
 | 
						|
        self.path = font
 | 
						|
        self.size = size
 | 
						|
        self.index = index
 | 
						|
        self.encoding = encoding
 | 
						|
 | 
						|
        if layout_engine not in (LAYOUT_BASIC, LAYOUT_RAQM):
 | 
						|
            layout_engine = LAYOUT_BASIC
 | 
						|
            if core.HAVE_RAQM:
 | 
						|
                layout_engine = LAYOUT_RAQM
 | 
						|
        elif layout_engine == LAYOUT_RAQM and not core.HAVE_RAQM:
 | 
						|
            layout_engine = LAYOUT_BASIC
 | 
						|
 | 
						|
        self.layout_engine = layout_engine
 | 
						|
 | 
						|
        def load_from_bytes(f):
 | 
						|
            self.font_bytes = f.read()
 | 
						|
            self.font = core.getfont(
 | 
						|
                "", size, index, encoding, self.font_bytes, layout_engine
 | 
						|
            )
 | 
						|
 | 
						|
        if isPath(font):
 | 
						|
            if sys.platform == "win32":
 | 
						|
                font_bytes_path = font if isinstance(font, bytes) else font.encode()
 | 
						|
                try:
 | 
						|
                    font_bytes_path.decode("ascii")
 | 
						|
                except UnicodeDecodeError:
 | 
						|
                    # FreeType cannot load fonts with non-ASCII characters on Windows
 | 
						|
                    # So load it into memory first
 | 
						|
                    with open(font, "rb") as f:
 | 
						|
                        load_from_bytes(f)
 | 
						|
                    return
 | 
						|
            self.font = core.getfont(
 | 
						|
                font, size, index, encoding, layout_engine=layout_engine
 | 
						|
            )
 | 
						|
        else:
 | 
						|
            load_from_bytes(font)
 | 
						|
 | 
						|
    def _multiline_split(self, text):
 | 
						|
        split_character = "\n" if isinstance(text, str) else b"\n"
 | 
						|
        return text.split(split_character)
 | 
						|
 | 
						|
    def getname(self):
 | 
						|
        """
 | 
						|
        :return: A tuple of the font family (e.g. Helvetica) and the font style
 | 
						|
            (e.g. Bold)
 | 
						|
        """
 | 
						|
        return self.font.family, self.font.style
 | 
						|
 | 
						|
    def getmetrics(self):
 | 
						|
        """
 | 
						|
        :return: A tuple of the font ascent (the distance from the baseline to
 | 
						|
            the highest outline point) and descent (the distance from the
 | 
						|
            baseline to the lowest outline point, a negative value)
 | 
						|
        """
 | 
						|
        return self.font.ascent, self.font.descent
 | 
						|
 | 
						|
    def getsize(
 | 
						|
        self, text, direction=None, features=None, language=None, stroke_width=0
 | 
						|
    ):
 | 
						|
        """
 | 
						|
        Returns width and height (in pixels) of given text if rendered in font with
 | 
						|
        provided direction, features, and language.
 | 
						|
 | 
						|
        :param text: Text to measure.
 | 
						|
 | 
						|
        :param direction: Direction of the text. It can be 'rtl' (right to
 | 
						|
                          left), 'ltr' (left to right) or 'ttb' (top to bottom).
 | 
						|
                          Requires libraqm.
 | 
						|
 | 
						|
                          .. versionadded:: 4.2.0
 | 
						|
 | 
						|
        :param features: A list of OpenType font features to be used during text
 | 
						|
                         layout. This is usually used to turn on optional
 | 
						|
                         font features that are not enabled by default,
 | 
						|
                         for example 'dlig' or 'ss01', but can be also
 | 
						|
                         used to turn off default font features for
 | 
						|
                         example '-liga' to disable ligatures or '-kern'
 | 
						|
                         to disable kerning.  To get all supported
 | 
						|
                         features, see
 | 
						|
                         https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist
 | 
						|
                         Requires libraqm.
 | 
						|
 | 
						|
                         .. versionadded:: 4.2.0
 | 
						|
 | 
						|
        :param language: Language of the text. Different languages may use
 | 
						|
                         different glyph shapes or ligatures. This parameter tells
 | 
						|
                         the font which language the text is in, and to apply the
 | 
						|
                         correct substitutions as appropriate, if available.
 | 
						|
                         It should be a `BCP 47 language code
 | 
						|
                         <https://www.w3.org/International/articles/language-tags/>`
 | 
						|
                         Requires libraqm.
 | 
						|
 | 
						|
                         .. versionadded:: 6.0.0
 | 
						|
 | 
						|
        :param stroke_width: The width of the text stroke.
 | 
						|
 | 
						|
                         .. versionadded:: 6.2.0
 | 
						|
 | 
						|
        :return: (width, height)
 | 
						|
        """
 | 
						|
        size, offset = self.font.getsize(text, direction, features, language)
 | 
						|
        return (
 | 
						|
            size[0] + stroke_width * 2 + offset[0],
 | 
						|
            size[1] + stroke_width * 2 + offset[1],
 | 
						|
        )
 | 
						|
 | 
						|
    def getsize_multiline(
 | 
						|
        self,
 | 
						|
        text,
 | 
						|
        direction=None,
 | 
						|
        spacing=4,
 | 
						|
        features=None,
 | 
						|
        language=None,
 | 
						|
        stroke_width=0,
 | 
						|
    ):
 | 
						|
        """
 | 
						|
        Returns width and height (in pixels) of given text if rendered in font
 | 
						|
        with provided direction, features, and language, while respecting
 | 
						|
        newline characters.
 | 
						|
 | 
						|
        :param text: Text to measure.
 | 
						|
 | 
						|
        :param direction: Direction of the text. It can be 'rtl' (right to
 | 
						|
                          left), 'ltr' (left to right) or 'ttb' (top to bottom).
 | 
						|
                          Requires libraqm.
 | 
						|
 | 
						|
        :param spacing: The vertical gap between lines, defaulting to 4 pixels.
 | 
						|
 | 
						|
        :param features: A list of OpenType font features to be used during text
 | 
						|
                         layout. This is usually used to turn on optional
 | 
						|
                         font features that are not enabled by default,
 | 
						|
                         for example 'dlig' or 'ss01', but can be also
 | 
						|
                         used to turn off default font features for
 | 
						|
                         example '-liga' to disable ligatures or '-kern'
 | 
						|
                         to disable kerning.  To get all supported
 | 
						|
                         features, see
 | 
						|
                         https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist
 | 
						|
                         Requires libraqm.
 | 
						|
 | 
						|
        :param language: Language of the text. Different languages may use
 | 
						|
                         different glyph shapes or ligatures. This parameter tells
 | 
						|
                         the font which language the text is in, and to apply the
 | 
						|
                         correct substitutions as appropriate, if available.
 | 
						|
                         It should be a `BCP 47 language code
 | 
						|
                         <https://www.w3.org/International/articles/language-tags/>`
 | 
						|
                         Requires libraqm.
 | 
						|
 | 
						|
                         .. versionadded:: 6.0.0
 | 
						|
 | 
						|
        :param stroke_width: The width of the text stroke.
 | 
						|
 | 
						|
                         .. versionadded:: 6.2.0
 | 
						|
 | 
						|
        :return: (width, height)
 | 
						|
        """
 | 
						|
        max_width = 0
 | 
						|
        lines = self._multiline_split(text)
 | 
						|
        line_spacing = self.getsize("A", stroke_width=stroke_width)[1] + spacing
 | 
						|
        for line in lines:
 | 
						|
            line_width, line_height = self.getsize(
 | 
						|
                line, direction, features, language, stroke_width
 | 
						|
            )
 | 
						|
            max_width = max(max_width, line_width)
 | 
						|
 | 
						|
        return max_width, len(lines) * line_spacing - spacing
 | 
						|
 | 
						|
    def getoffset(self, text):
 | 
						|
        """
 | 
						|
        Returns the offset of given text. This is the gap between the
 | 
						|
        starting coordinate and the first marking. Note that this gap is
 | 
						|
        included in the result of :py:func:`~PIL.ImageFont.FreeTypeFont.getsize`.
 | 
						|
 | 
						|
        :param text: Text to measure.
 | 
						|
 | 
						|
        :return: A tuple of the x and y offset
 | 
						|
        """
 | 
						|
        return self.font.getsize(text)[1]
 | 
						|
 | 
						|
    def getmask(
 | 
						|
        self,
 | 
						|
        text,
 | 
						|
        mode="",
 | 
						|
        direction=None,
 | 
						|
        features=None,
 | 
						|
        language=None,
 | 
						|
        stroke_width=0,
 | 
						|
    ):
 | 
						|
        """
 | 
						|
        Create a bitmap for the text.
 | 
						|
 | 
						|
        If the font uses antialiasing, the bitmap should have mode ``L`` and use a
 | 
						|
        maximum value of 255. Otherwise, it should have mode ``1``.
 | 
						|
 | 
						|
        :param text: Text to render.
 | 
						|
        :param mode: Used by some graphics drivers to indicate what mode the
 | 
						|
                     driver prefers; if empty, the renderer may return either
 | 
						|
                     mode. Note that the mode is always a string, to simplify
 | 
						|
                     C-level implementations.
 | 
						|
 | 
						|
                     .. versionadded:: 1.1.5
 | 
						|
 | 
						|
        :param direction: Direction of the text. It can be 'rtl' (right to
 | 
						|
                          left), 'ltr' (left to right) or 'ttb' (top to bottom).
 | 
						|
                          Requires libraqm.
 | 
						|
 | 
						|
                          .. versionadded:: 4.2.0
 | 
						|
 | 
						|
        :param features: A list of OpenType font features to be used during text
 | 
						|
                         layout. This is usually used to turn on optional
 | 
						|
                         font features that are not enabled by default,
 | 
						|
                         for example 'dlig' or 'ss01', but can be also
 | 
						|
                         used to turn off default font features for
 | 
						|
                         example '-liga' to disable ligatures or '-kern'
 | 
						|
                         to disable kerning.  To get all supported
 | 
						|
                         features, see
 | 
						|
                         https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist
 | 
						|
                         Requires libraqm.
 | 
						|
 | 
						|
                         .. versionadded:: 4.2.0
 | 
						|
 | 
						|
        :param language: Language of the text. Different languages may use
 | 
						|
                         different glyph shapes or ligatures. This parameter tells
 | 
						|
                         the font which language the text is in, and to apply the
 | 
						|
                         correct substitutions as appropriate, if available.
 | 
						|
                         It should be a `BCP 47 language code
 | 
						|
                         <https://www.w3.org/International/articles/language-tags/>`
 | 
						|
                         Requires libraqm.
 | 
						|
 | 
						|
                         .. versionadded:: 6.0.0
 | 
						|
 | 
						|
        :param stroke_width: The width of the text stroke.
 | 
						|
 | 
						|
                         .. versionadded:: 6.2.0
 | 
						|
 | 
						|
        :return: An internal PIL storage memory instance as defined by the
 | 
						|
                 :py:mod:`PIL.Image.core` interface module.
 | 
						|
        """
 | 
						|
        return self.getmask2(
 | 
						|
            text,
 | 
						|
            mode,
 | 
						|
            direction=direction,
 | 
						|
            features=features,
 | 
						|
            language=language,
 | 
						|
            stroke_width=stroke_width,
 | 
						|
        )[0]
 | 
						|
 | 
						|
    def getmask2(
 | 
						|
        self,
 | 
						|
        text,
 | 
						|
        mode="",
 | 
						|
        fill=Image.core.fill,
 | 
						|
        direction=None,
 | 
						|
        features=None,
 | 
						|
        language=None,
 | 
						|
        stroke_width=0,
 | 
						|
        *args,
 | 
						|
        **kwargs
 | 
						|
    ):
 | 
						|
        """
 | 
						|
        Create a bitmap for the text.
 | 
						|
 | 
						|
        If the font uses antialiasing, the bitmap should have mode ``L`` and use a
 | 
						|
        maximum value of 255. Otherwise, it should have mode ``1``.
 | 
						|
 | 
						|
        :param text: Text to render.
 | 
						|
        :param mode: Used by some graphics drivers to indicate what mode the
 | 
						|
                     driver prefers; if empty, the renderer may return either
 | 
						|
                     mode. Note that the mode is always a string, to simplify
 | 
						|
                     C-level implementations.
 | 
						|
 | 
						|
                     .. versionadded:: 1.1.5
 | 
						|
 | 
						|
        :param direction: Direction of the text. It can be 'rtl' (right to
 | 
						|
                          left), 'ltr' (left to right) or 'ttb' (top to bottom).
 | 
						|
                          Requires libraqm.
 | 
						|
 | 
						|
                          .. versionadded:: 4.2.0
 | 
						|
 | 
						|
        :param features: A list of OpenType font features to be used during text
 | 
						|
                         layout. This is usually used to turn on optional
 | 
						|
                         font features that are not enabled by default,
 | 
						|
                         for example 'dlig' or 'ss01', but can be also
 | 
						|
                         used to turn off default font features for
 | 
						|
                         example '-liga' to disable ligatures or '-kern'
 | 
						|
                         to disable kerning.  To get all supported
 | 
						|
                         features, see
 | 
						|
                         https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist
 | 
						|
                         Requires libraqm.
 | 
						|
 | 
						|
                         .. versionadded:: 4.2.0
 | 
						|
 | 
						|
        :param language: Language of the text. Different languages may use
 | 
						|
                         different glyph shapes or ligatures. This parameter tells
 | 
						|
                         the font which language the text is in, and to apply the
 | 
						|
                         correct substitutions as appropriate, if available.
 | 
						|
                         It should be a `BCP 47 language code
 | 
						|
                         <https://www.w3.org/International/articles/language-tags/>`
 | 
						|
                         Requires libraqm.
 | 
						|
 | 
						|
                         .. versionadded:: 6.0.0
 | 
						|
 | 
						|
        :param stroke_width: The width of the text stroke.
 | 
						|
 | 
						|
                         .. versionadded:: 6.2.0
 | 
						|
 | 
						|
        :return: A tuple of an internal PIL storage memory instance as defined by the
 | 
						|
                 :py:mod:`PIL.Image.core` interface module, and the text offset, the
 | 
						|
                 gap between the starting coordinate and the first marking
 | 
						|
        """
 | 
						|
        size, offset = self.font.getsize(text, direction, features, language)
 | 
						|
        size = size[0] + stroke_width * 2, size[1] + stroke_width * 2
 | 
						|
        im = fill("L", size, 0)
 | 
						|
        self.font.render(
 | 
						|
            text, im.id, mode == "1", direction, features, language, stroke_width
 | 
						|
        )
 | 
						|
        return im, offset
 | 
						|
 | 
						|
    def font_variant(
 | 
						|
        self, font=None, size=None, index=None, encoding=None, layout_engine=None
 | 
						|
    ):
 | 
						|
        """
 | 
						|
        Create a copy of this FreeTypeFont object,
 | 
						|
        using any specified arguments to override the settings.
 | 
						|
 | 
						|
        Parameters are identical to the parameters used to initialize this
 | 
						|
        object.
 | 
						|
 | 
						|
        :return: A FreeTypeFont object.
 | 
						|
        """
 | 
						|
        return FreeTypeFont(
 | 
						|
            font=self.path if font is None else font,
 | 
						|
            size=self.size if size is None else size,
 | 
						|
            index=self.index if index is None else index,
 | 
						|
            encoding=self.encoding if encoding is None else encoding,
 | 
						|
            layout_engine=layout_engine or self.layout_engine,
 | 
						|
        )
 | 
						|
 | 
						|
    def get_variation_names(self):
 | 
						|
        """
 | 
						|
        :returns: A list of the named styles in a variation font.
 | 
						|
        :exception IOError: If the font is not a variation font.
 | 
						|
        """
 | 
						|
        try:
 | 
						|
            names = self.font.getvarnames()
 | 
						|
        except AttributeError:
 | 
						|
            raise NotImplementedError("FreeType 2.9.1 or greater is required")
 | 
						|
        return [name.replace(b"\x00", b"") for name in names]
 | 
						|
 | 
						|
    def set_variation_by_name(self, name):
 | 
						|
        """
 | 
						|
        :param name: The name of the style.
 | 
						|
        :exception IOError: If the font is not a variation font.
 | 
						|
        """
 | 
						|
        names = self.get_variation_names()
 | 
						|
        if not isinstance(name, bytes):
 | 
						|
            name = name.encode()
 | 
						|
        index = names.index(name)
 | 
						|
 | 
						|
        if index == getattr(self, "_last_variation_index", None):
 | 
						|
            # When the same name is set twice in a row,
 | 
						|
            # there is an 'unknown freetype error'
 | 
						|
            # https://savannah.nongnu.org/bugs/?56186
 | 
						|
            return
 | 
						|
        self._last_variation_index = index
 | 
						|
 | 
						|
        self.font.setvarname(index)
 | 
						|
 | 
						|
    def get_variation_axes(self):
 | 
						|
        """
 | 
						|
        :returns: A list of the axes in a variation font.
 | 
						|
        :exception IOError: If the font is not a variation font.
 | 
						|
        """
 | 
						|
        try:
 | 
						|
            axes = self.font.getvaraxes()
 | 
						|
        except AttributeError:
 | 
						|
            raise NotImplementedError("FreeType 2.9.1 or greater is required")
 | 
						|
        for axis in axes:
 | 
						|
            axis["name"] = axis["name"].replace(b"\x00", b"")
 | 
						|
        return axes
 | 
						|
 | 
						|
    def set_variation_by_axes(self, axes):
 | 
						|
        """
 | 
						|
        :param axes: A list of values for each axis.
 | 
						|
        :exception IOError: If the font is not a variation font.
 | 
						|
        """
 | 
						|
        try:
 | 
						|
            self.font.setvaraxes(axes)
 | 
						|
        except AttributeError:
 | 
						|
            raise NotImplementedError("FreeType 2.9.1 or greater is required")
 | 
						|
 | 
						|
 | 
						|
class TransposedFont(object):
 | 
						|
    "Wrapper for writing rotated or mirrored text"
 | 
						|
 | 
						|
    def __init__(self, font, orientation=None):
 | 
						|
        """
 | 
						|
        Wrapper that creates a transposed font from any existing font
 | 
						|
        object.
 | 
						|
 | 
						|
        :param font: A font object.
 | 
						|
        :param orientation: An optional orientation.  If given, this should
 | 
						|
            be one of Image.FLIP_LEFT_RIGHT, Image.FLIP_TOP_BOTTOM,
 | 
						|
            Image.ROTATE_90, Image.ROTATE_180, or Image.ROTATE_270.
 | 
						|
        """
 | 
						|
        self.font = font
 | 
						|
        self.orientation = orientation  # any 'transpose' argument, or None
 | 
						|
 | 
						|
    def getsize(self, text, *args, **kwargs):
 | 
						|
        w, h = self.font.getsize(text)
 | 
						|
        if self.orientation in (Image.ROTATE_90, Image.ROTATE_270):
 | 
						|
            return h, w
 | 
						|
        return w, h
 | 
						|
 | 
						|
    def getmask(self, text, mode="", *args, **kwargs):
 | 
						|
        im = self.font.getmask(text, mode, *args, **kwargs)
 | 
						|
        if self.orientation is not None:
 | 
						|
            return im.transpose(self.orientation)
 | 
						|
        return im
 | 
						|
 | 
						|
 | 
						|
def load(filename):
 | 
						|
    """
 | 
						|
    Load a font file.  This function loads a font object from the given
 | 
						|
    bitmap font file, and returns the corresponding font object.
 | 
						|
 | 
						|
    :param filename: Name of font file.
 | 
						|
    :return: A font object.
 | 
						|
    :exception IOError: If the file could not be read.
 | 
						|
    """
 | 
						|
    f = ImageFont()
 | 
						|
    f._load_pilfont(filename)
 | 
						|
    return f
 | 
						|
 | 
						|
 | 
						|
def truetype(font=None, size=10, index=0, encoding="", layout_engine=None):
 | 
						|
    """
 | 
						|
    Load a TrueType or OpenType font from a file or file-like object,
 | 
						|
    and create a font object.
 | 
						|
    This function loads a font object from the given file or file-like
 | 
						|
    object, and creates a font object for a font of the given size.
 | 
						|
 | 
						|
    Pillow uses FreeType to open font files. If you are opening many fonts
 | 
						|
    simultaneously on Windows, be aware that Windows limits the number of files
 | 
						|
    that can be open in C at once to 512. If you approach that limit, an
 | 
						|
    ``OSError`` may be thrown, reporting that FreeType "cannot open resource".
 | 
						|
 | 
						|
    This function requires the _imagingft service.
 | 
						|
 | 
						|
    :param font: A filename or file-like object containing a TrueType font.
 | 
						|
                 If the file is not found in this filename, the loader may also
 | 
						|
                 search in other directories, such as the :file:`fonts/`
 | 
						|
                 directory on Windows or :file:`/Library/Fonts/`,
 | 
						|
                 :file:`/System/Library/Fonts/` and :file:`~/Library/Fonts/` on
 | 
						|
                 macOS.
 | 
						|
 | 
						|
    :param size: The requested size, in points.
 | 
						|
    :param index: Which font face to load (default is first available face).
 | 
						|
    :param encoding: Which font encoding to use (default is Unicode). Possible
 | 
						|
                     encodings include (see the FreeType documentation for more
 | 
						|
                     information):
 | 
						|
 | 
						|
                     * "unic" (Unicode)
 | 
						|
                     * "symb" (Microsoft Symbol)
 | 
						|
                     * "ADOB" (Adobe Standard)
 | 
						|
                     * "ADBE" (Adobe Expert)
 | 
						|
                     * "ADBC" (Adobe Custom)
 | 
						|
                     * "armn" (Apple Roman)
 | 
						|
                     * "sjis" (Shift JIS)
 | 
						|
                     * "gb  " (PRC)
 | 
						|
                     * "big5"
 | 
						|
                     * "wans" (Extended Wansung)
 | 
						|
                     * "joha" (Johab)
 | 
						|
                     * "lat1" (Latin-1)
 | 
						|
 | 
						|
                     This specifies the character set to use. It does not alter the
 | 
						|
                     encoding of any text provided in subsequent operations.
 | 
						|
    :param layout_engine: Which layout engine to use, if available:
 | 
						|
                     `ImageFont.LAYOUT_BASIC` or `ImageFont.LAYOUT_RAQM`.
 | 
						|
    :return: A font object.
 | 
						|
    :exception IOError: If the file could not be read.
 | 
						|
    """
 | 
						|
 | 
						|
    def freetype(font):
 | 
						|
        return FreeTypeFont(font, size, index, encoding, layout_engine)
 | 
						|
 | 
						|
    try:
 | 
						|
        return freetype(font)
 | 
						|
    except IOError:
 | 
						|
        if not isPath(font):
 | 
						|
            raise
 | 
						|
        ttf_filename = os.path.basename(font)
 | 
						|
 | 
						|
        dirs = []
 | 
						|
        if sys.platform == "win32":
 | 
						|
            # check the windows font repository
 | 
						|
            # NOTE: must use uppercase WINDIR, to work around bugs in
 | 
						|
            # 1.5.2's os.environ.get()
 | 
						|
            windir = os.environ.get("WINDIR")
 | 
						|
            if windir:
 | 
						|
                dirs.append(os.path.join(windir, "fonts"))
 | 
						|
        elif sys.platform in ("linux", "linux2"):
 | 
						|
            lindirs = os.environ.get("XDG_DATA_DIRS", "")
 | 
						|
            if not lindirs:
 | 
						|
                # According to the freedesktop spec, XDG_DATA_DIRS should
 | 
						|
                # default to /usr/share
 | 
						|
                lindirs = "/usr/share"
 | 
						|
            dirs += [os.path.join(lindir, "fonts") for lindir in lindirs.split(":")]
 | 
						|
        elif sys.platform == "darwin":
 | 
						|
            dirs += [
 | 
						|
                "/Library/Fonts",
 | 
						|
                "/System/Library/Fonts",
 | 
						|
                os.path.expanduser("~/Library/Fonts"),
 | 
						|
            ]
 | 
						|
 | 
						|
        ext = os.path.splitext(ttf_filename)[1]
 | 
						|
        first_font_with_a_different_extension = None
 | 
						|
        for directory in dirs:
 | 
						|
            for walkroot, walkdir, walkfilenames in os.walk(directory):
 | 
						|
                for walkfilename in walkfilenames:
 | 
						|
                    if ext and walkfilename == ttf_filename:
 | 
						|
                        return freetype(os.path.join(walkroot, walkfilename))
 | 
						|
                    elif not ext and os.path.splitext(walkfilename)[0] == ttf_filename:
 | 
						|
                        fontpath = os.path.join(walkroot, walkfilename)
 | 
						|
                        if os.path.splitext(fontpath)[1] == ".ttf":
 | 
						|
                            return freetype(fontpath)
 | 
						|
                        if not ext and first_font_with_a_different_extension is None:
 | 
						|
                            first_font_with_a_different_extension = fontpath
 | 
						|
        if first_font_with_a_different_extension:
 | 
						|
            return freetype(first_font_with_a_different_extension)
 | 
						|
        raise
 | 
						|
 | 
						|
 | 
						|
def load_path(filename):
 | 
						|
    """
 | 
						|
    Load font file. Same as :py:func:`~PIL.ImageFont.load`, but searches for a
 | 
						|
    bitmap font along the Python path.
 | 
						|
 | 
						|
    :param filename: Name of font file.
 | 
						|
    :return: A font object.
 | 
						|
    :exception IOError: If the file could not be read.
 | 
						|
    """
 | 
						|
    for directory in sys.path:
 | 
						|
        if isDirectory(directory):
 | 
						|
            if not isinstance(filename, str):
 | 
						|
                if py3:
 | 
						|
                    filename = filename.decode("utf-8")
 | 
						|
                else:
 | 
						|
                    filename = filename.encode("utf-8")
 | 
						|
            try:
 | 
						|
                return load(os.path.join(directory, filename))
 | 
						|
            except IOError:
 | 
						|
                pass
 | 
						|
    raise IOError("cannot find font file")
 | 
						|
 | 
						|
 | 
						|
def load_default():
 | 
						|
    """Load a "better than nothing" default font.
 | 
						|
 | 
						|
    .. versionadded:: 1.1.4
 | 
						|
 | 
						|
    :return: A font object.
 | 
						|
    """
 | 
						|
    f = ImageFont()
 | 
						|
    f._load_pilfont_data(
 | 
						|
        # courB08
 | 
						|
        BytesIO(
 | 
						|
            base64.b64decode(
 | 
						|
                b"""
 | 
						|
UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA
 | 
						|
BgAAAAH/+gADAAAAAQAAAAMABgAGAAAAAf/6AAT//QADAAAABgADAAYAAAAA//kABQABAAYAAAAL
 | 
						|
AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA
 | 
						|
AAAbAAYABgAAAAH/+QAE//wAGwAAAB4AAwAGAAAAAf/5AAQAAQAeAAAAIQAIAAYAAAAB//kABAAB
 | 
						|
ACEAAAAkAAgABgAAAAD/+QAE//0AJAAAACgABAAGAAAAAP/6AAX//wAoAAAALQAFAAYAAAAB//8A
 | 
						|
BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB
 | 
						|
//kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA
 | 
						|
AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH
 | 
						|
AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA
 | 
						|
ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv
 | 
						|
AAAAcQAEAAYAAAAA//wAAwACAHEAAAB0AAYABgAAAAD/+gAE//8AdAAAAHgABQAGAAAAAP/7AAT/
 | 
						|
/gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5
 | 
						|
AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA
 | 
						|
AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG
 | 
						|
AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA
 | 
						|
BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA
 | 
						|
AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA
 | 
						|
2AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF
 | 
						|
AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA////
 | 
						|
+gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA
 | 
						|
////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA
 | 
						|
BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv
 | 
						|
AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA
 | 
						|
AAE9AAEABgAAAAH/+QAE//wBPQAAAUAAAwAGAAAAAP/7AAYAAAFAAAABRgAFAAYAAP////kABQAA
 | 
						|
AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA
 | 
						|
BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP//
 | 
						|
//kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA
 | 
						|
AP////kABgAAAXcAAAF+AAcABgAAAAD/+QAGAAABfgAAAYQABwAGAAD////7AAUAAAGEAAABigAF
 | 
						|
AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB
 | 
						|
mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn
 | 
						|
AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA
 | 
						|
AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7
 | 
						|
AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA
 | 
						|
Av/6AAMAAQHdAAAB3gAHAAYAAAAA//kABAABAd4AAAHiAAgABgAAAAD/+wAF//0B4gAAAecAAgAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 | 
						|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB
 | 
						|
//sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA
 | 
						|
AAAA//oABf//AfQAAAH5AAUABgAAAAD/+QAGAAAB+QAAAf8ABwAGAAAAAv/5AAMAAgH/AAACAAAJ
 | 
						|
AAYAAAAA//kABQABAgAAAAIFAAgABgAAAAH/+gAE//sCBQAAAggAAQAGAAAAAP/5AAYAAAIIAAAC
 | 
						|
DgAHAAYAAAAB//kABf/+Ag4AAAISAAUABgAA////+wAGAAACEgAAAhkABQAGAAAAAP/7AAX//gIZ
 | 
						|
AAACHgADAAYAAAAA//wABf/9Ah4AAAIjAAEABgAAAAD/+QAHAAACIwAAAioABwAGAAAAAP/6AAT/
 | 
						|
+wIqAAACLgABAAYAAAAA//kABP/8Ai4AAAIyAAMABgAAAAD/+gAFAAACMgAAAjcABgAGAAAAAf/5
 | 
						|
AAT//QI3AAACOgAEAAYAAAAB//kABP/9AjoAAAI9AAQABgAAAAL/+QAE//sCPQAAAj8AAgAGAAD/
 | 
						|
///7AAYAAgI/AAACRgAHAAYAAAAA//kABgABAkYAAAJMAAgABgAAAAH//AAD//0CTAAAAk4AAQAG
 | 
						|
AAAAAf//AAQAAgJOAAACUQADAAYAAAAB//kABP/9AlEAAAJUAAQABgAAAAH/+QAF//4CVAAAAlgA
 | 
						|
BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA
 | 
						|
Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC
 | 
						|
eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG
 | 
						|
AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA////
 | 
						|
+gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA
 | 
						|
////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA
 | 
						|
BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT
 | 
						|
AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A
 | 
						|
AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA
 | 
						|
Au4AAALzAAkABgAAAAD/9wAFAAAC8wAAAvgACQAGAAAAAP/4AAUAAAL4AAAC/QAIAAYAAAAA//oA
 | 
						|
Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP//
 | 
						|
//cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA
 | 
						|
AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ
 | 
						|
AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA
 | 
						|
LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5
 | 
						|
AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA
 | 
						|
AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5
 | 
						|
AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA
 | 
						|
AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG
 | 
						|
AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA
 | 
						|
EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK
 | 
						|
AJsAEQAGAAAAAP/6AAX//wCbAAoAoAAPAAYAAAAA//oABQABAKAACgClABEABgAA////+AAGAAAA
 | 
						|
pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG
 | 
						|
AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA////
 | 
						|
+QAGAAIAzgAKANUAEw==
 | 
						|
"""
 | 
						|
            )
 | 
						|
        ),
 | 
						|
        Image.open(
 | 
						|
            BytesIO(
 | 
						|
                base64.b64decode(
 | 
						|
                    b"""
 | 
						|
iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u
 | 
						|
Mc4b7vuds/xzjz5/3/7u/n9vMe7vnfH/9++vPn/xyf5zhxzjt8GHw8+2d83u8x27199/nxuQ6Od9
 | 
						|
M43/5z2I+9n9ZtmDBwMQECDRQw/eQIQohJXxpBCNVE6QCCAAAAD//wBlAJr/AgALyj1t/wINwq0g
 | 
						|
LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F
 | 
						|
IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA
 | 
						|
Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791
 | 
						|
NAADfcoIDyP44K/jv4Y63/Z+t98Ovt+ub4T48LAAAAD//wBlAJr/AuplMlADJAAAAGuAphWpqhMx
 | 
						|
in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9
 | 
						|
SjdavWA8ePHeBIKB//81/83ndznOaXx379wAAAD//wBlAJr/AqDxW+D3AABAAbUh/QMnbQag/gAY
 | 
						|
AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt
 | 
						|
y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG
 | 
						|
ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY
 | 
						|
lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H
 | 
						|
/Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3
 | 
						|
AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47
 | 
						|
c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/
 | 
						|
/yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw
 | 
						|
pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv
 | 
						|
oJodAAAAAP//Yqo/83+dxePWlxl3npsel9lvLfPcqlE9725C+acfVLMEAAAA//9i+s9gwCoaaGMR
 | 
						|
evta/58PTEWzr21hufPjA8N+qlnBwAAAAAD//2JiWLci5v1+HmFXDqcnULE/MxgYGBj+f6CaJQAA
 | 
						|
AAD//2Ji2FrkY3iYpYC5qDeGgeEMAwPDvwQBBoYvcTwOVLMEAAAA//9isDBgkP///0EOg9z35v//
 | 
						|
Gc/eeW7BwPj5+QGZhANUswMAAAD//2JgqGBgYGBgqEMXlvhMPUsAAAAA//8iYDd1AAAAAP//AwDR
 | 
						|
w7IkEbzhVQAAAABJRU5ErkJggg==
 | 
						|
"""
 | 
						|
                )
 | 
						|
            )
 | 
						|
        ),
 | 
						|
    )
 | 
						|
    return f
 |