Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8cfd3d03 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Use serif fonts for serif fallback."

parents f1f708f1 99a7b60e
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -115,10 +115,14 @@
    <family lang="und-Hebr">
        <font weight="400" style="normal">NotoSansHebrew-Regular.ttf</font>
        <font weight="700" style="normal">NotoSansHebrew-Bold.ttf</font>
        <font weight="400" style="normal" fallbackFor="serif">NotoSerifHebrew-Regular.ttf</font>
        <font weight="700" style="normal" fallbackFor="serif">NotoSerifHebrew-Bold.ttf</font>
    </family>
    <family lang="und-Thai" variant="elegant">
        <font weight="400" style="normal">NotoSansThai-Regular.ttf</font>
        <font weight="700" style="normal">NotoSansThai-Bold.ttf</font>
        <font weight="400" style="normal" fallbackFor="serif">NotoSerifThai-Regular.ttf</font>
        <font weight="700" style="normal" fallbackFor="serif">NotoSerifThai-Bold.ttf</font>
    </family>
    <family lang="und-Thai" variant="compact">
        <font weight="400" style="normal">NotoSansThaiUI-Regular.ttf</font>
@@ -127,14 +131,20 @@
    <family lang="und-Armn">
        <font weight="400" style="normal">NotoSansArmenian-Regular.ttf</font>
        <font weight="700" style="normal">NotoSansArmenian-Bold.ttf</font>
        <font weight="400" style="normal" fallbackFor="serif">NotoSerifArmenian-Regular.ttf</font>
        <font weight="700" style="normal" fallbackFor="serif">NotoSerifArmenian-Bold.ttf</font>
    </family>
    <family lang="und-Geor und-Geok">
        <font weight="400" style="normal">NotoSansGeorgian-Regular.ttf</font>
        <font weight="700" style="normal">NotoSansGeorgian-Bold.ttf</font>
        <font weight="400" style="normal" fallbackFor="serif">NotoSerifGeorgian-Regular.ttf</font>
        <font weight="700" style="normal" fallbackFor="serif">NotoSerifGeorgian-Bold.ttf</font>
    </family>
    <family lang="und-Deva" variant="elegant">
        <font weight="400" style="normal">NotoSansDevanagari-Regular.ttf</font>
        <font weight="700" style="normal">NotoSansDevanagari-Bold.ttf</font>
        <font weight="400" style="normal" fallbackFor="serif">NotoSerifDevanagari-Regular.ttf</font>
        <font weight="700" style="normal" fallbackFor="serif">NotoSerifDevanagari-Bold.ttf</font>
    </family>
    <family lang="und-Deva" variant="compact">
        <font weight="400" style="normal">NotoSansDevanagariUI-Regular.ttf</font>
@@ -147,6 +157,8 @@
    <family lang="und-Gujr" variant="elegant">
        <font weight="400" style="normal">NotoSansGujarati-Regular.ttf</font>
        <font weight="700" style="normal">NotoSansGujarati-Bold.ttf</font>
        <font weight="400" style="normal" fallbackFor="serif">NotoSerifGujarati-Regular.ttf</font>
        <font weight="700" style="normal" fallbackFor="serif">NotoSerifGujarati-Bold.ttf</font>
    </family>
    <family lang="und-Gujr" variant="compact">
        <font weight="400" style="normal">NotoSansGujaratiUI-Regular.ttf</font>
@@ -163,6 +175,8 @@
    <family lang="und-Taml" variant="elegant">
        <font weight="400" style="normal">NotoSansTamil-Regular.ttf</font>
        <font weight="700" style="normal">NotoSansTamil-Bold.ttf</font>
        <font weight="400" style="normal" fallbackFor="serif">NotoSerifTamil-Regular.ttf</font>
        <font weight="700" style="normal" fallbackFor="serif">NotoSerifTamil-Bold.ttf</font>
    </family>
    <family lang="und-Taml" variant="compact">
        <font weight="400" style="normal">NotoSansTamilUI-Regular.ttf</font>
@@ -171,6 +185,8 @@
    <family lang="und-Mlym" variant="elegant">
        <font weight="400" style="normal">NotoSansMalayalam-Regular.ttf</font>
        <font weight="700" style="normal">NotoSansMalayalam-Bold.ttf</font>
        <font weight="400" style="normal" fallbackFor="serif">NotoSerifMalayalam-Regular.ttf</font>
        <font weight="700" style="normal" fallbackFor="serif">NotoSerifMalayalam-Bold.ttf</font>
    </family>
    <family lang="und-Mlym" variant="compact">
        <font weight="400" style="normal">NotoSansMalayalamUI-Regular.ttf</font>
