Пример #1
0
 def test_us_weight(self):
     "Tests the usWeight of the fonts to be correct." ""
     for font in self.fonts:
         weight = roboto_data.extract_weight_name(font_data.font_name(font))
         expected_numeric_weight = roboto_data.WEIGHTS[weight]
         self.assertEqual(font['OS/2'].usWeightClass,
                          expected_numeric_weight)
Пример #2
0
 def test_inclusion_of_sound_recording_copyright(self):
     """Tests that sound recording copyright symbol is in the fonts."""
     for font in self.fonts:
         charset = coverage.character_set(font)
         self.assertIn(
             0x2117, charset,  # SOUND RECORDING COPYRIGHT
             'U+2117 not found in %s.' % font_data.font_name(font))
Пример #3
0
    def parse_metadata(self, font):
        """Parse font name to infer weight and slope."""

        font_name = font_data.font_name(font)
        bold = ('Bold' in font_name) or (self.mark_heavier_as_bold
                                         and 'Black' in font_name)
        italic = 'Italic' in font_name
        return bold, italic
Пример #4
0
    def parse_metadata(self, font):
        """Parse font name to infer weight and slope."""

        font_name = font_data.font_name(font)
        bold = ('Bold' in font_name) or (
            self.mark_heavier_as_bold and 'Black' in font_name)
        italic = 'Italic' in font_name
        return bold, italic
Пример #5
0
 def test_us_weight(self):
     "Tests the usWeight of the fonts to be correct."""
     for font in self.fonts:
         weight = noto_fonts.parse_weight(font_data.font_name(font))
         expected_numeric_weight = noto_fonts.WEIGHTS[weight]
         self.assertEqual(
             font['OS/2'].usWeightClass,
             expected_numeric_weight)
Пример #6
0
 def test_inclusion_of_sound_recording_copyright(self):
     """Tests that sound recording copyright symbol is in the fonts."""
     for font in self.fonts:
         charset = coverage.character_set(font)
         self.assertIn(
             0x2117,
             charset,  # SOUND RECORDING COPYRIGHT
             'U+2117 not found in %s.' % font_data.font_name(font))
Пример #7
0
 def test_us_weight(self):
     "Tests the usWeight of the fonts to be correct." ""
     for font in self.fonts:
         weight = noto_fonts.parse_weight(font_data.font_name(font))
         expected_numeric_weight = noto_fonts.WEIGHTS[weight]
         # hack for windows GDI
         expected_numeric_weight = max(expected_numeric_weight, 250)
         self.assertEqual(font['OS/2'].usWeightClass,
                          expected_numeric_weight)
Пример #8
0
 def test_italic_angle(self):
     """Tests the italic angle of fonts to be correct."""
     for font in self.fonts:
         post_table = font['post']
         if 'Italic' in font_data.font_name(font):
             expected_angle = self.expected_italic_angle
         else:
             expected_angle = 0.0
         self.assertEqual(post_table.italicAngle, expected_angle)
Пример #9
0
 def test_italic_angle(self):
     """Tests the italic angle of fonts to be correct."""
     for font in self.fonts:
         post_table = font['post']
         if 'Italic' in font_data.font_name(font):
             expected_angle = self.expected_italic_angle
         else:
             expected_angle = 0.0
         self.assertEqual(post_table.italicAngle, expected_angle)
Пример #10
0
    def test_mac_style(self):
        """Tests the macStyle of the fonts to be correct."""

        for font in self.fonts:
            font_name = font_data.font_name(font)
            bold = ('Bold' in font_name) or (self.mark_heavier_as_bold
                                             and 'Black' in font_name)
            italic = 'Italic' in font_name
            expected_mac_style = (italic << 1) | bold
            self.assertEqual(font['head'].macStyle, expected_mac_style)
