コード例 #1
0
ファイル: gtknumerableicon.c プロジェクト: BoozzyAmdJin/gtk-
static cairo_surface_t *
get_image_surface (GtkNumerableIcon *self)
{
  cairo_surface_t *retval = NULL, *image;

  if (self->priv->background_icon != NULL)
    {
      retval = draw_from_gicon (self);
      self->priv->border_size = 0;
    }
  else if (self->priv->background_image != NULL)
    {
      if (cairo_pattern_get_surface (self->priv->background_image, &image) == CAIRO_STATUS_SUCCESS)
        retval = draw_from_image (image);
      else
        retval = draw_from_gradient (self->priv->background_image);

      self->priv->border_size = 0;
    }

  if (retval == NULL)
    {
      retval = draw_default_surface (self);
      self->priv->border_size = DEFAULT_BORDER_SIZE;
    }

  return retval;
}
コード例 #2
0
static void
pattern_value_print (const GValue *value,
                     GString      *string)
{
  cairo_pattern_t *pattern;
  cairo_surface_t *surface;

  pattern = g_value_get_boxed (value);

  if (pattern == NULL)
    {
      g_string_append (string, "none");
      return;
    }

  switch (cairo_pattern_get_type (pattern))
    {
    case CAIRO_PATTERN_TYPE_SURFACE:
      if (cairo_pattern_get_surface (pattern, &surface) != CAIRO_STATUS_SUCCESS)
        {
          g_assert_not_reached ();
        }
      surface_print (surface, string);
      break;
    case CAIRO_PATTERN_TYPE_LINEAR:
    case CAIRO_PATTERN_TYPE_RADIAL:
      g_string_append (string, "none /* FIXME: add support for printing gradients */");
      break;
    case CAIRO_PATTERN_TYPE_SOLID:
    default:
      g_assert_not_reached ();
      break;
    }
}
コード例 #3
0
JNIEXPORT jlong JNICALL
Java_org_freedesktop_cairo_CairoPatternOverride_cairo_1pattern_1get_1surface
(
	JNIEnv* env,
	jclass cls,
	jlong _self
)
{
	cairo_status_t result;
	cairo_pattern_t* self;
	cairo_surface_t* surface;

	// convert parameter self
	self = (cairo_pattern_t*) _self;

	// call function
	result = cairo_pattern_get_surface(self, &surface);

	// cleanup parameter self

	/*
	 * Check return value
	 */
	if (result != CAIRO_STATUS_SUCCESS) {
		bindings_java_throwByName(env, "org/freedesktop/cairo/FatalError", "Not a SurfacePatten!");
		return 0L;
	}

	return (jlong) surface;
}
コード例 #4
0
static const cairo_pattern_t *
_cairo_tee_surface_match_source (cairo_tee_surface_t *surface,
                                 const cairo_pattern_t *source,
                                 int index,
                                 cairo_surface_wrapper_t *dest,
                                 cairo_surface_pattern_t *temp)
{
    cairo_surface_t *s;
    cairo_status_t status = cairo_pattern_get_surface ((cairo_pattern_t *)source, &s);
    if (status == CAIRO_STATUS_SUCCESS &&
        cairo_surface_get_type (s) == CAIRO_SURFACE_TYPE_TEE) {
        cairo_surface_t *tee_surf = cairo_tee_surface_index (s, index);
        if (tee_surf->status == CAIRO_STATUS_SUCCESS &&
            tee_surf->backend == dest->target->backend) {
            status = _cairo_pattern_init_copy (&temp->base, source);
            if (status == CAIRO_STATUS_SUCCESS) {
                cairo_surface_destroy (temp->surface);
                temp->surface = tee_surf;
                cairo_surface_reference (temp->surface);
                return &temp->base;
            }
        }
    }

    return source;
}
コード例 #5
0
ファイル: rb_cairo_pattern.c プロジェクト: jdlehman/rcairo
static VALUE
cr_surface_pattern_get_surface (VALUE self)
{
  cairo_surface_t *surface;

  rb_cairo_check_status (cairo_pattern_get_surface (_SELF (self), &surface));
  return CRSURFACE2RVAL (surface);
}
コード例 #6
0
static PyObject *
surface_pattern_get_surface (PycairoSurfacePattern *o)
{
    cairo_surface_t *surface;
    cairo_pattern_get_surface (o->pattern, &surface);
    return PycairoSurface_FromSurface (
			       cairo_surface_reference (surface), NULL);
}
コード例 #7
0
ファイル: settings.cpp プロジェクト: MaartenBent/wxWidgets
static void bg(GtkStyleContext* sc, wxColour& color, int state = GTK_STATE_FLAG_NORMAL)
{
    GdkRGBA* rgba;
    cairo_pattern_t* pattern = NULL;
    gtk_style_context_set_state(sc, GtkStateFlags(state));
    gtk_style_context_get(sc, GtkStateFlags(state),
        "background-color", &rgba, "background-image", &pattern, NULL);
    color = wxColour(*rgba);
    gdk_rgba_free(rgba);

    // "background-image" takes precedence over "background-color".
    // If there is an image, try to get a color out of it.
    if (pattern)
    {
        if (cairo_pattern_get_type(pattern) == CAIRO_PATTERN_TYPE_SURFACE)
        {
            cairo_surface_t* surf;
            cairo_pattern_get_surface(pattern, &surf);
            if (cairo_surface_get_type(surf) == CAIRO_SURFACE_TYPE_IMAGE)
            {
                const guchar* data = cairo_image_surface_get_data(surf);
                const int stride = cairo_image_surface_get_stride(surf);
                // choose a pixel in the middle vertically,
                // images often have a vertical gradient
                const int i = stride * (cairo_image_surface_get_height(surf) / 2);
                const unsigned* p = reinterpret_cast<const unsigned*>(data + i);
                const unsigned pixel = *p;
                guchar r, g, b, a = 0xff;
                switch (cairo_image_surface_get_format(surf))
                {
                case CAIRO_FORMAT_ARGB32:
                    a = guchar(pixel >> 24);
                    // fallthrough
                case CAIRO_FORMAT_RGB24:
                    r = guchar(pixel >> 16);
                    g = guchar(pixel >> 8);
                    b = guchar(pixel);
                    break;
                default:
                    a = 0;
                    break;
                }
                if (a != 0)
                {
                    if (a != 0xff)
                    {
                        // un-premultiply
                        r = guchar((r * 0xff) / a);
                        g = guchar((g * 0xff) / a);
                        b = guchar((b * 0xff) / a);
                    }
                    color.Set(r, g, b, a);
                }
            }
        }
        cairo_pattern_destroy(pattern);
    }
コード例 #8
0
ファイル: pattern.c プロジェクト: 3ofcoins/graphite_stack
static PyObject *
surface_pattern_get_surface (PycairoSurfacePattern *o) {
  if (o->base != NULL) {
    // surface_pattern was created using surface_pattern_new()
    return Py_BuildValue("O", o->base);
  } else {
    cairo_surface_t *surface;
    cairo_pattern_get_surface (o->pattern, &surface);
    return PycairoSurface_FromSurface(cairo_surface_reference (surface), NULL);
  }
}
コード例 #9
0
static void releasePattern(cairo_pattern_t *pat)
{
  if (!pat)
    return;

  if (cairo_pattern_get_type(pat) == CAIRO_PATTERN_TYPE_SURFACE)
  {
    cairo_surface_t *surface;
    cairo_pattern_get_surface(pat, &surface);
    cairo_surface_destroy(surface);
  }

  cairo_pattern_destroy(pat);
}
コード例 #10
0
ファイル: unico-draw.c プロジェクト: Distrotech/unico
static gboolean
draw_arrow_texture (GtkThemingEngine *engine,
                    cairo_t          *cr,
                    gdouble           angle,
                    gdouble           x,
                    gdouble           y,
                    gdouble           size)
{
  GtkStateFlags state;
  GValue value = { 0, };
  cairo_pattern_t *texture = NULL;
  cairo_surface_t *surface = NULL;
  gboolean retval = FALSE;

  state = gtk_theming_engine_get_state (engine);

  gtk_theming_engine_get_property (engine, "-unico-arrow-texture", state, &value);

  if (!G_VALUE_HOLDS_BOXED (&value))
    return FALSE;

  texture = g_value_dup_boxed (&value);
  g_value_unset (&value);

  if (texture != NULL)
    cairo_pattern_get_surface (texture, &surface);

  if (surface != NULL)
    {
      cairo_save (cr);

      cairo_translate (cr, (gint) (x + size / 2), (gint) (y + size / 2));
      cairo_rotate (cr, angle);

      cairo_set_source_surface (cr, surface, - cairo_image_surface_get_width (surface) / 2,
                                             - cairo_image_surface_get_height (surface) / 2);
      cairo_paint (cr);

      cairo_restore (cr);

      retval = TRUE;
    }

  if (texture != NULL)
    cairo_pattern_destroy (texture);

  return retval;
}
コード例 #11
0
static cairo_surface_t *
pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
{
  cairo_surface_t *dummy_surface;
  cairo_pattern_t *pattern;
  cairo_surface_t *surface;
  cairo_t *cr;

  dummy_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);

  cr = cairo_create (dummy_surface);
  gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
  pattern = cairo_get_source (cr);
  cairo_pattern_get_surface (pattern, &surface);
  cairo_surface_reference (surface);
  cairo_destroy (cr);
  cairo_surface_destroy (dummy_surface);

  return surface;
}
コード例 #12
0
ファイル: main.c プロジェクト: evfool/gtk3-widgets
gboolean on_chart_draw (GtkWidget *widget,
                        cairo_t   *crx,
                        gpointer  user_data) 
{ 
  gint i,j;
  gdouble v_step, h_step;
  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  cairo_t *cr = NULL;
  if (offscreen == NULL) {
    printf ("Creating offscreen surface\n");
    cairo_pattern_t * pattern = cairo_get_source (crx);
    printf ("Created pattern\n");
    cairo_surface_t *surface;
    cairo_pattern_get_surface (pattern, &surface);
    printf ("Getting surface from pattern\n");
    offscreen = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, allocation.width, allocation.height);
    printf ("Creating offscreen\n");
    cr = cairo_create (offscreen);
    printf ("Created offscreen context %d, %p\n", cairo_status (cr), cr);
  }
  v_step = (double)allocation.height / (MAX_VALUE - MIN_VALUE);
  h_step = (double)allocation.width / (LENGTH -1);
  cairo_set_line_width (cr, 1.0);
  gint64 between = g_get_real_time () - last_data_time;
  gdouble shift = (double)between/1000000 * h_step;
  //printf ("Partial redraw at %li, after %li, shiftin with %.2f out of %.2f\n", g_get_real_time(), between, shift, h_step);
  for (j=0;j<CORES;j++) {
    GList *current = data[j];
    cairo_set_source_rgb (cr, j==0 || j==4 ? 1.0 :0.0, j==1 || j==4 ? 1.0 :0.0, j==2 || j==4 ? 1.0 :0.0);
    cairo_move_to (cr, 0, allocation.height - v_step * GPOINTER_TO_INT(current->data));
    for (i = 1;i<LENGTH-1;i++) {
      cairo_line_to (cr, i*h_step-shift, allocation.height - v_step * GPOINTER_TO_INT ((current = g_list_next (current))->data));
    }
    cairo_line_to (cr, allocation.width, allocation.height - v_step *  GPOINTER_TO_INT ((current = g_list_next (current))->data));
    cairo_stroke (cr);
  }
  //cairo_set_source_surface (crx, offscreen, 0, 0);
  //cairo_paint (crx);
  return TRUE;
}
コード例 #13
0
ファイル: panel-background.c プロジェクト: yetist/mate-panel
char *
panel_background_make_string (PanelBackground *background,
			      int              x,
			      int              y)
{
	PanelBackgroundType  effective_type;
	char                *retval;

	retval = NULL;

	effective_type = panel_background_effective_type (background);

	if (effective_type == PANEL_BACK_IMAGE ||
	    (effective_type == PANEL_BACK_COLOR && background->has_alpha
	    && (!gdk_window_check_composited_wm(background->window)))) {
		cairo_surface_t *surface;

		if (!background->composited_pattern)
			return NULL;

		if (cairo_pattern_get_surface (background->composited_pattern, &surface) != CAIRO_STATUS_SUCCESS)
			return NULL;

		if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_XLIB)
			return NULL;

		retval = g_strdup_printf ("pixmap:%d,%d,%d", (guint32)cairo_xlib_surface_get_drawable (surface), x, y);
	} else if (effective_type == PANEL_BACK_COLOR) {
		gchar *rgba = gdk_rgba_to_string (&background->color);
		retval = g_strdup_printf (
				"color:%s",
				rgba);
		g_free (rgba);
	} else
		retval = g_strdup ("none:");

	return retval;
}
コード例 #14
0
static cairo_pattern_t *
create_pattern (ccss_cairo_image_t const	*image,
		int				 width,
		int				 height)
{
	cairo_t			*cr;
	cairo_surface_t		*surface;
	cairo_status_t		 status;
	cairo_pattern_t		*pattern;

	g_return_val_if_fail (image, NULL);

	/* Setup. */
	surface = NULL;
	status = cairo_pattern_get_surface (image->pattern, &surface);
	if (status != CAIRO_STATUS_SUCCESS) {
		g_warning ("%s", cairo_status_to_string (status));
		return NULL;
	}

	surface = cairo_surface_create_similar (surface,
						CAIRO_CONTENT_COLOR_ALPHA,
						width, height);
	cr = cairo_create (surface);

	/* Drawing. */
	cairo_pattern_set_extend (image->pattern, CAIRO_EXTEND_REPEAT);
	cairo_set_source (cr, image->pattern);
	cairo_paint (cr);

	/* Cleanup. */
	pattern = cairo_pattern_create_for_surface (surface);
	cairo_destroy (cr), cr = NULL;
	cairo_surface_destroy (surface), surface = NULL;

	return pattern;
}
コード例 #15
0
ファイル: st-private.c プロジェクト: meetparikh7/gnome-shell
/**
 * _st_create_shadow_cairo_pattern:
 * @shadow_spec: the definition of the shadow
 * @src_pattern: surface pattern for which we create the shadow
 *               (must be a surface pattern)
 *
 * This is a utility function for creating shadows used by
 * st-theme-node.c; it's in this file to share the gaussian
 * blur implementation. The usage of this function is quite different
 * depending on whether shadow_spec->inset is %TRUE or not. If
 * shadow_spec->inset is %TRUE, the caller should pass in a @src_pattern
 * which is the <i>inverse</i> of what they want shadowed, and must take
 * care of the spread and offset from the shadow spec themselves. If
 * shadow_spec->inset is %FALSE then the caller should pass in what they
 * want shadowed directly, and this function takes care of the spread and
 * the offset.
 */
