Skip to content

Commit

Permalink
New check: overlapping_path_segments
Browse files Browse the repository at this point in the history
"Check there are no overlapping path segments"

'overlapping_path_segments'
Added to the Universal profile.

Some rasterizers encounter difficulties when rendering glyphs with
overlapping path segments.

A path segment is a section of a path defined by two on-curve points.
When two segments share the same coordinates, they are considered
overlapping.

(PR #4853)
  • Loading branch information
m4rc1e authored and felipesanches committed Oct 16, 2024
1 parent 1a24828 commit 2832c1b
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ A more detailed list of changes is available in the corresponding milestones for
### Noteworthy code-changes
- **[FontBakeryCondition:remote_styles]:** Fetching static fonts no longer raises an error. (PR # #4863)

### New checks
#### Added to the Universal profile
- **[overlapping_path_segments]:** Check there are no overlapping path segments. (PR #4853)

### Migration of checks
#### Moved from OpenType to Universal profile
- **[name/no_copyright_on_description]**: Adding copyright information to the description name entry is bad practice but is not a breach of specification. (issue #4857)
Expand Down
39 changes: 38 additions & 1 deletion Lib/fontbakery/checks/outline.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from fontbakery.callable import condition, check
from fontbakery.testable import Font
from fontbakery.status import PASS, WARN
from fontbakery.status import PASS, WARN, FAIL
from fontbakery.message import Message
from fontbakery.utils import bullet_list

Expand Down Expand Up @@ -382,3 +382,40 @@ def bounds_contains(bb1, bb2):
f"The following glyphs have a counter-clockwise outer contour:\n\n"
f"{formatted_list}",
)


@check(
id="overlapping_path_segments",
rationale="""
Some rasterizers encounter difficulties when rendering glyphs with
overlapping path segments.
A path segment is a section of a path defined by two on-curve points.
When two segments share the same coordinates, they are considered
overlapping.
""",
conditions=["outlines_dict", "is_ttf"],
proposal="https://github.com/google/fonts/issues/7594#issuecomment-2401909084",
)
def check_overlapping_path_segments(ttFont, outlines_dict, config):
"""Check there are no overlapping path segments"""
failed = []
for glyph, outlines in outlines_dict.items():
seen = set()
for p in outlines:
for seg in p.asSegments():
normal = ((seg.start.x, seg.start.y), (seg.end.x, seg.end.y))
flipped = ((seg.end.x, seg.end.y), (seg.start.x, seg.start.y))
if normal in seen or flipped in seen:
failed.append(
f"{glyph[1]}: {seg} has the same coordinates as a previous segment."
)
seen.add(normal)
if failed:
yield FAIL, Message(
"overlapping-path-segments",
f"The following glyphs have overlapping path segments:\n\n"
f"{bullet_list(config, failed, bullet='*')}",
)
else:
yield PASS, "No overlapping path segments found."
3 changes: 3 additions & 0 deletions Lib/fontbakery/profiles/adobefonts.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"pending_review": [
"notofonts/cmap/alien_codepoints", # Note: These two checks had not been previously marked as permanently excluded,
"notofonts/unicode_range_bits", # so maybe there's still some change they may be considered useful here?
#
"opentype/caret_slope",
"opentype/dsig",
"opentype/fsselection",
Expand All @@ -41,6 +42,7 @@
"opentype/varfont/family_axis_ranges",
"opentype/varfont/ital_range",
"opentype/vendor_id",
#
"alt_caron",
"arabic_high_hamza",
"arabic_spacing_symbols",
Expand Down Expand Up @@ -70,6 +72,7 @@
"name/italic_names",
"no_debugging_tables",
"no_mac_entries",
"overlapping_path_segments",
"render_own_name",
"smart_dropout",
"soft_hyphen",
Expand Down
1 change: 1 addition & 0 deletions Lib/fontbakery/profiles/fontbureau.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"name/family_and_style_max_length",
"name/ascii_only_entries",
"no_mac_entries",
"overlapping_path_segments",
"render_own_name",
"smart_dropout",
"stylisticset_description",
Expand Down
1 change: 1 addition & 0 deletions Lib/fontbakery/profiles/fontwerk.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
],
"pending_review": [
"googlefonts/axes_match",
"overlapping_path_segments",
"typographic_family_name",
"vtt_volt_data", # very similar to vttclean, may be a good idea to merge them.
#
Expand Down
2 changes: 2 additions & 0 deletions Lib/fontbakery/profiles/microsoft.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"opentype/cff_ascii_strings",
"opentype/slant_direction",
"opentype/weight_class_fvar",
#
"cjk_not_enough_glyphs",
"cmap/format_12",
"color_cpal_brightness",
Expand Down Expand Up @@ -38,6 +39,7 @@
"name/family_and_style_max_length",
"no_debugging_tables",
"no_mac_entries",
"overlapping_path_segments",
"render_own_name",
"smart_dropout",
"stylisticset_description",
Expand Down
1 change: 1 addition & 0 deletions Lib/fontbakery/profiles/typenetwork.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"legacy_accents",
"name/ascii_only_entries",
"no_debugging_tables",
"overlapping_path_segments",
"render_own_name",
"tabular_kerning",
"typoascender_exceeds_Agrave",
Expand Down
1 change: 1 addition & 0 deletions Lib/fontbakery/profiles/universal.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"no_mac_entries",
"os2_metrics_match_hhea",
"ots",
"overlapping_path_segments",
"required_tables",
"render_own_name",
"rupee",
Expand Down
Binary file not shown.
16 changes: 15 additions & 1 deletion tests/test_checks_outline.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from fontTools.ttLib import TTFont
from fontbakery.status import WARN, SKIP
from fontbakery.status import WARN, SKIP, FAIL
from fontbakery.codetesting import (
assert_results_contain,
CheckTester,
Expand Down Expand Up @@ -154,3 +154,17 @@ def test_check_outline_direction():

font = TEST_FILE("wonky_paths/OutlineTest.ttf")
assert_PASS(check(font))


def test_check_overlapping_path_segments():
check = CheckTester("overlapping_path_segments")

# Check a font that contains overlapping path segments
filename = TEST_FILE("overlapping_path_segments/Figtree[wght].ttf")
results = check(filename)
assert_results_contain(results, FAIL, "overlapping-path-segments")

# check a font that doesn't contain overlapping path segments
filename = TEST_FILE("merriweather/Merriweather-Regular.ttf")
results = check(filename)
assert_PASS(results)

0 comments on commit 2832c1b

Please sign in to comment.