generate_test_html.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #!/usr/bin/python
  2. # Copyright 2015 Google, Inc. All Rights Reserved.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. #
  16. # Google Author(s): Doug Felt
  17. import argparse
  18. import os
  19. import os.path
  20. import re
  21. import sys
  22. from fontTools import ttx
  23. import add_svg_glyphs
  24. def do_generate_test_html(font_basename, pairs, glyph=None, verbosity=1):
  25. header = r"""<!DOCTYPE html>
  26. <html>
  27. <head>
  28. <meta charset="utf-8">
  29. <style type="text/css">
  30. @font-face { font-family: svgfont; src: url("%s") }
  31. body { font-family: sans-serif; font-size: 24px }
  32. #emoji span { font-family: svgfont, sans-serif }
  33. #panel { font-family: svgfont, sans-serif; font-size: 256px }
  34. #paneltitle { font-family: sans-serif; font-size: 36px }
  35. </style>
  36. <script type="text/javascript">
  37. function hexify(text) {
  38. var surr_offset = 0x10000 - (0xd800 << 10) - 0xdc00
  39. var str = text.trim()
  40. var len = str.length
  41. var result = ""
  42. for (var i = 0; i < len; ++i) {
  43. var cp = str.charCodeAt(i)
  44. if (cp >= 0xd800 && cp < 0xdc00 && i < len - 1) {
  45. ncp = str.charCodeAt(i+1)
  46. if (ncp >= 0xdc00 && ncp < 0xe000) {
  47. cp = (cp << 10) + ncp + surr_offset
  48. ++i;
  49. }
  50. }
  51. result += " 0x" + cp.toString(16)
  52. }
  53. return result
  54. };
  55. function showText(event) {
  56. var text = event.target.textContent
  57. var p = document.getElementById('panel')
  58. p.textContent = text
  59. p = document.getElementById('paneltitle')
  60. p.textContent = hexify(text)
  61. };
  62. function setup() {
  63. var t = document.getElementById('emoji')
  64. var tdlist = t.getElementsByTagName('span')
  65. for (var i = 0; i < tdlist.length; ++i) {
  66. var e = tdlist[i]
  67. e.onmouseover = showText
  68. }
  69. };
  70. </script>
  71. </head>"""
  72. body_head = r"""<body onload="setup();">
  73. <p>Test for SVG glyphs in %(font)s. It uses the proposed
  74. <a href="http://lists.w3.org/Archives/Public/public-svgopentype/2013Jul/0003.html">SVG-in-OpenType format</a>.
  75. View using Firefox&nbsp;26 and later.
  76. <div style="float:left; text-align:center; margin:0 10px; width:40%%">
  77. <div id='panel' style="margin-left:auto; margin-right:auto">%(glyph)s</div>
  78. <div id='paneltitle' style="margin-left:auto; margin-right:auto">%(glyph_hex)s</div>
  79. </div>
  80. <div id='emoji'><p>"""
  81. body_tail = r"""</div>
  82. </body>
  83. </html>
  84. """
  85. font_name = font_basename + ".woff"
  86. html_name = font_basename + "_test.html"
  87. found_initial_glyph = False
  88. initial_glyph_str = None;
  89. initial_glyph_hex = None;
  90. text_parts = []
  91. for glyphstr, _ in pairs:
  92. name_parts = []
  93. hex_parts = []
  94. for cp in glyphstr:
  95. hex_str = hex(ord(cp))
  96. name_parts.append('&#x%s;' % hex_str[2:])
  97. hex_parts.append(hex_str)
  98. glyph_str = ''.join(name_parts)
  99. if not found_initial_glyph:
  100. if not glyph or glyph_str == glyph:
  101. initial_glyph_str = glyph_str
  102. initial_glyph_hex = ' '.join(hex_parts)
  103. found_initial_glyph = True
  104. elif not initial_glyph_str:
  105. initial_glyph_str = glyph_str
  106. initial_glyph_hex = ' '.join(hex_parts)
  107. text = '<span>%s</span>' % glyph_str
  108. text_parts.append(text)
  109. if verbosity and glyph and not found_initial_glyph:
  110. print "Did not find glyph '%s', using initial glyph '%s'" % (glyph, initial_glyph_str)
  111. elif verbosity > 1 and not glyph:
  112. print "Using initial glyph '%s'" % initial_glyph_str
  113. lines = [header % font_name]
  114. lines.append(body_head % {'font':font_name, 'glyph':initial_glyph_str,
  115. 'glyph_hex':initial_glyph_hex})
  116. lines.extend(text_parts) # we'll end up with space between each emoji
  117. lines.append(body_tail)
  118. output = '\n'.join(lines)
  119. with open(html_name, 'w') as fp:
  120. fp.write(output)
  121. if verbosity:
  122. print 'Wrote ' + html_name
  123. def do_generate_fonts(template_file, font_basename, pairs, reuse=0, verbosity=1):
  124. out_woff = font_basename + '.woff'
  125. if reuse > 1 and os.path.isfile(out_woff) and os.access(out_woff, os.R_OK):
  126. if verbosity:
  127. print 'Reusing ' + out_woff
  128. return
  129. out_ttx = font_basename + '.ttx'
  130. if reuse == 0:
  131. add_svg_glyphs.add_image_glyphs(template_file, out_ttx, pairs, verbosity=verbosity)
  132. elif verbosity:
  133. print 'Reusing ' + out_ttx
  134. quiet=verbosity < 2
  135. font = ttx.TTFont(flavor='woff', quiet=quiet)
  136. font.importXML(out_ttx, quiet=quiet)
  137. font.save(out_woff)
  138. if verbosity:
  139. print 'Wrote ' + out_woff
  140. def main(argv):
  141. usage = """This will search for files that have image_prefix followed by one or more
  142. hex numbers (separated by underscore if more than one), and end in ".svg".
  143. For example, if image_prefix is "icons/u", then files with names like
  144. "icons/u1F4A9.svg" or "icons/u1F1EF_1F1F5.svg" will be found. It generates
  145. an SVG font from this, converts it to woff, and also generates an html test
  146. page containing text for all the SVG glyphs."""
  147. parser = argparse.ArgumentParser(
  148. description='Generate font and html test file.', epilog=usage)
  149. parser.add_argument('template_file', help='name of template .ttx file')
  150. parser.add_argument('image_prefix', help='location and prefix of image files')
  151. parser.add_argument('-i', '--include', help='include files whoses name matches this regex')
  152. parser.add_argument('-e', '--exclude', help='exclude files whose name matches this regex')
  153. parser.add_argument('-o', '--out_basename', help='base name of (ttx, woff, html) files to generate, '
  154. 'defaults to the template base name')
  155. parser.add_argument('-g', '--glyph', help='set the initial glyph text (html encoded string), '
  156. 'defaults to first glyph')
  157. parser.add_argument('-rt', '--reuse_ttx_font', dest='reuse_font', help='use existing ttx font',
  158. default=0, const=1, action='store_const')
  159. parser.add_argument('-r', '--reuse_font', dest='reuse_font', help='use existing woff font',
  160. const=2, action='store_const')
  161. parser.add_argument('-q', '--quiet', dest='v', help='quiet operation', default=1,
  162. action='store_const', const=0)
  163. parser.add_argument('-v', '--verbose', dest='v', help='verbose operation',
  164. action='store_const', const=2)
  165. args = parser.parse_args(argv)
  166. pairs = add_svg_glyphs.collect_glyphstr_file_pairs(
  167. args.image_prefix, 'svg', include=args.include, exclude=args.exclude, verbosity=args.v)
  168. add_svg_glyphs.sort_glyphstr_tuples(pairs)
  169. out_basename = args.out_basename
  170. if not out_basename:
  171. out_basename = args.template_file.split('.')[0] # exclude e.g. '.tmpl.ttx'
  172. if args.v:
  173. print "Output basename is %s." % out_basename
  174. do_generate_fonts(args.template_file, out_basename, pairs, reuse=args.reuse_font, verbosity=args.v)
  175. do_generate_test_html(out_basename, pairs, glyph=args.glyph, verbosity=args.v)
  176. if __name__ == '__main__':
  177. main(sys.argv[1:])