[libgxps] Support opacity for Canvas elements
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgxps] Support opacity for Canvas elements
- Date: Tue, 1 Nov 2011 11:54:20 +0000 (UTC)
commit d5b60a831be69c0c08d2850937a6a866c6291338
Author: Jason Crain <jason aquaticape us>
Date: Mon Sep 12 23:28:57 2011 -0500
Support opacity for Canvas elements
Creates a new GXPSCanvas typedef to hold the opacity value.
https://bugzilla.gnome.org/show_bug.cgi?id=662653
libgxps/gxps-page.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 93 insertions(+), 2 deletions(-)
---
diff --git a/libgxps/gxps-page.c b/libgxps/gxps-page.c
index bd0d957..e49cad6 100644
--- a/libgxps/gxps-page.c
+++ b/libgxps/gxps-page.c
@@ -1642,6 +1642,74 @@ static GMarkupParser brush_parser = {
NULL
};
+typedef struct {
+ GXPSRenderContext *ctx;
+
+ gdouble opacity;
+} GXPSCanvas;
+
+static GXPSCanvas *
+gxps_canvas_new (GXPSRenderContext *ctx)
+{
+ GXPSCanvas *canvas;
+
+ canvas = g_slice_new0 (GXPSCanvas);
+ canvas->ctx = ctx;
+
+ /* Default values */
+ canvas->opacity = 1.0;
+
+ return canvas;
+}
+
+static void
+gxps_canvas_free (GXPSCanvas *canvas)
+{
+ if (G_UNLIKELY (!canvas))
+ return;
+
+ g_slice_free (GXPSCanvas, canvas);
+}
+
+static void
+canvas_start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **names,
+ const gchar **values,
+ gpointer user_data,
+ GError **error)
+{
+ GXPSCanvas *canvas = (GXPSCanvas *)user_data;
+
+ return render_start_element (context,
+ element_name,
+ names,
+ values,
+ canvas->ctx,
+ error);
+}
+
+static void
+canvas_end_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ GXPSCanvas *canvas = (GXPSCanvas *)user_data;
+
+ return render_end_element (context,
+ element_name,
+ canvas->ctx,
+ error);
+}
+
+static GMarkupParser canvas_parser = {
+ canvas_start_element,
+ canvas_end_element,
+ NULL,
+ NULL
+};
+
static void
path_geometry_start_element (GMarkupParseContext *context,
const gchar *element_name,
@@ -2715,11 +2783,14 @@ render_start_element (GMarkupParseContext *context,
g_markup_parse_context_push (context, &glyphs_parser, glyphs);
} else if (strcmp (element_name, "Canvas") == 0) {
+ GXPSCanvas *canvas;
gint i;
GXPS_DEBUG (g_message ("save"));
cairo_save (ctx->cr);
+ canvas = gxps_canvas_new (ctx);
+
for (i = 0; names[i] != NULL; i++) {
if (strcmp (names[i], "RenderTransform") == 0) {
cairo_matrix_t matrix;
@@ -2729,6 +2800,7 @@ render_start_element (GMarkupParseContext *context,
ctx->page->priv->source,
G_MARKUP_ERROR_INVALID_CONTENT,
"Canvas", "RenderTransform", values[i], error);
+ gxps_canvas_free (canvas);
return;
}
GXPS_DEBUG (g_message ("transform (%f, %f, %f, %f) [%f, %f]",
@@ -2737,14 +2809,24 @@ render_start_element (GMarkupParseContext *context,
matrix.x0, matrix.y0));
cairo_transform (ctx->cr, &matrix);
} else if (strcmp (names[i], "Opacity") == 0) {
- /* TODO */
+ canvas->opacity = g_ascii_strtod (values[i], NULL);
+ GXPS_DEBUG (g_message ("set_opacity (%f)", path->opacity));
} else if (strcmp (names[i], "Clip") == 0) {
- if (!path_data_parse (values[i], ctx->cr, error))
+ if (!path_data_parse (values[i], ctx->cr, error)) {
+ gxps_parse_error (context,
+ ctx->page->priv->source,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ "Canvas", "Clip", values[i], error);
+ gxps_canvas_free (canvas);
return;
+ }
GXPS_DEBUG (g_message ("clip"));
cairo_clip (ctx->cr);
}
}
+ if (canvas->opacity != 1.0)
+ cairo_push_group (canvas->ctx->cr);
+ g_markup_parse_context_push (context, &canvas_parser, canvas);
} else if (strcmp (element_name, "Canvas.RenderTransform") == 0) {
GXPSMatrix *matrix;
@@ -2933,8 +3015,17 @@ render_end_element (GMarkupParseContext *context,
GXPS_DEBUG (g_message ("restore"));
cairo_restore (ctx->cr);
} else if (strcmp (element_name, "Canvas") == 0) {
+ GXPSCanvas *canvas;
+
+ canvas = g_markup_parse_context_pop (context);
+
+ if (canvas->opacity != 1.0) {
+ cairo_pop_group_to_source (ctx->cr);
+ cairo_paint_with_alpha (ctx->cr, canvas->opacity);
+ }
cairo_restore (ctx->cr);
GXPS_DEBUG (g_message ("restore"));
+ gxps_canvas_free (canvas);
} else if (strcmp (element_name, "Canvas.RenderTransform") == 0) {
GXPSMatrix *matrix;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]