diff --git a/configure.in b/configure.in index 12c3c9606e..02493ad6a3 100644 --- a/configure.in +++ b/configure.in @@ -932,9 +932,6 @@ goffice_reqs=" pango >= 1.6.0 pangoft2 >= 1.6.0 " -goffice_cairo_reqs=" - cairo >= 0.5.0 -" goffice_gtk_reqs=" gtk+-2.0 >= 2.4.14 libglade-2.0 >= 2.3.6 @@ -946,21 +943,9 @@ goffice_gnome_reqs=" libgnomeui-2.0 >= 2.0.0 libgsf-gnome-1 >= 1.12.2 " -dnl ********************* -dnl Should we use cairo ? -dnl ********************* +dnl Should we use cairo ? no goffice_with_cairo=false -AC_ARG_WITH(cairo, [ --{with,without}-cairo Use cairo for graph rendering]) -if test "x$with_cairo" = xyes; then - cairo_msg="Enabled" - PKG_CHECK_MODULES(CAIRO, [$goffice_cairo_reqs]) - AC_DEFINE(WITH_CAIRO, 1, [Define if goffice is build with cairo]) - goffice_reqs="$goffice_reqs $goffice_cairo_reqs" - goffice_with_cairo=true -else - cairo_msg="Disabled" - goffice_with_cairo=false -fi +cairo_msg="Disabled" dnl ******************* dnl Should we use gtk ? diff --git a/lib/goffice-0.0.4/goffice/graph/Makefile.am b/lib/goffice-0.0.4/goffice/graph/Makefile.am index 9f64e20176..7f18b63c57 100644 --- a/lib/goffice-0.0.4/goffice/graph/Makefile.am +++ b/lib/goffice-0.0.4/goffice/graph/Makefile.am @@ -75,11 +75,6 @@ libgoffice_graph_la_HEADERS = \ gog-renderer-gnome-print.h \ gog-renderer-svg.h -if WITH_CAIRO - libgoffice_graph_la_SOURCES += gog-renderer-cairo.c - libgoffice_graph_la_HEADERS += gog-renderer-cairo.h -endif - gladedir = $(goffice_datadir)/glade dist_glade_DATA = \ gog-guru.glade \ diff --git a/lib/goffice-0.0.4/goffice/graph/gog-renderer-cairo.c b/lib/goffice-0.0.4/goffice/graph/gog-renderer-cairo.c deleted file mode 100644 index 1ba32961e9..0000000000 --- a/lib/goffice-0.0.4/goffice/graph/gog-renderer-cairo.c +++ /dev/null @@ -1,753 +0,0 @@ -/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * gog-renderer-cairo.c : - * - * Copyright (C) 2005 Emmanuel Pacaud (emmanuel.pacaud@univ-poitiers.fr) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -/* TODO: - * - * - implement stretched image texture - * - fix alpha channel of source image for texture - * - fix font size - * - implement mutiline text - * - cache font properties - * - implement rendering of marker with cairo - * (that will fix grayish outline bug) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include - -#define DOUBLE_RGBA_R(x) (double)UINT_RGBA_R(x)/255.0 -#define DOUBLE_RGBA_G(x) (double)UINT_RGBA_G(x)/255.0 -#define DOUBLE_RGBA_B(x) (double)UINT_RGBA_B(x)/255.0 -#define DOUBLE_RGBA_A(x) (double)UINT_RGBA_A(x)/255.0 - -#define GO_COLOR_TO_CAIRO(x) DOUBLE_RGBA_R(x),DOUBLE_RGBA_G(x),DOUBLE_RGBA_B(x),DOUBLE_RGBA_A(x) - -struct _GogRendererCairo { - GogRenderer base; - - int w, h; - - cairo_t *cairo; - GdkPixbuf *pixbuf; - - cairo_surface_t *marker_surface; - GdkPixbuf *marker_pixbuf; -}; - -typedef GogRendererClass GogRendererCairoClass; - -static GObjectClass *parent_klass; - -static void -gog_renderer_cairo_finalize (GObject *obj) -{ - GogRendererCairo *crend = GOG_RENDERER_CAIRO (obj); - cairo_surface_t *surface; - - if (crend->cairo != NULL){ - surface = cairo_get_target (crend->cairo); - cairo_surface_destroy (surface); - cairo_destroy (crend->cairo); - crend->cairo = NULL; - } - if (crend->pixbuf != NULL) { - g_object_unref (crend->pixbuf); - crend->pixbuf = NULL; - } - if (crend->marker_surface != NULL) { - cairo_surface_destroy (crend->marker_surface); - g_object_unref (crend->marker_pixbuf); - crend->marker_surface = NULL; - crend->marker_pixbuf = NULL; - } - - (*parent_klass->finalize) (obj); -} - -static void -gog_renderer_cairo_clip_push (GogRenderer *rend, GogRendererClip *clip) -{ - GogRendererCairo *crend = GOG_RENDERER_CAIRO (rend); - double x, y; - - /* Rounding clipping area trigger cairo fast clip */ - x = floor (clip->area.x + 0.5); - y = floor (clip->area.y + 0.5); - - cairo_save (crend->cairo); - cairo_rectangle (crend->cairo, x, y, - floor (clip->area.x + clip->area.w + 0.5) - x, - floor (clip->area.y + clip->area.h + 0.5) - y); - cairo_clip (crend->cairo); -} - -static void -gog_renderer_cairo_clip_pop (GogRenderer *rend, GogRendererClip *clip) -{ - GogRendererCairo *crend = GOG_RENDERER_CAIRO (rend); - - cairo_restore (crend->cairo); -} - -static double -grc_line_size (GogRenderer const *rend, double width) -{ - if (go_sub_epsilon (width) <= 0.) /* cheesy version of hairline */ - return 1.; - - width *= rend->scale; - if (width <= 1.) - return width; - - return floor (width); -} - -static double -gog_renderer_cairo_line_size (GogRenderer const *rend, double width) -{ - double size = grc_line_size (rend, width); - - if (size < 1.0) - return ceil (size); - - return size; -} - -static void -gog_renderer_cairo_sharp_path (GogRenderer *rend, ArtVpath *path, double line_width) -{ - ArtVpath *iter = path; - - if (((int) (rint (line_width)) % 2 == 0) && line_width > 1.0) - while (iter->code != ART_END) { - iter->x = floor (iter->x + .5); - iter->y = floor (iter->y + .5); - iter++; - } - else - while (iter->code != ART_END) { - iter->x = floor (iter->x) + .5; - iter->y = floor (iter->y) + .5; - iter++; - } -} - -static void -grc_path (cairo_t *cr, ArtVpath *vpath, ArtBpath *bpath) -{ - if (vpath) - while (vpath->code != ART_END) { - switch (vpath->code) { - case ART_MOVETO_OPEN: - case ART_MOVETO: - cairo_move_to (cr, vpath->x, vpath->y); - break; - case ART_LINETO: - cairo_line_to (cr, vpath->x, vpath->y); - break; - default: - break; - } - vpath++; - } - else - while (bpath->code != ART_END) { - switch (bpath->code) { - case ART_MOVETO_OPEN: - case ART_MOVETO: - cairo_move_to (cr, bpath->x3, bpath->y3); - break; - case ART_LINETO: - cairo_line_to (cr, bpath->x3, bpath->y3); - break; - case ART_CURVETO: - cairo_curve_to (cr, - bpath->x1, bpath->y1, - bpath->x2, bpath->y2, - bpath->x3, bpath->y3); - break; - default: - break; - } - bpath++; - } -} - -/* Red and blue are inverted in a pixbuf compared to cairo */ -static void -grc_invert_pixbuf_RB (unsigned char *pixels, int width, int height, int rowstride) -{ - int i,j; - unsigned char a; - - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) { - a = pixels[0]; - pixels[0] = pixels[2]; - pixels[2] = a; - pixels += 4; - } - pixels += rowstride - width * 4; - } -} - -static void -grc_draw_path (GogRenderer *rend, ArtVpath const *vpath, ArtBpath const*bpath) -{ - GogRendererCairo *crend = GOG_RENDERER_CAIRO (rend); - GogStyle const *style = rend->cur_style; - cairo_t *cr = crend->cairo; - double width = grc_line_size (rend, style->line.width); - - g_return_if_fail (bpath != NULL || vpath != NULL); - - cairo_set_line_width (cr, width); - if (rend->line_dash != NULL) - cairo_set_dash (cr, - rend->line_dash->dash, - rend->line_dash->n_dash, - rend->line_dash->offset); - grc_path (cr, (ArtVpath *) vpath, (ArtBpath *) bpath); - cairo_set_source_rgba (cr, GO_COLOR_TO_CAIRO (style->line.color)); - cairo_stroke (cr); -} - -static void -gog_renderer_cairo_draw_path (GogRenderer *rend, ArtVpath const *path) -{ - grc_draw_path (rend, path, NULL); -} - -static void -gog_renderer_cairo_draw_bezier_path (GogRenderer *rend, ArtBpath const *path) -{ - grc_draw_path (rend, NULL, path); -} - -static void -grc_draw_polygon (GogRenderer *rend, ArtVpath const *vpath, - ArtBpath const *bpath, gboolean narrow) -{ - struct { unsigned x0i, y0i, x1i, y1i; } const grad_i[GO_GRADIENT_MAX] = { - {0, 0, 0, 1}, - {0, 1, 0, 0}, - {0, 0, 0, 2}, - {0, 2, 0, 1}, - {0, 0, 1, 0}, - {1, 0, 0, 0}, - {0, 0, 2, 0}, - {2, 0, 1, 0}, - {0, 0, 1, 1}, - {1, 1, 0, 0}, - {0, 0, 2, 2}, - {2, 2, 1, 1}, - {1, 0, 0, 1}, - {0, 1, 1, 0}, - {1, 0, 2, 2}, - {2, 2, 0, 1} - }; - - GogRendererCairo *crend = GOG_RENDERER_CAIRO (rend); - GogStyle const *style = rend->cur_style; - cairo_t *cr = crend->cairo; - cairo_pattern_t *cr_pattern = NULL; - cairo_surface_t *cr_surface = NULL; - GdkPixbuf *pixbuf = NULL; - GOColor color; - double width = grc_line_size (rend, style->line.width); - double x[3], y[3]; - int i, j, w, h, rowstride; - guint8 const *pattern; - unsigned char *pixels, *iter; - - g_return_if_fail (bpath != NULL || vpath != NULL); - - narrow = narrow || (style->outline.dash_type == GO_LINE_NONE); - - if (narrow && style->fill.type == GOG_FILL_STYLE_NONE) - return; - - cairo_set_line_width (cr, width); - grc_path (cr, (ArtVpath *) vpath, (ArtBpath *) bpath); - - switch (style->fill.type) { - case GOG_FILL_STYLE_PATTERN: - if (go_pattern_is_solid (&style->fill.pattern, &color)) - cairo_set_source_rgba (cr, GO_COLOR_TO_CAIRO (color)); - else { - GOColor fore = style->fill.pattern.fore; - GOColor back = style->fill.pattern.back; - int rowstride; - - pattern = go_pattern_get_pattern (&style->fill.pattern); - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 8, 8); - iter = gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - cr_surface = cairo_image_surface_create_for_data ( iter, - CAIRO_FORMAT_ARGB32, 8, 8, rowstride); - for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) { - color = pattern[i] & (1 << j) ? fore : back; - iter[0] = UINT_RGBA_B (color); - iter[1] = UINT_RGBA_G (color); - iter[2] = UINT_RGBA_R (color); - iter[3] = UINT_RGBA_A (color); - iter += 4; - } - iter += rowstride - 32; - } - cr_pattern = cairo_pattern_create_for_surface (cr_surface); - cairo_pattern_set_extend (cr_pattern, CAIRO_EXTEND_REPEAT); - cairo_set_source (cr, cr_pattern); - } - break; - - case GOG_FILL_STYLE_GRADIENT: - cairo_fill_extents (cr, &x[0], &y[0], &x[1], &y[1]); - x[2] = (x[1] - x[0]) / 2.0 + x[1]; - y[2] = (y[1] - y[0]) / 2.0 + y[1]; - cr_pattern = cairo_pattern_create_linear ( - x[grad_i[style->fill.gradient.dir].x0i], - y[grad_i[style->fill.gradient.dir].y0i], - x[grad_i[style->fill.gradient.dir].x1i], - y[grad_i[style->fill.gradient.dir].y1i]); - cairo_pattern_set_extend (cr_pattern, CAIRO_EXTEND_REFLECT); - cairo_pattern_add_color_stop_rgba (cr_pattern, 0, - GO_COLOR_TO_CAIRO (style->fill.pattern.back)); - cairo_pattern_add_color_stop_rgba (cr_pattern, 1, - GO_COLOR_TO_CAIRO (style->fill.pattern.fore)); - cairo_set_source (cr, cr_pattern); - break; - - case GOG_FILL_STYLE_IMAGE: - if (style->fill.image.image == NULL) { - cairo_set_source_rgba (cr, 1, 1, 1, 1); - break; - } - pixbuf = gdk_pixbuf_add_alpha (style->fill.image.image, FALSE, 0, 0, 0); - pixels = gdk_pixbuf_get_pixels (pixbuf); - h = gdk_pixbuf_get_height (pixbuf); - w = gdk_pixbuf_get_width (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - cr_surface = cairo_image_surface_create_for_data (pixels, - CAIRO_FORMAT_ARGB32, w, h, rowstride); - grc_invert_pixbuf_RB (pixels, w, h, rowstride); - cr_pattern = cairo_pattern_create_for_surface (cr_surface); - cairo_pattern_set_extend (cr_pattern, CAIRO_EXTEND_REPEAT); - cairo_set_source (cr, cr_pattern); - break; - - case GOG_FILL_STYLE_NONE: - break; /* impossible */ - } - - if (style->fill.type != GOG_FILL_STYLE_NONE) { - if (!narrow) - cairo_fill_preserve (cr); - else - cairo_fill (cr); - } - - if (!narrow) { - cairo_set_source_rgba (cr, GO_COLOR_TO_CAIRO (style->outline.color)); - if (rend->outline_dash != NULL) - cairo_set_dash (cr, - rend->outline_dash->dash, - rend->outline_dash->n_dash, - rend->outline_dash->offset); - cairo_stroke (cr); - } - - if (cr_pattern != NULL) - cairo_pattern_destroy (cr_pattern); - if (cr_surface != NULL) - cairo_surface_destroy (cr_surface); - if (pixbuf) - g_object_unref (pixbuf); -} - -static void -gog_renderer_cairo_draw_polygon (GogRenderer *rend, ArtVpath const *path, - gboolean narrow) -{ - grc_draw_polygon (rend, path, NULL, narrow); -} - -static void -gog_renderer_cairo_draw_bezier_polygon (GogRenderer *rend, ArtBpath const *path, - gboolean narrow) -{ - grc_draw_polygon (rend, NULL, path, narrow); -} - -static void -gog_renderer_cairo_draw_text (GogRenderer *rend, char const *text, - GogViewAllocation const *pos, GtkAnchorType anchor, - GogViewAllocation *result) -{ - GogRendererCairo *crend = (GogRendererCairo *) rend; - GogStyle const *style = rend->cur_style; - PangoFontDescription const *fd = style->font.font->desc; - PangoWeight weight; - cairo_t *cr = crend->cairo; - cairo_text_extents_t text_extents; - cairo_font_extents_t font_extents; - cairo_font_slant_t slant; - GOGeometryOBR obr; - GOGeometryAABR aabr; - char const *family; - double size; - - family = pango_font_description_get_family (fd); - size = pango_font_description_get_size (fd) / PANGO_SCALE; - weight = pango_font_description_get_weight (fd); - switch (pango_font_description_get_style (fd)) { - case (PANGO_STYLE_NORMAL): slant = CAIRO_FONT_SLANT_NORMAL; break; - case (PANGO_STYLE_OBLIQUE): slant = CAIRO_FONT_SLANT_OBLIQUE; break; - case (PANGO_STYLE_ITALIC): slant = CAIRO_FONT_SLANT_ITALIC; break; - } -/* g_message ("family: %s, size: %g", family, size);*/ - /* FIXME: calculate dpi */ - size *= 96.0 * rend->scale * rend->zoom / 72.0; - cairo_select_font_face (cr, family, slant, - weight > PANGO_WEIGHT_SEMIBOLD ? CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL); - cairo_set_font_size (cr, size); - cairo_text_extents (cr, text, &text_extents); - cairo_font_extents (cr, &font_extents); - - obr.w = text_extents.width; - obr.h = font_extents.ascent + font_extents.descent; - obr.alpha = rend->cur_style->text_layout.angle * M_PI / 180.0; - obr.x = pos->x; - obr.y = pos->y; - go_geometry_OBR_to_AABR (&obr, &aabr); - - switch (anchor) { - case GTK_ANCHOR_NW: case GTK_ANCHOR_W: case GTK_ANCHOR_SW: - obr.x += aabr.w / 2.0; - break; - case GTK_ANCHOR_NE : case GTK_ANCHOR_SE : case GTK_ANCHOR_E : - obr.x -= aabr.w / 2.0; - break; - default : break; - } - if (obr.x <= 0) - obr.x = 0; - - switch (anchor) { - case GTK_ANCHOR_NW: case GTK_ANCHOR_N: case GTK_ANCHOR_NE: - obr.y += aabr.h / 2.0; - break; - case GTK_ANCHOR_SE : case GTK_ANCHOR_S : case GTK_ANCHOR_SW : - obr.y -= aabr.h / 2.0; - break; - default : break; - } - if (obr.y <= 0) - obr.y = 0; - - cairo_save (cr); - cairo_set_source_rgba (cr, GO_COLOR_TO_CAIRO (style->font.color)); - cairo_move_to (cr, obr.x, obr.y); - cairo_rotate (cr, -obr.alpha); - cairo_rel_move_to (cr, - obr.w / 2.0, + obr.h / 2.0 - font_extents.descent); - cairo_show_text (cr, text); - cairo_restore (cr); - - if (result != NULL) { - result->x = aabr.x; - result->y = aabr.y; - result->w = aabr.w; - result->h = aabr.h; - } -} - -static void -gog_renderer_cairo_get_text_OBR (GogRenderer *rend, - char const *text, GOGeometryOBR *obr) -{ - GogRendererCairo *crend = (GogRendererCairo *) rend; - GogStyle const *style = rend->cur_style; - PangoFontDescription const *fd = style->font.font->desc; - PangoWeight weight; - cairo_t *cr = crend->cairo; - cairo_text_extents_t text_extents; - cairo_font_extents_t font_extents; - cairo_font_slant_t slant; - char const *family; - double size; - - family = pango_font_description_get_family (fd); - /* FIXME: calculate dpi */ - size = pango_font_description_get_size (fd) / PANGO_SCALE / 72.0 * 96.0 * rend->scale * rend->zoom; - weight = pango_font_description_get_weight (fd); - switch (pango_font_description_get_style (fd)) { - case (PANGO_STYLE_NORMAL): slant = CAIRO_FONT_SLANT_NORMAL; break; - case (PANGO_STYLE_OBLIQUE): slant = CAIRO_FONT_SLANT_OBLIQUE; break; - case (PANGO_STYLE_ITALIC): slant = CAIRO_FONT_SLANT_ITALIC; break; - } - cairo_select_font_face (cr, family, slant, - weight > PANGO_WEIGHT_SEMIBOLD ? CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL); - cairo_set_font_size (cr, size); - cairo_text_extents (cr, text, &text_extents); - cairo_font_extents (cr, &font_extents); - - obr->w = text_extents.width; - obr->h = font_extents.ascent + font_extents.descent; -} - -static cairo_surface_t * -grc_get_marker_surface (GogRenderer *rend) -{ - GogRendererCairo *crend = GOG_RENDERER_CAIRO (rend); - GogStyle const *style = rend->cur_style; - GdkPixbuf *pixbuf, *marker_pixbuf; - cairo_surface_t *surface; - unsigned char *pixels; - int height, width, rowstride; - - if (crend->marker_surface != NULL) - return crend->marker_surface; - - marker_pixbuf = go_marker_get_pixbuf (style->marker.mark, rend->scale); - if (marker_pixbuf == NULL) - return NULL; - - pixbuf = gdk_pixbuf_copy (go_marker_get_pixbuf (style->marker.mark, rend->scale)); - pixels = gdk_pixbuf_get_pixels (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - width = gdk_pixbuf_get_width (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - surface = cairo_image_surface_create_for_data (pixels, - CAIRO_FORMAT_ARGB32, width, height, rowstride); - grc_invert_pixbuf_RB (pixels, width, height, rowstride); - - crend->marker_pixbuf = pixbuf; - crend->marker_surface = surface; - - return surface; -} - -static void -gog_renderer_cairo_draw_marker (GogRenderer *rend, double x, double y) -{ - GogRendererCairo *crend = GOG_RENDERER_CAIRO (rend); - cairo_surface_t *surface; - double width, height; - - surface = grc_get_marker_surface (rend); - if (surface == NULL) - return; - width = cairo_image_surface_get_width (surface); - height = cairo_image_surface_get_height (surface); - cairo_set_source_surface (crend->cairo, surface, - floor (floor (x + .5) - width / 2.0), - floor (floor (y + .5) - height / 2.0)); - cairo_paint (crend->cairo); -} - -static void -gog_renderer_cairo_push_style (GogRenderer *rend, GogStyle const *style) -{ -} - -static void -gog_renderer_cairo_pop_style (GogRenderer *rend) -{ - GogRendererCairo *crend = GOG_RENDERER_CAIRO (rend); - - if (crend->marker_surface != NULL) { - cairo_surface_destroy (crend->marker_surface); - g_object_unref (crend->marker_pixbuf); - crend->marker_surface = NULL; - crend->marker_pixbuf = NULL; - } -} - -static void -gog_renderer_cairo_class_init (GogRendererClass *rend_klass) -{ - GObjectClass *gobject_klass = (GObjectClass *) rend_klass; - - parent_klass = g_type_class_peek_parent (rend_klass); - gobject_klass->finalize = gog_renderer_cairo_finalize; - rend_klass->push_style = gog_renderer_cairo_push_style; - rend_klass->pop_style = gog_renderer_cairo_pop_style; - rend_klass->clip_push = gog_renderer_cairo_clip_push; - rend_klass->clip_pop = gog_renderer_cairo_clip_pop; - rend_klass->sharp_path = gog_renderer_cairo_sharp_path; - rend_klass->draw_path = gog_renderer_cairo_draw_path; - rend_klass->draw_polygon = gog_renderer_cairo_draw_polygon; - rend_klass->draw_bezier_path = gog_renderer_cairo_draw_bezier_path; - rend_klass->draw_bezier_polygon = gog_renderer_cairo_draw_bezier_polygon; - rend_klass->draw_text = gog_renderer_cairo_draw_text; - rend_klass->draw_marker = gog_renderer_cairo_draw_marker; - rend_klass->get_text_OBR = gog_renderer_cairo_get_text_OBR; - rend_klass->line_size = gog_renderer_cairo_line_size; -} - -static void -gog_renderer_cairo_init (GogRendererCairo *crend) -{ - crend->cairo = NULL; - crend->pixbuf = NULL; - crend->marker_surface = NULL; - crend->marker_pixbuf = NULL; - crend->w = crend->h = 0; -} - -GSF_CLASS (GogRendererCairo, gog_renderer_cairo, - gog_renderer_cairo_class_init, gog_renderer_cairo_init, - GOG_RENDERER_TYPE) - -GdkPixbuf * -gog_renderer_cairo_get_pixbuf (GogRendererCairo *crend) -{ - g_return_val_if_fail (crend != NULL, NULL); - - return crend->pixbuf; -} - -static gboolean -grc_cairo_setup (GogRendererCairo *crend, int w, int h) -{ - cairo_surface_t *surface; - - if (w == crend->w && h == crend->h) - return (w != 0 && h!= 0); - - if (crend->cairo != NULL) { - surface = cairo_get_target (crend->cairo); - cairo_surface_destroy (surface); - cairo_destroy (crend->cairo); - crend->cairo = NULL; - } - if (crend->pixbuf != NULL) { - g_object_unref (crend->pixbuf); - crend->pixbuf = NULL; - } - crend->w = w; - crend->h = h; - - if (w ==0 || h == 0) - return FALSE; - - crend->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, crend->w, crend->h); - if (crend->pixbuf == NULL) { - g_warning ("GogRendererCairo::cairo_setup: chart is too large"); - return FALSE; - } - - surface = cairo_image_surface_create_for_data (gdk_pixbuf_get_pixels (crend->pixbuf), - CAIRO_FORMAT_ARGB32, - crend->w, crend->h, - gdk_pixbuf_get_rowstride (crend->pixbuf)); - crend->cairo = cairo_create (surface); - cairo_set_line_join (crend->cairo, CAIRO_LINE_JOIN_ROUND); - cairo_set_line_cap (crend->cairo, CAIRO_LINE_CAP_ROUND); - - return TRUE; -} - -/** - * gog_renderer_update : - * @prend : - * @w : - * @h : - * - * Returns TRUE if the size actually changed. - **/ -gboolean -gog_renderer_cairo_update (GogRendererCairo *crend, int w, int h, double zoom) -{ - GogGraph *graph; - GogView *view; - GogViewAllocation allocation; - gboolean redraw = TRUE; - gboolean size_changed; - - g_return_val_if_fail (crend != NULL, FALSE); - g_return_val_if_fail (crend->base.view != NULL, FALSE); - - size_changed = crend->w != w || crend->h != h; - - view = crend->base.view; - graph = GOG_GRAPH (view->model); - gog_graph_force_update (graph); - allocation.x = allocation.y = 0.; - allocation.w = w; - allocation.h = h; - if (!grc_cairo_setup (crend, w, h)) - return redraw; - - if (size_changed) { - crend->base.scale_x = w / graph->width; - crend->base.scale_y = h / graph->height; - crend->base.scale = MIN (crend->base.scale_x, crend->base.scale_y); - crend->base.zoom = zoom; - - /* make sure we dont try to queue an update while updating */ - crend->base.needs_update = TRUE; - - /* scale just changed need to recalculate sizes */ - gog_renderer_invalidate_size_requests (&crend->base); - gog_view_size_allocate (view, &allocation); - } else - if (w != view->allocation.w || h != view->allocation.h) - gog_view_size_allocate (view, &allocation); - else - redraw = gog_view_update_sizes (view); - - redraw |= crend->base.needs_update; - crend->base.needs_update = FALSE; - - if (redraw) { - cairo_rectangle (crend->cairo, 0, 0, w, h); - cairo_set_source_rgba (crend->cairo, 1, 1, 1, 0); - cairo_fill (crend->cairo); - - gog_view_render (view, NULL); - - grc_invert_pixbuf_RB (gdk_pixbuf_get_pixels (crend->pixbuf), w, h, - gdk_pixbuf_get_rowstride (crend->pixbuf)); - } - - return redraw; -}