From 76d5ca1cd1699847c036f0d16cd7708fc21a259b Mon Sep 17 00:00:00 2001 From: Michael Fogleman Date: Sun, 4 Mar 2018 19:30:40 -0500 Subject: [PATCH] text --- examples/text.py | 126 ++++++++++++++++++++++++++++++----------------- 1 file changed, 81 insertions(+), 45 deletions(-) diff --git a/examples/text.py b/examples/text.py index e98c878..e998cb6 100644 --- a/examples/text.py +++ b/examples/text.py @@ -1,54 +1,90 @@ +from __future__ import division + import axi +import itertools +import string -LINES = [ - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor', - 'incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis', - 'nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.', - 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu', - 'fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in', - 'culpa qui officia deserunt mollit anim id est laborum.', -] +TEXT = ( + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor ' + 'incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis ' + 'nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ' + 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu ' + 'fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in ' + 'culpa qui officia deserunt mollit anim id est laborum. ' +) -LINES = [ - 'When you wish upon a star', - 'Makes no difference who you are', - 'Anything your heart desires will come to you', -] - -LINES = [ - 'Five Seconds of Donkey Kong' -] - -def stack_drawings(ds, spacing=0): - result = axi.Drawing() - y = 0 - for d in ds: - d = d.origin().translate(-d.width / 2, y) - result.add(d) - y += d.height + spacing +def word_wrap(text, width, measure_func): + result = [] + for line in text.split('\n'): + fields = itertools.groupby(line, lambda x: x.isspace()) + fields = [''.join(g) for _, g in fields] + if len(fields) % 2 == 1: + fields.append('') + x = '' + for a, b in zip(fields[::2], fields[1::2]): + w, _ = measure_func(x + a) + if w > width: + if x == '': + result.append(a) + continue + else: + result.append(x) + x = '' + x += a + b + if x != '': + result.append(x) + result = [x.strip() for x in result] return result +class Font(object): + def __init__(self, font, point_size): + self.font = font + self.max_height = axi.Drawing(axi.text(string.printable, font)).height + # self.cap_height = axi.Drawing(axi.text('H', font)).height + height = point_size / 72 + self.scale = height / self.max_height + def text(self, text): + d = axi.Drawing(axi.text(text, self.font)) + d = d.scale(self.scale) + return d + def justify_text(self, text, width): + d = self.text(text) + w = d.width + spaces = text.count(' ') + if spaces == 0 or w >= width: + return d + e = ((width - w) / spaces) / self.scale + d = axi.Drawing(axi.text(text, self.font, extra=e)) + d = d.scale(self.scale) + return d + def measure(self, text): + return self.text(text).size + def wrap(self, text, width, line_spacing=1, align=0, justify=False): + lines = word_wrap(text, width, self.measure) + ds = [self.text(line) for line in lines] + max_width = max(d.width for d in ds) + if justify: + jds = [self.justify_text(line, max_width) for line in lines] + ds = jds[:-1] + [ds[-1]] + spacing = line_spacing * self.max_height * self.scale + result = axi.Drawing() + y = 0 + for d in ds: + if align == 0: + x = 0 + elif align == 1: + x = max_width - d.width + else: + x = max_width / 2 - d.width / 2 + result.add(d.translate(x, y)) + y += spacing + return result + def main(): - font = axi.FUTURAM - ds = [axi.Drawing(axi.text(line, font)).scale_to_fit_height(1) for line in LINES] - d = stack_drawings(ds, 0.1) - # d = d.rotate_and_scale_to_fit(12, 8.5, step=90) - # d = d.scale(0.02, 0.02) - # d = d.center(12, 8.5) - # d = d.move(0, 0, 0, 0) - d = d.scale_to_fit(12, 8.5) - d = d.scale_to_fit(12, 0.25) - # d = d.center(12, 8.5) - d = d.move(6, 0, 0.5, 0) - d = d.translate(0, 0.01) - - d = d.move(6, 8.5, 0.5, 1) - d = d.translate(0, -0.01) - - d = d.join_paths(0.01) - d.render().write_to_png('out.png') - print sum(x.t for x in axi.Device().plan_drawing(d)) - axi.draw(d) + font = Font(axi.FUTURAL, 18) + d = font.wrap(TEXT * 2, 12, 1.5, justify=True) + d = d.center(12, 8.5) + d.render(bounds=axi.V3_BOUNDS).write_to_png('out.png') if __name__ == '__main__': main()