def calcCubicBounds(pt1, pt2, pt3, pt4): """Return the bounding rectangle for a cubic bezier segment. pt1 and pt4 are the "anchor" points, pt2 and pt3 are the "handles". >>> calcCubicBounds((0, 0), (25, 100), (75, 100), (100, 0)) (0, 0, 100, 75.0) >>> calcCubicBounds((0, 0), (50, 0), (100, 50), (100, 100)) (0.0, 0.0, 100, 100) >>> print("%f %f %f %f" % calcCubicBounds((50, 0), (0, 100), (100, 100), (50, 0))) 35.566243 0.000000 64.433757 75.000000 """ (ax, ay), (bx, by), (cx, cy), (dx, dy) = calcCubicParameters(pt1, pt2, pt3, pt4) # calc first derivative ax3 = ax * 3.0 ay3 = ay * 3.0 bx2 = bx * 2.0 by2 = by * 2.0 xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1] yRoots = [t for t in solveQuadratic(ay3, by2, cy) if 0 <= t < 1] roots = xRoots + yRoots points = [(ax * t * t * t + bx * t * t + cx * t + dx, ay * t * t * t + by * t * t + cy * t + dy) for t in roots] + [pt1, pt4] return calcBounds(points)
def calcCubicBounds(pt1, pt2, pt3, pt4): """Calculates the bounding rectangle for a quadratic Bezier segment. Args: pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples. Returns: A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``. Example:: >>> calcCubicBounds((0, 0), (25, 100), (75, 100), (100, 0)) (0, 0, 100, 75.0) >>> calcCubicBounds((0, 0), (50, 0), (100, 50), (100, 100)) (0.0, 0.0, 100, 100) >>> print("%f %f %f %f" % calcCubicBounds((50, 0), (0, 100), (100, 100), (50, 0))) 35.566243 0.000000 64.433757 75.000000 """ (ax, ay), (bx, by), (cx, cy), (dx, dy) = calcCubicParameters(pt1, pt2, pt3, pt4) # calc first derivative ax3 = ax * 3.0 ay3 = ay * 3.0 bx2 = bx * 2.0 by2 = by * 2.0 xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1] yRoots = [t for t in solveQuadratic(ay3, by2, cy) if 0 <= t < 1] roots = xRoots + yRoots points = [( ax * t * t * t + bx * t * t + cx * t + dx, ay * t * t * t + by * t * t + cy * t + dy, ) for t in roots] + [pt1, pt4] return calcBounds(points)
def calcQuadraticBounds(pt1, pt2, pt3): """Calculates the bounding rectangle for a quadratic Bezier segment. Args: pt1: Start point of the Bezier as a 2D tuple. pt2: Handle point of the Bezier as a 2D tuple. pt3: End point of the Bezier as a 2D tuple. Returns: A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``. Example:: >>> calcQuadraticBounds((0, 0), (50, 100), (100, 0)) (0, 0, 100, 50.0) >>> calcQuadraticBounds((0, 0), (100, 0), (100, 100)) (0.0, 0.0, 100, 100) """ (ax, ay), (bx, by), (cx, cy) = calcQuadraticParameters(pt1, pt2, pt3) ax2 = ax * 2.0 ay2 = ay * 2.0 roots = [] if ax2 != 0: roots.append(-bx / ax2) if ay2 != 0: roots.append(-by / ay2) points = [(ax * t * t + bx * t + cx, ay * t * t + by * t + cy) for t in roots if 0 <= t < 1] + [pt1, pt3] return calcBounds(points)
def recalcBounds(self, glyfTable): coordinates, endPts, flags = self.getCoordinates(glyfTable) if len(coordinates) > 0: self.xMin, self.yMin, self.xMax, self.yMax = calcBounds( coordinates) else: self.xMin, self.yMin, self.xMax, self.yMax = (0, 0, 0, 0)
def _get_controlPointBounds(self): from fontTools.misc.transform import Transform # storage glyphRects = {} componentReferences = {} # scan loaded glyphs for glyphName, glyph in self._glyphs.items(): if glyphName in self._scheduledForDeletion: continue glyphRect = glyph.controlPointBounds if glyphRect: glyphRects[glyphName] = glyphRect # scan glyphs that have not been loaded if self._glyphSet is not None: for glyphName, fileName in self._glyphSet.contents.items(): if glyphName in self._glyphs or glyphName in self._scheduledForDeletion: continue glif = self._glyphSet.getGLIF(glyphName) points, components = _fetchControlPointBoundsData(glif) if points: glyphRects[glyphName] = calcBounds(points) for base, transformation in components: xScale, xyScale, yxScale, yScale, xOffset, yOffset = transformation if glyphName not in componentReferences: componentReferences[glyphName] = [] componentReferences[glyphName].append((base, xScale, xyScale, yxScale, yScale, xOffset, yOffset)) # get the transformed component bounding boxes and update the glyphs for glyphName, components in componentReferences.items(): glyphRect = glyphRects.get(glyphName, (None, None, None, None)) # XXX this doesn't handle nested components for base, xScale, xyScale, yxScale, yScale, xOffset, yOffset in components: # base glyph doesn't exist if base not in glyphRects: continue baseRect = glyphRects[base] # base glyph has no points if None in baseRect: continue # transform the base rect transform = Transform(xx=xScale, xy=xyScale, yx=yxScale, yy=yScale, dx=xOffset, dy=yOffset) xMin, yMin, xMax, yMax = baseRect (xMin, yMin), (xMax, yMax) = transform.transformPoints([(xMin, yMin), (xMax, yMax)]) componentRect = (xMin, yMin, xMax, yMax) # update the glyph rect if None in glyphRect: glyphRect = componentRect else: glyphRect = unionRect(glyphRect, componentRect) # store the updated rect glyphRects[glyphName] = glyphRect # work out the unified rect fontRect = None for glyphRect in glyphRects.values(): if fontRect is None: fontRect = glyphRect elif glyphRect is not None: fontRect = unionRect(fontRect, glyphRect) # done return fontRect
def recalcBounds(self, glyfTable): coords, endPts, flags = self.getCoordinates(glyfTable) if len(coords) > 0: if 0: # This branch calculates exact glyph outline bounds # analytically, handling cases without on-curve # extremas, etc. However, the glyf table header # simply says that the bounds should be min/max x/y # "for coordinate data", so I suppose that means no # fancy thing here, just get extremas of all coord # points (on and off). As such, this branch is # disabled. # Collect on-curve points onCurveCoords = [coords[j] for j in range(len(coords)) if flags[j] & flagOnCurve] # Add implicit on-curve points start = 0 for end in endPts: last = end for j in range(start, end + 1): if not ((flags[j] | flags[last]) & flagOnCurve): x = (coords[last][0] + coords[j][0]) / 2 y = (coords[last][1] + coords[j][1]) / 2 onCurveCoords.append((x,y)) last = j start = end + 1 # Add bounds for curves without an explicit extrema start = 0 for end in endPts: last = end for j in range(start, end + 1): if not (flags[j] & flagOnCurve): next = j + 1 if j < end else start bbox = calcBounds([coords[last], coords[next]]) if not pointInRect(coords[j], bbox): # Ouch! warnings.warn("Outline has curve with implicit extrema.") # Ouch! Find analytical curve bounds. pthis = coords[j] plast = coords[last] if not (flags[last] & flagOnCurve): plast = ((pthis[0]+plast[0])/2, (pthis[1]+plast[1])/2) pnext = coords[next] if not (flags[next] & flagOnCurve): pnext = ((pthis[0]+pnext[0])/2, (pthis[1]+pnext[1])/2) bbox = calcQuadraticBounds(plast, pthis, pnext) onCurveCoords.append((bbox[0],bbox[1])) onCurveCoords.append((bbox[2],bbox[3])) last = j start = end + 1 self.xMin, self.yMin, self.xMax, self.yMax = calcIntBounds(onCurveCoords) else: self.xMin, self.yMin, self.xMax, self.yMax = calcIntBounds(coords) else: self.xMin, self.yMin, self.xMax, self.yMax = (0, 0, 0, 0)
def calcQuadraticBounds(pt1, pt2, pt3): """Return the bounding rectangle for a qudratic bezier segment. pt1 and pt3 are the "anchor" points, pt2 is the "handle". >>> calcQuadraticBounds((0, 0), (50, 100), (100, 0)) (0, 0, 100, 50.0) >>> calcQuadraticBounds((0, 0), (100, 0), (100, 100)) (0.0, 0.0, 100, 100) """ (ax, ay), (bx, by), (cx, cy) = calcQuadraticParameters(pt1, pt2, pt3) ax2 = ax*2.0 ay2 = ay*2.0 roots = [] if ax2 != 0: roots.append(-bx/ax2) if ay2 != 0: roots.append(-by/ay2) points = [(ax*t*t + bx*t + cx, ay*t*t + by*t + cy) for t in roots if 0 <= t < 1] + [pt1, pt3] return calcBounds(points)
def calcQuadraticBounds(pt1, pt2, pt3): """Return the bounding rectangle for a qudratic bezier segment. pt1 and pt3 are the "anchor" points, pt2 is the "handle". >>> calcQuadraticBounds((0, 0), (50, 100), (100, 0)) (0.0, 0.0, 100.0, 50.0) >>> calcQuadraticBounds((0, 0), (100, 0), (100, 100)) (0.0, 0.0, 100.0, 100.0) """ a, b, c = calcQuadraticParameters(pt1, pt2, pt3) # calc first derivative ax, ay = a * 2 bx, by = b roots = [] if ax != 0: roots.append(-bx / ax) if ay != 0: roots.append(-by / ay) points = [a * t * t + b * t + c for t in roots if 0 <= t < 1] + [pt1, pt3] return calcBounds(points)
def calcQuadraticBounds(pt1, pt2, pt3): """Return the bounding rectangle for a qudratic bezier segment. pt1 and pt3 are the "anchor" points, pt2 is the "handle". >>> calcQuadraticBounds((0, 0), (50, 100), (100, 0)) (0.0, 0.0, 100.0, 50.0) >>> calcQuadraticBounds((0, 0), (100, 0), (100, 100)) (0.0, 0.0, 100.0, 100.0) """ a, b, c = calcQuadraticParameters(pt1, pt2, pt3) # calc first derivative ax, ay = a * 2 bx, by = b roots = [] if ax != 0: roots.append(-bx/ax) if ay != 0: roots.append(-by/ay) points = [a*t*t + b*t + c for t in roots if 0 <= t < 1] + [pt1, pt3] return calcBounds(points)
def calcCubicBounds(pt1, pt2, pt3, pt4): """Return the bounding rectangle for a cubic bezier segment. pt1 and pt4 are the "anchor" points, pt2 and pt3 are the "handles". >>> calcCubicBounds((0, 0), (25, 100), (75, 100), (100, 0)) (0.0, 0.0, 100.0, 75.0) >>> calcCubicBounds((0, 0), (50, 0), (100, 50), (100, 100)) (0.0, 0.0, 100.0, 100.0) >>> calcCubicBounds((50, 0), (0, 100), (100, 100), (50, 0)) (35.5662432703, 0.0, 64.4337567297, 75.0) """ a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) # calc first derivative ax, ay = a * 3.0 bx, by = b * 2.0 cx, cy = c xRoots = [t for t in solveQuadratic(ax, bx, cx) if 0 <= t < 1] yRoots = [t for t in solveQuadratic(ay, by, cy) if 0 <= t < 1] roots = xRoots + yRoots points = [(a*t*t*t + b*t*t + c * t + d) for t in roots] + [pt1, pt4] return calcBounds(points)
def calcCubicBounds(pt1, pt2, pt3, pt4): """Return the bounding rectangle for a cubic bezier segment. pt1 and pt4 are the "anchor" points, pt2 and pt3 are the "handles". >>> calcCubicBounds((0, 0), (25, 100), (75, 100), (100, 0)) (0, 0, 100, 75.0) >>> calcCubicBounds((0, 0), (50, 0), (100, 50), (100, 100)) (0.0, 0.0, 100, 100) >>> print("%f %f %f %f" % calcCubicBounds((50, 0), (0, 100), (100, 100), (50, 0))) 35.566243 0.000000 64.433757 75.000000 """ (ax, ay), (bx, by), (cx, cy), (dx, dy) = calcCubicParameters(pt1, pt2, pt3, pt4) # calc first derivative ax3 = ax * 3.0 ay3 = ay * 3.0 bx2 = bx * 2.0 by2 = by * 2.0 xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1] yRoots = [t for t in solveQuadratic(ay3, by2, cy) if 0 <= t < 1] roots = xRoots + yRoots points = [(ax*t*t*t + bx*t*t + cx * t + dx, ay*t*t*t + by*t*t + cy * t + dy) for t in roots] + [pt1, pt4] return calcBounds(points)
def drawAICBOutlines(data, pen, fitInside=(None, None, None, None), fixedScale=None): """ Draw outline data from an eps. Returns True if the data was drawn, False if not. data = the EPS data (string) pen = a drawing pen fitInside = the maximum size that the outline can be drawn into. the function will transform the eps outlines to fit within this box. if you don't want to transform the data, send it a box of (None, None, None, None). it is also possible to transform based on only horizontal OR vertical parameters. Simply send a box formatted like: (None, -250, None, 750) to base the transform on vertical dimensions or like: (-1000, None, 1000, None) to base the transform on horizontal dimensions. fixedScale = a set scale factor for transforming the outline. If the resulting scaled outline is larger than the fit rect, the outline will be centered on those parameters. """ from fontTools.pens.transformPen import TransformPen from fontTools.misc.arrayTools import calcBounds data = '\n'.join(data.splitlines()) ## ## get the point data # FL follows the EPSF3.0 spec, but AI seems # to be using a different spec. AI puts the outline data # in layers. we can get around this by iterating over all lines # in the data and drawing points as we find them. contours = [] previousOnCurve = None for line in data.splitlines(): movetoMatch = moveto_RE.match(line) if movetoMatch: contours.append([]) x = float(movetoMatch.group(1)) y = float(movetoMatch.group(2)) contours[-1].append(('move', [(x, y)])) previousOnCurve = (x, y) continue linetoMatch = lineto_RE.match(line) if linetoMatch: x = float(linetoMatch.group(1)) y = float(linetoMatch.group(2)) contours[-1].append(('line', [(x, y)])) previousOnCurve = (x, y) continue startCurveToMatch = startCurveTo_RE.match(line) if startCurveToMatch: x1 = float(startCurveToMatch.group(1)) y1 = float(startCurveToMatch.group(2)) x2 = float(startCurveToMatch.group(3)) y2 = float(startCurveToMatch.group(4)) contours[-1].append( ('curve', [previousOnCurve, (x1, y1), (x2, y2)])) previousOnCurve = (x2, y2) continue endCurveToMatch = endCurveTo_RE.match(line) if endCurveToMatch: x1 = float(endCurveToMatch.group(1)) y1 = float(endCurveToMatch.group(2)) x2 = float(endCurveToMatch.group(3)) y2 = float(endCurveToMatch.group(4)) contours[-1].append(('curve', [(x1, y1), (x2, y2), (x2, y2)])) previousOnCurve = (x2, y2) continue curvetoMatch = curveto_RE.match(line) if curvetoMatch: x1 = float(curvetoMatch.group(1)) y1 = float(curvetoMatch.group(2)) x2 = float(curvetoMatch.group(3)) y2 = float(curvetoMatch.group(4)) x3 = float(curvetoMatch.group(5)) y3 = float(curvetoMatch.group(6)) contours[-1].append(('curve', [(x1, y1), (x2, y2), (x3, y3)])) previousOnCurve = (x3, y3) continue # no outline data. give up. if not contours: return False ## get the bounding box boundingBox = boundingBox_RE.findall(data) if boundingBox: # rudely assume that there is only one EPS level bounding box # (the spec says that it should be that way) boundingBox = [ int(i.split('.')[0]) # FL writes floats in the bounding box for i in boundingBox[0].split(' ') ] # the EPS does not have a bounding box # or the EPS has a stated box of (0, 0, 0, 0) # (which AI seems to do for open paths!) # so, we get the bounds from a points array if not boundingBox or boundingBox == [0, 0, 0, 0]: points = [] for contour in contours: for tp, pts in contour: points.extend(pts) boundingBox = calcBounds(points) ## ## determine if the outlines need to be transformed ## and set up the transformation pen. transform = _getRectTransform(fitInside, boundingBox, fixedScale) transformPen = TransformPen(pen, transform) ## ## finally, draw the points for contour in contours: haveClosedPath = False if len(contour) > 1: # filter out overlapping points at the # start and the end of the contour start = contour[0] end = contour[-1] if end[0] == 'line': startPoints = start[1] endPoints = end[1] if start[0] == end[0]: contour = contour[:-1] haveClosedPath = True for tp, pts in contour: if tp == 'move': transformPen.moveTo(pts[0]) elif tp == 'line': transformPen.lineTo(pts[0]) elif tp == 'curve': pt1, pt2, pt3 = pts transformPen.curveTo(pt1, pt2, pt3) transformPen.closePath() # XXX #if haveClosedPath: # transformPen.closePath() #else: # transformPen.endPath() return True
## loops c = 10000 print "(loop %s)" % c print "with numpy:" print "calcQuadraticParameters\t\t", n = time.time() for i in range(c): bezierTools.calcQuadraticParameters(pt1, pt2, pt3) print time.time() - n print "calcBounds\t\t\t", n = time.time() for i in range(c): arrayTools.calcBounds( [pt1, pt2, pt3, pt1, pt2, pt3, pt1, pt2, pt3, pt1, pt2, pt3]) print time.time() - n print "pointsInRect\t\t\t", n = time.time() for i in range(c): arrayTools.pointsInRect( [pt1, pt2, pt3, pt1, pt2, pt3, pt1, pt2, pt3, pt1, pt2, pt3, pt4], rect) print time.time() - n print "calcQuadraticBounds\t\t", n = time.time() for i in range(c): bezierTools.calcQuadraticBounds(pt1, pt2, pt3) print time.time() - n
def drawAICBOutlines(data, pen, fitInside=(None, None, None, None), fixedScale=None): """ Draw outline data from an eps. Returns True if the data was drawn, False if not. data = the EPS data (string) pen = a drawing pen fitInside = the maximum size that the outline can be drawn into. the function will transform the eps outlines to fit within this box. if you don't want to transform the data, send it a box of (None, None, None, None). it is also possible to transform based on only horizontal OR vertical parameters. Simply send a box formatted like: (None, -250, None, 750) to base the transform on vertical dimensions or like: (-1000, None, 1000, None) to base the transform on horizontal dimensions. fixedScale = a set scale factor for transforming the outline. If the resulting scaled outline is larger than the fit rect, the outline will be centered on those parameters. """ from fontTools.pens.transformPen import TransformPen from fontTools.misc.arrayTools import calcBounds data = '\n'.join(data.splitlines()) ## ## get the point data # FL follows the EPSF3.0 spec, but AI seems # to be using a different spec. AI puts the outline data # in layers. we can get around this by iterating over all lines # in the data and drawing points as we find them. contours = [] previousOnCurve = None for line in data.splitlines(): movetoMatch = moveto_RE.match(line) if movetoMatch: contours.append([]) x = float(movetoMatch.group(1)) y = float(movetoMatch.group(2)) contours[-1].append(('move', [(x, y)])) previousOnCurve = (x, y) continue linetoMatch = lineto_RE.match(line) if linetoMatch: x = float(linetoMatch.group(1)) y = float(linetoMatch.group(2)) contours[-1].append(('line', [(x, y)])) previousOnCurve = (x, y) continue startCurveToMatch = startCurveTo_RE.match(line) if startCurveToMatch: x1 = float(startCurveToMatch.group(1)) y1 = float(startCurveToMatch.group(2)) x2 = float(startCurveToMatch.group(3)) y2 = float(startCurveToMatch.group(4)) contours[-1].append(('curve', [previousOnCurve, (x1, y1), (x2, y2)])) previousOnCurve = (x2, y2) continue endCurveToMatch = endCurveTo_RE.match(line) if endCurveToMatch: x1 = float(endCurveToMatch.group(1)) y1 = float(endCurveToMatch.group(2)) x2 = float(endCurveToMatch.group(3)) y2 = float(endCurveToMatch.group(4)) contours[-1].append(('curve', [(x1, y1), (x2, y2), (x2, y2)])) previousOnCurve = (x2, y2) continue curvetoMatch = curveto_RE.match(line) if curvetoMatch: x1 = float(curvetoMatch.group(1)) y1 = float(curvetoMatch.group(2)) x2 = float(curvetoMatch.group(3)) y2 = float(curvetoMatch.group(4)) x3 = float(curvetoMatch.group(5)) y3 = float(curvetoMatch.group(6)) contours[-1].append(('curve', [(x1, y1), (x2, y2), (x3, y3)])) previousOnCurve = (x3, y3) continue # no outline data. give up. if not contours: return False ## get the bounding box boundingBox = boundingBox_RE.findall(data) if boundingBox: # rudely assume that there is only one EPS level bounding box # (the spec says that it should be that way) boundingBox = [ int(i.split('.')[0]) # FL writes floats in the bounding box for i in boundingBox[0].split(' ') ] # the EPS does not have a bounding box # or the EPS has a stated box of (0, 0, 0, 0) # (which AI seems to do for open paths!) # so, we get the bounds from a points array if not boundingBox or boundingBox == [0, 0, 0, 0]: points = [] for contour in contours: for tp, pts in contour: points.extend(pts) boundingBox = calcBounds(points) ## ## determine if the outlines need to be transformed ## and set up the transformation pen. transform = _getRectTransform(fitInside, boundingBox, fixedScale) transformPen = TransformPen(pen, transform) ## ## finally, draw the points for contour in contours: haveClosedPath = False if len(contour) > 1: # filter out overlapping points at the # start and the end of the contour start = contour[0] end = contour[-1] if end[0] == 'line': startPoints = start[1] endPoints = end[1] if start[0] == end[0]: contour = contour[:-1] haveClosedPath = True for tp, pts in contour: if tp == 'move': transformPen.moveTo(pts[0]) elif tp == 'line': transformPen.lineTo(pts[0]) elif tp == 'curve': pt1, pt2, pt3 = pts transformPen.curveTo(pt1, pt2, pt3) transformPen.closePath() # XXX #if haveClosedPath: # transformPen.closePath() #else: # transformPen.endPath() return True
def _get_controlPointBounds(self): from fontTools.misc.transform import Transform # storage glyphRects = {} componentReferences = {} # scan loaded glyphs for glyphName, glyph in self._glyphs.items(): if glyphName in self._scheduledForDeletion: continue glyphRect = glyph.controlPointBounds if glyphRect: glyphRects[glyphName] = glyphRect # scan glyphs that have not been loaded if self._glyphSet is not None: for glyphName, fileName in self._glyphSet.contents.items(): if glyphName in self._glyphs or glyphName in self._scheduledForDeletion: continue glif = self._glyphSet.getGLIF(glyphName) points, components = _fetchControlPointBoundsData(glif) if points: glyphRects[glyphName] = calcBounds(points) for base, transformation in components: xScale, xyScale, yxScale, yScale, xOffset, yOffset = transformation if glyphName not in componentReferences: componentReferences[glyphName] = [] componentReferences[glyphName].append( (base, xScale, xyScale, yxScale, yScale, xOffset, yOffset)) # get the transformed component bounding boxes and update the glyphs for glyphName, components in componentReferences.items(): glyphRect = glyphRects.get(glyphName, (None, None, None, None)) # XXX this doesn't handle nested components for base, xScale, xyScale, yxScale, yScale, xOffset, yOffset in components: # base glyph doesn't exist if base not in glyphRects: continue baseRect = glyphRects[base] # base glyph has no points if None in baseRect: continue # transform the base rect transform = Transform(xx=xScale, xy=xyScale, yx=yxScale, yy=yScale, dx=xOffset, dy=yOffset) xMin, yMin, xMax, yMax = baseRect (xMin, yMin), (xMax, yMax) = transform.transformPoints([ (xMin, yMin), (xMax, yMax) ]) componentRect = (xMin, yMin, xMax, yMax) # update the glyph rect if None in glyphRect: glyphRect = componentRect else: glyphRect = unionRect(glyphRect, componentRect) # store the updated rect glyphRects[glyphName] = glyphRect # work out the unified rect fontRect = None for glyphRect in glyphRects.values(): if fontRect is None: fontRect = glyphRect elif glyphRect is not None: fontRect = unionRect(fontRect, glyphRect) # done return fontRect
def test_calcBounds(): assert calcBounds([]) == (0, 0, 0, 0) assert calcBounds( [(0, 40), (0, 100), (50, 50), (80, 10)]) == (0, 10, 80, 100)
def recalcBounds(self, glyfTable): coordinates, endPts, flags = self.getCoordinates(glyfTable) if len(coordinates) > 0: self.xMin, self.yMin, self.xMax, self.yMax = calcBounds(coordinates) else: self.xMin, self.yMin, self.xMax, self.yMax = (0, 0, 0, 0)
c = 10000 print "(loop %s)"%c print "with numpy:" print "calcQuadraticParameters\t\t", n = time.time() for i in range(c): bezierTools.calcQuadraticParameters(pt1, pt2, pt3) print time.time() - n print "calcBounds\t\t\t", n = time.time() for i in range(c): arrayTools.calcBounds([pt1, pt2, pt3, pt1, pt2, pt3, pt1, pt2, pt3, pt1, pt2, pt3]) print time.time() - n print "pointsInRect\t\t\t", n = time.time() for i in range(c): arrayTools.pointsInRect([pt1, pt2, pt3, pt1, pt2, pt3, pt1, pt2, pt3, pt1, pt2, pt3, pt4], rect) print time.time() - n print "calcQuadraticBounds\t\t", n = time.time() for i in range(c): bezierTools.calcQuadraticBounds(pt1, pt2, pt3) print time.time() - n print "calcCubicBounds\t\t\t",
def test_calcBounds(): assert calcBounds([]) == (0, 0, 0, 0) assert calcBounds([(0, 40), (0, 100), (50, 50), (80, 10)]) == (0, 10, 80, 100)