The _cairo_region_get_boxes() interface was difficult to use and often
caused unnecessary memory allocation. With _cairo_region_get_box() it
is possible to access the boxes of a region without allocating a big
temporary array.
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.
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.
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.
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.
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.
The current version of DirectFB does not support any filters, so set
NEAREST on the source patterns so that we can fully optimize the pattern
inside core.
If we have non-integer translation on a source pattern then we need to use
STRECTHBLIT (the core takes care to optimize NEAREST patterns to integer
translations so that this will only be used when interpolation is
required).
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).
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...
If the internal buffer is wrapped in an image surface in acquire_dest_image,
that image surface needs the current clip region propagated to it. If not,
then the clip needs to be applied at release_dest_image time.
Originally reported here:
http://lists.cairographics.org/archives/cairo/2008-May/014032.html
and analyized later in the thread.
Change (font and surface) backend show_glyphs() API to take a
int *remaining_glyphs argument. It's used to communicate to the caller,
by way of setting remaining_glyphs and returning INT_STATUS_UNSUPPORTED,
that some of the glyphs were shown but not the others. The xlib backend
now correctly uses this to handle failure to upload a glyph to the server.
So the large-font test passes now.
An alternative approach could be to add some public value for glyphs
indices that are not shown. -1 perhaps (the xlib backend already uses
that value internally). Then instead of remaining_glyphs, a backend
could simply set glyph indices of glyphs shown to that -1 value.
Added a couple of (boolean) env. vars affecting the backend:
CAIRO_DIRECTFB_NO_ACCEL, disables acceleration
CAIRO_DIRECTFB_ARGB_FONT, enables using ARGB fonts instead of A8
- Improved performance in case of surface conversion: allocate a shadow buffer that can only grow
- Fixed support for small surfaces (less than 8x8)
- Optimize the blending function according to the surface format
- Added _directfb_categorize_operation(): selects the blitting function according to the transform matrix
- Avoid inverting the matrix when doing a simple StretchBlit()
- Use TextureTriangles() instead of StretchBlit() when scale factors are negative
- Added support for ARGB32 fonts (converted to A8 internally)
- Removed unused functions (flush() and mark_dirty_rectangle())
- Code cosmetics
gcc -ansi -pedantic gives a few syntax warnings, principally for use of
'//' comments and a comma at the end of enumerators. Apply these
corrections as they are trivial.
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.