Пример #11
0
    def test_mac_style(self):
        """Tests the macStyle of the fonts to be correct."""

        for font in self.fonts:
            font_name = font_data.font_name(font)
            bold = ('Bold' in font_name) or (
                self.mark_heavier_as_bold and 'Black' in font_name)
            italic = 'Italic' in font_name
            expected_mac_style = (italic << 1) | bold
            self.assertEqual(font['head'].macStyle, expected_mac_style)
Пример #12
0
    def test_mac_style(self):
        """Tests the macStyle of the fonts to be correct.

        Bug: https://code.google.com/a/google.com/p/roboto/issues/detail?id=8
        """
        for font in self.fonts:
            font_name = font_data.font_name(font)
            bold = ('Bold' in font_name) or ('Black' in font_name)
            italic = 'Italic' in font_name
            expected_mac_style = (italic << 1) | bold
            self.assertEqual(font['head'].macStyle, expected_mac_style)
Пример #13
0
    def test_mac_style(self):
        """Tests the macStyle of the fonts to be correct.

        Bug: https://code.google.com/a/google.com/p/roboto/issues/detail?id=8
        """
        for font in self.fonts:
            font_name = font_data.font_name(font)
            bold = ('Bold' in font_name) or ('Black' in font_name)
            italic = 'Italic' in font_name
            expected_mac_style = (italic << 1) | bold
            self.assertEqual(font['head'].macStyle, expected_mac_style)
Пример #14
0
def output_protruding_glyphs(font, ymin, ymax):
    """Outputs all glyphs going outside the specified vertical range."""
    protruding_glyphs = []
    glyf_table = font['glyf']
    for glyph_name in glyf_table.keys():
        glyph = glyf_table[glyph_name]
        if glyph.numberOfContours == 0:
            continue
        if glyph.yMin < ymin or glyph.yMax > ymax:
            protruding_glyphs.append(glyph_name)
    if protruding_glyphs:
        print("Protruding glyphs in %s:" % font_data.font_name(font))
        print(', '.join(sorted(protruding_glyphs)))
Пример #15
0
def apply_temporary_fixes(font):
    """Apply some temporary fixes."""
    # Fix usWeight:
    font_name = font_data.font_name(font)
    weight = noto_fonts.parse_weight(font_name)
    weight_number = noto_fonts.WEIGHTS[weight]
    font['OS/2'].usWeightClass = weight_number

    # Set ascent, descent, and lineGap values to Android K values
    hhea = font['hhea']
    hhea.ascent = 1900
    hhea.descent = -500
    hhea.lineGap = 0
Пример #16
0
def output_protruding_glyphs(font, ymin, ymax):
    """Outputs all glyphs going outside the specified vertical range."""
    protruding_glyphs = []
    glyf_table = font['glyf']
    for glyph_name in glyf_table.keys():
        glyph = glyf_table[glyph_name]
        if glyph.numberOfContours == 0:
            continue
        if glyph.yMin < ymin or glyph.yMax > ymax:
            protruding_glyphs.append(glyph_name)
    if protruding_glyphs:
        print "Protruding glyphs in %s:" % font_data.font_name(font),
        print ', '.join(sorted(protruding_glyphs))
Пример #17
0
    def test_existance_of_hints(self):
        """Tests all glyphs and makes sure non-composite ones have hints."""
        missing_hints = []
        for font in self.fonts:
            glyf_table = font['glyf']
            for glyph_name in font.getGlyphOrder():
                glyph = glyf_table[glyph_name]
                if glyph.numberOfContours <= 0:  # composite or empty glyph
                    continue
                if len(glyph.program.bytecode) <= 0:
                    missing_hints.append(
                        (glyph_name, font_data.font_name(font)))

        self.assertTrue(missing_hints == [])
