Add initial support for drawing symbols onto card frame.
This commit is contained in:
@@ -11,6 +11,7 @@ FRAMES_DIRECTORY = "frames"
|
|||||||
FONTS_DIRECTORIES = [".", "fonts", os.path.join(os.environ.get("HOME", ""), ".fonts")]
|
FONTS_DIRECTORIES = [".", "fonts", os.path.join(os.environ.get("HOME", ""), ".fonts")]
|
||||||
|
|
||||||
IMAGES_DIRECTORY = "images"
|
IMAGES_DIRECTORY = "images"
|
||||||
|
SYMBOLS_DIRECTORY = "symbols"
|
||||||
|
|
||||||
DEFAULT_TEXT_COLOR = "black"
|
DEFAULT_TEXT_COLOR = "black"
|
||||||
DEFAULT_FONT = "EBGaramond-Regular.ttf"
|
DEFAULT_FONT = "EBGaramond-Regular.ttf"
|
||||||
@@ -19,6 +20,33 @@ DEFAULT_FONT_SIZE = 12
|
|||||||
NAME_FONT = "Electrolize-Regular.ttf"
|
NAME_FONT = "Electrolize-Regular.ttf"
|
||||||
YAGICARDFILE = "Yagicardfile"
|
YAGICARDFILE = "Yagicardfile"
|
||||||
|
|
||||||
|
base_directory = "."
|
||||||
|
|
||||||
|
class Images ():
|
||||||
|
def __init__ (self, directory):
|
||||||
|
self.directory = directory
|
||||||
|
self.images = {}
|
||||||
|
|
||||||
|
def __getitem__ (self, key):
|
||||||
|
if key in self.images:
|
||||||
|
return self.images[key]
|
||||||
|
|
||||||
|
if os.path.splitext(key)[1] == "":
|
||||||
|
key = f"{key}.png"
|
||||||
|
|
||||||
|
if key in self.images:
|
||||||
|
return self.images[key]
|
||||||
|
|
||||||
|
image = Image.open(os.path.join(base_directory, self.directory, key))
|
||||||
|
self.images[key] = image
|
||||||
|
return image
|
||||||
|
|
||||||
|
def __setitem__ (self, key, value):
|
||||||
|
self.images[key] = value
|
||||||
|
|
||||||
|
images = Images(IMAGES_DIRECTORY)
|
||||||
|
symbols = Images(SYMBOLS_DIRECTORY)
|
||||||
|
|
||||||
class Field ():
|
class Field ():
|
||||||
def __init__ (self, style_rules, value, card):
|
def __init__ (self, style_rules, value, card):
|
||||||
self.style_rules = style_rules
|
self.style_rules = style_rules
|
||||||
@@ -47,7 +75,7 @@ def resolve_style_rule (rule, *args):
|
|||||||
def load_font (name, size):
|
def load_font (name, size):
|
||||||
for directory in FONTS_DIRECTORIES:
|
for directory in FONTS_DIRECTORIES:
|
||||||
try:
|
try:
|
||||||
return ImageFont.truetype(os.path.join(directory, name), size)
|
return ImageFont.truetype(os.path.join(base_directory, directory, name), size)
|
||||||
except OSError: pass
|
except OSError: pass
|
||||||
|
|
||||||
raise OSError("failed to open font: " + name)
|
raise OSError("failed to open font: " + name)
|
||||||
@@ -61,16 +89,17 @@ def draw_text (image, draw, field):
|
|||||||
font_name = field.get("typeface", DEFAULT_FONT)
|
font_name = field.get("typeface", DEFAULT_FONT)
|
||||||
text_anchor = field.get("anchor", None)
|
text_anchor = field.get("anchor", None)
|
||||||
alignment = field.get("align", "left")
|
alignment = field.get("align", "left")
|
||||||
|
direction = field.get("direction", "ltr")
|
||||||
|
|
||||||
font = load_font(font_name, font_size)
|
font = load_font(font_name, font_size)
|
||||||
font_variant = field.get("font_variant")
|
font_variant = field.get("font_variant")
|
||||||
if font_variant:
|
if font_variant:
|
||||||
font.set_variation_by_name(font_variant)
|
font.set_variation_by_name(font_variant)
|
||||||
|
|
||||||
draw.multiline_text((field.get("x"), field.get("y")), field.value, font=font, fill=color, anchor=text_anchor, align=alignment)
|
draw.multiline_text((field.get("x"), field.get("y")), field.value, font=font, fill=color, anchor=text_anchor, align=alignment) #, direction=direction)
|
||||||
|
|
||||||
def draw_image (image, draw, field):
|
def draw_image (image, draw, field):
|
||||||
source_image = Image.open(os.path.join(IMAGES_DIRECTORY, field.value))
|
source_image = images[field.value]
|
||||||
|
|
||||||
width = field.get("width")
|
width = field.get("width")
|
||||||
height = field.get("height")
|
height = field.get("height")
|
||||||
@@ -80,6 +109,30 @@ def draw_image (image, draw, field):
|
|||||||
|
|
||||||
image.paste(source_image, (field.get("x"), field.get("y")))
|
image.paste(source_image, (field.get("x"), field.get("y")))
|
||||||
|
|
||||||
|
def draw_symbols (image, draw, field):
|
||||||
|
symbol_text = field.value.lower()
|
||||||
|
if symbol_text.startswith("{") and symbol_text.endswith("}"):
|
||||||
|
symbol_text = symbol_text[1:-1].replace("}{", " ")
|
||||||
|
|
||||||
|
width = field.get("width", image.width)
|
||||||
|
height = field.get("height", image.height)
|
||||||
|
direction = field.get("direction", "ltr")
|
||||||
|
|
||||||
|
symbols_image = Image.new(image.mode, (width, height))
|
||||||
|
|
||||||
|
symbol_pos = (0, 0)
|
||||||
|
for symbol_name in symbol_text.split(" "):
|
||||||
|
if symbol_name:
|
||||||
|
symbol = symbols[symbol_name]
|
||||||
|
symbols_image.paste(symbol, symbol_pos)
|
||||||
|
|
||||||
|
if direction == "ltr":
|
||||||
|
symbol_pos = (symbol_pos[0] + symbol.width, symbol_pos[1])
|
||||||
|
elif direction == "ttb":
|
||||||
|
symbol_pos = (symbol_pos[0], symbol_pos[1] + symbol.height)
|
||||||
|
|
||||||
|
image.alpha_composite(symbols_image, (field.get("x"), field.get("y")))
|
||||||
|
|
||||||
def rescale_text_for_sizes (*args):
|
def rescale_text_for_sizes (*args):
|
||||||
def scaler (value):
|
def scaler (value):
|
||||||
for arg in args:
|
for arg in args:
|
||||||
@@ -211,6 +264,7 @@ def main():
|
|||||||
|
|
||||||
yagicardfile = os.path.join(yagicard_root, YAGICARDFILE)
|
yagicardfile = os.path.join(yagicard_root, YAGICARDFILE)
|
||||||
with open(yagicardfile) as yagicardcode:
|
with open(yagicardfile) as yagicardcode:
|
||||||
|
base_directory = yagicard_root
|
||||||
namespace = {
|
namespace = {
|
||||||
"YAGICARD_ROOT": yagicard_root
|
"YAGICARD_ROOT": yagicard_root
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user