зеркало из https://github.com/mozilla/gecko-dev.git
b=562574 fixes for cairo_copy_clip_rectangle_list and empty cairo_clip_extents r=jrmuizel
--HG-- extra : rebase_source : 7559cb07311c0328d62a625c631a6ab822934b0d
This commit is contained in:
Родитель
72e4ce62b7
Коммит
44ee4169cd
|
@ -128,6 +128,12 @@ win32-transparent-surface.patch: add API so we can create a win32 surface for an
|
|||
|
||||
cairo_qt_glyphs.patch: Drop X surface from Qt surface, add support for new qt glyphs api
|
||||
|
||||
empty-clip-rectangles.patch: f2fa15680ec3ac95cb68d4957557f06561a7dc55
|
||||
|
||||
empty-clip-extents.patch: b79ea8a6cab8bd28aebecf6e1e8229d5ac017264
|
||||
|
||||
clip-rects-surface-extents.patch: 108b1c7825116ed3f93aa57384bbd3290cdc9181
|
||||
|
||||
==== pixman patches ====
|
||||
|
||||
pixman-android-cpu-detect.patch: Add CPU detection support for Android, where we can't reliably access /proc/self/auxv.
|
||||
|
|
|
@ -1311,9 +1311,14 @@ _cairo_clip_combine_with_surface (cairo_clip_t *clip,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static const cairo_rectangle_int_t _cairo_empty_rectangle_int = { 0, 0, 0, 0 };
|
||||
|
||||
const cairo_rectangle_int_t *
|
||||
_cairo_clip_get_extents (const cairo_clip_t *clip)
|
||||
{
|
||||
if (clip->all_clipped)
|
||||
return &_cairo_empty_rectangle_int;
|
||||
|
||||
if (clip->path == NULL)
|
||||
return NULL;
|
||||
|
||||
|
@ -1453,7 +1458,7 @@ _cairo_rectangle_list_create_in_error (cairo_status_t status)
|
|||
cairo_rectangle_list_t *
|
||||
_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
|
||||
{
|
||||
#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S));
|
||||
#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S))
|
||||
|
||||
cairo_rectangle_list_t *list;
|
||||
cairo_rectangle_t *rectangles = NULL;
|
||||
|
@ -1462,57 +1467,40 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
|
|||
int n_rects = 0;
|
||||
int i;
|
||||
|
||||
if (clip != NULL && clip->path != NULL) {
|
||||
status = _cairo_clip_get_region (clip, ®ion);
|
||||
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
|
||||
goto DONE;
|
||||
} else if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)
|
||||
} else if (unlikely (status)) {
|
||||
return ERROR_LIST (status);
|
||||
}
|
||||
if (clip->all_clipped)
|
||||
goto DONE;
|
||||
|
||||
if (!clip->path)
|
||||
return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
|
||||
|
||||
status = _cairo_clip_get_region (clip, ®ion);
|
||||
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
|
||||
goto DONE;
|
||||
} else if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
|
||||
} else if (unlikely (status)) {
|
||||
return ERROR_LIST (status);
|
||||
}
|
||||
|
||||
if (region != NULL) {
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
if (n_rects) {
|
||||
rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t));
|
||||
if (unlikely (rectangles == NULL)) {
|
||||
return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_rects; ++i) {
|
||||
cairo_rectangle_int_t clip_rect;
|
||||
|
||||
cairo_region_get_rectangle (region, i, &clip_rect);
|
||||
|
||||
if (! _cairo_clip_int_rect_to_user (gstate,
|
||||
&clip_rect,
|
||||
&rectangles[i]))
|
||||
{
|
||||
free (rectangles);
|
||||
return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cairo_rectangle_int_t extents;
|
||||
|
||||
if (! _cairo_surface_get_extents (_cairo_gstate_get_target (gstate),
|
||||
&extents))
|
||||
{
|
||||
/* unbounded surface -> unclipped */
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
n_rects = 1;
|
||||
rectangles = malloc(sizeof (cairo_rectangle_t));
|
||||
if (unlikely (rectangles == NULL))
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
if (n_rects) {
|
||||
rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t));
|
||||
if (unlikely (rectangles == NULL)) {
|
||||
return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
if (! _cairo_clip_int_rect_to_user (gstate, &extents, rectangles)) {
|
||||
free (rectangles);
|
||||
return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
|
||||
for (i = 0; i < n_rects; ++i) {
|
||||
cairo_rectangle_int_t clip_rect;
|
||||
|
||||
cairo_region_get_rectangle (region, i, &clip_rect);
|
||||
|
||||
if (! _cairo_clip_int_rect_to_user (gstate,
|
||||
&clip_rect,
|
||||
&rectangles[i]))
|
||||
{
|
||||
free (rectangles);
|
||||
return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1443,7 +1443,19 @@ _cairo_gstate_clip_extents (cairo_gstate_t *gstate,
|
|||
cairo_rectangle_list_t*
|
||||
_cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate)
|
||||
{
|
||||
return _cairo_clip_copy_rectangle_list (&gstate->clip, gstate);
|
||||
cairo_clip_t clip;
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_rectangle_list_t *list;
|
||||
|
||||
_cairo_clip_init_copy (&clip, &gstate->clip);
|
||||
|
||||
if (_cairo_surface_get_extents (gstate->target, &extents))
|
||||
_cairo_clip_rectangle (&clip, &extents);
|
||||
|
||||
list = _cairo_clip_copy_rectangle_list (&clip, gstate);
|
||||
_cairo_clip_fini (&clip);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
From 108b1c7825116ed3f93aa57384bbd3290cdc9181 Mon Sep 17 00:00:00 2001
|
||||
From: Karl Tomlinson <karlt+@karlt.net>
|
||||
Date: Sat, 17 Jul 2010 01:08:53 +0000
|
||||
Subject: clip: consider gstate target extents in _cairo_gstate_copy_clip_rectangle_list
|
||||
|
||||
Fixes https://bugs.freedesktop.org/show_bug.cgi?id=29125
|
||||
|
||||
To be consistent with _cairo_gstate_clip_extents, the context's clip
|
||||
should be intersected with the target surface extents (instead of only
|
||||
using them when there is no clip).
|
||||
|
||||
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
---
|
||||
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
|
||||
index 77d8214..d5a2fab 100644
|
||||
--- a/src/cairo-clip.c
|
||||
+++ b/src/cairo-clip.c
|
||||
@@ -1495,7 +1495,7 @@ _cairo_rectangle_list_create_in_error (cairo_status_t status)
|
||||
cairo_rectangle_list_t *
|
||||
_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
|
||||
{
|
||||
-#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S));
|
||||
+#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S))
|
||||
|
||||
cairo_rectangle_list_t *list;
|
||||
cairo_rectangle_t *rectangles = NULL;
|
||||
@@ -1507,57 +1507,37 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
|
||||
if (clip->all_clipped)
|
||||
goto DONE;
|
||||
|
||||
- if (clip->path != NULL) {
|
||||
- status = _cairo_clip_get_region (clip, ®ion);
|
||||
- if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
|
||||
- goto DONE;
|
||||
- } else if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
- return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)
|
||||
- } else if (unlikely (status)) {
|
||||
- return ERROR_LIST (status);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (region != NULL) {
|
||||
- n_rects = cairo_region_num_rectangles (region);
|
||||
- if (n_rects) {
|
||||
- rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t));
|
||||
- if (unlikely (rectangles == NULL)) {
|
||||
- return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
|
||||
- }
|
||||
+ if (!clip->path)
|
||||
+ return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
|
||||
|
||||
- for (i = 0; i < n_rects; ++i) {
|
||||
- cairo_rectangle_int_t clip_rect;
|
||||
-
|
||||
- cairo_region_get_rectangle (region, i, &clip_rect);
|
||||
+ status = _cairo_clip_get_region (clip, ®ion);
|
||||
+ if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
|
||||
+ goto DONE;
|
||||
+ } else if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
+ return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
|
||||
+ } else if (unlikely (status)) {
|
||||
+ return ERROR_LIST (status);
|
||||
+ }
|
||||
|
||||
- if (! _cairo_clip_int_rect_to_user (gstate,
|
||||
- &clip_rect,
|
||||
- &rectangles[i]))
|
||||
- {
|
||||
- free (rectangles);
|
||||
- return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
|
||||
- }
|
||||
- }
|
||||
+ n_rects = cairo_region_num_rectangles (region);
|
||||
+ if (n_rects) {
|
||||
+ rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t));
|
||||
+ if (unlikely (rectangles == NULL)) {
|
||||
+ return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
- } else {
|
||||
- cairo_rectangle_int_t extents;
|
||||
|
||||
- if (! _cairo_surface_get_extents (_cairo_gstate_get_target (gstate),
|
||||
- &extents))
|
||||
- {
|
||||
- /* unbounded surface -> unclipped */
|
||||
- goto DONE;
|
||||
- }
|
||||
+ for (i = 0; i < n_rects; ++i) {
|
||||
+ cairo_rectangle_int_t clip_rect;
|
||||
|
||||
- n_rects = 1;
|
||||
- rectangles = malloc(sizeof (cairo_rectangle_t));
|
||||
- if (unlikely (rectangles == NULL))
|
||||
- return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
|
||||
+ cairo_region_get_rectangle (region, i, &clip_rect);
|
||||
|
||||
- if (! _cairo_clip_int_rect_to_user (gstate, &extents, rectangles)) {
|
||||
- free (rectangles);
|
||||
- return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
|
||||
+ if (! _cairo_clip_int_rect_to_user (gstate,
|
||||
+ &clip_rect,
|
||||
+ &rectangles[i]))
|
||||
+ {
|
||||
+ free (rectangles);
|
||||
+ return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
|
||||
index baf6145..7caf624 100644
|
||||
--- a/src/cairo-gstate.c
|
||||
+++ b/src/cairo-gstate.c
|
||||
@@ -1555,7 +1555,19 @@ _cairo_gstate_clip_extents (cairo_gstate_t *gstate,
|
||||
cairo_rectangle_list_t*
|
||||
_cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate)
|
||||
{
|
||||
- return _cairo_clip_copy_rectangle_list (&gstate->clip, gstate);
|
||||
+ cairo_clip_t clip;
|
||||
+ cairo_rectangle_int_t extents;
|
||||
+ cairo_rectangle_list_t *list;
|
||||
+
|
||||
+ _cairo_clip_init_copy (&clip, &gstate->clip);
|
||||
+
|
||||
+ if (_cairo_surface_get_extents (gstate->target, &extents))
|
||||
+ _cairo_clip_rectangle (&clip, &extents);
|
||||
+
|
||||
+ list = _cairo_clip_copy_rectangle_list (&clip, gstate);
|
||||
+ _cairo_clip_fini (&clip);
|
||||
+
|
||||
+ return list;
|
||||
}
|
||||
|
||||
static void
|
||||
diff --git a/test/get-clip.c b/test/get-clip.c
|
||||
index f0477a1..f97db3f 100644
|
||||
--- a/test/get-clip.c
|
||||
+++ b/test/get-clip.c
|
||||
@@ -120,6 +120,22 @@ preamble (cairo_test_context_t *ctx)
|
||||
}
|
||||
cairo_rectangle_list_destroy (rectangle_list);
|
||||
|
||||
+ /* We should get the same results after applying a clip that contains the
|
||||
+ existing clip. */
|
||||
+ phase = "Clip beyond surface extents";
|
||||
+ cairo_save (cr);
|
||||
+ cairo_rectangle (cr, -10, -10, SIZE + 20 , SIZE + 20);
|
||||
+ cairo_clip (cr);
|
||||
+ rectangle_list = cairo_copy_clip_rectangle_list (cr);
|
||||
+ if (! check_count (ctx, phase, rectangle_list, 1) ||
|
||||
+ ! check_clip_extents (ctx, phase, cr, 0, 0, SIZE, SIZE) ||
|
||||
+ ! check_rectangles_contain (ctx, phase, rectangle_list, 0, 0, SIZE, SIZE))
|
||||
+ {
|
||||
+ goto FAIL;
|
||||
+ }
|
||||
+ cairo_rectangle_list_destroy (rectangle_list);
|
||||
+ cairo_restore (cr);
|
||||
+
|
||||
/* Test simple clip rect. */
|
||||
phase = "Simple clip rect";
|
||||
cairo_save (cr);
|
||||
--
|
||||
cgit v0.8.3-6-g21f6
|
|
@ -0,0 +1,59 @@
|
|||
From b79ea8a6cab8bd28aebecf6e1e8229d5ac017264 Mon Sep 17 00:00:00 2001
|
||||
From: Karl Tomlinson <karlt+@karlt.net>
|
||||
Date: Fri, 16 Jul 2010 23:46:25 +0000
|
||||
Subject: clip: consider all_clipped in _cairo_clip_get_extents
|
||||
|
||||
If the gstate clip in _cairo_gstate_int_clip_extents() has all_clipped
|
||||
set (and path NULL), then it returns the gstate target extents instead of
|
||||
an empty rectangle. If the target is infinite, then it says the clip is
|
||||
unbounded.
|
||||
|
||||
Fixes https://bugs.freedesktop.org/show_bug.cgi?id=29124
|
||||
Tested-by test/get-clip
|
||||
|
||||
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
---
|
||||
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
|
||||
index f6173c6..77d8214 100644
|
||||
--- a/src/cairo-clip.c
|
||||
+++ b/src/cairo-clip.c
|
||||
@@ -1264,9 +1264,14 @@ _cairo_clip_combine_with_surface (cairo_clip_t *clip,
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
+static const cairo_rectangle_int_t _cairo_empty_rectangle_int = { 0, 0, 0, 0 };
|
||||
+
|
||||
const cairo_rectangle_int_t *
|
||||
_cairo_clip_get_extents (const cairo_clip_t *clip)
|
||||
{
|
||||
+ if (clip->all_clipped)
|
||||
+ return &_cairo_empty_rectangle_int;
|
||||
+
|
||||
if (clip->path == NULL)
|
||||
return NULL;
|
||||
|
||||
diff --git a/test/get-clip.c b/test/get-clip.c
|
||||
index 9d6e796..f0477a1 100644
|
||||
--- a/test/get-clip.c
|
||||
+++ b/test/get-clip.c
|
||||
@@ -83,6 +83,8 @@ check_clip_extents (const cairo_test_context_t *ctx,
|
||||
cairo_clip_extents (cr, &ext_x1, &ext_y1, &ext_x2, &ext_y2);
|
||||
if (ext_x1 == x && ext_y1 == y && ext_x2 == x + width && ext_y2 == y + height)
|
||||
return 1;
|
||||
+ if (width == 0.0 && height == 0.0 && ext_x1 == ext_x2 && ext_y1 == ext_y2)
|
||||
+ return 1;
|
||||
cairo_test_log (ctx, "Error: %s; clip extents %f,%f,%f,%f should be %f,%f,%f,%f\n",
|
||||
message, ext_x1, ext_y1, ext_x2 - ext_x1, ext_y2 - ext_y1,
|
||||
x, y, width, height);
|
||||
@@ -138,7 +140,8 @@ preamble (cairo_test_context_t *ctx)
|
||||
cairo_save (cr);
|
||||
cairo_clip (cr);
|
||||
rectangle_list = cairo_copy_clip_rectangle_list (cr);
|
||||
- if (! check_count (ctx, phase, rectangle_list, 0))
|
||||
+ if (! check_count (ctx, phase, rectangle_list, 0) ||
|
||||
+ ! check_clip_extents (ctx, phase, cr, 0, 0, 0, 0))
|
||||
{
|
||||
goto FAIL;
|
||||
}
|
||||
--
|
||||
cgit v0.8.3-6-g21f6
|
|
@ -0,0 +1,28 @@
|
|||
From f2fa15680ec3ac95cb68d4957557f06561a7dc55 Mon Sep 17 00:00:00 2001
|
||||
From: Karl Tomlinson <karlt+@karlt.net>
|
||||
Date: Fri, 16 Jul 2010 22:39:50 +0000
|
||||
Subject: clip: return empty clip from _cairo_clip_copy_rectangle_list when all_clipped
|
||||
|
||||
Fixes https://bugs.freedesktop.org/show_bug.cgi?id=29122
|
||||
Tested by test/get-clip
|
||||
|
||||
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
---
|
||||
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
|
||||
index 12dc04d..f6173c6 100644
|
||||
--- a/src/cairo-clip.c
|
||||
+++ b/src/cairo-clip.c
|
||||
@@ -1499,7 +1499,10 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
|
||||
int n_rects = 0;
|
||||
int i;
|
||||
|
||||
- if (clip != NULL && clip->path != NULL) {
|
||||
+ if (clip->all_clipped)
|
||||
+ goto DONE;
|
||||
+
|
||||
+ if (clip->path != NULL) {
|
||||
status = _cairo_clip_get_region (clip, ®ion);
|
||||
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
|
||||
goto DONE;
|
||||
--
|
||||
cgit v0.8.3-6-g21f6
|
Загрузка…
Ссылка в новой задаче