Example #1
0
def test_check_whitespace_glyphs():
    """ Font contains glyphs for whitespace characters ? """
    from fontbakery.profiles.universal import com_google_fonts_check_whitespace_glyphs as check
    from fontbakery.profiles.shared_conditions import missing_whitespace_chars

    # Our reference Mada Regular font is good here:
    ttFont = TTFont(TEST_FILE("mada/Mada-Regular.ttf"))
    missing = missing_whitespace_chars(ttFont)

    # So it must PASS the check:
    assert_PASS(check(ttFont, missing), 'with a good font...')

    # Then we remove the nbsp char (0x00A0) so that we get a FAIL:
    for table in ttFont['cmap'].tables:
        if 0x00A0 in table.cmap:
            del table.cmap[0x00A0]

    missing = missing_whitespace_chars(ttFont)
    assert_results_contain(check(ttFont, missing), FAIL,
                           'missing-whitespace-glyph-0x00A0',
                           'with a font lacking a nbsp (0x00A0)...')

    # restore original Mada Regular font:
    ttFont = TTFont(TEST_FILE("mada/Mada-Regular.ttf"))

    # And finally remove the space character (0x0020) to get another FAIL:
    for table in ttFont['cmap'].tables:
        if 0x0020 in table.cmap:
            del table.cmap[0x0020]

    missing = missing_whitespace_chars(ttFont)
    assert_results_contain(check(ttFont, missing), FAIL,
                           'missing-whitespace-glyph-0x0020',
                           'with a font lacking a space (0x0020)...')
Example #2
0
def test_check_unwanted_tables():
    """ Are there unwanted tables ? """
    from fontbakery.profiles.universal import com_google_fonts_check_unwanted_tables as check

    unwanted_tables = [
        "FFTM",  # FontForge
        "TTFA",  # TTFAutohint
        "TSI0",  # TSI* = VTT
        "TSI1",
        "TSI2",
        "TSI3",
        "TSI5",
        "prop",  # FIXME: Why is this one unwanted?
        "MVAR",  # Bugs in DirectWrite
    ]
    # Our reference Mada Regular font is good here:
    ttFont = TTFont(TEST_FILE("mada/Mada-Regular.ttf"))

    # So it must PASS the check:
    assert_PASS(check(ttFont), 'with a good font...')

    # We now add unwanted tables one-by-one to validate the FAIL code-path:
    for unwanted in unwanted_tables:
        ttFont = TTFont(TEST_FILE("mada/Mada-Regular.ttf"))
        ttFont.reader.tables[unwanted] = "foo"
        assert_results_contain(
            check(ttFont),
            FAIL,
            None,  # FIXME: This needs a message keyword
            f'with unwanted table {unwanted} ...')
Example #3
0
def test_check_family_underline_thickness(mada_ttFonts):
    """ Fonts have consistent underline thickness ? """
    from fontbakery.profiles.post import com_google_fonts_check_family_underline_thickness as check

    # We start with our reference Mada font family,
    # which we know has the same value of post.underlineThickness
    # across all of its font files, based on our inspection
    # of the file contents using TTX.
    #
    # So the check should PASS in this case:
    assert_PASS(check(mada_ttFonts), 'with a good family.')

    # Then we introduce the issue by setting a
    # different underlineThickness value in just
    # one of the font files:
    value = mada_ttFonts[0]['post'].underlineThickness
    incorrect_value = value + 1
    mada_ttFonts[0]['post'].underlineThickness = incorrect_value

    # And now re-running the check on the modified
    # family should result in a FAIL:
    assert_results_contain(
        check(mada_ttFonts),
        FAIL,
        None,  # FIXME: This needs a message keyword!
        'with an inconsistent family.')
