From 881ff1b3a5f7b16b2e8051de57526f1a66283e60 Mon Sep 17 00:00:00 2001 From: Simon Cozens Date: Tue, 29 Mar 2022 09:59:10 +0100 Subject: [PATCH 1/7] All Noto fonts should pass GF checks (since they're also intended to be Google Fonts) --- Lib/fontbakery/profiles/notofonts.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Lib/fontbakery/profiles/notofonts.py b/Lib/fontbakery/profiles/notofonts.py index bc080429ee..3addb47e73 100644 --- a/Lib/fontbakery/profiles/notofonts.py +++ b/Lib/fontbakery/profiles/notofonts.py @@ -1,4 +1,4 @@ -from fontbakery.profiles.universal import UNIVERSAL_PROFILE_CHECKS +from fontbakery.profiles.googlefonts import GOOGLEFONTS_PROFILE_CHECKS from fontbakery.section import Section from fontbakery.status import WARN, PASS #, INFO, ERROR, SKIP, FAIL from fontbakery.callable import check #, disable @@ -10,13 +10,12 @@ MacintoshEncodingID) from .googlefonts_conditions import * # pylint: disable=wildcard-import,unused-wildcard-import -profile_imports = ('fontbakery.profiles.universal',) # Maybe this should be .googlefonts instead... +profile_imports = ('fontbakery.profiles.googlefonts',) profile = profile_factory(default_section=Section("Noto Fonts")) -# Maybe this should be GOOGLEFONTS_PROFILE_CHECKS instead... NOTOFONTS_PROFILE_CHECKS = \ - UNIVERSAL_PROFILE_CHECKS + [ + GOOGLEFONTS_PROFILE_CHECKS + [ 'com.google.fonts/check/cmap/unexpected_subtables', 'com.google.fonts/check/unicode_range_bits', ] From 962bacc107ba4925e5009f9ee51eda07af4169cb Mon Sep 17 00:00:00 2001 From: Simon Cozens Date: Tue, 29 Mar 2022 14:47:15 +0100 Subject: [PATCH 2/7] Some Noto fonts refer to "Google Inc" --- Lib/fontbakery/profiles/googlefonts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/fontbakery/profiles/googlefonts.py b/Lib/fontbakery/profiles/googlefonts.py index e236810343..228b9a6b31 100644 --- a/Lib/fontbakery/profiles/googlefonts.py +++ b/Lib/fontbakery/profiles/googlefonts.py @@ -2374,7 +2374,7 @@ def com_google_fonts_check_metadata_valid_post_script_name_values(font_metadata, EXPECTED_COPYRIGHT_PATTERN = \ -r'copyright [0-9]{4}(\-[0-9]{4})? (the .* project authors \([^\@]*\)|google llc. all rights reserved)' +r'copyright [0-9]{4}(\-[0-9]{4})? (the .* project authors \([^\@]*\)|google (inc|llc). all rights reserved)' @check( id = 'com.google.fonts/check/metadata/valid_copyright', From 89a5b11d582f343f9bda8c726a22a03aa742a1e2 Mon Sep 17 00:00:00 2001 From: Simon Cozens Date: Tue, 29 Mar 2022 14:59:32 +0100 Subject: [PATCH 3/7] Fill out Noto profile with checks from notolint --- Lib/fontbakery/profiles/notofonts.py | 426 ++++++++++++++++++++++++++- 1 file changed, 423 insertions(+), 3 deletions(-) diff --git a/Lib/fontbakery/profiles/notofonts.py b/Lib/fontbakery/profiles/notofonts.py index 3addb47e73..9276814df9 100644 --- a/Lib/fontbakery/profiles/notofonts.py +++ b/Lib/fontbakery/profiles/notofonts.py @@ -1,6 +1,8 @@ +import re + from fontbakery.profiles.googlefonts import GOOGLEFONTS_PROFILE_CHECKS from fontbakery.section import Section -from fontbakery.status import WARN, PASS #, INFO, ERROR, SKIP, FAIL +from fontbakery.status import WARN, PASS, FAIL, SKIP #, INFO, ERROR from fontbakery.callable import check #, disable from fontbakery.message import Message from fontbakery.fonts_profile import profile_factory @@ -10,16 +12,114 @@ MacintoshEncodingID) from .googlefonts_conditions import * # pylint: disable=wildcard-import,unused-wildcard-import -profile_imports = ('fontbakery.profiles.googlefonts',) +profile_imports = [ + 'fontbakery.profiles.googlefonts', + ('.shared_conditions', ('glyph_metrics_stats', 'preferred_cmap', 'unicoderange')) +] + profile = profile_factory(default_section=Section("Noto Fonts")) +profile.configuration_defaults = { + "com.google.fonts/check/file_size": { + "WARN_SIZE": 1 * 1024 * 1024, + "FAIL_SIZE": 16 * 1024 * 1024 + } +} NOTOFONTS_PROFILE_CHECKS = \ GOOGLEFONTS_PROFILE_CHECKS + [ 'com.google.fonts/check/cmap/unexpected_subtables', 'com.google.fonts/check/unicode_range_bits', + 'com.google.fonts/check/name/noto_manufacturer', + 'com.google.fonts/check/name/noto_designer', + 'com.google.fonts/check/name/noto_trademark', + 'com.google.fonts/check/cmap/format_12', + 'com.google.fonts/check/os2/noto_vendor', + 'com.google.fonts/check/hmtx/encoded_latin_digits', + 'com.google.fonts/check/hmtx/comma_period', + 'com.google.fonts/check/hmtx/whitespace_advances', + 'com.google.fonts/check/cmap/alien_codepoints', +] + + +# For builds which target Google Fonts, we do want these checks, but as part of +# onboarding we will be running check-googlefonts on such builds. +# On other builds (e.g. targetting Android), we still want most of the Google +# strictures but size is a premium and we will be expecting to deliver a +# "minimal" font, so we accept the fact that there will be no Latin set and no +# hinting information at all. +SKIPPED_CHECKS = [ + 'com.google.fonts/check/render_own_name', + 'com.google.fonts/check/glyph_coverage', + 'com.google.fonts/check/smart_dropout', + 'com.google.fonts/check/gasp', +] + +NOTOFONTS_PROFILE_CHECKS = list(filter(lambda c: c not in SKIPPED_CHECKS, NOTOFONTS_PROFILE_CHECKS)) + +TRADEMARK = r"(Noto|Arimo|Tinos) is a trademark of Google (Inc|LLC)" +NOTO_URL = "http://www.google.com/get/noto/" # Vendor URL + +MANUFACTURERS_URLS = { + "Adobe Systems Incorporated": "http://www.adobe.com/type/", + "Ek Type": "http://www.ektype.in", + "Monotype Imaging Inc.": "http://www.monotype.com/studio", + "JamraPatel LLC": "http://www.jamra-patel.com", + "Danh Hong": "http://www.khmertype.org", + "Google LLC": "http://www.google.com/get/noto/", + "Dalton Maag Ltd": "http://www.daltonmaag.com/", + "Lisa Huang": "http://www.lisahuang.work", + "Mangu Purty": "", + "LiuZhao Studio": "", +} + +NOTO_DESIGNERS = [ + "Nadine Chahine - Monotype Design Team", + "Jelle Bosma - Monotype Design Team", + "Danh Hong and the Monotype Design Team", + "Indian Type Foundry and the Monotype Design Team", + "Ben Mitchell and the Monotype Design Team", + "Vaibhav Singh and the Monotype Design Team", + "Universal Thirst, Indian Type Foundry and the Monotype Design Team", + "Monotype Design Team", + "Ek Type & Mukund Gokhale", + "Ek Type", + "JamraPatel", + "Dalton Maag Ltd", + "Amélie Bonet and Sol Matas", + "Ben Nathan", + "Indian type Foundry, Jelle Bosma, Monotype Design Team", + "Indian Type Foundry, Tom Grace, and the Monotype Design Team", + "Jelle Bosma - Monotype Design Team, Universal Thirst", + "Juan Bruce, Universal Thirst, Indian Type Foundry and the Monotype Design Team.", + "Lisa Huang", + "Mangu Purty", + "Mark Jamra, Neil Patel", + "Monotype Design Team (Regular), Sérgio L. Martins (other weights)", + "Monotype Design Team 2013. Revised by David WIlliams 2020", + "Monotype Design Team and DaltonMaag", + "Monotype Design Team and Neelakash Kshetrimayum", + "Monotype Design Team, Akaki Razmadze", + "Monotype Design Team, Lewis McGuffie", + "Monotype Design Team, Nadine Chahine and Nizar Qandah", + "Monotype Design Team, Sérgio Martins", + "Monotype Design Team. David Williams.", + "Patrick Giasson and the Monotype Design Team", + "David Williams", + "LIU Zhao", + "Steve Matteson", + "Juan Bruce", + "Sérgio Martins", + "Lewis McGuffie", + "YANG Xicheng", ] +def _get_advance_width_for_char(ttFont, ch): + cp = ord(ch) + cmap = ttFont.getBestCmap() + if cp not in cmap: + return None + return ttFont["hmtx"][cmap[cp]][0] @check( id = 'com.google.fonts/check/cmap/unexpected_subtables', @@ -113,5 +213,325 @@ def com_google_fonts_check_unicode_range_bits(ttFont, unicoderange, preferred_cm f'UnicodeRange bit {bit} "{range_name}" should be {set_unset} because' f' cmap has {num_chars} of the {range_size} codepoints in this range.') -profile.auto_register(globals()) + +@check( + id = 'com.google.fonts/check/name/noto_manufacturer', + rationale = """ + Noto fonts must contain known manufacturer and manufacturer URL + entries in the name table. + """, +) +def com_google_fonts_check_noto_manufacturer(ttFont): + """Ensure the manufacturer is a known Noto manufacturer and the URL is correct.""" + from fontbakery.utils import get_name_entry_strings + bad = False + manufacturers = get_name_entry_strings(ttFont, NameID.MANUFACTURER_NAME) + good_manufacturer = None + if not manufacturers: + bad = True + yield FAIL,\ + Message("no-manufacturer", + "The font contained no manufacturer name" + ) + + manufacturer_re = "|".join(MANUFACTURERS_URLS.keys()) + for manufacturer in manufacturers: + m = re.search(manufacturer_re, manufacturer) + if m: + good_manufacturer = m[0] + else: + bad = True + yield WARN,\ + Message("unknown-manufacturer", + f"The font's manufacturer name '{manufacturer}' was " + "not a known Noto font manufacturer" + ) + + designer_urls = get_name_entry_strings(ttFont, NameID.DESIGNER_URL) + if not designer_urls: + bad = True + yield WARN,\ + Message("no-designer-urls", + "The font contained no designer URL" + ) + if good_manufacturer: + expected_url = MANUFACTURERS_URLS[good_manufacturer] + for designer_url in designer_urls: + if designer_url != expected_url: + yield WARN,\ + Message("bad-designer-url", + f"The font's designer URL was '{designer_url}' " + f"but should have been '{expected_url}'" + ) + if not bad: + yield PASS, "The manufacturer name and designer URL entries were valid" + +@check( + id = 'com.google.fonts/check/name/noto_designer', + rationale = """ + Noto fonts must contain known designer entries in the name table. + """, +) +def com_google_fonts_check_noto_designer(ttFont): + """Ensure the designer is a known Noto designer.""" + from fontbakery.utils import get_name_entry_strings + bad = False + designers = get_name_entry_strings(ttFont, NameID.DESIGNER) + if not designers: + bad = True + yield FAIL,\ + Message("no-designer", + "The font contained no designer name" + ) + + for designer in designers: + if designer not in NOTO_DESIGNERS: + bad = True + yield WARN,\ + Message("unknown-designer", + f"The font's designer name '{designer}' was " + "not a known Noto font designer" + ) + if not bad: + yield PASS, "The designer name entry was valid" + + +@check( + id = 'com.google.fonts/check/name/noto_trademark', + rationale = """ + Noto fonts must contain the correct trademark entry in the name table. + """, +) +def com_google_fonts_check_noto_trademark(ttFont): + """Ensure the trademark matches the expected string.""" + from fontbakery.utils import get_name_entry_strings + + bad = False + trademarks = get_name_entry_strings(ttFont, NameID.TRADEMARK) + if not trademarks: + bad = True + yield FAIL,\ + Message("no-trademark", + "The font contained no trademark entry" + ) + for trademark in trademarks: + if not re.match(TRADEMARK, trademark): + bad = True + yield FAIL,\ + Message("bad-trademark", + f"The trademark entry should be '{TRADEMARK}' " + f"but was actually '{trademark}'" + ) + + if not bad: + yield PASS, "The trademark name entry was valid" + + +@check( + id = 'com.google.fonts/check/cmap/format_12', + rationale = """ + If a format 12 cmap table is used to address codepoints beyond the + BMP, it should actually contain such codepoints. Additionally, it + should also contain all characters mapped in the format 4 subtable. + """, +) +def com_google_fonts_check_cmap_format_12(ttFont, config): + """Check that format 12 cmap subtables are correctly constituted.""" + bad = False + skipped = True + # Find the format 4 + cmap4 = None + for table in ttFont['cmap'].tables: + if table.format == 4: + cmap4 = table + break + + if not cmap4: + yield FAIL,\ + Message("no-cmap-4", + "The font did not contain a format 4 cmap table" + ) + return + + for subtable in ttFont['cmap'].tables: + if subtable.format != 12: + continue + skipped = False + codepoints = subtable.cmap.keys() + if not any(cp > 0x0FFF for cp in codepoints): + bad = True + yield FAIL,\ + Message("pointless-format-12", + "A format 12 subtable did not contain any codepoints beyond the BMP" + ) + unmapped_from_4 = set(cmap4.cmap.keys()) - set(codepoints) + if unmapped_from_4: + from fontbakery.utils import pretty_print_list + yield WARN,\ + Message("unmapped-from-4", + "A format 12 subtable did not the following codepoints " + f"mapped in the format 4 subtable: {pretty_print_list(config, unmapped_from_4)}") + + if skipped: + yield SKIP, "No format 12 subtables found" + elif not bad: + yield PASS, "All format 12 subtables were correctly formed" + + +@check( + id = 'com.google.fonts/check/os2/noto_vendor', + rationale = """ + Vendor ID must be GOOG + """, +) +def com_google_fonts_check_os2_noto_vendor(ttFont): + """Check OS/2 achVendID is set to GOOG.""" + + vendor_id = ttFont['OS/2'].achVendID + if vendor_id != 'GOOG': + yield FAIL,\ + Message("bad-vendor-id", + f"OS/2 VendorID is '{vendor_id}', but should be 'GOOG'.") + else: + yield PASS, f"OS/2 VendorID '{vendor_id}' is correct." + + +@check( + id = 'com.google.fonts/check/hmtx/encoded_latin_digits', + rationale = """ + Encoded Latin digits in Noto fonts should have equal advance widths + """ +) +def com_google_fonts_check_htmx_encoded_latin_digits(ttFont): + """Check all encoded Latin digits have the same advance width""" + bad = False + digits = "0123456789" + zero_width = _get_advance_width_for_char(ttFont, "0") + if zero_width is None: + yield SKIP, "No encoded Latin digits" + return + for d in digits: + actual_width = _get_advance_width_for_char(ttFont, d) + if actual_width is None: + bad = True + yield FAIL, Message("missing-digit", f"Missing Latin digit {d}") + elif actual_width != zero_width: + bad = True + yield FAIL,\ + Message("bad-digit-width", + f"Width of {d} was expected to be {zero_width} but was {actual_width}") + if not bad: + yield PASS, "All Latin digits had same advance width" + + +@check( + id = 'com.google.fonts/check/hmtx/comma_period', + rationale = """ + If Latin comma and period are encoded in Noto fonts, they should have equal advance widths + """ +) +def com_google_fonts_check_htmx_comma_period(ttFont): + """Check comma and period have the same advance width""" + comma = _get_advance_width_for_char(ttFont, ",") + period = _get_advance_width_for_char(ttFont, ".") + if comma is None or period is None: + yield SKIP, "No comma and/or period" + elif comma != period: + yield FAIL, Message("comma-period", f"Advance width of comma ({comma}) != advance width of period {period}") + else: + yield PASS, "Comma and period had the same advance width" + +@check( + id = 'com.google.fonts/check/hmtx/whitespace_advances', + rationale = """ + Encoded whitespace in Noto fonts should have well-defined advance widths + """ +) +def com_google_fonts_check_htmx_whitespace_advances(ttFont, config, glyph_metrics_stats): + """Check all whitespace glyphs have correct advances""" + import math + + problems = [] + if glyph_metrics_stats["seems_monospaced"]: + yield SKIP, "Monospace glyph widths handled in other checks" + return + space_width = _get_advance_width_for_char(ttFont, " ") + period_width = _get_advance_width_for_char(ttFont, ".") + digit_width = _get_advance_width_for_char(ttFont, "0") + em_width = ttFont["head"].unitsPerEm + expectations = { + 0x09: space_width, # tab + 0xa0: space_width, # nbsp + 0x2000: em_width / 2, + 0x2001: em_width, + 0x2002: em_width / 2, + 0x2003: em_width, + 0x2004: em_width / 3, + 0x2005: em_width / 4, + 0x2006: em_width / 6, + 0x2007: digit_width, + 0x2008: period_width, + 0x2009: (em_width / 6, em_width / 5), + 0x200A: (em_width / 16, em_width / 10), + 0x200B: 0 + } + for cp, expected_width in expectations.items(): + got_width = _get_advance_width_for_char(ttFont, chr(cp)) + if got_width is None: + continue + if isinstance(expected_width, tuple): + if got_width < math.floor(expected_width[0]) or got_width > math.ceil(expected_width[1]): + problems.append(f"0x{cp:02x} (got={got_width}, expected={expected_width[0]}...{expected_width[1]}") + else: + if got_width != round(expected_width): + problems.append(f"0x{cp:02x} (got={got_width}, expected={expected_width}") + + if problems: + from fontbakery.utils import pretty_print_list + formatted_list = "\t* " + pretty_print_list(config, + problems, + sep="\n\t* ") + yield FAIL,\ + Message("bad-whitespace-advances", + "The following glyphs had wrong advance widths:\n"+formatted_list) + else: + yield PASS, "Whitespace glyphs had correct advance widths" + + +@check( + id = 'com.google.fonts/check/cmap/alien_codepoints', + rationale = """ + Private Use Area codepoints and Surrogate Pairs should not be encoded. + """ +) +def com_google_fonts_check_cmap_alien_codepoints(ttFont, config): + """Check no PUA or Surrogate Pair codepoints encoded""" + pua = [] + surrogate = [] + for cp in ttFont.getBestCmap().keys(): + if ((0xE000 <= cp <= 0xF8FF) or + (0xF0000 <= cp <= 0xFFFFD) or + (0x100000 <= cp <= 0x10FFFD)): + pua.append(f"0x{cp:02x}") + if 0xD800 <= cp <= 0xDFFF: + surrogate.append(f"0x{cp:02x}") + if not pua and not surrogate: + yield PASS, "No alien codepoints were encoded" + return + + from fontbakery.utils import pretty_print_list + if pua: + yield FAIL,\ + Message("pua-encoded", + "The following private use area codepoints were encoded in the font: " + pretty_print_list(config, pua) + ) + if surrogate: + yield FAIL,\ + Message("surrogate-encoded", + "The following surrogate pair codepoints were encoded in the font: " + pretty_print_list(config, surrogate) + ) + +profile.auto_register(globals(), + filter_func=lambda type, id, _: + not (type == 'check' and id not in NOTOFONTS_PROFILE_CHECKS)) profile.test_expected_checks(NOTOFONTS_PROFILE_CHECKS, exclusive=True) From bded5dfb45f47888357e861517810d44130d95e0 Mon Sep 17 00:00:00 2001 From: Simon Cozens Date: Tue, 29 Mar 2022 15:12:13 +0100 Subject: [PATCH 4/7] Not my bug --- Lib/fontbakery/codetesting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/fontbakery/codetesting.py b/Lib/fontbakery/codetesting.py index c85573be11..2f2c37d934 100644 --- a/Lib/fontbakery/codetesting.py +++ b/Lib/fontbakery/codetesting.py @@ -70,7 +70,7 @@ def _get_args(self, condition_overrides=None): # args that are derived iterables are generators that must be # converted to lists, otherwise we end up with exhausted # generators after their first consumption. - for k in args: + for k in args.keys(): if self.profile.get_type(k, None) == 'derived_iterables': args[k] = list(args[k]) return args From ad0cf1c166a60fd96659bfd5a6bf725e44adc020 Mon Sep 17 00:00:00 2001 From: Simon Cozens Date: Tue, 29 Mar 2022 16:20:49 +0100 Subject: [PATCH 5/7] Revert "Some Noto fonts refer to "Google Inc"" This reverts commit ed77cea6dc644fbca8943d892e7a9643672e7ea6. --- Lib/fontbakery/profiles/googlefonts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/fontbakery/profiles/googlefonts.py b/Lib/fontbakery/profiles/googlefonts.py index 228b9a6b31..e236810343 100644 --- a/Lib/fontbakery/profiles/googlefonts.py +++ b/Lib/fontbakery/profiles/googlefonts.py @@ -2374,7 +2374,7 @@ def com_google_fonts_check_metadata_valid_post_script_name_values(font_metadata, EXPECTED_COPYRIGHT_PATTERN = \ -r'copyright [0-9]{4}(\-[0-9]{4})? (the .* project authors \([^\@]*\)|google (inc|llc). all rights reserved)' +r'copyright [0-9]{4}(\-[0-9]{4})? (the .* project authors \([^\@]*\)|google llc. all rights reserved)' @check( id = 'com.google.fonts/check/metadata/valid_copyright', From 88cffc0ea9567cf998ddae3df08469e678542ee8 Mon Sep 17 00:00:00 2001 From: Simon Cozens Date: Tue, 29 Mar 2022 16:21:18 +0100 Subject: [PATCH 6/7] Update CHANGELOG --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 215014b6c6..f322a79ea5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,19 @@ A more detailed list of changes is available in the corresponding milestones for #### On the Universal Profile - **[com.google.fonts/check/gpos7]:** Previously we checked for the existence of GSUB 5 lookups in the erroneous belief that they were not supported; GPOS 7 lookups are not supported in CoreText, but GSUB 5 lookups are fine. (issue #3689) +### New Checks +#### Added to the Noto Fonts Profile + - The majority of checks from the Google Fonts profile have been added. (PR #3681) + - **[com.google.fonts/check/name/noto_manufacturer]:** Checks for a known manufacturer name and correct designer URL in the name table. (PR #3681) + - **[com.google.fonts/check/name/noto_designer]:** Checks for a known designer name. (PR #3681) + - **[com.google.fonts/check/name/noto_trademark]:** Checks that the trademark entry in the name table is correct. (PR #3681) + - **[com.google.fonts/check/cmap/format_12]:** Checks that format 12 cmap tables are used appropriately. (PR #3681) + - **[com.google.fonts/check/os2/noto_vendor]:** Checks that the vendor ID in the OS/2 table is set to GOOG. (PR #3681) + - **[com.google.fonts/check/hmtx/encoded_latin_digits]:** Checks that any encoded Latin digits have equal advance width. (PR #3681) + - **[com.google.fonts/check/hmtx/comma_period]:** Checks that the comma and period glyphs have the same advance width as each other. (PR #3681) + - **[com.google.fonts/check/hmtx/whitespace_advances]:** Checks that whitespace glyphs have expected advance widths. (PR #3681) + - **[com.google.fonts/check/cmap/alien_codepoints]:** Checks that there are no surrogate pair or private use area codepoints encoded in the cmap table. (PR #3681) + ## 0.8.8 (2022-Mar-23) ### Noteworthy code-changes From 48c174c7344e9ccfbd00bd6a53134800064da1ff Mon Sep 17 00:00:00 2001 From: Simon Cozens Date: Tue, 29 Mar 2022 16:22:51 +0100 Subject: [PATCH 7/7] Add proposal, tidy rationale. --- Lib/fontbakery/profiles/notofonts.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Lib/fontbakery/profiles/notofonts.py b/Lib/fontbakery/profiles/notofonts.py index 9276814df9..17c5f2398a 100644 --- a/Lib/fontbakery/profiles/notofonts.py +++ b/Lib/fontbakery/profiles/notofonts.py @@ -217,9 +217,9 @@ def com_google_fonts_check_unicode_range_bits(ttFont, unicoderange, preferred_cm @check( id = 'com.google.fonts/check/name/noto_manufacturer', rationale = """ - Noto fonts must contain known manufacturer and manufacturer URL - entries in the name table. + Noto fonts must contain known manufacturer and manufacturer URL entries in the name table. """, + proposal = 'https://github.com/googlefonts/fontbakery/pull/3681', ) def com_google_fonts_check_noto_manufacturer(ttFont): """Ensure the manufacturer is a known Noto manufacturer and the URL is correct.""" @@ -271,6 +271,7 @@ def com_google_fonts_check_noto_manufacturer(ttFont): rationale = """ Noto fonts must contain known designer entries in the name table. """, + proposal = 'https://github.com/googlefonts/fontbakery/pull/3681', ) def com_google_fonts_check_noto_designer(ttFont): """Ensure the designer is a known Noto designer.""" @@ -301,6 +302,7 @@ def com_google_fonts_check_noto_designer(ttFont): rationale = """ Noto fonts must contain the correct trademark entry in the name table. """, + proposal = 'https://github.com/googlefonts/fontbakery/pull/3681', ) def com_google_fonts_check_noto_trademark(ttFont): """Ensure the trademark matches the expected string.""" @@ -330,10 +332,9 @@ def com_google_fonts_check_noto_trademark(ttFont): @check( id = 'com.google.fonts/check/cmap/format_12', rationale = """ - If a format 12 cmap table is used to address codepoints beyond the - BMP, it should actually contain such codepoints. Additionally, it - should also contain all characters mapped in the format 4 subtable. + If a format 12 cmap table is used to address codepoints beyond the BMP, it should actually contain such codepoints. Additionally, it should also contain all characters mapped in the format 4 subtable. """, + proposal = 'https://github.com/googlefonts/fontbakery/pull/3681', ) def com_google_fonts_check_cmap_format_12(ttFont, config): """Check that format 12 cmap subtables are correctly constituted.""" @@ -383,6 +384,7 @@ def com_google_fonts_check_cmap_format_12(ttFont, config): rationale = """ Vendor ID must be GOOG """, + proposal = 'https://github.com/googlefonts/fontbakery/pull/3681', ) def com_google_fonts_check_os2_noto_vendor(ttFont): """Check OS/2 achVendID is set to GOOG.""" @@ -400,7 +402,8 @@ def com_google_fonts_check_os2_noto_vendor(ttFont): id = 'com.google.fonts/check/hmtx/encoded_latin_digits', rationale = """ Encoded Latin digits in Noto fonts should have equal advance widths - """ + """, + proposal = 'https://github.com/googlefonts/fontbakery/pull/3681', ) def com_google_fonts_check_htmx_encoded_latin_digits(ttFont): """Check all encoded Latin digits have the same advance width""" @@ -445,7 +448,8 @@ def com_google_fonts_check_htmx_comma_period(ttFont): id = 'com.google.fonts/check/hmtx/whitespace_advances', rationale = """ Encoded whitespace in Noto fonts should have well-defined advance widths - """ + """, + proposal = 'https://github.com/googlefonts/fontbakery/pull/3681', ) def com_google_fonts_check_htmx_whitespace_advances(ttFont, config, glyph_metrics_stats): """Check all whitespace glyphs have correct advances""" @@ -502,7 +506,8 @@ def com_google_fonts_check_htmx_whitespace_advances(ttFont, config, glyph_metric id = 'com.google.fonts/check/cmap/alien_codepoints', rationale = """ Private Use Area codepoints and Surrogate Pairs should not be encoded. - """ + """, + proposal = 'https://github.com/googlefonts/fontbakery/pull/3681', ) def com_google_fonts_check_cmap_alien_codepoints(ttFont, config): """Check no PUA or Surrogate Pair codepoints encoded"""