def write(self, writer: UFOWriter, saveAs: bool | None = None) -> None: """Writes this LayerSet to a :class:`fontTools.ufoLib.UFOWriter`. Args: writer(fontTools.ufoLib.UFOWriter): The writer to write to. saveAs: If True, tells the writer to save out-of-place. If False, tells the writer to save in-place. This affects how resources are cleaned before writing. """ if saveAs is None: saveAs = self._reader is not writer # if in-place, remove deleted layers layers = self._layers if not saveAs: for name in set(writer.getLayerNames()).difference(layers): writer.deleteGlyphSet(name) # write layers defaultLayer = self.defaultLayer for name, layer in layers.items(): default = layer is defaultLayer if layer is _LAYER_NOT_LOADED: if saveAs: layer = self.loadLayer(name, lazy=False) else: continue glyphSet = writer.getGlyphSet(name, defaultLayer=default) layer.write(glyphSet, saveAs=saveAs) writer.writeLayerContents(self.layerOrder)
def save(self): if self.save_to_default_layer: self.defcon_font.save() else: if self.ufo_format <= UFOFormatVersion.FORMAT_2_0: # Up-convert the UFO to format 3 warnings.warn("The UFO was up-converted to format 3.") self.ufo_format = UFOFormatVersion.FORMAT_3_0 with UFOWriter(self.defcon_font.path, formatVersion=self.ufo_format) as writer: writer.getGlyphSet() writer.writeLayerContents() writer = UFOWriter(self.defcon_font.path, formatVersion=self.ufo_format) writer.layerContents[PROCD_GLYPHS_LAYER_NAME] = PROCD_GLYPHS_LAYER layers = self.defcon_font.layers layer = layers[PROCD_GLYPHS_LAYER_NAME] glyph_set = writer.getGlyphSet(layerName=PROCD_GLYPHS_LAYER_NAME, defaultLayer=False) if self.font_format == "PFC": libs = {} for f in layers.defaultLayer._glyphs.items(): libs[f[0]] = f[1].lib for g in layer._glyphs.items(): g[1].lib = libs[g[0]] writer.writeLayerContents(layers.layerOrder) layer.save(glyph_set) if self.font_type == UFO_FONT_TYPE: ufotools.regenerate_glyph_hashes(self.ufo_font_hash_data) # Write the hash data, if it has changed. self.ufo_font_hash_data.close() elif self.font_type == TYPE1_FONT_TYPE: args = ['tx', '-t1'] if self.font_format == 'PFB': args.append('-pfb') if not run_shell_command(args + [self.temp_ufo_path, self.font_path]): raise FocusFontError('Failed to convert UFO font to Type 1.') else: temp_cff_path = get_temp_file_path() if not run_shell_command([ 'tx', '-cff', '+S', '+b', '-std', self.temp_ufo_path, temp_cff_path ], suppress_output=True): raise FocusFontError('Failed to convert UFO font to CFF.') if self.font_type == CFF_FONT_TYPE: shutil.copy2(temp_cff_path, self.font_path) else: # OTF_FONT_TYPE if not run_shell_command( ['sfntedit', '-a', f'CFF={temp_cff_path}', self.font_path ]): raise FocusFontError('Failed to add CFF table to OTF.')
def save(self, path): if path is None: path = self.path if os.path.abspath(self.path) != os.path.abspath(path): # If user has specified a path other than the source font path, # then copy the entire UFO font, and operate on the copy. log.info("Copying from source UFO font to output UFO font before " "processing...") if os.path.exists(path): shutil.rmtree(path) shutil.copytree(self.path, path) writer = UFOWriter(path, self._reader.formatVersionTuple, validate=False) layer = PROCESSED_LAYER_NAME if self.writeToDefaultLayer: layer = None # Write layer contents. layers = writer.layerContents.copy() if self.writeToDefaultLayer and PROCESSED_LAYER_NAME in layers: # Delete processed glyphs directory writer.deleteGlyphSet(PROCESSED_LAYER_NAME) # Remove entry from 'layercontents.plist' file del layers[PROCESSED_LAYER_NAME] elif self.processedLayerGlyphMap or not self.writeToDefaultLayer: layers[PROCESSED_LAYER_NAME] = PROCESSED_GLYPHS_DIRNAME writer.layerContents.update(layers) writer.writeLayerContents() # Write glyphs. glyphset = writer.getGlyphSet(layer, defaultLayer=layer is None) for name, glyph in self.newGlyphMap.items(): filename = self.glyphMap[name] if not self.writeToDefaultLayer and \ name in self.processedLayerGlyphMap: filename = self.processedLayerGlyphMap[name] # Recalculate glyph hashes if self.writeToDefaultLayer: self.recalcHashEntry(name, glyph) glyphset.contents[name] = filename glyphset.writeGlyph(name, glyph, glyph.drawPoints) glyphset.writeContents() # Write hashmap if self.hashMapChanged: self.writeHashMap(writer)
def save(self, path): if path is None: path = self.path if os.path.abspath(self.path) != os.path.abspath(path): # If user has specified a path other than the source font path, # then copy the entire UFO font, and operate on the copy. log.info("Copying from source UFO font to output UFO font before " "processing...") if os.path.exists(path): shutil.rmtree(path) shutil.copytree(self.path, path) writer = UFOWriter(path, self._reader.formatVersion, validate=False) if self.hashMapChanged: self.writeHashMap(writer) self.hashMapChanged = False layer = PROCESSED_LAYER_NAME if self.writeToDefaultLayer: layer = None # Write layer contents. layers = {DEFAULT_LAYER_NAME: DEFAULT_GLYPHS_DIRNAME} if self.processedLayerGlyphMap or not self.writeToDefaultLayer: layers[PROCESSED_LAYER_NAME] = PROCESSED_GLYPHS_DIRNAME writer.layerContents.update(layers) writer.writeLayerContents([DEFAULT_LAYER_NAME, PROCESSED_LAYER_NAME]) # Write glyphs. glyphset = writer.getGlyphSet(layer, defaultLayer=layer is None) for name, glyph in self.newGlyphMap.items(): filename = self.glyphMap[name] if not self.writeToDefaultLayer and \ name in self.processedLayerGlyphMap: filename = self.processedLayerGlyphMap[name] glyphset.contents[name] = filename glyphset.writeGlyph(name, glyph, glyph.drawPoints) glyphset.writeContents()
def save(self): if self.save_to_default_layer: self.defcon_font.save() else: """ XXX A real hack here XXX RoboFont did not support layers (UFO3 feature) until version 3. So in order to allow editing (in RF 1.x) UFOs that contain a processed glyphs layer, checkoutlinesufo generates UFOs that are structured like UFO3, but advertise themselves as UFO2. To achieve this, the code below hacks ufoLib to surgically save only the processed layer. This hack is only performed if the original UFO is format 2. NOTE: this is deprecated and will be removed from AFDKO. """ writer = UFOWriter( self.defcon_font.path, formatVersion=self.ufo_format) writer.layerContents[ PROCD_GLYPHS_LAYER_NAME] = PROCD_GLYPHS_LAYER layers = self.defcon_font.layers layer = layers[PROCD_GLYPHS_LAYER_NAME] if self.ufo_format == UFOFormatVersion.FORMAT_2_0: # Override the UFO's formatVersion. This disguises a UFO2 to # be seen as UFO3 by ufoLib, thus enabling it to write the # layer without raising an error. warn_txt = ("Using a ‘hybrid’ UFO2-as-UFO3 is deprecated and " "will be removed from AFDKO by the end of 2020. " "This behavior (hack) was primarily to support " "older versions of RoboFont which did not support " "UFO3/layers. RoboFont 3 now supports UFO3 so the " "hack is no longer required. Please update your " "toolchain as needed.") warnings.warn(warn_txt, category=FutureWarning) writer._formatVersion = UFOFormatVersion.FORMAT_3_0 glyph_set = writer.getGlyphSet( layerName=PROCD_GLYPHS_LAYER_NAME, defaultLayer=False) writer.writeLayerContents(layers.layerOrder) if self.ufo_format == UFOFormatVersion.FORMAT_2_0: # Restore the UFO's formatVersion to the original value. # This makes the glif files be set to format 1 instead of 2. glyph_set.ufoFormatVersionTuple = UFOFormatVersion.FORMAT_2_0 layer.save(glyph_set) if self.font_type == UFO_FONT_TYPE: ufotools.regenerate_glyph_hashes(self.ufo_font_hash_data) # Write the hash data, if it has changed. self.ufo_font_hash_data.close() elif self.font_type == TYPE1_FONT_TYPE: args = ['tx', '-t1'] if self.font_format == 'PFB': args.append('-pfb') if not run_shell_command( args + [self.temp_ufo_path, self.font_path]): raise FocusFontError('Failed to convert UFO font to Type 1.') else: temp_cff_path = get_temp_file_path() if not run_shell_command([ 'tx', '-cff', '+S', '+b', '-std', self.temp_ufo_path, temp_cff_path], suppress_output=True): raise FocusFontError('Failed to convert UFO font to CFF.') if self.font_type == CFF_FONT_TYPE: copy2(temp_cff_path, self.font_path) else: # OTF_FONT_TYPE if not run_shell_command([ 'sfntedit', '-a', f'CFF={temp_cff_path}', self.font_path]): raise FocusFontError('Failed to add CFF table to OTF.')
def save(self): if self.save_to_default_layer: self.defcon_font.save() else: """ XXX A real hack here XXX RoboFont did not support layers (UFO3 feature) until version 3. So in order to allow editing (in RF 1.x) UFOs that contain a processed glyphs layer, checkoutlinesufo generates UFOs that are structured like UFO3, but advertise themselves as UFO2. To achieve this, the code below hacks ufoLib to surgically save only the processed layer. This hack is only performed if the original UFO is format 2. """ writer = UFOWriter(self.defcon_font.path, formatVersion=self.ufo_format) writer.layerContents[PROCD_GLYPHS_LAYER_NAME] = PROCD_GLYPHS_LAYER layers = self.defcon_font.layers layer = layers[PROCD_GLYPHS_LAYER_NAME] if self.ufo_format == 2: # Override the UFO's formatVersion. This disguises a UFO2 to # be seen as UFO3 by ufoLib, thus enabling it to write the # layer without raising an error. writer._formatVersion = 3 glyph_set = writer.getGlyphSet(layerName=PROCD_GLYPHS_LAYER_NAME, defaultLayer=False) writer.writeLayerContents(layers.layerOrder) if self.ufo_format == 2: # Restore the UFO's formatVersion to the original value. # This makes the glif files be set to format 1 instead of 2. glyph_set.ufoFormatVersion = self.ufo_format layer.save(glyph_set) if self.font_type == UFO_FONT_TYPE: ufotools.regenerate_glyph_hashes(self.ufo_font_hash_data) # Write the hash data, if it has changed. self.ufo_font_hash_data.close() elif self.font_type == TYPE1_FONT_TYPE: args = ['tx', '-t1'] if self.font_format == 'PFB': args.append('-pfb') if not run_shell_command(args + [self.temp_ufo_path, self.font_path]): raise FocusFontError('Failed to convert UFO font to Type 1.') else: temp_cff_path = get_temp_file_path() if not run_shell_command([ 'tx', '-cff', '+S', '+b', '-std', self.temp_ufo_path, temp_cff_path ], suppress_output=True): raise FocusFontError('Failed to convert UFO font to CFF.') if self.font_type == CFF_FONT_TYPE: copy2(temp_cff_path, self.font_path) else: # OTF_FONT_TYPE if not run_shell_command( ['sfntedit', '-a', f'CFF={temp_cff_path}', self.font_path ]): raise FocusFontError('Failed to add CFF table to OTF.')