Esempio n. 1
0
def run_bakery(bakery_yml_file, verbose=False):
    try:
        config = yaml.safe_load(open(op.join(bakery_yml_file), 'r'))
    except IOError:
        config = yaml.safe_load(open(BAKERY_CONFIGURATION_DEFAULTS))

    sourcedir = op.dirname(bakery_yml_file)
    try:
        builddir = 'build'
        if GITPYTHON_INSTALLED:
            try:
                repo = Repo(sourcedir)
                builddir = repo.git.rev_parse('HEAD', short=True)
            except git.exc.InvalidGitRepositoryError:
                pass
        builddir = os.environ.get('TRAVIS_COMMIT', builddir)

        if 'process_files' not in config:
            directory = UpstreamDirectory(sourcedir)
            # normalize process_files path
            config['process_files'] = directory.get_fonts()

        create_bakery_config(bakery_yml_file, config)

        b = Bakery('', sourcedir, 'builds', builddir)
        b.load_config(bakery_yml_file)
        b.run()
    except:
        if verbose or config.get('verbose'):
            raise
        sys.exit(1)
Esempio n. 2
0
    def test_metrics_descents_equal_bbox(self):
        """ Check that descents values are same as min glyph point """
        dirname = os.path.dirname(self.operator.path)

        directory = UpstreamDirectory(dirname)

        fonts_descents_not_bbox = []
        ymin = 0

        _cache = {}
        for filename in directory.get_binaries():
            ttfont = Font.get_ttfont(os.path.join(dirname, filename))

            ymin_, _ = ttfont.get_bounding()
            ymin = min(ymin, ymin_)

            _cache[filename] = {
                'os2typo': abs(ttfont.descents.os2typo),
                'os2win': abs(ttfont.descents.os2win),
                'hhea': abs(ttfont.descents.hhea)
            }

        for filename, data in _cache.items():
            datas = [data['os2typo'], data['os2win'], data['hhea']]
            if datas != [abs(ymin)] * 3:
                fonts_descents_not_bbox.append(filename)

        if fonts_descents_not_bbox:
            _ = '[%s] ascents differ to minimum value: %s'
            self.fail(_ % (', '.join(fonts_descents_not_bbox), ymin))
Esempio n. 3
0
    def execute(self, pipedata, prefix=""):
        task = self.bakery.logging_task('Convert sources to TTF')
        if self.bakery.forcerun:
            return

        if pipedata.get('compiler') == 'make':
            import subprocess
            directory = UpstreamDirectory(op.join(self.builddir, 'sources'))
            snapshot_bin = directory.BIN

            process = subprocess.Popen(['make'],
                                       cwd=op.join(self.builddir, 'sources'))
            process.communicate()

            directory = UpstreamDirectory(op.join(self.builddir, 'sources'))
            snapshot_after_bin = directory.BIN

            for fontpath in set(snapshot_bin) ^ set(snapshot_after_bin):
                if fontpath.lower().endswith('.ttf'):
                    os.copy(op.join(self.builddir, 'sources', fontpath),
                            self.builddir)
                    self.run_processes(op.basename(fontpath), pipedata)

            return pipedata

        self.convert(pipedata)

        return pipedata
Esempio n. 4
0
    def test_metrics_descents_equal_bbox(self):
        """ Check that descents values are same as min glyph point """
        dirname = os.path.dirname(self.operator.path)

        directory = UpstreamDirectory(dirname)

        fonts_descents_not_bbox = []
        ymin = 0

        _cache = {}
        for filename in directory.get_binaries():
            ttfont = Font.get_ttfont(os.path.join(dirname, filename))

            ymin_, _ = ttfont.get_bounding()
            ymin = min(ymin, ymin_)

            _cache[filename] = {
                'os2typo': abs(ttfont.descents.os2typo),
                'os2win': abs(ttfont.descents.os2win),
                'hhea': abs(ttfont.descents.hhea)
            }

        for filename, data in _cache.items():
            datas = [data['os2typo'], data['os2win'], data['hhea']]
            if datas != [abs(ymin)] * 3:
                fonts_descents_not_bbox.append(filename)

        if fonts_descents_not_bbox:
            _ = '[%s] ascents differ to minimum value: %s'
            self.fail(_ % (', '.join(fonts_descents_not_bbox), ymin))
