Skip to content

Commit 2849571

Browse files
committed
Check that Arabic spacing symbols U+FBB2–FBC1 aren't classified as marks.
Unicode has a few spacing symbols representing Arabic dots and other marks, but they are purposefully not classified as marks. Many fonts mistakenly classify them as marks, making them unsuitable for their original purpose as stand-alone symbols to used in pedagogical contexts discussing Arabic consonantal marks. com.google.fonts/check/arabic_spacing_symbols Added to Universal profile. (Ported from fonttools/fontbakery#4295)
1 parent 752d559 commit 2849571

File tree

4 files changed

+81
-1
lines changed

4 files changed

+81
-1
lines changed

fontspector-checkapi/src/font.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
use crate::{constants::RIBBI_STYLE_NAMES, filetype::FileTypeConvert, FileType, Testable};
2-
use read_fonts::{tables::os2::SelectionFlags, TableProvider};
2+
use read_fonts::{
3+
tables::cmap::Cmap,
4+
tables::gdef::ClassDef,
5+
tables::os2::SelectionFlags,
6+
TableProvider,
7+
};
38
use skrifa::{
49
charmap::Charmap,
510
font::FontRef,
@@ -68,6 +73,16 @@ impl TestFont {
6873
Ok(os2.fs_selection())
6974
}
7075

76+
pub fn get_gdef_glyph_class_def(&self) -> Result<ClassDef, Box<dyn Error>> {
77+
let gdef = self.font().gdef()?;
78+
Ok(gdef.glyph_class_def().unwrap()?)
79+
}
80+
81+
pub fn get_cmap(&self) -> Result<Cmap, Box<dyn Error>> {
82+
let cmap = self.font().cmap()?;
83+
Ok(cmap)
84+
}
85+
7186
pub fn get_name_entry_strings(&self, name_id: StringId) -> LocalizedStrings {
7287
self.font().localized_strings(name_id)
7388
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
use fontspector_checkapi::{prelude::*, FileTypeConvert};
2+
3+
const ARABIC_SPACING_SYMBOLS: [u16; 17] = [
4+
0xFBB2, // Dot Above
5+
0xFBB3, // Dot Below
6+
0xFBB4, // Two Dots Above
7+
0xFBB5, // Two Dots Below
8+
0xFBB6, // Three Dots Above
9+
0xFBB7, // Three Dots Below
10+
0xFBB8, // Three Dots Pointing Downwards Above
11+
0xFBB9, // Three Dots Pointing Downwards Below
12+
0xFBBA, // Four Dots Above
13+
0xFBBB, // Four Dots Below
14+
0xFBBC, // Double Vertical Bar Below
15+
0xFBBD, // Two Dots Vertically Above
16+
0xFBBE, // Two Dots Vertically Below
17+
0xFBBF, // Ring
18+
0xFBC0, // Small Tah Above
19+
0xFBC1, // Small Tah Below
20+
0xFBC2, // Wasla Above
21+
];
22+
23+
fn arabic_spacing_symbols(t: &Testable) -> StatusList {
24+
let mut problems: Vec<Status> = vec![];
25+
let f = TTF.from_testable(t).expect("Not a TTF file");
26+
let cmap = f.get_cmap().unwrap();
27+
let class_def = f.get_gdef_glyph_class_def().unwrap();
28+
29+
for codepoint in ARABIC_SPACING_SYMBOLS {
30+
let gid = cmap.map_codepoint(codepoint);
31+
if gid.is_some() && class_def.get(gid.unwrap()) == 3 {
32+
problems.push(Status::fail(&format!(
33+
"U+{:04X} is defined in GDEF as a mark (class 3).", codepoint)));
34+
}
35+
}
36+
37+
if problems.is_empty() {
38+
Status::just_one_pass()
39+
} else {
40+
return_result(problems)
41+
}
42+
}
43+
44+
pub const CHECK_ARABIC_SPACING_SYMBOLS: Check = Check {
45+
id: "com.google.fonts/check/arabic_spacing_symbols",
46+
title: "Check that Arabic spacing symbols U+FBB2–FBC1 aren't classified as marks.",
47+
rationale: "
48+
Unicode has a few spacing symbols representing Arabic dots and other marks,
49+
but they are purposefully not classified as marks.
50+
51+
Many fonts mistakenly classify them as marks, making them unsuitable
52+
for their original purpose as stand-alone symbols to used in pedagogical
53+
contexts discussing Arabic consonantal marks.
54+
",
55+
proposal: "https://github.com/googlefonts/fontbakery/issues/4295",
56+
check_one: Some(&arabic_spacing_symbols),
57+
check_all: None,
58+
applies_to: "TTF",
59+
hotfix: None,
60+
fix_source: None,
61+
};

profile-universal/src/checks/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
mod arabic_spacing_symbols;
12
mod bold_italic_unique;
23
mod name_trailing_spaces;
34
mod required_tables;
45
mod unwanted_tables;
6+
pub use arabic_spacing_symbols::CHECK_ARABIC_SPACING_SYMBOLS;
57
// pub use bold_italic_unique::CHECK_BOLD_ITALIC_UNIQUE;
68
pub use name_trailing_spaces::CHECK_NAME_TRAILING_SPACES;
79
pub use required_tables::CHECK_REQUIRED_TABLES;

profile-universal/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pub struct Universal;
55

66
impl fontspector_checkapi::Plugin for Universal {
77
fn register(&self, cr: &mut Registry) -> Result<(), String> {
8+
cr.register_check(checks::CHECK_ARABIC_SPACING_SYMBOLS);
89
cr.register_check(checks::CHECK_NAME_TRAILING_SPACES);
910
cr.register_check(checks::CHECK_UNWANTED_TABLES);
1011
cr.register_check(checks::CHECK_REQUIRED_TABLES);
@@ -14,6 +15,7 @@ impl fontspector_checkapi::Plugin for Universal {
1415
r#"
1516
[sections]
1617
"Universal Profile Checks" = [
18+
"com.google.fonts/check/arabic_spacing_symbols",
1719
"com.google.fonts/check/name/trailing_spaces",
1820
"com.google.fonts/check/unwanted_tables",
1921
"com.google.fonts/check/required_tables",

0 commit comments

Comments
 (0)