When an opaque surface is used as a mask, Quartz converts it to
greyscale and uses the result as an alpha value. Cairo expects the
mask operation to ignore the color components and only use the alpha
of the pattern.
The expected behavior can be achieved by drawing the mask on a
temporary surface with an alpha channel.
Fixes clear-source.
Quartz cannot correctly handle arbitrary domains. Falling back is
needed to get correct results on very large (in parameter space)
gradients.
For PAD extended gradients, limiting the domain to (at most) [-0.5,
1.5] is sufficient to guarantee that it will correctly sample the
extreme stops and improves the accuracy (over having a much bigger
domain).
Fixes radial-gradient, radial-gradient-mask, radial-gradient-source,
radial-gradient-mask-source, radial-gradient-one-stop.
Improves the quality of the linear gradients in linear-gradient,
linear-gradient-subset, mask, operator-source, trap-clip.
Make cairo-quartz respect the convention that stack-allocated data
structures use the size computed by CAIRO_STACK_ARRAY_LENGTH ().
Additionally this increases the size of the dash and glyph arrays,
making dynamic memory allocation less likely.
The tolerance argument of _cairo_gradient_pattern_box_to_parameter ()
is in pattern space, so to have it constant in device space, it should
depend on the pattern matrix.
In ps and pdf the fallback resolution alone is not meaningful. The
resolution/fallback_resolution ratio should be used instead.
cairo_image_get_data() and other direct access functions are often
misused by applications because they don't call cairo_surface_flush()
and/or cairo_surface_mark_dirty() around the code which accesses the
surface data directly.
Although this information is already available in the description of
the cairo_surface_t type, adding a reminder about it in the direct
access functions should make it easier to use them correctly.
README indicates MacOSX 10.4 as a requirement for quartz and we are
directly using some functions that have been added to the public
CoreGraphics API in 10.4.
rop 10.3-specific workarounds and link to 10.4 API functions instead
of loading them at runtime.
Share code between linear and radial gradients, using
_cairo_gradient_pattern_box_to_parameter() instead of open coding the
parameter range computation.
As a side effect this fixes parameter range computation for radial
gradients, because the previous code assumed that the focal point was
inside the circles.
Reviewed-by: M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
Path are always interpreted in forward direction, so the ability of
interpreting in the opposite direction (which is very unlikely to be
useful at all) can be removed.
imageSurface was used to store a reference to the fallback image
generated by during fallbacks for gradients. The fallback code
has been removed as it is not needed anymore, thus this field can
be removed as well.
Some pattern types (gradients, surface patterns) require some
temporary information to be stored as "graphic state", because it
doesn't belong to CGContext. Previously all of this data was stored
inside the surface during the drawing operations, now it's in a
stack-allocated structure (of type cairo_quartz_drawing_state_t).
Based on a patch by Robert O'Callahan <robert@ocallahan.org>.
See https://bugzilla.mozilla.org/show_bug.cgi?id=522859
DO_SHADING, DO_IMAGE and DO_TILED_IMAGE sources all require the source
to be painted over the whole surface (inside the clip region), thus can
share the same code path in drawing functions.
Both DO_SOLID and DO_PATTERN setup the underlying CGContext to directly
use the chosen color/pattern when filling and stroking, thus require no
additional drawing operations and can share the same drawing code.
Share some code between the drawing functions by saving the state
and setting the operator when setting up the source and by restoring
the state during teardown.
Based on a patch by Robert O'Callahan <robert@ocallahan.org>.
See https://bugzilla.mozilla.org/show_bug.cgi?id=522859
DO_NOTHING and DO_UNSUPPORTED are not actual actions and are better
handled by returning an appropriate cairo_int_status_t (and falling
back, if needed).
Instead of extending the range of the interpolation parameter to make
sure that pixels exactly on the edge get drawn, we are now asking
quartz to extend the gradient.
Make PAD extended gardients more robust, by computing the color
explicitly like for REPEAT and REFLECT extend modes.
This removes a hack introducing a small but non-0 negative value
that ensured that the gradient started with the correct color (but
not that it ended with the correct one, too).
Fixes linear-gradient-large.
By keeping "virtual extents", quartz surfaces now keep track of
the extents where they want the gradients to be consistent.
This works across various API for surface creation and editing:
- cairo_surface_create_for_rectangle
- cairo_surface_create_similar + cairo_surface_set_device_offset
- cairo_push_group/cairo_pop_group
This method does not use clip extents, so it also makes gradient
rasterization independent of clip/path extents.
Pixman master (soon to become pixman 0.20) implements radial
gradients based on the PDF specification (section 8.7.4.5.4).
Quartz natively implements them, so falling back is not needed
anymore.
Returning CAIRO_INT_STATUS_NOTHING_TO_DO removes some code that
specifically handles it to convert to CAIRO_STATUS_SUCCESS. This
is already performed out of the backend, in the upper layers, so
it is not needed here.
The pattern handling code ensures that 0 stops patterns are reduced
to clear solid patterns before being passed down to the backend.
An assertion is used to make sure that the assumption actually holds,
removing the duplication of the reduce-to-solid-clear logic.
Invalid enum values were being ignored (and replaced by a default
value). This behavior is not desirable on development builds,
because an explicit failure is much easier to track.
Assertions allow release builds to keep on with the old behaviour,
while development builds fail as soon as the invalid operaiton is
performed.
Quartz previously crashed with NULL backends and didn't check for
the backend type when getting a CGContext from a quartz surface,
returning meaningless data for subsurfaces.
Falling back when painting would ignore the alpha value (which is
needed to have the correct mask opacity).
_cairo_quartz_surface_paint_cg doesn't fallback, so the usual mask
fallback path is now taken, as expected.
Self-intersecting strokes were drawn incorrectly when an unbounded
operator was used, since the fixup operation also cleared the
intersection.
Fixes clip-stroke-unbounded.
The interpolation range of repeating radial gradients can safely be
reflected around any integer (previously 0), but for reflect-extended
radial gradients can only be reflected around odd integers if the
appearance is to be the same, thus reflecting around 1 is correct for both.
Fixes radial-gradient.
I did this manually so I could review the docs at the same time.
If anyone finds typos or other mistakes I did, please complain to me (or
better: fix them).
Use scale instead of manually compositing font_matrix and ctm and
composite it with the context ctm, so that no workaround for clipping
is needed anymore.
Quartz uses a bit ordering that is consistent with cairo on big
endian architectures, but isn't on little endian architectures.
Fixes a1-mask and large-source-roi (on little endian)
I discovered a small bug in cairo-quartz gradients. If you have multiple stops
at position 0, then cairo-quartz pads with the *last* stop at position 0,
instead of the first stop at position 0. This patch fixes that.
From https://bugzilla.mozilla.org/show_bug.cgi?id=513395