コード例 #1
0
ファイル: font_project.py プロジェクト: adrientetar/fontmake
 def convert_curves(self, ufos, compatible=False):
     if compatible:
         fonts_to_quadratic(ufos, reverse_direction=True, dump_stats=True)
     else:
         for ufo in ufos:
             print('>> Converting curves for ' + self._font_name(ufo))
             font_to_quadratic(ufo, reverse_direction=True, dump_stats=True)
コード例 #2
0
 def convert_curves(self, ufos, compatible=False):
     if compatible:
         fonts_to_quadratic(ufos, reverse_direction=True, dump_stats=True)
     else:
         for ufo in ufos:
             print('>> Converting curves for ' + self._font_name(ufo))
             font_to_quadratic(ufo, reverse_direction=True, dump_stats=True)
コード例 #3
0
    def test_incompatible_fonts(self):
        font1 = Font()
        font1.info.unitsPerEm = 1000
        glyph1 = font1.newGlyph("a")
        pen1 = glyph1.getPen()
        for operator, args in [("moveTo", ((0, 0),)),
                               ("lineTo", ((1, 1),)),
                               ("endPath", ())]:
            getattr(pen1, operator)(*args)

        font2 = Font()
        font2.info.unitsPerEm = 1000
        glyph2 = font2.newGlyph("a")
        pen2 = glyph2.getPen()
        for operator, args in [("moveTo", ((0, 0),)),
                               ("curveTo", ((1, 1), (2, 2), (3, 3))),
                               ("endPath", ())]:
            getattr(pen2, operator)(*args)

        with pytest.raises(IncompatibleFontsError) as excinfo:
            fonts_to_quadratic([font1, font2])
        assert excinfo.match("fonts contains incompatible glyphs: 'a'")

        assert hasattr(excinfo.value, "glyph_errors")
        error = excinfo.value.glyph_errors['a']
        assert isinstance(error, IncompatibleSegmentTypesError)
        assert error.segments == {1: ["line", "curve"]}
コード例 #4
0
ファイル: Build.py プロジェクト: LaurentLhoir/roboto
    def generateTTFs(self):
        """Build TTF for each font generated since last call to generateTTFs."""

        fonts = [OpenFont(ufo) for ufo in self.generatedFonts]
        self.generatedFonts = []

        log(">> Converting curves to quadratic")
        # using a slightly higher max error (e.g. 0.0025 em), dots will have
        # fewer control points and look noticeably different
        max_err = 0.002
        if self.compatible:
            fonts_to_quadratic(fonts, max_err_em=max_err, dump_stats=True)
        else:
            for font in fonts:
                fonts_to_quadratic([font], max_err_em=max_err, dump_stats=True)

        log(">> Generating TTF files")
        for font in fonts:
            ttfName = self.generateOutputPath(font, "ttf")
            log(os.path.basename(ttfName))
            for glyph in font:
                for contour in glyph:
                    contour.reverseContour()
            saveOTF(
                font, ttfName,
                self.thinGlyphOrder if "Thin" in ttfName else self.glyphOrder,
                truetype=True)
コード例 #5
0
    def process(self):
        from cu2qu.ufo import fonts_to_quadratic

        # first apply all custom pre-filters
        for funcs, ufo, glyphSet in zip(self.preFilters, self.ufos,
                                        self.glyphSets):
            for func in funcs:
                func(ufo, glyphSet)

        fonts_to_quadratic(
            self.glyphSets,
            max_err=self._conversionErrors,
            reverse_direction=self._reverseDirection,
            dump_stats=True,
            remember_curve_type=self._rememberCurveType and self.inplace,
        )

        decompose = DecomposeComponentsFilter(include=lambda g: len(g))
        for ufo, glyphSet in zip(self.ufos, self.glyphSets):
            decompose(ufo, glyphSet)

        # finally apply all custom post-filters
        for funcs, ufo, glyphSet in zip(self.postFilters, self.ufos,
                                        self.glyphSets):
            for func in funcs:
                func(ufo, glyphSet)

        return self.glyphSets
コード例 #6
0
    def generateTTFs(self):
        """Build TTF for each font generated since last call to generateTTFs."""

        fonts = [OpenFont(ufo) for ufo in self.generatedFonts]
        self.generatedFonts = []

        log(">> Converting curves to quadratic")
        # using a slightly higher max error (e.g. 0.0025 em), dots will have
        # fewer control points and look noticeably different
        max_err = 0.002
        if self.compatible:
            fonts_to_quadratic(fonts, max_err_em=max_err, dump_stats=True)
        else:
            for font in fonts:
                fonts_to_quadratic([font], max_err_em=max_err, dump_stats=True)

        log(">> Generating TTF files")
        for font in fonts:
            ttfName = self.generateOutputPath(font, "ttf")
            log(os.path.basename(ttfName))
            saveOTF(
                font,
                ttfName,
                self.thinGlyphOrder if "Thin" in ttfName else self.glyphOrder,
                truetype=True)