Esempio n. 5
0
def run_bakery(sourcedir, config=None):

    try:
        if config:
            config = yaml.safe_load(open(config, 'r'))
        else:
            config = yaml.safe_load(open(BAKERY_CONFIGURATION_DEFAULTS))

        if 'process_files' not in config:
            directory = UpstreamDirectory(sourcedir)
            config['process_files'] = directory.get_fonts()

        bakeryyaml = os.path.abspath(os.path.join(sourcedir, '.bakery.yaml'))
        l = open(bakeryyaml, 'w')
        l.write(yaml.safe_dump(config))
        l.close()

        b = Bakery('', sourcedir, 'builds', sourcedir)

        b.init_logging('%s.process.log' % sourcedir.replace('/', '-'))

        b.pipes = [
            pipe.Copy, pipe.Build, pipe.Rename, pipe.Metadata, pipe.PyFtSubset,
            pipe.FontLint, pipe.Optimize, pipe.AutoFix, pipe.CopyLicense,
            pipe.CopyFontLog, pipe.CopyDescription, pipe.CopyMetadata,
            pipe.CopyTxtFiles, pipe.TTFAutoHint, pipe.PyFontaine
        ]

        config = os.path.join(sourcedir, '.bakery.yaml')
        b.load_config(config)

        b.run()
    except Exception, ex:
        print >> sys.stderr, 'FAILED: %s' % sourcedir
        print >> sys.stderr, ex
Esempio n. 6
0
def run_bakery(path, verbose=False):
    # fontbakery-build supports passing arguments of directory or
    # concrete bakery.y[a]ml files. In case of passing directory
    # it looks at existing bakery.yml or bakery.yaml and runs on
    # first matched filepath

    # There can also be cases when directory does not contain any
    # bakery.y[a]ml or passed bakery.yml file does not exist. Then
    # fontbakery-build loads default configuration.
    bakery_yml_file = None
    sourcedir = path

    if os.path.isdir(path):
        for filename in ['bakery.yml', 'bakery.yaml']:
            if os.path.exists(os.path.join(path, filename)):
                bakery_yml_file = os.path.join(path, filename)
                break
    else:
        bakery_yml_file = path
        sourcedir = os.path.dirname(path)

    try:
        if bakery_yml_file:
            config = yaml.safe_load(open(bakery_yml_file, 'r'))
        else:
            raise IOError
    except IOError:
        bakery_yml_file = os.path.join(sourcedir, 'bakery.yml')
        config = yaml.safe_load(open(BAKERY_CONFIGURATION_DEFAULTS))

    try:
        builddir = 'build'
        if GITPYTHON_INSTALLED:
            try:
                repo = Repo(sourcedir)
                builddir = repo.git.rev_parse('HEAD', short=True)
            except git.exc.InvalidGitRepositoryError:
                pass
        builddir = os.environ.get('TRAVIS_COMMIT', builddir)

        if 'process_files' not in config:
            directory = UpstreamDirectory(sourcedir)
            # normalize process_files path
            config['process_files'] = directory.get_fonts()

        create_bakery_config(bakery_yml_file, config)

        Bakery.verbose = verbose or config.get('verbose')

        b = Bakery('', sourcedir, 'builds', builddir)
        b.addLoggingToFile()
        b.load_config(bakery_yml_file)
        b.run()
    except:
        if verbose or config.get('verbose'):
            raise
        sys.exit(1)
Esempio n. 7
0
    def test_font_test_prepolation_glyph_names(self):
        """ Check glyph names are all the same across family """
        directory = UpstreamDirectory(self.path)

        glyphs = []
        for f in directory.get_fonts():
            font = PiFont(op.join(self.path, f))
            glyphs_ = font.get_glyphs()

            if glyphs and glyphs != glyphs_:
                self.fail('Family has different glyphs across fonts')
