def test_whole_font(self, font): philter = FlattenComponentsFilter() modified = philter(font) assert modified == { "nestedComponentGlyph", "componentAndNestedComponentsGlyph", "nestedNestedContourAndComponentGlyph", "nestedScaledComponentGlyph", "scaledNestedComponentGlyph", } assert [(c.baseGlyph, c.transformation) for c in font["nestedComponentGlyph"].components ] == [("contourGlyph", (1, 0, 0, 1, 0, 0))] assert [(c.baseGlyph, c.transformation) for c in font["componentAndNestedComponentsGlyph"].components ] == [ ("contourGlyph", (1, 0, 0, 1, 0, 0)), ("contourGlyph", (1, 0, 0, 1, 350, 0)), ("contourGlyph", (1, 0, 0, 1, 700, 0)), ] assert [(c.baseGlyph, c.transformation) for c in font["nestedContourAndComponentGlyph"].components ] == [ ("contourAndComponentGlyph", (1, 0, 0, 1, 50, 0)), ] assert [ (c.baseGlyph, c.transformation) for c in font["nestedNestedContourAndComponentGlyph"].components ] == [("contourAndComponentGlyph", (1, 0, 0, 1, 95, 0))] assert [(c.baseGlyph, c.transformation) for c in font["nestedScaledComponentGlyph"].components ] == [("contourGlyph", (0.5, 0, 0, 0.5, 90, 90))] assert [(c.baseGlyph, c.transformation) for c in font["scaledNestedComponentGlyph"].components ] == [("contourGlyph", (0.6, 0, 0, 0.6, 100, 100))]
def test_nested_components_glyph(self, font): philter = FlattenComponentsFilter(include={"nestedComponentGlyph"}) modified = philter(font) assert modified == {"nestedComponentGlyph"} assert [(c.baseGlyph, c.transformation) for c in font["nestedComponentGlyph"].components ] == [("contourGlyph", (1, 0, 0, 1, 0, 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) if self.flattenComponents: from ufo2ft.filters.flattenComponents import FlattenComponentsFilter for ufo, glyphSet in zip(self.ufos, self.glyphSets): FlattenComponentsFilter()(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
def test_whole_font(self, font): philter = FlattenComponentsFilter() modified = philter(font) assert modified == set(['c', 'd']) assert ([(c.baseGlyph, c.transformation) for c in font['c'].components] == [('a', (1, 0, 0, 1, 0, 0))]) assert ([(c.baseGlyph, c.transformation) for c in font['d'].components ] == [('a', (1, 0, 0, 1, 0, 0)), ('a', (1, 0, 0, 1, 350, 0)), ('a', (1, 0, 0, 1, 700, 0))])
def test_whole_font(self, font): philter = FlattenComponentsFilter() modified = philter(font) assert modified == set(["c", "d"]) assert [(c.baseGlyph, c.transformation) for c in font["c"].components] == [ ("a", (1, 0, 0, 1, 0, 0)) ] assert [(c.baseGlyph, c.transformation) for c in font["d"].components] == [ ("a", (1, 0, 0, 1, 0, 0)), ("a", (1, 0, 0, 1, 350, 0)), ("a", (1, 0, 0, 1, 700, 0)), ]
def test_scaled_component_glyph(self, font): philter = FlattenComponentsFilter( include={ "scaledComponentGlyph", "nestedScaledComponentGlyph", "scaledNestedComponentGlyph", }) modified = philter(font) assert modified == { "nestedScaledComponentGlyph", "scaledNestedComponentGlyph", } assert [(c.baseGlyph, c.transformation) for c in font["nestedScaledComponentGlyph"].components ] == [("contourGlyph", (0.5, 0, 0, 0.5, 90, 90))] assert [(c.baseGlyph, c.transformation) for c in font["scaledNestedComponentGlyph"].components ] == [("contourGlyph", (0.6, 0, 0, 0.6, 100, 100))]
def initDefaultFilters( self, removeOverlaps=False, overlapsBackend=None, flattenComponents=False, convertCubics=True, conversionError=None, reverseDirection=True, rememberCurveType=True, ): filters = [] _init_explode_color_layer_glyphs_filter(self.ufo, filters) # len(g) is the number of contours, so we include the all glyphs # that have both components and at least one contour filters.append(DecomposeComponentsFilter(include=lambda g: len(g))) if flattenComponents: from ufo2ft.filters.flattenComponents import FlattenComponentsFilter filters.append(FlattenComponentsFilter()) if removeOverlaps: from ufo2ft.filters.removeOverlaps import RemoveOverlapsFilter if overlapsBackend is not None: filters.append(RemoveOverlapsFilter(backend=overlapsBackend)) else: filters.append(RemoveOverlapsFilter()) if convertCubics: from ufo2ft.filters.cubicToQuadratic import CubicToQuadraticFilter filters.append( CubicToQuadraticFilter( conversionError=conversionError, reverseDirection=reverseDirection, rememberCurveType=rememberCurveType and self.inplace, ) ) return filters
def run_fontmake(self, source, args): if "output_dir" in args: original_output_dir = args["output_dir"] tmpdir = tempfile.TemporaryDirectory() args["output_dir"] = tmpdir.name if (self.config["flattenComponents"] or self.config["decomposeTransformedComponents"]): filters = args.get("filters", []) if self.config["flattenComponents"]: filters.append(FlattenComponentsFilter(pre=True)) if self.config["decomposeTransformedComponents"]: filters.append(DecomposeTransformedComponentsFilter(pre=True)) args["filters"] = filters if source.endswith(".glyphs"): FontProject().run_from_glyphs(source, **args) elif source.endswith(".designspace"): FontProject().run_from_designspace(source, **args) elif source.endswith(".ufo"): FontProject().run_from_ufos([source], **args) else: raise ValueError("Can't build from unknown source file: %s" % source) if "output_path" in args: return [args["output_path"]] else: # Move it to where it should be... file_names = os.listdir(args["output_dir"]) for file_name in file_names: shutil.move(os.path.join(args["output_dir"], file_name), original_output_dir) tmpdir.cleanup() args["output_dir"] = original_output_dir return [os.path.join(original_output_dir, x) for x in file_names]
def test_logger(self, font): with CapturingLogHandler(logger, level="INFO") as captor: philter = FlattenComponentsFilter() _ = philter(font) captor.assertRegex("Flattened composite glyphs: 5")
def test_component_glyph(self, font): philter = FlattenComponentsFilter(include={"componentGlyph"}) assert not philter(font)
def test_empty_glyph(self, font): philter = FlattenComponentsFilter(include={"space"}) assert not philter(font)
def test_nested_components_glyph(self, font): philter = FlattenComponentsFilter(include={'c'}) modified = philter(font) assert modified == set(['c']) assert ([(c.baseGlyph, c.transformation) for c in font['c'].components] == [('a', (1, 0, 0, 1, 0, 0))])
def test_contour_glyph(self, font): philter = FlattenComponentsFilter(include={'a'}) assert not philter(font)