def subset_font_cmap(srcname, dstname, exclude=None, include=None, bump_version=True): opt = _DEFAULT_OPTIONS font = subset.load_font(srcname, opt) target_charset = set(font_data.get_cmap(font).keys()) if include is not None: target_charset &= include if exclude is not None: target_charset -= exclude subsetter = subset.Subsetter(options=opt) subsetter.populate(unicodes=target_charset) subsetter.subset(font) if bump_version: # assume version string has 'uh' if unhinted, else hinted. revision, version_string = swat_license.get_bumped_version(font) font['head'].fontRevision = revision font_data.set_name_record(font, _VERSION_ID, version_string) subset.save_font(font, dstname, opt)
def update(name_id, new, newText=None): old = names.get(name_id) if new and (new != old): if not dry_run and not '!!!' in new: font_data.set_name_record(ttfont, name_id, new, addIfMissing='win') label = _NAME_ID_LABELS[name_id] oldText = '\'%s\'' % old if old else 'None' newText = newText or ('\'%s\'' % new) print '%s:\n old: %s\n new: %s' % (label, oldText, newText or new) label_change = _changes.get(label) if not label_change: label_change = {} _changes[label] = label_change new_val_change = label_change.get(new) if not new_val_change: new_val_change = {} label_change[new] = new_val_change old_val_fonts = new_val_change.get(old) if not old_val_fonts: old_val_fonts = [] new_val_change[old] = old_val_fonts old_val_fonts.append(noto_font.filepath)
def apply_android_specific_fixes(font): """Apply fixes needed for Android.""" # Set ascent, descent, and lineGap values to Android K values hhea = font["hhea"] hhea.ascent = 1900 hhea.descent = -500 hhea.lineGap = 0 # Remove combining keycap and the arrows from the cmap table: # https://github.com/google/roboto/issues/99 font_data.delete_from_cmap( font, [0x20E3, 0x2191, 0x2193] # COMBINING ENCLOSING KEYCAP # UPWARDS ARROW # DOWNWARDS ARROW ) # Drop tables not useful on Android for table in ["LTSH", "hdmx", "VDMX", "gasp"]: if table in font: del font[table] cmap = font["cmap"] cmap.tables = [t for t in cmap.tables if t.format == 12] assert cmap.tables, "No format 12 cmap found in font" # Set bold bits for Black (macStyle bit 0, fsSelection bit 5, subfamily) name_records = font_data.get_name_records(font) family_name = name_records[1] subfam_name = name_records[2] if family_name.endswith("Black"): font["head"].macStyle |= 1 << 0 font["OS/2"].fsSelection |= 1 << 5 font["OS/2"].fsSelection &= ~(1 << 6) new_subfam_name = ("Bold " + subfam_name) if subfam_name != "Regular" else "Bold" font_data.set_name_record(font, 2, new_subfam_name)
def apply_android_specific_fixes(font): """Apply fixes needed for Android.""" # Set ascent, descent, and lineGap values to Android K values hhea = font['hhea'] hhea.ascent = 1900 hhea.descent = -500 hhea.lineGap = 0 # Remove combining keycap and the arrows from the cmap table: # https://github.com/google/roboto/issues/99 font_data.delete_from_cmap(font, [ 0x20E3, # COMBINING ENCLOSING KEYCAP 0x2191, # UPWARDS ARROW 0x2193, # DOWNWARDS ARROW ]) # Drop tables not useful on Android for table in ['LTSH', 'hdmx', 'VDMX', 'gasp']: if table in font: del font[table] # Set bold bits for Black (macStyle bit 0, fsSelection bit 5, subfamily) name_records = font_data.get_name_records(font) family_name = name_records[1] subfam_name = name_records[2] if family_name.endswith('Black'): font['head'].macStyle |= (1 << 0) font['OS/2'].fsSelection |= (1 << 5) font['OS/2'].fsSelection &= ~(1 << 6) new_subfam_name = ( ('Bold ' + subfam_name) if subfam_name != 'Regular' else 'Bold') font_data.set_name_record(font, 2, new_subfam_name)
def apply_android_specific_fixes(font): """Apply fixes needed for Android.""" # Set ascent, descent, and lineGap values to Android K values hhea = font['hhea'] hhea.ascent = 1900 hhea.descent = -500 hhea.lineGap = 0 # Remove combining keycap and the arrows from the cmap table: # https://github.com/google/roboto/issues/99 font_data.delete_from_cmap( font, [ 0x20E3, # COMBINING ENCLOSING KEYCAP 0x2191, # UPWARDS ARROW 0x2193, # DOWNWARDS ARROW ]) # Drop tables not useful on Android for table in ['LTSH', 'hdmx', 'VDMX', 'gasp']: if table in font: del font[table] # Set bold bits for Black (macStyle bit 0, fsSelection bit 5, subfamily) name_records = font_data.get_name_records(font) family_name = name_records[1] subfam_name = name_records[2] if family_name.endswith('Black'): font['head'].macStyle |= (1 << 0) font['OS/2'].fsSelection |= (1 << 5) font['OS/2'].fsSelection &= ~(1 << 6) new_subfam_name = (('Bold ' + subfam_name) if subfam_name != 'Regular' else 'Bold') font_data.set_name_record(font, 2, new_subfam_name)
def fix_font(f, dstdir, version_info, autohint, dry_run): print '\n-----\nfont:', f font = ttLib.TTFont(f) fname = path.basename(f) expected_font_revision = get_revision(font, fname) if expected_font_revision != None: font_revision = font_data.printable_font_revision(font, 3) if font_revision != expected_font_revision: _alert('revision', font_revision, expected_font_revision) font['head'].fontRevision = float(expected_font_revision) names = font_data.get_name_records(font) NAME_ID = 5 font_version = names[NAME_ID] expected_version = ( 'Version %s;%s' % (expected_font_revision, version_info)) if font_version != expected_version: _alert('version string', font_version, expected_version) font_data.set_name_record(font, NAME_ID, expected_version) expected_upem = 2048 upem = font['head'].unitsPerEm if upem != expected_upem: print 'expected %d upem but got %d upem' % (expected_upem, upem) if _is_ui_metrics(fname): if upem == 2048: expected_ascent = 2163 expected_descent = -555 elif upem == 1000: expected_ascent = 1069 expected_descent = -293 else: raise Exception('no expected ui ascent/descent for upem: %d' % upem) font_ascent = font['hhea'].ascent font_descent = font['hhea'].descent if font_ascent != expected_ascent: _alert_and_check('ascent', font_ascent, expected_ascent, 2) font['hhea'].ascent = expected_ascent font['OS/2'].sTypoAscender = expected_ascent font['OS/2'].usWinAscent = expected_ascent if font_descent != expected_descent: _alert_and_check('descent', font_descent, expected_descent, 2) font['hhea'].descent = expected_descent font['OS/2'].sTypoDescender = expected_descent font['OS/2'].usWinDescent = -expected_descent tool_utils.ensure_dir_exists(path.join(dstdir, 'unhinted')) dst = path.join(dstdir, 'unhinted', fname) if dry_run: print 'dry run would write:\n "%s"' % dst else: font.save(dst) print 'wrote %s' % dst if autohint: autohint_font(dst, path.join(dstdir, 'hinted', fname), autohint, dry_run)
def update_version_and_revision(font): """Update version and revision numbers.""" version_number = roboto_data.get_version_number() version_record = 'Version %s; %d' % (version_number, date.today().year) font_data.set_name_record(font, 5, version_record) font['head'].fontRevision = float(version_number)
def apply_temporary_fixes(font): """Apply some temporary fixes.""" # Fix usWeight: font_name = font_data.font_name(font) weight = roboto_data.extract_weight_name(font_name) weight_number = roboto_data.WEIGHTS[weight] font['OS/2'].usWeightClass = weight_number # Set ascent, descent, and lineGap values to Android K values hhea = font['hhea'] hhea.ascent = 1900 hhea.descent = -500 hhea.lineGap = 0 # Copyright message font_data.set_name_record( font, 0, 'Copyright 2011 Google Inc. All Rights Reserved.')
def apply_temporary_fixes(font): """Apply some temporary fixes.""" # Fix usWeight: font_name = font_data.font_name(font) weight = noto_fonts.parse_weight(font_name) weight_number = noto_fonts.WEIGHTS[weight] font['OS/2'].usWeightClass = weight_number # Set ascent, descent, and lineGap values to Android K values hhea = font['hhea'] hhea.ascent = 1900 hhea.descent = -500 hhea.lineGap = 0 # Copyright message font_data.set_name_record( font, 0, 'Copyright 2011 Google Inc. All Rights Reserved.')
def fix_name_table(font): """Fix copyright and reversed values in the 'name' table.""" modified = False name_records = font_data.get_name_records(font) copyright_data = name_records[0] years = re.findall('20[0-9][0-9]', copyright_data) year = min(years) copyright_data = u'Copyright %s Google Inc. All Rights Reserved.' % year if copyright_data != name_records[0]: print 'Updated copyright message to "%s"' % copyright_data font_data.set_name_record(font, 0, copyright_data) modified = True for name_id in [1, 3, 4, 6]: record = name_records[name_id] for source in NAME_CORRECTIONS: if source in record: oldrecord = record record = record.replace(source, NAME_CORRECTIONS[source]) break if record != name_records[name_id]: font_data.set_name_record(font, name_id, record) print 'Updated name table record #%d from "%s" to "%s"' % ( name_id, oldrecord, record) modified = True trademark_names = ['Noto', 'Arimo', 'Tinos', 'Cousine'] trademark_name = None font_family = name_records[1] for name in trademark_names: if font_family.find(name) != -1: trademark_name = name break if not trademark_name: print 'no trademarked name in \'%s\'' % font_family else: trademark_line = TRADEMARK_TEMPLATE % trademark_name if name_records[7] != trademark_line: old_line = name_records[7] font_data.set_name_record(font, 7, trademark_line) modified = True print 'Updated name table record 7 from "%s" to "%s"' % ( old_line, trademark_line) if name_records[11] != NOTO_URL: font_data.set_name_record(font, 11, NOTO_URL) modified = True print 'Updated name table record 11 to "%s"' % NOTO_URL # TODO: check preferred family/subfamily(16&17) return modified
def fix_name_table(font): """Fix copyright and reversed values in the 'name' table.""" modified = False name_records = font_data.get_name_records(font) copyright_data = name_records[0] years = re.findall('20[0-9][0-9]', copyright_data) year = min(years) copyright_data = u'Copyright %s Google Inc. All Rights Reserved.' % year if copyright_data != name_records[0]: print 'Updated copyright message to "%s"' % copyright_data font_data.set_name_record(font, 0, copyright_data) modified = True for name_id in [1, 3, 4, 6]: record = name_records[name_id] for source in NAME_CORRECTIONS: if source in record: oldrecord = record record = record.replace(source, NAME_CORRECTIONS[source]) break if record != name_records[name_id]: font_data.set_name_record(font, name_id, record) print 'Updated name table record #%d from "%s" to "%s"' % ( name_id, oldrecord, record) modified = True trademark_names = ['Noto', 'Arimo', 'Tinos', 'Cousine'] trademark_name = None font_family = name_records[1] for name in trademark_names: if font_family.find(name) != -1: trademark_name = name break if not trademark_name: print 'no trademarked name in \'%s\'' % font_family else: trademark_line = TRADEMARK_TEMPLATE % trademark_name if name_records[7] != trademark_line: old_line = name_records[7] font_data.set_name_record(font, 7, trademark_line) modified = True print 'Updated name table record 7 from "%s" to "%s"' % (old_line, trademark_line) if name_records[11] != NOTO_URL: font_data.set_name_record(font, 11, NOTO_URL) modified = True print 'Updated name table record 11 to "%s"' % NOTO_URL # TODO: check preferred family/subfamily(16&17) return modified
def subset_font_cmap( srcname, dstname, exclude=None, include=None, bump_version=True): opt = _DEFAULT_OPTIONS font = subset.load_font(srcname, opt) target_charset = set(font_data.get_cmap(font).keys()) if include is not None: target_charset &= include if exclude is not None: target_charset -= exclude subsetter = subset.Subsetter(options=opt) subsetter.populate(unicodes=target_charset) subsetter.subset(font) if bump_version: # assume version string has 'uh' if unhinted, else hinted. revision, version_string = swat_license.get_bumped_version(font) font['head'].fontRevision = revision font_data.set_name_record(font, _VERSION_ID, version_string) subset.save_font(font, dstname, opt)
def fix_name_table(font): """Fix copyright and reversed values in the 'name' table.""" modified = False name_records = font_data.get_name_records(font) copyright_data = name_records[0] years = re.findall('20[0-9][0-9]', copyright_data) year = min(years) copyright_data = u'Copyright %s Google Inc. All Rights Reserved.' % year if copyright_data != name_records[0]: print 'Updated copyright message to "%s"' % copyright_data font_data.set_name_record(font, 0, copyright_data) modified = True for name_id in [1, 3, 4, 6]: record = name_records[name_id] for source in NAME_CORRECTIONS: if source in record: oldrecord = record record = record.replace(source, NAME_CORRECTIONS[source]) break if record != name_records[name_id]: font_data.set_name_record(font, name_id, record) print 'Updated name table record #%d from "%s" to "%s"' % ( name_id, oldrecord, record) modified = True if name_records[7] != TRADEMARK_LINE: font_data.set_name_record(font, 7, TRADEMARK_LINE) modified = True print 'Updated name table record 7 to "%s"' % TRADEMARK_LINE # TODO: check preferred family/subfamily(16&17) return modified
def apply_web_specific_fixes(font, family_name): """Apply fixes needed for web fonts.""" # Set OS/2 table values to old values os2 = font['OS/2'] os2.sTypoAscender = 1536 os2.sTypoDescender = -512 os2.sTypoLineGap = 102 os2.usWinAscent = 1946 os2.usWinDescent = 512 subfamily_name = font_data.get_name_records(font)[2].encode('ASCII') assert(subfamily_name in ['Thin', 'Thin Italic', 'Light', 'Light Italic', 'Regular', 'Italic', 'Medium', 'Medium Italic', 'Bold', 'Bold Italic', 'Black', 'Black Italic']) if 'Condensed' in font_data.get_name_records(font)[1]: family_name += ' Condensed' full_name = family_name + ' ' + subfamily_name # Family name font_data.set_name_record(font, 1, family_name) font_data.set_name_record(font, 16, family_name) # Unique identifier and full name font_data.set_name_record(font, 3, full_name) font_data.set_name_record(font, 4, full_name) font_data.set_name_record(font, 18, None) # PostScript name font_data.set_name_record( font, 6, (family_name+'-'+subfamily_name).replace(' ', ''))
def apply_web_specific_fixes(font, family_name): """Apply fixes needed for web fonts.""" # Set OS/2 table values to old values os2 = font['OS/2'] os2.sTypoAscender = 1536 os2.sTypoDescender = -512 os2.sTypoLineGap = 102 os2.usWinAscent = 1946 os2.usWinDescent = 512 subfamily_name = font_data.get_name_records(font)[2].encode('ASCII') assert(subfamily_name in ['Thin', 'Thin Italic', 'Light', 'Light Italic', 'Regular', 'Italic', 'Medium', 'Medium Italic', 'Bold', 'Bold Italic', 'Black', 'Black Italic']) if 'Condensed' in font_data.get_name_records(font)[1]: family_name += ' Condensed' full_name = family_name + ' ' + subfamily_name # Family, subfamily names font_data.set_name_record(font, 16, family_name) style_map = ['Regular', 'Bold', 'Italic', 'Bold Italic'] if subfamily_name in style_map: font_data.set_name_record(font, 1, family_name) else: weight = subfamily_name.split()[0] new_family_name = family_name if weight != 'Regular': new_family_name += ' ' + weight font_data.set_name_record(font, 1, new_family_name) # all weights outside regular and bold should only have subfamily # "Regular" or "Italic" italic = subfamily_name.endswith('Italic') font_data.set_name_record(font, 2, style_map[italic << 1]) # Unique identifier and full name font_data.set_name_record(font, 3, full_name) font_data.set_name_record(font, 4, full_name.replace(' Regular', '')) font_data.set_name_record(font, 18, None) # PostScript name font_data.set_name_record( font, 6, (family_name+'-'+subfamily_name).replace(' ', '')) # Copyright message font_data.set_name_record( font, 0, 'Copyright 2011 Google Inc. All Rights Reserved.')
def fix_font(f, dst_dir, rel_dir, version, version_info, autohint, dry_run): print '\n-----\nfont:', f font = ttLib.TTFont(f) relfont = _get_release_font(f, rel_dir) expected_font_revision = get_new_version(font, relfont, version) if expected_font_revision != None: font_revision = font_data.printable_font_revision(font, 3) if font_revision != expected_font_revision: _alert('revision', font_revision, expected_font_revision) font['head'].fontRevision = float(expected_font_revision) names = font_data.get_name_records(font) NAME_ID = 5 font_version = names[NAME_ID] expected_version = ( 'Version %s;%s' % (expected_font_revision, version_info)) if font_version != expected_version: _alert('version string', font_version, expected_version) font_data.set_name_record(font, NAME_ID, expected_version) expected_upem = 1000 upem = font['head'].unitsPerEm if upem != expected_upem: print 'expected %d upem but got %d upem' % (expected_upem, upem) if _is_ui_metrics(f): if upem == 2048: expected_ascent = 2163 expected_descent = -555 elif upem == 1000: expected_ascent = 1069 expected_descent = -293 else: raise Exception('no expected ui ascent/descent for upem: %d' % upem) font_ascent = font['hhea'].ascent font_descent = font['hhea'].descent if font_ascent != expected_ascent: _alert_and_check('ascent', font_ascent, expected_ascent, 2) font['hhea'].ascent = expected_ascent font['OS/2'].sTypoAscender = expected_ascent font['OS/2'].usWinAscent = expected_ascent if font_descent != expected_descent: _alert_and_check('descent', font_descent, expected_descent, -2) font['hhea'].descent = expected_descent font['OS/2'].sTypoDescender = expected_descent font['OS/2'].usWinDescent = -expected_descent tool_utils.ensure_dir_exists(path.join(dst_dir, 'unhinted')) fname = path.basename(f) udst = path.join(dst_dir, 'unhinted', fname) if dry_run: print 'dry run would write:\n "%s"' % udst else: font.save(udst) print 'wrote %s' % udst if autohint: hdst = path.join(dst_dir, 'hinted', fname) autohint_font(udst, hdst, autohint, dry_run)
def apply_web_specific_fixes(font, unhinted, family_name): """Apply fixes needed for web fonts.""" # Set OS/2 table values to old values os2 = font['OS/2'] os2.sTypoAscender = 1536 os2.sTypoDescender = -512 os2.sTypoLineGap = 102 os2.usWinAscent = 1946 os2.usWinDescent = 512 subfamily_name = font_data.get_name_records(font)[2].encode('ASCII') assert (subfamily_name in [ 'Thin', 'Thin Italic', 'Light', 'Light Italic', 'Regular', 'Italic', 'Medium', 'Medium Italic', 'Bold', 'Bold Italic', 'Black', 'Black Italic' ]) if 'Condensed' in font_data.get_name_records(font)[1]: family_name += ' Condensed' full_name = family_name if subfamily_name != 'Regular': full_name += ' ' + subfamily_name # Family, subfamily names font_data.set_name_record(font, 16, family_name) style_map = ['Regular', 'Bold', 'Italic', 'Bold Italic'] if subfamily_name in style_map: font_data.set_name_record(font, 1, family_name) else: weight = subfamily_name.split()[0] new_family_name = family_name if weight != 'Regular': new_family_name += ' ' + weight font_data.set_name_record(font, 1, new_family_name) # all weights outside regular and bold should only have subfamily # "Regular" or "Italic" italic = subfamily_name.endswith('Italic') font_data.set_name_record(font, 2, style_map[italic << 1]) # Unique identifier and full name font_data.set_name_record(font, 3, full_name) font_data.set_name_record(font, 4, full_name) font_data.set_name_record(font, 18, None) # PostScript name font_data.set_name_record(font, 6, (family_name + '-' + subfamily_name).replace( ' ', '')) # Copyright message font_data.set_name_record( font, 0, 'Copyright 2011 Google Inc. All Rights Reserved.') # hotpatch glyphs by swapping # https://github.com/google/roboto/issues/18 glyf = font['glyf'] tmp = glyf['chi'] glyf['chi'] = glyf['chi.alt'] glyf['chi.alt'] = tmp # make glyph orders consistent for feature copying # https://github.com/google/roboto/issues/71 glyph_order = font.getGlyphOrder() for i, glyph_name in enumerate(glyph_order): if glyph_name.endswith('.lnum'): new_name = glyph_name.replace('.lnum', '.pnum') glyph_order[i] = new_name font['glyf'][new_name] = font['glyf'][glyph_name] # append old name to glyph order so del succeeds glyph_order.append(glyph_name) del font['glyf'][glyph_name] # copy features from unhinted # https://github.com/google/roboto/pull/163 for table in ['GDEF', 'GPOS', 'GSUB']: font[table] = unhinted[table]
def apply_web_specific_fixes(font, family_name): """Apply fixes needed for web fonts.""" # Set OS/2 table values to old values os2 = font['OS/2'] os2.sTypoAscender = 1536 os2.sTypoDescender = -512 os2.sTypoLineGap = 102 os2.usWinAscent = 1946 os2.usWinDescent = 512 subfamily_name = font_data.get_name_records(font)[2].encode('ASCII') assert (subfamily_name in [ 'Thin', 'Thin Italic', 'Light', 'Light Italic', 'Regular', 'Italic', 'Medium', 'Medium Italic', 'Bold', 'Bold Italic', 'Black', 'Black Italic' ]) if 'Condensed' in font_data.get_name_records(font)[1]: family_name += ' Condensed' full_name = family_name + ' ' + subfamily_name # Family, subfamily names font_data.set_name_record(font, 16, family_name) style_map = ['Regular', 'Bold', 'Italic', 'Bold Italic'] if subfamily_name in style_map: font_data.set_name_record(font, 1, family_name) else: weight = subfamily_name.split()[0] font_data.set_name_record(font, 1, '%s %s' % (family_name, weight)) font_data.set_name_record(font, 2, style_map[macStyle]) # Unique identifier and full name font_data.set_name_record(font, 3, full_name) font_data.set_name_record(font, 4, full_name) font_data.set_name_record(font, 18, None) # PostScript name font_data.set_name_record(font, 6, (family_name + '-' + subfamily_name).replace( ' ', ''))
def apply_web_specific_fixes(font, family_name): """Apply fixes needed for web fonts.""" # Set OS/2 table values to old values os2 = font['OS/2'] os2.sTypoAscender = 1536 os2.sTypoDescender = -512 os2.sTypoLineGap = 102 os2.usWinAscent = 1946 os2.usWinDescent = 512 subfamily_name = font_data.get_name_records(font)[2].encode('ASCII') assert(subfamily_name in ['Thin', 'Thin Italic', 'Light', 'Light Italic', 'Regular', 'Italic', 'Medium', 'Medium Italic', 'Bold', 'Bold Italic', 'Black', 'Black Italic']) if 'Condensed' in font_data.get_name_records(font)[1]: family_name += ' Condensed' full_name = family_name + ' ' + subfamily_name # macStyle bold = subfamily_name.startswith(('Bold', 'Black')) italic = subfamily_name.endswith('Italic') macStyle = (italic << 1) | bold font['head'].macStyle = macStyle # Family, subfamily names font_data.set_name_record(font, 16, family_name) style_map = ['Regular', 'Bold', 'Italic', 'Bold Italic'] if subfamily_name in style_map: font_data.set_name_record(font, 1, family_name) else: weight = subfamily_name.split()[0] font_data.set_name_record(font, 1, '%s %s' % (family_name, weight)) font_data.set_name_record(font, 2, style_map[macStyle]) # Unique identifier and full name font_data.set_name_record(font, 3, full_name) font_data.set_name_record(font, 4, full_name) font_data.set_name_record(font, 18, None) # PostScript name font_data.set_name_record( font, 6, (family_name+'-'+subfamily_name).replace(' ', ''))
def apply_web_cros_common_fixes(font, unhinted, family_name): """Apply fixes needed for web and CrOS targets""" subfamily_name = font_data.get_name_records(font)[2].encode('ASCII') assert(subfamily_name in ['Thin', 'Thin Italic', 'Light', 'Light Italic', 'Regular', 'Italic', 'Medium', 'Medium Italic', 'Bold', 'Bold Italic', 'Black', 'Black Italic']) if 'Condensed' in font_data.get_name_records(font)[1]: family_name += ' Condensed' full_name = family_name if subfamily_name != 'Regular': full_name += ' ' + subfamily_name # Family, subfamily names font_data.set_name_record(font, 16, family_name) style_map = ['Regular', 'Bold', 'Italic', 'Bold Italic'] if subfamily_name in style_map: font_data.set_name_record(font, 1, family_name) else: weight = subfamily_name.split()[0] new_family_name = family_name if weight != 'Regular': new_family_name += ' ' + weight font_data.set_name_record(font, 1, new_family_name) # all weights outside regular and bold should only have subfamily # "Regular" or "Italic" italic = subfamily_name.endswith('Italic') font_data.set_name_record(font, 2, style_map[italic << 1]) # Unique identifier and full name font_data.set_name_record(font, 3, full_name) font_data.set_name_record(font, 4, full_name) font_data.set_name_record(font, 18, None) # PostScript name font_data.set_name_record( font, 6, (family_name+'-'+subfamily_name).replace(' ', '')) # Copyright message font_data.set_name_record( font, 0, 'Copyright 2011 Google Inc. All Rights Reserved.') # hotpatch glyphs by swapping # https://github.com/google/roboto/issues/18 glyf = font['glyf'] tmp = glyf['chi'] glyf['chi'] = glyf['chi.alt'] glyf['chi.alt'] = tmp # make glyph orders consistent for feature copying # https://github.com/google/roboto/issues/71 glyph_order = font.getGlyphOrder() for i, glyph_name in enumerate(glyph_order): if glyph_name.endswith('.lnum'): new_name = glyph_name.replace('.lnum', '.pnum') glyph_order[i] = new_name font['glyf'][new_name] = font['glyf'][glyph_name] # append old name to glyph order so del succeeds glyph_order.append(glyph_name) del font['glyf'][glyph_name] # copy features from unhinted # https://github.com/google/roboto/pull/163 for table in ['GDEF', 'GPOS', 'GSUB']: font[table] = unhinted[table]
def fix_name_table(font): """Fix copyright and reversed values in the 'name' table.""" modified = False name_records = font_data.get_name_records(font) copyright_data = name_records[0] years = re.findall("20[0-9][0-9]", copyright_data) year = min(years) copyright_data = u"Copyright %s Google Inc. All Rights Reserved." % year if copyright_data != name_records[0]: print('Updated copyright message to "%s"' % copyright_data) font_data.set_name_record(font, 0, copyright_data) modified = True for name_id in [1, 3, 4, 6]: record = name_records[name_id] for source in NAME_CORRECTIONS: if source in record: oldrecord = record record = record.replace(source, NAME_CORRECTIONS[source]) break if record != name_records[name_id]: font_data.set_name_record(font, name_id, record) print( 'Updated name table record #%d from "%s" to "%s"' % (name_id, oldrecord, record) ) modified = True trademark_names = ["Noto", "Arimo", "Tinos", "Cousine"] trademark_name = None font_family = name_records[1] for name in trademark_names: if font_family.find(name) != -1: trademark_name = name break if not trademark_name: print("no trademarked name in '%s'" % font_family) else: trademark_line = TRADEMARK_TEMPLATE % trademark_name if name_records[7] != trademark_line: old_line = name_records[7] font_data.set_name_record(font, 7, trademark_line) modified = True print( 'Updated name table record 7 from "%s" to "%s"' % (old_line, trademark_line) ) if name_records[11] != NOTO_URL: font_data.set_name_record(font, 11, NOTO_URL) modified = True print('Updated name table record 11 to "%s"' % NOTO_URL) if name_records[_LICENSE_ID] != _SIL_LICENSE: font_data.set_name_record(font, _LICENSE_ID, _SIL_LICENSE) modified = True print("Updated license id") if name_records[_LICENSE_URL_ID] != _SIL_LICENSE_URL: font_data.set_name_record(font, _LICENSE_URL_ID, _SIL_LICENSE_URL) modified = True print("Updated license url") # TODO: check preferred family/subfamily(16&17) return modified