def __init__(self, parentWidget): super(WFontAnchors, self).__init__() # - Init self.upperWidget = parentWidget self.activeFont = pFont() self.activeGlyph = pGlyph() self.metricData = { layer.name: self.activeFont.fontMetrics().asDict(layer.name) for layer in self.activeGlyph.masters() } # - Interface self.btn_apply = QtGui.QPushButton('Apply Changes') self.btn_reset = QtGui.QPushButton('Reset') #self.btn_open = QtGui.QPushButton('Open') #self.btn_save = QtGui.QPushButton('Save') self.btn_apply.clicked.connect(self.applyChanges) self.btn_reset.clicked.connect(self.resetChanges) #self.btn_save.clicked.connect(self.exportMetrics) #self.btn_open.clicked.connect(self.importMetrics) self.tab_fontMetrics = WTableView(self.metricData) # - Build self.addWidget(self.tab_fontMetrics, 0, 1, 5, 6) self.addWidget(self.btn_save, 6, 3, 1, 1) self.addWidget(self.btn_open, 6, 4, 1, 1)
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()
#FLM: Glyph: Name Shapes # VER: 1.0 #---------------------------------- # Foundry: The FontMaker # Typeface: Bolyar Sans # Date: 11.12.2018 #---------------------------------- # - Dependancies import fontlab as fl6 from typerig.proxy import pFont, pGlyph # - Init ------------------------------------------------ font = pFont() glyph = pGlyph() layers = ['100', '900'] exclude_shape = '_' # - Process -------------------------------------------- for layer in layers: for shape in glyph.shapes(layer): if exclude_shape not in shape.shapeData.name: shape.shapeData.name = glyph.name # - Finish -------------------------------------------- glyph.update() glyph.updateObject(glyph.fl) print 'DONE.'
def classes_fromFile(self, font): fontPath = os.path.split(font.fg.path)[0] fname = QtGui.QFileDialog.getOpenFileName(self, 'Load kerning classes from file', fontPath, ';;'.join(fileFormats)) if fname != None: with open(fname, 'r') as importFile: source_data = json.load(importFile) if source_data.has_key('masters'): # A Fontlab JSON Class kerning file source_data = json_class_dumb_decoder(source_data) return source_data # - Init ----------------------------- font = proxy.pFont() g = proxy.pGlyph() ws = proxy.pWorkspace() transform = (getLowercaseCodepoint, getUppercaseCodepoint) load_dlg = load_classes(font) font_kerning = {layer:proxy.pKerning(font.kerning(layer), load_dlg.classes[layer]) for layer in font.masters()} # - This will effectively copy all of the UC:UC kerning pairs to LC:LC, UC:LC, LC:UC # - For Bolyar Sans project for layer, kerning in font_kerning.iteritems(): kerning_LC2LC = kerning.getKerningForLeaders(transform[0], transform[0]) kerning_UC2LC = kerning.getKerningForLeaders(None, transform[0]) kerning_LC2UC = kerning.getKerningForLeaders(transform[0], None) pri kerning_UC2LC kerning.fg.setPlainPairs(kerning_LC2LC + kerning_UC2LC + kerning_LC2UC)
def process(self): # - Init self.active_font = pFont() current_glyph = pGlyph() 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 process_layers = [self.cmb_layer.currentText] if self.cmb_layer.currentText != 'All masters' else self.active_font.masters() # - 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: print 'ERROR:\tInvalid 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 layer in process_layers: # - Process only specified layer or all if layer == w_layer or w_layer == syn_passlayer: for glyph_name, insert_command in process_glyphs.iteritems(): # - Set working glyph w_glyph = self.active_font.glyph(glyph_name) # - 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: print 'ERROR:\tInvalid 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: print 'ERROR:\tInvalid 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() #print 'New: %s; Insert: %s; Origin: %s' %(new_position, insert_coord, insert_origin) # - Finish w_glyph.updateObject(w_glyph.fl, 'Shapes inserted to glyph: %s' %w_glyph.name, verbose=False) print 'DONE:\t Glyphs processed: %s' %' '.join(dst_store) print 'Done.'