Example #4
0
def test_check_varfont_regular_opsz_coord():
    """ The variable font 'opsz' (Optical Size) axis coordinate
        should be between 9 and 13 on the 'Regular' instance. """
    check = CheckTester(opentype_profile,
                        "com.google.fonts/check/varfont/regular_opsz_coord")
    from fontTools.ttLib.tables._f_v_a_r import Axis

    # Our reference varfont, CabinVFBeta.ttf, lacks an 'opsz' variation axis.
    ttFont = TTFont("data/test/cabinvfbeta/CabinVFBeta.ttf")

    # So we add one:
    new_axis = Axis()
    new_axis.axisTag = "opsz"
    ttFont["fvar"].axes.append(new_axis)

    # and specify a bad coordinate for the Regular:
    ttFont["fvar"].instances[0].coordinates["opsz"] = 8
    # Note: I know the correct instance index for this hotfix because
    # I inspected the our reference CabinVF using ttx

    # Then we ensure the problem is detected:
    assert_results_contain(check(ttFont),
                           WARN, 'out-of-range',
                           'with a bad Regular:opsz coordinate (8)...')

    # We try yet another bad value
    # and the check should detect the problem:
    assert_results_contain(check(ttFont, {"regular_opsz_coord": 14}),
                           WARN, 'out-of-range',
                           'with another bad Regular:opsz value (14)...')

    # We then test with good default opsz values:
    for value in [9, 10, 11, 12, 13]:
        assert_PASS(check(ttFont, {"regular_opsz_coord": value}),
                    f'with a good Regular:opsz coordinate ({value})...')
Example #5
0
def test_check_family_underline_thickness(mada_ttFonts):
    """ Fonts have consistent underline thickness ? """
    check = CheckTester(opentype_profile,
                        "com.google.fonts/check/family/underline_thickness")

    # We start with our reference Mada font family,
    # which we know has the same value of post.underlineThickness
    # across all of its font files, based on our inspection
    # of the file contents using TTX.
    #
    # So the check should PASS in this case:
    assert_PASS(check(mada_ttFonts), 'with a good family.')

    # Then we introduce the issue by setting a
    # different underlineThickness value in just
    # one of the font files:
    value = mada_ttFonts[0]['post'].underlineThickness
    incorrect_value = value + 1
    mada_ttFonts[0]['post'].underlineThickness = incorrect_value

    # And now re-running the check on the modified
    # family should result in a FAIL:
    assert_results_contain(check(mada_ttFonts), FAIL,
                           "inconsistent-underline-thickness",
                           'with an inconsistent family.')
Example #6
0
def test_check_name_postscript_name_consistency():
    from fontbakery.profiles.name import \
        com_adobe_fonts_check_name_postscript_name_consistency as check

    base_path = portable_path("data/test/source-sans-pro/TTF")
    font_path = os.path.join(base_path, 'SourceSansPro-Regular.ttf')
    test_font = TTFont(font_path)

    # SourceSansPro-Regular only has one name ID 6 entry (for Windows),
    # let's add another one for Mac that matches the Windows entry:
    test_font['name'].setName(
        'SourceSansPro-Regular',
        NameID.POSTSCRIPT_NAME,
        PlatformID.MACINTOSH,
        MacintoshEncodingID.ROMAN,
        MacintoshLanguageID.ENGLISH
    )
    assert_PASS(check(test_font))

    # ...now let's change the Mac name ID 6 entry to something else:
    test_font['name'].setName(
        'YetAnotherFontName',
        NameID.POSTSCRIPT_NAME,
        PlatformID.MACINTOSH,
        MacintoshEncodingID.ROMAN,
        MacintoshLanguageID.ENGLISH
    )
    assert_results_contain(check(test_font),
                           FAIL, 'inconsistency')
Example #7
0
def test_check_fsselection_matches_macstyle():
    """Check if OS/2 fsSelection matches head macStyle bold and italic bits."""
    from fontbakery.profiles.os2 import \
      com_adobe_fonts_check_fsselection_matches_macstyle as check
    from fontbakery.constants import FsSelection

    test_font_path = TEST_FILE("nunito/Nunito-Regular.ttf")

    # try a regular (not bold, not italic) font
    test_font = TTFont(test_font_path)
    assert_PASS(check(test_font))

    # now turn on bold in OS/2.fsSelection, but not in head.macStyle
    test_font['OS/2'].fsSelection |= FsSelection.BOLD
    message = assert_results_contain(
        check(test_font), FAIL, None)  # FIXME: This needs a message keyword!
    assert 'bold' in message

    # now turn off bold in OS/2.fsSelection so we can focus on italic
    test_font['OS/2'].fsSelection &= ~FsSelection.BOLD

    # now turn on italic in OS/2.fsSelection, but not in head.macStyle
    test_font['OS/2'].fsSelection |= FsSelection.ITALIC
    message = assert_results_contain(
        check(test_font), FAIL, None)  # FIXME: This needs a message keyword!
    assert 'italic' in message
