The original test for wild miters would only work with a square transform
(and, in fact, the original code required an identity transform). Instead of
fixing that, I replaced it with a more obvious test which makes sure the
miter corner lies between the two faces and not out in space somewhere.
This fixes the current failure get-path-extents, which is a
demonstration of the following bug:
cairo_stroke_extents() gives wrong result for arcs in some cases
https://bugs.freedesktop.org/show_bug.cgi?id=7245
Many thanks to Michael Urman whose review of early versions of
this work found a fatal mistake in my algebra.
Every time we assign or return a hard-coded error status wrap that value
with a call to _cairo_error(). So the idiom becomes:
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
or
return _cairo_error (CAIRO_STATUS_INVALID_DASH);
This ensures that a breakpoint placed on _cairo_error() will trigger
immediately cairo detects the error.
Now, the functions to add new data to a polygon all become void,
and there's a new _cairo_polygon_status call to query the status
at the end of a sequence of operations.
With this change, we fix many callerswhich were previously not
checking the return values of _cairo_polygon functions by adding
only a single call to _cairo_polygon_status rathern than several
new checks.
Adds some state, 'dash_starts_on', to keep track of whether a dashed path
starts with dash_on or not. This fixes the 'leaky-dash' bug (#4863) and
some other degenerate cases. The new version is, in my opinion,
considerably cleaner and more understandable than the old code.
Finally, the rewrite changes the behaviour of dashing to add degenerate
caps around corners that start at the same place as a dash begins. This
matches the behaviour seen in acroread.
This rewrite is based on an initial rewrite done by Jeff Smith.
has_initial_sub_path more accurately describes the condition we want to
track. This flag is used to indicate when an initial sub_path needs capping
but has no associated slope and thus no associated faces.
This custom stroking code allows backends to use optimized region-based
drawing operations for rectilinear strokes. This results in a 5-25x
performance improvement when drawing rectilinear shapes:
image-rgb box-outline-stroke-100 0.18 -> 0.01: 25.58x speedup
████████████████████████▋
image-rgba box-outline-stroke-100 0.18 -> 0.01: 25.57x speedup
████████████████████████▋
xlib-rgb box-outline-stroke-100 0.49 -> 0.06: 8.67x speedup
███████▋
xlib-rgba box-outline-stroke-100 0.22 -> 0.04: 5.39x speedup
████▍
In other words, using cairo_stroke instead of cairo_fill to draw the
same shape was 5-15x slower before, but is 1.2-2x faster now.
This follows the PDF and SVG specifications which only draw degenerate paths when
round caps are in effect.
With this commit, the degenerate-path test passes with the image, xlib, and pdf
backends, (but still fails with ps and svg backends).
This patch was produced with the following (GNU) sed script:
sed -i -r -e '/^[ \t]*\/?\*/ s/[ \t]+$//'
run on all *.[ch] files within cairo, (though I manually excluded
src/cairo-atsui-font.c which has a code line that appears as a comment
to this script).
The extra check makes sure zero length segments are not skipped when computing
the dash start state. This is needed so that we get proper line capping if, for
example, the first dash segment has zero length and we have a dash offset of
zero.
Face computation still works if a line has zero length, all that is needed is a
slope and a point. This patch fixes bug #5561 because the faces are initialized
even if the segment has zero length as expected by
_cairo_stroker_line_to_dashed.
This makes the slope calculation more accurate for dashed lines by computing it
once for the entire line instead for each individual dash segment. It also
adjusts stroker_line_to() to match the new convention for
stroker_add_sub_edge().
This makes line_to_dashed more like line_to by returning immediately on
degenerate paths. This is needed so that we can do the slope calculation for
the entire line.
Fixes the bug mentioned in b87726ee2a by reseting
the dash pattern for each new subpath. This is correct behaviour according to
the end of PDF Reference v1.6 section 4.3.2.
This commit now makes the dash-caps-joins test case pass for all
backends except for the PostScript backend.
This adds a new function which has as its only effect the elimination
of
the current point. This makes it much easier to use the various
cairo_arc calls when the initial line_to is not actually desired.
This function also unifies and generalizes the long-existing behavior
of cairo_line_to being treated as cairo_move_to when there is no
current point. With the addition of cairo_new_sub_path this becomes a
documented feature with similar behavior in cairo_curve_to as well.
Track changes in surface backend from fill_path to fill.
Track the new canonical argument naming and ordering for the 5 drawing operations.
Move various stroke style settings into new cairo_stroke_style_t.
Drop NULL fill_path backend function which no longer exists.
Remove pen_regular field from the gstate.
Move stroke fallback from gstate to surface where it belongs.
Eliminate dependence on cairo_gstate_t object.
Fix to include just cairo-clip-private.h rather than cairo-gstate.private.h.
Move face-flipping from inside _cairo_stroker_add_caps to new _cairo_stroker_add_leading_cap variant of _cairo_stoker_add_cap.
Change to call _cairo_stroker_add_leading_cap or _cairo_stroker_add_trailing_cap as appropriate.
Remove dash-caps-joins from the XFAIL list and add reference image.
Abstract the cap-addition code from the end of the stroke operation into a new _cairo_stroker_add_caps function.
Call the new _cairo_stroker_add_caps at the beginning of every move_to so that we get caps on every subpath and not just the last one.