Merge "Add a script to rename fonts for SDK."
diff --git a/tools/layoutlib/rename_font/README b/tools/layoutlib/rename_font/README
new file mode 100644
index 0000000..600b756
--- /dev/null
+++ b/tools/layoutlib/rename_font/README
@@ -0,0 +1,9 @@
+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.
diff --git a/tools/layoutlib/rename_font/Roboto-Regular.ttf b/tools/layoutlib/rename_font/Roboto-Regular.ttf
new file mode 100644
index 0000000..7469063
--- /dev/null
+++ b/tools/layoutlib/rename_font/Roboto-Regular.ttf
Binary files differ
diff --git a/tools/layoutlib/rename_font/build_font.py b/tools/layoutlib/rename_font/build_font.py
new file mode 100755
index 0000000..ea3dccc
--- /dev/null
+++ b/tools/layoutlib/rename_font/build_font.py
@@ -0,0 +1,121 @@
+#!/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:])
diff --git a/tools/layoutlib/rename_font/test.py b/tools/layoutlib/rename_font/test.py
new file mode 100755
index 0000000..d4c86cb
--- /dev/null
+++ b/tools/layoutlib/rename_font/test.py
@@ -0,0 +1,44 @@
+#!/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()