https://bitbucket.org/daniel_fort/magic-lantern
Raw File
Tip revision: 433cdd26e6990437e9dfe98beed54357b43564be authored by Daniel Fort on 25 January 2017, 03:38:10 UTC
Closed branch 550D_10bit_12bit
Tip revision: 433cdd2
align_string_proportional.py
# http://code.activestate.com/recipes/577946-word-wrap-for-proportional-fonts/
# MIT license

import re

def word_wrap(text, width, extent_func):
    '''
    Word wrap function / algorithm for wrapping text using proportional (versus 
    fixed-width) fonts.
    
    `text`: a string of text to wrap
    `width`: the width in pixels to wrap to
    `extent_func`: a function that returns a (w, h) tuple given any string, to
                   specify the size (text extent) of the string when rendered. 
                   the algorithm only uses the width.
    
    Returns a list of strings, one for each line after wrapping.
    '''
    lines = []
    pattern = re.compile(r'(\s+)')
    lookup = dict((c, extent_func(c)[0]) for c in set(text))
    for line in text.splitlines():
        tokens = pattern.split(line)
        tokens.append('')
        widths = [sum(lookup[c] for c in token) for token in tokens]
        start, total = 0, 0
        for index in xrange(0, len(tokens), 2):
            if total + widths[index] > width:
                end = index + 2 if index == start else index
                lines.append(''.join(tokens[start:end]))
                start, total = end, 0
                if end == index + 2:
                    continue
            total += widths[index] + widths[index + 1]
        if start < len(tokens):
            lines.append(''.join(tokens[start:]))
    lines = [line.strip() for line in lines]
    return lines or ['']

if __name__ == '__main__':
    text = (
        'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do '
        'eiusmod tempor incididunt ut labore et dolore magna aliqua.\n\n'
        'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris '
        'nisi ut aliquip ex ea commodo consequat.\n\n'
        'Duis aute irure dolor in reprehenderit in voluptate velit esse '
        'cillum dolore eu fugiat nulla pariatur.\n\n'
        'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui '
        'officia deserunt mollit anim id est laborum.'
    )
    # dummy extent function behaves like a fixed-width font
    def extent_func(text):
        return (1, 0)
    # wrap to 80 columns
    lines = word_wrap(text, 80, extent_func)
    for line in lines:
        print line
back to top