mirror of
https://github.com/brl/mutter.git
synced 2024-11-23 00:20:42 -05:00
Merge branch 'cairo-texture'
* cairo-texture: [cairo-texture] Remove the construct only restriction on surface size [cairo-texture] Silently discard 0x0 surfaces Re-indent ClutterPath header Add a test case for the new cairo path functions Add clutter_path_to_cairo_path and clutter_path_add_cairo_path Warn instead of returning in the IN_PAINT check Small documentation fixes Print a warning when creating a cairo_t while painting Do not set the IN_PAINT flag inside the Stage paint Set the IN_PAINT private flag [docs] Add ClutterCairoTexture to the API reference Add ClutterCairoTexture Require Cairo as a Clutter dependency Conflicts: Fix merge conflict in clutter/clutter-path.h
This commit is contained in:
commit
8d98c28dfa
@ -57,6 +57,7 @@ source_h = \
|
|||||||
$(srcdir)/clutter-behaviour-rotate.h \
|
$(srcdir)/clutter-behaviour-rotate.h \
|
||||||
$(srcdir)/clutter-behaviour-scale.h \
|
$(srcdir)/clutter-behaviour-scale.h \
|
||||||
$(srcdir)/clutter-binding-pool.h \
|
$(srcdir)/clutter-binding-pool.h \
|
||||||
|
$(srcdir)/clutter-cairo-texture.h \
|
||||||
$(srcdir)/clutter-child-meta.h \
|
$(srcdir)/clutter-child-meta.h \
|
||||||
$(srcdir)/clutter-clone-texture.h \
|
$(srcdir)/clutter-clone-texture.h \
|
||||||
$(srcdir)/clutter-color.h \
|
$(srcdir)/clutter-color.h \
|
||||||
@ -148,6 +149,7 @@ source_c = \
|
|||||||
clutter-behaviour-scale.c \
|
clutter-behaviour-scale.c \
|
||||||
clutter-bezier.c \
|
clutter-bezier.c \
|
||||||
clutter-binding-pool.c \
|
clutter-binding-pool.c \
|
||||||
|
clutter-cairo-texture.c \
|
||||||
clutter-child-meta.c \
|
clutter-child-meta.c \
|
||||||
clutter-clone-texture.c \
|
clutter-clone-texture.c \
|
||||||
clutter-color.c \
|
clutter-color.c \
|
||||||
|
@ -1453,6 +1453,9 @@ clutter_actor_paint (ClutterActor *self)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* mark that we are in the paint process */
|
||||||
|
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IN_PAINT);
|
||||||
|
|
||||||
cogl_push_matrix();
|
cogl_push_matrix();
|
||||||
|
|
||||||
_clutter_actor_apply_modelview_transform (self);
|
_clutter_actor_apply_modelview_transform (self);
|
||||||
@ -1492,6 +1495,9 @@ clutter_actor_paint (ClutterActor *self)
|
|||||||
cogl_clip_unset();
|
cogl_clip_unset();
|
||||||
|
|
||||||
cogl_pop_matrix();
|
cogl_pop_matrix();
|
||||||
|
|
||||||
|
/* paint sequence complete */
|
||||||
|
CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IN_PAINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fixed point, unit based rotation setter, to be used by
|
/* fixed point, unit based rotation setter, to be used by
|
||||||
|
754
clutter/clutter-cairo-texture.c
Normal file
754
clutter/clutter-cairo-texture.c
Normal file
@ -0,0 +1,754 @@
|
|||||||
|
/*
|
||||||
|
* Clutter
|
||||||
|
*
|
||||||
|
* An OpenGL based 'interactive canvas' library.
|
||||||
|
*
|
||||||
|
* Authored By: Emmanuele Bassi <ebassi@linux.intel.com>
|
||||||
|
* Matthew Allum <mallum@o-hand.com>
|
||||||
|
* Chris Lord <chris@o-hand.com>
|
||||||
|
* Iain Holmes <iain@o-hand.com>
|
||||||
|
* Neil Roberts <neil@linux.intel.com>
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:clutter-cairo-texture
|
||||||
|
* @short_description: Texture with Cairo integration
|
||||||
|
*
|
||||||
|
* #ClutterCairoTexture is a #ClutterTexture that displays the contents
|
||||||
|
* of a Cairo context. The #ClutterCairoTexture actor will create a
|
||||||
|
* Cairo image surface which will then be uploaded to a GL texture when
|
||||||
|
* needed.
|
||||||
|
*
|
||||||
|
* #ClutterCairoTexture will provide a #cairo_t context by using the
|
||||||
|
* clutter_cairo_texture_create() and clutter_cairo_texture_create_region()
|
||||||
|
* functions; you can use the Cairo API to draw on the context and then
|
||||||
|
* call cairo_destroy() when done.
|
||||||
|
*
|
||||||
|
* As soon as the context is destroyed with cairo_destroy(), the contents
|
||||||
|
* of the surface will be uploaded into the #ClutterCairoTexture actor:
|
||||||
|
*
|
||||||
|
* |[
|
||||||
|
* cairo_t *cr;
|
||||||
|
*
|
||||||
|
* cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (texture));
|
||||||
|
*
|
||||||
|
* /* draw on the context */
|
||||||
|
*
|
||||||
|
* cairo_destroy (cr);
|
||||||
|
* ]|
|
||||||
|
*
|
||||||
|
* <warning><para>Note that you should never use the code above inside the
|
||||||
|
* #ClutterActor::paint or #ClutterActor::pick virtual functions or
|
||||||
|
* signal handlers because it will lead to performance
|
||||||
|
* degradation.</para></warning>
|
||||||
|
*
|
||||||
|
* <note><para>Since #ClutterCairoTexture uses a Cairo image surface
|
||||||
|
* internally all the drawing operations will be performed in
|
||||||
|
* software and not using hardware acceleration. This can lead to
|
||||||
|
* performance degradation if the contents of the texture change
|
||||||
|
* frequently.</para></note>
|
||||||
|
*
|
||||||
|
* #ClutterCairoTexture is available since Clutter 1.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "clutter-cairo-texture.h"
|
||||||
|
#include "clutter-debug.h"
|
||||||
|
#include "clutter-private.h"
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (ClutterCairoTexture,
|
||||||
|
clutter_cairo_texture,
|
||||||
|
CLUTTER_TYPE_TEXTURE);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_SURFACE_WIDTH,
|
||||||
|
PROP_SURFACE_HEIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CLUTTER_ENABLE_DEBUG
|
||||||
|
#define clutter_warn_if_paint_fail(obj) G_STMT_START { \
|
||||||
|
if (CLUTTER_PRIVATE_FLAGS ((obj)) & CLUTTER_ACTOR_IN_PAINT) { \
|
||||||
|
g_warning ("%s should not be called during the paint sequence " \
|
||||||
|
"of a ClutterCairoTexture as it will likely cause " \
|
||||||
|
"performance issues.", G_STRFUNC); \
|
||||||
|
} } G_STMT_END
|
||||||
|
#else
|
||||||
|
#define clutter_warn_if_paint_fail(obj) /* void */
|
||||||
|
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||||
|
|
||||||
|
#define CLUTTER_CAIRO_TEXTURE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_CAIRO_TEXTURE, ClutterCairoTexturePrivate))
|
||||||
|
|
||||||
|
struct _ClutterCairoTexturePrivate
|
||||||
|
{
|
||||||
|
cairo_format_t format;
|
||||||
|
|
||||||
|
cairo_surface_t *cr_surface;
|
||||||
|
guchar *cr_surface_data;
|
||||||
|
|
||||||
|
guint width;
|
||||||
|
guint height;
|
||||||
|
guint rowstride;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
gint x;
|
||||||
|
gint y;
|
||||||
|
guint width;
|
||||||
|
guint height;
|
||||||
|
} ClutterCairoTextureRectangle;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ClutterCairoTexture *cairo;
|
||||||
|
ClutterCairoTextureRectangle rect;
|
||||||
|
} ClutterCairoTextureContext;
|
||||||
|
|
||||||
|
static const cairo_user_data_key_t clutter_cairo_texture_surface_key;
|
||||||
|
static const cairo_user_data_key_t clutter_cairo_texture_context_key;
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_cairo_texture_surface_destroy (void *data)
|
||||||
|
{
|
||||||
|
ClutterCairoTexture *cairo = data;
|
||||||
|
|
||||||
|
cairo->priv->cr_surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_cairo_texture_set_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterCairoTexturePrivate *priv;
|
||||||
|
|
||||||
|
priv = CLUTTER_CAIRO_TEXTURE (object)->priv;
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_SURFACE_WIDTH:
|
||||||
|
priv->width = g_value_get_uint (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_SURFACE_HEIGHT:
|
||||||
|
priv->height = g_value_get_uint (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_cairo_texture_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterCairoTexturePrivate *priv;
|
||||||
|
|
||||||
|
priv = CLUTTER_CAIRO_TEXTURE (object)->priv;
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_SURFACE_WIDTH:
|
||||||
|
g_value_set_uint (value, priv->width);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_SURFACE_HEIGHT:
|
||||||
|
g_value_set_uint (value, priv->height);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_cairo_texture_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
ClutterCairoTexturePrivate *priv = CLUTTER_CAIRO_TEXTURE (object)->priv;
|
||||||
|
|
||||||
|
if (priv->cr_surface)
|
||||||
|
{
|
||||||
|
cairo_surface_t *surface = priv->cr_surface;
|
||||||
|
|
||||||
|
cairo_surface_finish (priv->cr_surface);
|
||||||
|
cairo_surface_set_user_data (priv->cr_surface,
|
||||||
|
&clutter_cairo_texture_surface_key,
|
||||||
|
NULL, NULL);
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
|
|
||||||
|
priv->cr_surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->cr_surface_data)
|
||||||
|
{
|
||||||
|
g_free (priv->cr_surface_data);
|
||||||
|
priv->cr_surface_data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (clutter_cairo_texture_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
clutter_cairo_texture_surface_resize_internal (ClutterCairoTexture *cairo)
|
||||||
|
{
|
||||||
|
ClutterCairoTexturePrivate *priv = cairo->priv;
|
||||||
|
|
||||||
|
if (priv->cr_surface)
|
||||||
|
{
|
||||||
|
cairo_surface_t *surface = priv->cr_surface;
|
||||||
|
|
||||||
|
/* If the surface is already the right size then don't bother
|
||||||
|
doing anything */
|
||||||
|
if (priv->width == cairo_image_surface_get_width (priv->cr_surface)
|
||||||
|
&& priv->height == cairo_image_surface_get_height (priv->cr_surface))
|
||||||
|
return;
|
||||||
|
|
||||||
|
cairo_surface_finish (surface);
|
||||||
|
cairo_surface_set_user_data (surface,
|
||||||
|
&clutter_cairo_texture_surface_key,
|
||||||
|
NULL, NULL);
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
|
|
||||||
|
priv->cr_surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->cr_surface_data)
|
||||||
|
{
|
||||||
|
g_free (priv->cr_surface_data);
|
||||||
|
priv->cr_surface_data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->width == 0 || priv->height == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if CAIRO_VERSION > 106000
|
||||||
|
priv->rowstride = cairo_format_stride_for_width (priv->format, priv->width);
|
||||||
|
#else
|
||||||
|
/* poor man's version of cairo_format_stride_for_width() */
|
||||||
|
switch (priv->format)
|
||||||
|
{
|
||||||
|
case CAIRO_FORMAT_ARGB32:
|
||||||
|
case CAIRO_FORMAT_RGB24:
|
||||||
|
priv->rowstride = priv->width * 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CAIRO_FORMAT_A8:
|
||||||
|
case CAIRO_FORMAT_A1:
|
||||||
|
priv->rowstride = priv->width;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif /* CAIRO_VERSION > 106000 */
|
||||||
|
|
||||||
|
priv->cr_surface_data = g_malloc0 (priv->height * priv->rowstride);
|
||||||
|
priv->cr_surface =
|
||||||
|
cairo_image_surface_create_for_data (priv->cr_surface_data,
|
||||||
|
priv->format,
|
||||||
|
priv->width, priv->height,
|
||||||
|
priv->rowstride);
|
||||||
|
|
||||||
|
cairo_surface_set_user_data (priv->cr_surface,
|
||||||
|
&clutter_cairo_texture_surface_key,
|
||||||
|
cairo,
|
||||||
|
clutter_cairo_texture_surface_destroy);
|
||||||
|
|
||||||
|
/* The texture data will be all zeroes so we can use it to create a
|
||||||
|
* blank Cogl texture even though its in a different format
|
||||||
|
*/
|
||||||
|
clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (cairo),
|
||||||
|
priv->cr_surface_data,
|
||||||
|
TRUE, priv->width, priv->height,
|
||||||
|
priv->rowstride,
|
||||||
|
4, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_cairo_texture_notify (GObject *object,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
/* When the surface width or height changes then resize the cairo
|
||||||
|
surface. This is done here instead of directly in set_property so
|
||||||
|
that if both the width and height properties are set using a
|
||||||
|
single call to g_object_set then the surface will only be resized
|
||||||
|
once because the notifications will be frozen in between */
|
||||||
|
if (!strcmp ("surface-width", pspec->name)
|
||||||
|
|| !strcmp ("surface-height", pspec->name))
|
||||||
|
{
|
||||||
|
ClutterCairoTexture *cairo = CLUTTER_CAIRO_TEXTURE (object);
|
||||||
|
|
||||||
|
clutter_cairo_texture_surface_resize_internal (cairo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (G_OBJECT_CLASS (clutter_cairo_texture_parent_class)->notify)
|
||||||
|
G_OBJECT_CLASS (clutter_cairo_texture_parent_class)->notify (object, pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_cairo_texture_get_preferred_width (ClutterActor *actor,
|
||||||
|
ClutterUnit for_height,
|
||||||
|
ClutterUnit *min_width,
|
||||||
|
ClutterUnit *natural_width)
|
||||||
|
{
|
||||||
|
ClutterCairoTexturePrivate *priv = CLUTTER_CAIRO_TEXTURE (actor)->priv;
|
||||||
|
|
||||||
|
if (min_width)
|
||||||
|
*min_width = 0;
|
||||||
|
|
||||||
|
if (natural_width)
|
||||||
|
*natural_width = CLUTTER_UNITS_FROM_DEVICE (priv->width);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_cairo_texture_get_preferred_height (ClutterActor *actor,
|
||||||
|
ClutterUnit for_width,
|
||||||
|
ClutterUnit *min_height,
|
||||||
|
ClutterUnit *natural_height)
|
||||||
|
{
|
||||||
|
ClutterCairoTexturePrivate *priv = CLUTTER_CAIRO_TEXTURE (actor)->priv;
|
||||||
|
|
||||||
|
if (min_height)
|
||||||
|
*min_height = 0;
|
||||||
|
|
||||||
|
if (natural_height)
|
||||||
|
*natural_height = CLUTTER_UNITS_FROM_DEVICE (priv->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_cairo_texture_class_init (ClutterCairoTextureClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||||
|
|
||||||
|
gobject_class->finalize = clutter_cairo_texture_finalize;
|
||||||
|
gobject_class->set_property = clutter_cairo_texture_set_property;
|
||||||
|
gobject_class->get_property = clutter_cairo_texture_get_property;
|
||||||
|
gobject_class->notify = clutter_cairo_texture_notify;
|
||||||
|
|
||||||
|
actor_class->get_preferred_width =
|
||||||
|
clutter_cairo_texture_get_preferred_width;
|
||||||
|
actor_class->get_preferred_height =
|
||||||
|
clutter_cairo_texture_get_preferred_height;
|
||||||
|
|
||||||
|
g_type_class_add_private (gobject_class, sizeof (ClutterCairoTexturePrivate));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterCairoTexture:surface-width:
|
||||||
|
*
|
||||||
|
* The width of the Cairo surface used by the #ClutterCairoTexture
|
||||||
|
* actor, in pixels.
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_SURFACE_WIDTH,
|
||||||
|
g_param_spec_uint ("surface-width",
|
||||||
|
"Surface-Width",
|
||||||
|
"Surface Width",
|
||||||
|
0, G_MAXUINT,
|
||||||
|
0,
|
||||||
|
CLUTTER_PARAM_READWRITE));
|
||||||
|
/**
|
||||||
|
* ClutterCairoTexture:surface-height:
|
||||||
|
*
|
||||||
|
* The height of the Cairo surface used by the #ClutterCairoTexture
|
||||||
|
* actor, in pixels.
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_SURFACE_HEIGHT,
|
||||||
|
g_param_spec_uint ("surface-height",
|
||||||
|
"Surface-Height",
|
||||||
|
"Surface Height",
|
||||||
|
0, G_MAXUINT,
|
||||||
|
0,
|
||||||
|
CLUTTER_PARAM_READWRITE));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_cairo_texture_init (ClutterCairoTexture *self)
|
||||||
|
{
|
||||||
|
ClutterCairoTexturePrivate *priv;
|
||||||
|
|
||||||
|
self->priv = priv = CLUTTER_CAIRO_TEXTURE_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
/* FIXME - we are hardcoding the format; it would be good to have
|
||||||
|
* a :surface-format construct-only property for creating
|
||||||
|
* textures with a different format and have the cairo surface
|
||||||
|
* match that format
|
||||||
|
*/
|
||||||
|
priv->format = CAIRO_FORMAT_ARGB32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_cairo_texture_new:
|
||||||
|
* @width: the width of the surface
|
||||||
|
* @height: the height of the surface
|
||||||
|
*
|
||||||
|
* Creates a new #ClutterCairoTexture actor, with a surface of @width by
|
||||||
|
* @height pixels.
|
||||||
|
*
|
||||||
|
* Return value: the newly created #ClutterCairoTexture actor
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
ClutterActor*
|
||||||
|
clutter_cairo_texture_new (guint width,
|
||||||
|
guint height)
|
||||||
|
{
|
||||||
|
return g_object_new (CLUTTER_TYPE_CAIRO_TEXTURE,
|
||||||
|
"surface-width", width,
|
||||||
|
"surface-height", height,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_cairo_texture_context_destroy (void *data)
|
||||||
|
{
|
||||||
|
ClutterCairoTextureContext *ctxt = data;
|
||||||
|
ClutterCairoTexture *cairo = ctxt->cairo;
|
||||||
|
ClutterCairoTexturePrivate *priv;
|
||||||
|
|
||||||
|
gint cairo_width, cairo_height, cairo_rowstride;
|
||||||
|
gint surface_width, surface_height;
|
||||||
|
guchar *pixbuf_data, *dst, *cairo_data;
|
||||||
|
guint *src, pixbuf_rowstride;
|
||||||
|
gint x, y;
|
||||||
|
|
||||||
|
priv = CLUTTER_CAIRO_TEXTURE_GET_PRIVATE (cairo);
|
||||||
|
|
||||||
|
if (!priv->cr_surface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
surface_width = cairo_image_surface_get_width (priv->cr_surface);
|
||||||
|
surface_height = cairo_image_surface_get_height (priv->cr_surface);
|
||||||
|
|
||||||
|
cairo_width = MIN (ctxt->rect.width, surface_width);
|
||||||
|
cairo_height = MIN (ctxt->rect.height, surface_height);
|
||||||
|
|
||||||
|
if (!cairo_width || !cairo_height)
|
||||||
|
{
|
||||||
|
g_free (ctxt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_rowstride = priv->rowstride;
|
||||||
|
cairo_data = priv->cr_surface_data;
|
||||||
|
pixbuf_data = g_malloc (cairo_width * cairo_height * 4);
|
||||||
|
pixbuf_rowstride = cairo_width * 4;
|
||||||
|
|
||||||
|
/* BAH BAH BAH ! un-pre-multiply alpha...
|
||||||
|
*
|
||||||
|
* FIXME: Need to figure out if GL has a premult texture
|
||||||
|
* format, or we need to change the order of the
|
||||||
|
* paint sequence in Clutter. or go back to battling
|
||||||
|
* glitz (ugh).
|
||||||
|
*
|
||||||
|
* in theory, this could be moved to a shader, but apparently
|
||||||
|
* the performance gain is not really worth it.
|
||||||
|
*/
|
||||||
|
for (y = 0; y < cairo_height; y++)
|
||||||
|
{
|
||||||
|
src = (unsigned int *) (cairo_data
|
||||||
|
+ ((y + ctxt->rect.y) * cairo_rowstride)
|
||||||
|
+ (ctxt->rect.x * 4));
|
||||||
|
dst = pixbuf_data + y * pixbuf_rowstride;
|
||||||
|
|
||||||
|
for (x = 0; x < cairo_width; x++)
|
||||||
|
{
|
||||||
|
guchar alpha = (*src >> 24) & 0xff;
|
||||||
|
|
||||||
|
if (alpha == 0)
|
||||||
|
dst[0] = dst[1] = dst[2] = dst[3] = alpha;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dst[0] = (((*src >> 16) & 0xff) * 255 ) / alpha;
|
||||||
|
dst[1] = (((*src >> 8) & 0xff) * 255 ) / alpha;
|
||||||
|
dst[2] = (((*src >> 0) & 0xff) * 255 ) / alpha;
|
||||||
|
dst[3] = alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += 4;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_texture_set_area_from_rgb_data (CLUTTER_TEXTURE (cairo),
|
||||||
|
pixbuf_data,
|
||||||
|
TRUE,
|
||||||
|
ctxt->rect.x,
|
||||||
|
ctxt->rect.y,
|
||||||
|
cairo_width, cairo_height,
|
||||||
|
pixbuf_rowstride,
|
||||||
|
4, 0, NULL);
|
||||||
|
|
||||||
|
g_free (pixbuf_data);
|
||||||
|
g_free (ctxt);
|
||||||
|
|
||||||
|
if (CLUTTER_ACTOR_IS_VISIBLE (cairo))
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (cairo));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
intersect_rectangles (ClutterCairoTextureRectangle *a,
|
||||||
|
ClutterCairoTextureRectangle *b,
|
||||||
|
ClutterCairoTextureRectangle *inter)
|
||||||
|
{
|
||||||
|
gint dest_x, dest_y;
|
||||||
|
gint dest_width, dest_height;
|
||||||
|
|
||||||
|
dest_x = MAX (a->x, b->x);
|
||||||
|
dest_y = MAX (a->y, b->y);
|
||||||
|
dest_width = MIN (a->x + a->width, b->x + b->width) - dest_x;
|
||||||
|
dest_height = MIN (a->y + a->height, b->y + b->height) - dest_y;
|
||||||
|
|
||||||
|
if (dest_width > 0 && dest_height > 0)
|
||||||
|
{
|
||||||
|
inter->x = dest_x;
|
||||||
|
inter->y = dest_y;
|
||||||
|
inter->width = dest_width;
|
||||||
|
inter->height = dest_height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inter->x = 0;
|
||||||
|
inter->y = 0;
|
||||||
|
inter->width = 0;
|
||||||
|
inter->height = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_cairo_texture_create_region:
|
||||||
|
* @cairo: a #ClutterCairoTexture
|
||||||
|
* @x_offset: offset of the region on the X axis
|
||||||
|
* @y_offset: offset of the region on the Y axis
|
||||||
|
* @width: width of the region, or -1 for the full surface width
|
||||||
|
* @height: height of the region, or -1 for the full surface height
|
||||||
|
*
|
||||||
|
* Creates a new Cairo context that will updat the region defined
|
||||||
|
* by @x_offset, @y_offset, @width and @height.
|
||||||
|
*
|
||||||
|
* Return value: a newly created Cairo context. Use cairo_destroy()
|
||||||
|
* to upload the contents of the context when done drawing.
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
cairo_t *
|
||||||
|
clutter_cairo_texture_create_region (ClutterCairoTexture *self,
|
||||||
|
gint x_offset,
|
||||||
|
gint y_offset,
|
||||||
|
gint width,
|
||||||
|
gint height)
|
||||||
|
{
|
||||||
|
ClutterCairoTexturePrivate *priv;
|
||||||
|
ClutterCairoTextureContext *ctxt;
|
||||||
|
ClutterCairoTextureRectangle region, area, inter;
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_CAIRO_TEXTURE (self), NULL);
|
||||||
|
|
||||||
|
clutter_warn_if_paint_fail (self);
|
||||||
|
|
||||||
|
priv = self->priv;
|
||||||
|
|
||||||
|
if (width < 0)
|
||||||
|
width = priv->width;
|
||||||
|
|
||||||
|
if (height < 0)
|
||||||
|
height = priv->height;
|
||||||
|
|
||||||
|
if (width == 0 || height == 0)
|
||||||
|
{
|
||||||
|
g_warning ("Unable to create a context for an image surface of "
|
||||||
|
"width %d and height %d. Set the surface size to be "
|
||||||
|
"at least 1 pixel by 1 pixel.",
|
||||||
|
width, height);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!priv->cr_surface)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ctxt = g_new0 (ClutterCairoTextureContext, 1);
|
||||||
|
ctxt->cairo = self;
|
||||||
|
|
||||||
|
region.x = x_offset;
|
||||||
|
region.y = y_offset;
|
||||||
|
region.width = width;
|
||||||
|
region.height = height;
|
||||||
|
|
||||||
|
area.x = 0;
|
||||||
|
area.y = 0;
|
||||||
|
area.width = priv->width;
|
||||||
|
area.height = priv->height;
|
||||||
|
|
||||||
|
/* Limit the region to the visible rectangle */
|
||||||
|
intersect_rectangles (&area, ®ion, &inter);
|
||||||
|
|
||||||
|
ctxt->rect.x = inter.x;
|
||||||
|
ctxt->rect.y = inter.y;
|
||||||
|
ctxt->rect.width = inter.width;
|
||||||
|
ctxt->rect.height = inter.height;
|
||||||
|
|
||||||
|
cr = cairo_create (priv->cr_surface);
|
||||||
|
cairo_set_user_data (cr, &clutter_cairo_texture_context_key,
|
||||||
|
ctxt, clutter_cairo_texture_context_destroy);
|
||||||
|
|
||||||
|
return cr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_cairo_texture_create:
|
||||||
|
* @cairo: a #ClutterCairoTexture
|
||||||
|
*
|
||||||
|
* Creates a new Cairo context for the @cairo texture. It is
|
||||||
|
* similar to using clutter_cairo_texture_create_region() with @x_offset
|
||||||
|
* and @y_offset of 0, @width equal to the @cairo texture surface width
|
||||||
|
* and @height equal to the @cairo texture surface height.
|
||||||
|
*
|
||||||
|
* Return value: a newly created Cairo context. Use cairo_destroy()
|
||||||
|
* to upload the contents of the context when done drawing.
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
cairo_t *
|
||||||
|
clutter_cairo_texture_create (ClutterCairoTexture *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_CAIRO_TEXTURE (self), NULL);
|
||||||
|
|
||||||
|
clutter_warn_if_paint_fail (self);
|
||||||
|
|
||||||
|
return clutter_cairo_texture_create_region (self, 0, 0, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_cairo_set_source_color:
|
||||||
|
* @cr: a Cairo context
|
||||||
|
* @color: a #ClutterColor
|
||||||
|
*
|
||||||
|
* Utility function for setting the source color of @cr using
|
||||||
|
* a #ClutterColor.
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_cairo_set_source_color (cairo_t *cr,
|
||||||
|
const ClutterColor *color)
|
||||||
|
{
|
||||||
|
g_return_if_fail (cr != NULL);
|
||||||
|
g_return_if_fail (color != NULL);
|
||||||
|
|
||||||
|
if (color->alpha == 0xff)
|
||||||
|
cairo_set_source_rgb (cr,
|
||||||
|
color->red / 255.0,
|
||||||
|
color->green / 255.0,
|
||||||
|
color->blue / 255.0);
|
||||||
|
else
|
||||||
|
cairo_set_source_rgba (cr,
|
||||||
|
color->red / 255.0,
|
||||||
|
color->green / 255.0,
|
||||||
|
color->blue / 255.0,
|
||||||
|
color->alpha / 255.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_cairo_texture_surface_set_size:
|
||||||
|
* @self: a #ClutterCairoTexture
|
||||||
|
* @width: the new width of the surface
|
||||||
|
* @height: the new height of the surface
|
||||||
|
*
|
||||||
|
* Resizes the Cairo surface used by @self to @width and @height.
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_cairo_texture_set_surface_size (ClutterCairoTexture *self,
|
||||||
|
guint width,
|
||||||
|
guint height)
|
||||||
|
{
|
||||||
|
ClutterCairoTexturePrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_CAIRO_TEXTURE (self));
|
||||||
|
|
||||||
|
priv = self->priv;
|
||||||
|
|
||||||
|
if (width == priv->width && height == priv->height)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_object_freeze_notify (G_OBJECT (self));
|
||||||
|
|
||||||
|
if (priv->width != width)
|
||||||
|
{
|
||||||
|
priv->width = width;
|
||||||
|
g_object_notify (G_OBJECT (self), "surface-width");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->height != height)
|
||||||
|
{
|
||||||
|
priv->height = height;
|
||||||
|
g_object_notify (G_OBJECT (self), "surface-height");
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_cairo_texture_surface_resize_internal (self);
|
||||||
|
|
||||||
|
g_object_thaw_notify (G_OBJECT (self));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_cairo_texture_get_surface_size:
|
||||||
|
* @self: a #ClutterCairoTexture
|
||||||
|
* @width: return location for the surface width, or %NULL
|
||||||
|
* @height: return location for the surface height, or %NULL
|
||||||
|
*
|
||||||
|
* Retrieves the surface width and height for @self.
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_cairo_texture_get_surface_size (ClutterCairoTexture *self,
|
||||||
|
guint *width,
|
||||||
|
guint *height)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CLUTTER_IS_CAIRO_TEXTURE (self));
|
||||||
|
|
||||||
|
if (width)
|
||||||
|
*width = self->priv->width;
|
||||||
|
|
||||||
|
if (height)
|
||||||
|
*height = self->priv->height;
|
||||||
|
}
|
92
clutter/clutter-cairo-texture.h
Normal file
92
clutter/clutter-cairo-texture.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Clutter
|
||||||
|
*
|
||||||
|
* An OpenGL based 'interactive canvas' library.
|
||||||
|
*
|
||||||
|
* Authored By: Emmanuele Bassi <ebassi@linux.intel.com>
|
||||||
|
* Matthew Allum <mallum@o-hand.com>
|
||||||
|
* Chris Lord <chris@o-hand.com>
|
||||||
|
* Iain Holmes <iain@o-hand.com>
|
||||||
|
* Neil Roberts <neil@linux.intel.com>
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||||
|
#error "Only <clutter/clutter.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __CLUTTER_CAIRO_TEXTURE_H__
|
||||||
|
#define __CLUTTER_CAIRO_TEXTURE_H__
|
||||||
|
|
||||||
|
#include <clutter/clutter-texture.h>
|
||||||
|
#include <cairo/cairo.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define CLUTTER_TYPE_CAIRO_TEXTURE (clutter_cairo_texture_get_type ())
|
||||||
|
#define CLUTTER_CAIRO_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CAIRO_TEXTURE, ClutterCairoTexture))
|
||||||
|
#define CLUTTER_CAIRO_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CAIRO_TEXTURE, ClutterCairoTextureClass))
|
||||||
|
#define CLUTTER_IS_CAIRO_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CAIRO_TEXTURE))
|
||||||
|
#define CLUTTER_IS_CAIRO_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CAIRO_TEXTURE))
|
||||||
|
#define CLUTTER_CAIRO_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CAIRO_TEXTURE, ClutterCairoTextureClass))
|
||||||
|
|
||||||
|
typedef struct _ClutterCairoTexture ClutterCairoTexture;
|
||||||
|
typedef struct _ClutterCairoTextureClass ClutterCairoTextureClass;
|
||||||
|
typedef struct _ClutterCairoTexturePrivate ClutterCairoTexturePrivate;
|
||||||
|
|
||||||
|
struct _ClutterCairoTexture
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
ClutterTexture parent_instance;
|
||||||
|
|
||||||
|
ClutterCairoTexturePrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _ClutterCairoTextureClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
ClutterTextureClass parent_class;
|
||||||
|
|
||||||
|
void (*_clutter_cairo_1) (void);
|
||||||
|
void (*_clutter_cairo_2) (void);
|
||||||
|
void (*_clutter_cairo_3) (void);
|
||||||
|
void (*_clutter_cairo_4) (void);
|
||||||
|
};
|
||||||
|
|
||||||
|
GType clutter_cairo_texture_get_type (void) G_GNUC_CONST;
|
||||||
|
ClutterActor *clutter_cairo_texture_new (guint width,
|
||||||
|
guint height);
|
||||||
|
cairo_t * clutter_cairo_texture_create_region (ClutterCairoTexture *self,
|
||||||
|
gint x_offset,
|
||||||
|
gint y_offset,
|
||||||
|
gint width,
|
||||||
|
gint height);
|
||||||
|
cairo_t * clutter_cairo_texture_create (ClutterCairoTexture *self);
|
||||||
|
void clutter_cairo_texture_set_surface_size (ClutterCairoTexture *self,
|
||||||
|
guint width,
|
||||||
|
guint height);
|
||||||
|
void clutter_cairo_texture_get_surface_size (ClutterCairoTexture *self,
|
||||||
|
guint *width,
|
||||||
|
guint *height);
|
||||||
|
|
||||||
|
void clutter_cairo_set_source_color (cairo_t *cr,
|
||||||
|
const ClutterColor *color);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __CLUTTER_CAIRO_TEXTURE_H__ */
|
@ -735,6 +735,121 @@ clutter_path_add_node (ClutterPath *path,
|
|||||||
clutter_path_add_node_full (path, node_full);
|
clutter_path_add_node_full (path, node_full);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_path_add_cairo_path:
|
||||||
|
* @path: a #ClutterPath
|
||||||
|
* @cpath: a Cairo path
|
||||||
|
*
|
||||||
|
* Add the nodes of the Cairo path to the end of @path.
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_path_add_cairo_path (ClutterPath *path,
|
||||||
|
const cairo_path_t *cpath)
|
||||||
|
{
|
||||||
|
int num_data;
|
||||||
|
const cairo_path_data_t *p;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_PATH (path));
|
||||||
|
g_return_if_fail (cpath != NULL);
|
||||||
|
|
||||||
|
/* Iterate over each command in the cairo path */
|
||||||
|
for (num_data = cpath->num_data, p = cpath->data;
|
||||||
|
num_data > 0;
|
||||||
|
num_data -= p->header.length, p += p->header.length)
|
||||||
|
{
|
||||||
|
switch (p->header.type)
|
||||||
|
{
|
||||||
|
case CAIRO_PATH_MOVE_TO:
|
||||||
|
g_assert (p->header.length >= 2);
|
||||||
|
|
||||||
|
clutter_path_add_move_to (path, p[1].point.x, p[1].point.y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CAIRO_PATH_LINE_TO:
|
||||||
|
g_assert (p->header.length >= 2);
|
||||||
|
|
||||||
|
clutter_path_add_line_to (path, p[1].point.x, p[1].point.y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CAIRO_PATH_CURVE_TO:
|
||||||
|
g_assert (p->header.length >= 4);
|
||||||
|
|
||||||
|
clutter_path_add_curve_to (path,
|
||||||
|
p[1].point.x, p[1].point.y,
|
||||||
|
p[2].point.x, p[2].point.y,
|
||||||
|
p[3].point.x, p[3].point.y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CAIRO_PATH_CLOSE_PATH:
|
||||||
|
clutter_path_add_close (path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_path_add_node_to_cairo_path (const ClutterPathNode *node,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
cairo_t *cr = data;
|
||||||
|
|
||||||
|
switch (node->type)
|
||||||
|
{
|
||||||
|
case CLUTTER_PATH_MOVE_TO:
|
||||||
|
cairo_move_to (cr, node->points[0].x, node->points[0].y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_PATH_LINE_TO:
|
||||||
|
cairo_line_to (cr, node->points[0].x, node->points[0].y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_PATH_CURVE_TO:
|
||||||
|
cairo_curve_to (cr,
|
||||||
|
node->points[0].x, node->points[0].y,
|
||||||
|
node->points[1].x, node->points[1].y,
|
||||||
|
node->points[2].x, node->points[2].y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_PATH_REL_MOVE_TO:
|
||||||
|
cairo_rel_move_to (cr, node->points[0].x, node->points[0].y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_PATH_REL_LINE_TO:
|
||||||
|
cairo_rel_line_to (cr, node->points[0].x, node->points[0].y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_PATH_REL_CURVE_TO:
|
||||||
|
cairo_rel_curve_to (cr,
|
||||||
|
node->points[0].x, node->points[0].y,
|
||||||
|
node->points[1].x, node->points[1].y,
|
||||||
|
node->points[2].x, node->points[2].y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_PATH_CLOSE:
|
||||||
|
cairo_close_path (cr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_path_to_cairo_path:
|
||||||
|
* @path: a #ClutterPath
|
||||||
|
* @cr: a Cairo context
|
||||||
|
*
|
||||||
|
* Add the nodes of the ClutterPath to the path in the Cairo context.
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_path_to_cairo_path (ClutterPath *path,
|
||||||
|
cairo_t *cr)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CLUTTER_IS_PATH (path));
|
||||||
|
g_return_if_fail (cr != NULL);
|
||||||
|
|
||||||
|
clutter_path_foreach (path, clutter_path_add_node_to_cairo_path, cr);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_path_get_n_nodes:
|
* clutter_path_get_n_nodes:
|
||||||
* @path: a #ClutterPath
|
* @path: a #ClutterPath
|
||||||
|
@ -30,49 +30,39 @@
|
|||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include <clutter/clutter-types.h>
|
#include <clutter/clutter-types.h>
|
||||||
|
#include <cairo/cairo.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define CLUTTER_TYPE_PATH \
|
#define CLUTTER_TYPE_PATH (clutter_path_get_type ())
|
||||||
(clutter_path_get_type())
|
#define CLUTTER_TYPE_PATH_NODE (clutter_path_node_get_type ())
|
||||||
#define CLUTTER_PATH(obj) \
|
#define CLUTTER_PATH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_PATH, ClutterPath))
|
||||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
#define CLUTTER_PATH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_PATH, ClutterPathClass))
|
||||||
CLUTTER_TYPE_PATH, \
|
#define CLUTTER_IS_PATH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_PATH))
|
||||||
ClutterPath))
|
#define CLUTTER_IS_PATH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_PATH))
|
||||||
#define CLUTTER_PATH_CLASS(klass) \
|
#define CLUTTER_PATH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_PATH, ClutterPathClass))
|
||||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
|
||||||
CLUTTER_TYPE_PATH, \
|
|
||||||
ClutterPathClass))
|
|
||||||
#define CLUTTER_IS_PATH(obj) \
|
|
||||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
|
||||||
CLUTTER_TYPE_PATH))
|
|
||||||
#define CLUTTER_IS_PATH_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
|
||||||
CLUTTER_TYPE_PATH))
|
|
||||||
#define CLUTTER_PATH_GET_CLASS(obj) \
|
|
||||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
|
||||||
CLUTTER_TYPE_PATH, \
|
|
||||||
ClutterPathClass))
|
|
||||||
|
|
||||||
#define CLUTTER_TYPE_PATH_NODE (clutter_path_node_get_type ())
|
#define CLUTTER_PATH_RELATIVE (32)
|
||||||
|
|
||||||
#define CLUTTER_PATH_RELATIVE 32
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterPathNodeType:
|
* ClutterPathNodeType:
|
||||||
* @CLUTTER_PATH_MOVE_TO: jump to the given position
|
* @CLUTTER_PATH_MOVE_TO: jump to the given position
|
||||||
* @CLUTTER_PATH_LINE_TO: create a line from the last node to the
|
* @CLUTTER_PATH_LINE_TO: create a line from the last node to the
|
||||||
* given position
|
* given position
|
||||||
* @CLUTTER_PATH_CURVE_TO: bezier curve using the last position and
|
* @CLUTTER_PATH_CURVE_TO: bezier curve using the last position and
|
||||||
* three control points.
|
* three control points.
|
||||||
* @CLUTTER_PATH_CLOSE: create a line from the last node to the last
|
* @CLUTTER_PATH_CLOSE: create a line from the last node to the last
|
||||||
* %CLUTTER_PATH_MOVE_TO node.
|
* %CLUTTER_PATH_MOVE_TO node.
|
||||||
* @CLUTTER_PATH_REL_MOVE_TO: same as %CLUTTER_PATH_MOVE_TO but with
|
* @CLUTTER_PATH_REL_MOVE_TO: same as %CLUTTER_PATH_MOVE_TO but with
|
||||||
* coordinates relative to the last node.
|
* coordinates relative to the last node.
|
||||||
* @CLUTTER_PATH_REL_LINE_TO: same as %CLUTTER_PATH_LINE_TO but with
|
* @CLUTTER_PATH_REL_LINE_TO: same as %CLUTTER_PATH_LINE_TO but with
|
||||||
* coordinates relative to the last node.
|
* coordinates relative to the last node.
|
||||||
* @CLUTTER_PATH_REL_CURVE_TO: same as %CLUTTER_PATH_CURVE_TO but with
|
* @CLUTTER_PATH_REL_CURVE_TO: same as %CLUTTER_PATH_CURVE_TO but with
|
||||||
* coordinates relative to the last node.
|
* coordinates relative to the last node.
|
||||||
|
*
|
||||||
|
* Types of nodes in a #ClutterPath.
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CLUTTER_PATH_MOVE_TO = 0,
|
CLUTTER_PATH_MOVE_TO = 0,
|
||||||
@ -101,24 +91,15 @@ typedef struct _ClutterPathNode ClutterPathNode;
|
|||||||
* Since: 1.0
|
* Since: 1.0
|
||||||
*/
|
*/
|
||||||
typedef void (* ClutterPathCallback) (const ClutterPathNode *node,
|
typedef void (* ClutterPathCallback) (const ClutterPathNode *node,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
|
||||||
/**
|
|
||||||
* ClutterPathClass:
|
|
||||||
*
|
|
||||||
* The #ClutterPathClass struct contains only private data.
|
|
||||||
*/
|
|
||||||
struct _ClutterPathClass
|
|
||||||
{
|
|
||||||
/*< private >*/
|
|
||||||
GInitiallyUnownedClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterPath:
|
* ClutterPath:
|
||||||
*
|
*
|
||||||
* The #ClutterPath struct contains only private data and should
|
* The #ClutterPath struct contains only private data and should
|
||||||
* be accessed with the functions below.
|
* be accessed with the functions below.
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
*/
|
*/
|
||||||
struct _ClutterPath
|
struct _ClutterPath
|
||||||
{
|
{
|
||||||
@ -128,6 +109,19 @@ struct _ClutterPath
|
|||||||
ClutterPathPrivate *priv;
|
ClutterPathPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterPathClass:
|
||||||
|
*
|
||||||
|
* The #ClutterPathClass struct contains only private data.
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
struct _ClutterPathClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
GInitiallyUnownedClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterPathNode:
|
* ClutterPathNode:
|
||||||
* @type: the node's type
|
* @type: the node's type
|
||||||
@ -150,95 +144,74 @@ struct _ClutterPathNode
|
|||||||
};
|
};
|
||||||
|
|
||||||
GType clutter_path_get_type (void) G_GNUC_CONST;
|
GType clutter_path_get_type (void) G_GNUC_CONST;
|
||||||
|
GType clutter_path_node_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
ClutterPath *clutter_path_new (void);
|
ClutterPath *clutter_path_new (void);
|
||||||
|
ClutterPath *clutter_path_new_with_description (const gchar *desc);
|
||||||
|
void clutter_path_add_move_to (ClutterPath *path,
|
||||||
|
gint x,
|
||||||
|
gint y);
|
||||||
|
void clutter_path_add_rel_move_to (ClutterPath *path,
|
||||||
|
gint x,
|
||||||
|
gint y);
|
||||||
|
void clutter_path_add_line_to (ClutterPath *path,
|
||||||
|
gint x,
|
||||||
|
gint y);
|
||||||
|
void clutter_path_add_rel_line_to (ClutterPath *path,
|
||||||
|
gint x,
|
||||||
|
gint y);
|
||||||
|
void clutter_path_add_curve_to (ClutterPath *path,
|
||||||
|
gint x1,
|
||||||
|
gint y1,
|
||||||
|
gint x2,
|
||||||
|
gint y2,
|
||||||
|
gint x3,
|
||||||
|
gint y3);
|
||||||
|
void clutter_path_add_rel_curve_to (ClutterPath *path,
|
||||||
|
gint x1,
|
||||||
|
gint y1,
|
||||||
|
gint x2,
|
||||||
|
gint y2,
|
||||||
|
gint x3,
|
||||||
|
gint y3);
|
||||||
|
void clutter_path_add_close (ClutterPath *path);
|
||||||
|
gboolean clutter_path_add_string (ClutterPath *path,
|
||||||
|
const gchar *str);
|
||||||
|
void clutter_path_add_node (ClutterPath *path,
|
||||||
|
const ClutterPathNode *node);
|
||||||
|
void clutter_path_add_cairo_path (ClutterPath *path,
|
||||||
|
const cairo_path_t *cpath);
|
||||||
|
guint clutter_path_get_n_nodes (ClutterPath *path);
|
||||||
|
void clutter_path_get_node (ClutterPath *path,
|
||||||
|
guint index_,
|
||||||
|
ClutterPathNode *node);
|
||||||
|
GSList * clutter_path_get_nodes (ClutterPath *path);
|
||||||
|
void clutter_path_foreach (ClutterPath *path,
|
||||||
|
ClutterPathCallback callback,
|
||||||
|
gpointer user_data);
|
||||||
|
void clutter_path_insert_node (ClutterPath *path,
|
||||||
|
gint index_,
|
||||||
|
const ClutterPathNode *node);
|
||||||
|
void clutter_path_remove_node (ClutterPath *path,
|
||||||
|
guint index_);
|
||||||
|
void clutter_path_replace_node (ClutterPath *path,
|
||||||
|
guint index_,
|
||||||
|
const ClutterPathNode *node);
|
||||||
|
gchar * clutter_path_get_description (ClutterPath *path);
|
||||||
|
gboolean clutter_path_set_description (ClutterPath *path,
|
||||||
|
const gchar *str);
|
||||||
|
void clutter_path_clear (ClutterPath *path);
|
||||||
|
void clutter_path_to_cairo_path (ClutterPath *path,
|
||||||
|
cairo_t *cr);
|
||||||
|
guint clutter_path_get_position (ClutterPath *path,
|
||||||
|
gdouble factor,
|
||||||
|
ClutterKnot *position);
|
||||||
|
guint clutter_path_get_length (ClutterPath *path);
|
||||||
|
|
||||||
ClutterPath *clutter_path_new_with_description (const gchar *desc);
|
ClutterPathNode *clutter_path_node_copy (const ClutterPathNode *node);
|
||||||
|
void clutter_path_node_free (ClutterPathNode *node);
|
||||||
void clutter_path_add_move_to (ClutterPath *path,
|
gboolean clutter_path_node_equal (const ClutterPathNode *node_a,
|
||||||
gint x,
|
const ClutterPathNode *node_b);
|
||||||
gint y);
|
|
||||||
|
|
||||||
void clutter_path_add_rel_move_to (ClutterPath *path,
|
|
||||||
gint x,
|
|
||||||
gint y);
|
|
||||||
|
|
||||||
void clutter_path_add_line_to (ClutterPath *path,
|
|
||||||
gint x,
|
|
||||||
gint y);
|
|
||||||
|
|
||||||
void clutter_path_add_rel_line_to (ClutterPath *path,
|
|
||||||
gint x,
|
|
||||||
gint y);
|
|
||||||
|
|
||||||
void clutter_path_add_curve_to (ClutterPath *path,
|
|
||||||
gint x1,
|
|
||||||
gint y1,
|
|
||||||
gint x2,
|
|
||||||
gint y2,
|
|
||||||
gint x3,
|
|
||||||
gint y3);
|
|
||||||
|
|
||||||
void clutter_path_add_rel_curve_to (ClutterPath *path,
|
|
||||||
gint x1,
|
|
||||||
gint y1,
|
|
||||||
gint x2,
|
|
||||||
gint y2,
|
|
||||||
gint x3,
|
|
||||||
gint y3);
|
|
||||||
|
|
||||||
void clutter_path_add_close (ClutterPath *path);
|
|
||||||
|
|
||||||
gboolean clutter_path_add_string (ClutterPath *path,
|
|
||||||
const gchar *str);
|
|
||||||
|
|
||||||
void clutter_path_add_node (ClutterPath *path,
|
|
||||||
const ClutterPathNode *node);
|
|
||||||
|
|
||||||
guint clutter_path_get_n_nodes (ClutterPath *path);
|
|
||||||
|
|
||||||
void clutter_path_get_node (ClutterPath *path,
|
|
||||||
guint index,
|
|
||||||
ClutterPathNode *node);
|
|
||||||
|
|
||||||
GSList *clutter_path_get_nodes (ClutterPath *path);
|
|
||||||
|
|
||||||
void clutter_path_foreach (ClutterPath *path,
|
|
||||||
ClutterPathCallback callback,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
void clutter_path_insert_node (ClutterPath *path,
|
|
||||||
gint index,
|
|
||||||
const ClutterPathNode *node);
|
|
||||||
|
|
||||||
void clutter_path_remove_node (ClutterPath *path,
|
|
||||||
guint index);
|
|
||||||
|
|
||||||
void clutter_path_replace_node (ClutterPath *path,
|
|
||||||
guint index,
|
|
||||||
const ClutterPathNode *node);
|
|
||||||
|
|
||||||
gchar *clutter_path_get_description (ClutterPath *path);
|
|
||||||
|
|
||||||
gboolean clutter_path_set_description (ClutterPath *path,
|
|
||||||
const gchar *str);
|
|
||||||
|
|
||||||
void clutter_path_clear (ClutterPath *path);
|
|
||||||
|
|
||||||
guint clutter_path_get_position (ClutterPath *path,
|
|
||||||
gdouble progress,
|
|
||||||
ClutterKnot *position);
|
|
||||||
|
|
||||||
guint clutter_path_get_length (ClutterPath *path);
|
|
||||||
|
|
||||||
ClutterPathNode *clutter_path_node_copy (const ClutterPathNode *node);
|
|
||||||
|
|
||||||
void clutter_path_node_free (ClutterPathNode *node);
|
|
||||||
|
|
||||||
gboolean clutter_path_node_equal (const ClutterPathNode *node_a,
|
|
||||||
const ClutterPathNode *node_b);
|
|
||||||
|
|
||||||
GType clutter_path_node_get_type (void);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -213,8 +213,6 @@ clutter_stage_paint (ClutterActor *self)
|
|||||||
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||||
CoglColor stage_color;
|
CoglColor stage_color;
|
||||||
|
|
||||||
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IN_PAINT);
|
|
||||||
|
|
||||||
CLUTTER_NOTE (PAINT, "Initializing stage paint");
|
CLUTTER_NOTE (PAINT, "Initializing stage paint");
|
||||||
|
|
||||||
cogl_color_set_from_4ub (&stage_color,
|
cogl_color_set_from_4ub (&stage_color,
|
||||||
@ -235,8 +233,6 @@ clutter_stage_paint (ClutterActor *self)
|
|||||||
CLUTTER_NOTE (PAINT, "Proxying the paint to the stage implementation");
|
CLUTTER_NOTE (PAINT, "Proxying the paint to the stage implementation");
|
||||||
clutter_actor_paint (priv->impl);
|
clutter_actor_paint (priv->impl);
|
||||||
|
|
||||||
CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IN_PAINT);
|
|
||||||
|
|
||||||
/* this will take care of painting every child */
|
/* this will take care of painting every child */
|
||||||
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (self);
|
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (self);
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include "clutter-behaviour-rotate.h"
|
#include "clutter-behaviour-rotate.h"
|
||||||
#include "clutter-behaviour-scale.h"
|
#include "clutter-behaviour-scale.h"
|
||||||
#include "clutter-binding-pool.h"
|
#include "clutter-binding-pool.h"
|
||||||
|
#include "clutter-cairo-texture.h"
|
||||||
#include "clutter-child-meta.h"
|
#include "clutter-child-meta.h"
|
||||||
#include "clutter-clone-texture.h"
|
#include "clutter-clone-texture.h"
|
||||||
#include "clutter-color.h"
|
#include "clutter-color.h"
|
||||||
|
@ -520,7 +520,7 @@ fi
|
|||||||
AC_SUBST(JSON_PREFIX)
|
AC_SUBST(JSON_PREFIX)
|
||||||
AM_CONDITIONAL(LOCAL_JSON_GLIB, test "x$have_json" = "xno")
|
AM_CONDITIONAL(LOCAL_JSON_GLIB, test "x$have_json" = "xno")
|
||||||
|
|
||||||
CLUTTER_REQUIRES="pangocairo >= 1.18 gobject-2.0 >= 2.16 gthread-2.0 gmodule-no-export-2.0 $BACKEND_PC_FILES $JSON_GLIB_PC"
|
CLUTTER_REQUIRES="cairo >= 1.4 pangocairo >= 1.18 gobject-2.0 >= 2.16 gthread-2.0 gmodule-no-export-2.0 $BACKEND_PC_FILES $JSON_GLIB_PC"
|
||||||
|
|
||||||
if test "x$imagebackend" = "xgdk-pixbuf"; then
|
if test "x$imagebackend" = "xgdk-pixbuf"; then
|
||||||
CLUTTER_REQUIRES="$CLUTTER_REQUIRES gdk-pixbuf-2.0"
|
CLUTTER_REQUIRES="$CLUTTER_REQUIRES gdk-pixbuf-2.0"
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
<xi:include href="xml/clutter-rectangle.xml"/>
|
<xi:include href="xml/clutter-rectangle.xml"/>
|
||||||
<xi:include href="xml/clutter-texture.xml"/>
|
<xi:include href="xml/clutter-texture.xml"/>
|
||||||
<xi:include href="xml/clutter-clone-texture.xml"/>
|
<xi:include href="xml/clutter-clone-texture.xml"/>
|
||||||
|
<xi:include href="xml/clutter-cairo-texture.xml"/>
|
||||||
<xi:include href="xml/clutter-label.xml"/>
|
<xi:include href="xml/clutter-label.xml"/>
|
||||||
<xi:include href="xml/clutter-entry.xml"/>
|
<xi:include href="xml/clutter-entry.xml"/>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
@ -702,6 +702,7 @@ clutter_path_add_rel_curve_to
|
|||||||
clutter_path_add_close
|
clutter_path_add_close
|
||||||
clutter_path_add_string
|
clutter_path_add_string
|
||||||
clutter_path_add_node
|
clutter_path_add_node
|
||||||
|
clutter_path_add_cairo_path
|
||||||
clutter_path_get_n_nodes
|
clutter_path_get_n_nodes
|
||||||
clutter_path_get_node
|
clutter_path_get_node
|
||||||
clutter_path_get_nodes
|
clutter_path_get_nodes
|
||||||
@ -711,6 +712,7 @@ clutter_path_remove_node
|
|||||||
clutter_path_replace_node
|
clutter_path_replace_node
|
||||||
clutter_path_get_description
|
clutter_path_get_description
|
||||||
clutter_path_set_description
|
clutter_path_set_description
|
||||||
|
clutter_path_to_cairo_path
|
||||||
clutter_path_clear
|
clutter_path_clear
|
||||||
clutter_path_get_position
|
clutter_path_get_position
|
||||||
clutter_path_get_length
|
clutter_path_get_length
|
||||||
@ -1629,3 +1631,32 @@ clutter_binding_pool_unblock_action
|
|||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
clutter_binding_pool_activate
|
clutter_binding_pool_activate
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<TITLE>ClutterCairoTexture</TITLE>
|
||||||
|
<FILE>clutter-cairo-texture</FILE>
|
||||||
|
ClutterCairoTexture
|
||||||
|
ClutterCairoTextureClass
|
||||||
|
clutter_cairo_texture_new
|
||||||
|
clutter_cairo_texture_set_surface_size
|
||||||
|
clutter_cairo_texture_get_surface_size
|
||||||
|
|
||||||
|
<SUBSECTION>
|
||||||
|
clutter_cairo_texture_create
|
||||||
|
clutter_cairo_texture_create_region
|
||||||
|
|
||||||
|
<SUBSECTION>
|
||||||
|
clutter_cairo_set_source_color
|
||||||
|
|
||||||
|
<SUBSECTION Standard>
|
||||||
|
CLUTTER_TYPE_CAIRO_TEXTURE
|
||||||
|
CLUTTER_CAIRO_TEXTURE
|
||||||
|
CLUTTER_IS_CAIRO_TEXTURE
|
||||||
|
CLUTTER_CAIRO_TEXTURE_CLASS
|
||||||
|
CLUTTER_IS_CAIRO_TEXTURE_CLASS
|
||||||
|
CLUTTER_CAIRO_TEXTURE_GET_CLASS
|
||||||
|
|
||||||
|
<SUBSECTION Private>
|
||||||
|
ClutterCairoTexturePrivate
|
||||||
|
clutter_cairo_texture_get_type
|
||||||
|
</SECTION>
|
||||||
|
@ -28,3 +28,4 @@ clutter_list_model_get_type
|
|||||||
clutter_score_get_type
|
clutter_score_get_type
|
||||||
clutter_shader_get_type
|
clutter_shader_get_type
|
||||||
clutter_child_meta_get_type
|
clutter_child_meta_get_type
|
||||||
|
clutter_cairo_texture_get_type
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <clutter/clutter.h>
|
#include <clutter/clutter.h>
|
||||||
|
#include <cairo/cairo.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@ -26,16 +27,19 @@ struct _CallbackData
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const char path_desc[] =
|
static const char path_desc[] =
|
||||||
"M 21 22 m 23 24 "
|
"M 21 22 "
|
||||||
"L 25 26 l 27 28 "
|
"L 25 26 "
|
||||||
"C 29 30 31 32 33 34 c 35 36 37 38 39 40 "
|
"C 29 30 31 32 33 34 "
|
||||||
|
"m 23 24 "
|
||||||
|
"l 27 28 "
|
||||||
|
"c 35 36 37 38 39 40 "
|
||||||
"z";
|
"z";
|
||||||
static const ClutterPathNode path_nodes[] =
|
static const ClutterPathNode path_nodes[] =
|
||||||
{ { CLUTTER_PATH_MOVE_TO, { { 21, 22 }, { 0, 0 }, { 0, 0 } } },
|
{ { CLUTTER_PATH_MOVE_TO, { { 21, 22 }, { 0, 0 }, { 0, 0 } } },
|
||||||
{ CLUTTER_PATH_REL_MOVE_TO, { { 23, 24 }, { 0, 0 }, { 0, 0 } } },
|
|
||||||
{ CLUTTER_PATH_LINE_TO, { { 25, 26 }, { 0, 0 }, { 0, 0 } } },
|
{ CLUTTER_PATH_LINE_TO, { { 25, 26 }, { 0, 0 }, { 0, 0 } } },
|
||||||
{ CLUTTER_PATH_REL_LINE_TO, { { 27, 28 }, { 0, 0 }, { 0, 0 } } },
|
|
||||||
{ CLUTTER_PATH_CURVE_TO, { { 29, 30 }, { 31, 32 }, { 33, 34 } } },
|
{ CLUTTER_PATH_CURVE_TO, { { 29, 30 }, { 31, 32 }, { 33, 34 } } },
|
||||||
|
{ CLUTTER_PATH_REL_MOVE_TO, { { 23, 24 }, { 0, 0 }, { 0, 0 } } },
|
||||||
|
{ CLUTTER_PATH_REL_LINE_TO, { { 27, 28 }, { 0, 0 }, { 0, 0 } } },
|
||||||
{ CLUTTER_PATH_REL_CURVE_TO, { { 35, 36 }, { 37, 38 }, { 39, 40 } } },
|
{ CLUTTER_PATH_REL_CURVE_TO, { { 35, 36 }, { 37, 38 }, { 39, 40 } } },
|
||||||
{ CLUTTER_PATH_CLOSE, { { 0, 0 }, { 0, 0 }, { 0, 0 } } } };
|
{ CLUTTER_PATH_CLOSE, { { 0, 0 }, { 0, 0 }, { 0, 0 } } } };
|
||||||
|
|
||||||
@ -391,6 +395,95 @@ path_test_get_description (CallbackData *data)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
path_test_convert_to_cairo_path (CallbackData *data)
|
||||||
|
{
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
cairo_t *cr;
|
||||||
|
cairo_path_t *cpath;
|
||||||
|
guint i, j;
|
||||||
|
ClutterKnot path_start = { 0, 0 }, last_point = { 0, 0 };
|
||||||
|
|
||||||
|
/* Create a temporary image surface and context to hold the cairo
|
||||||
|
path */
|
||||||
|
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 10, 10);
|
||||||
|
cr = cairo_create (surface);
|
||||||
|
|
||||||
|
/* Convert to a cairo path */
|
||||||
|
clutter_path_to_cairo_path (data->path, cr);
|
||||||
|
|
||||||
|
/* Get a copy of the cairo path data */
|
||||||
|
cpath = cairo_copy_path (cr);
|
||||||
|
|
||||||
|
/* Convert back to a clutter path */
|
||||||
|
clutter_path_clear (data->path);
|
||||||
|
clutter_path_add_cairo_path (data->path, cpath);
|
||||||
|
|
||||||
|
/* The relative nodes will have been converted to absolute so we
|
||||||
|
need to reflect this in the node array for comparison */
|
||||||
|
for (i = 0; i < data->n_nodes; i++)
|
||||||
|
{
|
||||||
|
switch (data->nodes[i].type)
|
||||||
|
{
|
||||||
|
case CLUTTER_PATH_MOVE_TO:
|
||||||
|
path_start = last_point = data->nodes[i].points[0];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_PATH_LINE_TO:
|
||||||
|
last_point = data->nodes[i].points[0];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_PATH_CURVE_TO:
|
||||||
|
last_point = data->nodes[i].points[2];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_PATH_REL_MOVE_TO:
|
||||||
|
last_point.x += data->nodes[i].points[0].x;
|
||||||
|
last_point.y += data->nodes[i].points[0].y;
|
||||||
|
data->nodes[i].points[0] = last_point;
|
||||||
|
data->nodes[i].type = CLUTTER_PATH_MOVE_TO;
|
||||||
|
path_start = last_point;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_PATH_REL_LINE_TO:
|
||||||
|
last_point.x += data->nodes[i].points[0].x;
|
||||||
|
last_point.y += data->nodes[i].points[0].y;
|
||||||
|
data->nodes[i].points[0] = last_point;
|
||||||
|
data->nodes[i].type = CLUTTER_PATH_LINE_TO;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_PATH_REL_CURVE_TO:
|
||||||
|
for (j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
data->nodes[i].points[j].x += last_point.x;
|
||||||
|
data->nodes[i].points[j].y += last_point.y;
|
||||||
|
}
|
||||||
|
last_point = data->nodes[i].points[2];
|
||||||
|
data->nodes[i].type = CLUTTER_PATH_CURVE_TO;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_PATH_CLOSE:
|
||||||
|
last_point = path_start;
|
||||||
|
|
||||||
|
/* Cairo always adds a move to after every close so we need
|
||||||
|
to insert one here */
|
||||||
|
memmove (data->nodes + i + 2, data->nodes + i + 1,
|
||||||
|
(data->n_nodes - i - 1) * sizeof (ClutterPathNode));
|
||||||
|
data->nodes[i + 1].type = CLUTTER_PATH_MOVE_TO;
|
||||||
|
data->nodes[i + 1].points[0] = last_point;
|
||||||
|
data->n_nodes++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the cairo resources */
|
||||||
|
cairo_path_destroy (cpath);
|
||||||
|
cairo_destroy (cr);
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
float_fuzzy_equals (float fa, float fb)
|
float_fuzzy_equals (float fa, float fb)
|
||||||
{
|
{
|
||||||
@ -523,6 +616,7 @@ path_tests[] =
|
|||||||
{ "Replace a node", path_test_replace },
|
{ "Replace a node", path_test_replace },
|
||||||
{ "Set description", path_test_set_description },
|
{ "Set description", path_test_set_description },
|
||||||
{ "Get description", path_test_get_description },
|
{ "Get description", path_test_get_description },
|
||||||
|
{ "Convert to cairo path and back", path_test_convert_to_cairo_path },
|
||||||
{ "Clear", path_test_clear },
|
{ "Clear", path_test_clear },
|
||||||
{ "Get position", path_test_get_position },
|
{ "Get position", path_test_get_position },
|
||||||
{ "Check node boxed type", path_test_boxed_type },
|
{ "Check node boxed type", path_test_boxed_type },
|
||||||
|
Loading…
Reference in New Issue
Block a user