textgen: cleanup

Make the classes self-contained
Make the functions re-entrant
This commit is contained in:
Nick Zatkovich 2017-07-31 01:19:53 -07:00
parent b00f9516e3
commit cac04c1271
2 changed files with 46 additions and 51 deletions

View file

@ -12,21 +12,16 @@ import re
from image_dimensions import *
from tint import image_tint
# Background color for output files.
BACKGROUND_COLOR = None
# Width of a space character in pixels.
SPACE_WIDTH = 4
# Height of the font.
FONT_HEIGHT = 8
# Regexp to match dimensions/x,y coordinate pair.
DIMENSION_MATCH_RE = re.compile(r'(\d+)[x,](\d+)')
class Font(object):
class SmallTextGenerator(object):
def __init__(self):
self.get_font_widths()
# Width of a space character in pixels.
SPACE_WIDTH = 4
# Height of the font.
FONT_HEIGHT = 8
# Regexp to match dimensions/x,y coordinate pair.
def compile_kerning_table(self, kerning_table):
"""Given a dictionary of kerning patterns, compile Regexps."""
@ -57,15 +52,15 @@ class Font(object):
def draw_for_text(self, image, text, x, y):
text = text.upper()
new_image = image.copy()
x1, y1 = x, y
for c in text:
if c == '\n':
y1 += FONT_HEIGHT
y1 += self.FONT_HEIGHT
x1 = x
elif c == ' ':
x1 += SPACE_WIDTH
x1 += self.SPACE_WIDTH
if c not in self:
continue
@ -73,13 +68,15 @@ class Font(object):
filename = self.char_filename(c)
char_image = Image.open(filename)
char_image.load()
self.paste_image(image, char_image, x1, y1)
new_image = self.paste_image(new_image, char_image, x1, y1)
x1 += self.char_width(c)
return new_image
def paste_image(self, image, src, x, y):
int_image = Image.new("RGBA", image.size, (0, 0, 0, 0))
int_image.paste(src, (x, y))
image = Image.alpha_composite(image, int_image)
new_image = Image.alpha_composite(image, int_image)
return new_image
def parse_command_line(args):
@ -126,7 +123,7 @@ if __name__ == '__main__':
print(" [x,y] [text]")
sys.exit(0)
smallfont = Font()
smallfont = SmallTextGenerator()
if args['background'] is not None:
background_image = Image.open(args['background'])
@ -146,9 +143,9 @@ if __name__ == '__main__':
if string.startswith('file:'):
src_image = Image.open(string[5:])
src_image.load()
smallfont.paste_image(image, src_image, xy[0], xy[1])
image = smallfont.paste_image(image, src_image, xy[0], xy[1])
else:
smallfont.draw_for_text(image, string, xy[0], xy[1])
image = smallfont.draw_for_text(image, string, xy[0], xy[1])
if args['background'] is not None:
image = Image.alpha_composite(background_image, image)

View file

@ -14,32 +14,30 @@ from config import *
from image_dimensions import *
from tint import image_tint
# Tinting parameters for colorizing text:
COLOR_BLUE = "#000001"
COLOR_RED = "#010000"
COLOR_WHITE = None
# Background color for output files.
BACKGROUND_COLOR = None
# Height of font in pixels.
FONT_HEIGHT = 15
FONT_LC_HEIGHT = 15 # 12
# If true, the font only has uppercase characters.
UPPERCASE_FONT = False
# Width of a space character in pixels.
SPACE_WIDTH = 7
LOWERCASE_RE = re.compile(r'^[a-z\!\. ]*$')
class Font(object):
class TextGenerator(object):
def __init__(self, fontdir, kerning_table={}):
self.fontdir = fontdir
self.kerning_table = self.compile_kerning_table(kerning_table)
self.get_font_widths()
# Tinting parameters for colorizing text:
COLOR_BLUE = "#000001"
COLOR_RED = "#010000"
COLOR_WHITE = None
# Height of font in pixels.
FONT_HEIGHT = 15
FONT_LC_HEIGHT = 15 # 12
# If true, the font only has uppercase characters.
UPPERCASE_FONT = False
# Width of a space character in pixels.
SPACE_WIDTH = 7
LOWERCASE_RE = re.compile(r'^[a-z\!\. ]*$')
def compile_kerning_table(self, kerning_table):
"""Given a dictionary of kerning patterns, compile Regexps."""
@ -87,7 +85,7 @@ class Font(object):
last_c = ' '
for c in text:
if c == ' ':
x += SPACE_WIDTH
x += self.SPACE_WIDTH
if c in self:
x += self.kerning_adjust(last_c, c)
@ -110,20 +108,20 @@ class Font(object):
if c is None:
return x
def generate_graphic(self, text, color=COLOR_WHITE):
def generate_graphic(self, text, color=None):
"""Get command to render text to a file
with the given background color.
"""
if UPPERCASE_FONT:
if self.UPPERCASE_FONT:
text = text.upper()
"""Command line construction helper, used in render functions"""
width = self.text_width(text)
if LOWERCASE_RE.match(text):
height = FONT_LC_HEIGHT
if self.LOWERCASE_RE.match(text):
height = self.FONT_LC_HEIGHT
else:
height = FONT_HEIGHT
height = self.FONT_HEIGHT
txt_image = Image.new("RGBA", (width, height), (0, 0, 0, 0))
for c, x in self.iterate_char_positions(text):
@ -134,14 +132,14 @@ class Font(object):
char_image = Image.open(filename)
char_image.load()
int_image = Image.new("RGBA", txt_image.size, (0, 0, 0, 0))
int_image.paste(char_image, (x, height - FONT_HEIGHT))
int_image.paste(char_image, (x, height - self.FONT_HEIGHT))
txt_image = Image.alpha_composite(txt_image, int_image)
txt_image = image_tint(txt_image, color)
return txt_image
def generate_graphics(graphics, color=COLOR_WHITE):
def generate_graphics(font, graphics, color=None):
for name, text in sorted(graphics.items()):
# write a makefile fragment
target = '%s.png' % name
@ -149,7 +147,7 @@ def generate_graphics(graphics, color=COLOR_WHITE):
image.save(target)
def generate_kerning_test():
def generate_kerning_test(font):
pairs = []
for c1 in sorted(font.char_widths):
char1 = "%c" % c1
@ -162,7 +160,7 @@ def generate_kerning_test():
if __name__ == '__main__':
font = Font('fontchars', kerning_table=FONT_KERNING_RULES)
generate_graphics(red_graphics, color=COLOR_RED)
generate_graphics(blue_graphics, color=COLOR_BLUE)
generate_graphics(white_graphics, color=COLOR_WHITE)
font = TextGenerator('fontchars', kerning_table=FONT_KERNING_RULES)
generate_graphics(font, red_graphics, color=font.COLOR_RED)
generate_graphics(font, blue_graphics, color=font.COLOR_BLUE)
generate_graphics(font, white_graphics, color=font.COLOR_WHITE)