Back to index

lightning-sunbird  0.9+nobinonly
Functions
cairo-clip.c File Reference
#include "cairoint.h"
#include "cairo-clip-private.h"

Go to the source code of this file.

Functions

static cairo_clip_path_t * _cairo_clip_path_reference (cairo_clip_path_t *clip_path)
static void _cairo_clip_path_destroy (cairo_clip_path_t *clip_path)
void _cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target)
void _cairo_clip_fini (cairo_clip_t *clip)
void _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
cairo_status_t _cairo_clip_reset (cairo_clip_t *clip)
cairo_status_t _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip, cairo_rectangle_t *rectangle)
cairo_status_t _cairo_clip_intersect_to_region (cairo_clip_t *clip, pixman_region16_t *region)
cairo_status_t _cairo_clip_combine_to_surface (cairo_clip_t *clip, cairo_operator_t operator, cairo_surface_t *dst, int dst_x, int dst_y, const cairo_rectangle_t *extents)
static cairo_status_t _cairo_clip_intersect_path (cairo_clip_t *clip, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, cairo_surface_t *target)
static cairo_status_t _cairo_clip_intersect_region (cairo_clip_t *clip, cairo_traps_t *traps, cairo_surface_t *target)
static cairo_status_t _cairo_clip_intersect_mask (cairo_clip_t *clip, cairo_traps_t *traps, cairo_antialias_t antialias, cairo_surface_t *target)
cairo_status_t _cairo_clip_clip (cairo_clip_t *clip, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, cairo_surface_t *target)

Function Documentation

cairo_status_t _cairo_clip_clip ( cairo_clip_t *  clip,
cairo_path_fixed_t *  path,
cairo_fill_rule_t  fill_rule,
double  tolerance,
cairo_antialias_t  antialias,
cairo_surface_t *  target 
)

Definition at line 410 of file cairo-clip.c.

