Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5414f83d authored by Deepanshu Gupta's avatar Deepanshu Gupta Committed by Android Git Automerger
Browse files

am d2829b49: am 432d16f9: Change font family name. [DO NOT MERGE]

* commit 'd2829b49':
  Change font family name. [DO NOT MERGE]
parents 5acf782c d2829b49
Loading
Loading
Loading
Loading
+117 −47
Original line number Diff line number Diff line
@@ -22,19 +22,45 @@ Usage: build_font.py /path/to/input_fonts1/ /path/to/input_fonts2/ /path/to/outp

"""

import glob
from multiprocessing import Pool
import os
import re
import shutil
import sys
import xml.etree.ElementTree as etree

# Prevent .pyc files from being created.
sys.dont_write_bytecode = True

# fontTools is available at platform/external/fonttools
from fontTools import ttx
import re
import os
import xml.etree.ElementTree as etree
import shutil
import glob
from multiprocessing import Pool

# global variable
dest_dir = '/tmp'


class FontInfo(object):
  family = None
  style = None
  version = None
  ends_in_regular = False
  fullname = None


class InvalidFontException(Exception):
  pass


# These constants represent the value of nameID parameter in the namerecord for
# different information.
# see http://scripts.sil.org/cms/scripts/page.php?item_id=IWS-Chapter08#3054f18b
NAMEID_FAMILY = 1
NAMEID_STYLE = 2
NAMEID_FULLNAME = 4
NAMEID_VERSION = 5


def main(argv):
  if len(argv) < 2:
    sys.exit('Usage: build_font.py /path/to/input_fonts/ /path/to/out/dir/')
@@ -56,9 +82,9 @@ def main(argv):
      for filename in filenames:
        input_path = os.path.join(dirname, filename)
        extension = os.path.splitext(filename)[1].lower()
          if (extension == '.ttf'):
        if extension == '.ttf':
          input_fonts.append(input_path)
          elif (extension == '.xml'):
        elif extension == '.xml':
          shutil.copy(input_path, dest_dir)
      if '.git' in dirnames:
        # don't go into any .git directories.
@@ -68,9 +94,6 @@ def main(argv):
  pool.map(convert_font, input_fonts)


class InvalidFontException(Exception):
  pass

def convert_font(input_path):
  filename = os.path.basename(input_path)
  print 'Converting font: ' + filename
@@ -86,10 +109,7 @@ def convert_font(input_path):
    tree = etree.parse(ttx_path)
    root = tree.getroot()
    for name in root.iter('name'):
      [old_ps_name, version] = get_font_info(name)
      if old_ps_name is not None and version is not None:
        new_ps_name = old_ps_name + version
        update_name(name, new_ps_name)
      update_tag(name, get_font_info(name))
    tree.write(ttx_path, xml_declaration=True, encoding='utf-8')
    # generate the udpated font now.
    ttx_args = ['-q', '-d', dest_dir, ttx_path]
@@ -110,37 +130,83 @@ def convert_font(input_path):
  except OSError:
    pass


def get_font_info(tag):
  ps_name = None
  ps_version = None
  """ Returns a list of FontInfo representing the various sets of namerecords
      found in the name table of the font. """
  fonts = []
  font = None
  last_name_id = sys.maxint
  for namerecord in tag.iter('namerecord'):
    if 'nameID' in namerecord.attrib:
      name_id = int(namerecord.attrib['nameID'])
      # A new font should be created for each platform, encoding and language
      # id. But, since the nameIDs are sorted, we use the easy approach of
      # creating a new one when the nameIDs reset.
      if name_id <= last_name_id and font is not None:
        fonts.append(font)
        font = None
      last_name_id = name_id
      if font is None:
        font = FontInfo()
      if name_id == NAMEID_FAMILY:
        font.family = namerecord.text.strip()
      if name_id == NAMEID_STYLE:
        font.style = namerecord.text.strip()
      if name_id == NAMEID_FULLNAME:
        font.ends_in_regular = ends_in_regular(namerecord.text)
        font.fullname = namerecord.text.strip()
      if name_id == NAMEID_VERSION:
        font.version = get_version(namerecord.text)
  if font is not None:
    fonts.append(font)
  return fonts


def update_tag(tag, fonts):
  last_name_id = sys.maxint
  fonts_iterator = fonts.__iter__()
  font = None
  for namerecord in tag.iter('namerecord'):
    if 'nameID' in namerecord.attrib:
      # if the tag has nameID=6, it is the postscript name of the font.
      # see: http://scripts.sil.org/cms/scripts/page.php?item_id=IWS-Chapter08#3054f18b
      if namerecord.attrib['nameID'] == '6':
        if ps_name is not None:
          if not sanitize(namerecord.text) == ps_name:
            raise InvalidFontException('found multiple possibilities of the font name')
      name_id = int(namerecord.attrib['nameID'])
      if name_id <= last_name_id:
        font = fonts_iterator.next()
        font = update_font_name(font)
      last_name_id = name_id
      if name_id == NAMEID_FAMILY:
        namerecord.text = font.family
      if name_id == NAMEID_FULLNAME:
        namerecord.text = font.fullname


def update_font_name(font):
  """ Compute the new font family name and font fullname. If the font has a
      valid version, it's sanitized and appended to the font family name. The
      font fullname is then created by joining the new family name and the
      style. If the style is 'Regular', it is appended only if the original font
      had it. """
  if font.family is None or font.style is None:
    raise InvalidFontException('Font doesn\'t have proper family name or style')
  if font.version is not None:
    new_family = font.family + font.version
  else:
          ps_name = sanitize(namerecord.text)
      # nameID=5 means the font version
      if namerecord.attrib['nameID'] == '5':
        if ps_version is not None:
          if not ps_version == get_version(namerecord.text):
            raise InvalidFontException('found multiple possibilities of the font version')
    new_family = font.family
  if font.style is 'Regular' and not font.ends_in_regular:
    font.fullname = new_family
  else:
          ps_version = get_version(namerecord.text)
  return [ps_name, ps_version]
    font.fullname = new_family + ' ' + font.style
  font.family = new_family
  return font


def update_name(tag, name):
  for namerecord in tag.iter('namerecord'):
    if 'nameID' in namerecord.attrib:
      if namerecord.attrib['nameID'] == '6':
        namerecord.text = name
def ends_in_regular(string):
  """ According to the specification, the font fullname should not end in
      'Regular' for plain fonts. However, some fonts don't obey this rule. We
      keep the style info, to minimize the diff. """
  string = string.strip().split()[-1]
  return string is 'Regular'

def sanitize(string):
  return re.sub(r'[^\w-]+', '', string)

def get_version(string):
  # The string must begin with 'Version n.nn '
@@ -150,5 +216,9 @@ def get_version(string):
    raise InvalidFontException('mal-formed font version')
  return sanitize(string.split()[1])


def sanitize(string):
  return re.sub(r'[^\w-]+', '', string)

if __name__ == '__main__':
  main(sys.argv[1:])
+3 −2
Original line number Diff line number Diff line
@@ -33,10 +33,11 @@ class MyTest(unittest.TestCase):
    tree = etree.parse(ttx_path)
    root = tree.getroot()
    name_tag = root.find('name')
    [f_name, f_version] = build_font.get_font_info(name_tag)
    fonts = build_font.get_font_info(name_tag)
    shutil.rmtree(srcdir)
    shutil.rmtree(destdir)
    self.assertEqual(f_name, "Roboto-Regular1200310")
    self.assertEqual(fonts[0].family, "Roboto1200310")
    self.assertEqual(fonts[0].fullname, "Roboto1200310 Regular")