Example #8
0
def test_check_fsselection_matches_macstyle():
    """Check if OS/2 fsSelection matches head macStyle bold and italic bits."""
    check = CheckTester(opentype_profile,
                        "com.adobe.fonts/check/fsselection_matches_macstyle")
    from fontbakery.constants import FsSelection

    test_font_path = TEST_FILE("nunito/Nunito-Regular.ttf")

    # try a regular (not bold, not italic) font
    test_font = TTFont(test_font_path)
    assert_PASS(check(test_font))

    # now turn on bold in OS/2.fsSelection, but not in head.macStyle
    test_font['OS/2'].fsSelection |= FsSelection.BOLD
    message = assert_results_contain(check(test_font),
                                     FAIL, "fsselection-macstyle-bold")
    assert 'bold' in message

    # now turn off bold in OS/2.fsSelection so we can focus on italic
    test_font['OS/2'].fsSelection &= ~FsSelection.BOLD

    # now turn on italic in OS/2.fsSelection, but not in head.macStyle
    test_font['OS/2'].fsSelection |= FsSelection.ITALIC
    message = assert_results_contain(check(test_font),
                                     FAIL, "fsselection-macstyle-italic")
    assert 'italic' in message
Example #9
0
def test_check_name_postscript_vs_cff():
    from fontbakery.profiles.name import com_adobe_fonts_check_name_postscript_vs_cff as check
    test_font = TTFont()
    test_font['CFF '] = fontTools.ttLib.newTable('CFF ')
    test_font['CFF '].cff.fontNames = ['SomeFontName']
    test_font['name'] = fontTools.ttLib.newTable('name')

    test_font['name'].setName(
        'SomeOtherFontName',
        NameID.POSTSCRIPT_NAME,
        PlatformID.WINDOWS,
        WindowsEncodingID.UNICODE_BMP,
        WindowsLanguageID.ENGLISH_USA
    )
    assert_results_contain(check(test_font),
                           FAIL, 'mismatch')

    test_font['name'].setName(
        'SomeFontName',
        NameID.POSTSCRIPT_NAME,
        PlatformID.WINDOWS,
        WindowsEncodingID.UNICODE_BMP,
        WindowsLanguageID.ENGLISH_USA
    )
    assert_PASS(check(test_font))
Example #10
0
def test_check_varfont_regular_ital_coord():
    """ The variable font 'ital' (Italic) axis coordinate
        must be zero on the 'Regular' instance. """
    from fontbakery.profiles.fvar import com_google_fonts_check_varfont_regular_ital_coord as check
    from fontbakery.profiles.shared_conditions import regular_ital_coord
    from fontTools.ttLib.tables._f_v_a_r import Axis

    # Our reference varfont, CabinVFBeta.ttf, lacks an 'ital' variation axis.
    ttFont = TTFont("data/test/cabinvfbeta/CabinVFBeta.ttf")

    # So we add one:
    new_axis = Axis()
    new_axis.axisTag = "ital"
    ttFont["fvar"].axes.append(new_axis)

    # and specify a bad coordinate for the Regular:
    ttFont["fvar"].instances[0].coordinates["ital"] = 123
    # Note: I know the correct instance index for this hotfix because
    # I inspected the our reference CabinVF using ttx

    # then we test the code of the regular_ital_coord condition:
    regular_italic_coord = regular_ital_coord(ttFont)

    # So it must FAIL the test
    assert_results_contain(check(ttFont,
                                 regular_italic_coord), FAIL, 'non-zero',
                           'with a bad Regular:ital coordinate (123)...')

    # We then fix the Regular:ital coordinate:
    regular_italic_coord = 0

    # and now this should PASS the test:
    assert_PASS(check(ttFont, regular_italic_coord),
                'with a good Regular:ital coordinate (zero)...')
