def drawOnGlyphCanvas(self, infoDict): glyphOnCanvas = infoDict['glyph'] scalingFactor = infoDict['scale'] bodySize = .25 horizontalOffset = 80 if PLUGIN_LIB_NAME in glyphOnCanvas.lib: thisLib = glyphOnCanvas.lib[PLUGIN_LIB_NAME] else: return None lftGlyph = None if thisLib['lft'] != '': lftGlyph = self.selectedFont[thisLib['lft']] rgtGlyph = None if thisLib['rgt'] != '': rgtGlyph = self.selectedFont[thisLib['rgt']] try: dt.fill(*GRAY) if lftGlyph is not None: dt.save() dt.translate(-lftGlyph.width * bodySize - horizontalOffset, -self.selectedFont.info.unitsPerEm * bodySize) # glyph dt.scale(bodySize) dt.drawGlyph(lftGlyph) # lock if thisLib['lftActive'] is True: txt = u'🔒' else: txt = u'🔓' dt.fontSize(300) txtWdt, txtHgt = dt.textSize(txt) dt.text(txt, (-txtWdt, 0)) dt.restore() if rgtGlyph is not None: dt.save() dt.translate(glyphOnCanvas.width + horizontalOffset, -self.selectedFont.info.unitsPerEm * bodySize) dt.scale(bodySize) dt.drawGlyph(rgtGlyph) # lock if thisLib['rgtActive'] is True: txt = u'🔒' else: txt = u'🔓' dt.fontSize(300) dt.text(txt, (rgtGlyph.width, 0)) dt.restore() except Exception as error: print(error)
def drawPoints(self, glyph, scale): save() _onCurveSize = self._onCurvePointsSize * scale _offCurveSize = self._offCurvePointsSize * scale _strokeWidth = self._strokeWidth * scale self._pointsColor.set() path = NSBezierPath.bezierPath() offCurveHandlesPath = NSBezierPath.bezierPath() pointsData = glyph.getRepresentation("doodle.OutlineInformation") for point1, point2 in pointsData["bezierHandles"]: offCurveHandlesPath.moveToPoint_(point1) offCurveHandlesPath.lineToPoint_(point2) for point in pointsData.get("offCurvePoints"): (x, y) = point["point"] path.appendBezierPathWithOvalInRect_(NSMakeRect(x - _offCurveSize, y - _offCurveSize, _offCurveSize * 2, _offCurveSize * 2)) for point in pointsData.get("onCurvePoints"): (x, y) = point["point"] path.appendBezierPathWithRect_(NSMakeRect(x - _onCurveSize, y - _onCurveSize, _onCurveSize * 2, _onCurveSize * 2)) path.fill() offCurveHandlesPath.setLineWidth_(_strokeWidth) strokePixelPath(offCurveHandlesPath) restore()
def _drawNeighborsGlyphs(self, glyph, stroke=True, scale=1): if glyph is None: return font = glyph.font baseName = self.getBaseGlyph(glyph.name) left, right = RamsayStData.get(baseName, ("n", "n")) if left in font: leftGlyph = font[left] save() # translate back the width of the glyph translate(-leftGlyph.width, 0) # performance tricks, the naked attr will return the defcon object # and get the cached bezier path to draw path = leftGlyph.naked().getRepresentation("defconAppKit.NSBezierPath") # fill the path path.fill() if stroke: path.setLineWidth_(scale) strokePixelPath(path) restore() # do the same for the other glyph if right in font: rightGlyph = font[right] save() # translate forward the width of the current glyph translate(glyph.width, 0) path = rightGlyph.naked().getRepresentation("defconAppKit.NSBezierPath") path.fill() if stroke: path.setLineWidth_(scale) strokePixelPath(path) restore()
def _drawLeftNeighborsGlyphs(self, glyph, stroke=True, scale=1): if glyph is None: return font = glyph.font left = self.view.unicodeLeftEditText.get() left = self.stringToGlyphs(left, font) save() for index, leftGlyph in enumerate(reversed(list(left))): if leftGlyph in font: leftGlyph = font[leftGlyph] # translate back the width of the glyph translate(-leftGlyph.width, 0) # performance tricks, the naked attr will return the defcon object # and get the cached bezier path to draw path = leftGlyph.naked().getRepresentation( "defconAppKit.NSBezierPath") # fill the path path.fill() if stroke: path.setLineWidth_(scale) strokePixelPath(path) restore()
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 _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 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 _drawNeighborsGlyphs(self, glyph, stroke=True, scale=1): if glyph is None: return font = glyph.getParent() baseName = self.getBaseGlyph(glyph.name) left, right = RamsayStData.get(baseName, ("n", "n")) if left in font: leftGlyph = font[left] save() # translate back the width of the glyph translate(-leftGlyph.width, 0) # performance tricks, the naked attr will return the defcon object # and get the cached bezier path to draw path = leftGlyph.naked().getRepresentation("defconAppKit.NSBezierPath") # fill the path path.fill() if stroke: path.setLineWidth_(scale) strokePixelPath(path) restore() # do the same for the other glyph if right in font: rightGlyph = font[right] save() # translate forward the width of the current glyph translate(glyph.width, 0) path = rightGlyph.naked().getRepresentation("defconAppKit.NSBezierPath") path.fill() if stroke: path.setLineWidth_(scale) strokePixelPath(path) restore()
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 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 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 _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 _drawRightNeighborsGlyphs(self, glyph, stroke=True, scale=1): if glyph is None: return font = glyph.font # left = self.view.unicodeLeftEditText.get() right = self.view.unicodeRightEditText.get() # right = self.rightInput right = self.stringToGlyphs(right, font) save() for index, rightGlyph in enumerate(list(right)): if rightGlyph in font: rightGlyph = font[rightGlyph] # translate back the width of the glyph if index == 0: translate(glyph.width, 0) else: translate(font[list(right)[index - 1]].width, 0) # performance tricks, the naked attr will return the defcon object # and get the cached bezier path to draw path = rightGlyph.naked().getRepresentation( "defconAppKit.NSBezierPath") # fill the path path.fill() if stroke: path.setLineWidth_(scale) strokePixelPath(path) restore()
def draw(self): # draw the color glyph on the canvas if self._font is not None: save() self.setFill(self.colorbg) rect(0, 0, 310, 200) self.setFill(self.color) scale(self.scale) translate(50.5, -self.metrics[0] + 20.5) self._canvas_draw_metrics() for i in range(len(self.layer_glyphs)): layerGlyph = self.layer_glyphs[i]["Layer Glyph"] if self._selected_color_index is None: op_factor = 1.0 else: if self._selected_color_index == self.layer_glyphs[i][ "layer_color_index"]: op_factor = 1.0 else: op_factor = 0.2 if layerGlyph in self.font: if i < len(self.layer_colors): _color = self.layer_colors[i] self.setFill(_color, op_factor) drawGlyph(self.font[layerGlyph]) restore()
def drawGlyph(self): if not self.previousGlyph == None: path = self.previousGlyph.naked().getRepresentation( "defconAppKit.NSBezierPath") dt.save() dt.translate(self.currentGlyph.width) path.fill() dt.restore()
def drawNeighbors(self, info): save() fillColor = NSColor.colorWithCalibratedRed_green_blue_alpha_( 0.0, 0.0, 0.0, 0.05) fillColor.set() self._drawLeftNeighborsGlyphs(info["glyph"], scale=info["scale"]) UpdateCurrentGlyphView() restore()
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 draw(self, char: str, scale: float = 1.0): save() for refFont in self.controller.settings: font(str(refFont), refFont.size) fill(*refFont.color) text(char, refFont.position) font(str(refFont), 20) text(str(refFont), (refFont.position[0], refFont.position[1]-10)) restore()
def drawDiffGlyph(self, info): g = info["glyph"] if g is not None: if g.name in self.headGlyphs: save() strokeWidth(None) fill(1,0,0,0.2) drawGlyph(self.headGlyphs[g.name]) 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 _drawColoredCorrection(self, correction): dt.save() if correction > 0: dt.fill(*LIGHT_GREEN) else: dt.fill(*LIGHT_RED) dt.rect(0, self.fontObj.info.descender, correction, self.fontObj.info.unitsPerEm) dt.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 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 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 _drawPoints(self, points): for point in points: x, y = point self.drawPath.append((x, y)) save() # 현재 상태 저장 translate(x, y) # x,y 만큼 평행이동 rotate(self.angle) # 각도 만큼 회전 translate(-self.width / 2, -self.height / 2) #설정한 높낮이 만큼 평행이동 self.shape(0, 0, self.width, self.height) #이동한 위치에서 설정한 모양대로 그림 그리기 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 _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 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 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 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 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 draw(self): # canvas draw callback drawing.save() self._drawGrid() drawing.restore() font = CurrentFont() if self.show_fixed and self.system is not None and self.system.fixed_units: # display the fixed widths of the current unitization system self.draw_histogram(font, self.system.upm, (0, 0, 1, 0.5), True, histogram=self.system.fixed_units) # draw the histogram for the current font print "__font:", font print "__font.info:", font.info self.draw_histogram(font, font.info.unitsPerEm, (1, 0, 0, 1), True)
def drawLock(closed, startingX, glyphQuota, scalingFactor): dt.save() dt.fill(*BLACK) dt.translate(startingX, 0) dt.scale(scalingFactor, scalingFactor) dt.translate(0, glyphQuota) dt.fontSize(300) if closed is True: txt = u'🔒' else: txt = u'🔓' txtWdt, txtHgt = dt.textSize(txt) dt.text(txt, (-txtWdt / 2, 0)) dt.restore()
def _drawGlyphOutline(self, glyph, scalingFactor, offset_X=0): dt.save() dt.translate(offset_X, 0) dt.fill(None) dt.strokeWidth(1 * scalingFactor) dt.stroke(*LIGHT_GRAY_COLOR) dt.drawGlyph(glyph) scaledRadius = BCP_RADIUS * scalingFactor for eachContour in glyph: for eachBPT in eachContour.bPoints: dt.stroke(None) dt.fill(*LIGHT_GRAY_COLOR) dt.rect(eachBPT.anchor[0] - scaledRadius / 2., eachBPT.anchor[1] - scaledRadius / 2., scaledRadius, scaledRadius) if eachBPT.bcpIn != (0, 0): dt.stroke(None) dt.fill(*LIGHT_GRAY_COLOR) dt.oval( eachBPT.anchor[0] + eachBPT.bcpIn[0] - scaledRadius / 2., eachBPT.anchor[1] + eachBPT.bcpIn[1] - scaledRadius / 2., scaledRadius, scaledRadius) dt.stroke(*LIGHT_GRAY_COLOR) dt.fill(None) dt.line((eachBPT.anchor[0], eachBPT.anchor[1]), (eachBPT.anchor[0] + eachBPT.bcpIn[0], eachBPT.anchor[1] + eachBPT.bcpIn[1])) if eachBPT.bcpOut != (0, 0): dt.stroke(None) dt.fill(*LIGHT_GRAY_COLOR) dt.oval( eachBPT.anchor[0] + eachBPT.bcpOut[0] - scaledRadius / 2., eachBPT.anchor[1] + eachBPT.bcpOut[1] - scaledRadius / 2., scaledRadius, scaledRadius) dt.stroke(*LIGHT_GRAY_COLOR) dt.fill(None) dt.line((eachBPT.anchor[0], eachBPT.anchor[1]), (eachBPT.anchor[0] + eachBPT.bcpOut[0], eachBPT.anchor[1] + eachBPT.bcpOut[1])) 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 _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._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 _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 _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 _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()
def draw(self, info): if not self._drawing: return glyph = info.get("glyph") drawingScale = info.get('scale') if glyph is None: return current = glyph.getParent() fonts = self.getActiveFonts() for font in fonts: nakedFont = font.naked() contextLeft, contextCurrent, contextRight = self.getContexts() contextLeft = splitText(contextLeft or '', nakedFont.unicodeData or '') contextLeft = [font[gname] for gname in contextLeft if gname in font.keys()] contextRight = splitText(contextRight or '', nakedFont.unicodeData or '') contextRight = [font[gname] for gname in contextRight if gname in font.keys()] contextCurrent = splitText(contextCurrent or '', nakedFont.unicodeData or '') if len(contextCurrent) > 0: contextCurrent = [font[gname] for gname in [contextCurrent[0]] if gname in font.keys()] if len(contextCurrent) > 0: sourceGlyph = contextCurrent[0] else: sourceGlyph = None elif glyph.name in font.keys(): sourceGlyph = font[glyph.name] contextCurrent = [sourceGlyph] else: sourceGlyph = None contextCurrent = [] save() self._fillColor.setFill() self._strokeColor.setStroke() scale(current.info.unitsPerEm/float(font.info.unitsPerEm)) # Draw left context previousGlyph = sourceGlyph contextLeft.reverse() totalWidth = 0 for i, cbGlyph in enumerate(contextLeft): kernValue = self.getKernValue(nakedFont, cbGlyph, previousGlyph) # right to left translate(-cbGlyph.width-kernValue, 0) totalWidth += cbGlyph.width + kernValue glyphBezierPath = cbGlyph.naked().getRepresentation("defconAppKit.NSBezierPath") if self._fill: glyphBezierPath.fill() if self._stroke: glyphBezierPath.setLineWidth_(self._strokeWidth*drawingScale) strokePixelPath(glyphBezierPath) previousGlyph = cbGlyph translate(totalWidth, 0) # Draw current context or current glyph if contextCurrent: previousGlyph = None alignment = self.getAlignment() if alignment == 'left': offset = 0 elif alignment == 'center': offset = (glyph.width - contextCurrent[0].width)/2 elif alignment == 'right': offset = glyph.width - contextCurrent[0].width totalWidth = offset translate(totalWidth, 0) for i, cbGlyph in enumerate(contextCurrent): #if cbGlyph == glyph: # continue # Don't show if is current glyph kernValue = self.getKernValue(nakedFont, previousGlyph, cbGlyph) translate(kernValue, 0) glyphBezierPath = cbGlyph.naked().getRepresentation("defconAppKit.NSBezierPath") if self._fill: glyphBezierPath.fill() if self._stroke: glyphBezierPath.setLineWidth_(self._strokeWidth*drawingScale) strokePixelPath(glyphBezierPath) if self._points: self.drawPoints(cbGlyph, info['scale']) translate(cbGlyph.width, 0) totalWidth += cbGlyph.width + kernValue previousGlyph = cbGlyph translate(-totalWidth, 0) # Draw right context translate(glyph.width) totalWidth = glyph.width for i, cbGlyph in enumerate(contextRight): kernValue = self.getKernValue(nakedFont, previousGlyph, cbGlyph) translate(kernValue, 0) glyphBezierPath = cbGlyph.naked().getRepresentation("defconAppKit.NSBezierPath") if self._fill: glyphBezierPath.fill() if self._stroke: glyphBezierPath.setLineWidth_(self._strokeWidth*drawingScale) strokePixelPath(glyphBezierPath) translate(cbGlyph.width, 0) totalWidth += cbGlyph.width + kernValue previousGlyph = cbGlyph restore()