MarginPen now has a isHorizontal flag when initialising. Default set to True, the calculations will be horizontal. When False, the measurements will be vertical.
Scripts using MarginPen should continue to work without changes. git-svn-id: http://svn.robofab.com/trunk@94 b5fa9d6c-a76f-4ffd-b3cb-f825fc41095c
This commit is contained in:
parent
339ce1c71c
commit
65b2d92a9f
@ -7,22 +7,30 @@ from sets import Set
|
|||||||
class MarginPen(BasePen):
|
class MarginPen(BasePen):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Pen to calculate the horizontal margins at a given height.
|
Pen to calculate the margins at a given value.
|
||||||
|
When isHorizontal is True, the margins at <value> are horizontal.
|
||||||
|
When isHorizontal is False, the margins at <value> are vertical.
|
||||||
|
|
||||||
When a glyphset or font is given, MarginPen will also calculate for glyphs with components.
|
When a glyphset or font is given, MarginPen will also calculate for glyphs with components.
|
||||||
|
|
||||||
pen.getMargins() returns the minimum and maximum intersections of the glyph.
|
pen.getMargins() returns the minimum and maximum intersections of the glyph.
|
||||||
pen.getContourMargins() returns the minimum and maximum intersections for each contour.
|
pen.getContourMargins() returns the minimum and maximum intersections for each contour.
|
||||||
|
|
||||||
|
|
||||||
|
Possible optimisation:
|
||||||
|
Initialise the pen object with a list of points we want to measure,
|
||||||
|
then draw the glyph once, but do the splitLine() math for all measure points.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, glyphSet, height):
|
def __init__(self, glyphSet, value, isHorizontal=True):
|
||||||
BasePen.__init__(self, glyphSet)
|
BasePen.__init__(self, glyphSet)
|
||||||
self.height = height
|
self.value = value
|
||||||
self.hits = {}
|
self.hits = {}
|
||||||
self.filterDoubles = True
|
self.filterDoubles = True
|
||||||
self.contourIndex = None
|
self.contourIndex = None
|
||||||
self.startPt = None
|
self.startPt = None
|
||||||
|
self.isHorizontal = isHorizontal
|
||||||
|
|
||||||
def _moveTo(self, pt):
|
def _moveTo(self, pt):
|
||||||
self.currentPt = pt
|
self.currentPt = pt
|
||||||
@ -36,7 +44,7 @@ class MarginPen(BasePen):
|
|||||||
if self.filterDoubles:
|
if self.filterDoubles:
|
||||||
if pt == self.currentPt:
|
if pt == self.currentPt:
|
||||||
return
|
return
|
||||||
hits = splitLine(self.currentPt, pt, self.height, True)
|
hits = splitLine(self.currentPt, pt, self.value, self.isHorizontal)
|
||||||
if len(hits)>1:
|
if len(hits)>1:
|
||||||
# result will be 2 tuples of 2 coordinates
|
# result will be 2 tuples of 2 coordinates
|
||||||
# first two points: start to intersect
|
# first two points: start to intersect
|
||||||
@ -45,27 +53,43 @@ class MarginPen(BasePen):
|
|||||||
# then, the first coordinate of that point is the x.
|
# then, the first coordinate of that point is the x.
|
||||||
if not self.contourIndex in self.hits:
|
if not self.contourIndex in self.hits:
|
||||||
self.hits[self.contourIndex] = []
|
self.hits[self.contourIndex] = []
|
||||||
self.hits[self.contourIndex].append(round(hits[0][-1][0], 4))
|
if self.isHorizontal:
|
||||||
if pt[1] == self.height:
|
self.hits[self.contourIndex].append(round(hits[0][-1][0], 4))
|
||||||
|
else:
|
||||||
|
self.hits[self.contourIndex].append(round(hits[0][-1][1], 4))
|
||||||
|
if self.isHorizontal and pt[1] == self.value:
|
||||||
# it could happen
|
# it could happen
|
||||||
if not self.contourIndex in self.hits:
|
if not self.contourIndex in self.hits:
|
||||||
self.hits[self.contourIndex] = []
|
self.hits[self.contourIndex] = []
|
||||||
self.hits[self.contourIndex].append(pt[0])
|
self.hits[self.contourIndex].append(pt[0])
|
||||||
|
elif (not self.isHorizontal) and (pt[0] == self.value):
|
||||||
|
# it could happen
|
||||||
|
if not self.contourIndex in self.hits:
|
||||||
|
self.hits[self.contourIndex] = []
|
||||||
|
self.hits[self.contourIndex].append(pt[1])
|
||||||
self.currentPt = pt
|
self.currentPt = pt
|
||||||
|
|
||||||
def _curveToOne(self, pt1, pt2, pt3):
|
def _curveToOne(self, pt1, pt2, pt3):
|
||||||
hits = splitCubic(self.currentPt, pt1, pt2, pt3, self.height, True)
|
hits = splitCubic(self.currentPt, pt1, pt2, pt3, self.value, self.isHorizontal)
|
||||||
for i in range(len(hits)-1):
|
for i in range(len(hits)-1):
|
||||||
# a number of intersections is possible. Just take the
|
# a number of intersections is possible. Just take the
|
||||||
# last point of each segment.
|
# last point of each segment.
|
||||||
if not self.contourIndex in self.hits:
|
if not self.contourIndex in self.hits:
|
||||||
self.hits[self.contourIndex] = []
|
self.hits[self.contourIndex] = []
|
||||||
self.hits[self.contourIndex].append(round(hits[i][-1][0], 4))
|
if self.isHorizontal:
|
||||||
if pt3[1] == self.height:
|
self.hits[self.contourIndex].append(round(hits[i][-1][0], 4))
|
||||||
|
else:
|
||||||
|
self.hits[self.contourIndex].append(round(hits[i][-1][1], 4))
|
||||||
|
if self.isHorizontal and pt3[1] == self.value:
|
||||||
# it could happen
|
# it could happen
|
||||||
if not self.contourIndex in self.hits:
|
if not self.contourIndex in self.hits:
|
||||||
self.hits[self.contourIndex] = []
|
self.hits[self.contourIndex] = []
|
||||||
self.hits[self.contourIndex].append(pt3[0])
|
self.hits[self.contourIndex].append(pt3[0])
|
||||||
|
if (not self.isHorizontal) and (pt3[0] == self.value):
|
||||||
|
# it could happen
|
||||||
|
if not self.contourIndex in self.hits:
|
||||||
|
self.hits[self.contourIndex] = []
|
||||||
|
self.hits[self.contourIndex].append(pt3[1])
|
||||||
self.currentPt = pt3
|
self.currentPt = pt3
|
||||||
|
|
||||||
def _closePath(self):
|
def _closePath(self):
|
||||||
@ -77,14 +101,12 @@ class MarginPen(BasePen):
|
|||||||
self.currentPt = None
|
self.currentPt = None
|
||||||
|
|
||||||
def addComponent(self, baseGlyph, transformation):
|
def addComponent(self, baseGlyph, transformation):
|
||||||
from fontTools.pens.transformPen import TransformPen
|
|
||||||
if self.glyphSet is None:
|
if self.glyphSet is None:
|
||||||
return
|
return
|
||||||
if baseGlyph in self.glyphSet:
|
if baseGlyph in self.glyphSet:
|
||||||
glyph = self.glyphSet[baseGlyph]
|
glyph = self.glyphSet[baseGlyph]
|
||||||
if glyph is not None:
|
if glyph is not None:
|
||||||
tPen = TransformPen(self, transformation)
|
glyph.draw(self)
|
||||||
glyph.draw(tPen)
|
|
||||||
|
|
||||||
def getMargins(self):
|
def getMargins(self):
|
||||||
"""Get the horizontal margins for all contours combined, i.e. the whole glyph."""
|
"""Get the horizontal margins for all contours combined, i.e. the whole glyph."""
|
||||||
@ -122,10 +144,9 @@ if __name__ == "__main__":
|
|||||||
g = CurrentGlyph()
|
g = CurrentGlyph()
|
||||||
|
|
||||||
pt = (74, 216)
|
pt = (74, 216)
|
||||||
if f is not None and g is not None:
|
|
||||||
pen = MarginPen(f, pt[1])
|
pen = MarginPen(f, pt[1], isHorizontal=False)
|
||||||
g.draw(pen)
|
g.draw(pen)
|
||||||
print 'glyph margins', pen.getMargins()
|
print 'glyph Y margins', pen.getMargins()
|
||||||
print pen.getContourMargins()
|
print pen.getContourMargins()
|
||||||
else:
|
|
||||||
print "no font or glyph"
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user