Example #11
0
def test_check_varfont_regular_wght_coord():
    """ The variable font 'wght' (Weight) axis coordinate
        must be 400 on the 'Regular' instance. """
    from fontbakery.profiles.fvar import com_google_fonts_check_varfont_regular_wght_coord as check
    from fontbakery.profiles.shared_conditions import regular_wght_coord

    # Our reference varfont, CabinVFBeta.ttf, has
    # a good Regular:wght coordinate
    ttFont = TTFont("data/test/cabinvfbeta/CabinVFBeta.ttf")
    regular_weight_coord = regular_wght_coord(ttFont)

    # So it must PASS the test
    assert_PASS(check(ttFont, regular_weight_coord),
                'with a good Regular:wght coordinate...')

    # We then change the value so it must FAIL:
    ttFont["fvar"].instances[0].coordinates["wght"] = 500

    # Then re-read the coord:
    regular_weight_coord = regular_wght_coord(ttFont)

    # and now this should FAIL the test:
    assert_results_contain(check(ttFont,
                                 regular_weight_coord), FAIL, 'not-400',
                           'with a bad Regular:wght coordinate (500)...')
Example #12
0
def test_check_varfont_wdth_valid_range():
    """ The variable font 'wdth' (Width) axis coordinate
        must be within spec range of 1 to 1000 on all instances. """
    from fontbakery.profiles.fvar import com_google_fonts_check_varfont_wdth_valid_range as check

    # Our reference varfont, CabinVFBeta.ttf, has
    # all instances within the 1-1000 range
    ttFont = TTFont("data/test/cabinvfbeta/CabinVFBeta.ttf")

    # so it must PASS the test:
    assert_PASS(check(ttFont), 'with a good varfont...')

    # We then introduce a bad value:
    ttFont["fvar"].instances[0].coordinates["wdth"] = 0

    # And it must FAIL the test
    assert_results_contain(check(ttFont), FAIL, 'out-of-range',
                           'with wght=0...')

    # And yet another bad value:
    ttFont["fvar"].instances[0].coordinates["wdth"] = 1001

    # Should also FAIL:
    assert_results_contain(check(ttFont), FAIL, 'out-of-range',
                           'with wght=1001...')
Example #13
0
def test_check_glyf_unused_data():
    """ Is there any unused data at the end of the glyf table? """
    check = CheckTester(opentype_profile,
                        "com.google.fonts/check/glyf_unused_data")

    font = TEST_FILE("nunito/Nunito-Regular.ttf")
    ttFont = TTFont(font)
    assert_PASS(check(ttFont))

    # Always start with a fresh copy, as fT works lazily. Accessing certain data
    # can prevent the test from working because we rely on uninitialized
    # behavior.
    ttFont = TTFont(font)
    ttFont["loca"].locations.pop()
    _file = io.BytesIO()
    ttFont.save(_file)
    ttFont = TTFont(_file)
    ttFont.reader.file.name = font
    assert_results_contain(check(ttFont),
                           FAIL, 'unreachable-data')

    ttFont = TTFont(font)
    ttFont["loca"].locations.append(50000)
    _file = io.BytesIO()
    ttFont.save(_file)
    ttFont = TTFont(_file)
    ttFont.reader.file.name = font
    assert_results_contain(check(ttFont),
                           FAIL, 'missing-data')
