1ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta#!/usr/bin/env python
2ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta
3ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta# Copyright (C) 2014 The Android Open Source Project
4ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta#
5ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta# Licensed under the Apache License, Version 2.0 (the 'License');
6ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta# you may not use this file except in compliance with the License.
7ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta# You may obtain a copy of the License at
8ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta#
9ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta#      http://www.apache.org/licenses/LICENSE-2.0
10ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta#
11ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta# Unless required by applicable law or agreed to in writing, software
12ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta# distributed under the License is distributed on an 'AS IS' BASIS,
13ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta# See the License for the specific language governing permissions and
15ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta# limitations under the License.
16ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta
17ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta"""
1849a60d4d6d1a512f1c193b38b2e7c8153f1150d9Deepanshu GuptaRename the PS name of all fonts in the input directories and copy them to the
19ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Guptaoutput directory.
20ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta
2149a60d4d6d1a512f1c193b38b2e7c8153f1150d9Deepanshu GuptaUsage: build_font.py /path/to/input_fonts1/ /path/to/input_fonts2/ /path/to/output_fonts/
22ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta
23ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta"""
24ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta
257ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Guptaimport glob
267ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Guptafrom multiprocessing import Pool
277ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Guptaimport os
287ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Guptaimport re
297ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Guptaimport shutil
30ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Guptaimport sys
317ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Guptaimport xml.etree.ElementTree as etree
327ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
337ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta# Prevent .pyc files from being created.
347ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Guptasys.dont_write_bytecode = True
357ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
36ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta# fontTools is available at platform/external/fonttools
37ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Guptafrom fontTools import ttx
38d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta
39d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta# global variable
40d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Guptadest_dir = '/tmp'
41ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta
427ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
437ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Guptaclass FontInfo(object):
447ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  family = None
457ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  style = None
467ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  version = None
477ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  ends_in_regular = False
487ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  fullname = None
497ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
507ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
517ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Guptaclass InvalidFontException(Exception):
527ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  pass
537ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
547ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
557ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta# These constants represent the value of nameID parameter in the namerecord for
567ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta# different information.
577ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta# see http://scripts.sil.org/cms/scripts/page.php?item_id=IWS-Chapter08#3054f18b
587ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu GuptaNAMEID_FAMILY = 1
597ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu GuptaNAMEID_STYLE = 2
607ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu GuptaNAMEID_FULLNAME = 4
617ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu GuptaNAMEID_VERSION = 5
627ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
637ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
64ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Guptadef main(argv):
6549a60d4d6d1a512f1c193b38b2e7c8153f1150d9Deepanshu Gupta  if len(argv) < 2:
6649a60d4d6d1a512f1c193b38b2e7c8153f1150d9Deepanshu Gupta    sys.exit('Usage: build_font.py /path/to/input_fonts/ /path/to/out/dir/')
67d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta  for directory in argv:
68d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    if not os.path.isdir(directory):
69d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta      sys.exit(directory + ' is not a valid directory')
70d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta  global dest_dir
7149a60d4d6d1a512f1c193b38b2e7c8153f1150d9Deepanshu Gupta  dest_dir = argv[-1]
7249a60d4d6d1a512f1c193b38b2e7c8153f1150d9Deepanshu Gupta  src_dirs = argv[:-1]
73ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta  cwd = os.getcwd()
7449a60d4d6d1a512f1c193b38b2e7c8153f1150d9Deepanshu Gupta  os.chdir(dest_dir)
75ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta  files = glob.glob('*')
76ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta  for filename in files:
77ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta    os.remove(filename)
78ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta  os.chdir(cwd)
79d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta  input_fonts = list()
8049a60d4d6d1a512f1c193b38b2e7c8153f1150d9Deepanshu Gupta  for src_dir in src_dirs:
8146eff27c32166f007132bfa5f4effc3c306b5f47Deepanshu Gupta    for dirname, dirnames, filenames in os.walk(src_dir):
8246eff27c32166f007132bfa5f4effc3c306b5f47Deepanshu Gupta      for filename in filenames:
837ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        input_path = os.path.join(dirname, filename)
847ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        extension = os.path.splitext(filename)[1].lower()
857ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        if extension == '.ttf':
867ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta          input_fonts.append(input_path)
877ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        elif extension == '.xml':
887ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta          shutil.copy(input_path, dest_dir)
8946eff27c32166f007132bfa5f4effc3c306b5f47Deepanshu Gupta      if '.git' in dirnames:
907ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        # don't go into any .git directories.
917ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        dirnames.remove('.git')
92d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta  # Create as many threads as the number of CPUs
93d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta  pool = Pool(processes=None)
94d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta  pool.map(convert_font, input_fonts)
95d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta
96d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta
97d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Guptadef convert_font(input_path):
98d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta  filename = os.path.basename(input_path)
99d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta  print 'Converting font: ' + filename
100d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta  # the path to the output file. The file name is the fontfilename.ttx
101d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta  ttx_path = os.path.join(dest_dir, filename)
102d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta  ttx_path = ttx_path[:-1] + 'x'
103d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta  try:
104d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    # run ttx to generate an xml file in the output folder which represents all
105d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    # its info
106d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    ttx_args = ['-q', '-d', dest_dir, input_path]
107d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    ttx.main(ttx_args)
108d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    # now parse the xml file to change its PS name.
109d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    tree = etree.parse(ttx_path)
110d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    root = tree.getroot()
111d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    for name in root.iter('name'):
1127ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      update_tag(name, get_font_info(name))
1137ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta    tree.write(ttx_path, xml_declaration=True, encoding='utf-8')
114d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    # generate the udpated font now.
115d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    ttx_args = ['-q', '-d', dest_dir, ttx_path]
116d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    ttx.main(ttx_args)
117d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta  except InvalidFontException:
118d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    # In case of invalid fonts, we exit.
119d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    print filename + ' is not a valid font'
120d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    raise
121d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta  except Exception as e:
122d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    print 'Error converting font: ' + filename
123d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    print e
124d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    # Some fonts are too big to be handled by the ttx library.
125d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    # Just copy paste them.
126d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    shutil.copy(input_path, dest_dir)
127d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta  try:
128d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    # delete the temp ttx file is it exists.
129d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    os.remove(ttx_path)
130d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta  except OSError:
131d23417ab5d1c623977d11b499c7f3bf2d5fb83b4Deepanshu Gupta    pass
132ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta
1337ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
134ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Guptadef get_font_info(tag):
1357ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  """ Returns a list of FontInfo representing the various sets of namerecords
1367ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      found in the name table of the font. """
1377ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  fonts = []
1387ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  font = None
1397ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  last_name_id = sys.maxint
140ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta  for namerecord in tag.iter('namerecord'):
141ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta    if 'nameID' in namerecord.attrib:
1427ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      name_id = int(namerecord.attrib['nameID'])
1437ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      # A new font should be created for each platform, encoding and language
1447ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      # id. But, since the nameIDs are sorted, we use the easy approach of
1457ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      # creating a new one when the nameIDs reset.
1467ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      if name_id <= last_name_id and font is not None:
1477ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        fonts.append(font)
1487ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        font = None
1497ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      last_name_id = name_id
1507ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      if font is None:
1517ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        font = FontInfo()
1527ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      if name_id == NAMEID_FAMILY:
1537ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        font.family = namerecord.text.strip()
1547ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      if name_id == NAMEID_STYLE:
1557ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        font.style = namerecord.text.strip()
1567ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      if name_id == NAMEID_FULLNAME:
1577ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        font.ends_in_regular = ends_in_regular(namerecord.text)
1587ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        font.fullname = namerecord.text.strip()
1597ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      if name_id == NAMEID_VERSION:
1607ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        font.version = get_version(namerecord.text)
1617ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  if font is not None:
1627ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta    fonts.append(font)
1637ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  return fonts
1647ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
1657ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
1667ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Guptadef update_tag(tag, fonts):
1677ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  last_name_id = sys.maxint
1687ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  fonts_iterator = fonts.__iter__()
1697ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  font = None
170ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta  for namerecord in tag.iter('namerecord'):
171ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta    if 'nameID' in namerecord.attrib:
1727ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      name_id = int(namerecord.attrib['nameID'])
1737ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      if name_id <= last_name_id:
1747ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        font = fonts_iterator.next()
1757ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        font = update_font_name(font)
1767ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      last_name_id = name_id
1777ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      if name_id == NAMEID_FAMILY:
1787ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        namerecord.text = font.family
1797ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      if name_id == NAMEID_FULLNAME:
1807ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta        namerecord.text = font.fullname
1817ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
1827ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
1837ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Guptadef update_font_name(font):
1847ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  """ Compute the new font family name and font fullname. If the font has a
1857ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      valid version, it's sanitized and appended to the font family name. The
1867ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      font fullname is then created by joining the new family name and the
1877ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      style. If the style is 'Regular', it is appended only if the original font
1887ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      had it. """
1897ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  if font.family is None or font.style is None:
1907ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta    raise InvalidFontException('Font doesn\'t have proper family name or style')
1917ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  if font.version is not None:
1927ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta    new_family = font.family + font.version
1937ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  else:
1947ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta    new_family = font.family
1957ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  if font.style is 'Regular' and not font.ends_in_regular:
1967ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta    font.fullname = new_family
1977ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  else:
1987ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta    font.fullname = new_family + ' ' + font.style
1997ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  font.family = new_family
2007ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  return font
2017ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
2027ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
2037ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Guptadef ends_in_regular(string):
2047ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  """ According to the specification, the font fullname should not end in
2057ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      'Regular' for plain fonts. However, some fonts don't obey this rule. We
2067ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta      keep the style info, to minimize the diff. """
2077ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  string = string.strip().split()[-1]
2087ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  return string is 'Regular'
209ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta
210ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta
211ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Guptadef get_version(string):
212ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta  string = string.strip()
213d654b6f981dbef7c6a6a57c8725fc9f510dd7a09Deepanshu Gupta  # The spec says that the version string should start with "Version ". But not
214d654b6f981dbef7c6a6a57c8725fc9f510dd7a09Deepanshu Gupta  # all fonts do. So, we return the complete string if it doesn't start with
215d654b6f981dbef7c6a6a57c8725fc9f510dd7a09Deepanshu Gupta  # the prefix, else we return the rest of the string after sanitizing it.
216d654b6f981dbef7c6a6a57c8725fc9f510dd7a09Deepanshu Gupta  prefix = 'Version '
217d654b6f981dbef7c6a6a57c8725fc9f510dd7a09Deepanshu Gupta  if string.startswith(prefix):
218d654b6f981dbef7c6a6a57c8725fc9f510dd7a09Deepanshu Gupta    string = string[len(prefix):]
219d654b6f981dbef7c6a6a57c8725fc9f510dd7a09Deepanshu Gupta  return sanitize(string)
220ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta
2217ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
2227ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Guptadef sanitize(string):
223d654b6f981dbef7c6a6a57c8725fc9f510dd7a09Deepanshu Gupta  """ Remove non-standard chars. """
2247ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta  return re.sub(r'[^\w-]+', '', string)
2257ea293bc6a31c5b1bf3b2663376a39dc3a79b671Deepanshu Gupta
226ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Guptaif __name__ == '__main__':
227ad3f2883112102c5ca4f0ce5d8f9e9df62a62f57Deepanshu Gupta  main(sys.argv[1:])
228