def setPairCorrection(self, amount, isRecording=True): if self.autoSave is True: self.checkAutoSave() selectedPair = self.getActiveWordDisplay().getActivePair() if self.isVerticalAlignedEditingOn is True: selectedFonts = self.fontsOrder else: selectedFonts = [self.fontsOrder[self.navCursor_Y]] for eachFont in selectedFonts: if isRecording is True: previousAmount = getCorrection(selectedPair, eachFont)[0] self.appendRecord('setCorrection', (selectedPair, eachFont, previousAmount)) setCorrection(selectedPair, eachFont, amount) self.kerningLogger.info( SET_CORRECTION_LOG.format(leftGlyphName=selectedPair[0], rightGlyphName=selectedPair[1], familyName=eachFont.info.familyName, styleName=eachFont.info.styleName, amount=amount)) if self.isSwappedEditingOn is True: swappedCorrectionKey = selectedPair[1], selectedPair[0] if isRecording is True: previousAmount = getCorrection(swappedCorrectionKey, eachFont)[0] self.appendRecord( 'setCorrection', (swappedCorrectionKey, eachFont, previousAmount)) setCorrection(swappedCorrectionKey, eachFont, amount) self.kerningLogger.info( SET_CORRECTION_LOG.format( leftGlyphName=swappedCorrectionKey[0], rightGlyphName=swappedCorrectionKey[1], familyName=eachFont.info.familyName, styleName=eachFont.info.styleName, amount=amount)) if self.isSymmetricalEditingOn is True: symmetricalCorrectionKey = findSymmetricalPair(selectedPair) if symmetricalCorrectionKey: if isRecording is True: previousAmount = getCorrection( symmetricalCorrectionKey, eachFont)[0] self.appendRecord('setCorrection', (symmetricalCorrectionKey, eachFont, previousAmount)) setCorrection(symmetricalCorrectionKey, eachFont, amount) self.kerningLogger.info( SET_CORRECTION_LOG.format( leftGlyphName=symmetricalCorrectionKey[0], rightGlyphName=symmetricalCorrectionKey[1], familyName=eachFont.info.familyName, styleName=eachFont.info.styleName, amount=amount)) self.updateWordDisplays()
def deletePair(self, isRecording=True): if self.autoSave is True: self.checkAutoSave() selectedPair = self.getActiveWordDisplay().getActivePair() if self.isVerticalAlignedEditingOn is True: selectedFonts = self.fontsOrder else: selectedFonts = [self.fontsOrder[self.navCursor_Y]] for eachFont in selectedFonts: previousAmount, kerningReference, pairKind = getCorrection( selectedPair, eachFont) deletePair(kerningReference, eachFont) if isRecording is True: self.appendRecord('deletePair', (kerningReference, eachFont, previousAmount)) self.kerningLogger.info( DELETE_PAIR_LOG.format(leftGlyphName=selectedPair[0], rightGlyphName=selectedPair[1], familyName=eachFont.info.familyName, styleName=eachFont.info.styleName)) if self.isSwappedEditingOn is True: swappedCorrectionKey = selectedPair[1], selectedPair[0] previousAmount, kerningReference, pairKind = getCorrection( swappedCorrectionKey, eachFont) deletePair(kerningReference, eachFont) if isRecording is True: self.appendRecord('deletePair', kerningReference, eachFont, previousAmount) self.kerningLogger.info( DELETE_PAIR_LOG.format(leftGlyphName=kerningReference[0], rightGlyphName=kerningReference[1], familyName=eachFont.info.familyName, styleName=eachFont.info.styleName)) if self.isSymmetricalEditingOn is True: symmetricalCorrectionKey = findSymmetricalPair(selectedPair) previousAmount, kerningReference, pairKind = getCorrection( symmetricalCorrectionKey, eachFont) deletePair(kerningReference, eachFont) if isRecording is True: self.appendRecord('deletePair', kerningReference, eachFont, previousAmount) self.kerningLogger.info( DELETE_PAIR_LOG.format(leftGlyphName=kerningReference[0], rightGlyphName=kerningReference[1], familyName=eachFont.info.familyName, styleName=eachFont.info.styleName)) self.updateWordDisplays()
def exceptionTrigger(self): activeFont = self.fontsOrder[self.navCursor_Y] selectedPair = self.getActiveWordDisplay().getActivePair() correction, kerningReference, pairKind = getCorrection( selectedPair, activeFont) isException, doesExists, parentPair = isPairException( kerningReference, activeFont) # delete exception if isException: if self.isVerticalAlignedEditingOn is True: selectedFonts = self.fontsOrder else: selectedFonts = [self.fontsOrder[self.navCursor_Y]] for eachFont in selectedFonts: isException, doesExists, parentPair = isPairException( kerningReference, eachFont) if isException: deletePair(kerningReference, eachFont) self.appendRecord('deletePair', (kerningReference, eachFont, correction)) else: if not correction: # set standard pair to zero self.setPairCorrection(0) correction, kerningReference, pairKind = getCorrection( selectedPair, activeFont) isException, doesExists, parentPair = isPairException( kerningReference, activeFont) # trigger exception window exceptionOptions = possibleExceptions(selectedPair, kerningReference, activeFont) if len(exceptionOptions) == 1: self.exceptionWindow.set(exceptionOptions[0]) self.exceptionWindow.trigger() elif len(exceptionOptions) > 1: self.exceptionWindow.setOptions(exceptionOptions) self.exceptionWindow.enable(True) else: self.showMessage( 'no possible exceptions', 'kerning exceptions can be triggered only starting from class kerning corrections' ) self.updateWordDisplays()
def exceptionWindowCallback(self, sender): if self.isVerticalAlignedEditingOn is False: selectedFonts = [self.fontsOrder[self.navCursor_Y]] else: selectedFonts = self.fontsOrder selectedPair = self.getActiveWordDisplay().getActivePair() if sender.lastEvent == 'submit': for indexFont, eachFont in enumerate(selectedFonts): exceptionKey = sender.get() correction, kerningReference, pairKind = getCorrection( selectedPair, eachFont) setRawCorrection(exceptionKey, eachFont, correction) self.appendRecord('createException', (exceptionKey, eachFont, correction)) if indexFont == self.navCursor_Y: self.w.joystick.updateCorrectionValue() self.updateWordDisplays()
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 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()
def updateCorrectionValue(self): correction, kerningReference, pairKind = getCorrection(self.activePair, self.fontObj) try: self.activePairEditCorrection.set('{:d}'.format(correction)) except ValueError: self.activePairEditCorrection.set('')