Esempio n. 8
0
    def test_family_glyph_names_match(self):
        """ Each font in family has matching glyph names? """
        directory = UpstreamDirectory(self.operator.path)
        # TODO does this glyphs list object get populated?
        glyphs = []
        for f in directory.get_fonts():
            font = PiFont(os.path.join(self.operator.path, f))
            glyphs_ = font.get_glyphs()

            if glyphs and glyphs != glyphs_:
                # TODO report which font
                self.fail('Family has different glyphs across fonts')
Esempio n. 9
0
 def convert(self, pipedata):
     directory = UpstreamDirectory(op.join(self.builddir, 'sources'))
     try:
         if directory.BIN:
             self.execute_bin([x for x in directory.BIN], pipedata)
         if directory.get_ttx():
             self.execute_ttx([op.join('sources', x) for x in directory.get_ttx()], pipedata)
         if directory.UFO:
             self.execute_ufo_sfd([op.join('sources', x) for x in directory.UFO], pipedata)
         if directory.SFD:
             self.execute_ufo_sfd([op.join('sources', x) for x in directory.SFD], pipedata)
     except:
         raise
     finally:
         self.remove_sourcesdir()
Esempio n. 10
0
def fix_metrics(testcase):
    """ Fix vmet table with actual min and max values """
    targetpath = os.path.dirname(testcase.operator.path)
    SCRIPTPATH = 'fontbakery-fix-vertical-metrics.py'

    directory = UpstreamDirectory(targetpath)

    paths = []
    for f in directory.BIN:
        path = op.join(targetpath, f)
        paths.append(path)

    command = "$ {0} --autofix {1}"
    command = command.format(SCRIPTPATH, ' '.join(paths))
    if hasattr(testcase, 'operator'):
        testcase.operator.debug(command)

    metricfix(paths)

    for path in paths:
        try:
            shutil.move(path + '.fix', path, log=testcase.operator.logger)
        except IOError:
            pass

    command = "$ {0} {1}".format(SCRIPTPATH, ' '.join(paths))
    if hasattr(testcase, 'operator'):
        testcase.operator.debug(command)
        testcase.operator.debug(metricview(paths))
Esempio n. 11
0
    def execute(self, pipedata):
        self.bakery.logging_task('Optimizing TTF')
        if self.bakery.forcerun:
            return

        for filename in UpstreamDirectory(self.builddir).BIN:
            self.run(op.join(self.builddir, filename), pipedata)
Esempio n. 12
0
    def __generateTests__(cls):
        pattern = re.compile(r'[\W_]+')
        library = Library(collections=['subsets'])

        directory = UpstreamDirectory(cls.operator.path)

        yamlpath = op.join(cls.operator.path, 'bakery.yaml')
        try:
            bakerydata = yaml.load(open(yamlpath))
        except IOError:
            bakerydata = yaml.load(open(BAKERY_CONFIGURATION_DEFAULTS))

        for fontpath in directory.UFO + directory.TTX:
            font = FontFactory.openfont(op.join(cls.operator.path, fontpath))
            for charmap, _, coverage, _ in \
                    font.get_orthographies(_library=library):
                common_name = charmap.common_name.replace('Subset ', '')
                shortname = pattern.sub('', common_name)
                if shortname not in bakerydata['subset']:
                    continue

                exec 'cls.test_charset_%s = get_test_subset_function(%s)' % (
                    shortname, coverage)
                exec 'cls.test_charset_%s.__func__.__doc__ = "Is %s covered 100%%?"' % (
                    shortname, common_name)
Esempio n. 13
0
    def test_font_prepolation_glyph_contours(self):
        """ Check that glyphs has same number of contours across family """
        directory = UpstreamDirectory(self.operator.path)

        glyphs = {}
        for f in directory.get_fonts():
            font = PiFont(os.path.join(self.operator.path, f))
            glyphs_ = font.get_glyphs()

            for glyphcode, glyphname in glyphs_:
                contours = font.get_contours_count(glyphname)
                if glyphcode in glyphs and glyphs[glyphcode] != contours:
                    msg = ('Number of contours of glyph "%s" does not match.'
                           ' Expected %s contours, but actual is %s contours')
                    self.fail(msg % (glyphname, glyphs[glyphcode], contours))
                glyphs[glyphcode] = contours