Пример #18
0
    def test_existance_of_hints(self):
        """Tests all glyphs and makes sure non-composite ones have hints."""
        missing_hints = []
        for font in self.fonts:
            glyf_table = font['glyf']
            for glyph_name in font.getGlyphOrder():
                glyph = glyf_table[glyph_name]
                if glyph.numberOfContours <= 0:  # composite or empty glyph
                    continue
                if len(glyph.program.bytecode) <= 0:
                    missing_hints.append(
                        (glyph_name, font_data.font_name(font)))

        self.assertTrue(missing_hints == [])
Пример #19
0
def apply_temporary_fixes(font):
    """Apply some temporary fixes."""
    # Fix usWeight:
    font_name = font_data.font_name(font)
    weight = roboto_data.extract_weight_name(font_name)
    weight_number = roboto_data.WEIGHTS[weight]
    font['OS/2'].usWeightClass = weight_number

    # Set ascent, descent, and lineGap values to Android K values
    hhea = font['hhea']
    hhea.ascent = 1900
    hhea.descent = -500
    hhea.lineGap = 0

    # Copyright message
    font_data.set_name_record(
        font, 0, 'Copyright 2011 Google Inc. All Rights Reserved.')
Пример #20
0
def apply_temporary_fixes(font):
    """Apply some temporary fixes."""
    # Fix usWeight:
    font_name = font_data.font_name(font)
    weight = noto_fonts.parse_weight(font_name)
    weight_number = noto_fonts.WEIGHTS[weight]
    font['OS/2'].usWeightClass = weight_number

    # Set ascent, descent, and lineGap values to Android K values
    hhea = font['hhea']
    hhea.ascent = 1900
    hhea.descent = -500
    hhea.lineGap = 0

    # Copyright message
    font_data.set_name_record(
        font, 0, 'Copyright 2011 Google Inc. All Rights Reserved.')
Пример #21
0
def main():
    """Checkes the coverage of all Roboto fonts."""
    with open('res/char_requirements.tsv') as char_reqs_file:
        char_reqs_data = char_reqs_file.read()

    # The format of the data to be parsed is like the following:
    # General Punctuation\t2000..206F\t111\t35\t54\t0\tEverything except 2028..202E, 2060..2064, and 2066..206F
    # Currency Symbols\t20A0..20CF\t29\t5\t24\t1\t
    required_set = set()
    for line in char_reqs_data.split('\n'):
        if line.startswith('#'):  # Skip comment lines
            continue
        line = line.split('\t')
        if not line[0]:
            continue  # Skip the first line and empty lines
        block_range = line[1]
        full_coverage_required = (line[5] == '1')
        exceptions = line[6]
        required_set.update(
            _find_required_chars(block_range, full_coverage_required,
                                 exceptions))

    # Skip Unicode 8.0 characters
    required_set = {
        ch
        for ch in required_set if float(unicode_data.age(ch)) <= 7.0
    }

    # Skip ASCII and C1 controls
    required_set -= set(range(0, 0x20) + range(0x7F, 0xA0))

    missing_char_found = False
    for font in load_fonts():
        font_coverage = coverage.character_set(font)
        missing_chars = required_set - font_coverage
        if missing_chars:
            missing_char_found = True
            font_name = font_data.font_name(font)
            print 'Characters missing from %s:' % font_name
            for char in sorted(missing_chars):
                _print_char(char)
            print

    if missing_char_found:
        sys.exit(1)
Пример #22
0
def apply_temporary_fixes(font, is_for_cros=False):
    """Apply some temporary fixes."""
    # Fix usWeight:
    font_name = font_data.font_name(font)
    weight = noto_fonts.parse_weight(font_name)
    weight_number = noto_fonts.WEIGHTS[weight]
    # Chrome OS wants Thin to have usWeightClass=100
    if is_for_cros and weight == 'Thin':
        weight_number = 100
    font['OS/2'].usWeightClass = weight_number

    # Set bold bits for Black (macStyle bit 0, fsSelection bit 5)
    name_records = font_data.get_name_records(font)
    family_name = name_records[1]
    if family_name.endswith('Black'):
        font['head'].macStyle |= (1 << 0)
        font['OS/2'].fsSelection |= (1 << 5)
        font['OS/2'].fsSelection &= ~(1 << 6)
