[cairo-commit] 3 commits - src/cairo.c src/cairo-gstate.c
src/cairoint.h src/cairo-pattern.c
Behdad Esfahbod
behdad at kemper.freedesktop.org
Wed Mar 21 09:34:41 PDT 2007
src/cairo-gstate.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++----
src/cairo-pattern.c | 19 +++++++++++++----
src/cairo.c | 32 +++++++++--------------------
src/cairoint.h | 8 +++----
4 files changed, 82 insertions(+), 34 deletions(-)
New commits:
diff-tree bd275c19782700f2cfc6905f348e4d4b3f15d311 (from e76d3cfa4f06ba813528a018fa77ba4d210a44e3)
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Mar 21 12:34:37 2007 -0400
[cairo-pattern] Make sure cached solid patterns are not put in error status
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index beb95e8..920542c 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -270,6 +270,19 @@ static struct {
int size;
} solid_pattern_cache;
+static cairo_pattern_t *
+_cairo_pattern_create_solid_not_cached (const cairo_color_t *color)
+{
+ void *pattern;
+
+ /* Not cached, need to create a new pattern. */
+ pattern = malloc (sizeof (cairo_solid_pattern_t));
+ if (pattern != NULL)
+ _cairo_pattern_init_solid (pattern, color);
+
+ return pattern;
+}
+
cairo_pattern_t *
_cairo_pattern_create_solid (const cairo_color_t *color)
{
@@ -290,12 +303,10 @@ _cairo_pattern_create_solid (const cairo
goto DONE;
/* Not cached, need to create a new pattern. */
- pattern = malloc (sizeof (cairo_solid_pattern_t));
+ pattern = _cairo_pattern_create_solid_not_cached (color);
if (pattern == NULL)
return (cairo_pattern_t *) &cairo_pattern_nil.base;
- _cairo_pattern_init_solid (pattern, color);
-
/* And insert it into the cache. */
if (solid_pattern_cache.size < MAX_PATTERN_CACHE_SIZE) {
solid_pattern_cache.size ++;
@@ -337,7 +348,7 @@ _cairo_pattern_create_in_error (cairo_st
{
cairo_pattern_t *pattern;
- pattern = _cairo_pattern_create_solid (_cairo_stock_color (CAIRO_STOCK_BLACK));
+ pattern = _cairo_pattern_create_solid_not_cached (_cairo_stock_color (CAIRO_STOCK_BLACK));
if (cairo_pattern_status (pattern))
return pattern;
diff-tree e76d3cfa4f06ba813528a018fa77ba4d210a44e3 (from 1469ea22ba659ba7afa6892e9b6b2a3f26d0dddb)
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Mar 21 12:33:31 2007 -0400
[cairo-gstate] Make sure gstate->next is initialized
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index cc4f893..d639cfd 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -64,6 +64,8 @@ cairo_status_t
_cairo_gstate_init (cairo_gstate_t *gstate,
cairo_surface_t *target)
{
+ gstate->next = NULL;
+
gstate->op = CAIRO_GSTATE_OPERATOR_DEFAULT;
gstate->tolerance = CAIRO_GSTATE_TOLERANCE_DEFAULT;
@@ -95,8 +97,6 @@ _cairo_gstate_init (cairo_gstate_t *gst
if (gstate->source->status)
return CAIRO_STATUS_NO_MEMORY;
- gstate->next = NULL;
-
return CAIRO_STATUS_SUCCESS;
}
diff-tree 1469ea22ba659ba7afa6892e9b6b2a3f26d0dddb (from 5f83a1b542a1932a59299a45f36dff22268dca14)
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Mar 21 11:22:33 2007 -0400
[cairo-gstate] Move save/restore logic into gstate instead of cairo_t
by adding _cairo_gstate_save/restore(). This is in preparation for
adding copy-on-write behavior to gstate.
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index b75a90b..cc4f893 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -175,7 +175,7 @@ _cairo_gstate_fini (cairo_gstate_t *gsta
gstate->source = NULL;
}
-void
+static void
_cairo_gstate_destroy (cairo_gstate_t *gstate)
{
if (gstate == NULL)
@@ -197,7 +197,7 @@ _cairo_gstate_destroy (cairo_gstate_t *g
* Return value: a new cairo_gstate_t or NULL if there is insufficient
* memory.
**/
-cairo_gstate_t*
+static cairo_gstate_t*
_cairo_gstate_clone (cairo_gstate_t *other)
{
cairo_status_t status;
@@ -218,6 +218,55 @@ _cairo_gstate_clone (cairo_gstate_t *oth
return gstate;
}
+/**
+ * _cairo_gstate_save:
+ * @gstate: input/output gstate pointer
+ *
+ * Makes a copy of the current state of @gstate and saves it
+ * to @gstate->next, then put the address of the newly allcated
+ * copy into @gstate. _cairo_gstate_restore() reverses this.
+ **/
+cairo_status_t
+_cairo_gstate_save (cairo_gstate_t **gstate)
+{
+ cairo_gstate_t *top;
+
+ top = _cairo_gstate_clone (*gstate);
+
+ if (top == NULL) {
+ return CAIRO_STATUS_NO_MEMORY;
+ }
+
+ top->next = *gstate;
+ *gstate = top;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+/**
+ * _cairo_gstate_restore:
+ * @gstate: input/output gstate pointer
+ *
+ * Reverses the effects of one _cairo_gstate_save() call.
+ **/
+cairo_status_t
+_cairo_gstate_restore (cairo_gstate_t **gstate)
+{
+ cairo_gstate_t *top;
+
+ top = *gstate;
+
+ if (top->next == NULL) {
+ return CAIRO_STATUS_INVALID_RESTORE;
+ }
+
+ *gstate = top->next;
+
+ _cairo_gstate_destroy (top);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
static cairo_status_t
_cairo_gstate_recursive_apply_clip_path (cairo_gstate_t *gstate,
cairo_clip_path_t *cpath)
diff --git a/src/cairo.c b/src/cairo.c
index 21303de..2165045 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -260,10 +260,8 @@ cairo_destroy (cairo_t *cr)
return;
while (cr->gstate != cr->gstate_tail) {
- cairo_gstate_t *tmp = cr->gstate;
- cr->gstate = tmp->next;
-
- _cairo_gstate_destroy (tmp);
+ if (_cairo_gstate_restore (&cr->gstate))
+ break;
}
_cairo_gstate_fini (cr->gstate);
@@ -368,20 +366,15 @@ cairo_get_reference_count (cairo_t *cr)
void
cairo_save (cairo_t *cr)
{
- cairo_gstate_t *top;
+ cairo_status_t status;
if (cr->status)
return;
- top = _cairo_gstate_clone (cr->gstate);
-
- if (top == NULL) {
- _cairo_set_error (cr, CAIRO_STATUS_NO_MEMORY);
- return;
+ status = _cairo_gstate_save (&cr->gstate);
+ if (status) {
+ _cairo_set_error (cr, status);
}
-
- top->next = cr->gstate;
- cr->gstate = top;
}
slim_hidden_def(cairo_save);
@@ -396,20 +389,15 @@ slim_hidden_def(cairo_save);
void
cairo_restore (cairo_t *cr)
{
- cairo_gstate_t *top;
+ cairo_status_t status;
if (cr->status)
return;
- if (cr->gstate == cr->gstate_tail) {
- _cairo_set_error (cr, CAIRO_STATUS_INVALID_RESTORE);
- return;
+ status = _cairo_gstate_restore (&cr->gstate);
+ if (status) {
+ _cairo_set_error (cr, status);
}
-
- top = cr->gstate;
- cr->gstate = top->next;
-
- _cairo_gstate_destroy (top);
}
slim_hidden_def(cairo_restore);
diff --git a/src/cairoint.h b/src/cairoint.h
index 6e171e5..d54292e 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1244,11 +1244,11 @@ _cairo_gstate_init (cairo_gstate_t *gst
cairo_private void
_cairo_gstate_fini (cairo_gstate_t *gstate);
-cairo_private cairo_gstate_t *
-_cairo_gstate_clone (cairo_gstate_t *gstate);
+cairo_private cairo_status_t
+_cairo_gstate_save (cairo_gstate_t **gstate);
-cairo_private void
-_cairo_gstate_destroy (cairo_gstate_t *gstate);
+cairo_private cairo_status_t
+_cairo_gstate_restore (cairo_gstate_t **gstate);
cairo_private cairo_bool_t
_cairo_gstate_is_redirected (cairo_gstate_t *gstate);
More information about the cairo-commit
mailing list