Move the mime-data into its own array so that it cannot be confused with
user-data and we do not need to hard-code the copy list during
snapshotting. The copy-on-snapshotting code becomes far simpler and will
accommodate all future mime-types.
Keeping mime-data separate from user-data is important due to the
principle of least surprise - the API is different and so it would be
surprising if you queried for user-data and were returned an opaque
mime-data pointer, and vice versa. (Note this should have been prevented
by using interned strings, but conceptually it is cleaner to make the
separation.) Also it aides in trimming the user data arrays which are
linearly searched.
Based on the original patch by Adrian Johnson:
http://cgit.freedesktop.org/~ajohnson/cairo/commit/?h=metadata&id=37e607cc777523ad12a2d214708d79ecbca5b380
Adds an error code replacing CAIRO_STATUS_NO_MEMORY in one case where it
is not really appropriate. CAIRO_STATUS_INVALID_SIZE is used by several
backends that do not support image sizes beyond 2^15 pixels on each side.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
If we are dithering on the Xlib backend we can not simply repaint the
surface used for a solid pattern and must recreate it from scratch.
However, for ordinary XRender usage we do not want to have to pay that
price - so query the backend to see if we can reuse the surface.
A surface will have the chance to use span rendering at cairo_fill()
time by creating a renderer for a specific combination of
pattern/dst/op before the path is scan converted. The protocol is to
first call check_span_renderer() to see if the surface wants to render
with spans and then later call create_span_renderer() to create the
renderer for real once the extents of the path are known.
No backends have an implementation yet.
When computing the bounds of the clip path, we care more for a fast result
than absolute precision as the extents are only used as a guide to trim
the future operations. So computing the extents of the path suffices.
Allow the user to pass in a pre-allocated array and use it if the number
of boxes permits. This eliminates the frequent allocations during clipping
by toolkits.
By using a NULL backend for the error surfaces, instead of a pointer to
the image surface backend end, we save a few lookup/redirections during
dynamic linking.
A limitation of the current API was that the destroy notifier was called
on the mime-data block. This prevents the user from passing in a pointer
to a managed block, for example a mime-data block belonging to a
ref-counted object. We can overcome this by allowing the user to specify
the closure to be used with the destroy notifier.
Instead of doing a full-copy of the mime data (which can be 10K-100K,
or even larger) just copy a reference to the original mime to the
snapshot surface (as suggested by Behdad).
Use the surface user-data array allow to store an arbitrary set of
alternate image representations keyed by an interned string (which
ensures that it has a unique key in the user-visible namespace).
Update the API to mirror that of cairo_surface_set_user_data() [i.e.
return a status indicator] and switch internal users of the mime-data to
the public functions.
Add a "cairo_rectangle_int_t *extents" argument to to the following
backend functions:
paint
mask,
stroke
fill
show_glyphs
show_text_glyphs
This will be used to pass the extents of each operation computed by
the analysis surface to the backend. This is required for implementing
EXTEND_PAD.
No need to copy font options if the similar surface is from the same
backend and no special options have been applied by the user. Doing so
breaks lazy initialisation of backend specific options.
Only copy the pattern if we need to modify it, e.g. preserve a copy in a
snapshot or a soft-mask, or to modify the matrix. Otherwise we can
continue to use the original pattern and mark it as const in order to
generate compiler warnings if we do attempt to write to it.
Adrian Johnson discovered cases where we mistakenly compared the result
of unsigned arithmetic where we need signed quantities. Look for similar
cases in the users of cairo_rectangle_int_t.
After discussing the scaled font locking with Behdad, it transpired that it
is not sufficient for a font to be locked for the lifetime of a scaled glyph,
but that the scaled font's glyph cache must be frozen for the glyph'
lifetime. If the cache is not frozen, then there is a possibility that the
glyph may be evicted before the reference goes out of scope i.e. the glyph
becomes invalid whilst we are trying to use it.
Since the freezing of the cache is the stronger barrier, we remove the
locking/unlocking of the mutex from the backends and instead move the
mutex acquisition into the freeze/thaw routines. Then update the rule on
acquiring glyphs to enforce that the cache is frozen and review the usage
of freeze/thaw by all the backends to ensure that the cache is frozen for
the lifetime of the glyph.
If the surface is in error, then we cannot assume anything about the
validity of its contents other than the error status (and reference
count). This is for the cases were the surface is replaced by a nil
surface, and in future where the error surface may be replaced by a tiny
error object.
Avoid masking fatal errors by enforcing any error to be returned via an
error surface, so that the NULL return only means UNSUPPORTED. A few
backends called their create_similar() directly, without correctly checking
for a potential NULL (for example, the directfb backend was a timebomb,
since it used NULL to indicate out-of-memory).
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.
Because we can independently set either the device scale or the device
offset, we need to be careful and recompute the inverse rather than simply
assuming that the original contents of the device transform is identity.
Fixes regression https://bugs.launchpad.net/inkscape/+bug/234546.
A little bit of sleep and reflection suggested that the use of
device_offset_[xy] was confusing and clone_offset_[xy] more consistent
with the function naming.
Previously the rule for clone_similar() was that the returned surface
had exactly the same size as the original, but only the contents within
the region of interest needed to be copied. This caused failures for very
large images in the xlib-backend (see test/large-source).
The obvious solution to allow cloning only the region of interest seemed
to be to simply set the device offset on the cloned surface. However, this
fails as a) nothing respects the device offset on the surface at that
layer in the compositing stack and b) possibly returning references to the
original source surface provides further confusion by mixing in another
source of device offset.
The second method was to add extra out parameters so that the
device offset could be returned separately and, for example, mixed into
the pattern matrix. Not as elegant, a couple of extra warts to the
interface, but it works - one less XFAIL...
We reverted the public API for setting lcd_filter font options
back in 1b42bc8033 , but we had left the implementation which
would examine fontconfig and Xft properties for the option, and
which would call into freetype for subpixel glyph rasterization.
However, I recently realized, (and the test suite had been trying
to tell me for a while), that this approach would cause a
regression for users who were previously using sub-pixel text,
but without sub-pixel rendering built directly into freetype.
That's not acceptable, so all the code is coming out for now.
Chris rightfully complained that having a boolean function argument is
new in cairo_show_text_glyphs, and indeed avoiding them has been one
of the API design criteria for cairo. Trying to come up with alternatives,
Owen suggested using a flag type which nicely solves the problem AND
future-proofs such a complex API.
Please welcome _flags_t APIs to cairo.h
We added cairo_has_show_text_glyphs() before. Since this is really a
surface property, should have the surface method too. Like we added
cairo_surface_show_page()...
cairo_surface_get_font_options() has the side effect of initialising the
font options on the surface, but fails to check that the surface is
valid first. Therefore if we are passed a read-only error object, we will
trigger a segmentation fault.
Most likely this is the bug behind:
http://bugs.freedesktop.org/show_bug.cgi?id=17096.
This is needed because analysis-surface takes any UNSUPPORTED returns
as a signal for using image fallbacks. So the fallback mechanism in
_cairo_surface_show_text_glyphs() is not enough. Reported by Adrian
Johnson.
New public API:
cairo_text_cluster_t
cairo_has_show_text_glyphs()
cairo_show_text_glyphs()
Add accompanying gstate and surface functions, and surface backend methods.
No backends implement them just yet.
This can be used by _cairo_pattern_acquire_surface_for_solid() to let
the backend create custom surfaces for solid fill instead of a 1x1
similar surface.
This was added in 41c6eebcd1, to avoid
allocating short-lived patterns. However, this was error prune as the
color information was duplicated in the pattern and could get out of
sync. Indeed, it was out of sync before this commit in the call from
cairo-clip.c.
By allocating the solid pattern on the stack we fix the original problem
without creating new ones.