Esempio n. 14
0
    def test_font_prepolation_glyph_points(self):
        """ Check that glyphs has same number of points across family """
        directory = UpstreamDirectory(self.operator.path)

        glyphs = {}
        for f in directory.get_fonts():
            font = PiFont(os.path.join(self.operator.path, f))
            glyphs_ = font.get_glyphs()

            for g, glyphname in glyphs_:
                points = font.get_points_count(glyphname)
                if g in glyphs and glyphs[g] != points:
                    msg = ('Number of points of glyph "%s" does not match.'
                           ' Expected %s points, but actual is %s points')
                    self.fail(msg % (glyphname, glyphs[g], points))
                glyphs[g] = points
Esempio n. 15
0
 def setUp(self):
     path = os.path.realpath(os.path.dirname(__file__))
     content = open(os.path.join(path, 'diacritics.txt')).read()
     self.diacriticglyphs = [
         x.strip() for x in content.split() if x.strip()
     ]
     self.directory = UpstreamDirectory(self.operator.path)
Esempio n. 16
0
def targettask(pyfontaine, pipedata, task):
    try:
        library = Library(collections=['subsets'])
        director = Director(_library=library)

        sourcedir = op.join(pyfontaine.builddir)
        directory = UpstreamDirectory(sourcedir)

        fonts = []
        for font in directory.ALL_FONTS:
            if font.startswith('sources'):
                continue
            fonts.append(op.join(pyfontaine.builddir, font))

        _ = ('fontaine --collections subsets --text %s'
             ' > fontaine.txt\n') % ' '.join(fonts)
        pyfontaine.bakery.logging_cmd(_)

        fontaine_log = op.join(pyfontaine.builddir, 'fontaine.txt')
        fp = codecs.open(fontaine_log, 'w', 'utf-8')

        result = Builder.text_(director.construct_tree(fonts))
        fp.write(result.output)
        pyfontaine.bakery.logging_raw('end of pyfontaine process\n')
        pyfontaine.bakery.logging_task_done(task)
    except Exception as ex:
        pyfontaine.bakery.logging_raw('pyfontaine error: {}'.format(ex))
        pyfontaine.bakery.logging_raw('pyfontaine process has been failed\n')
        pyfontaine.bakery.logging_task_done(task, failed=True)
Esempio n. 17
0
def run_bakery(sourcedir, config=None):

    try:
        if config:
            config = yaml.safe_load(open(config, 'r'))
        else:
            config = yaml.safe_load(open(BAKERY_CONFIGURATION_DEFAULTS))

        if 'process_files' not in config:
            directory = UpstreamDirectory(sourcedir)
            config['process_files'] = directory.get_fonts()

        bakeryyaml = os.path.abspath(os.path.join(sourcedir, '.bakery.yaml'))
        l = open(bakeryyaml, 'w')
        l.write(yaml.safe_dump(config))
        l.close()

        b = Bakery('', sourcedir, 'builds', sourcedir)

        b.init_logging('%s.process.log' % sourcedir.replace('/', '-'))

        b.pipes = [
            pipe.Copy,
            pipe.Build,
            pipe.Rename,
            pipe.Metadata,
            pipe.PyFtSubset,
            pipe.FontLint,
            pipe.Optimize,
            pipe.AutoFix,
            pipe.CopyLicense,
            pipe.CopyFontLog,
            pipe.CopyDescription,
            pipe.CopyMetadata,
            pipe.CopyTxtFiles,
            pipe.TTFAutoHint,
            pipe.PyFontaine
        ]

        config = os.path.join(sourcedir, '.bakery.yaml')
        b.load_config(config)

        b.run()
    except Exception, ex:
        print >> sys.stderr, 'FAILED: %s' % sourcedir
        print >> sys.stderr, ex