@@ -179,6 +195,8 @@
    <family lang="und-Beng" variant="elegant">
        <font weight="400" style="normal">NotoSansBengali-Regular.ttf</font>
        <font weight="700" style="normal">NotoSansBengali-Bold.ttf</font>
        <font weight="400" style="normal" fallbackFor="serif">NotoSerifBengali-Regular.ttf</font>
        <font weight="700" style="normal" fallbackFor="serif">NotoSerifBengali-Bold.ttf</font>
    </family>
    <family lang="und-Beng" variant="compact">
        <font weight="400" style="normal">NotoSansBengaliUI-Regular.ttf</font>
@@ -187,6 +205,8 @@
    <family lang="und-Telu" variant="elegant">
        <font weight="400" style="normal">NotoSansTelugu-Regular.ttf</font>
        <font weight="700" style="normal">NotoSansTelugu-Bold.ttf</font>
        <font weight="400" style="normal" fallbackFor="serif">NotoSerifTelugu-Regular.ttf</font>
        <font weight="700" style="normal" fallbackFor="serif">NotoSerifTelugu-Bold.ttf</font>
    </family>
    <family lang="und-Telu" variant="compact">
        <font weight="400" style="normal">NotoSansTeluguUI-Regular.ttf</font>
@@ -195,6 +215,8 @@
    <family lang="und-Knda" variant="elegant">
        <font weight="400" style="normal">NotoSansKannada-Regular.ttf</font>
        <font weight="700" style="normal">NotoSansKannada-Bold.ttf</font>
        <font weight="400" style="normal" fallbackFor="serif">NotoSerifKannada-Regular.ttf</font>
        <font weight="700" style="normal" fallbackFor="serif">NotoSerifKannada-Bold.ttf</font>
    </family>
    <family lang="und-Knda" variant="compact">
        <font weight="400" style="normal">NotoSansKannadaUI-Regular.ttf</font>
@@ -258,6 +280,8 @@
    <family lang="und-Laoo" variant="elegant">
        <font weight="400" style="normal">NotoSansLao-Regular.ttf</font>
        <font weight="700" style="normal">NotoSansLao-Bold.ttf</font>
        <font weight="400" style="normal" fallbackFor="serif">NotoSerifLao-Regular.ttf</font>
        <font weight="700" style="normal" fallbackFor="serif">NotoSerifLao-Bold.ttf</font>
    </family>
    <family lang="und-Laoo" variant="compact">
        <font weight="400" style="normal">NotoSansLaoUI-Regular.ttf</font>
@@ -472,15 +496,19 @@
    </family>
    <family lang="zh-Hans">
        <font weight="400" style="normal" index="2">NotoSansCJK-Regular.ttc</font>
        <font weight="400" style="normal" index="2" fallbackFor="serif">NotoSerifCJK-Regular.ttc</font>
    </family>
    <family lang="zh-Hant zh-Bopo">
        <font weight="400" style="normal" index="3">NotoSansCJK-Regular.ttc</font>
        <font weight="400" style="normal" index="3" fallbackFor="serif">NotoSerifCJK-Regular.ttc</font>
    </family>
    <family lang="ja">
        <font weight="400" style="normal" index="0">NotoSansCJK-Regular.ttc</font>
        <font weight="400" style="normal" index="0" fallbackFor="serif">NotoSerifCJK-Regular.ttc</font>
    </family>
    <family lang="ko">
        <font weight="400" style="normal" index="1">NotoSansCJK-Regular.ttc</font>
        <font weight="400" style="normal" index="1" fallbackFor="serif">NotoSerifCJK-Regular.ttc</font>
    </family>
    <family lang="und-Zsye">
        <font weight="400" style="normal">NotoColorEmoji.ttf</font>
+87 −41
Original line number Diff line number Diff line
@@ -163,11 +163,14 @@ def assert_font_supports_all_of_chars(font, chars):
            'U+%04X was not found in %s' % (char, font))


def assert_font_supports_none_of_chars(font, chars):
def assert_font_supports_none_of_chars(font, chars, fallbackName):
    best_cmap = get_best_cmap(font)
    for char in chars:
        if fallbackName:
            assert char not in best_cmap, 'U+%04X was found in %s' % (char, font)
        else:
            assert char not in best_cmap, (
            'U+%04X was found in %s' % (char, font))
                'U+%04X was found in %s in fallback %s' % (char, font, fallbackName))


def assert_font_supports_all_sequences(font, sequences):
@@ -196,19 +199,21 @@ def check_hyphens(hyphens_dir):


class FontRecord(object):
    def __init__(self, name, scripts, variant, weight, style, font):
    def __init__(self, name, scripts, variant, weight, style, fallback_for, font):
        self.name = name
        self.scripts = scripts
        self.variant = variant
        self.weight = weight
        self.style = style
        self.fallback_for = fallback_for
        self.font = font


def parse_fonts_xml(fonts_xml_path):
    global _script_to_font_map, _fallback_chain
    global _script_to_font_map, _fallback_chains, _all_fonts
    _script_to_font_map = collections.defaultdict(set)
    _fallback_chain = []
    _fallback_chains = {}
    _all_fonts = []
    tree = ElementTree.parse(fonts_xml_path)
    families = tree.findall('family')
    # Minikin supports up to 254 but users can place their own font at the first
