Skip to content

Commit

Permalink
split-out opentype/fvar code-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
felipesanches committed Nov 14, 2024
1 parent 313d706 commit 3b615af
Show file tree
Hide file tree
Showing 8 changed files with 662 additions and 612 deletions.
612 changes: 0 additions & 612 deletions tests/test_checks_opentype_fvar.py

This file was deleted.

247 changes: 247 additions & 0 deletions tests/test_checks_opentype_fvar_regular_coords_correct.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
from fontTools.ttLib import TTFont
from fontTools.ttLib.tables._f_v_a_r import Axis

from conftest import check_id
from fontbakery.status import FAIL, WARN, SKIP
from fontbakery.codetesting import (
assert_PASS,
assert_results_contain,
TEST_FILE,
MockFont,
)


@check_id("opentype/varfont/regular_wght_coord")
def test_check_varfont_regular_wght_coord(check):
"""The variable font 'wght' (Weight) axis coordinate
must be 400 on the 'Regular' instance."""

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

# We then ensure the check detects it when we
# introduce the problem by setting a bad value:
ttFont["fvar"].instances[0].coordinates["wght"] = 500
msg = assert_results_contain(check(ttFont), FAIL, "wght-not-400")
assert msg == (
'The "wght" axis coordinate of the "Regular" instance must be 400.'
" Got 500 instead."
)

# Reload the original font.
ttFont = TTFont("data/test/cabinvfbeta/CabinVFBeta.ttf")
# Change the name of the first instance from 'Regular' (nameID 258)
# to 'Medium' (nameID 259). The font now has no Regular instance.
ttFont["fvar"].instances[0].subfamilyNameID = 259
msg = assert_results_contain(check(ttFont), FAIL, "no-regular-instance")
assert msg == ('"Regular" instance not present.')

# Test with a variable font that doesn't have a 'wght' (Weight) axis.
# The check should yield SKIP.
ttFont = TTFont(TEST_FILE("BadGrades/BadGrades-VF.ttf"))
msg = assert_results_contain(check(ttFont), SKIP, "unfulfilled-conditions")
assert "Unfulfilled Conditions: has_wght_axis" in msg

# Test with an italic variable font. The Italic instance must also be 400
ttFont = TTFont(TEST_FILE("varfont/OpenSans-Italic[wdth,wght].ttf"))
assert_PASS(check(ttFont))

# Now test with a static font.
# The test should be skipped due to an unfulfilled condition.
ttFont = TTFont(TEST_FILE("source-sans-pro/TTF/SourceSansPro-Bold.ttf"))
msg = assert_results_contain(check(ttFont), SKIP, "unfulfilled-conditions")
assert "Unfulfilled Conditions: is_variable_font, has_wght_axis" in msg


@check_id("opentype/varfont/regular_wdth_coord")
def test_check_varfont_regular_wdth_coord(check):
"""The variable font 'wdth' (Width) axis coordinate
must be 100 on the 'Regular' instance."""

# Our reference varfont CabinVFBeta.ttf
# has a good Regular:wdth coordinate
ttFont = TTFont("data/test/cabinvfbeta/CabinVFBeta.ttf")
assert_PASS(check(ttFont))

# We then ensure the check detects it when we
# introduce the problem by setting a bad value:
ttFont["fvar"].instances[0].coordinates["wdth"] = 0
msg = assert_results_contain(check(ttFont), FAIL, "wdth-not-100")
assert msg == (
'The "wdth" axis coordinate of the "Regular" instance must be 100.'
" Got 0 as a default value instead."
)

# Reload the original font.
ttFont = TTFont("data/test/cabinvfbeta/CabinVFBeta.ttf")
# Change the name of the first instance from 'Regular' (nameID 258)
# to 'Medium' (nameID 259). The font now has no Regular instance.
ttFont["fvar"].instances[0].subfamilyNameID = 259
msg = assert_results_contain(check(ttFont), FAIL, "no-regular-instance")
assert msg == ('"Regular" instance not present.')

# Test with a variable font that doesn't have a 'wdth' (Width) axis.
# The check should yield SKIP.
ttFont = TTFont(TEST_FILE("source-sans-pro/VAR/SourceSansVariable-Italic.otf"))
msg = assert_results_contain(check(ttFont), SKIP, "unfulfilled-conditions")
assert "Unfulfilled Conditions: has_wdth_axis" in msg

# Test with an italic variable font. The Italic instance must also be 100
ttFont = TTFont(TEST_FILE("varfont/OpenSans-Italic[wdth,wght].ttf"))
assert_PASS(check(ttFont))

# Now test with a static font.
# The test should be skipped due to an unfulfilled condition.
ttFont = TTFont(TEST_FILE("source-sans-pro/TTF/SourceSansPro-Bold.ttf"))
msg = assert_results_contain(check(ttFont), SKIP, "unfulfilled-conditions")
assert "Unfulfilled Conditions: is_variable_font, has_wdth_axis" in msg