Esempio n. 18
0
 def convert(self, pipedata):
     directory = UpstreamDirectory(op.join(self.builddir, 'sources'))
     try:
         if directory.BIN:
             self.execute_bin([x for x in directory.BIN], pipedata)
         if directory.get_ttx():
             self.execute_ttx(
                 [op.join('sources', x) for x in directory.get_ttx()],
                 pipedata)
         if directory.UFO:
             self.execute_ufo_sfd(
                 [op.join('sources', x) for x in directory.UFO], pipedata)
         if directory.SFD:
             self.execute_ufo_sfd(
                 [op.join('sources', x) for x in directory.SFD], pipedata)
     except:
         raise
     finally:
         self.remove_sourcesdir()
Esempio n. 19
0
def generate_subsets_coverage_list():
    directory = UpstreamDirectory('.')

    source_fonts_paths = []
    # `get_sources_list` returns list of paths relative to root.
    # To complete to absolute paths use python os.path.join method
    # on root and path
    for p in directory.ALL_FONTS:
        source_fonts_paths.append(p)
    return get_subsets_coverage_data(source_fonts_paths)
Esempio n. 20
0
    def convert(self, pipedata):
        directory = UpstreamDirectory(op.join(self.builddir, 'sources'))
        try:
            if directory.BIN:
                self.execute_bin([x for x in directory.BIN], pipedata)
            if directory.get_ttx():
                self.execute_ttx([op.join('sources', x) for x in directory.get_ttx()], pipedata)
            if directory.UFO:
                self.execute_ufo_sfd([op.join('sources', x) for x in directory.UFO], pipedata)
            if directory.SFD:
                self.execute_ufo_sfd([op.join('sources', x) for x in directory.SFD], pipedata)

            # binfiles = self.movebin_to_builddir([op.join('sources', x) for x in directory.ALL_FONTS])

            # self.print_vertical_metrics(binfiles)

            # pipedata['bin_files'] = binfiles
        except:
            raise
Esempio n. 21
0
    def get_fonts(self, dirname):
        directory = UpstreamDirectory(dirname)

        fonts_ascents_not_bbox = []
        ymax = 0

        _cache = {}
        for filename in directory.get_binaries():
            ttfont = Font.get_ttfont(os.path.join(dirname, filename))

            _, ymax_ = ttfont.get_bounding()
            ymax = max(ymax, ymax_)

            _cache[filename] = {
                'os2typo': ttfont.ascents.os2typo,
                'os2win': ttfont.ascents.os2win,
                'hhea': ttfont.ascents.hhea
            }

        for filename, data in _cache.items():
            if [data['os2typo'], data['os2win'], data['hhea']] != [ymax] * 3:
                fonts_ascents_not_bbox.append(filename)
        return ymax, fonts_ascents_not_bbox
Esempio n. 22
0
    def get_fonts(self, dirname):
        directory = UpstreamDirectory(dirname)

        fonts_ascents_not_bbox = []
        ymax = 0

        _cache = {}
        for filename in directory.get_binaries():
            ttfont = Font.get_ttfont(os.path.join(dirname, filename))

            _, ymax_ = ttfont.get_bounding()
            ymax = max(ymax, ymax_)

            _cache[filename] = {
                'os2typo': ttfont.ascents.os2typo,
                'os2win': ttfont.ascents.os2win,
                'hhea': ttfont.ascents.hhea
            }

        for filename, data in _cache.items():
            if [data['os2typo'], data['os2win'], data['hhea']] != [ymax] * 3:
                fonts_ascents_not_bbox.append(filename)
        return ymax, fonts_ascents_not_bbox
Esempio n. 23
0
    def test_metrics_linegaps_are_zero(self):
        """ Check that linegaps in tables are zero """
        dirname = os.path.dirname(self.operator.path)

        directory = UpstreamDirectory(dirname)

        fonts_gaps_are_not_zero = []
        for filename in directory.BIN:
            ttfont = Font.get_ttfont(os.path.join(dirname, filename))
            if bool(ttfont.linegaps.os2typo) or bool(ttfont.linegaps.hhea):
                fonts_gaps_are_not_zero.append(filename)

        if fonts_gaps_are_not_zero:
            _ = '[%s] have not zero linegaps'
            self.fail(_ % ', '.join(fonts_gaps_are_not_zero))
