def assertDesignspaceRoundtrip(self, designspace): directory = tempfile.mkdtemp() font = to_glyphs(designspace, minimize_ufo_diffs=True) # Check that round-tripping in memory is the same as writing on disk roundtrip_in_mem = to_designspace(font, propagate_anchors=False) tmpfont_path = os.path.join(directory, "font.glyphs") font.save(tmpfont_path) font_rt = classes.GSFont(tmpfont_path) roundtrip = to_designspace(font_rt, propagate_anchors=False) font.save("intermediary.glyphs") write_designspace_and_UFOs(designspace, "expected/test.designspace") for source in designspace.sources: normalize_ufo_lib(source.path) normalizeUFO(source.path, floatPrecision=3, writeModTimes=False) write_designspace_and_UFOs(roundtrip, "actual/test.designspace") for source in roundtrip.sources: normalize_ufo_lib(source.path) normalizeUFO(source.path, floatPrecision=3, writeModTimes=False) self.assertDesignspacesEqual( roundtrip_in_mem, roundtrip, "The round-trip in memory or written to disk should be equivalent", ) self.assertDesignspacesEqual( designspace, roundtrip, "The font should not be modified by the roundtrip" )
def assertUFORoundtrip(self, font): self._normalize(font) expected = write_to_lines(font) # Don't propagate anchors when intending to round-trip designspace = to_designspace( font, propagate_anchors=False, minimize_glyphs_diffs=True) # Check that round-tripping in memory is the same as writing on disk roundtrip_in_mem = to_glyphs(designspace) self._normalize(roundtrip_in_mem) actual_in_mem = write_to_lines(roundtrip_in_mem) directory = tempfile.mkdtemp() path = os.path.join(directory, font.familyName + '.designspace') write_designspace_and_UFOs(designspace, path) designspace_roundtrip = DesignSpaceDocument() designspace_roundtrip.read(path) roundtrip = to_glyphs(designspace_roundtrip) self._normalize(roundtrip) actual = write_to_lines(roundtrip) with open('expected.txt', 'w') as f: f.write('\n'.join(expected)) with open('actual_in_mem.txt', 'w') as f: f.write('\n'.join(actual_in_mem)) with open('actual.txt', 'w') as f: f.write('\n'.join(actual)) self.assertLinesEqual( actual_in_mem, actual, "The round-trip in memory or written to disk should be equivalent") self.assertLinesEqual( expected, actual, "The font should not be modified by the roundtrip")
def main(): parser = argparse.ArgumentParser( "Translate all .glyphs files into UFO+designspace in the specified directories." ) parser.add_argument( "-o", "--out", metavar="OUTPUT_DIR", default="ufos", help="Output directory" ) parser.add_argument("directories", nargs="*") args = parser.parse_args() for directory in args.directories: files = glyphs_files(directory) for filename in files: try: # Code for glyphsLib with roundtrip from glyphsLib.builder import to_designspace font = glyphsLib.GSFont(filename) designspace = to_designspace(font) dsname = font.familyName.replace(" ", "") + ".designspace" designspace.write(os.path.join(args.out, dsname)) except ImportError: # This is the version that works with glyphsLib 2.1.0 glyphsLib.build_masters( filename, master_dir=args.out, designspace_instance_dir=args.out )
def build_masters(filename, master_dir, designspace_instance_dir=None, designspace_path=None, family_name=None, propagate_anchors=True, minimize_glyphs_diffs=False, normalize_ufos=False, create_background_layers=False): """Write and return UFOs from the masters and the designspace defined in a .glyphs file. Args: master_dir: Directory where masters are written. designspace_instance_dir: If provided, a designspace document will be written alongside the master UFOs though no instances will be built. family_name: If provided, the master UFOs will be given this name and only instances with this name will be included in the designspace. Returns: A named tuple of master UFOs (`ufos`) and the path to the designspace file (`designspace_path`). """ font = GSFont(filename) if designspace_instance_dir is None: instance_dir = None else: instance_dir = os.path.relpath(designspace_instance_dir, master_dir) designspace = to_designspace(font, family_name=family_name, propagate_anchors=propagate_anchors, instance_dir=instance_dir, minimize_glyphs_diffs=minimize_glyphs_diffs) ufos = [] for source in designspace.sources: ufos.append(source.font) if create_background_layers: ufo_create_background_layer_for_all_glyphs(source.font) ufo_path = os.path.join(master_dir, source.filename) clean_ufo(ufo_path) source.font.save(ufo_path) if normalize_ufos: import ufonormalizer ufonormalizer.normalizeUFO(ufo_path, writeModTimes=False) if not designspace_path: designspace_path = os.path.join(master_dir, designspace.filename) designspace.write(designspace_path) return Masters(ufos, designspace_path)
def build_masters(filename, master_dir, designspace_instance_dir=None, family_name=None, propagate_anchors=True): """Write and return UFOs from the masters defined in a .glyphs file. Args: master_dir: Directory where masters are written. designspace_instance_dir: If provided, a designspace document will be written alongside the master UFOs though no instances will be built. family_name: If provided, the master UFOs will be given this name and only instances with this name will be included in the designspace. Returns: A list of master UFOs, and if designspace_instance_dir is provided, a path to a designspace and a list of (path, data) tuples with instance paths from the designspace and respective data from the Glyphs source. """ font = GSFont(filename) instance_dir = None if designspace_instance_dir is not None: instance_dir = os.path.relpath(designspace_instance_dir, master_dir) designspace = to_designspace(font, family_name=family_name, propagate_anchors=propagate_anchors, instance_dir=instance_dir) ufos = [] for source in designspace.sources: ufos.append(source.font) ufo_path = os.path.join(master_dir, source.filename) clean_ufo(ufo_path) source.font.save(ufo_path) if designspace_instance_dir is not None: designspace_path = os.path.join(master_dir, designspace.filename) designspace.write(designspace_path) # All the instance data should be in the designspace. That's why for # now we return the full designspace in place of `instance_data`. # However, other functions still expect the instance data to have # a list of (path, something) tuples, hence the class `InstanceData`. return ufos, designspace_path, InstanceData(designspace) else: return ufos
def build_masters( filename, master_dir, designspace_instance_dir=None, designspace_path=None, family_name=None, propagate_anchors=True, minimize_glyphs_diffs=False, normalize_ufos=False, create_background_layers=False, generate_GDEF=True, store_editor_state=True, write_skipexportglyphs=False, ): """Write and return UFOs from the masters and the designspace defined in a .glyphs file. Args: master_dir: Directory where masters are written. designspace_instance_dir: If provided, a designspace document will be written alongside the master UFOs though no instances will be built. family_name: If provided, the master UFOs will be given this name and only instances with this name will be included in the designspace. Returns: A named tuple of master UFOs (`ufos`) and the path to the designspace file (`designspace_path`). """ font = GSFont(filename) if not os.path.isdir(master_dir): os.mkdir(master_dir) if designspace_instance_dir is None: instance_dir = None else: instance_dir = os.path.relpath(designspace_instance_dir, master_dir) designspace = to_designspace( font, family_name=family_name, propagate_anchors=propagate_anchors, instance_dir=instance_dir, minimize_glyphs_diffs=minimize_glyphs_diffs, generate_GDEF=generate_GDEF, store_editor_state=store_editor_state, write_skipexportglyphs=write_skipexportglyphs, ) # Only write full masters to disk. This assumes that layer sources are always part # of another full master source, which must always be the case in a .glyphs file. ufos = {} for source in designspace.sources: if source.filename in ufos: assert source.font is ufos[source.filename] continue if create_background_layers: ufo_create_background_layer_for_all_glyphs(source.font) ufo_path = os.path.join(master_dir, source.filename) clean_ufo(ufo_path) source.font.save(ufo_path) if normalize_ufos: import ufonormalizer ufonormalizer.normalizeUFO(ufo_path, writeModTimes=False) ufos[source.filename] = source.font if not designspace_path: designspace_path = os.path.join(master_dir, designspace.filename) designspace.write(designspace_path) return Masters(ufos, designspace_path)
def to_designspace(self, *args, **kwargs): kwargs["ufo_module"] = self.ufo_module return to_designspace(*args, **kwargs)