|
| 1 | +use std::path::PathBuf; |
| 2 | + |
| 3 | +use font_types::FWord; |
| 4 | +use fontspector_checkapi::{prelude::*, testfont, FileTypeConvert}; |
| 5 | +use itertools::Itertools; |
| 6 | +use read_fonts::TableProvider; |
| 7 | + |
| 8 | +#[check( |
| 9 | + id = "com.google.fonts/check/family/underline_thickness", |
| 10 | + title = "Fonts have consistent underline thickness?", |
| 11 | + rationale = r#" |
| 12 | + Dave C Lemon (Adobe Type Team) recommends setting the underline thickness to be |
| 13 | + consistent across the family. |
| 14 | +
|
| 15 | + If thicknesses are not family consistent, words set on the same line which have |
| 16 | + different styles look strange. |
| 17 | + "#, |
| 18 | + proposal = "legacy:check/008", |
| 19 | + implementation = "all" |
| 20 | +)] |
| 21 | +fn underline_thickness(c: &TestableCollection, _context: &Context) -> CheckFnResult { |
| 22 | + let fonts = TTF.from_collection(c); |
| 23 | + if fonts.len() < 2 { |
| 24 | + return Err(CheckError::Skip { |
| 25 | + code: "no-siblings".to_string(), |
| 26 | + message: "No sibling fonts found".to_string(), |
| 27 | + }); |
| 28 | + } |
| 29 | + let posts: Vec<(&PathBuf, FWord)> = fonts |
| 30 | + .iter() |
| 31 | + .map(|font| { |
| 32 | + ( |
| 33 | + &font.filename, |
| 34 | + font.font() |
| 35 | + .post() |
| 36 | + .map(|post| post.underline_thickness()) |
| 37 | + .unwrap_or_default(), |
| 38 | + ) |
| 39 | + }) |
| 40 | + .collect(); |
| 41 | + Ok(if posts.iter().unique_by(|(_, t)| t).count() == 1 { |
| 42 | + Status::just_one_pass() |
| 43 | + } else { |
| 44 | + let mut message = |
| 45 | + "Underline thickness is inconsistent. Detected underline thickness values are:\n\n" |
| 46 | + .to_string(); |
| 47 | + for (path, thickness) in posts { |
| 48 | + message.push_str(&format!("* {}: {}\n", path.display(), thickness)); |
| 49 | + } |
| 50 | + Status::just_one_fail("inconsistent-underline-thickness", &message) |
| 51 | + }) |
| 52 | +} |
| 53 | + |
| 54 | +#[check( |
| 55 | + id = "com.google.fonts/check/post_table_version", |
| 56 | + rationale = r#" |
| 57 | + Format 2.5 of the 'post' table was deprecated in OpenType 1.3 and |
| 58 | + should not be used. |
| 59 | +
|
| 60 | + According to Thomas Phinney, the possible problem with post format 3 |
| 61 | + is that under the right combination of circumstances, one can generate |
| 62 | + PDF from a font with a post format 3 table, and not have accurate backing |
| 63 | + store for any text that has non-default glyphs for a given codepoint. |
| 64 | +
|
| 65 | + It will look fine but not be searchable. This can affect Latin text with |
| 66 | + high-end typography, and some complex script writing systems, especially |
| 67 | + with higher-quality fonts. Those circumstances generally involve creating |
| 68 | + a PDF by first printing a PostScript stream to disk, and then creating a |
| 69 | + PDF from that stream without reference to the original source document. |
| 70 | + There are some workflows where this applies,but these are not common |
| 71 | + use cases. |
| 72 | +
|
| 73 | + Apple recommends against use of post format version 4 as "no longer |
| 74 | + necessary and should be avoided". Please see the Apple TrueType reference |
| 75 | + documentation for additional details. |
| 76 | +
|
| 77 | + https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6post.html |
| 78 | +
|
| 79 | + Acceptable post format versions are 2 and 3 for TTF and OTF CFF2 builds, |
| 80 | + and post format 3 for CFF builds. |
| 81 | + "#, |
| 82 | + proposal = "legacy:check/015 |
| 83 | + https://github.com/google/fonts/issues/215 |
| 84 | + https://github.com/fonttools/fontbakery/issues/263 |
| 85 | + https://github.com/fonttools/fontbakery/issues/3635", |
| 86 | + title = "Font has correct post table version?" |
| 87 | +)] |
| 88 | +fn post_table_version(t: &Testable, _context: &Context) -> CheckFnResult { |
| 89 | + let f = testfont!(t); |
| 90 | + let version = f |
| 91 | + .font() |
| 92 | + .post() |
| 93 | + .map(|post| post.version().to_major_minor()) |
| 94 | + .unwrap_or((0, 0)); |
| 95 | + let is_cff = f.has_table(b"CFF "); |
| 96 | + Ok(match (is_cff, version) { |
| 97 | + (true, (3, _)) => Status::just_one_pass(), |
| 98 | + (true, _) => Status::just_one_fail("post-table-version", "CFF fonts must contain post format 3 table."), |
| 99 | + (false, (3, _)) => Status::just_one_warn("post-table-version","Post table format 3 use has niche use case problems. Please review the check rationale for additional details."), |
| 100 | + (_, (2, 5)) => Status::just_one_fail("post-table-version", "Post format 2.5 was deprecated in OpenType 1.3 and should not be used."), |
| 101 | + (_, (4, _)) => Status::just_one_fail("post-table-version", "According to Apple documentation, post format 4 tables are no longer necessary and should not be used."), |
| 102 | + (_, _) => Status::just_one_pass(), |
| 103 | + }) |
| 104 | +} |
0 commit comments