def adjMetrics(self): process_glyphs = getProcessGlyphs(pMode) for glyph in process_glyphs: wLayers = glyph._prepareLayers(pLayers) copyOrder = [False] * 3 srcGlyphs = [glyph.name] * 3 adjPercents = (self.spb_lsb_percent.value, self.spb_rsb_percent.value, self.spb_adv_percent.value) adjUnits = (self.spb_lsb_units.value, self.spb_rsb_units.value, self.spb_adv_units.value) for layer in wLayers: glyph.setLSB( glyph.getLSB(layer) * adjPercents[0] / 100 + adjUnits[0], layer) glyph.setRSB( glyph.getRSB(layer) * adjPercents[1] / 100 + adjUnits[1], layer) glyph.setAdvance( glyph.getAdvance(layer) * adjPercents[2] / 100 + adjUnits[2], layer) glyph.updateObject( glyph.fl, 'Adjust Metrics @ %s | %s' % ('; '.join(wLayers), zip(('LSB', 'RSB', 'ADV'), adjPercents, adjUnits))) glyph.update()
def shape_replace(self): process_glyphs = getProcessGlyphs(pMode) replace_shape_name = self.cmb_fontShapes.currentText for glyph in process_glyphs: process_layers = glyph._prepareLayers(pLayers) for layer in process_layers: replace_shape = self.active_font.findShape( replace_shape_name, layer) selected_shape = glyph.selectedAtShapes(index=False, layer=layer, deep=False)[0][0] if selected_shape is not None: if replace_shape is not None: replace_shape.transform = selected_shape.transform # Apply transform glyph.replaceShape(selected_shape, replace_shape, layer) else: print 'ERROR:\t Glyph: %s\tElement: %s not found @Layer: %s' % ( glyph.name, replace_shape_name, layer) glyph.update() glyph.updateObject( glyph.fl, 'Glyph: %s;\tInsert Element:%s @ %s.' % (glyph.name, replace_shape_name, '; '.join(process_layers)))
def copyMetrics(self): process_glyphs = getProcessGlyphs(pMode) for glyph in process_glyphs: copyOrder = [ '--' in name for name in (self.edt_lsb.text, self.edt_rsb.text, self.edt_adv.text) ] srcGlyphs = [ str(name).replace('--', '') if len(name) else None for name in (self.edt_lsb.text, self.edt_rsb.text, self.edt_adv.text) ] adjPercents = (self.spb_lsb_percent.value, self.spb_rsb_percent.value, self.spb_adv_percent.value) adjUnits = (self.spb_lsb_units.value, self.spb_rsb_units.value, self.spb_adv_units.value) glyph.copyMetricsbyName(srcGlyphs, pLayers, copyOrder, adjPercents, adjUnits) glyph.updateObject( glyph.fl, 'Copy Metrics | LSB: %s; RSB: %s; ADV:%s.' % (srcGlyphs[0], srcGlyphs[1], srcGlyphs[2])) glyph.update() self.reset_fileds()
def rebuild(self): # - Init process_glyphs = getProcessGlyphs(pMode) # - Process if len(process_glyphs): for glyph in process_glyphs: if glyph is not None: wLayers = glyph._prepareLayers(pLayers) for layer in wLayers: selection = glyph.selectedNodes(layer, filterOn=True, extend=eNode, deep=True) if len(selection) > 1: node_first = selection[0] node_last = selection[-1] line_in = node_first.getPrevLine() if node_first.getPrevOn(False) not in selection else node_first.getNextLine() line_out = node_last.getNextLine() if node_last.getNextOn(False) not in selection else node_last.getPrevLine() crossing = line_in & line_out node_first.smartReloc(*crossing) node_first.parent.removeNodesBetween(node_first.fl, node_last.getNextOn()) glyph.update() glyph.updateObject(glyph.fl, 'Rebuild corner: %s nodes reduced; At layers: %s' %(len(selection), '; '.join(wLayers)))
def setStart(self, control=(0,0)): process_glyphs = getProcessGlyphs(pMode) for glyph in process_glyphs: wLayers = glyph._prepareLayers(pLayers) if control == (0,0): criteria = lambda node : (node.x, node.y) elif control == (0,1): criteria = lambda node : (-node.y, node.x) elif control == (1,0): criteria = lambda node : (-node.x, node.y) elif control == (1,1): criteria = lambda node : (-node.y, -node.x) for layerName in wLayers: contours = glyph.contours(layerName) for contour in contours: onNodes = [node for node in contour.nodes() if node.isOn] newFirstNode = sorted(onNodes, key=criteria)[0] contour.setStartPoint(newFirstNode.index) glyph.update() glyph.updateObject(glyph.fl, 'Glyph: %s;\tAction: Set Start Points @ %s.' %(glyph.name, '; '.join(wLayers)))
def remove_SmartCorner(self): # Finds active preset in glyphs smart corners and removes them # - Init process_glyphs = getProcessGlyphs(pMode) active_preset = self.getPreset() # - Process if len(process_glyphs): for work_glyph in process_glyphs: if work_glyph is not None: # - Init wLayers = work_glyph._prepareLayers(pLayers) smart_corners, target_corners = [], [] # - Get all smart nodes/corners for layer in wLayers: for builder in work_glyph.getBuilders(layer)[filter_name]: smart_corners += builder.getSmartNodes() if len(smart_corners): for node in smart_corners: wNode = eNode(node) if wNode.getSmartAngleRadius() == float(active_preset[layer]): wNode.delSmartAngle() self.update_glyphs(process_glyphs, True) print 'DONE:\t Filter: Remove Smart Corner; Glyphs: %s' %'; '.join([g.name for g in process_glyphs])
def execute_preset(self, preset_list): # - Init copy_options = self.getCopyOptions() process_glyphs = getProcessGlyphs(self.pMode) print_preset = [' -> '.join(item) for item in preset_list] # - Process for wGlyph in process_glyphs: for process_src, process_dst in preset_list: self.copyLayer(wGlyph, process_src, process_dst, copy_options, True, self.chk_crlayer.isChecked()) wGlyph.update() wGlyph.updateObject(wGlyph.fl, 'Glyph: %s\tCopy Layer Preset | %s.' %(wGlyph.name, ' | '.join(print_preset)))
def execute_table(self): # - Init copy_options = self.getCopyOptions() process_glyphs = getProcessGlyphs(self.pMode) # - Process process_dict = self.tab_masters.getTable() process_src = process_dict['SRC'][0] process_dst = process_dict['DST'] for wGlyph in process_glyphs: for dst_layer in process_dst: self.copyLayer(wGlyph, process_src, dst_layer, copy_options, True, self.chk_crlayer.isChecked()) wGlyph.update() wGlyph.updateObject(wGlyph.fl, 'Glyph: %s\tCopy Layer | %s -> %s.' %(wGlyph.name, process_src, '; '.join(process_dst)))
def autoMetricEquations(self): process_glyphs = getProcessGlyphs(pMode) for glyph in process_glyphs: wLayers = glyph._prepareLayers(pLayers) glyph_stat = [] for layer in wLayers: status = glyph.bindCompMetrics(layer) glyph_stat.append(status) glyph.update() glyph.updateObject( glyph.fl, 'Glyph: %s;\tAuto Metrics Equations @ %s.' % (glyph.name, '; '.join('%s: %s' % item for item in zip(wLayers, glyph_stat))))
def shape_delete(self): process_glyphs = getProcessGlyphs(pMode) for glyph in process_glyphs: process_layers = glyph._prepareLayers(pLayers) process_shapes = { layer: glyph.selectedAtShapes(index=False, layer=layer, deep=False)[0][0] for layer in process_layers } for layer, shape in process_shapes.items(): glyph.layer(layer).removeShape(shape) glyph.update() glyph.updateObject( glyph.fl, 'Remove Element @ %s.' % '; '.join(process_layers))
def shape_resetTransform(self): process_glyphs = getProcessGlyphs(pMode) for glyph in process_glyphs: process_layers = glyph._prepareLayers(pLayers) for layer in process_layers: wShape = pShape( glyph.selectedAtShapes(index=False, layer=layer, deep=False)[0][0]) wShape.reset_transform() glyph.update() glyph.updateObject( glyph.fl, 'Reset Element transformation data @ %s.' % '; '.join(process_layers)) self.reset_fileds()
def shape_setname(self): process_glyphs = getProcessGlyphs(pMode) for glyph in process_glyphs: process_layers = glyph._prepareLayers(pLayers) for layer in process_layers: #print glyph.selectedAtShapes(index=False, layer=layer, deep=False) wShape = pShape( glyph.selectedAtShapes(index=False, layer=layer, deep=False)[0][0]) wShape.setName(self.edt_shapeName.text) glyph.update() glyph.updateObject( glyph.fl, 'Set Element Name @ %s.' % '; '.join(process_layers)) self.reset_fileds()
def apply_SmartCorner(self, remove=False): # NOTE: apply and remove here apply only to soelected nodes. if self.builder is not None: # - Init process_glyphs = getProcessGlyphs(pMode) active_preset = self.getPreset() if remove: # Build a special preset that deletes active_preset = {key:'DEL' for key in active_preset.keys()} # - Process if len(process_glyphs): for work_glyph in process_glyphs: if work_glyph is not None: self.process_smartCorner(work_glyph, active_preset) self.update_glyphs(process_glyphs, True) print 'DONE:\t Filter: Smart Corner; Glyphs: %s' %'; '.join([g.name for g in process_glyphs]) else: print 'ERROR:\t Please specify a Glyph with suitable Shape Builder (Smart corner) first!'
def apply_trap(self): # - Init process_glyphs = getProcessGlyphs(pMode) active_preset = self.getPreset() # - Process if len(process_glyphs): for glyph in process_glyphs: if glyph is not None: wLayers = glyph._prepareLayers(pLayers) for layer in reversed(wLayers): if layer in active_preset.keys(): selection = glyph.selectedNodes(layer, filterOn=True, extend=eNode, deep=True) for node in reversed(selection): preset_values = tuple([float(item.strip()) for item in active_preset[layer].split(',')]) node.cornerTrapInc(*preset_values) glyph.update() glyph.updateObject(glyph.fl, '%s @ %s.' %('Ink Trap', '; '.join(active_preset.keys())))
def shape_insert(self): process_glyphs = getProcessGlyphs(pMode) insert_shape_name = self.cmb_fontShapes.currentText for glyph in process_glyphs: process_layers = glyph._prepareLayers(pLayers) for layer in process_layers: insert_shape = self.active_font.findShape( insert_shape_name, layer) if insert_shape is not None: glyph.addShape(insert_shape, layer) else: print 'ERROR:\t Glyph: %s\tElement: %s not found @Layer: %s' % ( glyph.name, insert_shape_name, layer) glyph.update() glyph.updateObject( glyph.fl, 'Glyph: %s;\tInsert Element:%s @ %s.' % (glyph.name, insert_shape_name, '; '.join(process_layers)))
def apply_mitre(self, doKnot=False): # - Init process_glyphs = getProcessGlyphs(pMode) active_preset = self.getPreset() # - Process if len(process_glyphs): for glyph in process_glyphs: if glyph is not None: wLayers = glyph._prepareLayers(pLayers) for layer in reversed(wLayers): if layer in active_preset.keys(): selection = glyph.selectedNodes(layer, filterOn=True, extend=eNode, deep=True) for node in reversed(selection): if not doKnot: node.cornerMitre(float(active_preset[layer])) else: node.cornerMitre(-float(active_preset[layer]), True) action = 'Mitre Corner' if not doKnot else 'Overlap Corner' glyph.update() glyph.updateObject(glyph.fl, '%s @ %s.' %(action, '; '.join(active_preset.keys())))
def setMetricEquations(self, clear=False): process_glyphs = getProcessGlyphs(pMode) for glyph in process_glyphs: wLayers = glyph._prepareLayers(pLayers) for layer in wLayers: if not clear: if len(self.edt_lsb.text): glyph.setLSBeq(self.edt_lsb.text, layer) if len(self.edt_rsb.text): glyph.setRSBeq(self.edt_rsb.text, layer) if len(self.edt_adv.text): glyph.setADVeq(self.edt_adv.text, layer) else: glyph.setLSBeq('', layer) glyph.setRSBeq('', layer) glyph.setADVeq('', layer) glyph.update() glyph.updateObject( glyph.fl, 'Set Metrics Equations @ %s.' % '; '.join(wLayers)) self.reset_fileds()
def moveNodes(self, offset_x, offset_y, method): # - Init glyph = eGlyph() font = pFont() process_glyphs = getProcessGlyphs(pMode) for glyph in process_glyphs: wLayers = glyph._prepareLayers(pLayers) for layer in wLayers: selected_shapes = glyph.selectedAtShapes(index=False, layer=layer, deep=False) for shape, contour, node in selected_shapes: wShape = pShape(shape) if method == 'Shift': wShape.shift(offset_x, offset_y) elif method == 'Scale': wShape.scale(1. + offset_x / 100., 1. + offset_y / 100.) elif method == 'Shear': wShape.shear(radians(offset_x), radians(offset_y)) glyph.update() glyph.updateObject( glyph.fl, 'Element: %s @ %s.' % (method, '; '.join(wLayers))) # - Set Undo #glyph.updateObject(glyph.activeLayer(), '%s @ %s.' %(method, glyph.activeLayer().name), verbose=False) # - Finish it glyph.update()
def setDirection(self, ccw=True): process_glyphs = getProcessGlyphs(pMode) for glyph in process_glyphs: selection = glyph.selectedAtContours() wLayers = glyph._prepareLayers(pLayers) for layerName in wLayers: all_contours = glyph.contours(layerName) if len(selection): process_contours = [pContour(all_contours[item[0]]) for item in selection] else: process_contours = [pContour(contour) for contour in all_contours] for contour in process_contours: if ccw: contour.setCCW() else: contour.setCW() glyph.update() glyph.updateObject(glyph.fl, 'Glyph: %s;\tAction: Set contour direction @ %s.' %(glyph.name, '; '.join(wLayers)))
def table_refresh(self): if self.rad_glyph.isChecked(): self.pMode = 0 if self.rad_window.isChecked(): self.pMode = 1 if self.rad_selection.isChecked(): self.pMode = 2 if self.rad_font.isChecked(): self.pMode = 3 self.data_glyphs = getProcessGlyphs(self.pMode)
def alignNodes(self, mode): process_glyphs = getProcessGlyphs(pMode) modifiers = QtGui.QApplication.keyboardModifiers() for glyph in process_glyphs: wLayers = glyph._prepareLayers(pLayers) for layer in wLayers: selection = glyph.selectedNodes(layer, extend=eNode, deep=True) if mode == 'L': target = min(selection, key=lambda item: item.x) control = (True, False) elif mode == 'R': target = max(selection, key=lambda item: item.x) control = (True, False) elif mode == 'T': target = max(selection, key=lambda item: item.y) control = (False, True) elif mode == 'B': target = min(selection, key=lambda item: item.y) control = (False, True) elif mode == 'Y': target = Line(min(selection, key=lambda item: item.y).fl, max(selection, key=lambda item: item.y).fl) control = (True, False) elif mode == 'X': target = Line(min(selection, key=lambda item: item.x).fl, max(selection, key=lambda item: item.x).fl) control = (False, True) elif mode == 'BBoxCenterX': newX = glyph.layer(layer).boundingBox.x() + glyph.layer(layer).boundingBox.width()/2 newY = 0. target = fl6.flNode(newX, newY) control = (True, False) elif mode == 'BBoxCenterY': newX = 0. newY = glyph.layer(layer).boundingBox.y() + glyph.layer(layer).boundingBox.height()/2 target = fl6.flNode(newX, newY) control = (False, True) elif 'FontMetrics' in mode: layerMetrics = glyph.fontMetricsInfo(layer) italicAngle = glyph.package.italicAngle_value newX = 0. toMaxY = True if '0' in mode: newY = layerMetrics.ascender toMaxY = True if modifiers == QtCore.Qt.ShiftModifier else False elif '1' in mode: newY = layerMetrics.capsHeight toMaxY = True if modifiers == QtCore.Qt.ShiftModifier else False elif '2' in mode: newY = layerMetrics.descender toMaxY = False if modifiers == QtCore.Qt.ShiftModifier else True elif '3' in mode: newY = layerMetrics.xHeight toMaxY = True if modifiers == QtCore.Qt.ShiftModifier else False elif '4' in mode: newY = 0 toMaxY = False if modifiers == QtCore.Qt.ShiftModifier else True elif '5' in mode: newY = self.edt_toYpos.value toMaxY = False if modifiers == QtCore.Qt.ShiftModifier else True elif '6' in mode: newY = glyph.mLine() toMaxY = newY >= 0 if modifiers == QtCore.Qt.ShiftModifier: toMaxY = not toMaxY elif mode == 'Layer_V': if 'BBox' in self.cmb_select_V.currentText: width = glyph.layer(layer).boundingBox.width() origin = glyph.layer(layer).boundingBox.x() elif 'Adv' in self.cmb_select_V.currentText: width = glyph.getAdvance(layer) origin = 0. target = fl6.flNode(float(width)*self.spb_prc_V.value/100 + origin + self.spb_unit_V.value, 0) control = (True, False) elif mode == 'Layer_H': metrics = pFontMetrics(glyph.package) if 'BBox' in self.cmb_select_H.currentText: height = glyph.layer(layer).boundingBox.height() origin = glyph.layer(layer).boundingBox.y() elif 'Adv' in self.cmb_select_H.currentText: height = glyph.layer(layer).advanceHeight origin = 0. elif 'X-H' in self.cmb_select_H.currentText: height = metrics.getXHeight(layer) origin = 0. elif 'Caps' in self.cmb_select_H.currentText: height = metrics.getCapsHeight(layer) origin = 0. elif 'Ascender' in self.cmb_select_H.currentText: height = metrics.getAscender(layer) origin = 0. elif 'Descender' in self.cmb_select_H.currentText: height = metrics.getDescender(layer) origin = 0. target = fl6.flNode(0, float(height)*self.spb_prc_H.value/100 + origin + self.spb_unit_H.value) control = (False, True) for node in selection: if 'FontMetrics' in mode: if italicAngle != 0 and not self.chk_slope.isChecked(): tempTarget = Coord(node.fl) tempTarget.setAngle(italicAngle) target = fl6.flNode(tempTarget.getWidth(newY), newY) control = (True, True) elif self.chk_slope.isChecked(): pairUp = node.getMaxY().position pairDown = node.getMinY().position pairPos = pairUp if toMaxY else pairDown newLine = Line(node.fl.position, pairPos) newX = newLine.solveX(newY) target = fl6.flNode(newX, newY) control = (True, True) else: target = fl6.flNode(newX, newY) control = (False, True) if mode == 'peerCenterX': newX = node.x + (node.getPrevOn().x + node.getNextOn().x - 2*node.x)/2. newY = node.y target = fl6.flNode(newX, newY) control = (True, False) elif mode == 'peerCenterY': newX = node.x newY = node.y + (node.getPrevOn().y + node.getNextOn().y - 2*node.y)/2. target = fl6.flNode(newX, newY) control = (False, True) # - Execute Align ---------- node.alignTo(target, control) glyph.updateObject(glyph.fl, 'Align Nodes @ %s.' %'; '.join(wLayers)) glyph.update()
def moveNodes(self, offset_x, offset_y, method, inPercent): # - Init font = pFont() glyph = eGlyph() italic_angle = font.getItalicAngle() process_glyphs = getProcessGlyphs(pMode) for glyph in process_glyphs: wLayers = glyph._prepareLayers(pLayers) for layer in wLayers: selectedNodes = glyph.selectedNodes(layer=layer, extend=eNode) # -- Scaling move - coordinates as percent of position def scaleOffset(node, off_x, off_y): return (-node.x + width*(float(node.x)/width + offset_x), -node.y + height*(float(node.y)/height + offset_y)) width = glyph.layer(layer).boundingBox.width() # glyph.layer().advanceWidth height = glyph.layer(layer).boundingBox.height() # glyph.layer().advanceHeight # - Process if method == self.methodList[0]: for node in selectedNodes: if node.isOn: if inPercent: node.smartShift(*scaleOffset(node, offset_x, offset_y)) else: node.smartShift(offset_x, offset_y) elif method == self.methodList[1]: for node in selectedNodes: if inPercent: node.shift(*scaleOffset(node, offset_x, offset_y)) else: node.shift(offset_x, offset_y) elif method == self.methodList[2]: for node in selectedNodes: if inPercent: node.interpShift(*scaleOffset(node, offset_x, offset_y)) else: node.interpShift(offset_x, offset_y) elif method == self.methodList[3]: if italic_angle != 0: for node in selectedNodes: if inPercent: node.slantShift(*scaleOffset(node, offset_x, offset_y)) else: node.slantShift(offset_x, offset_y, italic_angle) else: for node in selectedNodes: if inPercent: node.smartShift(*scaleOffset(node, offset_x, offset_y)) else: node.smartShift(offset_x, offset_y) elif method == self.methodList[4]: current_layer = glyph.activeLayer().name if len(self.aux.copyLine) and current_layer in self.aux.copyLine: for node in selectedNodes: node.slantShift(offset_x, offset_y, -90 + self.aux.copyLine[current_layer].getAngle()) else: print 'ERROR:\tNo slope information for layer found!\nNOTE:\tPlease <<Copy Slope>> first using TypeRig Node align toolbox.' # - Finish it glyph.update() glyph.updateObject(glyph.fl, 'Node: %s @ %s.' %(method, '; '.join(wLayers)))
def alignContours(self): # - Helpers def getContourBonds(work_contours): tmp_bounds = [contour.bounds() for contour in work_contours] cont_min_X, cont_min_Y, cont_max_X, cont_max_Y = map(set, zip(*tmp_bounds)) return (min(cont_min_X), min(cont_min_Y), max(cont_max_X), max(cont_max_Y)) def getAlignDict(bounds_tuple): align_dict = { 'L': bounds_tuple[0], 'R': bounds_tuple[2], 'C': bounds_tuple[2]/2, 'B': bounds_tuple[1], 'T': bounds_tuple[3], 'E': bounds_tuple[3]/2 } return align_dict # - Init user_mode = self.align_mode[self.cmb_align_mode.currentText] user_x = self.align_x[self.cmb_align_x.currentText] user_y = self.align_y[self.cmb_align_y.currentText] keep_x, keep_y = True, True if user_x == 'K': keep_x = False; user_x = 'L' if user_y == 'X': keep_y = False; user_y = 'B' process_glyphs = getProcessGlyphs(pMode) # - Process for glyph in process_glyphs: selection = glyph.selectedAtContours() wLayers = glyph._prepareLayers(pLayers) for layerName in wLayers: glyph_contours = glyph.contours(layerName, extend=eContour) work_contours = [glyph_contours[index] for index in list(set([item[0] for item in selection]))] if user_mode == 'CL': # Align all contours in given Layer layer_bounds = glyph.getBounds(layerName) cont_bounds = (layer_bounds.x(), layer_bounds.y(), layer_bounds.x() + layer_bounds.width(), layer_bounds.y() + layer_bounds.height()) align_type = getAlignDict(cont_bounds) target = Coord(align_type[user_x], align_type[user_y]) for contour in glyph_contours: contour.alignTo(target, user_x + user_y, (keep_x, keep_y)) elif user_mode =='CC': # Align contours to contours if 1 < len(work_contours) < 3: c1, c2 = work_contours c1.alignTo(c2, user_x + user_y, (keep_x, keep_y)) elif len(work_contours) > 2: cont_bounds = getContourBonds(work_contours) align_type = getAlignDict(cont_bounds) target = Coord(align_type[user_x], align_type[user_y]) for contour in work_contours: contour.alignTo(target, user_x + user_y, (keep_x, keep_y)) elif user_mode == 'RC': # Align contours to contours in reverse order if 1 < len(work_contours) < 3: c1, c2 = work_contours c2.alignTo(c1, user_x + user_y, (keep_x, keep_y)) elif len(work_contours) > 2: cont_bounds = getContourBonds(work_contours) align_type = getAlignDict(cont_bounds) target = Coord(align_type[user_x], align_type[user_y]) for contour in reversed(work_contours): contour.alignTo(target, user_x + user_y, (keep_x, keep_y)) # !!! To be implemented elif user_mode == 'CN': # Align contour to node pass elif user_mode == 'NN': # Align a node on contour to node on another pass glyph.update() glyph.updateObject(glyph.fl, 'Glyph: %s;\tAction: Align Contours @ %s.' %(glyph.name, '; '.join(wLayers)))