{
    cairo_status_t status;
    cairo_traps_t traps;
    
    status = _cairo_clip_intersect_path (clip,
                                    path, fill_rule, tolerance,
                                    antialias, target);
    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
       return status;

    _cairo_traps_init (&traps);
    status = _cairo_path_fixed_fill_to_traps (path,
                                         fill_rule,
                                         tolerance,
                                         &traps);
    if (status)
       goto bail;

    status = _cairo_clip_intersect_region (clip, &traps, target);
    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
       goto bail;

    status = _cairo_clip_intersect_mask (clip, &traps, antialias, target);
       
 bail:
    _cairo_traps_fini (&traps);

    return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

cairo_status_t _cairo_clip_combine_to_surface ( cairo_clip_t *  clip,
cairo_operator_t  operator,
cairo_surface_t *  dst,
int  dst_x,
int  dst_y,
const cairo_rectangle_t extents 
)

Definition at line 187 of file cairo-clip.c.

{
    cairo_pattern_union_t pattern;
    cairo_status_t status;

    _cairo_pattern_init_for_surface (&pattern.surface, clip->surface);
    
    status = _cairo_surface_composite (operator,
                                   &pattern.base,
                                   NULL,
                                   dst,
                                   extents->x - clip->surface_rect.x,
                                   extents->y - clip->surface_rect.y, 
                                   0, 0,
                                   extents->x - dst_x,
                                   extents->y - dst_y,
                                   extents->width, extents->height);
    
    _cairo_pattern_fini (&pattern.base);

    return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void _cairo_clip_fini ( cairo_clip_t *  clip)

Definition at line 59 of file cairo-clip.c.

{
    if (clip->surface)
       cairo_surface_destroy (clip->surface);
    clip->surface = NULL;

    if (clip->path)
       _cairo_clip_path_destroy (clip->path);
    clip->path = NULL;

    if (clip->region)
       pixman_region_destroy (clip->region);
    clip->region = NULL;
    clip->serial = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void _cairo_clip_init ( cairo_clip_t *  clip,
cairo_surface_t *  target 
)

Definition at line 49 of file cairo-clip.c.

{
    clip->mode = _cairo_surface_get_clip_mode (target);
    clip->region = NULL;
    clip->surface = NULL;
    clip->serial = 0;
    clip->path = NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void _cairo_clip_init_copy ( cairo_clip_t *  clip,
cairo_clip_t *  other 
)

Definition at line 76 of file cairo-clip.c.

{
    if (other->region) {
       clip->region = pixman_region_create ();
       pixman_region_copy (clip->region, other->region);
    }

    cairo_surface_reference (other->surface);
    clip->surface = other->surface;
    _cairo_clip_path_reference (other->path);
    clip->path = other->path;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_status_t _cairo_clip_intersect_mask ( cairo_clip_t *  clip,
cairo_traps_t traps,
cairo_antialias_t  antialias,
cairo_surface_t *  target 
) [static]

Definition at line 315 of file cairo-clip.c.

{
    cairo_pattern_union_t pattern;
    cairo_box_t extents;
    cairo_rectangle_t surface_rect, target_rect;
    cairo_surface_t *surface;
    cairo_status_t status;

    /* Represent the clip as a mask surface.  We create a new surface
     * the size of the intersection of the old mask surface and the
     * extents of the new clip path. */

    _cairo_traps_extents (traps, &extents);
    _cairo_box_round_to_rectangle (&extents, &surface_rect);

    if (clip->surface != NULL)
       _cairo_rectangle_intersect (&surface_rect, &clip->surface_rect);

    /* Intersect with the target surface rectangle so we don't use
     * more memory and time than we need to. */

    status = _cairo_surface_get_extents (target, &target_rect);
    if (!status)
       _cairo_rectangle_intersect (&surface_rect, &target_rect);

    surface = _cairo_surface_create_similar_solid (target,
                                             CAIRO_CONTENT_ALPHA,
                                             surface_rect.width,
                                             surface_rect.height,
                                             CAIRO_COLOR_WHITE);
    if (surface->status)
       return CAIRO_STATUS_NO_MEMORY;

    /* Render the new clipping path into the new mask surface. */

    _cairo_traps_translate (traps, -surface_rect.x, -surface_rect.y);
    _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE);
    
    status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN,
                                            &pattern.base,
                                            surface,
                                            antialias,
                                            0, 0,
                                            0, 0,
                                            surface_rect.width,
                                            surface_rect.height,
                                            traps->traps,
                                            traps->num_traps);

    _cairo_pattern_fini (&pattern.base);

    if (status) {
       cairo_surface_destroy (surface);
       return status;
    }

    /* If there was a clip surface already, combine it with the new
     * mask surface using the IN operator, so we get the intersection
     * of the old and new clipping paths. */

    if (clip->surface != NULL) {
       _cairo_pattern_init_for_surface (&pattern.surface, clip->surface);

       status = _cairo_surface_composite (CAIRO_OPERATOR_IN,
                                      &pattern.base,
                                      NULL,
                                      surface,
                                      surface_rect.x - clip->surface_rect.x,
                                      surface_rect.y - clip->surface_rect.y,
                                      0, 0,
                                      0, 0,
                                      surface_rect.width,
                                      surface_rect.height);

       _cairo_pattern_fini (&pattern.base);

       if (status) {
           cairo_surface_destroy (surface);
           return status;
       }

       cairo_surface_destroy (clip->surface);
    }

    clip->surface = surface;
    clip->surface_rect = surface_rect;
    clip->serial = _cairo_surface_allocate_clip_serial (target);

    return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_status_t _cairo_clip_intersect_path ( cairo_clip_t *  clip,
cairo_path_fixed_t *  path,
cairo_fill_rule_t  fill_rule,
double  tolerance,
cairo_antialias_t  antialias,
cairo_surface_t *  target 
) [static]

Definition at line 216 of file cairo-clip.c.

{
    cairo_clip_path_t *clip_path;
    cairo_status_t status;

    if (clip->mode != CAIRO_CLIP_MODE_PATH)
       return CAIRO_INT_STATUS_UNSUPPORTED;

    clip_path = malloc (sizeof (cairo_clip_path_t));
    if (clip_path == NULL)
       return CAIRO_STATUS_NO_MEMORY;

    status = _cairo_path_fixed_init_copy (&clip_path->path, path);
    if (status)
       return status;

    clip_path->ref_count = 1;
    clip_path->fill_rule = fill_rule;
    clip_path->tolerance = tolerance;
    clip_path->antialias = antialias;
    clip_path->prev = clip->path;
    clip->path = clip_path;
    clip->serial = _cairo_surface_allocate_clip_serial (target);

    return CAIRO_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_status_t _cairo_clip_intersect_region ( cairo_clip_t *  clip,
cairo_traps_t traps,
cairo_surface_t *  target 
) [static]

Definition at line 275 of file cairo-clip.c.

{
    pixman_region16_t *region;
    cairo_status_t status;

    if (clip->mode != CAIRO_CLIP_MODE_REGION)
       return CAIRO_INT_STATUS_UNSUPPORTED;
    
    status = _cairo_traps_extract_region (traps, &region);
    if (status)
       return status;
       
    if (region == NULL)
       return CAIRO_INT_STATUS_UNSUPPORTED;

    status = CAIRO_STATUS_SUCCESS;
    if (clip->region == NULL) {
       clip->region = region;
    } else {
       pixman_region16_t *intersection = pixman_region_create();
    
       if (pixman_region_intersect (intersection, 
                                 clip->region, region)
           == PIXMAN_REGION_STATUS_SUCCESS) {
           pixman_region_destroy (clip->region);
           clip->region = intersection;
       } else {             
           status = CAIRO_STATUS_NO_MEMORY;
       }
       pixman_region_destroy (region);
    }

    clip->serial = _cairo_surface_allocate_clip_serial (target);

    return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

cairo_status_t _cairo_clip_intersect_to_rectangle ( cairo_clip_t *  clip,
cairo_rectangle_t rectangle 
)

Definition at line 111 of file cairo-clip.c.

{
    if (clip->path) {
       /* Intersect path extents here. */
    }

    if (clip->region) {
       pixman_region16_t *intersection;
       cairo_status_t status = CAIRO_STATUS_SUCCESS;
       pixman_region_status_t pixman_status;
       
       intersection = _cairo_region_create_from_rectangle (rectangle);
       if (intersection == NULL)
           return CAIRO_STATUS_NO_MEMORY;
       
       pixman_status = pixman_region_intersect (intersection,
                                     clip->region,
                                     intersection);
       if (pixman_status == PIXMAN_REGION_STATUS_SUCCESS)
           _cairo_region_extents_rectangle (intersection, rectangle);
       else
           status = CAIRO_STATUS_NO_MEMORY;

       pixman_region_destroy (intersection);

       if (status)
           return status;
    }

    if (clip->surface)
       _cairo_rectangle_intersect (rectangle, &clip->surface_rect);

    return CAIRO_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

cairo_status_t _cairo_clip_intersect_to_region ( cairo_clip_t *  clip,
pixman_region16_t *  region 
)

Definition at line 148 of file cairo-clip.c.

{
    if (clip->path) {
       /* Intersect clip path into region. */
    }

    if (clip->region)
       pixman_region_intersect (region, clip->region, region);

    if (clip->surface) {
       pixman_region16_t *clip_rect;
       pixman_region_status_t pixman_status;
       cairo_status_t status = CAIRO_STATUS_SUCCESS;
    
       clip_rect = _cairo_region_create_from_rectangle (&clip->surface_rect);
       if (clip_rect == NULL)
           return CAIRO_STATUS_NO_MEMORY;
       
       pixman_status = pixman_region_intersect (region,
                                           clip_rect,
                                           region);
       if (pixman_status != PIXMAN_REGION_STATUS_SUCCESS)
           status = CAIRO_STATUS_NO_MEMORY;

       pixman_region_destroy (clip_rect);

       if (status)
           return status;
    }

    return CAIRO_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void _cairo_clip_path_destroy ( cairo_clip_path_t *  clip_path) [static]

Definition at line 260 of file cairo-clip.c.

{
    if (clip_path == NULL)
       return;

    clip_path->ref_count--;
    if (clip_path->ref_count)
       return;

    _cairo_path_fixed_fini (&clip_path->path);
    _cairo_clip_path_destroy (clip_path->prev);
    free (clip_path);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_clip_path_t * _cairo_clip_path_reference ( cairo_clip_path_t *  clip_path) [static]

Definition at line 249 of file cairo-clip.c.

{
    if (clip_path == NULL)
       return NULL;

    clip_path->ref_count++;

    return clip_path;
}

Here is the caller graph for this function:

cairo_status_t _cairo_clip_reset ( cairo_clip_t *  clip)

Definition at line 90 of file cairo-clip.c.

{
    /* destroy any existing clip-region artifacts */
    if (clip->surface)
       cairo_surface_destroy (clip->surface);
    clip->surface = NULL;

    if (clip->region)
       pixman_region_destroy (clip->region);
    clip->region = NULL;

    if (clip->path)
       _cairo_clip_path_destroy (clip->path);
    clip->path = NULL;

    clip->serial = 0;
    
    return CAIRO_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function: