
third_party subdir is for forks/clones of external projects. The svg code isn't a modification to that project, but an addition to the font-building code in noto/color_emoji. This also fixes a slight bug in the html generation, which set the default large glyph image but forgot to set the hex version of the text below it.
197 lines
6.8 KiB
Python
Executable File
197 lines
6.8 KiB
Python
Executable File
#!/usr/bin/python
|
|
# 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
|
|
|
|
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
|
|
var str = new String(text.trim())
|
|
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')
|
|
for (var i = 0, lim = tdlist.length; i < lim; ++i) {
|
|
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.
|
|
<div style="float:left; text-align:center; margin:0 10px">
|
|
<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:
|
|
print "Did not find glyph '%s', using initial glyph '%s'" % (glyph, initial_glyph_str)
|
|
elif verbosity > 1 and not glyph:
|
|
print "Using initial glyph '%s'" % initial_glyph_str
|
|
|
|
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:
|
|
print 'Wrote ' + html_name
|
|
|
|
|
|
def do_generate_fonts(template_file, font_basename, pairs, reuse=False, verbosity=1):
|
|
out_woff = font_basename + '.woff'
|
|
if reuse and os.path.isfile(out_woff) and os.access(out_woff, os.R_OK):
|
|
if verbosity:
|
|
print 'Reusing ' + out_woff
|
|
return
|
|
|
|
out_ttx = font_basename + '.ttx'
|
|
add_svg_glyphs.add_image_glyphs(template_file, out_ttx, pairs, verbosity=verbosity)
|
|
|
|
quiet=verbosity < 2
|
|
font = ttx.TTFont(flavor='woff', quiet=quiet)
|
|
font.importXML(out_ttx, quiet=quiet)
|
|
font.save(out_woff)
|
|
if verbosity:
|
|
print 'Wrote ' + out_woff
|
|
|
|
|
|
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')
|
|
parser.add_argument('-r', '--reuse_font', help='use existing woff font', action='store_true')
|
|
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:
|
|
print "Output basename is %s." % out_basename
|
|
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:])
|