Skip to content

Commit 5d37eb3

Browse files
committed
new check: arabic_spacing_symbols
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 4995194 commit 5d37eb3

File tree

4 files changed

+81
-2
lines changed

4 files changed

+81
-2
lines changed

src/checks/arabic_spacing_symbols.rs

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

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 unwanted_tables;
45
mod required_tables;
6+
pub use arabic_spacing_symbols::ARABIC_SPACING_SYMBOLS_CHECK;
57
pub use bold_italic_unique::BOLD_ITALIC_UNIQUE_CHECK;
68
pub use name_trailing_spaces::NAME_TRAILING_SPACES_CHECK;
79
pub use unwanted_tables::UNWANTED_TABLES_CHECK;

src/font.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
use crate::constants::RIBBI_STYLE_NAMES;
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
font::FontRef,
510
string::{LocalizedStrings, StringId},
@@ -37,6 +42,16 @@ impl TestFont {
3742
Ok(os2.fs_selection())
3843
}
3944

45+
pub(crate) fn get_gdef_glyph_class_def(&self) -> Result<ClassDef, Box<dyn Error>> {
46+
let gdef = self.font().gdef()?;
47+
Ok(gdef.glyph_class_def().unwrap()?)
48+
}
49+
50+
pub(crate) fn get_cmap(&self) -> Result<Cmap, Box<dyn Error>> {
51+
let cmap = self.font().cmap()?;
52+
Ok(cmap)
53+
}
54+
4055
pub fn get_name_entry_strings(&self, name_id: StringId) -> LocalizedStrings {
4156
self.font().localized_strings(name_id)
4257
}

src/universal.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use crate::checks::*;
22
use crate::Check;
33

4-
pub const UNIVERSAL_PROFILE: [Check<'_>; 4] = [
4+
pub const UNIVERSAL_PROFILE: [Check<'_>; 5] = [
5+
ARABIC_SPACING_SYMBOLS_CHECK,
56
BOLD_ITALIC_UNIQUE_CHECK,
67
NAME_TRAILING_SPACES_CHECK,
78
UNWANTED_TABLES_CHECK,

0 commit comments

Comments
 (0)