As is so often the case, reading the commit log gives you fresh insight in
the problem - often called confessional debugging...
We can simplify the problem by ignoring attr->[xy]_offset, for the time
being, and focus on computing the correct matrix. This is comparatively
simple as all we need to do is perform the appropriate rounding on the
translation vector.
A complication I realised after pushing 3eb4bc3 was handling larger
sampled areas. Extending the test case revealed that the optimization
was broken for anything but the identity transform (after removing the
translation). Correctness first, leaving the "pixel-exact" solution for
interested reader...
Carl suggested that cairo_pure and cairo_const are pretty opaque, even to
the developer who added them, so it is extremely important that they have
a good description so that they are used correctly and perhaps ported to
other compilers.
With the addition of cairo_show_text_glyphs() came a couple of functions
to query whether the target supported the extended attributes. However,
at Carl's request cairo_has_show_text_glyphs() was removed - but the
documentation was not updated to reflect that.
As identified in bug 15479,
Unpredictable performance of cairo-xlib with non-integer translations of a
source surface pattern
(https://bugs.freedesktop.org/show_bug.cgi?id=15479),
source surfaces with a fractional translation hit slow paths for some
drivers, causing seemingly random performance variations. As a work-around
Owen Taylor proposed that cairo could convert non-integer translations on
NEAREST sources patterns to their integer equivalents.
The messy detail involved here is replicating the rounding mode used by
pixman for the sample offset, but otherwise the conversion is fairly
trivial.
As proof-of-principle, compute a scale factor to avoid overflow when
converting a linear pattern to pixman_fixed_t. Fixes test/huge-pattern,
but the principle should be extended to handle more cases of overflow.
Since CAN_TEST_PS_SURFACE does not currently require spectre, we were
attempting to compile in spectre support for any2ppm even on systems
without libspectre installed. Fix that by adding a separate flag for
CAIRO_HAS_SPECTRE.
From bug 18010 (https://bugs.freedesktop.org/show_bug.cgi?id=18010),
in order to make flockfile() available we need to set _POSIX_C_SOURCE and
according to the man page, the appropriate feature check is
_POSIX_THREAD_SAFE_FUNCTIONS.
Bulia Byak reported a bug where cairo was crashing with a particular
font. The font had an incorrect entry in the cmap table that caused
cairo to read from outside of the buffer allocated for the cmap.
Mention that building the configure script requires at least version 0.16
of pkg-config.
See the old bug:
Bug 4702 PKG_PROG_PKG_CONFIG: command not found
(https://bugs.freedesktop.org/show_bug.cgi?id=4702)
Bug 11734:
XRender crashes due to NULL pointer from Cairo on SGI O2
(https://bugs.freedesktop.org/show_bug.cgi?id=1173)
is an example of a case where we try to perform an XRender operation on a
surface with a format that was not supported by the XRender extension. By
marking the extension version as -1 on those surfaces, the current checks
for SURFACE_RENDER_HAS_* always correctly return false and prevent us try
to create a Picture with a NULL xrender_format.
Add a new test case to Cairo for checking the performance of Cairo's
equivalent to GDK's gdk_pixbuf_composite_color() operation. That is an
operation that happens to be extremely useful when viewing or editing
transparent images so I think it is important that it is as fast as
possible.
Add a test case to capture the current behaviour when a segment ends on
an off/on dash transition.
Originally filed as bug:
Miter artifacts for dashed strokes
https://bugs.freedesktop.org/show_bug.cgi?id=17973
Since cairo.h is a public header file, we need to be careful so that it
can be compiled by random compilers and even users specifying "-Werror
-Wundef" (mentioning no names, Company). So replace the bare (and legal)
#if _MSC_VER
with
#if defined (_MSC_VER)
just in case.
Missed updating win32 when implementing the new paginated API to query
support for the fine-grained fallbacks.
(Thanks to Adrian for spotting this oversight.)
The use of fine-grained fallbacks requires the native support of the
SOURCE operator applied to an image on the target surface. SVG 1.2
introduces the "comp-op:src" mode fulfilling this criteria - so we can
enable fine-grained fallbacks for 1.2+.
Update test/fine-grained-fallbacks to exercise this pathway in SVG 1.2 -
as SVG natively supported all the current operations within that test.
This reveals yet another librsvg bug in handling SVG 1.2.
Avoid passing a 32bit integer as a cairo_int64_t in case we do not have a
64bit native integral type. As a side-effect this means we can also use a
narrower multiply.
For the simple case where the pattern matrix only contains an integer
translation then care is taken to convert that to a identity source matrix
with the translation applied to the [xy]_offsets. 5b97ee6525 broke this
guarantee by applying the clone offsets to the source matrix. So when the
source matrix is identity we can simply adjust the [xy]_offsets and
preserve the identity matrix. (This idea can be extended further by
removing any integer translation from the source matrix and storing it in
the [xy]_offsets as a means to extend the limited precision in
pixman_matrix_t - encountered when downscaling large images offset onto
the target surface.)
A precondition for using the core XCopyArea protocol is that the source
attributes contain only integer translations. However, we failed to apply
any integer translations from the source matrix to the XCopyArea offsets.
This worked prior to 5b97ee6525 as
_cairo_pattern_acquire_surface_for_surface() was careful to only generate
an identity matrix if the pattern matrix only contained an integer
translation (and thus we would use XCopyArea in the xlib backend).
mitch reported on irc that expose events in the gimp were suffering from
artifacts which he tracked down to a bug with clipping and source
surfaces. This is the cairo test case for that regression.
gtk-doc fails make check for array as it insists that even the simplest
functions must have a long description and cannot be entirely described by
their arguments and return value.
During insertion we must traverse the skiplist in order to find the
insertion point for the new element. As we descend each level, the next
element in the chain for this level is sometimes the same as the one we
just compared against (and know that the new element is greater than).
Hence we can skip the search on that level and descend to the next. During
world_map this reduces the number of calls into _sweep_line_elt_compare()
by ~2.5% (and when performing trapezoidation on strokes gives a similar
speed up of about 2% - not bad for the addition of a single line.)
Use primitives from cairo-wideint-private.h - in this case it helps to
make the code more readable as well as reduce dependence on native 64bit
integers.
Prefer to use the operations form cairo-wideint-private.h in order to
improve readability and reduce our assumptions on the availability of
64bit integers.
'const' is a stricter form of 'pure' in that functions declared with that
attribute do not access any values other than their arguments (in
contrast to 'pure' which is allowed to read from global memory).
In the cairo 1.8.0 release the documentation would get generated with
the second and third version components transposed, (so it would say
1.0.8). Fix the obviously mistaken transposition.
Take advantage of the gcc function attribute 'pure', which tells gcc that
the function result only depends upon its arguments and it has zero side
effects (e.g. it does not clobber memory). This gives gcc greater
opportunity to rearrange and optimize the wideint arithmetic.
We often use the construct:
if (_cairo_int64_lt (A, B)
return -1;
if (_cairo_int64_gt (A, B)
return 1;
return 0;
to compare two large integers (int64, or int128) which does twice the
required work on CPUs without large integer support. So replace it with a
single wideint function _cairo_int64_cmp() and therefore allow
opportunities to both shrink the code size and write a more efficient
comparison. (The primarily motivation is to simply replace each block with
a single more expressive line.)