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

Commit 779b59ce authored by Deepanshu Gupta's avatar Deepanshu Gupta Committed by Android (Google) Code Review
Browse files

Merge "Add a script to rename fonts for SDK."

parents 4b0ec7e9 ad3f2883
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
This tool is used to rename the PS name encoded inside the ttf font that we ship
with the SDK. There is bug in Java that returns incorrect results for
java.awt.Font#layoutGlyphVector() if two fonts with same name but differnt
versions are loaded. As a workaround, we rename all the fonts that we ship with
the SDK by appending the font version to its name.


The build_font.py copies all files from input_dir to output_dir while renaming
the font files (*.ttf) in the process.
+112 KiB

File added.

No diff preview for this file type.

+121 −0
Original line number Diff line number Diff line
#!/usr/bin/env python

# Copyright (C) 2014 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Rename the PS name of all fonts in the input directory and copy them to the
output directory.

Usage: build_font.py /path/to/input_fonts/ /path/to/output_fonts/

"""

import sys
# fontTools is available at platform/external/fonttools
from fontTools import ttx
import re
import os
from lxml import etree
import shutil
import glob

def main(argv):
  if len(argv) != 2:
    print "Usage: build_font.py /path/to/input_fonts/ /path/to/out/dir/"
    sys.exit(1)
  if not os.path.isdir(argv[0]):
    print argv[0] + "is not a valid directory"
    sys.exit(1)
  if not os.path.isdir(argv[1]):
    print argv[1] + "is not a valid directory"
    sys.exit(1)
  cwd = os.getcwd()
  os.chdir(argv[1])
  files = glob.glob('*')
  for filename in files:
    os.remove(filename)
  os.chdir(cwd)
  for filename in os.listdir(argv[0]):
    if not os.path.splitext(filename)[1].lower() == ".ttf":
      shutil.copy(os.path.join(argv[0], filename), argv[1])
      continue
    print os.path.join(argv[0], filename)
    old_ttf_path = os.path.join(argv[0], filename)
    # run ttx to generate an xml file in the output folder which represents all
    # its info
    ttx_args = ["-d", argv[1], old_ttf_path]
    ttx.main(ttx_args)
    # the path to the output file. The file name is the fontfilename.ttx
    ttx_path = os.path.join(argv[1], filename)
    ttx_path = ttx_path[:-1] + "x"
    # now parse the xml file to change its PS name.
    tree = etree.parse(ttx_path)
    encoding = tree.docinfo.encoding
    root = tree.getroot()
    for name in root.iter('name'):
      [old_ps_name, version] = get_font_info(name)
      new_ps_name = old_ps_name + version
      update_name(name, new_ps_name)
    tree.write(ttx_path, xml_declaration=True, encoding=encoding )
    # generate the udpated font now.
    ttx_args = ["-d", argv[1], ttx_path]
    ttx.main(ttx_args)
    # delete the temp ttx file.
    os.remove(ttx_path)

def get_font_info(tag):
  ps_name = None
  ps_version = 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:
            sys.exit('found multiple possibilities of the font name')
        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):
            sys.exit('found multiple possibilities of the font version')
        else:
          ps_version = get_version(namerecord.text)
  if ps_name is not None and ps_version is not None:
    return [ps_name, ps_version]
  sys.exit('didn\'t find the font name or version')


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 sanitize(string):
  return re.sub(r'[^\w-]+', '', string)

def get_version(string):
  # The string must begin with "Version n.nn "
  # to extract n.nn, we return the second entry in the split strings.
  string = string.strip()
  if not string.startswith("Version "):
    sys.exit('mal-formed font version')
  return sanitize(string.split()[1])

if __name__ == '__main__':
  main(sys.argv[1:])
+44 −0
Original line number Diff line number Diff line
#!/usr/bin/env python

"""Tests build_font.py by renaming a font.

The test copies Roboto-Regular.ttf to a tmp directory and ask build_font.py to rename it and put in another dir.
We then use ttx to dump the new font to its xml and check if rename was successful

To test locally, use:
PYTHONPATH="$PYTHONPATH:/path/to/android/checkout/external/fonttools/Lib" ./test.py
"""

import unittest
import build_font

from fontTools import ttx
import os
from lxml import etree
import shutil
import tempfile

class MyTest(unittest.TestCase):
  def test(self):
    font_name = "Roboto-Regular.ttf"
    srcdir = tempfile.mkdtemp()
    print "srcdir: " + srcdir
    shutil.copy(font_name, srcdir)
    destdir = tempfile.mkdtemp()
    print "destdir: " + destdir
    self.assertTrue(build_font.main([srcdir, destdir]) is None)
    out_path = os.path.join(destdir, font_name)
    ttx.main([out_path])
    ttx_path = out_path[:-1] + "x"
    tree = etree.parse(ttx_path)
    root = tree.getroot()
    name_tag = root.find('name')
    [f_name, f_version] = build_font.get_font_info(name_tag)
    shutil.rmtree(srcdir)
    shutil.rmtree(destdir)
    self.assertEqual(f_name, "Roboto-Regular1200310")



if __name__ == '__main__':
  unittest.main()