Example #14
0
def test_check_rupee():
    """ Ensure indic fonts have the Indian Rupee Sign glyph. """
    check = CheckTester(universal_profile, "com.google.fonts/check/rupee")

    # FIXME: This should be possible:
    #          The `assert_SKIP` helper should be able to detect when a
    #          check skips due to unmet @conditions.
    #          For now it only detects explicit SKIP messages instead.
    #
    # non_indic = TTFont(TEST_FILE("mada/Mada-Regular.ttf"))
    # assert_SKIP(check(non_indic),
    #             "with a non-indic font.")
    #
    #        But for now we have to do this:
    #
    from fontbakery.profiles.shared_conditions import is_indic_font
    print("Ensure the check will SKIP when dealing with a non-indic font...")
    non_indic = TTFont(TEST_FILE("mada/Mada-Regular.ttf"))
    assert is_indic_font(non_indic) == False

    # This one is good:
    ttFont = TTFont(
        TEST_FILE(
            "indic-font-with-rupee-sign/NotoSerifDevanagari-Regular.ttf"))
    assert_PASS(check(ttFont),
                "with a sample font that has the Indian Rupee Sign.")

    # But this one lacks the glyph:
    ttFont = TTFont(
        TEST_FILE("indic-font-without-rupee-sign/NotoSansOlChiki-Regular.ttf"))
    assert_results_contain(check(ttFont), FAIL, "missing-rupee",
                           "with a sample font missing it.")
Example #15
0
def test_check_glyf_unused_data():
    """ Is there any unused data at the end of the glyf table? """
    from fontbakery.profiles.glyf import com_google_fonts_check_glyf_unused_data as check

    test_font_path = TEST_FILE("nunito/Nunito-Regular.ttf")

    test_font = TTFont(test_font_path)
    assert_PASS(check(test_font))

    # Always start with a fresh copy, as fT works lazily. Accessing certain data
    # can prevent the test from working because we rely on uninitialized
    # behavior.
    test_font = TTFont(test_font_path)
    test_font["loca"].locations.pop()
    test_file = io.BytesIO()
    test_font.save(test_file)
    test_font = TTFont(test_file)
    assert_results_contain(check(test_font), FAIL, 'unreachable-data')

    test_font = TTFont(test_font_path)
    test_font["loca"].locations.append(50000)
    test_file = io.BytesIO()
    test_font.save(test_file)
    test_font = TTFont(test_file)
    assert_results_contain(check(test_font), FAIL, 'missing-data')
Example #16
0
def test_check_unwanted_tables():
    """ Are there unwanted tables ? """
    check = CheckTester(universal_profile,
                        "com.google.fonts/check/unwanted_tables")

    unwanted_tables = [
        "FFTM",  # FontForge
        "TTFA",  # TTFAutohint
        "TSI0",  # TSI* = VTT
        "TSI1",
        "TSI2",
        "TSI3",
        "TSI5",
        "prop",  # FIXME: Why is this one unwanted?
        "MVAR",  # Bugs in DirectWrite
    ]
    # Our reference Mada Regular font is good here:
    ttFont = TTFont(TEST_FILE("mada/Mada-Regular.ttf"))

    # So it must PASS the check:
    assert_PASS(check(ttFont), 'with a good font...')

    # We now add unwanted tables one-by-one to validate the FAIL code-path:
    for unwanted in unwanted_tables:
        ttFont = TTFont(TEST_FILE("mada/Mada-Regular.ttf"))
        ttFont.reader.tables[unwanted] = "foo"
        assert_results_contain(check(ttFont), FAIL, "unwanted-tables",
                               f'with unwanted table {unwanted} ...')
Example #17
0
def test_check_family_win_ascent_and_descent(mada_ttFonts):
    """ Checking OS/2 usWinAscent & usWinDescent. """
    check = CheckTester(
        universal_profile,
        "com.google.fonts/check/family/win_ascent_and_descent")
    from fontbakery.profiles.shared_conditions import vmetrics

    # Our reference Mada Regular is know to be bad here.
    ttFont = TTFont(TEST_FILE("mada/Mada-Regular.ttf"))

    # But we fix it first to test the PASS code-path:
    vm = vmetrics(mada_ttFonts)
    ttFont['OS/2'].usWinAscent = vm['ymax']
    ttFont['OS/2'].usWinDescent = abs(vm['ymin'])
    assert_PASS(check(ttFont), 'with a good font...')

    # Then we break it:
    ttFont[
        'OS/2'].usWinAscent = 0  # FIXME: this should be bad as well: vm['ymax'] - 1
    ttFont['OS/2'].usWinDescent = abs(vm['ymin'])
    assert_results_contain(check(ttFont), FAIL, 'ascent',
                           'with a bad OS/2.usWinAscent...')

    # and also this other way of breaking it:
    ttFont['OS/2'].usWinAscent = vm['ymax']
    ttFont[
        'OS/2'].usWinDescent = 0  # FIXME: this should be bad as well: abs(vm['ymin']) - 1
    assert_results_contain(check(ttFont), FAIL, 'descent',
                           'with a bad OS/2.usWinDescent...')