@@ -225,10 +230,17 @@ def parse_fonts_xml(fonts_xml_path):
                'No variant expected for LGC font %s.' % name)
            assert langs is None, (
                'No language expected for LGC fonts %s.' % name)
            assert name not in _fallback_chains, 'Duplicated name entry %s' % name
            _fallback_chains[name] = []
        else:
            assert variant in {None, 'elegant', 'compact'}, (
                'Unexpected value for variant: %s' % variant)

    for family in families:
        name = family.get('name')
        variant = family.get('variant')
        langs = family.get('lang')

        if langs:
            langs = langs.split()
            scripts = {lang_to_script(lang) for lang in langs}
@@ -247,17 +259,36 @@ def parse_fonts_xml(fonts_xml_path):
            assert style in {'normal', 'italic'}, (
                'Unknown style "%s"' % style)

            fallback_for = child.get('fallbackFor')

            assert not name or not fallback_for, (
                'name and fallbackFor cannot be present at the same time')
            assert not fallback_for or fallback_for in _fallback_chains, (
                'Unknown fallback name: %s' % fallback_for)

            index = child.get('index')
            if index:
                index = int(index)

            _fallback_chain.append(FontRecord(
            record = FontRecord(
                name,
                frozenset(scripts),
                variant,
                weight,
                style,
                (font_file, index)))
                fallback_for,
                (font_file, index))

            _all_fonts.append(record)

            if not fallback_for:
                if not name or name == 'sans-serif':
                    for _, fallback in _fallback_chains.iteritems():
                        fallback.append(record)
                else:
                    _fallback_chains[name].append(record)
            else:
                _fallback_chains[fallback_for].append(record)

            if name: # non-empty names are used for default LGC fonts
                map_scripts = {'Latn', 'Grek', 'Cyrl'}
@@ -274,7 +305,7 @@ def check_emoji_coverage(all_emoji, equivalent_emoji):

def get_emoji_font():
    emoji_fonts = [
        record.font for record in _fallback_chain
        record.font for record in _all_fonts
        if 'Zsye' in record.scripts]
    assert len(emoji_fonts) == 1, 'There are %d emoji fonts.' % len(emoji_fonts)
    return emoji_fonts[0]
@@ -318,8 +349,9 @@ def check_emoji_font_coverage(emoji_font, all_emoji, equivalent_emoji):

def check_emoji_defaults(default_emoji):
    missing_text_chars = _emoji_properties['Emoji'] - default_emoji
    for name, fallback_chain in _fallback_chains.iteritems():
        emoji_font_seen = False
    for record in _fallback_chain:
        for record in fallback_chain:
            if 'Zsye' in record.scripts:
                emoji_font_seen = True
                # No need to check the emoji font
@@ -334,7 +366,7 @@ def check_emoji_defaults(default_emoji):
                continue

            # Check default emoji-style characters
        assert_font_supports_none_of_chars(record.font, sorted(default_emoji))
            assert_font_supports_none_of_chars(record.font, sorted(default_emoji), name)

            # Mark default text-style characters appearing in fonts above the emoji
            # font as seen
@@ -626,8 +658,19 @@ def compute_expected_emoji():
    return all_emoji, default_emoji, equivalent_emoji


def check_compact_only_fallback():
    for name, fallback_chain in _fallback_chains.iteritems():
        for record in fallback_chain:
            if record.variant == 'compact':
                same_script_elegants = [x for x in fallback_chain
                    if x.scripts == record.scripts and x.variant == 'elegant']
                assert same_script_elegants, (
                    '%s must be in elegant of %s as fallback of "%s" too' % (
                    record.font, record.scripts, record.fallback_for),)


def check_vertical_metrics():
    for record in _fallback_chain:
    for record in _all_fonts:
        if record.name in ['sans-serif', 'sans-serif-condensed']:
            font = open_font(record.font)
            assert font['head'].yMax == 2163 and font['head'].yMin == -555, (
@@ -646,11 +689,12 @@ def check_vertical_metrics():
def check_cjk_punctuation():
    cjk_scripts = {'Hans', 'Hant', 'Jpan', 'Kore'}
    cjk_punctuation = range(0x3000, 0x301F + 1)
    for record in _fallback_chain:
    for name, fallback_chain in _fallback_chains.iteritems():
        for record in fallback_chain:
            if record.scripts.intersection(cjk_scripts):
                # CJK font seen. Stop checking the rest of the fonts.
                break
        assert_font_supports_none_of_chars(record.font, cjk_punctuation)
            assert_font_supports_none_of_chars(record.font, cjk_punctuation, name)


def main():
@@ -661,6 +705,8 @@ def main():
    fonts_xml_path = path.join(target_out, 'etc', 'fonts.xml')
    parse_fonts_xml(fonts_xml_path)

    check_compact_only_fallback()

    check_vertical_metrics()

    hyphens_dir = path.join(target_out, 'usr', 'hyphen-data')