| # -*- coding: utf-8 -*- |
| # Copyright 2010-2015, Google Inc. |
| # All rights reserved. |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions are |
| # met: |
| # |
| # * Redistributions of source code must retain the above copyright |
| # notice, this list of conditions and the following disclaimer. |
| # * Redistributions in binary form must reproduce the above |
| # copyright notice, this list of conditions and the following disclaimer |
| # in the documentation and/or other materials provided with the |
| # distribution. |
| # * Neither the name of Google Inc. nor the names of its |
| # contributors may be used to endorse or promote products derived from |
| # this software without specific prior written permission. |
| # |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| """Generates subset font. |
| |
| 1. Corrects characters from .svg files in given directory. |
| Only text nodes in <text> element are taken into account. |
| 2. Make subset font which contains only the characters corrected above. |
| """ |
| |
| import logging |
| import optparse |
| import os |
| import shutil |
| import subprocess |
| import sys |
| import tempfile |
| from xml.etree import cElementTree as ElementTree |
| |
| from build_tools import util |
| |
| |
| def ExtractCharactersFromSvgFile(svg_file): |
| result = set() |
| for text in ElementTree.parse(svg_file).findall( |
| './/{http://www.w3.org/2000/svg}text'): |
| if text.text: |
| result.update(tuple(text.text)) # Split into characters. |
| logging.debug('%s: %s', svg_file, result) |
| return result |
| |
| |
| def ExtractCharactersFromDirectory(svg_paths): |
| result = set() |
| for dirpath, _, filenames in util.WalkFileContainers(svg_paths): |
| for filename in filenames: |
| if os.path.splitext(filename)[1] != '.svg': |
| # Do nothing for files other than svg. |
| continue |
| result.update(ExtractCharactersFromSvgFile( |
| os.path.join(dirpath, filename))) |
| return list(result) |
| |
| |
| def MakeSubsetFont(fonttools_path, unicodes, input_font, output_font): |
| """Makes subset font using fontTools toolchain. |
| |
| Args: |
| fonttools_path: Path to fontTools library. |
| unicodes: A list of unicode characters of which glyph should be in |
| the output. |
| input_font: Path to input font. |
| output_font: Path to output font. |
| """ |
| if not unicodes: |
| # subset.py requires at least one unicode character. |
| logging.debug('No unicode character is specified. Use "A" as stub.') |
| unicodes = [u'A'] |
| |
| tempdir = tempfile.mkdtemp() |
| try: |
| # fontTools's output file name is fixed (input file path + '.subset'). |
| # To get result with specified file name, copy the input font |
| # to temporary directory and copy the result with renaming. |
| shutil.copy(input_font, tempdir) |
| temp_input_font = os.path.join(tempdir, os.path.basename(input_font)) |
| commands = ['python', os.path.join(fonttools_path, 'subset.py'), |
| temp_input_font] |
| commands.extend(['U+%08x' % ord(char) for char in unicodes]) |
| env = os.environ.copy() |
| # In fontTools toolchain, "from fontTools import XXXX" is executed. |
| # In order for successfull import, add parent directory of the toolchain |
| # into PYTHONPATH. |
| env['PYTHONPATH'] += ':%s' % os.path.join(fonttools_path, '..') |
| if subprocess.call(commands, env=env) != 0: |
| sys.exit(1) |
| shutil.copyfile('%s.subset' % temp_input_font, output_font) |
| finally: |
| shutil.rmtree(tempdir) |
| |
| |
| def ParseOptions(): |
| """Parses options.""" |
| parser = optparse.OptionParser() |
| parser.add_option('--svg_paths', dest='svg_paths', |
| help='Comma separated paths to a directory or' |
| ' a .zip file containing .svg files.') |
| parser.add_option('--input_font', dest='input_font', |
| help='Path to the input font.') |
| parser.add_option('--output_font', dest='output_font', |
| help='Path to the output font.') |
| parser.add_option('--fonttools_path', dest='fonttools_path', |
| help='Path to fontTools toolchain.') |
| parser.add_option('--verbose', dest='verbose', |
| help='Verbosity') |
| return parser.parse_args()[0] |
| |
| |
| def main(): |
| logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s') |
| |
| options = ParseOptions() |
| if options.verbose: |
| logging.getLogger().setLevel(logging.DEBUG) |
| unicodes = ExtractCharactersFromDirectory(options.svg_paths) |
| MakeSubsetFont(options.fonttools_path, unicodes, |
| options.input_font, options.output_font) |
| |
| |
| if __name__ == '__main__': |
| main() |
| |