Example #18
0
def test_check_family_max_4_fonts_per_family_name():
    from fontbakery.profiles.name import \
        com_adobe_fonts_check_family_max_4_fonts_per_family_name as check

    base_path = portable_path("data/test/source-sans-pro/OTF")

    font_names = [
        'SourceSansPro-Black.otf', 'SourceSansPro-BlackIt.otf',
        'SourceSansPro-Bold.otf', 'SourceSansPro-BoldIt.otf',
        'SourceSansPro-ExtraLight.otf', 'SourceSansPro-ExtraLightIt.otf',
        'SourceSansPro-It.otf', 'SourceSansPro-Light.otf',
        'SourceSansPro-LightIt.otf', 'SourceSansPro-Regular.otf',
        'SourceSansPro-Semibold.otf', 'SourceSansPro-SemiboldIt.otf'
    ]

    font_paths = [os.path.join(base_path, n) for n in font_names]

    test_fonts = [TTFont(x) for x in font_paths]

    # try fonts with correct family name grouping
    assert_PASS(check(test_fonts))

    # now set 5 of the fonts to have the same family name
    for font in test_fonts[:5]:
        name_records = font['name'].names
        for name_record in name_records:
            if name_record.nameID == 1:
                # print(repr(name_record.string))
                name_record.string = 'foobar'.encode('utf-16be')

    assert_results_contain(check(test_fonts), FAIL, 'too-many')
Example #19
0
def test_check_whitespace_glyphs():
    """ Font contains glyphs for whitespace characters? """
    check = CheckTester(universal_profile,
                        "com.google.fonts/check/whitespace_glyphs")

    # Our reference Mada Regular font is good here:
    ttFont = TTFont(TEST_FILE("mada/Mada-Regular.ttf"))
    assert_PASS(check(ttFont), 'with a good font...')

    # We remove the nbsp char (0x00A0)
    for table in ttFont['cmap'].tables:
        if 0x00A0 in table.cmap:
            del table.cmap[0x00A0]

    # And make sure the problem is detected:
    assert_results_contain(check(ttFont), FAIL,
                           'missing-whitespace-glyph-0x00A0',
                           'with a font lacking a nbsp (0x00A0)...')

    # restore original Mada Regular font:
    ttFont = TTFont(TEST_FILE("mada/Mada-Regular.ttf"))

    # And finally do the same with the space character (0x0020):
    for table in ttFont['cmap'].tables:
        if 0x0020 in table.cmap:
            del table.cmap[0x0020]
    assert_results_contain(check(ttFont), FAIL,
                           'missing-whitespace-glyph-0x0020',
                           'with a font lacking a space (0x0020)...')
Example #20
0
def test_check_unitsperem():
    """ Checking unitsPerEm value is reasonable. """
    from fontbakery.profiles.head import com_google_fonts_check_unitsperem as check

    # In this test we'll forge several known-good and known-bad values.
    # We'll use Mada Regular to start with:
    ttFont = TTFont(TEST_FILE("mada/Mada-Regular.ttf"))

    for good_value in [16, 32, 64, 128, 256, 512, 1000,
                       1024, 2000, 2048, 4096, 8192, 16384]:
        ttFont['head'].unitsPerEm = good_value
        assert_PASS(check(ttFont),
                    f'with a good value of unitsPerEm = {good_value} ...')

    for warn_value in [20, 50, 100, 500, 4000]:
        ttFont['head'].unitsPerEm = warn_value
        assert_results_contain(check(ttFont),
                               WARN, 'suboptimal',
                               f'with a value of unitsPerEm = {warn_value} ...')

    # These are arbitrarily chosen bad values:
    for bad_value in [0, 1, 2, 4, 8, 10, 15, 16385, 32768]:
        ttFont['head'].unitsPerEm = bad_value
        assert_results_contain(check(ttFont),
                               FAIL, 'out-of-range',
                               f'with a bad value of unitsPerEm = {bad_value} ...')
