Skip to content

Commit 78d7e92

Browse files
committed
shape_languages
1 parent 9ddede9 commit 78d7e92

File tree

6 files changed

+98
-7
lines changed

6 files changed

+98
-7
lines changed

fontspector-py/tests/test_checks_googlefonts.py

-6
Original file line numberDiff line numberDiff line change
@@ -3796,16 +3796,10 @@ def test_check_metadata_unreachable_subsetting(check):
37963796
)
37973797

37983798

3799-
@pytest.mark.skip("Check not ported yet.")
38003799
@check_id("googlefonts/glyphsets/shape_languages")
38013800
def test_check_shape_languages(check):
38023801
"""Shapes languages in all GF glyphsets."""
38033802

3804-
# FIXME: With the latest version of shaperglot (v0.6.3), our reference
3805-
# Cabin-Regular.ttf is not fully passing anymore:
3806-
# test_font = TTFont(TEST_FILE("cabin/Cabin-Regular.ttf"))
3807-
# assert_PASS(check(test_font))
3808-
38093803
test_font = TTFont(TEST_FILE("BadGrades/BadGrades-VF.ttf"))
38103804
assert_results_contain(check(test_font), FAIL, "no-glyphset-supported")
38113805

profile-googlefonts/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ google-fonts-axisregistry = { git = "https://github.com/googlefonts/axisregistry
1818
google-fonts-languages = "0"
1919
google-fonts-subsets = "0"
2020
google-fonts-glyphsets = { git = "https://github.com/googlefonts/glyphsets" }
21+
shaperglot = "1"
2122
indexmap = { workspace = true }
2223
itertools = { workspace = true }
2324
markdown-table = { workspace = true }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
mod shape_languages;
2+
pub use shape_languages::shape_languages;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
use fontspector_checkapi::{prelude::*, testfont, FileTypeConvert};
2+
use google_fonts_glyphsets::{get_glyphset_coverage, languages_per_glyphset};
3+
use hashbrown::HashMap;
4+
use markdown_table::MarkdownTable;
5+
use shaperglot::{Checker, Languages, ResultCode};
6+
7+
fn table_of_results(
8+
context: &Context,
9+
_title: &str,
10+
results: &HashMap<String, Vec<String>>,
11+
) -> Result<String, CheckError> {
12+
let table = MarkdownTable::new(
13+
results
14+
.iter()
15+
.map(|(message, languages)| vec![message.to_string(), bullet_list(context, languages)])
16+
.collect(),
17+
);
18+
table
19+
.as_markdown()
20+
.map_err(|_| CheckError::Error("Can't happen (table creation failed)".to_string()))
21+
}
22+
#[check(
23+
id = "googlefonts/glyphsets/shape_languages",
24+
rationale = "
25+
This check uses a heuristic to determine which GF glyphsets a font supports.
26+
Then it checks the font for correct shaping behaviour for all languages in
27+
those glyphsets.
28+
",
29+
proposal = "https://github.com/googlefonts/fontbakery/issues/4147",
30+
title = "Shapes languages in all GF glyphsets."
31+
)]
32+
fn shape_languages(t: &Testable, context: &Context) -> CheckFnResult {
33+
let f = testfont!(t);
34+
let checker = Checker::new(&t.contents).map_err(|e| CheckError::Error(e.to_string()))?;
35+
let languages = Languages::new();
36+
let codepoints = f.codepoints(Some(context));
37+
let mut warns = HashMap::new();
38+
let mut fails = HashMap::new();
39+
let mut any_glyphset_supported = false;
40+
for (glyphset, coverage) in get_glyphset_coverage(&codepoints).iter() {
41+
if coverage.fraction > 0.8 {
42+
any_glyphset_supported = true;
43+
for language_code in languages_per_glyphset(glyphset)?.iter() {
44+
if let Some(language) = languages.get_language(language_code) {
45+
let reporter = checker.check(language);
46+
let name = language.name();
47+
let language_string = format!("{} ({})", language_code, name);
48+
for result in reporter.iter() {
49+
let message = result.to_string();
50+
if result.status == ResultCode::Warn {
51+
warns
52+
.entry(message)
53+
.or_insert(vec![])
54+
.push(language_string.clone());
55+
} else if result.status == ResultCode::Fail {
56+
fails
57+
.entry(message)
58+
.or_insert(vec![])
59+
.push(language_string.clone());
60+
}
61+
}
62+
}
63+
}
64+
}
65+
}
66+
67+
let mut problems = vec![];
68+
if !fails.is_empty() {
69+
problems.push(Status::fail(
70+
"failed-language-shaping",
71+
&format!(
72+
"Failed language shaping:\n{}",
73+
table_of_results(context, "FAIL", &fails)?
74+
),
75+
));
76+
}
77+
if !warns.is_empty() {
78+
problems.push(Status::warn(
79+
"warning-language-shaping",
80+
&format!(
81+
"Warning language shaping:\n{}",
82+
table_of_results(context, "WARN", &warns)?
83+
),
84+
));
85+
}
86+
if !any_glyphset_supported {
87+
problems.push(Status::fail("no-glyphset-supported",
88+
"No GF glyphset was found to be supported >80%, so language shaping support couldn't get checked.",
89+
));
90+
}
91+
92+
return_result(problems)
93+
}

profile-googlefonts/src/checks/googlefonts/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,4 @@ mod vertical_metrics;
5454
pub use vertical_metrics::vertical_metrics;
5555
mod cjk_vertical_metrics;
5656
pub use cjk_vertical_metrics::cjk_vertical_metrics;
57+
pub mod glyphsets;

profile-googlefonts/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl fontspector_checkapi::Plugin for GoogleFonts {
8383
.add_and_register_check(checks::googlefonts::metadata::valid_nameid25)
8484
// .add_and_register_check(checks::googlefonts::metadata::weightclass)
8585
.add_section("Glyphset Checks")
86-
// .add_and_register_check(checks::googlefonts::glyphsets::shape_languages)
86+
.add_and_register_check(checks::googlefonts::glyphsets::shape_languages)
8787
.add_and_register_check(checks::googlefonts::tofu)
8888
.add_section("Description Checks");
8989

0 commit comments

Comments
 (0)