def main(argv):
    """Fix all the fonts given in the command line.
    
    If they are Lao fonts, make sure they have ZWSP and dotted circle. If they
    are Khmer fonts, make sure they have ZWSP, joiners, and dotted circle."""

    for font_name in argv[1:]:
        if 'Khmer' in font_name:
            script = 'Khmr'
        elif 'Lao' in font_name:
            script = 'Laoo'
        needed_chars = set(opentype_data.SPECIAL_CHARACTERS_NEEDED[script])

        lgc_font_name = (
            os.path.basename(font_name).replace('Khmer', '').replace('Lao', ''))
        lgc_font_name = os.path.join(_UNHINTED_FONTS_DIR, lgc_font_name)

        font_charset = coverage.character_set(font_name)
        missing_chars = needed_chars - font_charset
        if missing_chars:
            merge_chars_from_bank(
                font_name,
                lgc_font_name,
                os.path.dirname(font_name)+'/new/'+os.path.basename(font_name),
                missing_chars)
def main(argv):
    """Fix all the fonts given in the command line.
    
    If they are Lao fonts, make sure they have ZWSP and dotted circle. If they
    are Khmer fonts, make sure they have ZWSP, joiners, and dotted circle."""

    for font_name in argv[1:]:
        if 'Khmer' in font_name:
            script = 'Khmr'
        elif 'Lao' in font_name:
            script = 'Laoo'
        needed_chars = set(opentype_data.SPECIAL_CHARACTERS_NEEDED[script])

        lgc_font_name = (os.path.basename(font_name).replace('Khmer',
                                                             '').replace(
                                                                 'Lao', ''))
        lgc_font_name = os.path.join(_UNHINTED_FONTS_DIR, lgc_font_name)

        font_charset = coverage.character_set(font_name)
        missing_chars = needed_chars - font_charset
        if missing_chars:
            merge_chars_from_bank(
                font_name, lgc_font_name,
                os.path.dirname(font_name) + '/new/' +
                os.path.basename(font_name), missing_chars)
def test_rendering(data,
                   font_file_name,
                   min_allowed,
                   max_allowed,
                   language=None):
    """Test the rendering of the input data in a given font.
    
    The input data is first filtered for sequences supported in the font.
    """
    font_characters = coverage.character_set(font_file_name)
    # Hack to add ASCII digits, even if the font doesn't have them,
    # to keep potential frequency info in the input intact
    font_characters |= set(range(ord('0'), ord('9') + 1))

    supported_chars_regex = _regular_expression_from_set(font_characters)

    harfbuzz_input = []
    for match in supported_chars_regex.finditer(data):
        harfbuzz_input.append(match.group(0))

    harfbuzz_input = '\n'.join(harfbuzz_input)

    return render.test_text_vertical_extents(harfbuzz_input, font_file_name,
                                             min_allowed, max_allowed,
                                             language)
Example #4
0
    def test_sanity(self):
        """Test basic sanity of the method."""
        font_file_name = path.join(path.dirname(__file__), os.pardir, 'fonts',
                                   'individual', 'unhinted',
                                   'NotoSansAvestan-Regular.ttf')
        charset = coverage.character_set(font_file_name)

        self.assertTrue(ord(' ') in charset)
        self.assertTrue(0x10B00 in charset)
        self.assertFalse(ord('A') in charset)
Example #5
0
    def test_sanity(self):
        """Test basic sanity of the method."""
        font_file_name = path.join(
            path.dirname(__file__), os.pardir,
            'fonts', 'individual', 'unhinted', 'NotoSansAvestan-Regular.ttf')
        charset = coverage.character_set(font_file_name)

        self.assertTrue(ord(' ') in charset)
        self.assertTrue(0x10B00 in charset)
        self.assertFalse(ord('A') in charset)