Example #21
0
def test_check_varfont_regular_ital_coord():
    """ The variable font 'ital' (Italic) axis coordinate
        must be zero on the 'Regular' instance. """
    check = CheckTester(opentype_profile,
                        "com.google.fonts/check/varfont/regular_ital_coord")
    from fontTools.ttLib.tables._f_v_a_r import Axis

    # Our reference varfont, CabinVFBeta.ttf, lacks an 'ital' variation axis.
    ttFont = TTFont("data/test/cabinvfbeta/CabinVFBeta.ttf")

    # So we add one:
    new_axis = Axis()
    new_axis.axisTag = "ital"
    ttFont["fvar"].axes.append(new_axis)

    # and specify a bad coordinate for the Regular:
    ttFont["fvar"].instances[0].coordinates["ital"] = 123
    # Note: I know the correct instance index for this hotfix because
    # I inspected the our reference CabinVF using ttx

    # And with this the check must detect the problem:
    assert_results_contain(check(ttFont),
                           FAIL, 'non-zero',
                           'with a bad Regular:ital coordinate (123)...')

    # but with zero it must PASS the check:
    assert_PASS(check(ttFont, {"regular_ital_coord": 0}),
                'with a good Regular:ital coordinate (zero)...')
Example #22
0
def test_check_font_version():
    """ Checking font version fields. """
    from fontbakery.profiles.head import com_google_fonts_check_font_version as check

    test_font_path = TEST_FILE("nunito/Nunito-Regular.ttf")
    test_font = TTFont(test_font_path)
    assert_PASS(check(test_font))

    # 1.00099 is only a mis-interpretation of a valid float value (1.001)
    # See more detailed discussion at:
    # https://github.com/googlefonts/fontbakery/issues/2006
    test_font = TTFont(test_font_path)
    test_font["head"].fontRevision = 1.00098
    test_font["name"].setName("Version 1.001", 5, 1, 0, 0x0)
    test_font["name"].setName("Version 1.001", 5, 3, 1, 0x409)

    # There should be at least one WARN...
    assert_results_contain(check(test_font),
                           WARN, None) # FIXME: This needs a message keyword!

    # But final result is a PASS:
    assert_PASS(check(test_font))

    # Test that having more than 3 decimal places in the version
    # in the Name table is acceptable.
    # See https://github.com/googlefonts/fontbakery/issues/2928
    test_font = TTFont(test_font_path)
    # This is the nearest multiple of 1/65536 to 2020.0613
    test_font["head"].fontRevision = 2020.061294555664
    test_font["name"].setName("Version 2020.0613", 5, 1, 0, 0x0)
    test_font["name"].setName("Version 2020.0613", 5, 3, 1, 0x409)
    assert_PASS(check(test_font))

    test_font = TTFont(test_font_path)
    test_font["head"].fontRevision = 3.1
    test_font["name"].setName("Version 3.000", 5, 1, 0, 0x0)
    test_font["name"].setName("Version 3.000", 5, 3, 1, 0x409)
    assert_results_contain(check(test_font),
                           FAIL, 'mismatch')

    test_font = TTFont(test_font_path)
    test_font["head"].fontRevision = 3.0
    test_font["name"].setName("Version 1.000", 5, 3, 1, 0x409)
    assert_results_contain(check(test_font),
                           FAIL, 'mismatch')

    test_font = TTFont(test_font_path)
    test_font["name"].setName("Version x.000", 5, 3, 1, 0x409)
    assert_results_contain(check(test_font),
                           FAIL, 'parse')

    test_font = TTFont(test_font_path)
    v1 = test_font["name"].getName(5, 3, 1)
    v2 = test_font["name"].getName(5, 1, 0)
    test_font["name"].names.remove(v1)
    test_font["name"].names.remove(v2)
    assert_results_contain(check(test_font),
                           FAIL, 'missing')