Esempio n. 24
0
def inferLicense(familydir):
    from bakery_cli.utils import UpstreamDirectory
    directory = UpstreamDirectory(familydir)

    if not directory.LICENSE:
        return ""

    with io.open(directory.LICENSE[0]) as fp:
        content = fp.read()
        if 'Apache License' in content:
            return 'Apache2'
        if 'SIL Open Font License, Version 1.1' in content:
            return 'OFL'
        if 'UBUNTU FONT LICENCE Version 1.0' in content:
            return 'UFL'
    return ""
Esempio n. 25
0
def generate(config, outfile='review.html'):
    directory = UpstreamDirectory(config['path'])
    fonts = [(path, FontFactory.openfont(op.join(config['path'], path)))
             for path in directory.BIN]

    metadata_file = open(op.join(config['path'], 'METADATA.json')).read()
    family_metadata = Metadata.get_family_metadata(metadata_file)
    faces = []
    for f in family_metadata.fonts:
        faces.append({
            'name': f.full_name,
            'basename': f.post_script_name,
            'path': f.filename,
            'meta': f
        })

    report_app = report_utils.BuildInfo(config)
    fonts_orthography = get_orthography(fonts)

    report_app.review_page.dump_file(fonts_orthography, 'orthography.json')
Esempio n. 26
0
    def execute(self, pipedata):
        self.bakery.logging_task('Run upstream tests')
        if self.bakery.forcerun:
            return

        result = {}
        upstreamdir = op.join(self.builddir, 'sources')

        self.bakery.logging_cmd('fontbakery-check.py upstream-repo sources')
        result['Project'] = run_set(upstreamdir, 'upstream-repo')
        directory = UpstreamDirectory(upstreamdir)

        for font in directory.ALL_FONTS:
            if font[-4:] not in '.ttx':
                self.bakery.logging_cmd('fontbakery-check.py upstream {}'.format(font))
                result[font] = run_set(op.join(upstreamdir, font), 'upstream')

        _out_yaml = op.join(self.builddir, 'upstream.yaml')

        l = codecs.open(_out_yaml, mode='w', encoding="utf-8")
        l.write(yaml.safe_dump(result))
        l.close()
Esempio n. 27
0
def generate(config, outfile='tests.html'):
    directory = UpstreamDirectory(config['path'])

    tests = {}

    data = {}
    for fp in directory.BIN:
        path = op.join(config['path'], '{}.yaml'.format(fp[:-4]))
        if op.exists(path):
            data[fp] = yaml.load(open(path))
            tests[fp] = {
                'success': len(data[fp].get('success', [])),
                'error': len(data[fp].get('error', [])),
                'failure': len(data[fp].get('failure', [])),
                'fixed': len(data[fp].get('fixed', []))
            }

    if not data:
        return

    new_data = []
    for k in data:
        d = {'name': k}
        d.update(data[k])
        new_data.append(d)

    tests_summary = {}
    tests_summary_filepath = op.join(config['path'], 'summary.tests.json')
    if op.exists(tests_summary_filepath):
        tests_summary = json.load(open(tests_summary_filepath))
    tests_summary.update(tests)

    json.dump(tests_summary, open(tests_summary_filepath, 'w'))

    report_app = report_utils.BuildInfo(config)
    report_app.tests_page.dump_file(new_data, 'tests.json')