Пример #23
0
def apply_temporary_fixes(font, is_for_cros=False):
    """Apply some temporary fixes."""
    # Fix usWeight:
    font_name = font_data.font_name(font)
    weight = noto_fonts.parse_weight(font_name)
    weight_number = noto_fonts.WEIGHTS[weight]
    # Chrome OS wants Thin to have usWeightClass=100
    if is_for_cros and weight == 'Thin':
        weight_number = 100
    font['OS/2'].usWeightClass = weight_number

    # Set bold bits for Black (macStyle bit 0, fsSelection bit 5)
    name_records = font_data.get_name_records(font)
    family_name = name_records[1]
    if family_name.endswith('Black'):
        font['head'].macStyle |= (1 << 0)
        font['OS/2'].fsSelection |= (1 << 5)
        font['OS/2'].fsSelection &= ~(1 << 6)
Пример #24
0
def main():
    """Checkes the coverage of all Roboto fonts."""
    with open('res/char_requirements.tsv') as char_reqs_file:
        char_reqs_data = char_reqs_file.read()

    # The format of the data to be parsed is like the following:
    # General Punctuation\t2000..206F\t111\t35\t54\t0\tEverything except 2028..202E, 2060..2064, and 2066..206F
    # Currency Symbols\t20A0..20CF\t29\t5\t24\t1\t
    required_set = set()
    for line in char_reqs_data.split('\n'):
        if line.startswith('#'):  # Skip comment lines
            continue
        line = line.split('\t')
        if not line[0]:
            continue  # Skip the first line and empty lines
        block_range = line[1]
        full_coverage_required = (line[5] == '1')
        exceptions = line[6]
        required_set.update(
            _find_required_chars(block_range,
                                 full_coverage_required,
                                 exceptions))

    # Skip Unicode 8.0 characters
    required_set = {ch for ch in required_set
                    if float(unicode_data.age(ch)) <= 7.0}

    # Skip ASCII and C1 controls
    required_set -= set(range(0, 0x20) + range(0x7F, 0xA0))

    missing_char_found = False
    for font in load_fonts():
        font_coverage = coverage.character_set(font)
        missing_chars = required_set - font_coverage
        if missing_chars:
            missing_char_found = True
            font_name = font_data.font_name(font)
            print 'Characters missing from %s:' % font_name
            for char in sorted(missing_chars):
                _print_char(char)
            print

    if missing_char_found:
        sys.exit(1)
Пример #25
0
def fix_font(src_root, dst_root, file_path, is_hinted, save_unmodified):
    """Fix font under src_root and write to similar path under dst_root, modulo
    fixes to the filename.  If is_hinted is false, strip hints.  If unmodified,
    don't write destination unless save_unmodified is true."""

    src_file = os.path.join(src_root, file_path)

    print 'Font file: %s' % src_file
    font = ttLib.TTFont(src_file)
    modified = False

    modified |= fix_revision(font)
    modified |= fix_fstype(font)
    modified |= fix_vendor_id(font)
    modified |= fix_name_table(font)
    modified |= fix_attachlist(font)
    modified |= fix_os2_unicoderange(font)
    # leave line gap for non-noto fonts alone, metrics are more constrained there
    if font_data.font_name(font).find('Noto') != -1:
        modified |= fix_linegap(font)

    tables_to_drop = TABLES_TO_DROP
    if not is_hinted:
        modified |= drop_hints(font)
        tables_to_drop += ['fpgm', 'prep', 'cvt']

    modified |= drop_tables(font, tables_to_drop)

    fixed_path = fix_path(file_path, is_hinted)
    if fixed_path != file_path:
        print 'changed file_path from "%s" to "%s"' % (file_path, fixed_path)
        modified = True

    if not modified:
        print 'No modification necessary'
    if modified or save_unmodified:
        # wait until we need it before we create the dest directory
        dst_file = os.path.join(dst_root, fixed_path)
        dst_dir = path.dirname(dst_file)
        if not path.isdir(dst_dir):
            os.makedirs(dst_dir)
        font.save(dst_file)
        print 'Wrote %s' % dst_file