Example #23
0
def test_check_points_out_of_bounds():
    """ Check for points out of bounds. """
    from fontbakery.profiles.glyf import com_google_fonts_check_points_out_of_bounds as check

    test_font = TTFont(TEST_FILE("nunito/Nunito-Regular.ttf"))
    assert_results_contain(check(test_font), WARN, 'points-out-of-bounds')

    test_font2 = TTFont(TEST_FILE("familysans/FamilySans-Regular.ttf"))
    assert_PASS(check(test_font2))
Example #24
0
def test_check_STAT_strings():
    from fontbakery.profiles.universal import com_google_fonts_check_STAT_strings as check

    good = TTFont(TEST_FILE("ibmplexsans-vf/IBMPlexSansVar-Roman.ttf"))
    assert_PASS(check(good))

    bad = TTFont(TEST_FILE("ibmplexsans-vf/IBMPlexSansVar-Italic.ttf"))
    assert_results_contain(check(bad), FAIL,
                           None)  # FIXME: This needs a message keyword
Example #25
0
def test_check_STAT_strings():
    check = CheckTester(universal_profile,
                        "com.google.fonts/check/STAT_strings")

    good = TTFont(TEST_FILE("ibmplexsans-vf/IBMPlexSansVar-Roman.ttf"))
    assert_PASS(check(good))

    bad = TTFont(TEST_FILE("ibmplexsans-vf/IBMPlexSansVar-Italic.ttf"))
    assert_results_contain(check(bad), FAIL, "bad-italic")
Example #26
0
def test_check_family_vertical_metrics(montserrat_ttFonts):
    from fontbakery.profiles.universal import com_google_fonts_check_family_vertical_metrics as check

    assert_PASS(check(montserrat_ttFonts), 'with multiple good fonts...')

    montserrat_ttFonts[0]['OS/2'].usWinAscent = 4000
    assert_results_contain(
        check(montserrat_ttFonts), FAIL, 'usWinAscent-mismatch',
        'with one bad font that has one different vertical metric val...')
Example #27
0
def test_check_outline_short_segments():
    """ Check for short segments. """
    check = CheckTester(outline_profile,
                        "com.google.fonts/check/outline_short_segments")

    filename = TEST_FILE("wonky_paths/WonkySourceSansPro-Regular.otf")
    results = check(filename)
    assert_results_contain(results, WARN, 'found-short-segments')
    messages = "".join([m[1].message for m in results])
    assert "D contains a short segment L<<180.0,68.0>--<173.0,71.0>>" in messages
Example #28
0
def test_check_layout_valid_feature_tags():
    """Does the font have any invalid feature tags?"""
    check = CheckTester(layout_profile,
                        "com.google.fonts/check/layout_valid_feature_tags")

    font = TEST_FILE("nunito/Nunito-Regular.ttf")
    assert_PASS(check(font))

    font = TEST_FILE("rosarivo/Rosarivo-Regular.ttf")
    assert_results_contain(check(font), FAIL, 'bad-feature-tags')
Example #29
0
def test_check_outline_alignment_miss():
    """ Check for misaligned points. """
    check = CheckTester(outline_profile,
                        "com.google.fonts/check/outline_alignment_miss")

    filename = TEST_FILE("wonky_paths/WonkySourceSansPro-Regular.otf")
    results = check(filename)
    assert_results_contain(results, WARN, 'found-misalignments')
    messages = "".join([m[1].message for m in results])
    assert "A: X=3.0,Y=-2.0 (should be at baseline 0?)" in messages
Example #30
0
def test_check_family_vertical_metrics(montserrat_ttFonts):
    check = CheckTester(universal_profile,
                        "com.google.fonts/check/family/vertical_metrics")

    assert_PASS(check(montserrat_ttFonts), 'with multiple good fonts...')

    montserrat_ttFonts[0]['OS/2'].usWinAscent = 4000
    assert_results_contain(
        check(montserrat_ttFonts), FAIL, 'usWinAscent-mismatch',
        'with one bad font that has one different vertical metric val...')