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