Skip to content

Vger filling BezPath uses incorrect closing point #821

@timboudreau

Description

@timboudreau

Attaching screen shots of the same code rendered with vello and vger - I'm doing some stuff that involves rendering a design view of characters in a programmatically generated font.

It took a while to figure out exactly what was going wrong with fill-rendering, but this simple example makes it clear. This is two rectangles, one inside the other, the outer added clockwise from the top-left, the inner added counter-clockwise from the top-left.

This means there are two logical paths within the BezPath which is filled; when working with such paths, "closing" the path means returning to the start point of the current segment - that is, the nearest move-to instruction prior to the closing one in the list of path segments.

As is visible in the attached screen-shot, while the vello renderer fills the path correctly, the vger renderer is using the start point of the entire BezPath rather than the start point of the current segment when filling.

I have dug through the code a little, but it is not obvious where it is happening. That it works in vello rules out it being a bug in kurbo, but I have not been able to track it down yet - it could be in vger proper - PathScanner::init() seems a likely place for it but I haven't dug through it thoroughly. Is Floem using a fork of vger where that could be fixed?

Image Image

The code to generate this uses an internal library (I'm porting this code from Java), converted to a kurbo::BezPath, but it's pretty clear what it does:

pub fn box_test(sz: &Sizes, path: &mut P2D) {
    let outer_rect = sz.mid_box_2();
    let inner_rect = outer_rect.grown(-sz.thickness);
    path.move_to(outer_rect.corner(Corner::TopLeft));
    path.line_to(outer_rect.corner(Corner::TopRight));
    path.line_to(outer_rect.corner(Corner::BottomRight));
    path.line_to(outer_rect.corner(Corner::BottomLeft));
    path.close();
    
    path.move_to(inner_rect.corner(Corner::TopLeft));
    path.line_to(inner_rect.corner(Corner::BottomLeft));
    path.line_to(inner_rect.corner(Corner::BottomRight));
    path.line_to(inner_rect.corner(Corner::TopRight));
    path.close();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions