1  #!/usr/bin/env python3
       2  
       3  import sys, os, subprocess, shutil, glob
       4  import xml.etree.ElementTree as ET
       5  
       6  # Can we extract this from HTML element itself? I couldn't.
       7  namespaces = {
       8  	'ft': 'https://github.com/OpenType/fonttest',
       9  	'xlink': 'http://www.w3.org/1999/xlink',
      10  }
      11  def ns (s):
      12  	ns,s = s.split(':')
      13  	return '{%s}%s' % (namespaces[ns], s)
      14  
      15  def unistr (s):
      16  	return ','.join('U+%04X' % ord(c) for c in s)
      17  
      18  def glyphstr (glyphs):
      19  	out = []
      20  	for glyphname, x, y in glyphs:
      21  		if x or y:
      22  			out.append ('%s@%d,%d' % (glyphname, x, y))
      23  		else:
      24  			out.append (glyphname)
      25  	return '[' + '|'.join (out) + ']'
      26  
      27  def extract_tests (input):
      28  	html = ET.fromstring (input)
      29  	found = False
      30  
      31  	result = []
      32  
      33  	for elt in html.findall (".//*[@class='expected'][@ft:id]", namespaces):
      34  		found = True
      35  		name = elt.get (ns ('ft:id'))
      36  		text = elt.get (ns ('ft:render'))
      37  		font = elt.get (ns ('ft:font'))
      38  		variations = elt.get (ns ('ft:var'), '').replace (':', '=').replace (';', ',')
      39  		glyphs = []
      40  		for use in elt.findall (".//use"):
      41  			x = int (use.get ('x'))
      42  			y = int (use.get ('y'))
      43  			href = use.get (ns ('xlink:href'))
      44  			assert href[0] == '#'
      45  			glyphname = '.'.join (href[1:].split ('/')[1].split ('.')[1:])
      46  			glyphs.append ((glyphname, x, y))
      47  		opts = '--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft'
      48  		if variations:
      49  			opts = opts + ' --variations=%s' % variations
      50  		result.append ("../fonts/%s:%s:%s:%s" % (font, opts, unistr(text), glyphstr(glyphs)))
      51  
      52  	for elt in html.findall (".//*[@class='expected-no-crash'][@ft:id]", namespaces):
      53  		found = True
      54  		name = elt.get (ns ('ft:id'))
      55  		text = elt.get (ns ('ft:render'))
      56  		font = elt.get (ns ('ft:font'))
      57  		variations = elt.get (ns ('ft:var'), '').replace (':', '=').replace (';', ',')
      58  		opts = ''
      59  		if variations:
      60  			opts = '--variations=%s' % variations
      61  		result.append ("../fonts/%s:%s:%s:*" % (font, opts, unistr (text)))
      62  
      63  	assert found
      64  	return '\n'.join (result) + '\n'
      65  
      66  os.chdir (os.getenv ('srcdir', os.path.dirname (__file__)))
      67  
      68  git = shutil.which ('git')
      69  assert git
      70  
      71  if os.path.isdir ('./text-rendering-tests'):
      72  	subprocess.run ([git, 'pull'], cwd='text-rendering-tests', check=True)
      73  else:
      74  	subprocess.run ([git, 'clone', 'https://github.com/unicode-org/text-rendering-tests'], check=True)
      75  
      76  shutil.rmtree ('fonts', ignore_errors=True)
      77  assert not os.path.exists ('fonts')
      78  shutil.copytree ('text-rendering-tests/fonts', 'fonts')
      79  subprocess.run([git, 'add', 'fonts'], check=True)
      80  
      81  shutil.rmtree ('tests', ignore_errors=True)
      82  assert not os.path.isdir('tests')
      83  os.mkdir ('tests')
      84  
      85  with open ('DISABLED', 'r') as f: disabled = f.read ()
      86  
      87  tests = []
      88  disabled_tests = []
      89  
      90  for x in sorted (os.listdir ('text-rendering-tests/testcases')):
      91  	if not x.endswith ('.html') or x == 'index.html': continue
      92  	out = 'tests/%s.tests' % x.split('.html')[0]
      93  	with open ('text-rendering-tests/testcases/' + x, 'r') as f: content = f.read ()
      94  	with open (out, 'w') as f: f.write (extract_tests (content))
      95  	if out in disabled:
      96  		disabled_tests.append (out)
      97  	else:
      98  		tests.append (out)
      99  
     100  subprocess.run([git, 'add', 'tests'], check=True)
     101  
     102  with open ('meson.build', 'w') as f: f.write ('\n'.join (
     103  	['text_rendering_tests = ['] +
     104  	['  \'%s\',' % x.split('tests/')[1] for x in tests] +
     105  	[']', '', 'disabled_text_rendering_tests = ['] +
     106  	['  \'%s\',' % x.split('tests/')[1] for x in disabled_tests] +
     107  	[']', '']
     108  ))
     109  
     110  with open ('Makefile.sources', 'w') as f: f.write ('\n'.join (
     111  	['TESTS = \\'] +
     112  	['	%s \\' % x for x in tests] +
     113  	['	$(NULL)', '', 'DISBALED_TESTS = \\'] +
     114  	['	%s \\' % x for x in disabled_tests] +
     115  	['	$(NULL)', '']
     116  ))
     117  
     118  subprocess.run([git, 'add', 'Makefile.sources'], check=True)
     119  
     120  print ('Updated the testsuit, now run `git commit -e -m "[test/text-rendering-tests] Update from upstream"`')