summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorJames Godfrey-Kittle <jamesgk@google.com>2015-10-06 12:26:57 -0700
committerJames Godfrey-Kittle <jamesgk@google.com>2015-10-06 12:31:45 -0700
commit70927d037377b501c9d53dd4e993106977ef722b (patch)
tree6b0a4946c200c4f3d251dd4359774dae6c8bbd9c /scripts
parent561fd3fd27641a5c89a5eec729234e2c786e8082 (diff)
Use common tests from nototools
Diffstat (limited to 'scripts')
-rw-r--r--scripts/common_tests.py567
-rw-r--r--scripts/glyph_area_pen.py77
-rw-r--r--scripts/layout.py58
-rwxr-xr-xscripts/run_android_tests.py13
-rwxr-xr-xscripts/run_exhaustive_tests.py7
-rwxr-xr-xscripts/run_general_tests.py24
-rwxr-xr-xscripts/run_web_tests.py21
7 files changed, 32 insertions, 735 deletions
diff --git a/scripts/common_tests.py b/scripts/common_tests.py
deleted file mode 100644
index c58bdce..0000000
--- a/scripts/common_tests.py
+++ /dev/null
@@ -1,567 +0,0 @@
-# coding=UTF-8
-#
-# 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.
-
-"""Common tests for different targets."""
-
-import glob
-from os import path
-import unittest
-
-from fontTools import ttLib
-from nototools import coverage
-from nototools import font_data
-from nototools import noto_fonts
-from nototools import unicode_data
-
-import freetype
-
-import layout
-from glyph_area_pen import GlyphAreaPen
-
-
-def get_rendered_char_height(font_filename, font_size, char, target='mono'):
- if target == 'mono':
- render_params = freetype.FT_LOAD_TARGET_MONO
- elif target == 'lcd':
- render_params = freetype.FT_LOAD_TARGET_LCD
- render_params |= freetype.FT_LOAD_RENDER
-
- face = freetype.Face(font_filename)
- face.set_char_size(font_size*64)
- face.load_char(char, render_params)
- return face.glyph.bitmap.rows
-
-
-def load_fonts(patterns, expected_count=None, font_class=None):
- """Load all fonts specified in the patterns.
-
- Also assert that the number of the fonts found is exactly the same as
- expected_count."""
-
- if font_class is None:
- font_class = ttLib.TTFont
-
- all_font_files = []
- for pattern in patterns:
- all_font_files += glob.glob(pattern)
- all_fonts = [font_class(font) for font in all_font_files]
- if expected_count:
- assert len(all_font_files) == expected_count
- return all_font_files, all_fonts
-
-
-class FontTest(unittest.TestCase):
- """Parent class for all font tests."""
- loaded_fonts = None
-
-
-class TestItalicAngle(FontTest):
- """Test the italic angle of fonts."""
-
- def setUp(self):
- _, self.fonts = self.loaded_fonts
-
- def test_italic_angle(self):
- """Tests the italic angle of fonts to be correct."""
- for font in self.fonts:
- post_table = font['post']
- if 'Italic' in font_data.font_name(font):
- expected_angle = self.expected_italic_angle
- else:
- expected_angle = 0.0
- self.assertEqual(post_table.italicAngle, expected_angle)
-
-
-class TestMetaInfo(FontTest):
- """Test various meta information."""
-
- mark_heavier_as_bold = False
-
- def setUp(self):
- _, self.fonts = self.loaded_fonts
-
- def test_mac_style(self):
- """Tests the macStyle of the fonts to be correct."""
-
- for font in self.fonts:
- font_name = font_data.font_name(font)
- bold = ('Bold' in font_name) or (
- self.mark_heavier_as_bold and 'Black' in font_name)
- italic = 'Italic' in font_name
- expected_mac_style = (italic << 1) | bold
- self.assertEqual(font['head'].macStyle, expected_mac_style)
-
- def test_fs_type(self):
- """Tests the fsType of the fonts."""
-
- for font in self.fonts:
- self.assertEqual(font['OS/2'].fsType, self.expected_os2_fsType)
-
- def test_vendor_id(self):
- """Tests the vendor ID of the fonts."""
- for font in self.fonts:
- self.assertEqual(font['OS/2'].achVendID,
- self.expected_os2_achVendID)
-
- def test_us_weight(self):
- "Tests the usWeight of the fonts to be correct."""
- for font in self.fonts:
- weight = noto_fonts.parse_weight(font_data.font_name(font))
- expected_numeric_weight = noto_fonts.WEIGHTS[weight]
- self.assertEqual(
- font['OS/2'].usWeightClass,
- expected_numeric_weight)
-
- def test_version_numbers(self):
- "Tests the two version numbers of the font to be correct."""
- for font in self.fonts:
- version = font_data.font_version(font)
- usable_part_of_version = version.split(';')[0]
- self.assertEqual(usable_part_of_version,
- 'Version ' + self.expected_version)
-
- revision = font_data.printable_font_revision(font, accuracy=5)
- self.assertEqual(revision, self.expected_version)
-
-
-class TestNames(FontTest):
- """Tests various strings in the name table."""
-
- mark_heavier_as_bold = False
-
- def setUp(self):
- font_files, self.fonts = self.loaded_fonts
- self.font_files = [path.basename(f) for f in font_files]
- self.condensed_family_name = self.family_name + ' Condensed'
- self.names = []
- for font in self.fonts:
- self.names.append(font_data.get_name_records(font))
-
- def test_copyright(self):
- """Tests the copyright message."""
- for records in self.names:
- self.assertEqual(records[0], self.expected_copyright)
-
- def parse_filename(self, filename):
- """Parse expected name attributes from filename."""
-
- name_nosp = self.family_name.replace(' ', '')
- condensed_name_nosp = self.condensed_family_name.replace(' ', '')
- family_names = '%s|%s' % (condensed_name_nosp, name_nosp)
-
- filename_match = noto_fonts.match_filename(filename, family_names)
- family, _, _, _, _, weight, slope, _ = filename_match.groups()
-
- if family == condensed_name_nosp:
- family = self.condensed_family_name
- else: # family == name_nosp
- family = self.family_name
- if not weight:
- weight = 'Regular'
- return family, weight, slope
-
- def build_style(self, weight, slope):
- """Build style (typographic subfamily) out of weight and slope."""
-
- style = weight
- if slope:
- if style == 'Regular':
- style = 'Italic'
- else:
- style += ' ' + slope
- return style
-
- def test_family_name(self):
- """Tests the family name."""
-
- for font_file, records in zip(self.font_files, self.names):
-
- family, weight, _ = self.parse_filename(font_file)
-
- # check that family name includes weight, if not regular or bold
- if weight not in ['Regular', 'Bold']:
- self.assertEqual(records[1], '%s %s' % (family, weight))
-
- # check typographic name, if present
- self.assertIn(16, records)
- self.assertEqual(records[16], family)
-
- # check that family name does not include weight, if regular or bold
- else:
- self.assertEqual(records[1], family)
-
- def test_subfamily_name(self):
- """Tests the subfamily name."""
-
- for font_file, records in zip(self.font_files, self.names):
- _, weight, slope = self.parse_filename(font_file)
- subfam = records[2]
-
- # check that subfamily is just a combination of bold and italic
- self.assertIn(subfam, ['Regular', 'Bold', 'Italic', 'Bold Italic'])
-
- # check that subfamily weight/slope are consistent with filename
- bold = (weight == 'Bold') or (
- self.mark_heavier_as_bold and
- noto_fonts.WEIGHTS[weight] > noto_fonts.WEIGHTS['Bold'])
- self.assertEqual(bold, subfam.startswith('Bold'))
- self.assertEqual(slope == 'Italic', subfam.endswith('Italic'))
-
- # check typographic name, if present
- if weight not in ['Regular', 'Bold']:
- self.assertIn(17, records)
- self.assertEqual(records[17], self.build_style(weight, slope))
-
- def test_unique_identifier_and_full_name(self):
- """Tests the unique identifier and full name."""
- for font_file, records in zip(self.font_files, self.names):
- family, weight, slope = self.parse_filename(font_file)
- style = self.build_style(weight, slope)
- expected_name = family + ' ' + style
- self.assertEqual(records[3], self.expected_unique_id(expected_name))
- self.assertEqual(records[4], expected_name)
- self.assertFalse(records.has_key(18))
-
- def test_postscript_name(self):
- """Tests the postscript name."""
- for font_file, records in zip(self.font_files, self.names):
- family, weight, slope = self.parse_filename(font_file)
- style = self.build_style(weight, slope)
- expected_name = (family + '-' + style).replace(' ', '')
- self.assertEqual(records[6], expected_name)
-
- def test_postscript_name_for_spaces(self):
- """Tests that there are no spaces in PostScript names."""
- for records in self.names:
- self.assertFalse(' ' in records[6])
-
-
-class TestDigitWidths(FontTest):
- """Tests the width of digits."""
-
- def setUp(self):
- self.font_files, self.fonts = self.loaded_fonts
- self.digits = [
- 'zero', 'one', 'two', 'three', 'four',
- 'five', 'six', 'seven', 'eight', 'nine']
-
- def test_digit_widths(self):
- """Tests all decimal digits to make sure they have the same width."""
- for font in self.fonts:
- hmtx_table = font['hmtx']
- widths = [hmtx_table[digit][0] for digit in self.digits]
- self.assertEqual(len(set(widths)), 1)
-
- def test_superscript_digits(self):
- """Tests that 'numr' features maps digits to Unicode superscripts."""
- ascii_digits = '0123456789'
- superscript_digits = u'⁰¹²³⁴⁵⁶⁷⁸⁹'
- for font_file in self.font_files:
- numr_glyphs = layout.get_advances(
- ascii_digits, font_file, '--features=numr')
- superscript_glyphs = layout.get_advances(
- superscript_digits, font_file)
- self.assertEqual(superscript_glyphs, numr_glyphs)
-
-
-class TestCharacterCoverage(FontTest):
- """Tests character coverage."""
-
- def setUp(self):
- _, self.fonts = self.loaded_fonts
-
- def test_inclusion(self):
- """Tests for characters which should be included."""
-
- for font in self.fonts:
- charset = coverage.character_set(font)
- for char in self.include:
- self.assertIn(char, charset)
-
- def test_exclusion(self):
- """Tests that characters which should be excluded are absent."""
-
- for font in self.fonts:
- charset = coverage.character_set(font)
- for char in self.exclude:
- self.assertNotIn(char, charset)
-
-
-class TestLigatures(FontTest):
- """Tests formation or lack of formation of ligatures."""
-
- def setUp(self):
- self.fontfiles, _ = self.loaded_fonts
-
- def test_lack_of_ff_ligature(self):
- """Tests that the ff ligature is not formed by default."""
- for fontfile in self.fontfiles:
- advances = layout.get_advances('ff', fontfile)
- self.assertEqual(len(advances), 2)
-
- def test_st_ligatures(self):
- """Tests that st ligatures are formed by dlig."""
- for fontfile in self.fontfiles:
- for combination in [u'st', u'ſt']:
- normal = layout.get_glyphs(combination, fontfile)
- ligated = layout.get_glyphs(
- combination, fontfile, '--features=dlig')
- self.assertTrue(len(normal) == 2 and len(ligated) == 1)
-
-
-class TestFeatures(FontTest):
- """Tests typographic features."""
-
- def setUp(self):
- self.fontfiles, _ = self.loaded_fonts
-
- def test_smcp_coverage(self):
- """Tests that smcp is supported for our required set."""
- with open('res/smcp_requirements.txt') as smcp_reqs_file:
- smcp_reqs_list = []
- for line in smcp_reqs_file.readlines():
- line = line[:line.index(' #')]
- smcp_reqs_list.append(unichr(int(line, 16)))
-
- for fontfile in self.fontfiles:
- chars_with_no_smcp = []
- for char in smcp_reqs_list:
- normal = layout.get_glyphs(char, fontfile)
- smcp = layout.get_glyphs(char, fontfile, '--features=smcp')
- if normal == smcp:
- chars_with_no_smcp.append(char)
- self.assertEqual(
- chars_with_no_smcp, [],
- ("smcp feature is not applied to '%s'" %
- u''.join(chars_with_no_smcp).encode('UTF-8')))
-
-
-class TestVerticalMetrics(FontTest):
- """Test the vertical metrics of fonts."""
-
- def setUp(self):
- self.font_files, self.fonts = self.loaded_fonts
-
- def test_ymin_ymax(self):
- """Tests yMin and yMax to be equal to Roboto v1 values.
-
- Android requires this, and web fonts expect this.
- """
- for font in self.fonts:
- head_table = font['head']
- self.assertEqual(head_table.yMin, self.expected_head_yMin)
- self.assertEqual(head_table.yMax, self.expected_head_yMax)
-
- def test_glyphs_ymin_ymax(self):
- """Tests yMin and yMax of all glyphs to not go outside the range."""
- for font_file, font in zip(self.font_files, self.fonts):
- glyf_table = font['glyf']
- for glyph_name in glyf_table.glyphOrder:
- try:
- y_min = glyf_table[glyph_name].yMin
- y_max = glyf_table[glyph_name].yMax
- except AttributeError:
- continue
-
- self.assertTrue(
- self.expected_head_yMin <= y_min and
- y_max <= self.expected_head_yMax,
- ('The vertical metrics for glyph %s in %s exceed the '
- 'acceptable range: yMin=%d, yMax=%d' % (
- glyph_name, font_file, y_min, y_max)))
-
- def test_hhea_table_metrics(self):
- """Tests ascent, descent, and lineGap to be equal to Roboto v1 values.
- """
- for font in self.fonts:
- hhea_table = font['hhea']
- self.assertEqual(hhea_table.descent, self.expected_hhea_descent)
- self.assertEqual(hhea_table.ascent, self.expected_hhea_ascent)
- self.assertEqual(hhea_table.lineGap, self.expected_hhea_lineGap)
-
- def test_os2_metrics(self):
- """Tests OS/2 vertical metrics to be equal to the old values."""
- for font in self.fonts:
- os2_table = font['OS/2']
- self.assertEqual(os2_table.sTypoDescender,
- self.expected_os2_sTypoDescender)
- self.assertEqual(os2_table.sTypoAscender,
- self.expected_os2_sTypoAscender)
- self.assertEqual(os2_table.sTypoLineGap,
- self.expected_os2_sTypoLineGap)
- self.assertEqual(os2_table.usWinDescent,
- self.expected_os2_usWinDescent)
- self.assertEqual(os2_table.usWinAscent,
- self.expected_os2_usWinAscent)
-
-
-class TestHints(FontTest):
- """Tests hints."""
-
- def setUp(self):
- self.fontfiles, self.fonts = self.loaded_fonts
-
- def test_existance_of_hints(self):
- """Tests all glyphs and makes sure non-composite ones have hints."""
- missing_hints = []
- for font in self.fonts:
- glyf_table = font['glyf']
- for glyph_name in font.getGlyphOrder():
- glyph = glyf_table[glyph_name]
- if glyph.numberOfContours <= 0: # composite or empty glyph
- continue
- if len(glyph.program.bytecode) <= 0:
- missing_hints.append(
- (glyph_name, font_data.font_name(font)))
-
- self.assertTrue(missing_hints == [])
-
- def test_height_of_lowercase_o(self):
- """Tests the height of the lowercase o in low resolutions."""
- for fontfile in self.fontfiles:
- for size in range(8, 30): # Kind of arbitrary
- o_height = get_rendered_char_height(
- fontfile, size, 'o')
- n_height = get_rendered_char_height(
- fontfile, size, 'n')
- self.assertEqual(o_height, n_height)
-
-
-class TestGlyphAreas(unittest.TestCase):
- """Tests that glyph areas between weights have the right ratios."""
-
- def setUp(self):
- """Determine which glyphs are intentionally unchanged."""
-
- self.unchanged = set()
- pen = self.pen = GlyphAreaPen()
- thin, bold = self.getFonts(self.masters[1], "Roboto", "Thin", "Bold")
- for glyph in thin:
- glyph.draw(pen)
- thin_area = pen.unload()
- bold[glyph.name].draw(pen)
- bold_area = pen.unload()
- if thin_area == bold_area:
- if thin_area:
- self.unchanged.add(glyph.name)
- else:
- assert thin_area and bold_area
-
- def getFonts(self, fonts, family, *weights):
- """Extract fonts of certain family and weights from given font list."""
-
- fonts = dict((f.info.styleName, f) for f in fonts
- if f.info.familyName == family)
- return [fonts[w] for w in weights]
-
- def test_output(self):
- """Test that only empty or intentionally unchanged glyphs are unchanged.
- """
-
- pen = self.pen
- thin, regular, bold = self.getFonts(
- self.loaded_fonts[1], "Roboto", "Thin", "Regular", "Bold")
- regular_areas = {}
- for glyph in regular:
- glyph.draw(pen)
- regular_areas[glyph.name] = pen.unload()
-
- for other in [thin, bold]:
- for name, regular_area in regular_areas.iteritems():
- other[name].draw(pen)
- other_area = pen.unload()
- if not regular_area: # glyph probably contains only components
- self.assertFalse(other_area)
- continue
- unchanged = regular_area == other_area
- if unchanged:
- msg = name + " has not changed, but should have."
- else:
- msg = name + " has changed, but should not have."
- self.assertEqual(unchanged, name in self.unchanged, msg)
-
-
-class TestSpacingMarks(FontTest):
- """Tests that spacing marks are indeed spacing."""
-
- def setUp(self):
- self.font_files, _ = self.loaded_fonts
- charset = coverage.character_set(self.font_files[0])
- self.marks_to_test = [char for char in charset
- if unicode_data.category(char) in ['Lm', 'Sk']]
- self.advance_cache = {}
-
- def test_individual_spacing_marks(self):
- """Tests that spacing marks are spacing by themselves."""
- for font in self.font_files:
- print 'Testing %s for stand-alone spacing marks...' % font
- for mark in self.marks_to_test:
- mark = unichr(mark)
- advances = layout.get_advances(mark, font)
- assert len(advances) == 1
- self.assertNotEqual(advances[0], 0)
-
- def test_spacing_marks_in_combination(self):
- """Tests that spacing marks do not combine with base letters."""
- for font in self.font_files:
- print 'Testing %s for spacing marks in combination...' % font
- for base_letter in (u'A\u00C6BCDEFGHIJKLMNO\u00D8\u01A0PRST'
- u'U\u01AFVWXYZ'
- u'a\u00E6bcdefghi\u0131j\u0237klmn'
- u'o\u00F8\u01A1prs\u017Ftu\u01B0vwxyz'
- u'\u03D2'):
- print 'Testing %s combinations' % base_letter
- for mark in self.marks_to_test:
- if mark == 0x02DE:
- # Skip rhotic hook, as it's perhaps OK for it to form
- # ligatures
- continue
- mark = unichr(mark)
- advances = layout.get_advances(base_letter + mark, font)
- self.assertEqual(len(advances), 2,
- 'The sequence <%04X, %04X> combines, '
- 'but it should not' % (ord(base_letter), ord(mark)))
-
-
-class TestSoftDottedChars(FontTest):
- """Tests that soft-dotted characters lose their dots."""
-
- def setUp(self):
- self.font_files, _ = self.loaded_fonts
- charset = coverage.character_set(self.font_files[0])
- self.marks_to_test = [char for char in charset
- if unicode_data.combining(char) == 230]
- self.advance_cache = {}
-
- def test_combinations(self):
- """Tests that soft-dotted characters lose their dots when combined."""
-
- for font in self.font_files:
- print 'Testing %s for soft-dotted combinations...' % font
-
- # TODO: replace the following list with actual derivation based on
- # Unicode's soft-dotted property
- for base_letter in (u'ij\u012F\u0249\u0268\u029D\u02B2\u03F3\u0456'
- u'\u0458\u1D62\u1D96\u1DA4\u1DA8\u1E2D\u1ECB'
- u'\u2071\u2C7C'):
- print 'Testing %s combinations' % base_letter.encode('UTF-8')
- for mark in self.marks_to_test:
- mark = unichr(mark)
- letter_only = layout.get_glyphs(base_letter, font)
- combination = layout.get_glyphs(base_letter + mark, font)
- self.assertNotEqual(combination[0], letter_only[0],
- "The sequence <%04X, %04X> doesn't lose its dot, "
- "but it should" % (ord(base_letter), ord(mark)))
diff --git a/scripts/glyph_area_pen.py b/scripts/glyph_area_pen.py
deleted file mode 100644
index 1251b6a..0000000
--- a/scripts/glyph_area_pen.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# 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.
-
-
-from fontTools.pens.basePen import AbstractPen
-
-
-class GlyphAreaPen(AbstractPen):
- """Pen used for calculating the area of the contours in a glyph."""
-
- def __init__(self):
- self.area = 0
-
- def unload(self):
- """Return and then reset the calculated area."""
-
- area = self.area
- self.area = 0
- return area
-
- def moveTo(self, pt):
- """Remember the first point in this contour, in case it's closed. Also
- set the initial value for p0 in this contour, which will always refer to
- the most recent point.
- """
-
- self.first = pt
- self.p0 = pt
-
- def lineTo(self, pt):
- """Add the signed area beneath the line from the latest point to this
- one. Signed areas cancel each other based on the horizontal direction of
- the line.
- """
-
- (x0, y0), (x1, y1) = self.p0, pt
- self.area += (x1 - x0) * (y1 + y0) / 2.0
- self.p0 = pt
-
- def curveTo(self, *points):
- """Add the signed area of this cubic curve.
- https://github.com/Pomax/bezierinfo/issues/44
- """
-
- p1, p2, p3 = points
- x0, y0 = self.p0
- x1, y1 = p1[0] - x0, p1[1] - y0
- x2, y2 = p2[0] - x0, p2[1] - y0
- x3, y3 = p3[0] - x0, p3[1] - y0
- self.area += (
- x1 * ( - y2 - y3) +
- x2 * (y1 - 2 * y3) +
- x3 * (y1 + 2 * y2 )
- ) * 3.0 / 20
- self.lineTo(p3)
-
- def closePath(self):
- """Add the area beneath this contour's closing line."""
- self.lineTo(self.first)
-
- def endPath(self):
- pass
-
- def addComponent(self, glyphName, transformation):
- """Don't count components towards the area, for now."""
- pass
diff --git a/scripts/layout.py b/scripts/layout.py
deleted file mode 100644
index 343f359..0000000
--- a/scripts/layout.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# 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.
-
-"""Test general health of the fonts."""
-
-import json
-
-from nototools import render
-
-def _run_harfbuzz(text, font, language, extra_parameters=None):
- """Run harfbuzz on some text and return the shaped list."""
- try:
- # if extra_parameters is a string, split it into a list
- extra_parameters = extra_parameters.split(' ')
- except AttributeError:
- pass
- hb_output = render.run_harfbuzz_on_text(
- text, font, language, extra_parameters)
- return json.loads(hb_output)
-
-
-_advance_cache = {}
-def get_advances(text, font, extra_parameters=None):
- """Get a list of horizontal advances for text rendered in a font."""
- try:
- return _advance_cache[(text, font, extra_parameters)]
- except KeyError:
- pass
-
- hb_output = _run_harfbuzz(text, font, None, extra_parameters)
- advances = [glyph['ax'] for glyph in hb_output]
- _advance_cache[(text, font, extra_parameters)] = advances
- return advances
-
-
-_shape_cache = {}
-def get_glyphs(text, font, extra_parameters=None):
- """Get a list of shaped glyphs for text rendered in a font."""
- try:
- return _shape_cache[(text, font, extra_parameters)]
- except KeyError:
- pass
-
- hb_output = _run_harfbuzz(text, font, None, extra_parameters)
- shapes = [glyph['g'] for glyph in hb_output]
- _shape_cache[(text, font, extra_parameters)] = shapes
- return shapes
diff --git a/scripts/run_android_tests.py b/scripts/run_android_tests.py
index f10c7fd..3751670 100755
--- a/scripts/run_android_tests.py
+++ b/scripts/run_android_tests.py
@@ -17,16 +17,15 @@
"""Test assumptions that Android relies on."""
import unittest
+from nototools.unittests import font_tests
-import common_tests
-
-FONTS = common_tests.load_fonts(
+FONTS = font_tests.load_fonts(
['out/android/*.ttf'],
expected_count=18)
-class TestVerticalMetrics(common_tests.TestVerticalMetrics):
+class TestVerticalMetrics(font_tests.TestVerticalMetrics):
loaded_fonts = FONTS
test_glyphs_ymin_ymax = None
test_hhea_table_metrics = None
@@ -36,12 +35,12 @@ class TestVerticalMetrics(common_tests.TestVerticalMetrics):
expected_head_yMax = 2163
-class TestDigitWidths(common_tests.TestDigitWidths):
+class TestDigitWidths(font_tests.TestDigitWidths):
loaded_fonts = FONTS
test_superscript_digits = None
-class TestCharacterCoverage(common_tests.TestCharacterCoverage):
+class TestCharacterCoverage(font_tests.TestCharacterCoverage):
loaded_fonts = FONTS
include = frozenset([
@@ -57,7 +56,7 @@ class TestCharacterCoverage(common_tests.TestCharacterCoverage):
) - include # don't exclude legacy PUA
-class TestSpacingMarks(common_tests.TestSpacingMarks):
+class TestSpacingMarks(font_tests.TestSpacingMarks):
loaded_fonts = FONTS
diff --git a/scripts/run_exhaustive_tests.py b/scripts/run_exhaustive_tests.py
index 19eb960..10dd2d7 100755
--- a/scripts/run_exhaustive_tests.py
+++ b/scripts/run_exhaustive_tests.py
@@ -17,17 +17,18 @@
"""Time-consuming tests for general health of the fonts."""
import unittest
+from nototools.unittests import font_tests
-FONTS = common_tests.load_fonts(
+FONTS = font_tests.load_fonts(
['out/RobotoTTF/*.ttf', 'out/RobotoCondensedTTF/*.ttf'],
expected_count=18)
-class TestSpacingMarks(common_tests.TestSpacingMarks):
+class TestSpacingMarks(font_tests.TestSpacingMarks):
loaded_fonts = FONTS
-class TestSoftDottedChars(common_tests.TestSoftDottedChars):
+class TestSoftDottedChars(font_tests.TestSoftDottedChars):
loaded_fonts = FONTS
# FIXME: Test is currently disabled, since the fonts fail it
test_combinations = None
diff --git a/scripts/run_general_tests.py b/scripts/run_general_tests.py
index 193cc5a..ddfae17 100755
--- a/scripts/run_general_tests.py
+++ b/scripts/run_general_tests.py
@@ -19,30 +19,30 @@
import unittest
from robofab.world import OpenFont
+from nototools.unittests import font_tests
-import common_tests
import roboto_data
-FONTS = common_tests.load_fonts(
+FONTS = font_tests.load_fonts(
['hinted/*.ttf'],
expected_count=18)
-UFOS = common_tests.load_fonts(
+UFOS = font_tests.load_fonts(
['out/RobotoUFO/*.ufo', 'out/RobotoCondensedUFO/*.ufo'],
expected_count=18,
font_class=OpenFont)
-UFO_MASTERS = common_tests.load_fonts(
+UFO_MASTERS = font_tests.load_fonts(
['src/v2/*.ufo'],
expected_count=3,
font_class=OpenFont)
-class TestItalicAngle(common_tests.TestItalicAngle):
+class TestItalicAngle(font_tests.TestItalicAngle):
loaded_fonts = FONTS
expected_italic_angle = -12.0
-class TestMetaInfo(common_tests.TestMetaInfo):
+class TestMetaInfo(font_tests.TestMetaInfo):
"""Bugs:
https://code.google.com/a/google.com/p/roboto/issues/detail?id=8
https://code.google.com/a/google.com/p/roboto/issues/detail?id=29
@@ -60,11 +60,11 @@ class TestMetaInfo(common_tests.TestMetaInfo):
expected_os2_achVendID = 'GOOG'
-class TestDigitWidths(common_tests.TestDigitWidths):
+class TestDigitWidths(font_tests.TestDigitWidths):
loaded_fonts = FONTS
-class TestCharacterCoverage(common_tests.TestCharacterCoverage):
+class TestCharacterCoverage(font_tests.TestCharacterCoverage):
loaded_fonts = FONTS
include = frozenset([
@@ -77,15 +77,15 @@ class TestCharacterCoverage(common_tests.TestCharacterCoverage):
) - include # don't exclude legacy PUA
-class TestLigatures(common_tests.TestLigatures):
+class TestLigatures(font_tests.TestLigatures):
loaded_fonts = FONTS
-class TestFeatures(common_tests.TestFeatures):
+class TestFeatures(font_tests.TestFeatures):
loaded_fonts = FONTS
-class TestVerticalMetrics(common_tests.TestVerticalMetrics):
+class TestVerticalMetrics(font_tests.TestVerticalMetrics):
loaded_fonts = FONTS
test_ymin_ymax = None
test_hhea_table_metrics = None
@@ -95,7 +95,7 @@ class TestVerticalMetrics(common_tests.TestVerticalMetrics):
expected_head_yMax = 2163
-class TestGlyphAreas(common_tests.TestGlyphAreas):
+class TestGlyphAreas(font_tests.TestGlyphAreas):
loaded_fonts = UFOS
masters = UFO_MASTERS
diff --git a/scripts/run_web_tests.py b/scripts/run_web_tests.py
index be9ffa0..4f051bf 100755
--- a/scripts/run_web_tests.py
+++ b/scripts/run_web_tests.py
@@ -19,19 +19,18 @@
import unittest
from nototools import font_data
+from nototools.unittests import font_tests
-import common_tests
-
-FONTS = common_tests.load_fonts(
+FONTS = font_tests.load_fonts(
['out/web/*.ttf'],
expected_count=18)
-class TestItalicAngle(common_tests.TestItalicAngle):
+class TestItalicAngle(font_tests.TestItalicAngle):
loaded_fonts = FONTS
expected_italic_angle = -12.0
-class TestMetaInfo(common_tests.TestMetaInfo):
+class TestMetaInfo(font_tests.TestMetaInfo):
loaded_fonts = FONTS
mark_heavier_as_bold = True
@@ -44,7 +43,7 @@ class TestMetaInfo(common_tests.TestMetaInfo):
expected_os2_achVendID = 'GOOG'
-class TestNames(common_tests.TestNames):
+class TestNames(font_tests.TestNames):
"""Bugs:
https://github.com/google/roboto/issues/37
"""
@@ -58,14 +57,14 @@ class TestNames(common_tests.TestNames):
return full_name
-class TestDigitWidths(common_tests.TestDigitWidths):
+class TestDigitWidths(font_tests.TestDigitWidths):
loaded_fonts = FONTS
# disable this test while *.frac and *superior glyphs are separate
# the webfont glyph subset contains *.frac but not *superior
test_superscript_digits = False
-class TestCharacterCoverage(common_tests.TestCharacterCoverage):
+class TestCharacterCoverage(font_tests.TestCharacterCoverage):
loaded_fonts = FONTS
include = frozenset([
@@ -77,7 +76,7 @@ class TestCharacterCoverage(common_tests.TestCharacterCoverage):
) - include # don't exclude legacy PUA
-class TestVerticalMetrics(common_tests.TestVerticalMetrics):
+class TestVerticalMetrics(font_tests.TestVerticalMetrics):
loaded_fonts = FONTS
expected_head_yMin = -555
@@ -94,11 +93,11 @@ class TestVerticalMetrics(common_tests.TestVerticalMetrics):
expected_os2_usWinAscent = 1946
-class TestLigatures(common_tests.TestLigatures):
+class TestLigatures(font_tests.TestLigatures):
loaded_fonts = FONTS
-class TestHints(common_tests.TestHints):
+class TestHints(font_tests.TestHints):
loaded_fonts = FONTS