Esempio n. 28
0
def run_bakery(path, verbose=False):
    # fontbakery-build supports passing arguments of directory or
    # concrete bakery.y[a]ml files. In case of passing directory
    # it looks at existing bakery.yml or bakery.yaml and runs on
    # first matched filepath

    # There can also be cases when directory does not contain any
    # bakery.y[a]ml or passed bakery.yml file does not exist. Then
    # fontbakery-build loads default configuration.
    bakery_yml_file = None
    sourcedir = path

    if os.path.isdir(path):
        for filename in ['bakery.yml', 'bakery.yaml']:
            if os.path.exists(os.path.join(path, filename)):
                bakery_yml_file = os.path.join(path, filename)
                break
    else:
        bakery_yml_file = path
        sourcedir = os.path.dirname(path)

    try:
        if bakery_yml_file:
            config = yaml.safe_load(open(bakery_yml_file, 'r'))
        else:
            raise IOError
    except IOError:
        bakery_yml_file = os.path.join(sourcedir, 'bakery.yml')
        config = yaml.safe_load(open(BAKERY_CONFIGURATION_DEFAULTS))

    try:
        builddir = 'build'
        if GITPYTHON_INSTALLED:
            try:
                repo = Repo(sourcedir)
                builddir = repo.git.rev_parse('HEAD', short=True)
            except git.exc.InvalidGitRepositoryError:
                pass
        builddir = os.environ.get('TRAVIS_COMMIT', builddir)

        if 'process_files' not in config:
            directory = UpstreamDirectory(sourcedir)
            # normalize process_files path
            config['process_files'] = directory.get_fonts()

        create_bakery_config(bakery_yml_file, config)

        b = Bakery('', sourcedir, 'builds', builddir)
        b.addLoggingToFile()
        b.load_config(bakery_yml_file)
        b.run()

        if not ttfautohint_installed():
            msg = ('Command line tool `ttfautohint` is required. Install it with'
                   ' `apt-get install ttfautohint` or `brew install ttfautohint`')
            logger.error(msg)
    except:
        logger.error('BUILD FAILED')
        if verbose or config.get('verbose'):
            raise
        logger.error('Run with --verbose to get stacktrace info.')
        sys.exit(1)
Esempio n. 29
0
    for p in directory.ALL_FONTS:
        source_fonts_paths.append(p)
    return get_subsets_coverage_data(source_fonts_paths)


import argparse


parser = argparse.ArgumentParser()
parser.add_argument('directory')


args = parser.parse_args()


directory = UpstreamDirectory(args.directory)
process_files = directory.ALL_FONTS

import urwid.curses_display
import urwid.raw_display
import urwid.web_display
import urwid

def show_or_exit(key):
    if key in ('q', 'Q', 'esc'):
        raise urwid.ExitMainLoop()

header = urwid.Text("Fontbakery Setup. Q exits.")


app = App(args.directory)
Esempio n. 30
0
def generate(config):
    if config.get('failed'):
        return

    directory = UpstreamDirectory(config['path'])
    if op.exists(op.join(config['path'], 'METADATA.json.new')):
        metadata_file = open(op.join(config['path'],
                                     'METADATA.json.new')).read()
    else:
        metadata_file = open(op.join(config['path'], 'METADATA.json')).read()
    family_metadata = Metadata.get_family_metadata(metadata_file)
    faces = []
    for f in family_metadata.fonts:
        faces.append({
            'name': f.full_name,
            'basename': f.post_script_name,
            'path': f.filename,
            'meta': f
        })

    metadata = yaml.load(open(op.join(config['path'], 'METADATA.yaml')))
    upstreamdata = {}
    upstreamdatafile = op.join(config['path'], 'upstream.yaml')
    if op.exists(upstreamdatafile):
        upstreamdata = yaml.load(open(upstreamdatafile))

    data = {}
    for fp in directory.BIN:
        path = op.join(config['path'], '{}.yaml'.format(fp[:-4]))
        if op.exists(path):
            data[fp] = yaml.load(open(path))
    data.update(metadata)
    data.update(upstreamdata)

    fontpaths = [op.join(config['path'], path) for path in directory.BIN]
    ttftablesizes = get_fonts_table_sizes(fontpaths)

    ftables_data = get_fonts_table_sizes_grouped(fontpaths)

    buildstate = yaml.load(open(op.join(config['path'], 'build.state.yaml')))
    autohint_sizes = buildstate.get('autohinting_sizes', [])
    vmet = get_metric_view(fontpaths)

    fonts = [(path, FontFactory.openfont(op.join(config['path'], path)))
             for path in directory.BIN]

    stems = [
        get_stem_info(op.join(config['path'], path)) for path in directory.BIN
    ]

    new_data = []
    for k in data:
        d = {'name': k}
        d.update(data[k])
        new_data.append(d)

    report_app = report_utils.BuildInfo(config)
    metrics = {'data': vmet._its_metrics, 'headings': vmet._its_metrics_header}
    table_sizes = {'tables': ttftablesizes[0], 'sizes': ttftablesizes[1:]}
    report_app.summary_page.dump_file(metrics, 'metrics.json')
    report_app.summary_page.dump_file(stems, 'stems.json')
    report_app.summary_page.dump_file(table_sizes, 'table_sizes.json')
    report_app.summary_page.dump_file(autohint_sizes, 'autohint_sizes.json')
    report_app.summary_page.dump_file(new_data, 'tests.json')
    report_app.summary_page.dump_file(
        {
            'mean': ftables_data.mean,
            'grouped': ftables_data.grouped,
            'delta': ftables_data.delta
        }, 'fonts_tables_grouped.json')
    for face in family_metadata.fonts:
        face_template = "@font-face {{ font-family: {}; src: url(fonts/{});}}\n".format(
            face.metadata_object['postScriptName'],
            face.metadata_object['filename'])
        report_app.write_file(face_template,
                              op.join(report_app.css_dir, 'faces.css'),
                              mode='a')

    fonts_serialized = dict([(str(path),
                              font_factory_instance_to_dict(fontaine))
                             for path, fontaine in fonts])
    report_app.summary_page.dump_file(fonts_serialized, 'fontaine_fonts.json')

    #Temporarily remove this broken piece of code
    if False:
        fonts_orthography = get_orthography(fonts)
        report_app.summary_page.dump_file(
            {
                'fonts_list': fonts_orthography[0],
                'coverage_averages': fonts_orthography[1],
                'fonts_info': fonts_orthography[2]
            }, 'fonts_orthography.json')