cairo_pattern_t *
_st_create_shadow_cairo_pattern (StShadow        *shadow_spec,
                                 cairo_pattern_t *src_pattern)
{
    static cairo_user_data_key_t shadow_pattern_user_data;
    cairo_t *cr;
    cairo_surface_t *src_surface;
    cairo_surface_t *surface_in;
    cairo_surface_t *surface_out;
    cairo_pattern_t *dst_pattern;
    guchar          *pixels_in, *pixels_out;
    gint             width_in, height_in, rowstride_in;
    gint             width_out, height_out, rowstride_out;
    cairo_matrix_t   shadow_matrix;
    int i, j;

    g_return_val_if_fail (shadow_spec != NULL, NULL);
    g_return_val_if_fail (src_pattern != NULL, NULL);

    cairo_pattern_get_surface (src_pattern, &src_surface);

    width_in  = cairo_image_surface_get_width  (src_surface);
    height_in = cairo_image_surface_get_height (src_surface);

    /* We want the output to be a color agnostic alpha mask,
     * so we need to strip the color channels from the input
     */
    if (cairo_image_surface_get_format (src_surface) != CAIRO_FORMAT_A8)
    {
        surface_in = cairo_image_surface_create (CAIRO_FORMAT_A8,
                     width_in, height_in);

        cr = cairo_create (surface_in);
        cairo_set_source_surface (cr, src_surface, 0, 0);
        cairo_paint (cr);
        cairo_destroy (cr);
    }
    else
    {
        surface_in = cairo_surface_reference (src_surface);
    }

    pixels_in = cairo_image_surface_get_data (surface_in);
    rowstride_in = cairo_image_surface_get_stride (surface_in);

    pixels_out = blur_pixels (pixels_in, width_in, height_in, rowstride_in,
                              shadow_spec->blur,
                              &width_out, &height_out, &rowstride_out);
    cairo_surface_destroy (surface_in);

    /* Invert pixels for inset shadows */
    if (shadow_spec->inset)
    {
        for (j = 0; j < height_out; j++)
        {
            guchar *p = pixels_out + rowstride_out * j;
            for (i = 0; i < width_out; i++, p++)
                *p = ~*p;
        }
    }

    surface_out = cairo_image_surface_create_for_data (pixels_out,
                  CAIRO_FORMAT_A8,
                  width_out,
                  height_out,
                  rowstride_out);
    cairo_surface_set_user_data (surface_out, &shadow_pattern_user_data,
                                 pixels_out, (cairo_destroy_func_t) g_free);

    dst_pattern = cairo_pattern_create_for_surface (surface_out);
    cairo_surface_destroy (surface_out);

    cairo_pattern_get_matrix (src_pattern, &shadow_matrix);

    if (shadow_spec->inset)
    {
        /* For inset shadows, offsets and spread radius have already been
         * applied to the original pattern, so all left to do is shift the
         * blurred image left, so that it aligns centered under the
         * unblurred one
         */
        cairo_matrix_translate (&shadow_matrix,
                                (width_out - width_in) / 2.0,
                                (height_out - height_in) / 2.0);
        cairo_pattern_set_matrix (dst_pattern, &shadow_matrix);
        return dst_pattern;
    }

    /* Read all the code from the cairo_pattern_set_matrix call
     * at the end of this function to here from bottom to top,
     * because each new affine transformation is applied in
     * front of all the previous ones */

    /* 6. Invert the matrix back */
    cairo_matrix_invert (&shadow_matrix);

    /* 5. Adjust based on specified offsets */
    cairo_matrix_translate (&shadow_matrix,
                            shadow_spec->xoffset,
                            shadow_spec->yoffset);

    /* 4. Recenter the newly scaled image */
    cairo_matrix_translate (&shadow_matrix,
                            - shadow_spec->spread,
                            - shadow_spec->spread);

    /* 3. Scale up the blurred image to fill the spread */
    cairo_matrix_scale (&shadow_matrix,
                        (width_in + 2.0 * shadow_spec->spread) / width_in,
                        (height_in + 2.0 * shadow_spec->spread) / height_in);

    /* 2. Shift the blurred image left, so that it aligns centered
     * under the unblurred one */
    cairo_matrix_translate (&shadow_matrix,
                            - (width_out - width_in) / 2.0,
                            - (height_out - height_in) / 2.0);

    /* 1. Invert the matrix so we can work with it in pattern space
     */
    cairo_matrix_invert (&shadow_matrix);

    cairo_pattern_set_matrix (dst_pattern, &shadow_matrix);

    return dst_pattern;
}
コード例 #16
0
ファイル: IoCairoSurfacePattern.c プロジェクト: cdcarter/io
IoObject *IoCairoSurfacePattern_getSurface(IoCairoSurfacePattern *self, IoObject *locals, IoMessage *m)
{
	cairo_surface_t *surface = 0;
	cairo_pattern_get_surface(PATTERN(self), &surface);
	return IoCairoSurface_newWithRawSurface_(IOSTATE, m, cairo_surface_reference(surface));
}
コード例 #17
0
ファイル: pattern-getters.c プロジェクト: redheli/cairo-gral
static cairo_test_status_t
draw (cairo_t *cr, int width, int height)
{
    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
    cairo_status_t status;
    cairo_pattern_t *pat;

    /* Test pattern_get_rgba */
    {
        double r, g, b, a;
        pat = cairo_pattern_create_rgba (0.2, 0.3, 0.4, 0.5);

        status = cairo_pattern_get_rgba (pat, &r, &g, &b, &a);
        CHECK_SUCCESS;

        if (!CAIRO_TEST_DOUBLE_EQUALS(r,0.2) ||
                !CAIRO_TEST_DOUBLE_EQUALS(g,0.3) ||
                !CAIRO_TEST_DOUBLE_EQUALS(b,0.4) ||
                !CAIRO_TEST_DOUBLE_EQUALS(a,0.5)) {
            cairo_test_log (ctx, "Error: cairo_pattern_get_rgba returned unexepcted results: %g, %g, %g, %g\n",
                            r, g, b, a);
            return CAIRO_TEST_FAILURE;
        }

        cairo_pattern_destroy (pat);
    }

    /* Test pattern_get_surface */
    {
        cairo_surface_t *surf;

        pat = cairo_pattern_create_for_surface (cairo_get_target (cr));

        status = cairo_pattern_get_surface (pat, &surf);
        CHECK_SUCCESS;

        if (surf != cairo_get_target (cr)) {
            cairo_test_log (ctx, "Error: cairo_pattern_get_resurface returned wrong surface\n");
            return CAIRO_TEST_FAILURE;
        }

        cairo_pattern_destroy (pat);
    }

    /* Test get_color_stops & linear_get_points */
    {
        int i;
        double x0, y0, x1, y1;
        double expected_values[15] = { 0.0, 0.2, 0.4, 0.2, 1.0,
                                       0.5, 0.4, 0.5, 0.2, 0.5,
                                       1.0, 0.2, 0.4, 0.5, 0.2
                                     };
        double new_buf[15];

        pat = cairo_pattern_create_linear (1.0, 2.0, 3.0, 4.0);

        for (i = 0; i < 3; i++) {
            cairo_pattern_add_color_stop_rgba (pat,
                                               expected_values[i*5+0],
                                               expected_values[i*5+1],
                                               expected_values[i*5+2],
                                               expected_values[i*5+3],
                                               expected_values[i*5+4]);
        }

        status = cairo_pattern_get_linear_points (pat, &x0, &y0, &x1, &y1);
        CHECK_SUCCESS;

        if (!CAIRO_TEST_DOUBLE_EQUALS(x0,1.0) ||
                !CAIRO_TEST_DOUBLE_EQUALS(y0,2.0) ||
                !CAIRO_TEST_DOUBLE_EQUALS(x1,3.0) ||
                !CAIRO_TEST_DOUBLE_EQUALS(y1,4.0))
            return CAIRO_TEST_FAILURE;

        status = cairo_pattern_get_color_stop_count (pat, &i);
        CHECK_SUCCESS;

        if (i != 3)
            return CAIRO_TEST_FAILURE;

        for (i = 0; i < 3; i++) {
            status = cairo_pattern_get_color_stop_rgba (pat, i,
                     &new_buf[i*5+0],
                     &new_buf[i*5+1],
                     &new_buf[i*5+2],
                     &new_buf[i*5+3],
                     &new_buf[i*5+4]);
            CHECK_SUCCESS;
        }

        status = cairo_pattern_get_color_stop_rgba (pat, 5, NULL, NULL, NULL, NULL, NULL);
        if (status != CAIRO_STATUS_INVALID_INDEX)
            return CAIRO_TEST_FAILURE;

        if (!double_buf_equal (ctx, new_buf, expected_values, sizeof(expected_values)/sizeof(double)) != 0)
            return CAIRO_TEST_FAILURE;

        cairo_pattern_destroy (pat);
    }

    /* Test radial_get_circles */
    {
        double a, b, c, d, e, f;
        pat = cairo_pattern_create_radial (1, 2, 3,
                                           4, 5, 6);

        status = cairo_pattern_get_radial_circles (pat, &a, &b, &c, &d, &e, &f);
        CHECK_SUCCESS;

        if (!CAIRO_TEST_DOUBLE_EQUALS(a,1.0) ||
                !CAIRO_TEST_DOUBLE_EQUALS(b,2.0) ||
                !CAIRO_TEST_DOUBLE_EQUALS(c,3.0) ||
                !CAIRO_TEST_DOUBLE_EQUALS(d,4.0) ||
                !CAIRO_TEST_DOUBLE_EQUALS(e,5.0) ||
                !CAIRO_TEST_DOUBLE_EQUALS(f,6.0))
            return CAIRO_TEST_FAILURE;

        cairo_pattern_destroy (pat);
    }

    cairo_set_source_rgb (cr, 0, 1, 0);
    cairo_paint (cr);

    return CAIRO_TEST_SUCCESS;
}
コード例 #18
0
ファイル: panel-background.c プロジェクト: yetist/mate-panel
static gboolean
panel_background_prepare (PanelBackground *background)
{
	PanelBackgroundType  effective_type;
	GtkWidget           *widget = NULL;

	if (!background->transformed)
		return FALSE;

	effective_type = panel_background_effective_type (background);

	switch (effective_type) {
	case PANEL_BACK_NONE:
		if (background->default_pattern) {
			/* the theme background-image pattern must be scaled by
			* the width & height of the panel so that when the
			* backing region is cleared
			* (gdk_window_clear_backing_region), the correctly
			* scaled pattern is used */
			cairo_matrix_t m;
			cairo_surface_t *surface;
			double width, height;

			surface = NULL;
			width = 1.0;
			height = 1.0;
			cairo_pattern_get_surface(background->default_pattern, &surface);
			/* catch invalid images (e.g. -gtk-gradient) before scaling and rendering */
			if (surface != NULL ){
				cairo_surface_reference(surface);
				width = cairo_image_surface_get_width (surface);
				height = cairo_image_surface_get_height (surface);
				cairo_matrix_init_translate (&m, 0, 0);
				cairo_matrix_scale (&m,
						width / background->region.width,
						height / background->region.height);
				cairo_pattern_set_matrix (background->default_pattern, &m);

				gdk_window_set_background_pattern (background->window,
											background->default_pattern);
			}
			else {
				g_warning ("%s", "unsupported value of 'background-image' in GTK+ theme (such as '-gtk-gradient')");
				/* use any background color that has been set if image is invalid */
				gdk_window_set_background_rgba (
				background->window, &background->default_color);
			}
			cairo_surface_destroy(surface);
		} else
			gdk_window_set_background_rgba (
				background->window, &background->default_color);
		break;

	case PANEL_BACK_COLOR:
		if (background->has_alpha &&
		    !gdk_window_check_composited_wm(background->window))
			set_pixbuf_background (background);
		else {
			gdk_window_set_background_rgba (background->window,
			                                &background->color);
		}
		break;

	case PANEL_BACK_IMAGE:
		set_pixbuf_background (background);
		break;

	default:
		g_assert_not_reached ();
		break;
	}

	/* Panel applets may use the panel's background pixmap to
	 * decide how to draw themselves.  Therefore, we need to
	 * make sure that all drawing has been completed before
	 * the applet looks at the pixmap. */
	gdk_display_sync (gdk_window_get_display (background->window));

	gdk_window_get_user_data (GDK_WINDOW (background->window),
				  (gpointer) &widget);

	if (GTK_IS_WIDGET (widget)) {
		panel_background_apply_css (background, gtk_widget_get_toplevel(widget));
		gtk_widget_set_app_paintable(widget,TRUE);
		gtk_widget_queue_draw (widget);
	}

	background->notify_changed (background, background->user_data);

	return TRUE;
}