Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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)
Ejemplo n.º 8
0
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.')
Ejemplo n.º 9
0
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.')
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
  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)
Ejemplo n.º 13
0
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)
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
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(' ', ''))
Ejemplo n.º 16
0
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.')
Ejemplo n.º 17
0
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)
Ejemplo n.º 18
0
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]
Ejemplo n.º 19
0
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(
                                  ' ', ''))
Ejemplo n.º 20
0
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(' ', ''))
Ejemplo n.º 21
0
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]
Ejemplo n.º 22
0
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