From 2d940b54cfc16c0e2f791782570a4b7796451244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20Corr=C3=AAa=20da=20Silva=20Sanches?= Date: Thu, 26 Dec 2024 13:30:16 -0300 Subject: [PATCH] Merge opentype/fsselection_matches_macstyle into opentype/fsselection Following FontSpector. (issue #4865) --- Lib/fontbakery/checks/opentype/fsselection.py | 67 +++++++++---------- Lib/fontbakery/legacy_checkids.py | 2 +- Lib/fontbakery/profiles/opentype.py | 1 - tests/test_checks_opentype_os2.py | 53 +++++++-------- 4 files changed, 56 insertions(+), 67 deletions(-) diff --git a/Lib/fontbakery/checks/opentype/fsselection.py b/Lib/fontbakery/checks/opentype/fsselection.py index 2275d268d7..e10b9fd9f1 100644 --- a/Lib/fontbakery/checks/opentype/fsselection.py +++ b/Lib/fontbakery/checks/opentype/fsselection.py @@ -1,3 +1,10 @@ +from fontbakery.constants import ( + RIBBI_STYLE_NAMES, + STATIC_STYLE_NAMES, + FsSelection, + MacStyle, +) +from fontbakery.utils import check_bit_entry from fontbakery.prelude import check, Message, FAIL @@ -5,21 +12,36 @@ id="opentype/fsselection", conditions=["style"], rationale=""" - The OS/2.fsSelection field is a bit field used to specify the stylistic - qualities of the font - in particular, it specifies to some operating - systems whether the font is italic (bit 0), bold (bit 5) or regular - (bit 6). + The OS/2.fsSelection field is a bit field used to specify the stylistic + qualities of the font - in particular, it specifies to some operating + systems whether the font is italic (bit 0), bold (bit 5) or regular + (bit 6). + + This check verifies that the fsSelection field is set correctly for the + font style. For a family of static fonts created in GlyphsApp, this is + set by using the style linking checkboxes in the exports settings. - This check verifies that the fsSelection field is set correctly for the - font style. For a family of static fonts created in GlyphsApp, this is - set by using the style linking checkboxes in the exports settings. + Additionally, the bold and italic bits in OS/2.fsSelection must match the + bold and italic bits in head.macStyle per the OpenType spec. """, - proposal="https://github.com/fonttools/fontbakery/issues/4829", # legacy check + proposal=[ + "https://github.com/fonttools/fontbakery/issues/4829", # legacy check + "https://github.com/fonttools/fontbakery/pull/2382", + ], ) def check_fsselection(ttFont, style): """Checking OS/2 fsSelection value.""" - from fontbakery.constants import RIBBI_STYLE_NAMES, STATIC_STYLE_NAMES, FsSelection - from fontbakery.utils import check_bit_entry + + # Check both OS/2 and head are present. + missing_tables = False + + required = ["OS/2", "head"] + for key in required: + if key not in ttFont: + missing_tables = True + yield FAIL, Message(f"lacks-{key}", f"The '{key}' table is missing.") + if missing_tables: + return # Checking fsSelection REGULAR bit: expected = "Regular" in style or ( @@ -58,31 +80,6 @@ def check_fsselection(ttFont, style): bitname="BOLD", ) - -@check( - id="opentype/fsselection_matches_macstyle", - rationale=""" - The bold and italic bits in OS/2.fsSelection must match the bold and italic - bits in head.macStyle per the OpenType spec. - """, - proposal="https://github.com/fonttools/fontbakery/pull/2382", -) -def check_fsselection_matches_macstyle(ttFont): - """Check if OS/2 fsSelection matches head macStyle bold and italic bits.""" - - # Check both OS/2 and head are present. - missing_tables = False - - required = ["OS/2", "head"] - for key in required: - if key not in ttFont: - missing_tables = True - yield FAIL, Message(f"lacks-{key}", f"The '{key}' table is missing.") - if missing_tables: - return - - from fontbakery.constants import FsSelection, MacStyle - head_bold = (ttFont["head"].macStyle & MacStyle.BOLD) != 0 os2_bold = (ttFont["OS/2"].fsSelection & FsSelection.BOLD) != 0 if head_bold != os2_bold: diff --git a/Lib/fontbakery/legacy_checkids.py b/Lib/fontbakery/legacy_checkids.py index 2ccb8d62e5..28429912e2 100644 --- a/Lib/fontbakery/legacy_checkids.py +++ b/Lib/fontbakery/legacy_checkids.py @@ -219,7 +219,7 @@ "com.google.fonts/check/family/underline_thickness": "opentype/family/underline_thickness", "com.google.fonts/check/font_version TODO: double-check this!": "opentype/font_version", "com.google.fonts/check/fsselection": "opentype/fsselection", - "com.adobe.fonts/check/fsselection_matches_macstyle": "opentype/fsselection_matches_macstyle", + "com.adobe.fonts/check/fsselection_matches_macstyle": "opentype/fsselection", "com.typenetwork/check/varfont/ital_range": "opentype/fvar/axis_ranges_correct", "com.google.fonts/check/varfont/slnt_range": "opentype/fvar/axis_ranges_correct", "com.google.fonts/check/varfont/wdth_valid_range": "opentype/fvar/axis_ranges_correct", diff --git a/Lib/fontbakery/profiles/opentype.py b/Lib/fontbakery/profiles/opentype.py index 9710a3f350..5c88295c17 100644 --- a/Lib/fontbakery/profiles/opentype.py +++ b/Lib/fontbakery/profiles/opentype.py @@ -17,7 +17,6 @@ "opentype/family/underline_thickness", "opentype/font_version", "opentype/fsselection", - "opentype/fsselection_matches_macstyle", "opentype/fvar/axis_ranges_correct", "opentype/fvar/regular_coords_correct", "opentype/gdef_mark_chars", diff --git a/tests/test_checks_opentype_os2.py b/tests/test_checks_opentype_os2.py index bb3d389ba1..3c83c60de2 100644 --- a/tests/test_checks_opentype_os2.py +++ b/tests/test_checks_opentype_os2.py @@ -176,36 +176,6 @@ def test_check_xavgcharwidth(check): assert_results_contain(check(test_font), FATAL, "missing-glyphs") -@check_id("opentype/fsselection_matches_macstyle") -def test_check_fsselection_matches_macstyle(check): - """Check if OS/2 fsSelection matches head macStyle bold and italic bits.""" - - 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 - - @check_id("opentype/family/bold_italic_unique_for_nameid1") def test_check_family_bold_italic_unique_for_nameid1(check): """Check that OS/2.fsSelection bold/italic settings are unique within each @@ -371,3 +341,26 @@ def test_check_fsselection(check): f"with fsSelection:{fsSelection_value} style:{style}...", ) assert message == expected_message + + 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