# -*- coding: utf-8 -*-

"""Aligner

A FontLab Studio/RoboFab macro class implementing alignment
left/right/top/bottom functions for contours, oddly missing from
FontLab Studio.

Simple usage (with an open FontLab glyph window and two or more
contours selected):

  from aligner import Aligner

  aligner = Aligner()
  aligner.align('top')

If you put this file in
~/Library/Application Support/FontLab/Studio 5/Macros/System/Modules
you’ll be able to call it from other scripts from within FontLab.

I have several of these in my Macros/Aligner/ folder called
align_top.py, align_bottom.py… that only have the code shown above. I
then hooked them up to keystrokes.

Known issues:

- RoboFab doesn’t deal with Multiple Masters, so this script will only
  align contours on the first master of MM fonts or on non-MM fonts;

- Aligner currently only works with contours, not single points;
"""

__author__ = "Antonio Cavedoni <http://cavedoni.com/>"
__version__ = "0.1"
__svnid__ = "$Id$"
__license__ = "Python"

from FL import *
from robofab.world import CurrentGlyph

class Aligner:
    def __init__(self):
        self.glyph = CurrentGlyph()
        self.contours = [x for x in self.glyph.contours if x.selected]
        if len(self.contours) <= 1:
            fl.Message('Please select more than one contour.')
        self.max_x = 0  
        self.min_x = 1000   
        self.max_y = 0
        self.min_y = 1000
        
    def align(self, location='top'):
        for contour in self.contours:
            if location == 'top':
                m_y = max([x.y for x in contour.points])
                if m_y > self.max_y: self.max_y = m_y
            elif location == 'bottom':
                m_y = min([x.y for x in contour.points])
                if m_y < self.min_y: self.min_y = m_y
            elif location == 'left':
                m_x = min([x.x for x in contour.points])
                if m_x < self.min_x: self.min_x = m_x
            elif location == 'right':
                m_x = max([x.x for x in contour.points])
                if m_x > self.max_x: self.max_x = m_x
                    
        for contour in self.contours:
            if location == 'top' or location == 'bottom':           
                if location == 'top':
                    y = self.max_y - contour.box[3]
                elif location == 'bottom':
                    y = self.min_y - contour.box[1]
                contour.move((0, y))
            else:
                if location == 'left':
                    x = self.min_x - contour.box[0]
                elif location == 'right':
                    x = self.max_x - contour.box[2]
                contour.move((x, 0))
        self.glyph.update()