Esempio n. 31
0
 def __init__(self, testcase, fontpath):
     super(Vmet, self).__init__(testcase, fontpath)
     d = os.path.dirname(fontpath)
     directory = UpstreamDirectory(d)
     self.fonts = [os.path.join(d, f) for f in directory.BIN]
Esempio n. 32
0
def run_bakery(path, verbose=False):
    # fontbakery-build supports passing arguments of directory or
    # concrete bakery.y[a]ml files. In case of passing directory
    # it looks at existing bakery.yml or bakery.yaml and runs on
    # first matched filepath

    # There can also be cases when directory does not contain any
    # bakery.y[a]ml or passed bakery.yml file does not exist. Then
    # fontbakery-build loads default configuration.
    bakery_yml_file = None
    sourcedir = path

    if os.path.isdir(path):
        for filename in ["bakery.yml", "bakery.yaml"]:
            if os.path.exists(os.path.join(path, filename)):
                bakery_yml_file = os.path.join(path, filename)
                break
    else:
        bakery_yml_file = path
        sourcedir = os.path.dirname(path)

    try:
        if bakery_yml_file:
            config = yaml.safe_load(open(bakery_yml_file, "r"))
        else:
            raise IOError
    except IOError:
        bakery_yml_file = os.path.join(sourcedir, "bakery.yml")
        config = yaml.safe_load(open(BAKERY_CONFIGURATION_DEFAULTS))

    try:
        builddir = "build"
        if GITPYTHON_INSTALLED:
            try:
                repo = Repo(sourcedir)
                builddir = repo.git.rev_parse("HEAD", short=True)
            except git.exc.InvalidGitRepositoryError:
                pass
        builddir = os.environ.get("TRAVIS_COMMIT", builddir)

        if "process_files" not in config:
            directory = UpstreamDirectory(sourcedir)
            # normalize process_files path
            config["process_files"] = directory.get_fonts()

        create_bakery_config(bakery_yml_file, config)

        b = Bakery("", sourcedir, "builds", builddir)
        b.addLoggingToFile()
        b.load_config(bakery_yml_file)
        b.run()

        if not ttfautohint_installed():
            msg = (
                "Command line tool `ttfautohint` is required. Install it with"
                " `apt-get install ttfautohint` or `brew install ttfautohint`"
            )
            logger.error(msg)
    except:
        if verbose or config.get("verbose"):
            raise
        sys.exit(1)