def _drawGeometry(self, info): reference_glyph = CurrentGlyph() #rect(0, 0, 200, 100) #rect(0, 0, self.w.eqCurvatureSlider.get() * 200, 100) if roboFontVersion > "3.1": reference_glyph_selected_points = reference_glyph.selectedPoints else: reference_glyph_selected_points = reference_glyph.selection stroke(0.5, 0.6, 0.9, 0.8) strokeWidth(0.8 * info["scale"]) if reference_glyph_selected_points != []: for contourIndex in range(len(reference_glyph.contours)): reference_contour = reference_glyph.contours[contourIndex] for i in range(len(reference_contour.segments)): reference_segment = reference_contour[i] if reference_segment.selected and reference_segment.type == "curve": # last point of the previous segment p0 = reference_contour[i-1][-1] if len(reference_segment.points) == 3: p1, p2, p3 = reference_segment.points alpha = atan2(p1.y - p0.y, p1.x - p0.x) beta = atan2(p2.y - p3.y, p2.x - p3.x) if abs(alpha - beta) >= 0.7853981633974483: if isOnLeft(p0, p3, p1) and isOnLeft(p0, p3, p2) or isOnRight(p0, p3, p1) and isOnRight(p0, p3, p2): #alpha, beta, gamma = getTriangleAngles(p0, p1, p2, p3) a, b, c = getTriangleSides(p0, p1, p2, p3) line((p0.x, p0.y), (p0.x + (c+5) * cos(alpha), p0.y + (c+5) * sin(alpha))) line((p3.x, p3.y), (p3.x + (a+5) * cos(beta) , p3.y + (a+5) * sin(beta) )) line((p0.x, p0.y), (p3.x, p3.y))
def drawReferenceGlyph(aGlyph, scalingFactor, startingX, left=False, right=False): dt.save() dt.fill(*BLACK) dt.stroke(None) dt.translate(startingX, 0) dt.scale(scalingFactor, scalingFactor) dt.translate(0, -aGlyph.getParent().info.descender) dt.translate(-aGlyph.width / 2, 0) dt.fill(*BLACK) dt.drawGlyph(aGlyph) descender = aGlyph.getParent().info.descender unitsPerEm = aGlyph.getParent().info.unitsPerEm baseTck = 40 if left is True: dt.fill(*RED) dt.rect(0, -baseTck, aGlyph.leftMargin, baseTck) dt.rect(0, descender, 8, unitsPerEm) if right is True: dt.fill(*BLUE) dt.rect(aGlyph.width - aGlyph.rightMargin, -baseTck, aGlyph.rightMargin, baseTck) dt.rect(aGlyph.width, descender, 8, unitsPerEm) dt.restore()
def draw(self, info): if not self.calculatePreview: return cur = CurrentGlyph() if cur == None: return scale = info['scale'] layerToConvert = self.layers[self.w.layerPopup.get()] otherLayer = layerToConvert != 'foreground' if (not otherLayer) and ( CurrentFont().lib['com.typemytype.robofont.segmentType'] == 'qcurve'): return if otherLayer: cur.flipLayers('foreground', layerToConvert) copy = cur.copy() if otherLayer: cur.flipLayers('foreground', layerToConvert) convert(copy, self.maxDistanceValue, self.minLengthValue, self.useArcLength) for c in copy: for p in c.points: if p.type == 'offCurve': color = OffColor r = 4 * scale else: color = OnColor r = 6 * scale self.drawDiscAtPoint(r, p.x, p.y, color) save() stroke(0.2, .8, .8, 1) fill(None) strokeWidth(scale) drawGlyph(copy) restore()
def drawLines(self, lineThickness): # Don't do anything if no segments have been selected, # or if more than 1 contour has been selected if not self.selectedSegments or len(self.selectedContours) > 1: return contourPoints = self._collectPointsInContour(self.selectedContours[0]) for segment in self.selectedSegments: selectedOnCurves = [] selectedOffCurves = [] for point in segment.points: if point.type == "offcurve": selectedOffCurves.append(point) else: selectedOnCurves.append(point) pt0 = self._findPrevOnCurvePt(selectedOnCurves[0], contourPoints).position pt1 = selectedOnCurves[0].position pt2 = selectedOffCurves[0].position pt3 = selectedOffCurves[1].position # if lines are parallel, lines are green; otherwise, red if self._checkParallel((pt0, pt1), (pt2, pt3)): dt.stroke(0, 1, 0, 1) else: dt.stroke(1, 0, 0, 1) dt.strokeWidth(lineThickness) dt.line(pt0, pt1) dt.line(pt2, pt3)
def _curvePreview(self, info): _doodle_glyph = info["glyph"] if CurrentGlyph() is not None and _doodle_glyph is not None and len(_doodle_glyph.components) == 0 and _doodle_glyph.selection != []: ######## # Here's how this works: if there is a current glyph, and that glyph has a selection, we get here # then there is a temp glyph, in memory. Every "draw", this is called, it clears the glyph # and then draws the current glyph in its place, then equilizes that glyph in a different # method, then draws it into this view. # The problem is the outline is not updating. If you commit the change it shows up, but this memory # glyph isn't getting redrawn ever. The glyph is redrawing the same thing over and over. ####### self.tmp_glyph.clear() self.tmp_glyph.appendGlyph(_doodle_glyph) # I think what needs to happen here is instead of this mysterious function happening, # it needs to return an equilized glyph object that is then drawn onto the view # instead of maintaining a virtual copy that needs to be cleared and updated each draw # more like tmp_glyph = self._equalized_glyph(_doodle_glyph); drawGlyph(tmp_glyph) # vvvvvvvvvvvvvvvv self._eqSelected() # ^^^^^^^^^^^^^^^^^ self.tmp_glyph.update() save() stroke(random(), random(), random(), 1.0) # stroke(0, 0, 0, 0.5) #if self.method == "hobby": # fill(1, 0, 0, 0.9) #else: fill(None) strokeWidth(info["scale"]) drawGlyph(self.tmp_glyph) restore()
def _drawGlyphOutlines(self, glyphName): dt.save() dt.fill(*BLACK) dt.stroke(None) glyphToDisplay = self.fontObj[glyphName] dt.drawGlyph(glyphToDisplay) dt.restore()
def _drawOffgridPoints(self, glyph, scalingFactor): dt.save() dt.fill(*RED_COLOR) dt.stroke(None) scaledRadius = OFFGRID_RADIUS * scalingFactor for eachContour in glyph: for eachBPT in eachContour.bPoints: if eachBPT.anchor[0] % 4 != 0 or eachBPT.anchor[1] % 4 != 0: dt.oval(eachBPT.anchor[0] - scaledRadius / 2., eachBPT.anchor[1] - scaledRadius / 2., scaledRadius, scaledRadius) if eachBPT.bcpIn != (0, 0): bcpInAbs = eachBPT.anchor[0] + eachBPT.bcpIn[ 0], eachBPT.anchor[1] + eachBPT.bcpIn[1] if bcpInAbs[0] % 4 != 0 or bcpInAbs[1] % 4 != 0: dt.oval(bcpInAbs[0] - scaledRadius / 2., bcpInAbs[1] - scaledRadius / 2., scaledRadius, scaledRadius) if eachBPT.bcpOut != (0, 0): bcpOutAbs = eachBPT.anchor[0] + eachBPT.bcpOut[ 0], eachBPT.anchor[1] + eachBPT.bcpOut[1] if bcpOutAbs[0] % 4 != 0 or bcpOutAbs[1] % 4 != 0: dt.oval(bcpOutAbs[0] - scaledRadius / 2., bcpOutAbs[1] - scaledRadius / 2., scaledRadius, scaledRadius) dt.restore()
def draw(self, info): if not self.calculatePreview: return cur = CurrentGlyph() if cur == None: return; scale = info['scale'] layerToConvert = self.layers[self.w.layerPopup.get()] otherLayer = layerToConvert != 'foreground' if (not otherLayer) and (CurrentFont().lib['com.typemytype.robofont.segmentType'] == 'qcurve'): return if otherLayer: cur.flipLayers('foreground', layerToConvert) copy = cur.copy() if otherLayer: cur.flipLayers('foreground', layerToConvert) convert(copy, self.maxDistanceValue, self.minLengthValue, self.useArcLength) for c in copy: for p in c.points: if p.type == 'offCurve': color = OffColor r = 4*scale else: color = OnColor r = 6*scale self.drawDiscAtPoint(r, p.x, p.y, color) save() stroke(0.2, .8, .8, 1) fill(None) strokeWidth(scale) drawGlyph(copy) restore()
def _curvePreview(self, info): _doodle_glyph = info["glyph"] if roboFontVersion > "3.1": _doodle_glyph_selected_points = _doodle_glyph.selectedPoints else: _doodle_glyph_selected_points = _doodle_glyph.selection if CurrentGlyph() is not None \ and _doodle_glyph is not None \ and len(_doodle_glyph.components) == 0 \ and _doodle_glyph_selected_points != []: self.tmp_glyph = CurrentGlyph().copy() self._eqSelected() if self.previewCurves: save() stroke(0, 0, 0, 0.5) fill(None) strokeWidth(info["scale"]) drawGlyph(self.tmp_glyph) restore() if self.drawGeometry: self._drawGeometry(info) if self.previewHandles: self._handlesPreview(info)
def _handlesPreview(self, info): _doodle_glyph = info["glyph"] if roboFontVersion > "3.1": _doodle_glyph_selected_points = _doodle_glyph.selectedPoints else: _doodle_glyph_selected_points = _doodle_glyph.selection if CurrentGlyph() is not None \ and _doodle_glyph is not None \ and len(_doodle_glyph.components) == 0 \ and _doodle_glyph_selected_points != []: glyph = self.tmp_glyph #.copy() ref_glyph = CurrentGlyph() save() stroke(0, 0, 0, 0.3) strokeWidth(info["scale"]) fill(None) l = 4 * info["scale"] for contourIndex in range(len(glyph)): contour = self.tmp_glyph.contours[contourIndex] ref_contour = ref_glyph.contours[contourIndex] for i in range(len(contour.segments)): segment = contour[i] if ref_contour[i].selected and segment.type == "curve": for p in segment.points[0:2]: x = p.x y = p.y line((x-l, y-l), (x+l, y+l)) line((x-l, y+l), (x+l, y-l)) restore()
def textQualities(scaledFontSize, weight='regular', color=BLACK_COLOR): dt.stroke(None) dt.fill(*color) if weight == 'bold': dt.font(SYSTEM_FONT_NAME_BOLD) else: dt.font(SYSTEM_FONT_NAME) dt.fontSize(scaledFontSize)
def _drawDiagonals(self, currentGlyph, scalingFactor, offset_X=0): if DIAGONALS_KEY not in currentGlyph.lib: return None diagonalsData = calcDiagonalsData(currentGlyph, DIAGONALS_KEY) for ptsToDisplay, angle, distance in diagonalsData: pt1, pt2 = ptsToDisplay dt.save() dt.stroke(*self.diagonalColor) dt.fill(None) dt.strokeWidth(1 * scalingFactor) if 90 < angle <= 180 or -180 < angle < -90: direction = -1 adjustedAngle = angle + 180 + 90 else: direction = 1 adjustedAngle = angle + 90 diagonalPt1 = pt1[0] + cos(radians(adjustedAngle)) * ( (DIAGONAL_OFFSET - 1) * direction), pt1[1] + sin( radians(adjustedAngle)) * ( (DIAGONAL_OFFSET - 1) * direction) diagonalPt2 = pt2[0] + cos(radians(adjustedAngle)) * ( (DIAGONAL_OFFSET - 1) * direction), pt2[1] + sin( radians(adjustedAngle)) * ( (DIAGONAL_OFFSET - 1) * direction) offsetPt1 = pt1[0] + cos(radians( adjustedAngle)) * DIAGONAL_OFFSET * direction, pt1[1] + sin( radians(adjustedAngle)) * DIAGONAL_OFFSET * direction offsetPt2 = pt2[0] + cos(radians( adjustedAngle)) * DIAGONAL_OFFSET * direction, pt2[1] + sin( radians(adjustedAngle)) * DIAGONAL_OFFSET * direction dt.line((pt1), (offsetPt1)) dt.line((pt2), (offsetPt2)) dt.line((diagonalPt1), (diagonalPt2)) dt.restore() dt.save() textQualities(BODYSIZE_CAPTION * scalingFactor) offsetMidPoint = calcMidPoint(offsetPt1, offsetPt2) dt.translate(offsetMidPoint[0], offsetMidPoint[1]) if 90 < angle <= 180 or -180 < angle < -90: dt.rotate(angle + 180) textBoxY = -BODYSIZE_CAPTION * 1.2 * scalingFactor else: dt.rotate(angle) textBoxY = 0 dataToPlot = u'∡{:.1f} ↗{:d}'.format(angle % 180, int(distance)) textWidth, textHeight = dt.textSize(dataToPlot) dt.textBox(dataToPlot, (-textWidth / 2., textBoxY, textWidth, BODYSIZE_CAPTION * 1.2 * scalingFactor), align='center') dt.restore()
def _drawGlyphBlack(self, glyph, scalingFactor, offset_X=0): dt.save() dt.translate(offset_X, 0) dt.fill(*BLACK_COLOR) dt.stroke(None) dt.drawGlyph(glyph) dt.restore()
def draw(self, scale): size = 20 * scale save() fill(0.2, 0.5, 0.35, 0.3) stroke(None) #for contour in self.errors.keys(): # for p in contour: # oval(p[0]-5, p[1]-5, 10, 10) for p in self.errors: oval(p[0]-size/2, p[1]-size/2, size, size) restore()
def draw(self, scale): size = 20 * scale save() fill(0.2, 0.5, 0.35, 0.3) stroke(None) #for contour in self.errors.keys(): # for p in contour: # oval(p[0]-5, p[1]-5, 10, 10) for p in self.errors: oval(p[0] - size / 2, p[1] - size / 2, size, size) restore()
def drawPreview(self, scale): # only draws if there are already outlines in the glyph if self._xMin is None: return ctx.save() ctx.stroke(1, .4, 0) ctx.strokeWidth(2 * scale) ctx.lineDash(10 * scale, 20 * scale) ctx.fill(0) self.buildShapePath(scale) ctx.drawPath() ctx.restore()
def dot(self, p, s=4, scale=1, stacked=False): # draw a dot ctx.save() ctx.stroke(None) if stacked: ctx.fill(0, .5, 1) else: ctx.fill(1, .5, 0) s *= scale ctx.oval(p[0] - .5 * s, p[1] - .5 * s, s, s) ctx.restore()
def drawPreview(self, info): # Draw a filled in version of the interpolated glyph scale = info["scale"] if self.interpolatedGlyph: pen = CocoaPen(None) self.interpolatedGlyph.draw(pen) dt.fill(r=0, g=0, b=0, a=0.6) dt.stroke(r=None, g=None, b=None, a=1) dt.save() dt.translate(self.currentGlyph.width) dt.drawPath(pen.path) dt.restore()
def _canvas_draw_metrics(self): save() strokeWidth(1 / self.scale) stroke(0.8, 0.8, 0.8) line((0, 0), (self.width, 0)) line((0, self.metrics[0]), (self.width, self.metrics[0])) line((0, self.metrics[1]), (self.width, self.metrics[1])) line((0, self.metrics[2]), (self.width, self.metrics[2])) line((0, self.metrics[3]), (self.width, self.metrics[3])) line((0, self.metrics[3]), (0, self.metrics[0])) line((self.width, self.metrics[3]), (self.width, self.metrics[0])) restore()
def drawVariationPreview(self, glyph, scale, color, strokecolor): mjdt.save() mjdt.fill(*color) mjdt.stroke(*strokecolor) mjdt.strokeWidth(scale) loc = {} if glyph.sourcesList: loc = {x["Axis"]: x["PreviewValue"] for x in glyph.sourcesList} for g in glyph.preview(loc, forceRefresh=False): # for g in glyph.previewGlyph: mjdt.drawGlyph(self.roundGlyph(g.glyph)) mjdt.restore()
def drawPoints(self, info): newPoints = self.getValues(None) if newPoints != None: glyph = CurrentGlyph() onCurveSize = getDefault("glyphViewOncurvePointsSize") * 5 offCurveSize = getDefault("glyphViewOncurvePointsSize") * 3 fillColor = tuple([i for i in getDefault("glyphViewCurvePointsFill")]) upmScale = (glyph.font.info.unitsPerEm/1000) scale = info["scale"] oPtSize = onCurveSize * scale fPtSize = offCurveSize * scale d.save() # thanks Erik! textLoc = newPoints[0][3][0] + math.cos(self.returnAngle(newPoints)) * (scale*.25*120) * 2, newPoints[0][3][1] + math.sin(self.returnAngle(newPoints)) * (scale*.25*120) * 2 for b in newPoints: for a in b: if a == newPoints[1][0] or a == newPoints[0][-1]: d.oval(a[0]-oPtSize/2,a[1]-oPtSize/2, oPtSize, oPtSize) else: d.oval(a[0]-fPtSize/2,a[1]-fPtSize/2, fPtSize, fPtSize) d.fill(fillColor[0],fillColor[1],fillColor[2],fillColor[3]) d.stroke(fillColor[0],fillColor[1],fillColor[2],fillColor[3]) d.strokeWidth(scale) d.line(newPoints[0][2],newPoints[1][1]) d.restore() # https://robofont.com/documentation/building-tools/toolspace/observers/draw-info-text-in-glyph-view/?highlight=draw%20text glyphWindow = CurrentGlyphWindow() if not glyphWindow: return glyphView = glyphWindow.getGlyphView() textAttributes = { AppKit.NSFontAttributeName: AppKit.NSFont.userFixedPitchFontOfSize_(11), } glyphView.drawTextAtPoint( f'{round(abs(math.degrees(self.returnAngle(newPoints)))%180,4)}°\n{str(round(self.returnRatio(newPoints),4))}', textAttributes, textLoc, yOffset=0, drawBackground=True, centerX=True, centerY=True, roundBackground=False,) UpdateCurrentGlyphView()
def _drawBaseline(self, glyphName): glyphToDisplay = self.fontObj[glyphName] dt.save() dt.stroke(*BLACK) dt.fill(None) # reversed scaling factor dt.strokeWidth( 1 / (self.ctrlHeight / (self.canvasScalingFactor * self.fontObj.info.unitsPerEm))) dt.line((0, 0), (glyphToDisplay.width, 0)) dt.restore()
def draw(self, info): self.w.pointSize.set(self.w.multiLineView.getPointSize()) glyph = self.RCJKI.currentFont[info["glyph"].name]#, self.RCJKI.currentFont._RFont) scale = info["scale"] sourcesList = {x["Axis"]:x["PreviewValue"] for x in self.sourcesList} mjdt.save() mjdt.fill(0, 0, 0, 1) mjdt.stroke(0, 0, 0, 0) mjdt.strokeWidth(scale) for c in glyph.preview(sourcesList, forceRefresh=True): mjdt.drawGlyph(c.glyph) mjdt.restore()
def _curvePreview(self, info): dg = info["glyph"] scale = info["scale"] if dg is not None: self.tmpGlyph.clear() self.tmpGlyph.appendGlyph(CurrentGlyph()) self._eqSelected() mPen = MojoDrawingToolsPen(self.tmpGlyph, CurrentFont()) save() stroke(0, 0, 0, 0.5) fill(None) strokeWidth(scale) self.tmpGlyph.draw(mPen) mPen.draw() restore()
def _curvePreview(self, info): _doodle_glyph = info["glyph"] if _doodle_glyph is not None and len(_doodle_glyph.components) == 0 and _doodle_glyph.selection != []: self.tmp_glyph.clear() self.tmp_glyph.appendGlyph(_doodle_glyph) self._eqSelected() save() stroke(0, 0, 0, 0.5) #if self.method == "hobby": # fill(1, 0, 0, 0.9) #else: fill(None) strokeWidth(info["scale"]) drawGlyph(self.tmp_glyph) restore()
def _curvePreview(self, info): _doodle_glyph = info["glyph"] if _doodle_glyph is not None and len(_doodle_glyph.components) == 0 and _doodle_glyph.selection != []: self.tmp_glyph.clear() self.tmp_glyph.appendGlyph(_doodle_glyph) self._hobbycurve() pen = MojoDrawingToolsPen(self.tmp_glyph, _doodle_glyph.getParent()) save() stroke(0, 0, 0, 0.5) fill(1, 0, 0, 0.9) strokeWidth(info["scale"]) self.tmp_glyph.draw(pen) pen.draw() restore() UpdateCurrentGlyphView()
def _drawMetricsCorrection(self, correction): dt.save() dt.fill(*BLACK) dt.stroke(None) dt.translate( 0, self.fontObj.info.unitsPerEm + self.fontObj.info.descender + 100) dt.scale(1 / (self.ctrlHeight / (self.canvasScalingFactor * self.fontObj.info.unitsPerEm))) dt.font(SYSTEM_FONT_NAME) dt.fontSize(BODY_SIZE) textWidth, textHeight = dt.textSize('{:+d}'.format(correction)) dt.textBox('{:+d}'.format(correction), (-textWidth / 2., -textHeight / 2., textWidth, textHeight), align='center') dt.restore()
def _curvePreview(self, info): _doodle_glyph = info["glyph"] if _doodle_glyph is not None and len( _doodle_glyph.components ) == 0 and _doodle_glyph.selection != []: self.tmp_glyph.clear() self.tmp_glyph.appendGlyph(_doodle_glyph) self._eqSelected() save() stroke(0, 0, 0, 0.5) #if self.method == "hobby": # fill(1, 0, 0, 0.9) #else: fill(None) strokeWidth(info["scale"]) drawGlyph(self.tmp_glyph) restore()
def drawRect_(self, rect): # draw here! if self.delegate.checked: AppKit.NSColor.selectedControlColor().set() selectionPath = AppKit.NSBezierPath.bezierPathWithRoundedRect_xRadius_yRadius_( AppKit.NSInsetRect(rect, 2, 2), 4, 4) AppKit.NSColor.selectedControlColor().colorWithAlphaComponent_( 0.1).set() selectionPath.fill() AppKit.NSColor.selectedControlColor().set() selectionPath.stroke() frame_width, frame_height = self.frame().size w, h = [i - 2 * self._inset for i in self.frame().size] glyph_pair = self._glyphData glyph_l, glyph_r = glyph_pair font = glyph_l.getParent() upm = font.info.unitsPerEm scale_factor = h / (upm * 1.2) drawBot.translate(frame_width / 2, self._inset) drawBot.scale(scale_factor) drawBot.stroke(None) if self._kern_value <= 0: drawBot.fill(1, 0.3, 0.75) else: drawBot.fill(0, 0.8, 0) drawBot.rect( # bottom rectangle 0 - abs(self._kern_value) / 2, self._inset / scale_factor, abs(self._kern_value), 2 * self._inset / scale_factor) drawBot.rect( # top rectangle 0 - abs(self._kern_value) / 2, (h - self._inset) / scale_factor, abs(self._kern_value), 2 * self._inset / scale_factor) drawBot.translate(0, upm / 3) drawBot.translate(-glyph_l.width - self._kern_value / 2, 0) for glyph in glyph_pair: path = glyph.getRepresentation('defconAppKit.NSBezierPath') drawBot.stroke(None) drawBot.fill(0) drawBot.drawPath(path) drawBot.translate(glyph.width + self._kern_value, 0)
def _drawStems(self, currentGlyph, scalingFactor, offset_X=0): if STEM_KEY not in currentGlyph.lib: return None stemData = calcStemsData(currentGlyph, STEM_KEY) for PTs, DIFFs, middlePoint in stemData: pt1, pt2 = PTs horDiff, verDiff = DIFFs dt.save() dt.translate(offset_X, 0) dt.stroke(*self.stemColor) dt.fill(None) dt.strokeWidth(1 * scalingFactor) dt.newPath() if horDiff > verDiff: # ver rightPt, leftPt = PTs if pt1.x > pt2.x: rightPt, leftPt = leftPt, rightPt dt.moveTo((leftPt.x, leftPt.y)) dt.curveTo((leftPt.x - horDiff / 2, leftPt.y), (rightPt.x + horDiff / 2, rightPt.y), (rightPt.x, rightPt.y)) else: # hor topPt, btmPt = PTs if pt2.y > pt1.y: btmPt, topPt = topPt, btmPt dt.moveTo((btmPt.x, btmPt.y)) dt.curveTo((btmPt.x, btmPt.y + verDiff / 2), (topPt.x, topPt.y - verDiff / 2), (topPt.x, topPt.y)) dt.drawPath() dt.restore() dt.save() dt.translate(offset_X, 0) textQualities(BODYSIZE_CAPTION * scalingFactor) dataToPlot = u'↑{:d}\n→{:d}'.format(int(verDiff), int(horDiff)) textWidth, textHeight = dt.textSize(dataToPlot) textRect = (middlePoint[0] - textWidth / 2., middlePoint[1] - textHeight / 2., textWidth, textHeight) dt.textBox(dataToPlot, textRect, align='center') dt.restore()
def _drawArrow(self, position, kind, size, width): x, y = position save() translate(x, y) fill(0, 0.8, 0, 0.1) strokeWidth(width) stroke(0.9, 0.1, 0, 0.85) line(-width/2, 0, size, 0) line(0, width/2, 0, -size) line(0, 0, size, -size) #rect(x-scale, y-scale, scale, scale) if self.showLabels: fill(0.4, 0.4, 0.4, 0.7) stroke(None) font("LucidaGrande") fontSize(int(round(size * 1.1))) text(kind, (int(round(size * 1.8)), int(round(-size)))) restore()
def _drawArrow(self, position, kind, size, width): x, y = position save() translate(x, y) fill(0, 0.8, 0, 0.1) strokeWidth(width) stroke(0.9, 0.1, 0, 0.85) line(-width / 2, 0, size, 0) line(0, width / 2, 0, -size) line(0, 0, size, -size) #rect(x-scale, y-scale, scale, scale) if self.showLabels: fill(0.4, 0.4, 0.4, 0.7) stroke(None) font("LucidaGrande") fontSize(int(round(size * 1.1))) text(kind, (int(round(size * 1.8)), int(round(-size)))) restore()
def drawActionPreview(self, data): if not self.previewObjects: return pen = CocoaPen(glyphSet=self.glyph.layer) for obj in self.previewObjects: if isinstance(obj, BaseBPoint): pass elif isinstance(obj, BaseContour): obj.draw(pen) elif isinstance(obj, BaseComponent): obj.draw(pen) pixel = 1.0 / data["scale"] r, g, b, a = getDefault("glyphViewEchoStrokeColor") with bot.savedState(): bot.fill(None) bot.stroke(r, g, b, a) bot.strokeWidth(pixel) bot.drawPath(pen.path)
def _drawArrows(self, notification): glyph = notification["glyph"] if glyph is None: return font = glyph.getParent() if roboFontVersion > "1.5.1": self.errors = glyph.getRepresentation("de.kutilek.RedArrow.report") else: self.errors = getGlyphReport(font, glyph) scale = notification["scale"] size = 10 * scale width = 3 * scale errors_by_position = {} for e in self.errors: #if not e.kind == "Vector on closepath": # FIXME if e.position in errors_by_position: errors_by_position[e.position].extend([e]) else: errors_by_position[e.position] = [e] for pos, errors in errors_by_position.items(): message = "" for e in errors: if e.badness is None or not DEBUG: message += "%s, " % (e.kind) else: message += "%s (Severity %0.1f), " % (e.kind, e.badness) self._drawArrow(pos, message.strip(", "), size, width) if options.get("show_bbox"): if roboFontVersion >= "2.0b": box = glyph.bounds else: box = glyph.box if box is not None: save() fill(None) strokeWidth(0.5 * scale) stroke(1, 0, 0, 0.5) x, y, w, h = box rect(x, y, w - x, h - y) restore()
def _drawGlyphCellArrow(self, num_errors): x = 3 y = 3 width = 2 size = 7 save() translate(4, 4) fill(0.9, 0.4, 0.3, 1) rect(-1, -1, size+1, size+1) lineJoin("round") lineCap("butt") # butt, square, round strokeWidth(width) stroke(1, 1, 1) line(-width/2, 0, size, 0) line(0, -width/2, 0, size) line(width/2, width/2, size-0.5, size-0.5) restore()
def _drawSidebearings(self, glyphName): glyphToDisplay = self.fontObj[glyphName] dt.save() dt.stroke(*BLACK) dt.fill(None) # reversed scaling factor dt.strokeWidth( 1 / (self.ctrlHeight / (self.canvasScalingFactor * self.fontObj.info.unitsPerEm))) dt.fill(*LIGHT_GRAY) dt.line( (0, self.fontObj.info.descender), (0, self.fontObj.info.descender + self.fontObj.info.unitsPerEm)) dt.line((glyphToDisplay.width, self.fontObj.info.descender), (glyphToDisplay.width, self.fontObj.info.descender + self.fontObj.info.unitsPerEm)) dt.restore()
def __init__(self, glyphSet, angle, width, height, show_nib_faces=False, alpha=0.2, nib_superness=2.5, trace=False, round_coords=False): BasePen.__init__(self, glyphSet) self.angle = angle if self.angle > pi: self.angle -= pi elif self.angle < -pi: self.angle += pi # Store a transform, used for calculating extrema in some nib models self.transform = Transform().rotate(-self.angle) self.transform_reverse = Transform().rotate(self.angle) self.width = width self.height = height self.a = 0.5 * width self.b = 0.5 * height self.color = show_nib_faces self.highlight_nib_faces = False self.alpha = alpha self.nib_superness = nib_superness self.trace = trace self.round_coords = round_coords # Initialize the nib face path # This is only needed for more complex shapes self.setup_nib() self.path = [] self.__currentPoint = None if self.color: stroke(0, 0, 0, 0.5) strokeWidth(0.1)
def spaceCenterDraw(self, notification): glyph = notification["glyph"] spaceCenter = notification["spaceCenter"] scale = notification["scale"] attrValues = self.getAttributes() outGlyph = self.getGlyph(glyph, *attrValues) inverse = spaceCenter.glyphLineView.getDisplayStates()['Inverse'] foreground = tuple(getDefault('spaceCenterGlyphColor')) if not inverse else tuple(getDefault('spaceCenterBackgroundColor')) background = tuple(getDefault('spaceCenterBackgroundColor')) if not inverse else tuple(getDefault('spaceCenterGlyphColor')) # cover current glyph drawingTools.fill(*background) drawingTools.stroke(*background) drawingTools.strokeWidth(2*scale) drawingTools.drawGlyph(glyph) drawingTools.stroke(None) # draw glyph preview drawingTools.fill(*foreground) drawingTools.drawGlyph(outGlyph)
def drawBkgnd(self, info): # Draw the interpolated glyph outlines scale = info["scale"] ptSize = 7 * scale if self.interpolatedGlyph: # Draw the glyph outline pen = CocoaPen(None) self.interpolatedGlyph.draw(pen) dt.fill(r=None, g=None, b=None, a=1) dt.stroke(r=0, g=0, b=0, a=0.4) dt.strokeWidth(2 * scale) dt.save() dt.translate(self.currentGlyph.width) dt.drawPath(pen.path) dt.stroke(r=0, g=0, b=0, a=1) # Draw the points and handles for contour in self.interpolatedGlyph.contours: for bPoint in contour.bPoints: inLoc = self.addPoints(bPoint.anchor, bPoint.bcpIn) outLoc = self.addPoints(bPoint.anchor, bPoint.bcpOut) dt.line(inLoc, bPoint.anchor) dt.line(bPoint.anchor, outLoc) dt.fill(r=1, g=1, b=1, a=1) dt.oval(bPoint.anchor[0] - (ptSize * 0.5), bPoint.anchor[1] - (ptSize * 0.5), ptSize, ptSize) dt.fill(0) # Draw an "X" over each BCP if not bPoint.bcpIn == (0, 0): dt.oval(inLoc[0] - (ptSize * 0.5), inLoc[1] - (ptSize * 0.5), ptSize, ptSize) #dt.line((inLoc[0]-(ptSize*0.5), inLoc[1]-(ptSize*0.5)), (inLoc[0]+(ptSize*0.5), inLoc[1]+(ptSize*0.5))) #dt.line((inLoc[0]+(ptSize*0.5), inLoc[1]-(ptSize*0.5)), (inLoc[0]-(ptSize*0.5), inLoc[1]+(ptSize*0.5))) if not bPoint.bcpOut == (0, 0): dt.oval(outLoc[0] - (ptSize * 0.5), outLoc[1] - (ptSize * 0.5), ptSize, ptSize) #dt.line((outLoc[0]-(ptSize*0.5), outLoc[1]-(ptSize*0.5)), (outLoc[0]+(ptSize*0.5), outLoc[1]+(ptSize*0.5))) #dt.line((outLoc[0]+(ptSize*0.5), outLoc[1]-(ptSize*0.5)), (outLoc[0]-(ptSize*0.5), outLoc[1]+(ptSize*0.5))) dt.restore()
def _drawArrows(self, notification): glyph = notification["glyph"] if glyph is None: return font = glyph.getParent() if roboFontVersion > "1.5.1": self.errors = glyph.getRepresentation("de.kutilek.RedArrow.report") else: self.errors = getGlyphReport(font, glyph) scale = notification["scale"] size = 10 * scale width = 3 * scale errors_by_position = {} for e in self.errors: #if not e.kind == "Vector on closepath": # FIXME if e.position in errors_by_position: errors_by_position[e.position].extend([e]) else: errors_by_position[e.position] = [e] for pos, errors in errors_by_position.iteritems(): message = "" for e in errors: if e.badness is None or not DEBUG: message += "%s, " % (e.kind) else: message += "%s (Severity %0.1f), " % (e.kind, e.badness) self._drawArrow(pos, message.strip(", "), size, width) if options.get("show_bbox"): box = glyph.box if box is not None: save() fill(None) strokeWidth(0.5 * scale) stroke(1, 0, 0, 0.5) x, y, w, h = box rect(x, y, w-x, h-y) restore()
def _drawGrid(self): label_every = 1 if self.units > 24: label_every = 2 drawing.save() drawing.strokeWidth(0) drawing.stroke(None) drawing.fill(0.88, 0.92, 0.98) if self.system is not None: if self.system.min_units is not None: drawing.rect(0, 0, 10 + self.system.min_units * self.histogram_width / (self.units * self.ems_horizontal), self.histogram_height) if self.system.max_units is not None: drawing.rect(10 + self.system.max_units * self.histogram_width / (self.units * self.ems_horizontal), 0, self.histogram_width, self.histogram_height) drawing.strokeWidth(1.0) drawing.stroke(0.8, 0.8, 0.8) drawing.fill(0.6, 0.6, 0.6) for u in range(0, int(ceil(self.units * self.ems_horizontal))): x = 10 + u * self.histogram_width / (self.units * self.ems_horizontal) if u == self.units: # mark the full em drawing.stroke(0, 0, 0) drawing.line(x, 20, x, self.histogram_height-10) drawing.strokeWidth(0) drawing.text("1 em", x + 4, self.histogram_height - 21) drawing.strokeWidth(1.0) elif u % 10 == 0: # make every 10th line darker drawing.stroke(0.5, 0.5, 0.5) drawing.line(x, 20, x, self.histogram_height - 20) else: drawing.stroke(0.8, 0.8, 0.8) drawing.line(x, 20, x, self.histogram_height - 30) if u % label_every == 0: drawing.strokeWidth(0) drawing.text("%s" % (u), x - 3 * len(str(u)), 5) drawing.restore()
def draw_histogram(self, font, upm, color, show_glyphs=False, histogram=None): if histogram is None: if self.histogram is None: return histogram = self.histogram drawing.save() drawing.fill(1, 0.5, 0.2, 1.0) drawing.stroke(color[0], color[1], color[2], color[3]) for width in sorted(histogram.keys()): num = len(histogram[width]) x = 10 + width * self.histogram_width / (upm * self.ems_horizontal) drawing.save() if show_glyphs: drawing.save() drawing.fill(color[0], color[1], color[2], 0.2) drawing.fontsize(self.scale_vertical) for i in range(len(histogram[width])): glyph_name = histogram[width][i] if glyph_name in font: u = font[glyph_name].unicode if u: drawing.text("%s" % unichr(u), x + 4, 18 + i * self.scale_vertical) else: drawing.text("%s" % glyph_name, x + 4, 18 + i * self.scale_vertical) else: drawing.text("%s" % glyph_name, x + 4, 18 + i * self.scale_vertical) drawing.restore() drawing.strokewidth(2) else: drawing.strokewidth(6) # draw bars drawing.line(x, 20, x, 20 + num * self.scale_vertical) drawing.strokewidth(0) drawing.text("%s" % (num), x - 3 * len(str(num)), 22 + num * self.scale_vertical) drawing.restore() drawing.restore()