コード例 #7
0
 def makeMasterGlyphsQuadractic(self):
     """
     Optimize and convert all master ufo to quad curves.
     """
     masters = self.fonts.values()
     # use cu2qu to optimize all masters
     fonts_to_quadratic(masters)
     for master in masters:
         master.segmentType = "qcurve"
コード例 #8
0
 def makeMasterGlyphsQuadractic(self):
     """
     Optimize and convert all master ufo to quad curves.
     """
     masters = self.masters.values()
     # use cu2qu to optimize all masters
     fonts_to_quadratic(masters)
     for master in masters:
         master.font.segmentType = "qcurve"
コード例 #9
0
ファイル: font_project.py プロジェクト: googlei18n/fontmake
 def convert_curves(self, ufos, compatible=False, reverse_direction=True,
                    conversion_error=None):
     if compatible:
         fonts_to_quadratic(
             ufos, max_err_em=conversion_error,
             reverse_direction=reverse_direction, dump_stats=True)
     else:
         for ufo in ufos:
             print('>> Converting curves for ' + self._font_name(ufo))
             font_to_quadratic(
                 ufo, max_err_em=conversion_error,
                 reverse_direction=reverse_direction, dump_stats=True)
コード例 #10
0
    def process(self):
        from cu2qu.ufo import fonts_to_quadratic

        fonts_to_quadratic(self.glyphSets,
                           max_err=self._conversionErrors,
                           reverse_direction=self._reverseDirection,
                           dump_stats=True)

        decompose = DecomposeComponentsFilter(include=lambda g: len(g))
        for ufo, glyphSet in zip(self.ufos, self.glyphSets):
            decompose(ufo, glyphSet)

        return self.glyphSets
コード例 #11
0
ファイル: font_project.py プロジェクト: sahwar/fontmake
    def convert_curves(self, ufos, compatible=False, reverse_direction=True,
                       conversion_error=None):
        from cu2qu.ufo import font_to_quadratic, fonts_to_quadratic

        if compatible:
            logger.info('Converting curves compatibly')
            fonts_to_quadratic(
                ufos, max_err_em=conversion_error,
                reverse_direction=reverse_direction, dump_stats=True)
        else:
            for ufo in ufos:
                logger.info('Converting curves for ' + self._font_name(ufo))
                font_to_quadratic(
                    ufo, max_err_em=conversion_error,
                    reverse_direction=reverse_direction, dump_stats=True)
コード例 #12
0
 def convert_curves(self,
                    ufos,
                    compatible=False,
                    reverse_direction=True,
                    conversion_error=None):
     if compatible:
         fonts_to_quadratic(ufos,
                            max_err_em=conversion_error,
                            reverse_direction=reverse_direction,
                            dump_stats=True)
     else:
         for ufo in ufos:
             print('>> Converting curves for ' + self._font_name(ufo))
             font_to_quadratic(ufo,
                               max_err_em=conversion_error,
                               reverse_direction=reverse_direction,
                               dump_stats=True)
コード例 #13
0
 def test_both_max_err_and_max_err_em(self, fonts):
     with pytest.raises(TypeError, match="Only one .* can be specified"):
         fonts_to_quadratic(fonts, max_err=1.000, max_err_em=0.001)
コード例 #14
0
ファイル: cli.py プロジェクト: fullstackenviormentss/cu2qu
def main(args=None):
    parser = argparse.ArgumentParser(prog="cu2qu")
    parser.add_argument(
        "--version", action="version", version=cu2qu.__version__)
    parser.add_argument(
        "infiles",
        nargs="+",
        metavar="INPUT",
        help="one or more input UFO source file(s).")
    parser.add_argument("-v", "--verbose", action="count", default=0)
    parser.add_argument(
        "-e",
        "--conversion-error",
        type=float,
        metavar="ERROR",
        default=None,
        help="maxiumum approximation error measured in EM (default: 0.001)")
    parser.add_argument(
        "--keep-direction",
        dest="reverse_direction",
        action="store_false",
        help="do not reverse the contour direction")

    mode_parser = parser.add_mutually_exclusive_group()
    mode_parser.add_argument(
        "-i",
        "--interpolatable",
        action="store_true",
        help="whether curve conversion should keep interpolation compatibility"
    )
    mode_parser.add_argument(
        "-j",
        "--jobs",
        type=int,
        nargs="?",
        default=1,
        const=_cpu_count(),
        metavar="N",
        help="Convert using N multiple processes (default: %(default)s)")

    output_parser = parser.add_mutually_exclusive_group()
    output_parser.add_argument(
        "-o",
        "--output-file",
        default=None,
        metavar="OUTPUT",
        help=("output filename for the converted UFO. By default fonts are "
              "modified in place. This only works with a single input."))
    output_parser.add_argument(
        "-d",
        "--output-dir",
        default=None,
        metavar="DIRECTORY",
        help="output directory where to save converted UFOs")

    options = parser.parse_args(args)

    if not options.verbose:
        level = "WARNING"
    elif options.verbose == 1:
        level = "INFO"
    else:
        level = "DEBUG"
    logging.basicConfig(level=level)

    if len(options.infiles) > 1 and options.output_file:
        parser.error("-o/--output-file can't be used with multile inputs")

    if options.output_dir:
        output_paths = [
            os.path.join(options.output_dir, os.path.basename(p))
            for p in options.infiles
        ]
    elif options.output_file:
        output_paths = [options.output_file]
    else:
        # save in-place
        output_paths = list(options.infiles)

    kwargs = dict(dump_stats=options.verbose > 0,
                  max_err_em=options.conversion_error,
                  reverse_direction=options.reverse_direction)

    if options.interpolatable:
        logger.info('Converting curves compatibly')
        ufos = [defcon.Font(infile) for infile in options.infiles]
        if fonts_to_quadratic(ufos, **kwargs):
            for ufo, output_path in zip(ufos, output_paths):
                logger.info("Saving %s", output_path)
                ufo.save(output_path)
        else:
            for input_path, output_path in zip(options.infiles, output_paths):
                _copytree(input_path, output_path)
    else:
        jobs = min(len(options.infiles),
                   options.jobs) if options.jobs > 1 else 1
        if jobs > 1:
            func = partial(_font_to_quadratic, **kwargs)
            logger.info('Running %d parallel processes', jobs)
            with closing(mp.Pool(jobs)) as pool:
                # can't use Pool.starmap as it's 3.3+ only
                pool.map(func, zip(options.infiles, output_paths))
        else:
            for paths in zip(options.infiles, output_paths):
                _font_to_quadratic(paths, **kwargs)