@check_id("opentype/varfont/regular_slnt_coord")
def test_check_varfont_regular_slnt_coord(check):
"""The variable font 'slnt' (Slant) axis coordinate
must be zero on the 'Regular' instance."""

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

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

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

# And with this the check must detect the problem:
msg = assert_results_contain(check(ttFont), FAIL, "slnt-not-0")
assert msg == (
'The "slnt" axis coordinate of the "Regular" instance must be zero.'
" Got 12 as a default value instead."
)

# We correct the slant coordinate value to make the check PASS.
first_instance.coordinates["slnt"] = 0
assert_PASS(check(ttFont))

# Change the name of the first instance from 'Regular' (nameID 258)
# to 'Medium' (nameID 259). The font now has no Regular instance.
first_instance.subfamilyNameID = 259
msg = assert_results_contain(check(ttFont), FAIL, "no-regular-instance")
assert msg == ('"Regular" instance not present.')

# Test with a variable font that doesn't have a 'slnt' (Slant) axis.
# The check should yield SKIP.
ttFont = TTFont(TEST_FILE("source-sans-pro/VAR/SourceSansVariable-Italic.otf"))
msg = assert_results_contain(check(ttFont), SKIP, "unfulfilled-conditions")
assert "Unfulfilled Conditions: has_slnt_axis" in msg

# Now test with a static font.
# The test should be skipped due to an unfulfilled condition.
ttFont = TTFont(TEST_FILE("source-sans-pro/TTF/SourceSansPro-Bold.ttf"))
msg = assert_results_contain(check(ttFont), SKIP, "unfulfilled-conditions")
assert "Unfulfilled Conditions: is_variable_font, has_slnt_axis" in msg


@check_id("opentype/varfont/regular_ital_coord")
def test_check_varfont_regular_ital_coord(check):
"""The variable font 'ital' (Italic) axis coordinate
must be zero on the 'Regular' instance."""

# 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:
first_instance = ttFont["fvar"].instances[0]
first_instance.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:
msg = assert_results_contain(check(ttFont), FAIL, "ital-not-0")
assert msg == (
'The "ital" axis coordinate of the "Regular" instance must be zero.'
" Got 123 as a default value instead."
)

# We correct the italic coordinate value to make the check PASS.
first_instance.coordinates["ital"] = 0
assert_PASS(check(ttFont))

# Change the name of the first instance from 'Regular' (nameID 258)
# to 'Medium' (nameID 259). The font now has no Regular instance.
first_instance.subfamilyNameID = 259
msg = assert_results_contain(check(ttFont), FAIL, "no-regular-instance")
assert msg == ('"Regular" instance not present.')

# Test with a variable font that doesn't have an 'ital' (Italic) axis.
# The check should yield SKIP.
ttFont = TTFont(TEST_FILE("source-sans-pro/VAR/SourceSansVariable-Italic.otf"))
msg = assert_results_contain(check(ttFont), SKIP, "unfulfilled-conditions")
assert "Unfulfilled Conditions: has_ital_axis" in msg

# Now test with a static font.
# The test should be skipped due to an unfulfilled condition.
ttFont = TTFont(TEST_FILE("source-sans-pro/TTF/SourceSansPro-It.ttf"))
msg = assert_results_contain(check(ttFont), SKIP, "unfulfilled-conditions")
assert "Unfulfilled Conditions: is_variable_font, has_ital_axis" in msg


@check_id("opentype/varfont/regular_opsz_coord")
def test_check_varfont_regular_opsz_coord(check):
"""The variable font 'opsz' (Optical Size) axis coordinate
should be between 10 and 16 on the 'Regular' instance."""

# 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:
first_instance = ttFont["fvar"].instances[0]
first_instance.coordinates["opsz"] = 9
# 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,
"opsz-out-of-range",
"with a bad Regular:opsz coordinate (9)...",
)

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

# We then test with good default opsz values:
for value in [10, 11, 12, 13, 14, 15, 16]:
assert_PASS(
check(MockFont(ttFont=ttFont, regular_opsz_coord=value)),
f"with a good Regular:opsz coordinate ({value})...",
)

# Change the name of the first instance from 'Regular' (nameID 258)
# to 'Medium' (nameID 259). The font now has no Regular instance.
first_instance.subfamilyNameID = 259
msg = assert_results_contain(check(ttFont), FAIL, "no-regular-instance")
assert msg == ('"Regular" instance not present.')
44 changes: 44 additions & 0 deletions tests/test_checks_opentype_varfont_distinct_instance_records.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from fontTools.ttLib import TTFont

