diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e1a73f9a9..a81c62e8db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ A more detailed list of changes is available in the corresponding milestones for - All rationale text needs to have 8 indentation spaces (because this indentation on the source should not show up on the user-interface when rationale text is printed on the text terminal) - Remove PriorityLevel class as it makes classifying checks by priority more complicated then necessary! (issue #2981) - Use the http://fonts.google.com/metadata/fonts endpoint to determine if a font is listed in Google Fonts. (issue #2991) + - Style condition will now work on variable fonts. Since the style name cannot be inferred from the filename for a variable font, we have to use the Typographic Subfamily name or Subfamily name instead. ### New Checks - **[com.google.fonts/check/varfont_duplicate_instance_names]**: Avoid duplicate instance names in variable fonts (issue #2986) @@ -17,6 +18,7 @@ A more detailed list of changes is available in the corresponding milestones for ### Changes to existing checks - **[com.google.fonts/check/font_version]**: fixed tolerance for warnings (PR #3009) - **[com.google.fonts/check/fontbakery_version]**: use pip_api module and PyPI JSON API instead of invoking command-line pip/pip3 via subprocess (#2966) + - **[com.google.fonts/check/fsselection]**: Ensure fsSelection bit 7 (USE_TYPO_METRICS) is enabled for variable fonts. ### Bugfixes - Fix ERROR in com.google.fonts/check/STAT_strings (issue #2992) diff --git a/Lib/fontbakery/profiles/googlefonts.py b/Lib/fontbakery/profiles/googlefonts.py index a83c197d12..bc3b03fffd 100644 --- a/Lib/fontbakery/profiles/googlefonts.py +++ b/Lib/fontbakery/profiles/googlefonts.py @@ -2843,6 +2843,14 @@ def com_google_fonts_check_fsselection(ttFont, style): bitmask=FsSelection.BOLD, bitname="BOLD") + # Checking fsSelection bit 7 is enabled for variable fonts: + if is_variable_font(ttFont): + yield check_bit_entry(ttFont, "OS/2", "fsSelection", + True, + bitmask=FsSelection.USETYPOMETRICS, + bitname="USE_TYPO_METRICS") + + @check( id = 'com.google.fonts/check/italic_angle', diff --git a/tests/profiles/googlefonts_test.py b/tests/profiles/googlefonts_test.py index e2f0944e2f..12fbdaaaad 100644 --- a/tests/profiles/googlefonts_test.py +++ b/tests/profiles/googlefonts_test.py @@ -2254,13 +2254,59 @@ def NOT_IMPLEMENTED_test_check_production_glyphs_similarity(): # - PASS, "Glyphs are similar" -def NOT_IMPLEMENTED_test_check_fsselection(): +def test_check_fsselection(): """ Checking OS/2 fsSelection value. """ - # from fontbakery.profiles.googlefonts import com_google_fonts_check_fsselection as check - # TODO: Implement-me! - # - # code-paths: - # ... + from fontbakery.profiles.googlefonts import com_google_fonts_check_fsselection as check + from fontbakery.profiles.googlefonts_conditions import style + from fontbakery.constants import FsSelection, RIBBI_STYLE_NAMES + + # Our reference family Montserrat is known to be good + montserrat_fontfiles = MONTSERRAT_RIBBI + MONTSERRAT_NON_RIBBI + + for fontfile in montserrat_fontfiles: + ttFont = TTFont(fontfile) + font_style = style(ttFont) + + # all font should pass this since the family is good + assert_PASS(check(ttFont, font_style), + f'with a good fsSelection font ({fontfile})...') + + # Check REGULAR bit. All non-RIBBI style must also have this bit enabled + if font_style == "Regular" or font_style not in RIBBI_STYLE_NAMES: + # Fail if REGULAR is not set + ttFont['OS/2'].fsSelection = ttFont['OS/2'].fsSelection ^ FsSelection.REGULAR + assert_results_contain(check(ttFont, font_style), + FAIL, 'bad-REGULAR', + f'with a bad fsSelection font ({fontfile})...') + # Check BOLD bit + if font_style == "Bold" or "BoldItalic": + # Fail if BOLD is not set + ttFont['OS/2'].fsSelection = ttFont['OS/2'].fsSelection ^ FsSelection.BOLD + assert_results_contain(check(ttFont, font_style), + FAIL, 'bad-BOLD', + f'with a bad fsSelection font ({fontfile})...') + # Check ITALIC bit + if "Italic" in font_style: + ttFont['OS/2'].fsSelection = ttFont['OS/2'].fsSelection ^ FsSelection.ITALIC + # Fail if ITALIC is not set + assert_results_contain(check(ttFont, font_style), + FAIL, 'bad-ITALIC', + f'with a bad fsSelection font ({fontfile})...') + + fontfile = TEST_FILE("varfont/OpenSans[wdth,wght].ttf") + ttFont = TTFont(fontfile) + + # Check USE_TYPO_METRICS is set for variable fonts + # Our reference file Open Sans VF is known to be good + font_style = style(ttFont) + assert_PASS(check(ttFont, font_style), + f'with a good fsSelection font ({fontfile})...') + + # And fail if the value is not USE_TYPO_METRICS + ttFont['OS/2'].fsSelection = ttFont['OS/2'].fsSelection ^ FsSelection.USETYPOMETRICS + assert_results_contain(check(ttFont, font_style), + FAIL, 'bad-USE_TYPO_METRICS', + f'with a bad fsSelection font ({fontfile})...') def test_check_italic_angle():