2019-07-17 08:35:02 +00:00
|
|
|
#!/usr/bin/env python3
|
2015-02-20 22:58:34 +00:00
|
|
|
# Copyright 2015 Google, Inc. All Rights Reserved.
|
|
|
|
#
|
|
|
|
# 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.
|
|
|
|
#
|
|
|
|
# Google Author(s): Doug Felt
|
|
|
|
|
2017-09-14 20:18:24 +00:00
|
|
|
from __future__ import print_function
|
2015-02-20 22:58:34 +00:00
|
|
|
import argparse
|
|
|
|
import os
|
|
|
|
import os.path
|
|
|
|
import re
|
|
|
|
import sys
|
|
|
|
|
|
|
|
from fontTools import ttx
|
|
|
|
|
|
|
|
import add_svg_glyphs
|
|
|
|
|
|
|
|
def do_generate_test_html(font_basename, pairs, glyph=None, verbosity=1):
|
|
|
|
header = r"""<!DOCTYPE html>
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<meta charset="utf-8">
|
|
|
|
<style type="text/css">
|
|
|
|
@font-face { font-family: svgfont; src: url("%s") }
|
|
|
|
body { font-family: sans-serif; font-size: 24px }
|
|
|
|
#emoji span { font-family: svgfont, sans-serif }
|
|
|
|
#panel { font-family: svgfont, sans-serif; font-size: 256px }
|
|
|
|
#paneltitle { font-family: sans-serif; font-size: 36px }
|
|
|
|
</style>
|
|
|
|
<script type="text/javascript">
|
|
|
|
function hexify(text) {
|
|
|
|
var surr_offset = 0x10000 - (0xd800 << 10) - 0xdc00
|
2015-02-21 01:07:41 +00:00
|
|
|
var str = text.trim()
|
2015-02-20 22:58:34 +00:00
|
|
|
var len = str.length
|
|
|
|
var result = ""
|
|
|
|
for (var i = 0; i < len; ++i) {
|
|
|
|
var cp = str.charCodeAt(i)
|
|
|
|
if (cp >= 0xd800 && cp < 0xdc00 && i < len - 1) {
|
|
|
|
ncp = str.charCodeAt(i+1)
|
|
|
|
if (ncp >= 0xdc00 && ncp < 0xe000) {
|
|
|
|
cp = (cp << 10) + ncp + surr_offset
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
result += " 0x" + cp.toString(16)
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
};
|
|
|
|
|
|
|
|
function showText(event) {
|
|
|
|
var text = event.target.textContent
|
|
|
|
var p = document.getElementById('panel')
|
|
|
|
p.textContent = text
|
|
|
|
p = document.getElementById('paneltitle')
|
|
|
|
p.textContent = hexify(text)
|
|
|
|
};
|
|
|
|
|
|
|
|
function setup() {
|
|
|
|
var t = document.getElementById('emoji')
|
|
|
|
var tdlist = t.getElementsByTagName('span')
|
2015-02-21 01:07:41 +00:00
|
|
|
for (var i = 0; i < tdlist.length; ++i) {
|
2015-02-20 22:58:34 +00:00
|
|
|
var e = tdlist[i]
|
|
|
|
e.onmouseover = showText
|
|
|
|
}
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
</head>"""
|
|
|
|
|
|
|
|
body_head = r"""<body onload="setup();">
|
|
|
|
<p>Test for SVG glyphs in %(font)s. It uses the proposed
|
|
|
|
<a href="http://lists.w3.org/Archives/Public/public-svgopentype/2013Jul/0003.html">SVG-in-OpenType format</a>.
|
|
|
|
View using Firefox 26 and later.
|
2015-02-26 23:01:30 +00:00
|
|
|
<div style="float:left; text-align:center; margin:0 10px; width:40%%">
|
2015-02-20 22:58:34 +00:00
|
|
|
<div id='panel' style="margin-left:auto; margin-right:auto">%(glyph)s</div>
|
|
|
|
<div id='paneltitle' style="margin-left:auto; margin-right:auto">%(glyph_hex)s</div>
|
|
|
|
</div>
|
|
|
|
<div id='emoji'><p>"""
|
|
|
|
|
|
|
|
body_tail = r"""</div>
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
"""
|
|
|
|
|
|
|
|
font_name = font_basename + ".woff"
|
|
|
|
html_name = font_basename + "_test.html"
|
|
|
|
|
|
|
|
found_initial_glyph = False
|
|
|
|
initial_glyph_str = None;
|
|
|
|
initial_glyph_hex = None;
|
|
|
|
text_parts = []
|
|
|
|
for glyphstr, _ in pairs:
|
|
|
|
name_parts = []
|
|
|
|
hex_parts = []
|
|
|
|
for cp in glyphstr:
|
|
|
|
hex_str = hex(ord(cp))
|
|
|
|
name_parts.append('&#x%s;' % hex_str[2:])
|
|
|
|
hex_parts.append(hex_str)
|
|
|
|
glyph_str = ''.join(name_parts)
|
|
|
|
|
|
|
|
if not found_initial_glyph:
|
|
|
|
if not glyph or glyph_str == glyph:
|
|
|
|
initial_glyph_str = glyph_str
|
|
|
|
initial_glyph_hex = ' '.join(hex_parts)
|
|
|
|
found_initial_glyph = True
|
|
|
|
elif not initial_glyph_str:
|
|
|
|
initial_glyph_str = glyph_str
|
|
|
|
initial_glyph_hex = ' '.join(hex_parts)
|
|
|
|
|
|
|
|
text = '<span>%s</span>' % glyph_str
|
|
|
|
text_parts.append(text)
|
|
|
|
|
|
|
|
if verbosity and glyph and not found_initial_glyph:
|
2017-09-14 20:18:24 +00:00
|
|
|
print("Did not find glyph '%s', using initial glyph '%s'" % (glyph, initial_glyph_str))
|
2015-02-20 22:58:34 +00:00
|
|
|
elif verbosity > 1 and not glyph:
|
2017-09-14 20:18:24 +00:00
|
|
|
print("Using initial glyph '%s'" % initial_glyph_str)
|
2015-02-20 22:58:34 +00:00
|
|
|
|
|
|
|
lines = [header % font_name]
|
|
|
|
lines.append(body_head % {'font':font_name, 'glyph':initial_glyph_str,
|
|
|
|
'glyph_hex':initial_glyph_hex})
|
|
|
|
lines.extend(text_parts) # we'll end up with space between each emoji
|
|
|
|
lines.append(body_tail)
|
|
|
|
output = '\n'.join(lines)
|
|
|
|
with open(html_name, 'w') as fp:
|
|
|
|
fp.write(output)
|
|
|
|
if verbosity:
|
2017-09-14 20:18:24 +00:00
|
|
|
print('Wrote ' + html_name)
|
2015-02-20 22:58:34 +00:00
|
|
|
|
|
|
|
|
2015-02-26 23:01:30 +00:00
|
|
|
def do_generate_fonts(template_file, font_basename, pairs, reuse=0, verbosity=1):
|
2015-02-20 22:58:34 +00:00
|
|
|
out_woff = font_basename + '.woff'
|
2015-02-26 23:01:30 +00:00
|
|
|
if reuse > 1 and os.path.isfile(out_woff) and os.access(out_woff, os.R_OK):
|
2015-02-20 22:58:34 +00:00
|
|
|
if verbosity:
|
2017-09-14 20:18:24 +00:00
|
|
|
print('Reusing ' + out_woff)
|
2015-02-20 22:58:34 +00:00
|
|
|
return
|
|
|
|
|
|
|
|
out_ttx = font_basename + '.ttx'
|
2015-02-26 23:01:30 +00:00
|
|
|
if reuse == 0:
|
|
|
|
add_svg_glyphs.add_image_glyphs(template_file, out_ttx, pairs, verbosity=verbosity)
|
|
|
|
elif verbosity:
|
2017-09-14 20:18:24 +00:00
|
|
|
print('Reusing ' + out_ttx)
|
2015-02-20 22:58:34 +00:00
|
|
|
|
|
|
|
quiet=verbosity < 2
|
|
|
|
font = ttx.TTFont(flavor='woff', quiet=quiet)
|
|
|
|
font.importXML(out_ttx, quiet=quiet)
|
|
|
|
font.save(out_woff)
|
|
|
|
if verbosity:
|
2017-09-14 20:18:24 +00:00
|
|
|
print('Wrote ' + out_woff)
|
2015-02-20 22:58:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
def main(argv):
|
|
|
|
usage = """This will search for files that have image_prefix followed by one or more
|
|
|
|
hex numbers (separated by underscore if more than one), and end in ".svg".
|
|
|
|
For example, if image_prefix is "icons/u", then files with names like
|
|
|
|
"icons/u1F4A9.svg" or "icons/u1F1EF_1F1F5.svg" will be found. It generates
|
|
|
|
an SVG font from this, converts it to woff, and also generates an html test
|
|
|
|
page containing text for all the SVG glyphs."""
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser(
|
|
|
|
description='Generate font and html test file.', epilog=usage)
|
|
|
|
parser.add_argument('template_file', help='name of template .ttx file')
|
|
|
|
parser.add_argument('image_prefix', help='location and prefix of image files')
|
|
|
|
parser.add_argument('-i', '--include', help='include files whoses name matches this regex')
|
|
|
|
parser.add_argument('-e', '--exclude', help='exclude files whose name matches this regex')
|
|
|
|
parser.add_argument('-o', '--out_basename', help='base name of (ttx, woff, html) files to generate, '
|
|
|
|
'defaults to the template base name')
|
|
|
|
parser.add_argument('-g', '--glyph', help='set the initial glyph text (html encoded string), '
|
|
|
|
'defaults to first glyph')
|
2015-02-26 23:01:30 +00:00
|
|
|
parser.add_argument('-rt', '--reuse_ttx_font', dest='reuse_font', help='use existing ttx font',
|
|
|
|
default=0, const=1, action='store_const')
|
|
|
|
parser.add_argument('-r', '--reuse_font', dest='reuse_font', help='use existing woff font',
|
|
|
|
const=2, action='store_const')
|
2015-02-20 22:58:34 +00:00
|
|
|
parser.add_argument('-q', '--quiet', dest='v', help='quiet operation', default=1,
|
|
|
|
action='store_const', const=0)
|
|
|
|
parser.add_argument('-v', '--verbose', dest='v', help='verbose operation',
|
|
|
|
action='store_const', const=2)
|
|
|
|
args = parser.parse_args(argv)
|
|
|
|
|
|
|
|
pairs = add_svg_glyphs.collect_glyphstr_file_pairs(
|
|
|
|
args.image_prefix, 'svg', include=args.include, exclude=args.exclude, verbosity=args.v)
|
|
|
|
add_svg_glyphs.sort_glyphstr_tuples(pairs)
|
|
|
|
|
|
|
|
out_basename = args.out_basename
|
|
|
|
if not out_basename:
|
|
|
|
out_basename = args.template_file.split('.')[0] # exclude e.g. '.tmpl.ttx'
|
|
|
|
if args.v:
|
2017-09-14 20:18:24 +00:00
|
|
|
print("Output basename is %s." % out_basename)
|
2015-02-20 22:58:34 +00:00
|
|
|
do_generate_fonts(args.template_file, out_basename, pairs, reuse=args.reuse_font, verbosity=args.v)
|
|
|
|
do_generate_test_html(out_basename, pairs, glyph=args.glyph, verbosity=args.v)
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main(sys.argv[1:])
|