-
Notifications
You must be signed in to change notification settings - Fork 1
/
fontawesome.py
80 lines (61 loc) · 2.36 KB
/
fontawesome.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
'''
Use FontAwesome svg's, internally converted to raster images using cairosvg
Operates similar to textfun.py, keeping previously used icons at specific size in memory
Check 'README.md' in the 'fa' folder on how to download and extract icons
Icon list at https://fontawesome.com/v5.15/icons?d=gallery&p=2&s=brands,regular,solid&m=free
'''
import logging
from threading import Lock
from io import BytesIO
from cairosvg import svg2png
from PIL import Image
logging.getLogger('PIL.PngImagePlugin').setLevel(logging.WARNING)
class FontAwesome:
_icons = {}
_lock = Lock()
def __init__(self, cfg):
self.logger = logging.getLogger(__name__)
self._default_size = 18
def get_icon(self, icon, size = None):
if size == None:
size = self._default_size
# Return previously used icons from memory
if icon in FontAwesome._icons:
if size in FontAwesome._icons[icon]:
return FontAwesome._icons[icon][size]
# Load new icon
path = 'fa/{}.svg'.format(icon)
try:
f = open(path, 'rb')
except IOError:
self.logger.error('Could not load icon: {}'.format(icon))
return None
with f:
output = svg2png(file_obj=f,
parent_width = size,
parent_height = size
)
icon_png = Image.open(BytesIO(output))
# Paste transparent icon onto white background
canvas = Image.new("RGBA", icon_png.size, "WHITE")
canvas.alpha_composite(icon_png)
canvas = canvas.convert('L')
if canvas.width != size or canvas.height != size:
self.logger.warning("Unexpected canvas size ({}, {})".format(
canvas.width, canvas.height
))
# Add new icon to memory
with FontAwesome._lock:
if icon not in FontAwesome._icons:
FontAwesome._icons[icon] = {}
FontAwesome._icons[icon][size] = canvas
self.logger.debug('Loaded icon {} size {}'.format(icon, size))
return canvas
def paste_icon(self, canvas, name, size = None, pos = (0,0)):
icon = self.get_icon(name, size)
if icon:
box = (
pos[0], pos[1],
pos[0] + icon.width, pos[1] + icon.height
)
canvas.paste(icon, box)