Пример #26
0
def fix_font(src_root, dst_root, file_path, is_hinted, save_unmodified):
    """Fix font under src_root and write to similar path under dst_root, modulo
    fixes to the filename.  If is_hinted is false, strip hints.  If unmodified,
    don't write destination unless save_unmodified is true."""

    src_file = os.path.join(src_root, file_path)

    print 'Font file: %s' % src_file
    font = ttLib.TTFont(src_file)
    modified = False

    modified |= fix_revision(font)
    modified |= fix_fstype(font)
    modified |= fix_vendor_id(font)
    modified |= fix_name_table(font)
    modified |= fix_attachlist(font)
    modified |= fix_os2_unicoderange(font)
    # leave line gap for non-noto fonts alone, metrics are more constrained there
    if font_data.font_name(font).find('Noto') != -1:
      modified |= fix_linegap(font)

    tables_to_drop = TABLES_TO_DROP
    if not is_hinted:
        modified |= drop_hints(font)
        tables_to_drop += ['fpgm', 'prep', 'cvt']

    modified |= drop_tables(font, tables_to_drop)

    fixed_path = fix_path(file_path, is_hinted)
    if fixed_path != file_path:
        print 'changed file_path from "%s" to "%s"' % (file_path, fixed_path)
        modified = True

    if not modified:
        print 'No modification necessary'
    if modified or save_unmodified:
        # wait until we need it before we create the dest directory
        dst_file = os.path.join(dst_root, fixed_path)
        dst_dir = path.dirname(dst_file)
        if not path.isdir(dst_dir):
            os.makedirs(dst_dir)
        font.save(dst_file)
        print 'Wrote %s' % dst_file
Пример #27
0
def apply_temporary_fixes(font):
    """Apply some temporary fixes."""
    # Fix usWeight:
    font_name = font_data.font_name(font)
    weight = noto_fonts.parse_weight(font_name)
    weight_number = noto_fonts.WEIGHTS[weight]
    font['OS/2'].usWeightClass = weight_number

    # Set ascent, descent, and lineGap values to Android K values
    hhea = font['hhea']
    hhea.ascent = 1900
    hhea.descent = -500
    hhea.lineGap = 0

    # Set bold bits for Black (macStyle bit 0, fsSelection bit 5)
    name_records = font_data.get_name_records(font)
    family_name = name_records[1]
    if family_name.endswith('Black'):
        font['head'].macStyle |= (1 << 0)
        font['OS/2'].fsSelection |= (1 << 5)
        font['OS/2'].fsSelection &= ~(1 << 6)
Пример #28
0
def apply_temporary_fixes(font):
    """Apply some temporary fixes."""
    # Fix usWeight:
    font_name = font_data.font_name(font)
    weight = noto_fonts.parse_weight(font_name)
    weight_number = noto_fonts.WEIGHTS[weight]
    font['OS/2'].usWeightClass = weight_number

    # Set ascent, descent, and lineGap values to Android K values
    hhea = font['hhea']
    hhea.ascent = 1900
    hhea.descent = -500
    hhea.lineGap = 0

    # Set bold bits for Black (macStyle bit 0, fsSelection bit 5)
    name_records = font_data.get_name_records(font)
    family_name = name_records[1]
    if family_name.endswith('Black'):
        font['head'].macStyle |= (1 << 0)
        font['OS/2'].fsSelection |= (1 << 5)
        font['OS/2'].fsSelection &= ~(1 << 6)