Ejemplo n.º 1
0
def coordinates_report(glyph: Glyph, glyf_table: Any, nocolor: bool) -> str:
    """
    Returns a coordinates report string from glyph-level parameter
    data.
    """
    if glyph.numberOfContours > 0:
        coords, endpoints, flags = glyph.getCoordinates(glyf_table)

        endpoint_coordinates = [coords[endpoint] for endpoint in endpoints]

        coordinates_string: str = ""
        for x, coord in enumerate(coords):
            # on- and off-curve points are defined in
            # the `flags` integer array that are mapped
            # 1:1 to coordinate indices
            # test the on curve bit mask here and
            # use this to define the appropriate
            # string value in the report
            on_off = ON_OFF[flags[x] & FLAG_ON_CURVE]
            # this is a start coordinate if it
            # (1) is the first coordinate in the iterable
            # (2) follows a previous endpoint coordinate
            start_coord = (x == 0) or (coords[x - 1] in endpoint_coordinates)
            if start_coord:
                coordinates_string += (
                    f"{str(coord): >13} "
                    f"{green_text(START_STRING, nocolor=nocolor): <13}{os.linesep}"
                )
            # end coordinates are defined by the indices returned
            # in the Glyph.getGlyphCoordinates method return tuple
            # compare current test coordinate with those coordinate
            # values
            elif coords[x] in endpoint_coordinates:
                coordinates_string += (
                    f"{str(coord): >13} "
                    f"{red_text(END_STRING, nocolor=nocolor): <13}{os.linesep}"
                )
            else:
                coordinates_string += f"{str(coord): >13} {on_off: >13}{os.linesep}"

        return coordinates_string
    else:
        return f"   No contours{os.linesep}"
Ejemplo n.º 2
0
def quadratic_path(glyph: Glyph,
                   glyf_table: Any,
                   include_implied=False) -> List[Coordinate]:
    """
    Returns a list of datastructure.Coordinate objects for
    a quadratic curve path without implied on-curve points
    by default. Implied on-curve points are calculated and
    added to the path when the include_implied parameter is
    set to `True`.

    Note: composite fontTools.ttLib.tables._g_l_y_f.Glyph
    *must* be decomposed before they are passed to this
    function.

    See https://stackoverflow.com/a/20772557/2848172 for
    detailed information about implied on-curve points, loss
    of information, and the TTF binary quadratic curve
    specification.
    """
    coords, endpoints, flags = glyph.getCoordinates(glyf_table)
    endpoint_coordinates = [coords[endpoint] for endpoint in endpoints]
    new_coords: List[Coordinate] = []

    for x, coord in enumerate(coords):
        # on- and off-curve points are defined in
        # the `flags` integer array that are mapped
        # 1:1 to coordinate indices
        on_curve: bool = (flags[x] & FLAG_ON_CURVE) != 0
        # this is a start coordinate if it
        # (1) is the first coordinate in the iterable
        # (2) follows a previous endpoint coordinate
        start_coord: bool = (x == 0) or (coords[x - 1] in endpoint_coordinates)
        # this is an end coordinate if the coordinate tuple is in
        # endpoint_coordinates
        end_coord: bool = coord in endpoint_coordinates
        # cannot be both start and end point
        assert not (end_coord and start_coord)

        if include_implied:
            if not on_curve:
                # there should always be a previous point in the contour
                # if this is *not* an on-curve point
                last_on_curve = (flags[x - 1] & FLAG_ON_CURVE) != 0
                if not last_on_curve:
                    last = coords[x - 1]
                    # get the implied on curve point between two off curve points
                    implied_coordinate = midpoint_between_coordinates(
                        last, coord)
                    new_implied_coordinate = Coordinate(
                        implied_coordinate[0],
                        implied_coordinate[1],
                        oncurve=True,
                        startpoint=False,
                        endpoint=False,
                        implied=True,
                    )
                    # add *new* implied coordinate that was not in the original
                    # coordinate set
                    # set next coordinate attr in the last coordinate if there is one
                    if len(new_coords) > 0 and not new_coords[-1].endpoint:
                        new_coords[-1].set_coord_next(new_implied_coordinate)
                        new_implied_coordinate.set_coord_previous(
                            new_coords[-1])
                    # add the new implied coordinate
                    new_coords.append(new_implied_coordinate)
        # add current coordinate object from this
        # iteration on the original coordinate set
        new_coordinate = Coordinate(
            coord[0],
            coord[1],
            oncurve=on_curve,
            startpoint=start_coord,
            endpoint=end_coord,
            implied=False,
        )
        if len(new_coords) > 0 and not new_coords[-1].endpoint:
            new_coords[-1].set_coord_next(new_coordinate)
            new_coordinate.set_coord_previous(new_coords[-1])
        new_coords.append(new_coordinate)

    return new_coords