コード例 #15
0
'''
 First, install dependencies in requirements.txt.
 
 Then, use this script like this:
 python src/build-scripts/convert-fonts-cu2qu-CLI.py <directory path>
'''

import sys
import glob
from defcon import Font
from cu2qu.ufo import fonts_to_quadratic

directory = sys.argv[1]

print(directory)

fonts = []

for filepath in glob.iglob(f'{directory}/*.ufo'):
    print(filepath)
    fonts.append(Font(str(filepath)))

print(fonts)

stats = {}
print(fonts_to_quadratic(fonts, stats=stats, dump_stats=True))
コード例 #16
0
from defcon import Font
from cu2qu.ufo import fonts_to_quadratic

casual_a = Font(
    'src/masters--quadratic_production/experiments--curvier-casual/Recursive Mono-Casual A.ufo'
)
casual_a_ital = Font(
    'src/masters--quadratic_production/experiments--curvier-casual/Recursive Mono-Casual A Italic - gradually fixed.ufo'
)
casual_b = Font(
    'src/masters--quadratic_production/experiments--curvier-casual/Recursive Mono-Casual B.ufo'
)
casual_b_ital = Font(
    'src/masters--quadratic_production/experiments--curvier-casual/Recursive Mono-Casual B Italic - gradually fixed.ufo'
)

# fonts_to_quadratic([casual_a, casual_a_ital, casual_b, casual_b_ital])

for font in [casual_a, casual_a_ital, casual_b, casual_b_ital]:
    fonts_to_quadratic([font])
コード例 #17
0
 def test_modified(self, fonts):
     modified = fonts_to_quadratic(fonts)
     assert modified
コード例 #18
0
 def test_stats(self, fonts):
     stats = {}
     fonts_to_quadratic(fonts, stats=stats)
     assert stats == {'1': 1, '2': 79, '3': 130, '4': 2}
コード例 #19
0
 def test_dump_stats(self, fonts):
     with CapturingLogHandler(logger, "INFO") as captor:
         fonts_to_quadratic(fonts, dump_stats=True)
     assert captor.assertRegex("New spline lengths:")
コード例 #20
0
 def test_no_remember_curve_type(self, fonts):
     assert CURVE_TYPE_LIB_KEY not in fonts[0].lib
     fonts_to_quadratic(fonts, remember_curve_type=False)
     assert CURVE_TYPE_LIB_KEY not in fonts[0].lib
コード例 #21
0
 def test_different_glyphsets(self, fonts):
     del fonts[0]['a']
     assert 'a' not in fonts[0]
     assert 'a' in fonts[1]
     assert fonts_to_quadratic(fonts)
コード例 #22
0
 def test_max_err_em_list(self, fonts):
     stats = {}
     fonts_to_quadratic(fonts, max_err_em=[0.002, 0.002], stats=stats)
     assert stats == {'1': 5, '2': 193, '3': 14}
コード例 #23
0
 def test_max_err_list(self, fonts):
     stats = {}
     fonts_to_quadratic(fonts, max_err=[4.096, 4.096], stats=stats)
     assert stats == {'1': 5, '2': 193, '3': 14}
コード例 #24
0
 def test_remember_curve_type(self, fonts):
     fonts_to_quadratic(fonts, remember_curve_type=True)
     assert fonts[0].lib[CURVE_TYPE_LIB_KEY] == "quadratic"
     with CapturingLogHandler(logger, "INFO") as captor:
         fonts_to_quadratic(fonts, remember_curve_type=True)
     assert captor.assertRegex("already converted")