from conftest import check_id
from fontbakery.status import FAIL, WARN
from fontbakery.codetesting import (
assert_PASS,
assert_results_contain,
)


@check_id("opentype/varfont/distinct_instance_records")
def test_check_varfont_distinct_instance_records(check):
"""All of the instance records in a font should have distinct coordinates
and distinct subfamilyNameID and postScriptName ID values."""

# All of the instance records in the reference varfont are unique
ttFont = TTFont("data/test/cabinvf/Cabin[wdth,wght].ttf")
assert_PASS(check(ttFont), "with a good varfont...")

fvar_table = ttFont["fvar"]
inst_1 = fvar_table.instances[0]
inst_2 = fvar_table.instances[1]
inst_3 = fvar_table.instances[2]
inst_4 = fvar_table.instances[3]

# Make instance 2 the same as instance 1
inst_2.subfamilyNameID = inst_1.subfamilyNameID
inst_2.coordinates["wght"] = inst_1.coordinates["wght"]
msg = assert_results_contain(
check(ttFont), WARN, "repeated-instance-record:Regular"
)
assert msg == "'Regular' is a repeated instance record."

# Make instance 4 the same as instance 3
inst_4.subfamilyNameID = inst_3.subfamilyNameID
inst_4.coordinates["wght"] = inst_3.coordinates["wght"]
msg = assert_results_contain(
check(ttFont), WARN, "repeated-instance-record:SemiBold"
)
assert msg == "'SemiBold' is a repeated instance record."

# Confirm the check yields FAIL if the font doesn't have a required table
del ttFont["name"]
assert_results_contain(check(ttFont), FAIL, "lacks-table")
37 changes: 37 additions & 0 deletions tests/test_checks_opentype_varfont_family_axis_ranges.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from fontTools.ttLib import TTFont

from conftest import check_id
from fontbakery.status import FAIL
from fontbakery.codetesting import (
assert_PASS,
assert_results_contain,
TEST_FILE,
)


@check_id("opentype/varfont/family_axis_ranges")
def test_check_varfont_family_axis_ranges(check):
"""Check that family axis ranges are indentical"""

ttFonts = [
TTFont("data/test/ubuntusansmono/UbuntuMono[wght].ttf"),
TTFont("data/test/ubuntusansmono/UbuntuMono-Italic[wght].ttf"),
]
assert_results_contain(check(ttFonts), FAIL, "axis-range-mismatch")

ttFonts = [
TTFont("data/test/cabinvf/Cabin[wdth,wght].ttf"),
TTFont("data/test/cabinvf/Cabin-Italic[wdth,wght].ttf"),
]
assert_PASS(check(ttFonts), "with good varfont...")


@check_id("opentype/slant_direction")
def test_check_slant_direction(check):
"""Checking direction of slnt axis angles."""

font = TEST_FILE("slant_direction/Cairo_correct_slnt_axis.ttf")
assert_PASS(check(font))

font = TEST_FILE("slant_direction/Cairo_wrong_slnt_axis.ttf")
assert_results_contain(check(font), FAIL, "positive-value-for-clockwise-lean")
47 changes: 47 additions & 0 deletions tests/test_checks_opentype_varfont_foundry_defined_tag_name.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from fontTools.ttLib import TTFont

from conftest import check_id
from fontbakery.status import FAIL, WARN
from fontbakery.codetesting import (
assert_PASS,
assert_results_contain,
)


@check_id("opentype/varfont/foundry_defined_tag_name")
def test_check_varfont_foundry_defined_tag_name(check):
"Validate foundry-defined design-variation axis tag names."

# Our reference varfont CabinVFBeta.ttf has registered tags.
ttFont = TTFont("data/test/cabinvfbeta/CabinVFBeta.ttf")
assert_PASS(check(ttFont), "with a good varfont...")

ttFont["fvar"].axes[0].axisTag = "GOOD"
assert_PASS(check(ttFont), "with a good all uppercase axis tag...")

ttFont["fvar"].axes[0].axisTag = "G009"
assert_PASS(check(ttFont), "with all uppercase + digits...")

ttFont["fvar"].axes[0].axisTag = "ITAL"
assert_results_contain(
check(ttFont),
WARN,
"foundry-defined-similar-registered-name",
"with an uppercase version of registered tag...",
)

ttFont["fvar"].axes[0].axisTag = "nope"
assert_results_contain(
check(ttFont),
FAIL,
"invalid-foundry-defined-tag-first-letter",
"when first letter of axis tag is not uppercase...",
)

ttFont["fvar"].axes[0].axisTag = "N0pe"
assert_results_contain(
check(ttFont),
FAIL,
"invalid-foundry-defined-tag-chars",
"when characters not all uppercase-letters or digits...",
)
Loading

0 comments on commit 3b615af

Please sign in to comment.