[dia] [gradient] cairo: implement DiaRenderer::set_pattern()
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] [gradient] cairo: implement DiaRenderer::set_pattern()
- Date: Tue, 24 Dec 2013 14:28:39 +0000 (UTC)
commit d8f1a97613dcac5e4355290958e4611aa0a21e5d
Author: Hans Breuer <hans breuer org>
Date: Tue Dec 24 15:19:30 2013 +0100
[gradient] cairo: implement DiaRenderer::set_pattern()
Step 6 of 7 for gradient support in Dia: render gradients with cairo.
plug-ins/cairo/diacairo-renderer.c | 117 +++++++++++++++++++++++++++++++++--
plug-ins/cairo/diacairo.h | 3 +
2 files changed, 113 insertions(+), 7 deletions(-)
---
diff --git a/plug-ins/cairo/diacairo-renderer.c b/plug-ins/cairo/diacairo-renderer.c
index dd295f6..334a416 100644
--- a/plug-ins/cairo/diacairo-renderer.c
+++ b/plug-ins/cairo/diacairo-renderer.c
@@ -59,6 +59,7 @@
#include "filter.h"
#include "plug-ins.h"
#include "object.h" /* only for object->ops->draw */
+#include "pattern.h"
#include "diacairo.h"
@@ -204,6 +205,8 @@ is_capable_to (DiaRenderer *renderer, RenderCapability cap)
return TRUE;
else if (RENDER_AFFINE == cap)
return TRUE;
+ else if (RENDER_PATTERN == cap)
+ return TRUE;
if (cap != warned)
g_warning ("New capability not supported by cairo??");
warned = cap;
@@ -211,10 +214,109 @@ is_capable_to (DiaRenderer *renderer, RenderCapability cap)
}
/*!
+ * \brief Remember the given pattern to use for consecutive fill
+ * @param self explicit this pointer
+ * @param pattern linear or radial gradient
+ */
+static void
+set_pattern (DiaRenderer *self, DiaPattern *pattern)
+{
+ DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
+ DiaPattern *prev = renderer->pattern;
+ if (pattern)
+ renderer->pattern = g_object_ref (pattern);
+ else
+ renderer->pattern = pattern;
+ if (prev)
+ g_object_unref (prev);
+}
+
+static gboolean
+_add_color_stop (real ofs, const Color *col, gpointer user_data)
+{
+ cairo_pattern_t *pat = (cairo_pattern_t *)user_data;
+
+ cairo_pattern_add_color_stop_rgba (pat, ofs,
+ col->red, col->green, col->blue, col->alpha);
+}
+
+static cairo_pattern_t *
+_pattern_build_for_cairo (DiaPattern *pattern, const Rectangle *ext)
+{
+ cairo_pattern_t *pat;
+ gsize i;
+ real x, y;
+ DiaPatternType type;
+ guint flags;
+ Point p1, p2;
+ real r;
+
+ g_return_val_if_fail (pattern != NULL, NULL);
+
+ dia_pattern_get_settings (pattern, &type, &flags);
+ dia_pattern_get_points (pattern, &p1, &p2);
+ dia_pattern_get_radius (pattern, &r);
+
+ switch (type ) {
+ case DIA_LINEAR_GRADIENT :
+ pat = cairo_pattern_create_linear (p1.x, p1.y, p2.x, p2.y);
+ break;
+ case DIA_RADIAL_GRADIENT :
+ pat = cairo_pattern_create_radial (p2.x, p2.y, 0.0, p1.x, p1.y, r);
+ break;
+ default :
+ g_warning ("_pattern_build_for_cairo non such.");
+ return NULL;
+ }
+ /* this must only be optionally done */
+ if ((flags & DIA_PATTERN_USER_SPACE)==0) {
+ cairo_matrix_t matrix;
+ real w = ext->right - ext->left;
+ real h = ext->bottom - ext->top;
+ cairo_matrix_init (&matrix, w, 0.0, 0.0, h, ext->left, ext->top);
+ cairo_matrix_invert (&matrix);
+ cairo_pattern_set_matrix (pat, &matrix);
+ }
+ if (flags & DIA_PATTERN_EXTEND_PAD)
+ cairo_pattern_set_extend (pat, CAIRO_EXTEND_PAD);
+ else if (flags & DIA_PATTERN_EXTEND_REPEAT)
+ cairo_pattern_set_extend (pat, CAIRO_EXTEND_REPEAT);
+ else if (flags & DIA_PATTERN_EXTEND_REFLECT)
+ cairo_pattern_set_extend (pat, CAIRO_EXTEND_REFLECT);
+
+ dia_pattern_foreach (pattern, _add_color_stop, pat);
+
+ return pat;
+}
+
+/*!
+ * \brief Make use of the pattern if any
+ */
+static void
+_dia_cairo_fill (DiaCairoRenderer *renderer)
+{
+ if (!renderer->pattern) {
+ cairo_fill (renderer->cr);
+ } else {
+ /* maybe we should cache the cairo-pattern */
+ cairo_pattern_t *pat;
+ Rectangle fe;
+
+ /* Using the extents to scale the pattern is probably not correct */
+ cairo_fill_extents (renderer->cr, &fe.left, &fe.top, &fe.right, &fe.bottom);
+
+ pat = _pattern_build_for_cairo (renderer->pattern, &fe);
+ cairo_set_source (renderer->cr, pat);
+ cairo_fill (renderer->cr);
+ cairo_pattern_destroy (pat);
+ }
+}
+
+/*!
* \brief Render the given object optionally transformed by matrix
* @param self explicit this pointer
* @param object the _DiaObject to draw
- * @param matrix the trnsformation matrix to use or NULL
+ * @param matrix the transformation matrix to use or NULL
*/
static void
draw_object (DiaRenderer *self, DiaObject *object, DiaMatrix *matrix)
@@ -517,7 +619,7 @@ _polygon(DiaRenderer *self,
cairo_line_to (renderer->cr, points[0].x, points[0].y);
cairo_close_path (renderer->cr);
if (fill)
- cairo_fill (renderer->cr);
+ _dia_cairo_fill (renderer);
else
cairo_stroke (renderer->cr);
DIAG_STATE(renderer->cr)
@@ -558,7 +660,7 @@ _rect(DiaRenderer *self,
lr_corner->x - ul_corner->x, lr_corner->y - ul_corner->y);
if (fill)
- cairo_fill (renderer->cr);
+ _dia_cairo_fill (renderer);
else
cairo_stroke (renderer->cr);
DIAG_STATE(renderer->cr)
@@ -648,7 +750,7 @@ fill_arc(DiaRenderer *self,
a1, a2);
cairo_line_to (renderer->cr, center->x, center->y);
cairo_close_path (renderer->cr);
- cairo_fill (renderer->cr);
+ _dia_cairo_fill (renderer);
DIAG_STATE(renderer->cr)
}
@@ -683,7 +785,7 @@ _ellipse(DiaRenderer *self,
cairo_restore (renderer->cr);
if (fill)
- cairo_fill (renderer->cr);
+ _dia_cairo_fill (renderer);
else
cairo_stroke (renderer->cr);
DIAG_STATE(renderer->cr)
@@ -749,7 +851,7 @@ _bezier(DiaRenderer *self,
* and should be closed or if it was a Bezierline which happens to end in the start point.
*/
if (fill)
- cairo_fill (renderer->cr);
+ _dia_cairo_fill (renderer);
else
cairo_stroke (renderer->cr);
DIAG_STATE(renderer->cr)
@@ -998,7 +1100,7 @@ _rounded_rect (DiaRenderer *self,
cairo_arc (renderer->cr,
topleft->x + radius, topleft->y + radius, radius, G_PI, -G_PI_2);
if (fill)
- cairo_fill (renderer->cr);
+ _dia_cairo_fill (renderer);
else
cairo_stroke (renderer->cr);
DIAG_STATE(renderer->cr)
@@ -1153,4 +1255,5 @@ cairo_renderer_class_init (DiaCairoRendererClass *klass)
renderer_class->draw_rounded_polyline = draw_rounded_polyline;
/* other */
renderer_class->is_capable_to = is_capable_to;
+ renderer_class->set_pattern = set_pattern;
}
diff --git a/plug-ins/cairo/diacairo.h b/plug-ins/cairo/diacairo.h
index 94e1993..b4b809e 100644
--- a/plug-ins/cairo/diacairo.h
+++ b/plug-ins/cairo/diacairo.h
@@ -82,6 +82,9 @@ struct _DiaCairoRenderer
/** caching the font description from set_font */
PangoLayout *layout;
+
+ /*! If set use for fill */
+ DiaPattern *pattern;
};
struct _DiaCairoRendererClass
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]