Example #6
0
def subset_font(source_file,
                target_file,
                include=None,
                exclude=None,
                options=None):
    """Subsets a font file.

    Subsets a font file based on a specified character set. If only include is
    specified, only characters from that set would be included in the output
    font.  If only exclude is specified, all characters except those in that
    set will be included.  If neither is specified, the character set will
    remain the same, but inaccessible glyphs will be removed.

    Args:
      source_file: Input file name.
      target_file: Output file name
      include: The list of characters to include from the source font.
      exclude: The list of characters to exclude from the source font.
      options: A dictionary listing which options should be different from the
          default.

    Raises:
      NotImplementedError: Both include and exclude were specified.
    """
    opt = subset.Options()

    opt.name_IDs = ['*']
    opt.name_legacy = True
    opt.name_languages = ['*']
    opt.layout_features = ['*']
    opt.notdef_outline = True
    opt.recalc_bounds = True
    opt.recalc_timestamp = True
    opt.canonical_order = True

    if options is not None:
        for name, value in options.iteritems():
            setattr(opt, name, value)

    if include is not None:
        if exclude is not None:
            raise NotImplementedError(
                'Subset cannot include and exclude a set at the same time.')
        target_charset = include
    else:
        if exclude is None:
            exclude = []
        source_charset = coverage.character_set(source_file)
        target_charset = source_charset - set(exclude)

    font = subset.load_font(source_file, opt)
    subsetter = subset.Subsetter(options=opt)
    subsetter.populate(unicodes=target_charset)
    subsetter.subset(font)
    subset.save_font(font, target_file, opt)
Example #7
0
def subset_font(source_file, target_file,
                include=None, exclude=None, options=None):
    """Subsets a font file.

    Subsets a font file based on a specified character set. If only include is
    specified, only characters from that set would be included in the output
    font.  If only exclude is specified, all characters except those in that
    set will be included.  If neither is specified, the character set will
    remain the same, but inaccessible glyphs will be removed.

    Args:
      source_file: Input file name.
      target_file: Output file name
      include: The list of characters to include from the source font.
      exclude: The list of characters to exclude from the source font.
      options: A dictionary listing which options should be different from the
          default.

    Raises:
      NotImplementedError: Both include and exclude were specified.
    """
    opt = subset.Options()

    opt.name_IDs = ['*']
    opt.name_legacy = True
    opt.name_languages = ['*']
    opt.layout_features = ['*']
    opt.notdef_outline = True
    opt.recalc_bounds = True
    opt.recalc_timestamp = True
    opt.canonical_order = True
    opt.drop_tables = ['+TTFA']

    if options is not None:
        for name, value in options.iteritems():
            setattr(opt, name, value)

    if include is not None:
        if exclude is not None:
            raise NotImplementedError(
                'Subset cannot include and exclude a set at the same time.')
        target_charset = include
    else:
        if exclude is None:
            exclude = []
        source_charset = coverage.character_set(source_file)
        target_charset = source_charset - set(exclude)

    font = subset.load_font(source_file, opt)
    subsetter = subset.Subsetter(options=opt)
    subsetter.populate(unicodes=target_charset)
    subsetter.subset(font)
    subset.save_font(font, target_file, opt)
Example #8
0
def test_all_combinations(
    max_len, font_file_name, min_allowed, max_allowed, language=None):
    """Tests the rendering of all combinations up to certain length."""

    font_characters = coverage.character_set(font_file_name)
    font_characters -= set(range(0x00, 0x20))  # Remove ASCII controls
    font_characters = [unichr(code) for code in font_characters]
    font_characters = sorted(font_characters)

    all_strings = []
    for length in range(1, max_len+1):
        all_combinations = itertools.product(font_characters, repeat=length)
        all_strings += [''.join(comb) for comb in all_combinations]

    test_data = '\n'.join(all_strings)
    return test_rendering(
        test_data, font_file_name, min_allowed, max_allowed, language)
def test_rendering(
    data, font_file_name, min_allowed, max_allowed, language=None):
    """Test the rendering of the input data in a given font.
    
    The input data is first filtered for sequences supported in the font.
    """
    font_characters = coverage.character_set(font_file_name)
    # Hack to add ASCII digits, even if the font doesn't have them,
    # to keep potential frequency info in the input intact
    font_characters |= set(range(ord('0'), ord('9')+1))

    supported_chars_regex = _regular_expression_from_set(font_characters)

    harfbuzz_input = []
    for match in supported_chars_regex.finditer(data):
        harfbuzz_input.append(match.group(0))

    harfbuzz_input = '\n'.join(harfbuzz_input)

    return render.test_text_vertical_extents(
        harfbuzz_input, font_file_name, min_allowed, max_allowed, language)
