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 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 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 drawObserver(self, notification): glyph = notification['glyph'] scale = notification['scale'] lockStatus = self.getLockStatus(glyph) if not lockStatus: # is None: return lockStatusIcon = '🔒' if lockStatus else '🔓' ctx.save() ctx.fontSize(24 * scale) ctx.textBox(lockStatusIcon, (0, -100, glyph.width, 24 * scale), align='right') ctx.restore()
def spaceCenterDrawObserver(self, notification): glyph = notification['glyph'] scale = notification['scale'] lockStatus = self.getLockStatus(glyph) if not lockStatus: # is None: return lockStatusIcon = '🔒' if lockStatus else '🔓' # 'L' if lockStatus else 'U' ctx.save() ctx.scale(1, -1) ctx.fontSize(120) ctx.text(lockStatusIcon, (glyph.width - 100, 30)) ctx.restore()
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 _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 drawCellObserver(self, notification): # print(notification.keys()) # print(notification["glyphCell"]) # print(notification["cell"]) glyph = notification["glyph"] if self.w.mode.get() == 0: return lockStatus = self.getLockStatus(glyph) if not lockStatus: # is None: return lockStatusIcon = '🔒' if lockStatus else '🔓' ctx.save() ctx.fontSize(16) ctx.text(lockStatusIcon, (0, 0)) ctx.restore()
def draw(self): try: dt.save() dt.font(SYSTEM_FONT_NAME) dt.fontSize(CAPTION_BODY_SIZE) for indexGlyphName, eachGlyphName in enumerate( self.glyphNamesToDisplay): # in this way it does not draw what's outside the canvas frame! if SPACING_COL_WIDTH * indexGlyphName > self.getPosSize()[2]: continue self._drawMatrixColumn(eachGlyphName) dt.translate(SPACING_COL_WIDTH, 0) self._setBoxQualities() dt.line((0, 0), (0, self.getPosSize()[3])) dt.restore() except Exception, error: print traceback.format_exc()
def _drawCollisions(self, aPair): dt.save() correction, kerningReference, pairKind = getCorrection( aPair, self.fontObj) if kerningReference is None: lftName, rgtName = aPair else: lftName, rgtName = kerningReference lftGlyphs = [] if lftName.startswith('@MMK') is True: lftGlyphs = self.fontObj.groups[lftName] else: lftGlyphs = [lftName] rgtGlyphs = [] if rgtName.startswith('@MMK') is True: rgtGlyphs = self.fontObj.groups[rgtName] else: rgtGlyphs = [rgtName] dt.fontSize(COLLISION_BODY_SIZE) breakCycle = False for eachLftName in lftGlyphs: for eachRgtName in rgtGlyphs: isTouching = checkIfPairOverlaps(self.fontObj[eachLftName], self.fontObj[eachRgtName]) if isTouching: dt.text(u'💥', (0, 0)) breakCycle = True break if breakCycle is True: break dt.restore()
def _drawMetricsData(self, glyphName, offset): dt.save() glyphToDisplay = self.fontObj[glyphName] dt.translate(0, self.fontObj.info.descender) reverseScalingFactor = 1 / ( self.ctrlHeight / (self.canvasScalingFactor * self.fontObj.info.unitsPerEm)) if self.isSidebearingsActive is True: dt.fill(None) dt.stroke(*BLACK) dt.strokeWidth(reverseScalingFactor) dt.line((0, 0), (0, -offset * reverseScalingFactor)) dt.line((glyphToDisplay.width, 0), (glyphToDisplay.width, -offset * reverseScalingFactor)) dt.restore() dt.save() dt.translate(0, self.fontObj.info.descender) dt.translate(0, -offset * reverseScalingFactor) dt.fill(*BLACK) dt.stroke(None) dt.font(SYSTEM_FONT_NAME) dt.fontSize(BODY_SIZE * reverseScalingFactor) textWidth, textHeight = dt.textSize(u'{}'.format(glyphToDisplay.width)) dt.textBox(u'{:d}'.format(int(glyphToDisplay.width)), (0, 0, glyphToDisplay.width, textHeight * 2), align='center') dt.textBox(u'\n{:d}'.format(int(glyphToDisplay.leftMargin)), (0, 0, glyphToDisplay.width / 2., textHeight * 2), align='center') dt.textBox(u'\n{:d}'.format(int(glyphToDisplay.rightMargin)), (glyphToDisplay.width / 2., 0, glyphToDisplay.width / 2., textHeight * 2), align='center') dt.restore()
def _setTypeQualities(self, color): dt.fill(*color) dt.stroke(None) dt.fontSize(CAPTION_BODY_SIZE) dt.font(SYSTEM_FONT_NAME)
def draw(self, scale): if not self._didCalculate: return cornerDot = bcpDot = tanDot = 4 if self.dragState == 'flats': tanDot = 10 elif self.dragState == "curves": bcpDot = 10 stackedbv = self._b1_v == self._b2_v stackedbh = self._b1_h == self._b2_h stackedtv = self._t1_v == self._t2_v stackedth = self._t1_h == self._t2_h self.dot((self._xMin, self._t1_v), s=tanDot, scale=scale, stacked=stackedtv) self.dot((self._xMax, self._t1_v), s=tanDot, scale=scale, stacked=stackedtv) self.dot((self._xMin, self._t2_v), s=tanDot, scale=scale, stacked=stackedtv) self.dot((self._xMax, self._t2_v), s=tanDot, scale=scale, stacked=stackedtv) self.dot((self._t1_h, self._yMin), s=tanDot, scale=scale, stacked=stackedth) self.dot((self._t1_h, self._yMax), s=tanDot, scale=scale, stacked=stackedth) self.dot((self._t2_h, self._yMin), s=tanDot, scale=scale, stacked=stackedth) self.dot((self._t2_h, self._yMax), s=tanDot, scale=scale, stacked=stackedth) self.dot((self._xMin, self._b1_v), s=bcpDot, scale=scale, stacked=stackedbv) self.dot((self._xMax, self._b1_v), s=bcpDot, scale=scale, stacked=stackedbv) self.dot((self._xMin, self._b2_v), s=bcpDot, scale=scale, stacked=stackedbv) self.dot((self._xMax, self._b2_v), s=bcpDot, scale=scale, stacked=stackedbv) self.dot((self._b1_h, self._yMax), s=bcpDot, scale=scale, stacked=stackedbh) self.dot((self._b2_h, self._yMax), s=bcpDot, scale=scale, stacked=stackedbh) self.dot((self._b1_h, self._yMin), s=bcpDot, scale=scale, stacked=stackedbh) self.dot((self._b2_h, self._yMin), s=bcpDot, scale=scale, stacked=stackedbh) ctx.save() ctx.stroke(1, 0, 0, .4) ctx.fill(0, 0, 0, 0.03) ctx.strokeWidth(.5 * scale) self.buildShapePath(scale) ctx.drawPath() center = .5 * (self._xMax + self._xMin), .5 * (self._yMax + self._yMin) self.dot(center, scale=scale) ctx.fontSize(10 * scale) ctx.fill(1, 0.5, 0) ctx.font("Menlo-Regular") ctx.stroke(None) t = "the symmetrical,\nround shape\ndrawing tool\npress command to move the flat\npress option to move the bcps\n\nwidth %3.3f\nheight %3.3f" % ( self._width, self._height) if self._orientation: t += "\nhorizontal" else: t += "\nvertical" if self.dragState == "flats": t += "\n\nyou're changing the flat factor\nx %3.3f\ny %3.3f" % ( self.flatFactor_x, self.flatFactor_y) elif self.dragState == "curves": t += "\n\nyou're changing the bcp factor\nx %3.3f\ny %3.3f" % ( self.bcpFactor_x, self.bcpFactor_y) ctx.text(t, center) ctx.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 drawAxisPreview(self, glyph, color, scale, customColor, view=False, flatComponentColor=(.8, .6, 0, .7), drawSelectedElements=True): mjdt.save() index = None # loc = {} # if glyph.selectedSourceAxis: # loc = {glyph.selectedSourceAxis:1} # for i, atomicInstance in enumerate(glyph.preview()): for i, atomicInstance in enumerate( glyph.preview(forceRefresh=False, axisPreview=True)): # for i, atomicInstance in enumerate(glyph.previewGlyph): transformIntance = atomicInstance._transformation atomicInstance = atomicInstance.glyph mjdt.fill(*color) if drawSelectedElements and i in glyph.selectedElement: mjdt.save() mjdt.stroke(1, 0, 0, 1) mjdt.strokeWidth(1 * scale) tx = transformIntance['x'] + transformIntance['tcenterx'] ty = transformIntance['y'] + transformIntance['tcentery'] mjdt.line((tx - 5 * scale, ty), (tx + 5 * scale, ty)) mjdt.line((tx, ty - 5 * scale), (tx, ty + 5 * scale)) mjdt.stroke(None) mjdt.fill(1, 0, 0, 1) mjdt.fontSize(8 * scale) mjdt.textBox( f"{int(transformIntance['tcenterx'])} {int(transformIntance['tcentery'])}", ((tx - 30 * scale, ty - 30 * scale, 60 * scale, 20 * scale)), align="center") mjdt.restore() mjdt.fill(0, .8, .8, .5) # for c in atomicInstance: # if c.clockwise: # mjdt.stroke(1, 0, 0, 1) # mjdt.strokeWidth(2*scale) mjdt.save() # mjdt.drawGlyph(atomicInstance.getTransformedGlyph(round = self.RCJKI.roundToGrid)) mjdt.drawGlyph(atomicInstance) mjdt.restore() if customColor is None and view: if i != index: self.drawIndexOfElements(i, atomicInstance, view) if glyph.type == "characterGlyph": response = self.RCJKI.currentFont.mysqlGlyphData.get( glyph.name, False) try: if response: for dc in response["made_of"]: if dc["name"] != glyph._deepComponents[ i].name: continue char = getChar(dc["name"]) if not char: continue txt = "%s/%s\nused at %s%s" % ( len(dc["used_by"]), len(self.RCJKI.currentFont. deepComponents2Chars[char]), round( (len(dc["used_by"]) / len(self.RCJKI.currentFont. deepComponents2Chars[char])) * 100), "%") x, y = atomicInstance[0].points[ 0].x, atomicInstance[0].points[0].y mjdt.fill(1, 0, 1, 1) mjdt.fontSize(10 * scale) mjdt.text(txt, (x, y - 30 * scale)) except Exception as e: pass index = i if customColor is None: mjdt.fill(customColor) else: mjdt.fill(*customColor) mjdt.drawGlyph(glyph) mjdt.restore() for c in glyph.flatComponents: if self.RCJKI.currentFont[c.baseGlyph].type == "atomicElement": mjdt.drawGlyph( self.roundGlyph(self.RCJKI.currentFont[c.baseGlyph])) else: # self.RCJKI.currentFont[c.baseGlyph].preview.computeDeepComponents(update = False) self.drawAxisPreview(self.RCJKI.currentFont[c.baseGlyph], flatComponentColor, scale, customColor, view)
def draw(self): w = self.w.c.width() h = self.w.c.height() m = 130 center = w * .5, h * .5 d = self.dotSize r = min(.5 * (h - 2 * m), .5 * (w - 2 * m)) if self.pointer is None: self.pointer = center a1 = self.orientation * math.pi a2 = a1 + 2 / 3 * math.pi a3 = a1 - 2 / 3 * math.pi self.p1 = p1 = center[0] + (r * math.sin(a1)), center[1] + ( r * math.cos(a1)) self.p2 = p2 = center[0] + (r * math.sin(a2)), center[1] + ( r * math.cos(a2)) self.p3 = p3 = center[0] + (r * math.sin(a3)), center[1] + ( r * math.cos(a3)) self.snapped = None if self.closeToPoint(self.p1, self.pointer): self.pointer = self.p1 self.snapped = 0 if self.closeToPoint(self.p2, self.pointer): self.pointer = self.p2 self.snapped = 1 if self.closeToPoint(self.p3, self.pointer): self.pointer = self.p3 self.snapped = 2 p1d = p1[0] - .5 * d, p1[1] - .5 * d, d, d p2d = p2[0] - .5 * d, p2[1] - .5 * d, d, d p3d = p3[0] - .5 * d, p3[1] - .5 * d, d, d ctx.save() ctx.stroke(.8, .8, .7) ctx.strokeWidth(.4) ctx.strokeWidth(.8) ctx.line(p1, p2) ctx.line(p2, p3) ctx.line(p3, p1) if self.pointer is not None: ctx.line(p1, self.pointer) ctx.line(p2, self.pointer) ctx.line(p3, self.pointer) ctx.stroke(None) ctx.fill(0) ctx.oval(*p1d) ctx.oval(*p2d) ctx.oval(*p3d) g1, g2, g3 = self.glyphs if g1 is not None: ctx.save() ctx.translate(p1[0], p1[1]) ctx.scale(self.glyphScale) ctx.translate(100, 0) ctx.drawGlyph(g1) ctx.restore() if g2 is not None: ctx.save() ctx.translate(p2[0], p2[1]) ctx.scale(self.glyphScale) ctx.translate(100, 0) ctx.drawGlyph(g2) ctx.restore() if g3 is not None: ctx.save() ctx.translate(p3[0], p3[1]) ctx.scale(self.glyphScale) ctx.translate(100, 0) ctx.drawGlyph(g3) ctx.restore() if self.pointer: ctx.save() ctx.fill(1, 0, 0) ctx.stroke(None) d = 10 ctx.oval(self.pointer[0] - .5 * d, self.pointer[1] - .5 * d, d, d) f1, f2, f3 = ip(p1, p2, p3, self.pointer) self._factors = f1, f2, f3 r = None if self.mGlyphs is not None: if None not in self.mGlyphs: try: self.result = r = f1 * self.mGlyphs[ 0] + f2 * self.mGlyphs[1] + f3 * self.mGlyphs[2] except IndexError or TypeError: print("Sorry, these glyphs can't interpolate..") if r: ctx.save() ctx.translate(self.pointer[0], self.pointer[1]) ctx.scale(self.glyphScale) ctx.translate(100, 0) g = RGlyph() g.fromMathGlyph(r) ctx.drawGlyph(g) t = "{:02.2f}, {:02.2f}, {:02.2f}".format(f1, f2, f3) ctx.font("Menlo-Regular") ctx.fontSize(6 / self.glyphScale) ctx.text(t, (0, -200)) ctx.restore() ctx.restore() ctx.restore()
def _drawGlyphOutlinesFromGroups(self, aPair, kerningReference, correction): prevGlyphName, eachGlyphName = aPair if kerningReference is not None: lftReference, rgtReference = kerningReference else: lftReference = whichGroup(prevGlyphName, 'left', self.fontObj) rgtReference = whichGroup(eachGlyphName, 'right', self.fontObj) prevGlyph, eachGlyph = self.fontObj[prevGlyphName], self.fontObj[ eachGlyphName] reverseScalingFactor = 1 / ( self.ctrlHeight / (self.canvasScalingFactor * self.fontObj.info.unitsPerEm)) # _L__ group if lftReference: if lftReference.startswith('@MMK_L_'): dt.save() dt.fill(*LAYERED_GLYPHS_COLOR) groupContent = self.fontObj.groups[lftReference] if len(groupContent) > 1: for eachGroupSibling in groupContent: if eachGroupSibling != prevGlyphName: glyphToDisplay = self.fontObj[eachGroupSibling] dt.save() dt.translate( -glyphToDisplay.width, 0 ) # back, according to his width, otherwise it does not coincide dt.drawGlyph(glyphToDisplay) dt.restore() dt.fill(*BLACK) # caption dt.translate(-prevGlyph.width, 0) # we need a caption in the right place dt.font(SYSTEM_FONT_NAME) dt.fontSize(GROUP_NAME_BODY_SIZE * reverseScalingFactor) textWidth, textHeight = dt.textSize(lftReference) dt.text(lftReference, (glyphToDisplay.width / 2. - textWidth / 2., -GROUP_NAME_BODY_SIZE * reverseScalingFactor * 2)) dt.restore() # _R__ group if rgtReference: if rgtReference.startswith('@MMK_R_'): dt.save() dt.translate(correction, 0) dt.fill(*LAYERED_GLYPHS_COLOR) groupContent = self.fontObj.groups[rgtReference] if len(groupContent) > 1: for eachGroupSibling in groupContent: if eachGroupSibling != eachGlyphName: glyphToDisplay = self.fontObj[eachGroupSibling] dt.drawGlyph(glyphToDisplay) dt.fill(*BLACK) dt.font(SYSTEM_FONT_NAME) dt.fontSize(GROUP_NAME_BODY_SIZE * reverseScalingFactor) textWidth, textHeight = dt.textSize(rgtReference) dt.text(rgtReference, (glyphToDisplay.width / 2. - textWidth / 2., -GROUP_NAME_BODY_SIZE * reverseScalingFactor * 2)) dt.restore()