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 _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 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 _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 _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 _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 _drawMatrixColumn(self, glyphName): dt.save() # definitive dt.translate( 0, self.getPosSize()[3] - vanillaControlsSize['EditTextSmallHeight']) # top dt.fill(*BLACK) dt.stroke(None) textWidth, textHeight = dt.textSize(glyphName) self._setTypeQualities(BLACK) dt.text(glyphName, (SPACING_COL_WIDTH / 2. - textWidth / 2., BASELINE_CORRECTION)) dt.translate(0, -vanillaControlsSize['EditTextSmallHeight']) # metrics for eachFont in self.fontsOrder: try: eachGlyph = eachFont[glyphName] except Exception, error: continue if eachGlyph == self.lineViewSelectedGlyph: color = RED else: color = BLACK # line over glyph width self._setBoxQualities() dt.line((0, vanillaControlsSize['EditTextSmallHeight']), (SPACING_COL_WIDTH, vanillaControlsSize['EditTextSmallHeight'])) widthString = '{:d}'.format(int(round(eachGlyph.width, 0))) textWidth, textHeight = dt.textSize(widthString) self._setTypeQualities(color) dt.text( widthString, (SPACING_COL_WIDTH / 2. - textWidth / 2., BASELINE_CORRECTION)) # line over sidebearings self._setBoxQualities() dt.line((0, 0), (SPACING_COL_WIDTH, 0)) dt.translate(0, -vanillaControlsSize['EditTextSmallHeight']) leftMarginString = '{:d}'.format( int(round(eachGlyph.leftMargin, 0))) textWidth, textHeight = dt.textSize(leftMarginString) self._setTypeQualities(color) dt.text( leftMarginString, (SPACING_COL_WIDTH / 4. - textWidth / 2., BASELINE_CORRECTION)) self._setBoxQualities() dt.line((SPACING_COL_WIDTH / 2., 0), (SPACING_COL_WIDTH / 2., vanillaControlsSize['EditTextSmallHeight'])) rightMarginString = '{:d}'.format( int(round(eachGlyph.rightMargin, 0))) textWidth, textHeight = dt.textSize(rightMarginString) self._setTypeQualities(color) dt.text(rightMarginString, (SPACING_COL_WIDTH * 3 / 4. - textWidth / 2., BASELINE_CORRECTION)) dt.translate(0, -vanillaControlsSize['EditTextSmallHeight'])
def _drawSquarings(self, glyph, scalingFactor, offset_X=0): for eachContour in glyph: for indexBPT, eachBPT in enumerate(eachContour.bPoints): if eachBPT.bcpOut != (0, 0): nextBPT = eachContour.bPoints[(indexBPT + 1) % len(eachContour.bPoints)] absBcpOut = (eachBPT.anchor[0] + eachBPT.bcpOut[0], eachBPT.anchor[1] + eachBPT.bcpOut[1]) angleOut = calcAngle(eachBPT.anchor, absBcpOut) handleOutLen = calcDistance(eachBPT.anchor, absBcpOut) absBcpIn = (nextBPT.anchor[0] + nextBPT.bcpIn[0], nextBPT.anchor[1] + nextBPT.bcpIn[1]) angleIn = calcAngle(nextBPT.anchor, absBcpIn) nextHandleInLen = calcDistance(nextBPT.anchor, absBcpIn) handlesIntersection = intersectionBetweenSegments( eachBPT.anchor, absBcpOut, absBcpIn, nextBPT.anchor) if handlesIntersection is not None: maxOutLen = calcDistance(eachBPT.anchor, handlesIntersection) maxInLen = calcDistance(nextBPT.anchor, handlesIntersection) sqrOut = handleOutLen / maxOutLen sqrIn = nextHandleInLen / maxInLen projOut_X = eachBPT.anchor[0] + cos( radians(angleOut)) * handleOutLen projOut_Y = eachBPT.anchor[1] + sin( radians(angleOut)) * handleOutLen if angleOut != 0 and angleOut % 90 != 0: captionSqrOut = u'{:.0%}, {:d}°'.format( sqrOut, int(angleOut % 180)) else: captionSqrOut = '{:.0%}'.format(sqrOut) captionSqrOut = captionSqrOut.replace('0.', '') dt.save() dt.translate(projOut_X + offset_X, projOut_Y) textQualities(BODYSIZE_CAPTION * scalingFactor) textWidth, textHeight = dt.textSize(captionSqrOut) if angleOut == 90: # text above textRect = (-textWidth / 2., SQR_CAPTION_OFFSET * scalingFactor, textWidth, textHeight) elif angleOut == -90: # text below textRect = (-textWidth / 2., -textHeight - SQR_CAPTION_OFFSET * scalingFactor, textWidth, textHeight) elif -90 < angleOut < 90: # text on the right textRect = (SQR_CAPTION_OFFSET * scalingFactor, -textHeight / 2., textWidth, textHeight) else: # text on the left textRect = (-textWidth - SQR_CAPTION_OFFSET * scalingFactor, -textHeight / 2., textWidth, textHeight) dt.textBox(captionSqrOut, textRect, align='center') dt.restore() projIn_X = nextBPT.anchor[0] + cos( radians(angleIn)) * nextHandleInLen projIn_Y = nextBPT.anchor[1] + sin( radians(angleIn)) * nextHandleInLen if angleIn != 0 and angleIn % 90 != 0: captionSqrIn = u'{:.0%}, {:d}°'.format( sqrIn, int(angleIn % 180)) else: captionSqrIn = '{:.0%}'.format(sqrIn) captionSqrIn = captionSqrIn.replace('0.', '') dt.save() dt.translate(projIn_X + offset_X, projIn_Y) textQualities(BODYSIZE_CAPTION * scalingFactor) textWidth, textHeight = dt.textSize(captionSqrIn) if angleIn == 90: # text above textRect = (-textWidth / 2., SQR_CAPTION_OFFSET * scalingFactor, textWidth, textHeight) elif angleIn == -90: # text below textRect = (-textWidth / 2., -textHeight - SQR_CAPTION_OFFSET * scalingFactor, textWidth, textHeight) elif -90 < angleIn < 90: # text on the right textRect = (SQR_CAPTION_OFFSET * scalingFactor, -textHeight / 2., textWidth, textHeight) else: # text on the left textRect = (-textWidth - SQR_CAPTION_OFFSET * scalingFactor, -textHeight / 2., textWidth, textHeight) dt.textBox(captionSqrIn, textRect, align='center') dt.restore()
def _drawBcpLenght(self, glyph, scalingFactor, offset_X=0): for eachContour in glyph: for indexBPT, eachBPT in enumerate(eachContour.bPoints): if eachBPT.bcpOut != (0, 0): absBcpOut = eachBPT.anchor[0] + eachBPT.bcpOut[ 0], eachBPT.anchor[1] + eachBPT.bcpOut[1] bcpOutAngle = calcAngle(eachBPT.anchor, absBcpOut) bcpOutLenght = calcDistance(eachBPT.anchor, absBcpOut) captionBcpOut = u'→{:d}'.format(int(bcpOutLenght)) projOut_X = eachBPT.anchor[0] + cos( radians(bcpOutAngle)) * bcpOutLenght / 2. projOut_Y = eachBPT.anchor[1] + sin( radians(bcpOutAngle)) * bcpOutLenght / 2. textQualities(BODYSIZE_CAPTION * scalingFactor, weight='bold') textWidth, textHeight = dt.textSize(captionBcpOut) dt.save() dt.translate(projOut_X + offset_X, projOut_Y) dt.rotate(bcpOutAngle % 90) belowRect = (-textWidth / 2. - 1, -textHeight / 2. - 1, textWidth + 2, textHeight + 2, 1) dt.fill(0, 0, 0, .7) dt.roundedRect(*belowRect) textRect = (-textWidth / 2., -textHeight / 2., textWidth, textHeight) textQualities(BODYSIZE_CAPTION * scalingFactor, weight='bold', color=WHITE_COLOR) dt.textBox(captionBcpOut, textRect, align='center') dt.restore() if eachBPT.bcpIn != (0, 0): absBcpIn = eachBPT.anchor[0] + eachBPT.bcpIn[ 0], eachBPT.anchor[1] + eachBPT.bcpIn[1] bcpInAngle = calcAngle(eachBPT.anchor, absBcpIn) bcpInLenght = calcDistance(eachBPT.anchor, absBcpIn) captionBcpIn = u'→{:d}'.format(int(bcpInLenght)) projIn_X = eachBPT.anchor[0] + cos( radians(bcpInAngle)) * bcpInLenght / 2. projIn_Y = eachBPT.anchor[1] + sin( radians(bcpInAngle)) * bcpInLenght / 2. textQualities(BODYSIZE_CAPTION * scalingFactor, weight='bold') textWidth, textHeight = dt.textSize(captionBcpIn) dt.save() dt.translate(projIn_X + offset_X, projIn_Y) dt.rotate(bcpInAngle % 90) belowRect = (-textWidth / 2. - 1, -textHeight / 2. - 1, textWidth + 2, textHeight + 2, 1) dt.fill(0, 0, 0, .7) dt.roundedRect(*belowRect) textQualities(BODYSIZE_CAPTION * scalingFactor, weight='bold', color=WHITE_COLOR) textRect = (-textWidth / 2., -textHeight / 2., textWidth, textHeight) dt.textBox(captionBcpIn, textRect, align='center') dt.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()