Example #10
0
def find_fonts():
    font_name_regexp = re.compile(
        '(NotoSans|NotoSerif|NotoNaskh|NotoKufi|Arimo|Cousine|Tinos)'
        '(.*?)'
        '(UI|Eastern|Estrangela|Western)?'
        '-'
        '(|Black|Bold|DemiLight|Light|Medium|Regular|Thin)'
        '(Italic)?'
        '(-Windows)?'
        '.[ot]t[cf]')

    unicode_data.load_data()

    for directory in [
            path.join(FONT_DIR, 'hinted'),
            path.join(FONT_DIR, 'unhinted'), CJK_DIR
    ]:
        for filename in os.listdir(directory):
            match = font_name_regexp.match(filename)
            if not match:
                assert (filename == 'NotoSansCJK.ttc'
                        or  # All-comprenehsive CJK
                        filename.endswith('.ttx') or
                        filename.startswith('README.') or filename
                        in ['COPYING', 'LICENSE', 'NEWS'])
                continue
            family, script, variant, weight, style, platform = match.groups()

            if family in {'Arimo', 'Cousine', 'Tinos'}:
                continue  # Skip these three for the website

            if family.startswith('Noto'):
                family = family.replace('Noto', 'Noto ')

            if weight == '':
                weight = 'Regular'

            assert platform is None

            if script == '':  # LGC
                supported_scripts.update({'Latn', 'Grek', 'Cyrl'})
            elif script in {'JP', 'KR', 'SC', 'TC', 'CJK'}:
                continue  # Skip unified or old CJK fonts
            else:
                script = convert_to_four_letter(script)
                supported_scripts.add(script)

            file_path = path.join(directory, filename)
            if filename.endswith('.ttf') or filename.endswith('.otf'):
                charset = coverage.character_set(file_path)
            else:
                charset = NotImplemented

            if directory == CJK_DIR:
                hint_status = 'hinted'
            else:
                hint_status = path.basename(directory)
            assert hint_status in ['hinted', 'unhinted']

            key = family.replace(' ', '-')
            if script:
                key += '-' + script
            if variant not in {None, 'UI'}:
                key += '-' + variant
            key = key.lower()

            font = Font(file_path, hint_status, key, family, script, variant,
                        weight, style, platform, charset)
            all_fonts.append(font)
def find_fonts():
    font_name_regexp = re.compile(
        '(NotoSans|NotoSerif|NotoNaskh|NotoKufi|Arimo|Cousine|Tinos)'
        '(.*?)'
        '(UI|Eastern|Estrangela|Western)?'
        '-'
        '(|Black|Bold|DemiLight|Light|Medium|Regular|Thin)'
        '(Italic)?'
        '(-Windows)?'
        '.[ot]t[cf]')

    unicode_data.load_data()

    for directory in [path.join(FONT_DIR, 'hinted'),
                      path.join(FONT_DIR, 'unhinted'),
                      CJK_DIR]:
        for filename in os.listdir(directory):
            match = font_name_regexp.match(filename)
            if not match:
                assert (
                    filename == 'NotoSansCJK.ttc' or  # All-comprenehsive CJK
                    filename.endswith('.ttx') or
                    filename.startswith('README.') or
                    filename in ['COPYING', 'LICENSE', 'NEWS'])
                continue
            family, script, variant, weight, style, platform = match.groups()

            if family in {'Arimo', 'Cousine', 'Tinos'}:
                continue  # Skip these three for the website

            if family.startswith('Noto'):
                family = family.replace('Noto', 'Noto ')

            if weight == '':
                weight = 'Regular'

            assert platform is None

            if script == '':  # LGC
                supported_scripts.update({'Latn', 'Grek', 'Cyrl'})
            elif script in {'JP', 'KR', 'SC', 'TC', 'CJK'}:
                continue  # Skip unified or old CJK fonts
            else:
                script = convert_to_four_letter(script)
                supported_scripts.add(script)

            file_path = path.join(directory, filename)
            if filename.endswith('.ttf') or filename.endswith('.otf'):
                charset = coverage.character_set(file_path)
            else:
                charset = NotImplemented

            if directory == CJK_DIR:
                hint_status = 'hinted'
            else:
                hint_status = path.basename(directory)
            assert hint_status in ['hinted', 'unhinted']

            key = family.replace(' ', '-')
            if script:
                key += '-' + script
            if variant not in {None, 'UI'}:
                key += '-' + variant
            key = key.lower()

            font = Font(file_path, hint_status, key,
                        family, script, variant, weight, style, platform,
                        charset)
            all_fonts.append(font)