def to_ufo_gasp_table(value): # XXX maybe the parser should cast the gasp values to int? value = {int(k): int(v) for k, v in value.items()} gasp_records = [] # gasp range records must be sorted in ascending rangeMaxPPEM for max_ppem, gasp_behavior in sorted(value.items()): gasp_records.append({ 'rangeMaxPPEM': max_ppem, 'rangeGaspBehavior': bin_to_int_list(gasp_behavior) }) return gasp_records
def test_bin_to_int_list(self): self.assertEqual([], bin_to_int_list(0)) self.assertEqual([0], bin_to_int_list(1)) self.assertEqual([1], bin_to_int_list(2)) self.assertEqual([0, 1], bin_to_int_list(3)) self.assertEqual([2], bin_to_int_list(4)) self.assertEqual([7, 30], bin_to_int_list((1 << 7) + (1 << 30)))
def set_custom_params(ufo, parsed=None, data=None, misc_keys=(), non_info=()): """Set Glyphs custom parameters in UFO info or lib, where appropriate. Custom parameter data can be pre-parsed out of Glyphs data and provided via the `parsed` argument, otherwise `data` should be provided and will be parsed. The `parsed` option is provided so that custom params can be popped from Glyphs data once and used several times; in general this is used for debugging purposes (to detect unused Glyphs data). The `non_info` argument can be used to specify potential UFO info attributes which should not be put in UFO info. """ if parsed is None: parsed = parse_custom_params(data or {}, misc_keys) else: assert data is None, "Shouldn't provide parsed data and data to parse." fsSelection_flags = {'Use Typo Metrics', 'Has WWS Names'} for name, value in parsed: name = normalize_custom_param_name(name) if name in fsSelection_flags: if value: if ufo.info.openTypeOS2Selection is None: ufo.info.openTypeOS2Selection = [] if name == 'Use Typo Metrics': ufo.info.openTypeOS2Selection.append(7) elif name == 'Has WWS Names': ufo.info.openTypeOS2Selection.append(8) continue # deal with any Glyphs naming quirks here if name == 'disablesNiceNames': name = 'useNiceNames' value = int(not value) # convert code page numbers to OS/2 ulCodePageRange bits if name == 'codePageRanges': value = [CODEPAGE_RANGES[v] for v in value] # convert Glyphs' GASP Table to UFO openTypeGaspRangeRecords if name == 'GASP Table': name = 'openTypeGaspRangeRecords' # XXX maybe the parser should cast the gasp values to int? value = {int(k): int(v) for k, v in value.items()} gasp_records = [] # gasp range records must be sorted in ascending rangeMaxPPEM for max_ppem, gasp_behavior in sorted(value.items()): gasp_records.append({ 'rangeMaxPPEM': max_ppem, 'rangeGaspBehavior': bin_to_int_list(gasp_behavior) }) value = gasp_records opentype_attr_prefix_pairs = (('hhea', 'Hhea'), ('description', 'NameDescription'), ('license', 'NameLicense'), ('panose', 'OS2Panose'), ('typo', 'OS2Typo'), ('unicodeRanges', 'OS2UnicodeRanges'), ('codePageRanges', 'OS2CodePageRanges'), ('weightClass', 'OS2WeightClass'), ('widthClass', 'OS2WidthClass'), ('win', 'OS2Win'), ('vendorID', 'OS2VendorID'), ('versionString', 'NameVersion'), ('fsType', 'OS2Type')) for glyphs_prefix, ufo_prefix in opentype_attr_prefix_pairs: name = re.sub('^' + glyphs_prefix, 'openType' + ufo_prefix, name) postscript_attrs = ('underlinePosition', 'underlineThickness') if name in postscript_attrs: name = 'postscript' + name[0].upper() + name[1:] # enforce that winAscent/Descent are positive, according to UFO spec if name.startswith('openTypeOS2Win') and value < 0: value = -value # The value of these could be a float, and ufoLib/defcon expect an int. if name in ('openTypeOS2WeightClass', 'openTypeOS2WidthClass'): value = int(value) if name == 'glyphOrder': # store the public.glyphOrder in lib.plist ufo.lib[PUBLIC_PREFIX + name] = value elif name == 'Filter': filter_struct = parse_glyphs_filter(value) if not filter_struct: continue if UFO2FT_FILTERS_KEY not in ufo.lib.keys(): ufo.lib[UFO2FT_FILTERS_KEY] = [] ufo.lib[UFO2FT_FILTERS_KEY].append(filter_struct) elif hasattr(ufo.info, name) and name not in non_info: # most OpenType table entries go in the info object setattr(ufo.info, name, value) else: # everything else gets dumped in the lib ufo.lib[GLYPHS_PREFIX + name] = value