def __init__(self, font=None, v=0, kernlist=None, overlay=None, anchorPath=None): if isinstance(font, FFont): self.font = None self.ffont = font elif isinstance(font, str): self.openFont(font, overlay, anchorPath) elif isinstance(font, Mix): self.font = font else: self.font = font self.ffont = FFont(font) if isinstance(v, float) or isinstance(v, int): self.v = RPoint(v, v) else: self.v = v if kernlist != None: kerns = [i.strip().split() for i in open(kernlist).readlines()] self.kernlist = [{ 'left': k[0], 'right': k[1], 'value': k[2] } for k in kerns if not k[0].startswith("#") and not k[0] == ""]
def getMitreOffset(n,v1,v2,mitreSize=4,maxAngle=.9): # dont mitre if segment is too short if abs(getMagnitude(v1)) < mitreSize * 2 or abs(getMagnitude(v2)) < mitreSize * 2: return angle = getAngle2(v2,v1) v1 = normalizeVector(v1) v2 = normalizeVector(v2) if v1.x == v2.x and v1.y == v2.y: return # only mitre corners sharper than maxAngle if angle > maxAngle: return radius = mitreSize / abs(getDistance(v1,v2)) offset1 = RPoint(round(v1.x * radius), round(v1.y * radius)) offset2 = RPoint(round(v2.x * radius), round(v2.y * radius)) return offset1, offset2
def __init__(self, masters, v): self.masters = masters if isinstance(v, float) or isinstance(v, int): self.v = RPoint(v, v) else: self.v = v
def _flushContour(self, segments): # # adapted from robofab.pens.adapterPens.PointToSegmentPen # assert len(segments) >= 1 # if we only have one point and it has a name, we must have an anchor first = segments[0] segmentType, points = first pt, smooth, name, kwargs = points[0] if len(segments) == 1 and name != None: self.glyph.appendAnchor(name, pt) return # we must have a contour contour = RContour() contour.setParent(self.glyph) if segments[0][0] == "move": # It's an open path. closed = False points = segments[0][1] assert len(points) == 1 movePt, smooth, name, kwargs = points[0] del segments[0] else: # It's a closed path, do a moveTo to the last # point of the last segment. only if it isn't a qcurve closed = True segmentType, points = segments[-1] movePt, smooth, name, kwargs = points[-1] ## THIS IS STILL UNDECIDED!!! # since objectsRF currently follows the FL model of not # allowing open contours, remove the last segment # since it is being replaced by a move if segmentType == 'line': del segments[-1] # construct a move segment and apply it to the contou if we aren't dealing with a qcurve segment = RSegment() segment.setParent(contour) segment.smooth = smooth rPoint = RPoint(x=movePt[0], y=movePt[1], pointType=MOVE, name=name) rPoint.setParent(segment) segment.points = [rPoint] contour.segments.append(segment) # do the rest of the segments for segmentType, points in segments: points = [pt for pt, smooth, name, kwargs in points] if segmentType == "line": assert len(points) == 1 sType = LINE elif segmentType == "curve": sType = CURVE elif segmentType == "qcurve": sType = QCURVE else: assert 0, "illegal segmentType: %s" % segmentType segment = RSegment() segment.setParent(contour) segment.smooth = smooth rPoints = [] # handle the offCurves for point in points[:-1]: rPoint = RPoint(x=point[0], y=point[1], pointType=OFFCURVE, name=name) rPoint.setParent(segment) rPoints.append(rPoint) # now the onCurve point = points[-1] rPoint = RPoint(x=point[0], y=point[1], pointType=sType, name=name) rPoint.setParent(segment) rPoints.append(rPoint) # apply them to the segment segment.points = rPoints contour.segments.append(segment) self.glyph.contours.append(contour)
return f proj = FontProject(rg.font, BASEDIR, "res/roboto.cfg", th.ffont) #proj.incrementBuildNumber() # FAMILYNAME = "Roboto 2 DRAFT" # FAMILYNAME = "Roboto2" FAMILYNAME = "Roboto" proj.buildOTF = True #proj.compatible = True proj.generateFont(th.font, "%s/Thin/Regular/Th"%FAMILYNAME) proj.generateFont(Mix([th, rg], 0.45), "%s/Light/Regular/Lt"%FAMILYNAME) proj.generateFont(Mix([th, rg], RPoint(0.90, 0.92)), "%s/Regular/Regular/Rg"%FAMILYNAME) proj.generateFont(Mix([rg, bd], 0.35), "%s/Medium/Regular/Lt"%FAMILYNAME) proj.generateFont(Mix([rg, bd], RPoint(0.73, 0.73)), "%s/Bold/Bold/Rg"%FAMILYNAME) proj.generateFont(Mix([rg, bd], RPoint(1.125, 1.0)), "%s/Black/Bold/Bk"%FAMILYNAME) proj.generateFont(th.font, "%s/Thin Italic/Italic/Th"%FAMILYNAME, italic=True, stemWidth=80) proj.generateFont(Mix([th, rg], 0.45), "%s/Light Italic/Italic/Lt"%FAMILYNAME, italic=True, stemWidth=120) proj.generateFont(Mix([th, rg], RPoint(0.90, 0.92)), "%s/Italic/Italic/Rg"%FAMILYNAME, italic=True, stemWidth=185) proj.generateFont(Mix([rg, bd], 0.35), "%s/Medium Italic/Italic/Lt"%FAMILYNAME, italic=True, stemWidth=230)
def getDistance(v1,v2): return getMagnitude(RPoint(v1.x - v2.x, v1.y - v2.y))
def normalizeVector(p): m = getMagnitude(p); if m != 0: return p*(1/m) else: return RPoint(0,0)