def tag_nodes(self, mode): # - Init new_name = self.edt_tagStringNode.text.strip() # - Helper def tag(glyph, newName): wLayers = glyph._prepareLayers(pLayers) for layer in wLayers: for node in glyph.selectedNodes(layer): node.name = newName glyph.updateObject( glyph.fl, 'Glyph: %s; Nodes named: %s ' % (glyph.name, new_name)) glyph.update() # - Process if mode == 'G': glyph = eGlyph() tag(glyph, new_name) elif mode == 'W': process_glyphs = [] process_glyphs = [ eGlyph(glyph) for glyph in pWorkspace().getTextBlockGlyphs() ] for glyph in process_glyphs: tag(glyph, new_name)
def setFontMetrics(self, metricName): glyph = eGlyph() wLayers = glyph._prepareLayers(pLayers) for layer in wLayers: if self.btn_togSelection.isChecked(): selection = glyph.selectedNodes(layer) if len(selection): glyph.package.setMaster(layer) exec('glyph.package.%s_value = selection[0].y' % metricName) if self.btn_togBBOX.isChecked(): glyph.package.setMaster(layer) bbox_layer = glyph.layer(layer).boundingBox if metricName in ['ascender', 'capsHeight', 'xHeight']: exec( 'glyph.package.%s_value = int(bbox_layer.y() + bbox_layer.height())' % metricName) elif metricName == 'descender': glyph.package.descender_value = int(bbox_layer.y()) self.btn_togSelection.setChecked(False) self.btn_togBBOX.setChecked(False) glyph.update() glyph.updateObject( glyph.package, 'Set Font Metrics: %s @ %s.' % (metricName, '; '.join(wLayers)))
def getMetricEquations(self): glyph = eGlyph() lsbEq, rsbEq = glyph.getSBeq() self.reset_fileds() self.edt_lsb.setText(lsbEq) self.edt_rsb.setText(rsbEq)
def _addCustomMenuItems(self, menu): menu.addSeparator() menu.addAction(u'{Glyph Name}', lambda: self.setText(eGlyph().name)) menu.addSeparator() menu.addAction(u'To Lowercase', lambda: self.setText(self.text.lower())) menu.addAction(u'To Uppercase', lambda: self.setText(self.text.upper())) menu.addSeparator() menu.addAction(u'EQ', lambda: self.setText('=%s' % self.text)) menu.addAction(u'LSB', lambda: self.setText('=lsb("%s")' % self.text)) menu.addAction(u'RSB', lambda: self.setText('=rsb("%s")' % self.text)) menu.addAction(u'ADV', lambda: self.setText('=width("%s")' % self.text)) menu.addAction(u'L', lambda: self.setText('=l("%s")' % self.text)) menu.addAction(u'R', lambda: self.setText('=r("%s")' % self.text)) menu.addAction(u'W', lambda: self.setText('=w("%s")' % self.text)) menu.addAction(u'G', lambda: self.setText('=g("%s")' % self.text)) menu.addSeparator() menu.addAction(u'.salt', lambda: self.setText('%s.salt' % self.text)) menu.addAction(u'.calt', lambda: self.setText('%s.calt' % self.text)) menu.addAction(u'.ss0', lambda: self.setText('%s.ss0' % self.text)) menu.addAction(u'.locl', lambda: self.setText('%s.locl' % self.text)) menu.addAction(u'.smcp', lambda: self.setText('%s.smcp' % self.text)) menu.addAction(u'.cscp', lambda: self.setText('%s.cscp' % self.text)) menu.addAction(u'.onum', lambda: self.setText('%s.onum' % self.text)) menu.addAction(u'.pnum', lambda: self.setText('%s.pnum' % self.text)) menu.addAction(u'.tnum', lambda: self.setText('%s.tnum' % self.text))
def bindShapeParent(self): glyph = eGlyph() layer = None # Static! Make it smart, so it detects on all layers, dough unnecessary shapeIndex = self.spb_shapeIndex.value # Static! Make it smart, so it detects... namedShapes = [ shape for shape in glyph.shapes() + glyph.components() if len(shape.shapeData.name) ] try: wShape = namedShapes[shapeIndex] transform = wShape.transform if len(wShape.shapeData.name): if transform.m11() > 0: self.edt_lsb.setText('=%s' % wShape.shapeData.name) self.edt_rsb.setText('=%s' % wShape.shapeData.name) else: self.edt_lsb.setText('=rsb("%s")' % wShape.shapeData.name) self.edt_rsb.setText('=lsb("%s")' % wShape.shapeData.name) except IndexError: warnings.warn( 'Glyph: %s\tNo named shape with index: %s' % (glyph.name, shapeIndex), GlyphWarning)
def refresh(self, master_mode=False): def check_type(layer): if layer.isMaskLayer: return 'Mask' if layer.isMasterLayer: return 'Master' if layer.isService: return 'Service' if fl6.CurrentFont() is not None and fl6.CurrentGlyph() is not None: self.glyph = eGlyph() self.edt_glyphName.setText(self.glyph.name) if master_mode: init_data = [(layer, 'Master', layer.wireframeColor) for layer in self.glyph.layers() if layer.isMasterLayer] else: init_data = [ (layer.name, check_type(layer), layer.wireframeColor) for layer in self.glyph.layers() if '#' not in layer.name ] table_dict = { n: OrderedDict(zip(column_names, data)) for n, data in enumerate(init_data) } self.lst_layers.setTable(init_table_dict) self.lst_layers.setTable(table_dict)
def tag_glyphs(self, mode): # - Init new_tags = self.edt_tagString.text.replace(' ', '').split(',') # - Helper def tag(glyph, tagList): glyph.setTags(tagList) glyph.updateObject( glyph.fl, 'Glyph: %s; Add tags: %s ' % (glyph.name, tagList)) glyph.update() # - Process if mode == 'G': glyph = eGlyph() tag(glyph, new_tags) else: process_glyphs = [] if mode == 'W': process_glyphs = [ pGlyph(glyph) for glyph in pWorkspace().getTextBlockGlyphs() ] elif mode == 'S': process_glyphs = pFont().selected_pGlyphs() for glyph in process_glyphs: tag(glyph, new_tags) self.edt_tagString.clear()
def hobby_get(self): glyph = eGlyph() selSegment = eCurveEx( eNode(glyph.selectedNodes()[0]).getSegmentNodes()) c0, c1 = selSegment.curve.solve_hobby_curvature() self.spn_hobby0.setValue(c0.real) self.spn_hobby1.setValue(c1.real)
def _addCustomMenuItems(self, menu): menu.addSeparator() menu.addAction(u'{Glyph Name}', lambda: self.setText(eGlyph().name)) menu.addAction(u'_part', lambda: self.smartSetText('_part')) menu.addAction(u'_UC', lambda: self.smartSetText('_UC')) menu.addAction(u'_LC', lambda: self.smartSetText('_LC')) menu.addAction(u'_LAT', lambda: self.smartSetText('_LAT')) menu.addAction(u'_CYR', lambda: self.smartSetText('_CYR'))
def capture(self): # - Init process_angles = {} active_workspace = pWorkspace() # - Rebuild self.__clear() self.__build() # - Collect process glyphs if pMode == 0: self.process_glyphs.append(eGlyph()) # Current Active Glyph if pMode == 1: self.process_glyphs = [ eGlyph(glyph) for glyph in active_workspace.getTextBlockGlyphs() ] # All glyphs in current window if pMode == 2: self.process_glyphs = self.active_font.selectedGlyphs( extend=eGlyph) # Selected glyphs in font window if pMode > 2: return # - Get nodes grouped by smart angle value if len(self.process_glyphs): for glyph in self.process_glyphs: #wLayers = glyph._prepareLayers(pLayers) layer = None eNodes = glyph.nodes(layer=layer, extend=eNode) for node in eNodes: smart_angle = node.getSmartAngle() if smart_angle[0]: process_angles.setdefault(smart_angle[1], []).append(node) # - Build sliders for angle_value, angle_nodes in process_angles.iteritems(): new_slider = TRSliderCtrl('0', '100', angle_value, 5) new_slider.sld_axis.valueChanged.connect(self.__processNodes) self.addLayout(new_slider) self.sliders.append([new_slider, angle_value, angle_nodes]) # - Set undo snapshot self.update_glyphs(self.process_glyphs, True)
def drop_guide_H(self): font = pFont() glyph = eGlyph() src_glyph = glyph src_name = self.edt_sourceName.text if len(src_name) and font.hasGlyph(src_name): src_glyph = font.glyph(src_name) wLayers = glyph._prepareLayers(pLayers) italicAngle = 0 #glyph.package.italicAngle_value guide_name = self.edt_guideName.text if len( self.edt_guideName.text) else '%s:%s:%s%%' % ( src_name, self.cmb_select_H.currentText, self.spb_prc_H.value) for layerName in wLayers: metrics = pFontMetrics(glyph.package) if 'BBox' in self.cmb_select_H.currentText: height = src_glyph.layer(layerName).boundingBox.height() origin = glyph.layer(layerName).boundingBox.y() elif 'Adv' in self.cmb_select_H.currentText: height = src_glyph.layer(layerName).advanceHeight origin = 0. elif 'X-H' in self.cmb_select_H.currentText: height = metrics.getXHeight(layerName) origin = 0. elif 'Caps' in self.cmb_select_H.currentText: height = metrics.getCapsHeight(layerName) origin = 0. elif 'Ascender' in self.cmb_select_H.currentText: height = metrics.getAscender(layerName) origin = 0. elif 'Descender' in self.cmb_select_H.currentText: height = metrics.getDescender(layerName) origin = 0. guidePos = (0, float(height) * self.spb_prc_H.value / 100 + origin + self.spb_unit_H.value) glyph.addGuideline(guidePos, layer=layerName, angle=90, name=guide_name, tag=self.edt_guideTag.text, color=self.cmb_select_color.currentText) glyph.updateObject( glyph.fl, 'Drop Guide <%s> @ %s.' % (self.edt_guideName.text, '; '.join( glyph._prepareLayers(pLayers)))) glyph.update()
def refresh(self, layer=None): # - Init self.glyph = eGlyph() self.edt_glyphName.setText(eGlyph().name) self.table_dict = {} node_count = 0 # - Populate layers if layer is None: self.layer_names = [ item.name for item in self.glyph.layers() if '#' not in item.name ] self.cmb_layer.clear() self.cmb_layer.addItems(self.layer_names) self.cmb_layer.setCurrentIndex( self.layer_names.index(self.glyph.activeLayer().name)) # - Populate table try: # Dirty Quick Fix - Solve later for sID, shape in enumerate(self.glyph.shapes(layer)): for cID, contour in enumerate(shape.contours): for nID, node in enumerate(contour.nodes()): table_values = [ node_count, sID, cID, round(node.x, 2), round(node.y, 2), node.type, round(eNode(node).distanceToPrev(), 2) ] self.table_dict[node_count] = OrderedDict( zip(self.table_columns, table_values)) node_count += 1 self.tab_nodes.setTable(self.table_dict, (False, False)) self.tab_nodes.resizeColumnsToContents() except AttributeError: pass
def drop_guide_nodes(self, flip): glyph = eGlyph() glyph.dropGuide(layers=pLayers, name=self.edt_guideName.text, tag=self.edt_guideTag.text, color=self.cmb_select_color.currentText, flip=flip) glyph.updateObject( glyph.fl, 'Drop Guide <%s> @ %s.' % (self.edt_guideName.text, '; '.join( glyph._prepareLayers(pLayers)))) glyph.update()
def refresh(self): # - Init self.glyph = eGlyph() self.edt_glyphName.setText(self.glyph.name) # - Build Tree and style it self.data = [((layer.name), [ (anchor.name, int(anchor.point.x()), int(anchor.point.y()), anchor.expressionX, anchor.expressionY) for anchor in self.glyph.anchors(layer.name) ]) for layer in self.glyph.masters()] self.tree_anchors.setTree(OrderedDict(reversed(self.data)), self.header_names) self.tree_anchors.markDiff()
def getProcessGlyphs(mode=0, font=None, workspace=None): '''Returns a list of glyphs for processing in TypeRig gui apps Args: mode (int): 0 - Current active glyph; 1 - All glyphs in current window; 2 - All selected glyphs; 3 - All glyphs in font font (fgFont) - Font file (object) workspace (flWorkspace) - Workspace Returns: list(eGlyph) ''' # - Init process_glyphs = [] active_workspace = pWorkspace() active_font = pFont(font) # - Collect process glyphs if mode == 0: process_glyphs.append(eGlyph()) if mode == 1: process_glyphs = [eGlyph(glyph) for glyph in active_workspace.getTextBlockGlyphs()] if mode == 2: process_glyphs = active_font.selectedGlyphs(extend=eGlyph) if mode == 3: process_glyphs = active_font.glyphs(extend=eGlyph) return process_glyphs
def copy_bbox(self, copy_height=False): dst_glyph = eGlyph() if len(dst_glyph.selectedNodes()): font = pFont() src_glyph = font.glyph(self.edt_width.text) adjPercent = self.spb_bbox_percent.value adjUnits = self.spb_bbox_units.value wLayers = dst_glyph._prepareLayers(pLayers) for layer in wLayers: selection = eNodesContainer(dst_glyph.selectedNodes(layer)) if copy_height: dst_glyph_height = dst_glyph.getBounds(layer).height() src_glyph_height = src_glyph.getBounds(layer).height() dst_glyph_y = dst_glyph.getBounds(layer).y() src_glyph_y = src_glyph.getBounds(layer).y() process_shift = src_glyph_height * adjPercent / 100 - dst_glyph_height + adjUnits process_y = src_glyph_y * adjPercent / 100 - dst_glyph_y + adjUnits selection.shift(0, process_shift) if process_y != 0: selection = eNodesContainer(dst_glyph.nodes(layer)) selection.shift(0, process_y) else: dst_glyph_width = dst_glyph.getBounds(layer).width() src_glyph_width = src_glyph.getBounds(layer).width() process_shift = src_glyph_width * adjPercent / 100 - dst_glyph_width + adjUnits selection.shift(process_shift, 0) dst_glyph.updateObject( dst_glyph.fl, 'Copy BBox | SRC: %s; DST: %s @ %s.' % (src_glyph.name, dst_glyph.name, '; '.join(wLayers))) dst_glyph.update() else: warnings.warn('Glyph: %s\tNo nodes selected.' % dst_glyph.name, GlyphWarning)
def getBuilder(self): if self.btn_getBuilder.isChecked(): if len(self.edt_glyphName.text): builder_glyph = self.active_font.glyph(self.edt_glyphName.text) else: builder_glyph = eGlyph() self.edt_glyphName.setText(builder_glyph.name) if builder_glyph is not None: temp_builder = builder_glyph.getBuilders() if len(temp_builder.keys() ) and filter_name in temp_builder.keys(): self.builder = temp_builder[filter_name][0] self.btn_getBuilder.setText('Release') else: self.builder = None self.edt_glyphName.clear() self.btn_getBuilder.setText('Set Builder')
def get_stem(self, get_y=False): if self.__doCheck(): self.masters_data = self.tree_layer.getTree() self.active_glyph = eGlyph() for group, data in self.masters_data.items(): for layer_data in data: try: selection = self.active_glyph.selectedNodes(layer_data[0], True) if get_y: layer_data[2] = abs(selection[0].y - selection[-1].y) else: layer_data[1] = abs(selection[0].x - selection[-1].x) except IndexError: warnings.warn('Missing or incompatible layer: %s!' %layer_data[0], LayerWarning) continue self.tree_layer.setTree(OrderedDict(self.masters_data), tree_column_names)
def _addCustomMenuItems(self, menu): curret_glyph = eGlyph() menu.addSeparator() menu.addAction(u'Get {Glyph Name}', lambda: self.setText(curret_glyph.name)) menu.addAction(u'Get {Glyph Unicodes}', lambda: self.setText(' '.join(map(str,curret_glyph.unicodes)))) menu.addAction(u'Get {Glyph Tags}', lambda: self.setText(' '.join(map(str,curret_glyph.tags)))) menu.addSeparator() menu.addAction(u'To Lowercase', lambda: self.setText(self.text.lower())) menu.addAction(u'To Uppercase', lambda: self.setText(self.text.upper())) menu.addAction(u'To Titlecase', lambda: self.setText(self.text.title())) menu.addSeparator() menu.addAction(u'.salt', lambda: self.setText('%s.salt' %self.text)) menu.addAction(u'.calt', lambda: self.setText('%s.calt' %self.text)) menu.addAction(u'.ss0', lambda: self.setText('%s.ss0' %self.text)) menu.addAction(u'.locl', lambda: self.setText('%s.locl' %self.text)) menu.addAction(u'.smcp', lambda: self.setText('%s.smcp' %self.text)) menu.addAction(u'.cscp', lambda: self.setText('%s.cscp' %self.text)) menu.addAction(u'.onum', lambda: self.setText('%s.onum' %self.text)) menu.addAction(u'.pnum', lambda: self.setText('%s.pnum' %self.text)) menu.addAction(u'.tnum', lambda: self.setText('%s.tnum' %self.text)) menu.addAction(u'.bak', lambda: self.setText('%s.bak' %self.text))
def drop_guide_V(self): font = pFont() glyph = eGlyph() src_glyph = glyph src_name = self.edt_sourceName.text if len(src_name) and font.hasGlyph(src_name): src_glyph = font.glyph(src_name) wLayers = glyph._prepareLayers(pLayers) italicAngle = 0 #glyph.package.italicAngle_value guide_name = self.edt_guideName.text if len( self.edt_guideName.text) else '%s:%s:%s%%' % ( src_name, self.cmb_select_V.currentText, self.spb_prc_V.value) for layerName in wLayers: if 'BBox' in self.cmb_select_V.currentText: width = src_glyph.layer(layerName).boundingBox.width() origin = glyph.layer(layerName).boundingBox.x() elif 'Adv' in self.cmb_select_V.currentText: width = src_glyph.getAdvance(layerName) origin = 0. #print width, origin , width + origin, float(width)*self.spb_prc_V.value/100 + origin guidePos = (float(width) * self.spb_prc_V.value / 100 + origin + self.spb_unit_V.value, 0) glyph.addGuideline(guidePos, layer=layerName, angle=italicAngle, name=guide_name, tag=self.edt_guideTag.text, color=self.cmb_select_color.currentText) glyph.updateObject( glyph.fl, 'Drop Guide <%s> @ %s.' % (self.edt_guideName.text, '; '.join( glyph._prepareLayers(pLayers)))) glyph.update()
def convert_segment(self, toCurve=False): glyph = eGlyph() wLayers = glyph._prepareLayers(pLayers) # - Get selected nodes. # - NOTE: Only the fist node in every selected segment is important, so we filter for that selection = glyph.selectedAtContours(True, filterOn=True) selection_dict, selection_filtered = {}, {} for cID, nID in selection: selection_dict.setdefault(cID, []).append(nID) for cID, sNodes in selection_dict.items(): onNodes = glyph.contours(extend=pContour)[cID].indexOn() segments = zip( onNodes, onNodes[1:] + [onNodes[0] ]) # Shift and zip so that we have the last segment working onSelected = [] for pair in segments: if pair[0] in sNodes and pair[1] in sNodes: onSelected.append(pair[1]) selection_filtered[cID] = onSelected # - Process for layer in wLayers: for cID, sNodes in selection_filtered.items(): for nID in reversed(sNodes): if toCurve: glyph.contours( layer)[cID].nodes()[nID].convertToCurve() else: glyph.contours(layer)[cID].nodes()[nID].convertToLine() glyph.updateObject(glyph.fl, 'Convert Segment @ %s.' % '; '.join(wLayers)) glyph.update()
def refresh(self): # - Init self.axis_points = [] self.axis_stems = [] self.data_glyphs = getProcessGlyphs(pMode) self.data_glyphs = [glyph for glyph in self.data_glyphs if not glyph.isEmpty()] self.glyph_arrays = {} self.glyph_arrays_service = {} self.active_glyph = eGlyph() self.active_font = pFont() self.active_workspace = pWorkspace() self.active_canvas = self.active_workspace.getCanvas(True) self.working_names = [glyph.name for glyph in self.data_glyphs] if len(self.data_glyphs) > 1 else [self.active_glyph.name] self.lst_glyphName.clear() self.lst_glyphName.addItems(self.working_names) if len(self.active_font.masters()) > 1: # - Activate self.__lbl_warn.setText('') self.__lbl_warn.setStyleSheet('') self.btn_setAxis.setEnabled(True) self.btn_getVstem.setEnabled(True) self.btn_getHstem.setEnabled(True) self.mixer_dx.reset() self.mixer_dy.reset() self.scalerX.reset() self.scalerY.reset() else: # - Deactivate self.__lbl_warn.show() self.__lbl_warn.setText('<b>Insufficient number of Master layers!</b><br>Delta Panel is currently disabled!') self.__lbl_warn.setStyleSheet('padding: 10; font-size: 10pt; background: lightpink;') self.btn_setAxis.setEnabled(False) self.btn_getVstem.setEnabled(False) self.btn_getHstem.setEnabled(False)
def eqContour(self, method, value=None): glyph = eGlyph() selection = glyph.selected(True) wLayers = glyph._prepareLayers(pLayers) for layer in wLayers: # !!! Fixed the problem, but with too many loops - rethink nodes_fl = [glyph.nodes(layer)[nid] for nid in selection] nodes = [eNode(node) for node in nodes_fl] conNodes = [node for node in nodes if node.getNextOn() in nodes_fl] segmentNodes = [node.getSegmentNodes() for node in conNodes] for segment in reversed(segmentNodes): if len(segment) == 4: wSegment = eCurveEx(segment) if method is 'tunni': wSegment.eqTunni() elif method is 'hobby': curvature = (float(self.spn_hobby0.value), float(self.spn_hobby1.value)) wSegment.eqHobbySpline(curvature) elif method is 'hobby_value': wSegment.eqHobbySpline((float(value), float(value))) elif method is 'prop': proportion = float(self.spn_prop.value / 100.) wSegment.eqProportionalHandles(proportion) elif method is 'prop_value': wSegment.eqProportionalHandles(value) glyph.updateObject(glyph.fl, 'Optimize %s @ %s.' % (method, '; '.join(wLayers))) glyph.update()
def moveElement(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 process_insert(self): # - Init self.active_font = pFont() current_glyph = eGlyph() getUniGlyph = lambda c: self.active_font.fl.findUnicode(ord( c)).name if all(['uni' not in c, '.' not in c, '_' not in c] ) else c # - Parse input ------------------------------------------------------------ for line in self.txt_editor.toPlainText().splitlines(): # - Init process_glyphs = {} dst_store, src_store = [], [] w_layer = syn_passlayer # Pass all commands - no specific layer selected if syn_insert in line and syn_comment not in line: init_parse = line.split(syn_insert) if len(init_parse) == 2: # No specific layer given left, rigth = init_parse elif len(init_parse) == 3: # Layer explicitly set w_layer, left, rigth = init_parse w_layer = w_layer.strip() else: output(2, app_name, 'Invalid syntax! Skipping Line: %s\n' % line) continue # - Set basics #dst_store = [getUniGlyph(name) if syn_currglyph not in name else current_glyph.name for name in rigth.split()] dst_store = [ name if syn_currglyph not in name else current_glyph.name for name in rigth.split() ] src_temp = [ item.strip().split(syn_pos) for item in left.split() ] src_temp = [[item[0], item[1].split(syn_transform)] if len(item) > 1 else item for item in src_temp] process_glyphs = {glyph: src_temp for glyph in dst_store} # - Process ------------------------------------------------------------ for glyph_name, insert_command in process_glyphs.iteritems(): # - Set working glyph w_glyph = eGlyph(self.active_font.glyph(glyph_name).fl) process_layers = w_glyph._prepareLayers(pLayers) for layer in process_layers: # - Process insertions for insert in insert_command: if len(insert): # - Init # -- Shape retrieval and origin determination if len(insert[0]): if syn_bboxBL in insert[ 0]: # Shape origin: measured at Shapes BBox Bottom Left insert_name = insert[0].replace( syn_bboxBL, '') w_shape = self.active_font.findShape( insert_name, layer) insert_origin = Coord( w_shape.boundingBox.x(), w_shape.boundingBox.y()) elif syn_bboxBR in insert[ 0]: # Shape origin: measured at Shapes BBox Bottom Right insert_name = insert[0].replace( syn_bboxBR, '') w_shape = self.active_font.findShape( insert_name, layer) insert_origin = Coord( w_shape.boundingBox.x() + w_shape.boundingBox.width(), w_shape.boundingBox.y()) elif syn_bboxTL in insert[ 0]: # Shape origin: measured at Shapes BBox Top Left insert_name = insert[0].replace( syn_bboxTL, '') w_shape = self.active_font.findShape( insert_name, layer) insert_origin = Coord( w_shape.boundingBox.x(), w_shape.boundingBox.y() + w_shape.boundingBox.height()) elif syn_bboxTR in insert[ 0]: # Shape origin: measured at Shapes BBox Top Right insert_name = insert[0].replace( syn_bboxTR, '') w_shape = self.active_font.findShape( insert_name, layer) insert_origin = Coord( w_shape.boundingBox.x() + w_shape.boundingBox.height(), w_shape.boundingBox.y() + w_shape.boundingBox.width()) elif syn_label in insert[ 0]: # Shape origin: At source Glyphs Labeled Node insert_name, node_label = insert[ 0].split(syn_label) for glyph in self.active_font.pGlyphs( ): w_shape = glyph.findShape( insert_name, layer) if w_shape is not None: insert_origin = Coord( glyph.findNodeCoords( node_label, layer)) break else: # Shape origin: Not set insert_name = insert[0] w_shape = self.active_font.findShape( insert_name, layer) insert_origin = Coord(0, 0) else: output( 2, app_name, 'Invalid command! Skipping insertion command: %s\n' % insert) continue # -- In-glyph positioning insert_position = None if len( insert ) == 1: # Position: Simplest case no positional tags insert_coord = Coord((0, 0)) else: if len(insert[1]): w_bbox = w_glyph.getBounds(layer) if syn_currnode == insert[1][ 0]: # Position: Destination Glyphs Currently selected node position = w_glyph.selectedCoords( layer, applyTransform=True) insert_position = position[ 0] if len(position) else None elif syn_bboxBL == insert[1][ 0]: # Position: Destination Glyphs BBox Bottom Left insert_position = (w_bbox.x(), w_bbox.y()) elif syn_bboxBR == insert[1][ 0]: # Position: Destination Glyphs BBox Bottom Right insert_position = (w_bbox.x() + w_bbox.width(), w_bbox.y()) elif syn_bboxTL == insert[1][ 0]: # Position: Destination Glyphs BBox Top Left insert_position = (w_bbox.x(), w_bbox.y() + w_bbox.height()) elif syn_bboxTR == insert[1][ 0]: # Position: Destination Glyphs BBox Top Right insert_position = (w_bbox.x() + w_bbox.height(), w_bbox.y() + w_bbox.width()) elif syn_label in insert[1][ 0]: # Position: Destination Glyphs Labeled Node insert_position = w_glyph.findNodeCoords( insert[1][0].strip(syn_label), layer) elif syn_anchor in insert[1][ 0]: # Position: Destination Glyphs Anchor insert_position = w_glyph.findAnchorCoords( insert[1][0].strip(syn_anchor), layer) elif syn_coordsep in insert[1][ 0]: # Position: Destination Glyphs Coordinates insert_position = eval( '(%s)' % insert[1][0]) if len( insert[1] ) > 1: # Positional correction in format (x,y) insert_correction = Coord( eval('(%s)' % insert[1][1])) else: insert_correction = Coord((0, 0)) if insert_position is None: output( 2, app_name, 'Invalid positional tags! Skipping insertion command: %s\n' % insert) continue # - Set insertion coordinates insert_coord = Coord( insert_position) + insert_correction # - Insert and reposition # !!! A quirky way of adding shapes follows # !!! This is so very wrong - adding the shape twice and removing the first, # !!! forces FL to make a proper clone of the shape!? temp_shape = w_glyph.addShape( w_shape, layer) # A dummy that helps ??! new_shape = w_glyph.addShape(w_shape, layer) w_glyph.layer(layer).removeShape(temp_shape) new_shape.assignStyle( w_shape ) # The only way to copy the 'non-spacing' property for now new_position = insert_coord - insert_origin new_transform = QtGui.QTransform( 1, 0, 0, 0, 1, 0, new_position.x, new_position.y, 1) new_shape.transform = new_transform w_glyph.update() # - Finish w_glyph.updateObject( w_glyph.fl, 'Shapes inserted to glyph: %s' % w_glyph.name) output(0, app_name, 'Glyphs processed: %s' % ' '.join(dst_store))
# - Dependancies from __future__ import absolute_import, print_function import fontlab as fl6 import fontgate as fgt import FL as legacy import PythonQt as pqt from typerig.proxy.fl.objects.font import pFont from typerig.proxy.fl.objects.glyph import eGlyph from typerig.proxy.fl.objects.node import eNode # - Init ----------------------------- font = pFont() glyph = eGlyph() # Warning: Solution is not universal, it just relies on the last part of the layer name search_layers_suffix = ' S' # Last part of the layer name layer_pairs = [(layer, layer + search_layers_suffix) for layer in font.masters() if search_layers_suffix not in layer] # - Process for layer_in, layer_out in layer_pairs: shapes_in = glyph.shapes(layer_in) shapes_out = glyph.shapes(layer_out) if len(shapes_in) == len(shapes_out): for shi in range(len(shapes_in)): shapes_out[shi].fl_transform = shapes_in[shi].fl_transform