gfx/cairo/clip-rects-surface-extents.patch

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 From 108b1c7825116ed3f93aa57384bbd3290cdc9181 Mon Sep 17 00:00:00 2001
     2 From: Karl Tomlinson <karlt+@karlt.net>
     3 Date: Sat, 17 Jul 2010 01:08:53 +0000
     4 Subject: clip: consider gstate target extents in _cairo_gstate_copy_clip_rectangle_list
     6 Fixes https://bugs.freedesktop.org/show_bug.cgi?id=29125
     8 To be consistent with _cairo_gstate_clip_extents, the context's clip
     9 should be intersected with the target surface extents (instead of only
    10 using them when there is no clip).
    12 Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
    13 ---
    14 diff --git a/src/cairo-clip.c b/src/cairo-clip.c
    15 index 77d8214..d5a2fab 100644
    16 --- a/src/cairo-clip.c
    17 +++ b/src/cairo-clip.c
    18 @@ -1495,7 +1495,7 @@ _cairo_rectangle_list_create_in_error (cairo_status_t status)
    19  cairo_rectangle_list_t *
    20  _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
    21  {
    22 -#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S));
    23 +#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S))
    25      cairo_rectangle_list_t *list;
    26      cairo_rectangle_t *rectangles = NULL;
    27 @@ -1507,57 +1507,37 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
    28      if (clip->all_clipped)
    29  	goto DONE;
    31 -    if (clip->path != NULL) {
    32 -	status = _cairo_clip_get_region (clip, &region);
    33 -	if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
    34 -	    goto DONE;
    35 -	} else if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
    36 -	    return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)
    37 -	} else if (unlikely (status)) {
    38 -	    return ERROR_LIST (status);
    39 -	}
    40 -    }
    41 -
    42 -    if (region != NULL) {
    43 -	n_rects = cairo_region_num_rectangles (region);
    44 -	if (n_rects) {
    45 -	    rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t));
    46 -	    if (unlikely (rectangles == NULL)) {
    47 -		return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
    48 -	    }
    49 +    if (!clip->path)
    50 +	return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
    52 -	    for (i = 0; i < n_rects; ++i) {
    53 -		cairo_rectangle_int_t clip_rect;
    54 -
    55 -		cairo_region_get_rectangle (region, i, &clip_rect);
    56 +    status = _cairo_clip_get_region (clip, &region);
    57 +    if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
    58 +	goto DONE;
    59 +    } else if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
    60 +	return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
    61 +    } else if (unlikely (status)) {
    62 +	return ERROR_LIST (status);
    63 +    }
    65 -		if (! _cairo_clip_int_rect_to_user (gstate,
    66 -						    &clip_rect,
    67 -						    &rectangles[i]))
    68 -		{
    69 -		    free (rectangles);
    70 -		    return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
    71 -		}
    72 -	    }
    73 +    n_rects = cairo_region_num_rectangles (region);
    74 +    if (n_rects) {
    75 +	rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t));
    76 +	if (unlikely (rectangles == NULL)) {
    77 +	    return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
    78  	}
    79 -    } else {
    80 -        cairo_rectangle_int_t extents;
    82 -	if (! _cairo_surface_get_extents (_cairo_gstate_get_target (gstate),
    83 -					  &extents))
    84 -	{
    85 -	    /* unbounded surface -> unclipped */
    86 -	    goto DONE;
    87 -	}
    88 +	for (i = 0; i < n_rects; ++i) {
    89 +	    cairo_rectangle_int_t clip_rect;
    91 -	n_rects = 1;
    92 -	rectangles = malloc(sizeof (cairo_rectangle_t));
    93 -	if (unlikely (rectangles == NULL))
    94 -	    return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
    95 +	    cairo_region_get_rectangle (region, i, &clip_rect);
    97 -	if (! _cairo_clip_int_rect_to_user (gstate, &extents, rectangles)) {
    98 -	    free (rectangles);
    99 -	    return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
   100 +	    if (! _cairo_clip_int_rect_to_user (gstate,
   101 +						&clip_rect,
   102 +						&rectangles[i]))
   103 +	    {
   104 +		free (rectangles);
   105 +		return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
   106 +	    }
   107  	}
   108      }
   110 diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
   111 index baf6145..7caf624 100644
   112 --- a/src/cairo-gstate.c
   113 +++ b/src/cairo-gstate.c
   114 @@ -1555,7 +1555,19 @@ _cairo_gstate_clip_extents (cairo_gstate_t *gstate,
   115  cairo_rectangle_list_t*
   116  _cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate)
   117  {
   118 -    return _cairo_clip_copy_rectangle_list (&gstate->clip, gstate);
   119 +    cairo_clip_t clip;
   120 +    cairo_rectangle_int_t extents;
   121 +    cairo_rectangle_list_t *list;
   122 +
   123 +    _cairo_clip_init_copy (&clip, &gstate->clip);
   124 +
   125 +    if (_cairo_surface_get_extents (gstate->target, &extents))
   126 +        _cairo_clip_rectangle (&clip, &extents);
   127 +
   128 +    list = _cairo_clip_copy_rectangle_list (&clip, gstate);
   129 +    _cairo_clip_fini (&clip);
   130 +
   131 +    return list;
   132  }
   134  static void
   135 diff --git a/test/get-clip.c b/test/get-clip.c
   136 index f0477a1..f97db3f 100644
   137 --- a/test/get-clip.c
   138 +++ b/test/get-clip.c
   139 @@ -120,6 +120,22 @@ preamble (cairo_test_context_t *ctx)
   140      }
   141      cairo_rectangle_list_destroy (rectangle_list);
   143 +    /* We should get the same results after applying a clip that contains the
   144 +       existing clip. */
   145 +    phase = "Clip beyond surface extents";
   146 +    cairo_save (cr);
   147 +    cairo_rectangle (cr, -10, -10, SIZE + 20 , SIZE + 20);
   148 +    cairo_clip (cr);
   149 +    rectangle_list = cairo_copy_clip_rectangle_list (cr);
   150 +    if (! check_count (ctx, phase, rectangle_list, 1) ||
   151 +        ! check_clip_extents (ctx, phase, cr, 0, 0, SIZE, SIZE) ||
   152 +        ! check_rectangles_contain (ctx, phase, rectangle_list, 0, 0, SIZE, SIZE))
   153 +    {
   154 +	goto FAIL;
   155 +    }
   156 +    cairo_rectangle_list_destroy (rectangle_list);
   157 +    cairo_restore (cr);
   158 +
   159      /* Test simple clip rect. */
   160      phase = "Simple clip rect";
   161      cairo_save (cr);
   162 --
   163 cgit v0.8.3-6-g21f6

mercurial