mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-27 16:20:11 +01:00
Bound mask fallback operation by transformed mask and source. This should speed up any applications calling cairo_mask with a bounded source or mask operand.
This commit is contained in:
parent
93cbc71a79
commit
83ff8ea194
4 changed files with 113 additions and 8 deletions
|
|
@ -1,3 +1,12 @@
|
|||
2005-10-28 Keith Packard <keithp@keithp.com>
|
||||
|
||||
* src/cairo-pattern.c: (_cairo_pattern_get_extents):
|
||||
* src/cairo-surface.c: (_fallback_mask):
|
||||
* src/cairoint.h:
|
||||
Bound mask fallback operation by transformed mask and
|
||||
source. This should speed up any applications calling
|
||||
cairo_mask with a bounded source or mask operand.
|
||||
|
||||
2005-10-28 Keith Packard <keithp@keithp.com>
|
||||
|
||||
* src/cairo-gstate.c: (_cairo_operator_bounded_by_mask),
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@
|
|||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: David Reveman <davidr@novell.com>
|
||||
* Authors: David Reveman <davidr@novell.com>
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
|
@ -1624,3 +1626,84 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
|
|||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_pattern_get_extents:
|
||||
*
|
||||
* Return the "target-space" extents of @pattern in @extents.
|
||||
*
|
||||
* For unbounded patterns, the @extents will be initialized with
|
||||
* "infinite" extents, (minimum and maximum fixed-point values).
|
||||
*
|
||||
* XXX: Currently, bounded gradient patterns will also return
|
||||
* "infinite" extents, though it would be possible to optimize these
|
||||
* with a little more work.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_pattern_get_extents (cairo_pattern_t *pattern,
|
||||
cairo_rectangle_t *extents)
|
||||
{
|
||||
if (pattern->extend == CAIRO_EXTEND_NONE &&
|
||||
pattern->type == CAIRO_PATTERN_SURFACE)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_t surface_extents;
|
||||
cairo_surface_pattern_t *surface_pattern =
|
||||
(cairo_surface_pattern_t *) pattern;
|
||||
cairo_surface_t *surface = surface_pattern->surface;
|
||||
cairo_matrix_t imatrix;
|
||||
double x, y;
|
||||
int left, right, top, bottom;
|
||||
int lx, rx, ty, by;
|
||||
int sx, sy;
|
||||
cairo_bool_t set = FALSE;
|
||||
|
||||
status = _cairo_surface_get_extents (surface, &surface_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
imatrix = pattern->matrix;
|
||||
cairo_matrix_invert (&imatrix);
|
||||
|
||||
for (sy = 0; sy <= 1; sy++) {
|
||||
for (sx = 0; sx <= 1; sx++) {
|
||||
x = surface_extents.x + sx * surface_extents.width;
|
||||
y = surface_extents.y + sy * surface_extents.height;
|
||||
cairo_matrix_transform_point (&imatrix, &x, &y);
|
||||
if (x < 0) x = 0;
|
||||
if (x > CAIRO_MAXSHORT) x = CAIRO_MAXSHORT;
|
||||
if (y < 0) y = 0;
|
||||
if (y > CAIRO_MAXSHORT) y = CAIRO_MAXSHORT;
|
||||
lx = floor (x); rx = ceil (x);
|
||||
ty = floor (y); by = ceil (y);
|
||||
if (!set) {
|
||||
left = lx;
|
||||
right = rx;
|
||||
top = ty;
|
||||
bottom = by;
|
||||
set = TRUE;
|
||||
} else {
|
||||
if (lx < left) left = lx;
|
||||
if (rx > right) right = rx;
|
||||
if (ty < top) top = ty;
|
||||
if (by > bottom) bottom = by;
|
||||
}
|
||||
}
|
||||
}
|
||||
extents->x = left; extents->width = right - left;
|
||||
extents->y = top; extents->height = bottom - top;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* XXX: We could optimize gradients with pattern->extend of NONE
|
||||
* here in some cases, (eg. radial gradients and 1 axis of
|
||||
* horizontal/vertical linear gradients).
|
||||
*/
|
||||
|
||||
extents->x = 0;
|
||||
extents->y = 0;
|
||||
extents->width = CAIRO_MAXSHORT;
|
||||
extents->height = CAIRO_MAXSHORT;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1236,18 +1236,27 @@ _fallback_mask (cairo_operator_t operator,
|
|||
cairo_surface_t *dst)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_t extents;
|
||||
cairo_rectangle_t extents, source_extents, mask_extents;
|
||||
|
||||
status = _cairo_surface_get_extents (dst, &extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/*
|
||||
* XXX should take mask extents into account, but
|
||||
* that involves checking the transform and
|
||||
* _cairo_operator_bounded (operator)... For now,
|
||||
* be lazy and just use the destination extents
|
||||
*/
|
||||
if (_cairo_operator_bounded_by_source (operator)) {
|
||||
status = _cairo_pattern_get_extents (source_pattern, &source_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
_cairo_rectangle_intersect (&extents, &source_extents);
|
||||
}
|
||||
|
||||
if (_cairo_operator_bounded_by_mask (operator)) {
|
||||
status = _cairo_pattern_get_extents (mask_pattern, &mask_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
_cairo_rectangle_intersect (&extents, &mask_extents);
|
||||
}
|
||||
|
||||
status = _cairo_clip_intersect_to_rectangle (dst->clip, &extents);
|
||||
if (status)
|
||||
|
|
|
|||
|
|
@ -1972,6 +1972,10 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
|
|||
cairo_surface_attributes_t *src_attributes,
|
||||
cairo_surface_attributes_t *mask_attributes);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_pattern_get_extents (cairo_pattern_t *pattern,
|
||||
cairo_rectangle_t *extents);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_set_antialias (cairo_gstate_t *gstate,
|
||||
cairo_antialias_t antialias);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue