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 drawBackground(self, info): #print('Drawing' ,info['glyph']) if not self.updating: glyph = info['glyph'] self.w.mySlider.set(glyph.width) if self.w.doDraw.get(): fill(0, 0, 1, 0.5) rect(0, 0, glyph.width, 50)
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 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 _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 spaceCenterDraw(self, notification): glyph = notification["glyph"] attrValues = self.getAttributes() outGlyph = self.getGlyph(glyph, *attrValues) box = glyph.box if box: x, y, maxx, maxy = box w = maxx - x h = maxy - y drawingTools.fill(1) offset = 10 drawingTools.rect(x-offset, y-offset, w+offset*2, h+offset*2) drawingTools.fill(0) drawingTools.drawGlyph(outGlyph)
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 _drawCursor(self, correction, pairKind): assert pairKind in ('gr2gr', 'gr2gl', 'gl2gr', 'gl2gl') or pairKind is None dt.save() if pairKind is None: lftColor = NON_KERNED_COLOR rgtColor = NON_KERNED_COLOR elif pairKind == 'gr2gr': lftColor = GROUP_COLOR rgtColor = GROUP_COLOR elif pairKind == 'gr2gl': lftColor = GROUP_COLOR rgtColor = GLYPH_COLOR elif pairKind == 'gl2gr': lftColor = GLYPH_COLOR rgtColor = GROUP_COLOR else: lftColor = GLYPH_COLOR rgtColor = GLYPH_COLOR lftGlyphName, rgtGlyphName = self.activePair lftGlyph = self.fontObj[lftGlyphName] rgtGlyph = self.fontObj[rgtGlyphName] lftCursorWidth = lftGlyph.width / 2. + correction / 2. rgtCursorWidth = rgtGlyph.width / 2. + correction / 2. cursorHeight = 50 # upm # lft dt.fill(*lftColor) dt.rect(-lftGlyph.width / 2. - correction, self.fontObj.info.descender - cursorHeight + cursorHeight / 2., lftCursorWidth, cursorHeight) # rgt dt.fill(*rgtColor) dt.rect(-correction / 2., self.fontObj.info.descender - cursorHeight + cursorHeight / 2., rgtCursorWidth, cursorHeight) 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.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 _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 drawRect_(self, rect): # draw here! frame_width, frame_height = self.frame().size w, h = [i - 2 * self._inset for i in self.frame().size] drawBot.fill(None) drawBot.rect(self._inset, self._inset, w, h) drawBot.stroke(0) drawBot.strokeWidth(1) 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.fill(0.4, 1, 0.8) drawBot.rect( 0 - abs(self._kern_value) / 2, 0, abs(self._kern_value), h * 1 / 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, 1, 0) drawBot.fill(0) drawBot.drawPath(path) drawBot.translate(glyph.width + self._kern_value, 0)
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(self): if not self.RCJKI.get("currentFont"): return if not self.glyph: return # self.glyph = self.RCJKI.currentFont[self.glyphName] # glyph = self.glyph.preview.computeCharacterGlyphPreview(self.glyph, {"WGHT":1}) mjdt.save() scale = .15 mjdt.scale(scale, scale) mjdt.translate(((200 - (self.glyph.width * scale)) / scale) * .5, 450) # for g in self.glyph.preview({}, forceRefresh=False): locationKey = ','.join( [k + ':' + str(v) for k, v in self.glyph.getLocation().items()]) if locationKey in self.glyph.previewLocationsStore: for g in self.glyph.previewLocationsStore[locationKey]: # for g in self.glyph.preview({}, forceRefresh=False): mjdt.drawGlyph(g.glyph) mjdt.restore() # outlines, items, width = self.instantiateCharacterGlyph(self.glyph, {"WGHT":1}) # print(outlines, items, width) # self.glyph = self.RCJKI.currentFont[self.glyphName] # d = self.glyph._glyphVariations # if self.glyph.type == "atomicElement": # self.glyph.sourcesList = [ # {"Axis":axisName, "Layer":layer, "PreviewValue":layer.minValue} for axisName, layer in d.items() # ] # else: # self.glyph.sourcesList = [ # {"Axis":axisName, "Layer":layerName, "PreviewValue":layerName.minValue} for axisName, layerName in d.items() # ] if self.glyph.markColor is not None: mjdt.fill(*self.glyph.markColor) mjdt.rect(0, 0, 200, 20)
def _drawGlyphCellArrow(self, num_errors): x = 3 y = 3 width = 2 size = 7 save() translate(4, 4) stroke(0.2) strokeWidth(0.5) lineJoin("miter") fill(0.9, 0.4, 0.3) rect(-1, -1, size + 1, size + 1) lineCap("butt") # butt, square, round strokeWidth(width) stroke(1, 0.9, 0.65) line((0, width / 2 - 0.5), (size - width / 2 + 0.5, width / 2 - 0.5)) line((width / 2 - 0.5, width / 2 - 1.5), (width / 2 - 0.5, size - width / 2 + 0.5)) lineCap("round") line((width // 2, width // 2), (size - 1.5, size - 1.5)) restore()
def draw(self, scale): circleRadius = 12 * scale if self.selectionBounds: # The selection rect rect = (self.selectionBounds[0], self.selectionBounds[1], self.selectionBounds[2] - self.selectionBounds[0], self.selectionBounds[3] - self.selectionBounds[1]) dt.save() dt.font("Lucida Grande") dt.fontSize(11 * scale) # Circles around opoints dt.fill(None) dt.stroke(*self.selectionColor[0:3], 0.25) dt.strokeWidth(7 * scale) for point in self.glyph.selection: dt.oval(point.x - circleRadius, point.y - circleRadius, circleRadius * 2, circleRadius * 2) # Bounding box dt.strokeWidth(1 * scale) dt.stroke(*self.selectionColor) dt.rect(*rect) # Boxes on the handles for handle, handleLoc in self.selectionHandles.items(): dt.strokeWidth(2 * scale) dt.stroke(*self.selectionColor[0:3], 1) if handle == self.selectedHandle: dt.fill(*self.selectionColor[0:3], 1) boxRadius = 6 * scale else: dt.fill(None) boxRadius = 4 * scale # Draw the handle dt.rect(handleLoc[0] - boxRadius, handleLoc[1] - boxRadius, boxRadius * 2, boxRadius * 2) # Draw the handle delta text dt.stroke(None) dt.fill(*self.selectionColor[0:3], 1) if handle == "N": dt.textBox(str( int(self.selectionBounds[3] - self.cachedSelectionBounds[3])), (handleLoc[0] - (100 * scale), handleLoc[1], (200 * scale), (20 * scale)), align="center") if handle == "S": dt.textBox(str( int(self.selectionBounds[1] - self.cachedSelectionBounds[1])), (handleLoc[0] - (100 * scale), handleLoc[1] - (30 * scale), (200 * scale), (20 * scale)), align="center") if handle == "E": dt.textBox(str( int(self.selectionBounds[2] - self.cachedSelectionBounds[2])), (handleLoc[0] + (10 * scale), handleLoc[1] - (11 * scale), (200 * scale), (20 * scale)), align="left") if handle == "W": dt.textBox(str( int(self.selectionBounds[0] - self.cachedSelectionBounds[0])), (handleLoc[0] - (211 * scale), handleLoc[1] - (11 * scale), (200 * scale), (20 * scale)), align="right") # Draw the scale text dt.stroke(None) dt.fill(*self.selectionColor[0:3], 1) infoText = "Scale: %.3f %.3f" % self.currentScale dt.text(infoText, self.selectionBounds[2] + (10 * scale), self.selectionBounds[1] - (20 * scale)) dt.restore()
def draw(self): try: glyphsToDisplay = splitText(self.displayedWord, self.fontObj.naked().unicodeData) # if the user switches the glyphs from the groups #Â here we have to arrange the list of glyphnames properly if self.activePair is not None: lftName, rgtName = self.activePair glyphsToDisplay[self.indexPair] = lftName glyphsToDisplay[self.indexPair + 1] = rgtName # here we draw dt.save() # this is for safety reason, user should be notified about possible unwanted kerning corrections if self.isSwappedEditingOn is True: dt.save() dt.fill(*FLIPPED_BACKGROUND_COLOR) dt.rect(0, 0, self.ctrlWidth, self.ctrlHeight) dt.restore() if self.isSymmetricalEditingOn is True: dt.save() dt.fill(*SYMMETRICAL_BACKGROUND_COLOR) dt.rect(0, 0, self.ctrlWidth, self.ctrlHeight) dt.restore() dt.scale( self.ctrlHeight / (self.canvasScalingFactor * self.fontObj.info.unitsPerEm) ) # the canvas is virtually scaled according to self.canvasScalingFactor value and canvasSize dt.translate(TEXT_MARGIN, 0) # group glyphs dt.translate(0, 600) if self.areGroupsShown is True: dt.save() prevGlyphName = None for indexChar, eachGlyphName in enumerate(glyphsToDisplay): eachGlyph = self.fontObj[eachGlyphName] # this is for kerning if indexChar > 0: correction, kerningReference, pairKind = getCorrection( (prevGlyphName, eachGlyphName), self.fontObj) if kerningReference: exceptionStatus, doesExists, exceptionParents = isPairException( kerningReference, self.fontObj) if exceptionStatus is True: self._drawException( (prevGlyphName, eachGlyphName), correction) if (indexChar - 1) == self.indexPair: if correction is None: offsetCorrection = 0 else: offsetCorrection = correction self._drawGlyphOutlinesFromGroups( (prevGlyphName, eachGlyphName), kerningReference, offsetCorrection) if correction and correction != 0 and self.isKerningDisplayActive: dt.translate(correction, 0) dt.translate(eachGlyph.width, 0) prevGlyphName = eachGlyphName dt.restore() # background loop dt.save() glyphsToDisplayTotalWidth = 0 prevGlyphName = None for indexChar, eachGlyphName in enumerate(glyphsToDisplay): eachGlyph = self.fontObj[eachGlyphName] # this is for kerning if indexChar > 0: correction, kerningReference, pairKind = getCorrection( (prevGlyphName, eachGlyphName), self.fontObj) if self.isKerningDisplayActive and correction is not None: if correction != 0 and self.isColorsActive is True: self._drawColoredCorrection(correction) if self.isCorrectionActive is True: self._drawMetricsCorrection(correction) dt.translate(correction, 0) glyphsToDisplayTotalWidth += correction if (indexChar - 1) == self.indexPair: if correction is None: offsetCorrection = 0 else: offsetCorrection = correction self._drawCursor(offsetCorrection, pairKind) # # draw metrics info if self.isMetricsActive is True: self._drawMetricsData(eachGlyphName, 52) if self.isSidebearingsActive is True: self._drawBaseline(eachGlyphName) self._drawSidebearings(eachGlyphName) dt.translate(eachGlyph.width, 0) glyphsToDisplayTotalWidth += eachGlyph.width prevGlyphName = eachGlyphName dt.restore() # foreground loop dt.save() prevGlyphName = None for indexChar, eachGlyphName in enumerate(glyphsToDisplay): eachGlyph = self.fontObj[eachGlyphName] # this is for kerning if indexChar > 0: correction, kerningReference, pairKind = getCorrection( (prevGlyphName, eachGlyphName), self.fontObj) if correction and correction != 0 and self.isKerningDisplayActive: dt.translate(correction, 0) self._drawGlyphOutlines(eachGlyphName) dt.translate(eachGlyph.width, 0) prevGlyphName = eachGlyphName dt.restore() # collisions loop if self.areCollisionsShown is True: dt.save() prevGlyphName = None for indexChar, eachGlyphName in enumerate(glyphsToDisplay): eachGlyph = self.fontObj[eachGlyphName] if indexChar > 0: correction, kerningReference, pairKind = getCorrection( (prevGlyphName, eachGlyphName), self.fontObj) if correction and correction != 0 and self.isKerningDisplayActive: dt.translate(correction, 0) if (indexChar - 1) == self.indexPair: self._drawCollisions( (prevGlyphName, eachGlyphName)) dt.translate(eachGlyph.width, 0) prevGlyphName = eachGlyphName dt.restore() # main restore, it wraps the three loops dt.restore() if self.areVerticalLettersDrawn is True: # separate from the rest, we put the vertical letters dt.save() # we push the matrix forward dt.translate(self.ctrlWidth, 0) # then we rotate dt.rotate(90) # then we scale, but how much? a quarter of the main lettering dt.scale( self.ctrlHeight / (self.canvasScalingFactor * self.fontObj.info.unitsPerEm) * .25) # the reference is the baseline, so we have to put some air below the letters dt.translate(0, 600) # upm value # let's define the graphics dt.fill(*BLACK) dt.stroke(None) # then we draw, we need a prevGlyphName in order to get kerning correction prevGlyphName = None # we iterate on the letters we need to draw + a space as a margin for indexChar, eachGlyphName in enumerate(['space'] + glyphsToDisplay): # accessing the glyph obj eachGlyph = self.fontObj[eachGlyphName] # if it isn't the first letter... if indexChar > 0: # ... we grab the kerning correction from the pair correction, kerningReference, pairKind = getCorrection( (prevGlyphName, eachGlyphName), self.fontObj) # if there is any correction... if correction and correction != 0 and self.isKerningDisplayActive: # ... we apply it to the transformation matrix dt.translate(correction, 0) # then we draw the outlines self._drawGlyphOutlines(eachGlyphName) # and we move the transformation matrix according to glyph width dt.translate(eachGlyph.width, 0) # then we load the glyph to the prevGlyphName prevGlyphName = eachGlyphName # restoring the vertical drawing dt.restore() except Exception: print traceback.format_exc()