mirror of
https://github.com/freedoom/freedoom.git
synced 2025-09-02 16:25:47 -04:00
BUILD: code cleanup, VERSION fix
Performed code cleanup, made changes to version number Make gets from Git to make it consistent across git versions
This commit is contained in:
parent
e9015b43b3
commit
09f39d4e64
8 changed files with 21 additions and 20 deletions
166
graphics/text/textgen
Executable file
166
graphics/text/textgen
Executable file
|
@ -0,0 +1,166 @@
|
|||
#!/usr/bin/env python
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
# Script to generate menu and intermission screen 'text' graphics for
|
||||
# Freedoom, by compositing individual font character graphics together.
|
||||
#
|
||||
|
||||
from PIL import Image
|
||||
from glob import glob
|
||||
import re
|
||||
import sys
|
||||
|
||||
from config import *
|
||||
from image_dimensions import *
|
||||
from tint import image_tint
|
||||
|
||||
|
||||
|
||||
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."""
|
||||
|
||||
result = {}
|
||||
for pattern, adjust in kerning_table.items():
|
||||
result[re.compile(pattern)] = adjust
|
||||
return result
|
||||
|
||||
def get_font_widths(self):
|
||||
charfiles = glob('%s/font*.png' % self.fontdir)
|
||||
self.char_widths = {}
|
||||
for c in range(128):
|
||||
filename = self.char_filename(chr(c))
|
||||
if filename not in charfiles:
|
||||
continue
|
||||
w, _ = get_image_dimensions(filename)
|
||||
self.char_widths[chr(c)] = w
|
||||
|
||||
def __contains__(self, c):
|
||||
return c in self.char_widths
|
||||
|
||||
def char_width(self, c):
|
||||
return self.char_widths[c]
|
||||
|
||||
def char_filename(self, c):
|
||||
return '%s/font%03d.png' % (self.fontdir, ord(c))
|
||||
|
||||
def kerning_adjust(self, char_1, char_2):
|
||||
"""Get kerning adjustment for pair of characters.
|
||||
|
||||
Zero means no adjustment. A negative value adjusts to the
|
||||
left and a positive value adjusts to the right.
|
||||
"""
|
||||
for pattern, adjust in self.kerning_table.items():
|
||||
if pattern.match(char_1 + char_2):
|
||||
return adjust
|
||||
else:
|
||||
return 0
|
||||
|
||||
def iterate_char_positions(self, text):
|
||||
"""Iterate over characters in string, yielding character with
|
||||
position it should be placed at in the output file.
|
||||
"""
|
||||
x = 0
|
||||
last_c = ' '
|
||||
for c in text:
|
||||
if c == ' ':
|
||||
x += self.SPACE_WIDTH
|
||||
|
||||
if c in self:
|
||||
x += self.kerning_adjust(last_c, c)
|
||||
|
||||
yield c, x
|
||||
|
||||
# Characters overlap by one pixel.
|
||||
x += self.char_width(c) - 1
|
||||
|
||||
last_c = c
|
||||
|
||||
# We need to add back the missing pixel from the right side
|
||||
# of the last char.
|
||||
x += 1
|
||||
yield None, x
|
||||
|
||||
def text_width(self, text):
|
||||
"""Given a string of text, get text width in pixels."""
|
||||
for c, x in self.iterate_char_positions(text):
|
||||
if c is None:
|
||||
return x
|
||||
|
||||
def generate_graphic(self, text, color=None):
|
||||
"""Get command to render text to a file
|
||||
with the given background color.
|
||||
"""
|
||||
|
||||
if self.UPPERCASE_FONT:
|
||||
text = text.upper()
|
||||
"""Command line construction helper, used in render functions"""
|
||||
width = self.text_width(text)
|
||||
|
||||
if self.LOWERCASE_RE.match(text):
|
||||
height = self.FONT_LC_HEIGHT
|
||||
else:
|
||||
height = self.FONT_HEIGHT
|
||||
|
||||
txt_image = Image.new("RGBA", (width, height), (0, 0, 0, 0))
|
||||
for c, x in self.iterate_char_positions(text):
|
||||
if c is None:
|
||||
break
|
||||
|
||||
filename = self.char_filename(c)
|
||||
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 - 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(font, graphics, color=None):
|
||||
for name, text in sorted(graphics.items()):
|
||||
# write a makefile fragment
|
||||
target = '%s.png' % name
|
||||
image = font.generate_graphic(text, color=color)
|
||||
image.save(target)
|
||||
|
||||
|
||||
def generate_kerning_test(font):
|
||||
pairs = []
|
||||
for c1 in sorted(font.char_widths):
|
||||
char1 = "%c" % c1
|
||||
for c2 in sorted(font.char_widths):
|
||||
char2 = "%c" % c2
|
||||
if font.kerning_adjust(char1, char2) != 0:
|
||||
pairs.append(char1 + char2)
|
||||
|
||||
cmd = font.generate_graphic(" ".join(pairs), "kerning.png")
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
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)
|
Loading…
Add table
Add a link
Reference in a new issue