diff --git a/Lib/robofab/pens/marginPen.py b/Lib/robofab/pens/marginPen.py index adfa70b78..a5aa97127 100644 --- a/Lib/robofab/pens/marginPen.py +++ b/Lib/robofab/pens/marginPen.py @@ -7,22 +7,30 @@ from sets import Set 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 are horizontal. + When isHorizontal is False, the margins at are vertical. 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.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) - self.height = height + self.value = value self.hits = {} self.filterDoubles = True self.contourIndex = None self.startPt = None + self.isHorizontal = isHorizontal def _moveTo(self, pt): self.currentPt = pt @@ -36,7 +44,7 @@ class MarginPen(BasePen): if self.filterDoubles: if pt == self.currentPt: return - hits = splitLine(self.currentPt, pt, self.height, True) + hits = splitLine(self.currentPt, pt, self.value, self.isHorizontal) if len(hits)>1: # result will be 2 tuples of 2 coordinates # first two points: start to intersect @@ -45,27 +53,43 @@ class MarginPen(BasePen): # then, the first coordinate of that point is the x. if not self.contourIndex in self.hits: self.hits[self.contourIndex] = [] - self.hits[self.contourIndex].append(round(hits[0][-1][0], 4)) - if pt[1] == self.height: + if self.isHorizontal: + 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 if not self.contourIndex in self.hits: self.hits[self.contourIndex] = [] 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 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): # a number of intersections is possible. Just take the # last point of each segment. if not self.contourIndex in self.hits: self.hits[self.contourIndex] = [] - self.hits[self.contourIndex].append(round(hits[i][-1][0], 4)) - if pt3[1] == self.height: + if self.isHorizontal: + 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 if not self.contourIndex in self.hits: self.hits[self.contourIndex] = [] 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 def _closePath(self): @@ -77,14 +101,12 @@ class MarginPen(BasePen): self.currentPt = None def addComponent(self, baseGlyph, transformation): - from fontTools.pens.transformPen import TransformPen if self.glyphSet is None: return if baseGlyph in self.glyphSet: glyph = self.glyphSet[baseGlyph] if glyph is not None: - tPen = TransformPen(self, transformation) - glyph.draw(tPen) + glyph.draw(self) def getMargins(self): """Get the horizontal margins for all contours combined, i.e. the whole glyph.""" @@ -122,10 +144,9 @@ if __name__ == "__main__": g = CurrentGlyph() pt = (74, 216) - if f is not None and g is not None: - pen = MarginPen(f, pt[1]) - g.draw(pen) - print 'glyph margins', pen.getMargins() - print pen.getContourMargins() - else: - print "no font or glyph" \ No newline at end of file + + pen = MarginPen(f, pt[1], isHorizontal=False) + g.draw(pen) + print 'glyph Y margins', pen.getMargins() + print pen.getContourMargins() +