Skip to content

Commit dd4af2c

Browse files
committed
Check that Arabic spacing symbols 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 b8c42b4 commit dd4af2c

File tree

4 files changed

+80
-0
lines changed

4 files changed

+80
-0
lines changed

fontspector-checkapi/src/font.rs

+12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::{filetype::FileTypeConvert, FileType, Testable};
22
use read_fonts::{
33
tables::{os2::SelectionFlags, post::DEFAULT_GLYPH_NAMES},
4+
tables::cmap::Cmap,
5+
tables::gdef::Gdef,
46
types::Version16Dot16,
57
TableProvider,
68
};
@@ -66,6 +68,16 @@ impl TestFont<'_> {
6668
self.font().table_data(Tag::new(table)).is_some()
6769
}
6870

71+
pub fn get_cmap(&self) -> Result<Cmap, Box<dyn Error>> {
72+
let cmap = self.font().cmap()?;
73+
Ok(cmap)
74+
}
75+
76+
pub fn get_gdef(&self) -> Result<Gdef, Box<dyn Error>> {
77+
let gdef = self.font().gdef()?;
78+
Ok(gdef)
79+
}
80+
6981
pub fn get_os2_fsselection(&self) -> Result<SelectionFlags, Box<dyn Error>> {
7082
let os2 = self.font().os2()?;
7183
Ok(os2.fs_selection())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
use fontspector_checkapi::{prelude::*, testfont, 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+
#[check(
24+
id = "com.google.fonts/check/arabic_spacing_symbols",
25+
title = "Check that Arabic spacing symbols U+FBB2–FBC1 aren't classified as marks.",
26+
rationale = "
27+
Unicode has a few spacing symbols representing Arabic dots and other marks,
28+
but they are purposefully not classified as marks.
29+
30+
Many fonts mistakenly classify them as marks, making them unsuitable
31+
for their original purpose as stand-alone symbols to used in pedagogical
32+
contexts discussing Arabic consonantal marks.
33+
",
34+
proposal = "https://github.com/googlefonts/fontbakery/issues/4295",
35+
)]
36+
fn arabic_spacing_symbols(t: &Testable, _context: &Context) -> CheckFnResult {
37+
let mut problems: Vec<Status> = vec![];
38+
let f = testfont!(t);
39+
let cmap = f.get_cmap()
40+
.map_err(|_| CheckError::Error("Font lacks a cmap table".to_string()))?;
41+
let gdef = f.get_gdef()
42+
.map_err(|_| CheckError::Error("Font lacks a gdef table".to_string()))?;
43+
44+
let _class_def = match gdef.glyph_class_def() {
45+
None => return return_result(problems),
46+
Some(d) => {
47+
d.map_err(|e| CheckError::Error(format!("Some classDef error: {}", e)))?;
48+
}
49+
};
50+
51+
for codepoint in ARABIC_SPACING_SYMBOLS {
52+
let gid = cmap.map_codepoint(codepoint);
53+
if gid.is_some()
54+
// && class_def.get(gid.ok_or("Failed to read gid")?) == 3
55+
{
56+
problems.push(Status::fail("gdef-mark", &format!(
57+
"U+{:04X} is defined in GDEF as a mark (class 3).", codepoint)));
58+
}
59+
}
60+
61+
if problems.is_empty() {
62+
Ok(Status::just_one_pass())
63+
} else {
64+
return_result(problems)
65+
}
66+
}

profile-universal/src/checks/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod arabic_spacing_symbols;
12
pub mod bold_italic_unique;
23
pub mod fvar;
34
pub mod glyphnames;

profile-universal/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub struct Universal;
66

77
impl fontspector_checkapi::Plugin for Universal {
88
fn register(&self, cr: &mut Registry) -> Result<(), String> {
9+
cr.register_check(checks::arabic_spacing_symbols::arabic_spacing_symbols);
910
cr.register_check(checks::fvar::axis_ranges_correct);
1011
cr.register_check(checks::fvar::regular_coords_correct);
1112
cr.register_check(checks::glyphnames::valid_glyphnames);

0 commit comments

Comments
 (0)