# cu2qu: Cubic to quadratic curve conversion

Routines for converting cubic curves to quadratic splines, suitable for use in OpenType to TrueType outline conversion.

Conversion is carried out to a degree of tolerance provided by the user. While it is relatively easy to find the best single quadratic curve to represent a given cubic (see for example this method from CAGD), the best-fit method may not be sufficiently accurate for type design.

Instead, this method chops the cubic curve into multiple segments before converting each cubic segment to a quadratic, in order to ensure that the resulting spline fits within the given tolerance.

The basic curve conversion routines are implemented in the `fontTools.cu2qu.cu2qu` module; the `fontTools.cu2qu.ufo` module applies these routines to all of the curves in a UFO file or files; while the `fontTools.cu2qu.cli` module implements the `fonttools cu2qu` command for converting a UFO format font with cubic curves into one with quadratic curves.

## fontTools.cu2qu.cu2qu

fontTools.cu2qu.cu2qu.curve_to_quadratic(curve, double max_err)

  Approximate a cubic Bezier curve with a spline of n quadratics.

  Parameters

    - cubic (sequence) – Four 2D tuples representing control points of the cubic Bezier curve.

    - max_err (double) – Permitted deviation from the original curve.

  Returns

    A list of 2D tuples, representing control points of the quadratic spline if it fits within the given tolerance, or `None` if no suitable spline could be calculated.

fontTools.cu2qu.cu2qu.curves_to_quadratic(curves, max_errors)

  Return quadratic Bezier splines approximating the input cubic Beziers.

  Parameters

    - curves – A sequence of n curves, each curve being a sequence of four 2D tuples.

    - max_errors – A sequence of n floats representing the maximum permissible deviation from each of the cubic Bezier curves.

  Example:

      >>> curves_to_quadratic( [
      ...   [ (50,50), (100,100), (150,100), (200,50) ],
      ...   [ (75,50), (120,100), (150,75),  (200,60) ]
      ... ], [1,1] )
      [[(50.0, 50.0), (75.0, 75.0), (125.0, 91.66666666666666), (175.0, 75.0), (200.0, 50.0)], [(75.0, 50.0), (97.5, 75.0), (135.41666666666666, 82.08333333333333), (175.0, 67.5), (200.0, 60.0)]]

  The returned splines have “implied oncurve points” suitable for use in TrueType `glif` outlines - i.e. in the first spline returned above, the first quadratic segment runs from (50,50) to ( (75 + 125)/2 , (120 + 91.666..)/2 ) = (100, 83.333…).

  Returns

    A list of splines, each spline being a list of 2D tuples.

  Raises

    - fontTools.cu2qu.Errors.ApproxNotFoundError – if no suitable approximation

    - can be found for all curves with the given parameters. –

## fontTools.cu2qu.ufo

Converts cubic bezier curves to quadratic splines.

Conversion is performed such that the quadratic splines keep the same end-curve tangents as the original cubics. The approach is iterative, increasing the number of segments for a spline until the error gets below a bound.

Respective curves from multiple fonts will be converted at once to ensure that the resulting splines are interpolation-compatible.

fontTools.cu2qu.ufo.font_to_quadratic(font, **kwargs)

  Convenience wrapper around fonts_to_quadratic, for just one font. Return True if the font was modified, else return False.

fontTools.cu2qu.ufo.fonts_to_quadratic(fonts, max_err_em=None, max_err=None, reverse_direction=False, stats=None, dump_stats=False, remember_curve_type=True)

  Convert the curves of a collection of fonts to quadratic.

  All curves will be converted to quadratic at once, ensuring interpolation compatibility. If this is not required, calling fonts_to_quadratic with one font at a time may yield slightly more optimized results.

  Return True if fonts were modified, else return False.

  By default, cu2qu stores the curve type in the fonts’ lib, under a private key “com.github.googlei18n.cu2qu.curve_type”, and will not try to convert them again if the curve type is already set to “quadratic”. Setting ‘remember_curve_type’ to False disables this optimization.

  Raises IncompatibleFontsError if same-named glyphs from different fonts have non-interpolatable outlines.