Age | Commit message (Collapse) | Author | Files | Lines |
|
Only the very first line-to following a move-to can have any
significance if degenerate whilst stroking, so skip all others.
In other words,
0 0 m 0 0 l stroke
produces a capped degenerate path (i.e a dot),
0 0 m 0 0 l 0 0 l stroke
produces the same degenerate stroke, and
0 0 m 0 0 l 1 0 l stroke
produce a horizontal line.
|
|
Malte Nuhn reported hitting an assertion:
cairo-path-stroke.c:1816: _cairo_rectilinear_stroker_line_to: Assertion `a->x == b->x || a->y == b->y' failed.
http://bugs.freedesktop.org/show_bug.cgi?id=24797
when stroking an apparently simple path:
0 8.626485 m
0 8.626485 l
5.208333 2.5 l
10.416667 2.5 l
15.625 2.5 l
20.833333 2.5 l
26.041667 2.5 l
31.25 2.5 l
36.458333 2.5 l
41.666667 2.5 l
46.875 2.5 l
52.083333 2.5 l
57.291667 2.5 l
62.5 2.5 l
67.708333 2.5 l
72.916667 2.5 l
78.125 2.5 l
83.333333 2.5 l
88.541667 2.5 l
93.75 2.5 l
98.958333 2.5 l
104.166667 2.5 l
109.375 2.5 l
114.583333 2.5 l
119.791667 2.5 l
125 2.5 l
stroke
which upon reduction becomes:
0.000000 8.625000 m 5.207031 2.500000 l 125.000000 2.500000 l stroke
The bug is that after spotting a repeated line-to we move the previous
end-point without reclassifying the path, hence we miss the
non-rectilinear step.
|
|
When returning the single box that represents a path, always return it
consistently wound.
|
|
To correctly handle retessellating trapezods constructed from alternately
wound boxes, then we need to pass that information from the path to the
tessellator. We do this by switching the direction of the box if the first
edge is horizontal as opposed to vertical.
|
|
_cairo_path_fixed_is_box() is only called for filled paths and so must
handle the implicit close (which was already being correctly handled by
_cairo_path_fixed_iter_is_box).
|
|
As the close implicitly issues a line-to to the initial point, remove an
identical line-to if present.
|
|
Eliminate repeated line-to to the current point.
|
|
Move the definition to a separate header file and allow callers to inline
the simple function.
|
|
If a subsequent PATH_OP is just a continuation of the previous line, i.e.
it has the same gradient, then just replace the end-point of the previous
line with the new point rather than adding a new operation. Surprisingly
this occurs in the wild, but the main motivation is a future optimisation
to reduce the number of intersections during stroke-to-path.
|
|
When switching the path over to use the circularly linked list, 73f801,
I missed updating the path iterator.
|
|
As pointed out by Andrea, and now tested by test/degenerate-rel-curve-to,
this attempt at removing degenerate curve-to was broken.
|
|
As pointed out by Andrea, and now tested by test/degenerate-curve-to, a
curve-to that begins and ends on the same point may extend further due to
its control points. It can not be simply replaced with a degenerate
line-to. In order to do so we will need more extensive degeneracy
checking, ala _cairo_spline_init().
|
|
This reverts commit c72ca2f2296b5fbc5859059b98221e5ffe087dae.
This commit was broken as verified by the curve-to-as-line-to test
case.
|
|
Avoid the high cost associated with curves if we can convert the curve to
a straight line.
|
|
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
|
|
As we don't strictly use the current-point in comparing paths, exclude it
from the hash. Similarly use the path content flags as a cheap means to
differentiate contents.
|
|
Use the cairo_list_t and its style of iterators to improve the readability
of the cairo_path_buf_t management. Note the complications that arise from
the embedding of the initial buf -- however the macros do help make the
unusual manipulations more identifiable.
|
|
Simple debug macro to print the path to stderr during construction.
|
|
Whilst constructing the path, if the operations continue to be
axis-aligned lines, allow the is_box and is_region flags to persist. These
are set to false as soon as a curve-to is added, a diagonal or in the case
of is_region a non-integer point.
|
|
When cairo_curve_to happens to start a new subpath (e.g., after a call
to cairo_new_sub_path()), it also needs to update the last_move_point.
Otherwise the new current point after a close_path() will be at an
unexpected position.
Therefore, call _cairo_path_fixed_move_to() explicitly.
|
|
Annotate object init/fini routines to detect use-after-free for
on-stack/embedded objects.
|
|
Adds a new, fake, fontconfig font backend. Fontconfig can be disabled
using --disable-fc, in which case the toy text API wont find fonts and
the internal font will always be used.
Also defines the feature macro CAIRO_HAS_FC_FONT. The two fontconfig-specific
functions in cairo-ft.h depend on that macro now.
|
|
Be consistent.
|
|
A normal comment was marked as a gtk-doc entry and thus causing gtk-doc to
complain.
|
|
Use const to document the read-only nature of the arguments passed to the
callbacks.
|
|
Yikes! The callback could fail so we need to propagate the error status.
|
|
We want to hit the current fast paths for rendering axis aligned
rectilinear paths rather than spans, and for that we need to be able
to identify regional paths.
|
|
Perform a plain iteration rather than a flattening one if the path
knows it doesn't have any curves.
|
|
Use the gcc likelihood annotation to indicate that allocation failures are
extremely unlikely.
|
|
The error paths should be hit very rarely during normal operation, so mark
them as being unlikely so gcc may emit better code.
|
|
Also scan for appendages of simple rectangles.
|
|
As the empty path points to an embedded buf, we cannot rely on the buf
pointer being NULL to mark end-of-path.
|
|
Scan the path for a series of consistently wound rectangles.
|
|
The spline decomposition code allocates and stores points in a temporary
buffer which is immediately consumed by the caller. If the caller supplies
a callback that handles each point computed along the spline, then we can
use the point immediately and avoid the allocation.
|
|
A new meta-surface backend for serialising drawing operations to a
CairoScript file. The principal use (as currently envisaged) is to provide
a round-trip testing mechanism for CairoScript - i.e. we can generate
script files for every test in the suite and check that we can replay them
with perfect fidelity. (Obviously this does not provide complete coverage
of CairoScript's syntax, but should give reasonable coverage over the
operators.)
|
|
|
|
|
|
Based on patch from Peter Clifton.
|
|
|
|
|
|
|
|
Ensure the entire path is compared.
|
|
Modify cairo-pdf-operators.c to emit to 're' path operator when the
path contains only a rectangle. This can only be done when the path is
logically equivilent to the the path drawn by the 're'
operator. Otherwise dashed strokes may start on the wrong line.
ie the path must be equivalent to:
cairo_move_to (cr, x, y);
cairo_rel_line_to (cr, width, 0);
cairo_rel_line_to (cr, 0, height);
cairo_rel_line_to (cr, -width, 0);
cairo_close_path (cr);
which is also equivilent to cairo_rectangle().
|
|
|
|
_cairo_path_fixed_interpret_flat flattens the path as it
interprets it, meaning that a curve_to callback is not
required.
|
|
When copying the cairo_path_fixed_t, consolidate the list of
dynamically allocated cairo_path_buf_t into a single buffer.
|
|
By enlarging buf_size to ensure the correct alignment of the points
array with the cairo_path_buf_t block, we can efficiently use the
padding bytes to store more ops.
|
|
In http://bugs.gentoo.org/show_bug.cgi?id=203282, it was identified that
the cairo_path_buf was causing unaligned accesses (thus generating SIGBUS
on architectures like the SPARC) to its array of points. As we manually
allocate a single block of memory for the cairo_path_buf_t and its
arrays, we must also manually ensure correct alignment - as opposed to
cairo_path_buf_fixed_t for which the compiler automatically aligns the
embedded arrays.
|
|
cairo_path_op_t is a char, and can't be directly used as array subscript.
|
|
All the copied data buffers except the first one weren't completely
initialized (num_ops and num_points). That was the cause of the failure
of some vector surface tests, like random-intersections.
|