Merge branch 'master' into cogl-float

This commit is contained in:
Robert Bragg 2009-01-08 11:48:00 +00:00
commit 378ca42d5b
72 changed files with 6664 additions and 5198 deletions

2
.gitignore vendored
View File

@ -111,6 +111,7 @@ stamp-h1
/tests/interactive/test-easing /tests/interactive/test-easing
/tests/interactive/test-interactive /tests/interactive/test-interactive
/tests/interactive/test-binding-pool /tests/interactive/test-binding-pool
/tests/interactive/test-text-field
/tests/interactive/redhand.png /tests/interactive/redhand.png
/tests/interactive/test-script.json /tests/interactive/test-script.json
/tests/conform/test-conformance /tests/conform/test-conformance
@ -158,6 +159,7 @@ stamp-h1
/clutter/x11/stamp-clutter-x11-enum-types.h /clutter/x11/stamp-clutter-x11-enum-types.h
/po/Makefile.in.in /po/Makefile.in.in
/po/POTFILES /po/POTFILES
/po/*.pot
*.swn *.swn
*.swo *.swo
*.swp *.swp

View File

@ -64,7 +64,6 @@ source_h = \
$(srcdir)/clutter-container.h \ $(srcdir)/clutter-container.h \
$(srcdir)/clutter-deprecated.h \ $(srcdir)/clutter-deprecated.h \
$(srcdir)/clutter-effect.h \ $(srcdir)/clutter-effect.h \
$(srcdir)/clutter-entry.h \
$(srcdir)/clutter-event.h \ $(srcdir)/clutter-event.h \
$(srcdir)/clutter-feature.h \ $(srcdir)/clutter-feature.h \
$(srcdir)/clutter-fixed.h \ $(srcdir)/clutter-fixed.h \
@ -72,7 +71,6 @@ source_h = \
$(srcdir)/clutter-group.h \ $(srcdir)/clutter-group.h \
$(srcdir)/clutter-interval.h \ $(srcdir)/clutter-interval.h \
$(srcdir)/clutter-keysyms.h \ $(srcdir)/clutter-keysyms.h \
$(srcdir)/clutter-label.h \
$(srcdir)/clutter-list-model.h \ $(srcdir)/clutter-list-model.h \
$(srcdir)/clutter-main.h \ $(srcdir)/clutter-main.h \
$(srcdir)/clutter-media.h \ $(srcdir)/clutter-media.h \
@ -87,6 +85,7 @@ source_h = \
$(srcdir)/clutter-stage.h \ $(srcdir)/clutter-stage.h \
$(srcdir)/clutter-stage-manager.h \ $(srcdir)/clutter-stage-manager.h \
$(srcdir)/clutter-texture.h \ $(srcdir)/clutter-texture.h \
$(srcdir)/clutter-text.h \
$(srcdir)/clutter-timeline.h \ $(srcdir)/clutter-timeline.h \
$(srcdir)/clutter-timeout-pool.h \ $(srcdir)/clutter-timeout-pool.h \
$(srcdir)/clutter-types.h \ $(srcdir)/clutter-types.h \
@ -155,7 +154,6 @@ source_c = \
clutter-color.c \ clutter-color.c \
clutter-container.c \ clutter-container.c \
clutter-effect.c \ clutter-effect.c \
clutter-entry.c \
clutter-enum-types.c \ clutter-enum-types.c \
clutter-event.c \ clutter-event.c \
clutter-feature.c \ clutter-feature.c \
@ -164,7 +162,6 @@ source_c = \
clutter-group.c \ clutter-group.c \
clutter-id-pool.c \ clutter-id-pool.c \
clutter-interval.c \ clutter-interval.c \
clutter-label.c \
clutter-list-model.c \ clutter-list-model.c \
clutter-main.c \ clutter-main.c \
clutter-marshal.c \ clutter-marshal.c \
@ -182,6 +179,7 @@ source_c = \
clutter-stage-manager.c \ clutter-stage-manager.c \
clutter-stage-window.c \ clutter-stage-window.c \
clutter-texture.c \ clutter-texture.c \
clutter-text.c \
clutter-timeline.c \ clutter-timeline.c \
clutter-timeout-pool.c \ clutter-timeout-pool.c \
clutter-units.c \ clutter-units.c \

View File

@ -221,7 +221,9 @@ struct _ClutterActorPrivate
/* cached allocation is invalid (request has changed, probably) */ /* cached allocation is invalid (request has changed, probably) */
guint needs_allocation : 1; guint needs_allocation : 1;
guint show_on_set_parent : 1;
guint has_clip : 1; guint has_clip : 1;
ClutterUnit clip[4]; ClutterUnit clip[4];
/* Rotation angles */ /* Rotation angles */
@ -260,7 +262,7 @@ struct _ClutterActorPrivate
ShaderData *shader_data; ShaderData *shader_data;
gboolean show_on_set_parent; PangoContext *pango_context;
}; };
enum enum
@ -772,6 +774,24 @@ clutter_actor_real_allocate (ClutterActor *self,
g_object_thaw_notify (G_OBJECT (self)); g_object_thaw_notify (G_OBJECT (self));
} }
/* like ClutterVertex, but using CoglFixed and with a w component */
typedef struct {
CoglFixed x;
CoglFixed y;
CoglFixed z;
CoglFixed w;
} fixed_vertex_t;
/* copies a fixed vertex into a ClutterVertex */
static inline void
fixed_vertex_to_units (const fixed_vertex_t *f,
ClutterVertex *u)
{
u->x = CLUTTER_UNITS_FROM_FIXED (f->x);
u->y = CLUTTER_UNITS_FROM_FIXED (f->y);
u->z = CLUTTER_UNITS_FROM_FIXED (f->z);
}
/* /*
* Utility functions for manipulating transformation matrix * Utility functions for manipulating transformation matrix
* *
@ -779,35 +799,39 @@ clutter_actor_real_allocate (ClutterActor *self,
*/ */
#define M(m,row,col) (m)[(col) * 4 + (row)] #define M(m,row,col) (m)[(col) * 4 + (row)]
/* Transform point (x,y,z) by matrix */ /* Transforms a vertex using the passed matrix; vertex is
static void * an in-out parameter
mtx_transform (ClutterFixed m[16], */
ClutterFixed *x, ClutterFixed *y, ClutterFixed *z, static inline void
ClutterFixed *w) mtx_transform (const ClutterFixed m[],
fixed_vertex_t *vertex)
{ {
ClutterFixed _x, _y, _z, _w; ClutterFixed _x, _y, _z, _w;
_x = *x;
_y = *y;
_z = *z;
_w = *w;
/* We care lot about precision here, so have to use QMUL */ _x = vertex->x;
*x = COGL_FIXED_MUL (M (m, 0, 0), _x) _y = vertex->y;
_z = vertex->z;
_w = vertex->w;
/* We care lot about precision here, so have to use MUL instead
* of FAST_MUL
*/
vertex->x = COGL_FIXED_MUL (M (m, 0, 0), _x)
+ COGL_FIXED_MUL (M (m, 0, 1), _y) + COGL_FIXED_MUL (M (m, 0, 1), _y)
+ COGL_FIXED_MUL (M (m, 0, 2), _z) + COGL_FIXED_MUL (M (m, 0, 2), _z)
+ COGL_FIXED_MUL (M (m, 0, 3), _w); + COGL_FIXED_MUL (M (m, 0, 3), _w);
*y = COGL_FIXED_MUL (M (m, 1, 0), _x) vertex->y = COGL_FIXED_MUL (M (m, 1, 0), _x)
+ COGL_FIXED_MUL (M (m, 1, 1), _y) + COGL_FIXED_MUL (M (m, 1, 1), _y)
+ COGL_FIXED_MUL (M (m, 1, 2), _z) + COGL_FIXED_MUL (M (m, 1, 2), _z)
+ COGL_FIXED_MUL (M (m, 1, 3), _w); + COGL_FIXED_MUL (M (m, 1, 3), _w);
*z = COGL_FIXED_MUL (M (m, 2, 0), _x) vertex->z = COGL_FIXED_MUL (M (m, 2, 0), _x)
+ COGL_FIXED_MUL (M (m, 2, 1), _y) + COGL_FIXED_MUL (M (m, 2, 1), _y)
+ COGL_FIXED_MUL (M (m, 2, 2), _z) + COGL_FIXED_MUL (M (m, 2, 2), _z)
+ COGL_FIXED_MUL (M (m, 2, 3), _w); + COGL_FIXED_MUL (M (m, 2, 3), _w);
*w = COGL_FIXED_MUL (M (m, 3, 0), _x) vertex->w = COGL_FIXED_MUL (M (m, 3, 0), _x)
+ COGL_FIXED_MUL (M (m, 3, 1), _y) + COGL_FIXED_MUL (M (m, 3, 1), _y)
+ COGL_FIXED_MUL (M (m, 3, 2), _z) + COGL_FIXED_MUL (M (m, 3, 2), _z)
+ COGL_FIXED_MUL (M (m, 3, 3), _w); + COGL_FIXED_MUL (M (m, 3, 3), _w);
@ -819,9 +843,70 @@ mtx_transform (ClutterFixed m[16],
#undef M #undef M
/* Help macros to scale from OpenGL <-1,1> coordinates system to our
* X-window based <0,window-size> coordinates
*/
#define MTX_GL_SCALE_X(x,w,v1,v2) (COGL_FIXED_MUL (((COGL_FIXED_DIV ((x), (w)) + COGL_FIXED_1) >> 1), (v1)) + (v2))
#define MTX_GL_SCALE_Y(y,w,v1,v2) ((v1) - COGL_FIXED_MUL (((COGL_FIXED_DIV ((y), (w)) + COGL_FIXED_1) >> 1), (v1)) + (v2))
#define MTX_GL_SCALE_Z(z,w,v1,v2) (MTX_GL_SCALE_X ((z), (w), (v1), (v2)))
/* transforms a 4-tuple of coordinates using @matrix and
* places the result into a fixed @vertex
*/
static inline void
fixed_vertex_transform (const ClutterFixed matrix[],
ClutterFixed x,
ClutterFixed y,
ClutterFixed z,
ClutterFixed w,
fixed_vertex_t *vertex)
{
fixed_vertex_t tmp = { 0, };
tmp.x = x;
tmp.y = y;
tmp.z = z;
tmp.w = w;
mtx_transform (matrix, &tmp);
*vertex = tmp;
}
/* scales a fixed @vertex using @matrix and @viewport, and
* transforms the result into ClutterUnits, filling @vertex_p
*/
static inline void
fixed_vertex_scale (const ClutterFixed matrix[],
const fixed_vertex_t *vertex,
const ClutterFixed viewport[],
ClutterVertex *vertex_p)
{
ClutterFixed v_x, v_y, v_width, v_height;
fixed_vertex_t tmp = { 0, };
tmp = *vertex;
mtx_transform (matrix, &tmp);
v_x = viewport[0];
v_y = viewport[1];
v_width = viewport[2];
v_height = viewport[3];
tmp.x = MTX_GL_SCALE_X (tmp.x, tmp.w, v_width, v_x);
tmp.y = MTX_GL_SCALE_Y (tmp.y, tmp.w, v_height, v_y);
tmp.z = MTX_GL_SCALE_Z (tmp.z, tmp.w, v_width, v_x);
tmp.w = 0;
fixed_vertex_to_units (&tmp, vertex_p);
}
/* Applies the transforms associated with this actor and its ancestors, /* Applies the transforms associated with this actor and its ancestors,
* retrieves the resulting OpenGL modelview matrix, and uses the matrix * retrieves the resulting OpenGL modelview matrix, and uses the matrix
* to transform the supplied point * to transform the supplied point
*
* The point coordinates are in-out parameters
*/ */
static void static void
clutter_actor_transform_point_relative (ClutterActor *actor, clutter_actor_transform_point_relative (ClutterActor *actor,
@ -832,14 +917,33 @@ clutter_actor_transform_point_relative (ClutterActor *actor,
ClutterUnit *w) ClutterUnit *w)
{ {
ClutterFixed mtx[16]; ClutterFixed mtx[16];
fixed_vertex_t vertex = { 0, };
vertex.x = (x != NULL) ? CLUTTER_UNITS_TO_FIXED (*x) : 0;
vertex.y = (y != NULL) ? CLUTTER_UNITS_TO_FIXED (*y) : 0;
vertex.z = (z != NULL) ? CLUTTER_UNITS_TO_FIXED (*z) : 0;
vertex.w = (w != NULL) ? CLUTTER_UNITS_TO_FIXED (*w) : 0;
cogl_push_matrix(); cogl_push_matrix();
_clutter_actor_apply_modelview_transform_recursive (actor, ancestor); _clutter_actor_apply_modelview_transform_recursive (actor, ancestor);
cogl_get_modelview_matrix (mtx); cogl_get_modelview_matrix (mtx);
mtx_transform (mtx, x, y, z, w); mtx_transform (mtx, &vertex);
cogl_pop_matrix(); cogl_pop_matrix();
if (x)
*x = CLUTTER_UNITS_FROM_FIXED (vertex.x);
if (y)
*y = CLUTTER_UNITS_FROM_FIXED (vertex.y);
if (z)
*z = CLUTTER_UNITS_FROM_FIXED (vertex.z);
if (w)
*w = CLUTTER_UNITS_FROM_FIXED (vertex.w);
} }
/* Applies the transforms associated with this actor and its ancestors, /* Applies the transforms associated with this actor and its ancestors,
@ -854,22 +958,34 @@ clutter_actor_transform_point (ClutterActor *actor,
ClutterUnit *w) ClutterUnit *w)
{ {
ClutterFixed mtx[16]; ClutterFixed mtx[16];
fixed_vertex_t vertex = { 0, };
vertex.x = (x != NULL) ? CLUTTER_UNITS_TO_FIXED (*x) : 0;
vertex.y = (y != NULL) ? CLUTTER_UNITS_TO_FIXED (*y) : 0;
vertex.z = (z != NULL) ? CLUTTER_UNITS_TO_FIXED (*z) : 0;
vertex.w = (w != NULL) ? CLUTTER_UNITS_TO_FIXED (*w) : 0;
cogl_push_matrix(); cogl_push_matrix();
_clutter_actor_apply_modelview_transform_recursive (actor, NULL); _clutter_actor_apply_modelview_transform_recursive (actor, NULL);
cogl_get_modelview_matrix (mtx); cogl_get_modelview_matrix (mtx);
mtx_transform (mtx, x, y, z, w); mtx_transform (mtx, &vertex);
cogl_pop_matrix(); cogl_pop_matrix();
}
/* Help macros to scale from OpenGL <-1,1> coordinates system to our if (x)
* X-window based <0,window-size> coordinates *x = CLUTTER_UNITS_FROM_FIXED (vertex.x);
*/
#define MTX_GL_SCALE_X(x,w,v1,v2) (COGL_FIXED_MUL (((COGL_FIXED_DIV ((x), (w)) + COGL_FIXED_1) >> 1), (v1)) + (v2)) if (y)
#define MTX_GL_SCALE_Y(y,w,v1,v2) ((v1) - COGL_FIXED_MUL (((COGL_FIXED_DIV ((y), (w)) + COGL_FIXED_1) >> 1), (v1)) + (v2)) *y = CLUTTER_UNITS_FROM_FIXED (vertex.y);
#define MTX_GL_SCALE_Z(z,w,v1,v2) (MTX_GL_SCALE_X ((z), (w), (v1), (v2)))
if (z)
*z = CLUTTER_UNITS_FROM_FIXED (vertex.z);
if (w)
*w = CLUTTER_UNITS_FROM_FIXED (vertex.w);
}
/** /**
* clutter_actor_apply_relative_transform_to_point: * clutter_actor_apply_relative_transform_to_point:
@ -896,21 +1012,22 @@ clutter_actor_apply_relative_transform_to_point (ClutterActor *self,
const ClutterVertex *point, const ClutterVertex *point,
ClutterVertex *vertex) ClutterVertex *vertex)
{ {
ClutterVertex tmp = { 0, };
ClutterFixed v[4]; ClutterFixed v[4];
ClutterFixed w = COGL_FIXED_1; ClutterFixed x, y, z, w;
g_return_if_fail (CLUTTER_IS_ACTOR (self)); g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (ancestor == NULL || CLUTTER_IS_ACTOR (ancestor)); g_return_if_fail (ancestor == NULL || CLUTTER_IS_ACTOR (ancestor));
g_return_if_fail (point != NULL); g_return_if_fail (point != NULL);
g_return_if_fail (vertex != NULL); g_return_if_fail (vertex != NULL);
tmp = *point; x = CLUTTER_UNITS_TO_FIXED (vertex->x);
y = CLUTTER_UNITS_TO_FIXED (vertex->y);
z = CLUTTER_UNITS_TO_FIXED (vertex->z);
w = COGL_FIXED_1;
/* First we tranform the point using the OpenGL modelview matrix */ /* First we tranform the point using the OpenGL modelview matrix */
clutter_actor_transform_point_relative (self, ancestor, clutter_actor_transform_point_relative (self, ancestor,
&tmp.x, &tmp.y, &tmp.z, &x, &y, &z, &w);
&w);
cogl_get_viewport (v); cogl_get_viewport (v);
@ -918,9 +1035,12 @@ clutter_actor_apply_relative_transform_to_point (ClutterActor *self,
* The w[3] parameter should always be 1.0 here, so we ignore it; otherwise * The w[3] parameter should always be 1.0 here, so we ignore it; otherwise
* we would have to divide the original verts with it. * we would have to divide the original verts with it.
*/ */
vertex->x = COGL_FIXED_MUL ((tmp.x + COGL_FIXED_0_5), v[2]); vertex->x =
vertex->y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - tmp.y), v[3]); CLUTTER_UNITS_FROM_FIXED (COGL_FIXED_MUL ((x + COGL_FIXED_0_5), v[2]));
vertex->z = COGL_FIXED_MUL ((tmp.z + COGL_FIXED_0_5), v[2]); vertex->y =
CLUTTER_UNITS_FROM_FIXED (COGL_FIXED_MUL ((COGL_FIXED_0_5 - y), v[3]));
vertex->z =
CLUTTER_UNITS_FROM_FIXED (COGL_FIXED_MUL ((z + COGL_FIXED_0_5), v[2]));
} }
/** /**
@ -940,30 +1060,35 @@ clutter_actor_apply_transform_to_point (ClutterActor *self,
const ClutterVertex *point, const ClutterVertex *point,
ClutterVertex *vertex) ClutterVertex *vertex)
{ {
ClutterVertex tmp = { 0, };
ClutterFixed mtx_p[16]; ClutterFixed mtx_p[16];
ClutterFixed v[4]; ClutterFixed v[4];
ClutterFixed w = COGL_FIXED_1; fixed_vertex_t tmp = { 0, };
g_return_if_fail (CLUTTER_IS_ACTOR (self)); g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (point != NULL); g_return_if_fail (point != NULL);
g_return_if_fail (vertex != NULL); g_return_if_fail (vertex != NULL);
tmp = *point; tmp.x = CLUTTER_UNITS_TO_FIXED (vertex->x);
tmp.y = CLUTTER_UNITS_TO_FIXED (vertex->y);
tmp.z = CLUTTER_UNITS_TO_FIXED (vertex->z);
tmp.w = COGL_FIXED_1;
/* First we tranform the point using the OpenGL modelview matrix */ /* First we tranform the point using the OpenGL modelview matrix */
clutter_actor_transform_point (self, &tmp.x, &tmp.y, &tmp.z, &w); clutter_actor_transform_point (self, &tmp.x, &tmp.y, &tmp.z, &tmp.w);
cogl_get_projection_matrix (mtx_p); cogl_get_projection_matrix (mtx_p);
cogl_get_viewport (v); cogl_get_viewport (v);
/* Now, transform it again with the projection matrix */ /* Now, transform it again with the projection matrix */
mtx_transform (mtx_p, &tmp.x, &tmp.y, &tmp.z, &w); mtx_transform (mtx_p, &tmp);
/* Finaly translate from OpenGL coords to window coords */ /* Finaly translate from OpenGL coords to window coords */
vertex->x = MTX_GL_SCALE_X (tmp.x, w, v[2], v[0]); vertex->x =
vertex->y = MTX_GL_SCALE_Y (tmp.y, w, v[3], v[1]); CLUTTER_UNITS_FROM_FIXED (MTX_GL_SCALE_X (tmp.x, tmp.w, v[2], v[0]));
vertex->z = MTX_GL_SCALE_Z (tmp.z, w, v[2], v[0]); vertex->y =
CLUTTER_UNITS_FROM_FIXED (MTX_GL_SCALE_Y (tmp.y, tmp.w, v[3], v[1]));
vertex->z =
CLUTTER_UNITS_FROM_FIXED (MTX_GL_SCALE_Z (tmp.z, tmp.w, v[2], v[0]));
} }
/* Recursively tranform supplied vertices with the tranform for the current /* Recursively tranform supplied vertices with the tranform for the current
@ -973,64 +1098,25 @@ clutter_actor_apply_transform_to_point (ClutterActor *self,
static void static void
clutter_actor_transform_vertices_relative (ClutterActor *self, clutter_actor_transform_vertices_relative (ClutterActor *self,
ClutterActor *ancestor, ClutterActor *ancestor,
ClutterVertex verts[4], fixed_vertex_t vertices[])
ClutterFixed w[4])
{ {
ClutterActorPrivate *priv = self->priv;
ClutterFixed mtx[16]; ClutterFixed mtx[16];
ClutterFixed _x, _y, _z, _w; ClutterFixed width, height;
width = CLUTTER_UNITS_TO_FIXED (priv->allocation.x2 - priv->allocation.x1);
height = CLUTTER_UNITS_TO_FIXED (priv->allocation.y2 - priv->allocation.y1);
cogl_push_matrix(); cogl_push_matrix();
_clutter_actor_apply_modelview_transform_recursive (self, ancestor); _clutter_actor_apply_modelview_transform_recursive (self, ancestor);
cogl_get_modelview_matrix (mtx); cogl_get_modelview_matrix (mtx);
_x = 0; fixed_vertex_transform (mtx, 0, 0, 0, COGL_FIXED_1, &vertices[0]);
_y = 0; fixed_vertex_transform (mtx, width, 0, 0, COGL_FIXED_1, &vertices[1]);
_z = 0; fixed_vertex_transform (mtx, 0, height, 0, COGL_FIXED_1, &vertices[2]);
_w = COGL_FIXED_1; fixed_vertex_transform (mtx, width, height, 0, COGL_FIXED_1, &vertices[3]);
mtx_transform (mtx, &_x, &_y, &_z, &_w);
verts[0].x = _x;
verts[0].y = _y;
verts[0].z = _z;
w[0] = _w;
_x = self->priv->allocation.x2 - self->priv->allocation.x1;
_y = 0;
_z = 0;
_w = COGL_FIXED_1;
mtx_transform (mtx, &_x, &_y, &_z, &_w);
verts[1].x = _x;
verts[1].y = _y;
verts[1].z = _z;
w[1] = _w;
_x = 0;
_y = self->priv->allocation.y2 - self->priv->allocation.y1;
_z = 0;
_w = COGL_FIXED_1;
mtx_transform (mtx, &_x, &_y, &_z, &_w);
verts[2].x = _x;
verts[2].y = _y;
verts[2].z = _z;
w[2] = _w;
_x = self->priv->allocation.x2 - self->priv->allocation.x1;
_y = self->priv->allocation.y2 - self->priv->allocation.y1;
_z = 0;
_w = COGL_FIXED_1;
mtx_transform (mtx, &_x, &_y, &_z, &_w);
verts[3].x = _x;
verts[3].y = _y;
verts[3].z = _z;
w[3] = _w;
cogl_pop_matrix(); cogl_pop_matrix();
} }
@ -1048,9 +1134,12 @@ clutter_actor_transform_and_project_box (ClutterActor *self,
ClutterActor *stage; ClutterActor *stage;
ClutterFixed mtx[16]; ClutterFixed mtx[16];
ClutterFixed mtx_p[16]; ClutterFixed mtx_p[16];
ClutterFixed _x, _y, _z, _w;
ClutterFixed w[4];
ClutterFixed v[4]; ClutterFixed v[4];
ClutterFixed width, height;
fixed_vertex_t vertices[4];
width = CLUTTER_UNITS_TO_FIXED (box->x2 - box->x1);
height = CLUTTER_UNITS_TO_FIXED (box->y2 - box->y1);
/* We essentially have to dupe some code from clutter_redraw() here /* We essentially have to dupe some code from clutter_redraw() here
* to make sure GL Matrices etc are initialised if we're called and we * to make sure GL Matrices etc are initialised if we're called and we
@ -1071,102 +1160,25 @@ clutter_actor_transform_and_project_box (ClutterActor *self,
_clutter_stage_maybe_setup_viewport (CLUTTER_STAGE (stage)); _clutter_stage_maybe_setup_viewport (CLUTTER_STAGE (stage));
cogl_push_matrix(); cogl_push_matrix();
_clutter_actor_apply_modelview_transform_recursive (self, NULL); _clutter_actor_apply_modelview_transform_recursive (self, NULL);
cogl_get_modelview_matrix (mtx); cogl_get_modelview_matrix (mtx);
_x = 0; fixed_vertex_transform (mtx, 0, 0, 0, COGL_FIXED_1, &vertices[0]);
_y = 0; fixed_vertex_transform (mtx, width, 0, 0, COGL_FIXED_1, &vertices[1]);
_z = 0; fixed_vertex_transform (mtx, 0, height, 0, COGL_FIXED_1, &vertices[2]);
_w = COGL_FIXED_1; fixed_vertex_transform (mtx, width, height, 0, COGL_FIXED_1, &vertices[3]);
mtx_transform (mtx, &_x, &_y, &_z, &_w);
verts[0].x = _x;
verts[0].y = _y;
verts[0].z = _z;
w[0] = _w;
_x = box->x2 - box->x1;
_y = 0;
_z = 0;
_w = COGL_FIXED_1;
mtx_transform (mtx, &_x, &_y, &_z, &_w);
verts[1].x = _x;
verts[1].y = _y;
verts[1].z = _z;
w[1] = _w;
_x = 0;
_y = box->y2 - box->y1;
_z = 0;
_w = COGL_FIXED_1;
mtx_transform (mtx, &_x, &_y, &_z, &_w);
verts[2].x = _x;
verts[2].y = _y;
verts[2].z = _z;
w[2] = _w;
_x = box->x2 - box->x1;
_y = box->y2 - box->y1;
_z = 0;
_w = COGL_FIXED_1;
mtx_transform (mtx, &_x, &_y, &_z, &_w);
verts[3].x = _x;
verts[3].y = _y;
verts[3].z = _z;
w[3] = _w;
cogl_pop_matrix(); cogl_pop_matrix();
cogl_get_projection_matrix (mtx_p); cogl_get_projection_matrix (mtx_p);
cogl_get_viewport (v); cogl_get_viewport (v);
mtx_transform (mtx_p, fixed_vertex_scale (mtx_p, &vertices[0], v, &verts[0]);
&verts[0].x, fixed_vertex_scale (mtx_p, &vertices[1], v, &verts[1]);
&verts[0].y, fixed_vertex_scale (mtx_p, &vertices[2], v, &verts[2]);
&verts[0].z, fixed_vertex_scale (mtx_p, &vertices[3], v, &verts[3]);
&w[0]);
verts[0].x = MTX_GL_SCALE_X (verts[0].x, w[0], v[2], v[0]);
verts[0].y = MTX_GL_SCALE_Y (verts[0].y, w[0], v[3], v[1]);
verts[0].z = MTX_GL_SCALE_Z (verts[0].z, w[0], v[2], v[0]);
mtx_transform (mtx_p,
&verts[1].x,
&verts[1].y,
&verts[1].z,
&w[1]);
verts[1].x = MTX_GL_SCALE_X (verts[1].x, w[1], v[2], v[0]);
verts[1].y = MTX_GL_SCALE_Y (verts[1].y, w[1], v[3], v[1]);
verts[1].z = MTX_GL_SCALE_Z (verts[1].z, w[1], v[2], v[0]);
mtx_transform (mtx_p,
&verts[2].x,
&verts[2].y,
&verts[2].z,
&w[2]);
verts[2].x = MTX_GL_SCALE_X (verts[2].x, w[2], v[2], v[0]);
verts[2].y = MTX_GL_SCALE_Y (verts[2].y, w[2], v[3], v[1]);
verts[2].z = MTX_GL_SCALE_Z (verts[2].z, w[2], v[2], v[0]);
mtx_transform (mtx_p,
&verts[3].x,
&verts[3].y,
&verts[3].z,
&w[3]);
verts[3].x = MTX_GL_SCALE_X (verts[3].x, w[3], v[2], v[0]);
verts[3].y = MTX_GL_SCALE_Y (verts[3].y, w[3], v[3], v[1]);
verts[3].z = MTX_GL_SCALE_Z (verts[3].z, w[3], v[2], v[0]);
} }
/** /**
@ -1181,10 +1193,10 @@ clutter_actor_transform_and_project_box (ClutterActor *self,
* actor in the plane of @ancestor. The returned vertices relate to * actor in the plane of @ancestor. The returned vertices relate to
* the #ClutterActorBox coordinates as follows: * the #ClutterActorBox coordinates as follows:
* <itemizedlist> * <itemizedlist>
* <listitem><para>v[0] contains (x1, y1)</para></listitem> * <listitem><para>@verts[0] contains (x1, y1)</para></listitem>
* <listitem><para>v[1] contains (x2, y1)</para></listitem> * <listitem><para>@verts[1] contains (x2, y1)</para></listitem>
* <listitem><para>v[2] contains (x1, y2)</para></listitem> * <listitem><para>@verts[2] contains (x1, y2)</para></listitem>
* <listitem><para>v[3] contains (x2, y2)</para></listitem> * <listitem><para>@verts[3] contains (x2, y2)</para></listitem>
* </itemizedlist> * </itemizedlist>
* *
* If @ancestor is %NULL the ancestor will be the #ClutterStage. In * If @ancestor is %NULL the ancestor will be the #ClutterStage. In
@ -1197,12 +1209,13 @@ clutter_actor_transform_and_project_box (ClutterActor *self,
void void
clutter_actor_get_allocation_vertices (ClutterActor *self, clutter_actor_get_allocation_vertices (ClutterActor *self,
ClutterActor *ancestor, ClutterActor *ancestor,
ClutterVertex verts[4]) ClutterVertex verts[])
{ {
ClutterFixed v[4];
ClutterFixed w[4];
ClutterActorPrivate *priv; ClutterActorPrivate *priv;
ClutterActor *stage; ClutterActor *stage;
ClutterFixed v[4];
fixed_vertex_t vertices[4];
fixed_vertex_t tmp = { 0, };
g_return_if_fail (CLUTTER_IS_ACTOR (self)); g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (ancestor == NULL || CLUTTER_IS_ACTOR (ancestor)); g_return_if_fail (ancestor == NULL || CLUTTER_IS_ACTOR (ancestor));
@ -1234,28 +1247,33 @@ clutter_actor_get_allocation_vertices (ClutterActor *self,
if (priv->needs_allocation) if (priv->needs_allocation)
_clutter_stage_maybe_relayout (stage); _clutter_stage_maybe_relayout (stage);
clutter_actor_transform_vertices_relative (self, ancestor, verts, w); clutter_actor_transform_vertices_relative (self, ancestor, vertices);
cogl_get_viewport (v); cogl_get_viewport (v);
/* /*
* The w[3] parameter should always be 1.0 here, so we ignore it; otherwise * The w[3] parameter should always be 1.0 here, so we ignore it;
* we would have to devide the original verts with it. * otherwise we would have to divide the original verts with it.
*/ */
verts[0].x = COGL_FIXED_MUL ((verts[0].x + COGL_FIXED_0_5), v[2]); tmp.x = COGL_FIXED_MUL ((vertices[0].x + COGL_FIXED_0_5), v[2]);
verts[0].y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - verts[0].y), v[3]); tmp.y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - vertices[0].y), v[3]);
verts[0].z = COGL_FIXED_MUL ((verts[0].z + COGL_FIXED_0_5), v[2]); tmp.z = COGL_FIXED_MUL ((vertices[0].z + COGL_FIXED_0_5), v[2]);
fixed_vertex_to_units (&tmp, &verts[0]);
verts[1].x = COGL_FIXED_MUL ((verts[1].x + COGL_FIXED_0_5), v[2]); tmp.x = COGL_FIXED_MUL ((vertices[1].x + COGL_FIXED_0_5), v[2]);
verts[1].y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - verts[1].y), v[3]); tmp.y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - vertices[1].y), v[3]);
verts[1].z = COGL_FIXED_MUL ((verts[1].z + COGL_FIXED_0_5), v[2]); tmp.z = COGL_FIXED_MUL ((vertices[1].z + COGL_FIXED_0_5), v[2]);
fixed_vertex_to_units (&tmp, &verts[1]);
verts[2].x = COGL_FIXED_MUL ((verts[2].x + COGL_FIXED_0_5), v[2]); tmp.x = COGL_FIXED_MUL ((vertices[2].x + COGL_FIXED_0_5), v[2]);
verts[2].y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - verts[2].y), v[3]); tmp.y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - vertices[2].y), v[3]);
verts[2].z = COGL_FIXED_MUL ((verts[2].z + COGL_FIXED_0_5), v[2]); tmp.z = COGL_FIXED_MUL ((vertices[2].z + COGL_FIXED_0_5), v[2]);
fixed_vertex_to_units (&tmp, &verts[2]);
verts[3].x = COGL_FIXED_MUL ((verts[3].x + COGL_FIXED_0_5), v[2]); tmp.x = COGL_FIXED_MUL ((vertices[3].x + COGL_FIXED_0_5), v[2]);
verts[3].y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - verts[3].y), v[3]); tmp.y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - vertices[3].y), v[3]);
verts[3].z = COGL_FIXED_MUL ((verts[3].z + COGL_FIXED_0_5), v[2]); tmp.z = COGL_FIXED_MUL ((vertices[3].z + COGL_FIXED_0_5), v[2]);
fixed_vertex_to_units (&tmp, &verts[3]);
} }
/** /**
@ -1941,6 +1959,12 @@ clutter_actor_dispose (GObject *object)
destroy_shader_data (self); destroy_shader_data (self);
if (priv->pango_context)
{
g_object_unref (priv->pango_context);
priv->pango_context = NULL;
}
g_signal_emit (self, actor_signals[DESTROY], 0); g_signal_emit (self, actor_signals[DESTROY], 0);
G_OBJECT_CLASS (clutter_actor_parent_class)->dispose (object); G_OBJECT_CLASS (clutter_actor_parent_class)->dispose (object);
@ -6852,7 +6876,8 @@ clutter_actor_transform_stage_point (ClutterActor *self,
ClutterFixed ST[3][3]; ClutterFixed ST[3][3];
ClutterFixed RQ[3][3]; ClutterFixed RQ[3][3];
int du, dv, xi, yi; int du, dv, xi, yi;
ClutterFixed xf, yf, wf, px, py, det; ClutterUnit px, py;
ClutterFixed xf, yf, wf, det;
ClutterActorPrivate *priv; ClutterActorPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
@ -6865,11 +6890,12 @@ clutter_actor_transform_stage_point (ClutterActor *self,
* *
* http://www.cs.cmu.edu/~ph/texfund/texfund.pdf * http://www.cs.cmu.edu/~ph/texfund/texfund.pdf
* *
* and the sample implementaion at http://www.cs.cmu.edu/~ph/src/texfund/. * and the sample implementation at http://www.cs.cmu.edu/~ph/src/texfund/.
* *
* Our texture is a rectangle with origin [0,0], so we are mapping from quad * Our texture is a rectangle with origin [0, 0], so we are mapping from
* to rectangle only, which significantly simplifies things; the function * quad to rectangle only, which significantly simplifies things; the
* calls have been unrolled, and most of the math is done in fixed point. * function calls have been unrolled, and most of the math is done in fixed
* point.
*/ */
clutter_actor_get_abs_allocation_vertices (self, v); clutter_actor_get_abs_allocation_vertices (self, v);
@ -6886,9 +6912,11 @@ clutter_actor_transform_stage_point (ClutterActor *self,
#define FP2FX COGL_FIXED_FROM_FLOAT #define FP2FX COGL_FIXED_FROM_FLOAT
#define FX2FP COGL_FIXED_TO_DOUBLE #define FX2FP COGL_FIXED_TO_DOUBLE
#define UX2FP CLUTTER_UNITS_TO_FLOAT
#define UX2FX CLUTTER_UNITS_TO_FIXED
#define FP2INT CLUTTER_FLOAT_TO_INT #define FP2INT CLUTTER_FLOAT_TO_INT
#define DET2X(a,b,c,d) (COGL_FIXED_MUL (a, d) - COGL_FIXED_MUL (b, c)) #define DET2X(a,b,c,d) (COGL_FIXED_MUL ((a), (d)) - COGL_FIXED_MUL ((b), (c)))
#define DET2FP(a,b,c,d) (a*d - b*c) #define DET2FP(a,b,c,d) ((a) * (d) - (b) * (c))
/* /*
* First, find mapping from unit uv square to xy quadrilateral; this * First, find mapping from unit uv square to xy quadrilateral; this
@ -6900,20 +6928,21 @@ clutter_actor_transform_stage_point (ClutterActor *self,
py = v[0].y - v[1].y + v[3].y - v[2].y; py = v[0].y - v[1].y + v[3].y - v[2].y;
if (!px && !py) if (!px && !py)
{ /* affine transform */ {
RQ[0][0] = v[1].x - v[0].x; /* affine transform */
RQ[1][0] = v[3].x - v[1].x; RQ[0][0] = UX2FX (v[1].x - v[0].x);
RQ[2][0] = v[0].x; RQ[1][0] = UX2FX (v[3].x - v[1].x);
RQ[0][1] = v[1].y - v[0].y; RQ[2][0] = UX2FX (v[0].x);
RQ[1][1] = v[3].y - v[1].y; RQ[0][1] = UX2FX (v[1].y - v[0].y);
RQ[2][1] = v[0].y; RQ[1][1] = UX2FX (v[3].y - v[1].y);
RQ[2][1] = UX2FX (v[0].y);
RQ[0][2] = 0; RQ[0][2] = 0;
RQ[1][2] = 0; RQ[1][2] = 0;
RQ[2][2] = COGL_FIXED_1; RQ[2][2] = COGL_FIXED_1;
} }
else else
{ /* {
* projective transform /* projective transform
* *
* Must do this in floating point, as the del value can overflow the * Must do this in floating point, as the del value can overflow the
* range of ClutterFixed for large actors. * range of ClutterFixed for large actors.
@ -6923,13 +6952,12 @@ clutter_actor_transform_stage_point (ClutterActor *self,
*/ */
double dx1, dx2, dy1, dy2, del; double dx1, dx2, dy1, dy2, del;
dx1 = FX2FP (v[1].x - v[3].x); dx1 = UX2FP (v[1].x - v[3].x);
dx2 = FX2FP (v[2].x - v[3].x); dx2 = UX2FP (v[2].x - v[3].x);
dy1 = FX2FP (v[1].y - v[3].y); dy1 = UX2FP (v[1].y - v[3].y);
dy2 = FX2FP (v[2].y - v[3].y); dy2 = UX2FP (v[2].y - v[3].y);
del = DET2FP (dx1, dx2, dy1, dy2); del = DET2FP (dx1, dx2, dy1, dy2);
if (!del) if (!del)
return FALSE; return FALSE;
@ -6937,16 +6965,20 @@ clutter_actor_transform_stage_point (ClutterActor *self,
* The division here needs to be done in floating point for * The division here needs to be done in floating point for
* precisions reasons. * precisions reasons.
*/ */
RQ[0][2] = FP2FX (DET2FP (FX2FP(px),dx2, FX2FP(py),dy2) / del); RQ[0][2] = FP2FX (DET2FP (UX2FP (px), dx2, UX2FP (py), dy2) / del);
RQ[1][2] = FP2FX (DET2FP (dx1,FX2FP(px), dy1,FX2FP(py)) / del); RQ[1][2] = FP2FX (DET2FP (dx1, UX2FP (px), dy1, UX2FP (py)) / del);
RQ[1][2] = FP2FX (DET2FP(dx1,FX2FP(px), dy1,FX2FP(py))/del); RQ[1][2] = FP2FX (DET2FP (dx1, UX2FP (px), dy1, UX2FP (py)) / del);
RQ[2][2] = COGL_FIXED_1; RQ[2][2] = COGL_FIXED_1;
RQ[0][0] = v[1].x - v[0].x + COGL_FIXED_MUL (RQ[0][2], v[1].x); RQ[0][0] = UX2FX (v[1].x - v[0].x)
RQ[1][0] = v[2].x - v[0].x + COGL_FIXED_MUL (RQ[1][2], v[2].x); + COGL_FIXED_MUL (RQ[0][2], UX2FX (v[1].x));
RQ[2][0] = v[0].x; RQ[1][0] = UX2FX (v[2].x - v[0].x)
RQ[0][1] = v[1].y - v[0].y + COGL_FIXED_MUL (RQ[0][2], v[1].y); + COGL_FIXED_MUL (RQ[1][2], UX2FX (v[2].x));
RQ[1][1] = v[2].y - v[0].y + COGL_FIXED_MUL (RQ[1][2], v[2].y); RQ[2][0] = UX2FX (v[0].x);
RQ[2][1] = v[0].y; RQ[0][1] = UX2FX (v[1].y - v[0].y)
+ COGL_FIXED_MUL (RQ[0][2], UX2FX (v[1].y));
RQ[1][1] = UX2FX (v[2].y - v[0].y)
+ COGL_FIXED_MUL (RQ[1][2], UX2FX (v[2].y));
RQ[2][1] = UX2FX (v[0].y);
} }
/* /*
@ -6985,8 +7017,8 @@ clutter_actor_transform_stage_point (ClutterActor *self,
return FALSE; return FALSE;
/* /*
* Now transform our point with the ST matrix; the notional w coordiance * Now transform our point with the ST matrix; the notional w
* is 1, hence the last part is simply added. * coordinate is 1, hence the last part is simply added.
*/ */
xi = CLUTTER_UNITS_TO_DEVICE (x); xi = CLUTTER_UNITS_TO_DEVICE (x);
yi = CLUTTER_UNITS_TO_DEVICE (y); yi = CLUTTER_UNITS_TO_DEVICE (y);
@ -7000,9 +7032,12 @@ clutter_actor_transform_stage_point (ClutterActor *self,
*/ */
if (x_out) if (x_out)
*x_out = CLUTTER_UNITS_FROM_FLOAT (FX2FP (xf) / FX2FP (wf)); *x_out = CLUTTER_UNITS_FROM_FLOAT (FX2FP (xf) / FX2FP (wf));
if (y_out) if (y_out)
*y_out = CLUTTER_UNITS_FROM_FLOAT (FX2FP (yf) / FX2FP (wf)); *y_out = CLUTTER_UNITS_FROM_FLOAT (FX2FP (yf) / FX2FP (wf));
#undef UX2FX
#undef UX2FP
#undef FP2FX #undef FP2FX
#undef FX2FP #undef FX2FP
#undef FP2INT #undef FP2INT
@ -7197,11 +7232,11 @@ clutter_actor_set_shader (ClutterActor *self,
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
g_return_val_if_fail (shader == NULL || CLUTTER_IS_SHADER (shader), FALSE); g_return_val_if_fail (shader == NULL || CLUTTER_IS_SHADER (shader), FALSE);
if (shader)
g_object_ref (shader);
else
/* if shader passed in is NULL we destroy the shader */ /* if shader passed in is NULL we destroy the shader */
if (shader == NULL)
{
destroy_shader_data (self); destroy_shader_data (self);
}
actor_priv = self->priv; actor_priv = self->priv;
shader_data = actor_priv->shader_data; shader_data = actor_priv->shader_data;
@ -7215,15 +7250,9 @@ clutter_actor_set_shader (ClutterActor *self,
shader_value_free); shader_value_free);
} }
if (shader_data->shader) if (shader_data->shader)
{
g_object_unref (shader_data->shader); g_object_unref (shader_data->shader);
shader_data->shader = NULL;
}
if (shader) shader_data->shader = shader;
{
shader_data->shader = g_object_ref (shader);
}
if (CLUTTER_ACTOR_IS_VISIBLE (self)) if (CLUTTER_ACTOR_IS_VISIBLE (self))
clutter_actor_queue_redraw (self); clutter_actor_queue_redraw (self);
@ -7570,3 +7599,99 @@ clutter_actor_allocate_preferred_size (ClutterActor *self,
clutter_actor_allocate (self, &actor_box, absolute_origin_changed); clutter_actor_allocate (self, &actor_box, absolute_origin_changed);
} }
/**
* clutter_actor_grab_key_focus:
* @self: a #ClutterActor
*
* Sets the key focus of the #ClutterStage including @self
* to this #ClutterActor.
*
* Since: 1.0
*/
void
clutter_actor_grab_key_focus (ClutterActor *self)
{
ClutterActor *parent;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
parent = clutter_actor_get_parent (self);
if (!parent)
return;
parent = clutter_actor_get_stage (self);
if (parent && CLUTTER_IS_STAGE (parent))
clutter_stage_set_key_focus (CLUTTER_STAGE (parent), self);
}
/**
* clutter_actor_get_pango_context:
* @self: a #ClutterActor
*
* Retrieves the #PangoContext for @self. The actor's #PangoContext
* is already configured using the appropriate font map, resolution
* and font options.
*
* Unlike clutter_actor_create_pango_context(), this context is owend
* by the #ClutterActor and it will be updated each time the options
* stored by the #ClutterBackend change.
*
* You can use the returned #PangoContext to create a #PangoLayout
* and render text using cogl_pango_render_layout() to reuse the
* glyphs cache also used by Clutter.
*
* Return value: the #PangoContext for a #ClutterActor. The returned
* #PangoContext is owned by the actor and should not be unreferenced
* by the application code
*
* Since: 1.0
*/
PangoContext *
clutter_actor_get_pango_context (ClutterActor *self)
{
ClutterActorPrivate *priv;
ClutterMainContext *ctx;
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL);
priv = self->priv;
if (priv->pango_context)
return priv->pango_context;
ctx = CLUTTER_CONTEXT ();
priv->pango_context = _clutter_context_get_pango_context (ctx);
g_object_ref (priv->pango_context);
return priv->pango_context;
}
/**
* clutter_actor_create_pango_context:
* @self: a #ClutterActor
*
* Creates a #PangoContext for the given actor. The #PangoContext
* is already configured using the appropriate font map, resolution
* and font options.
*
* See also clutter_actor_get_pango_context().
*
* Return value: the newly created #PangoContext. Use g_object_ref()
* on the returned value to deallocate its resources
*
* Since: 1.0
*/
PangoContext *
clutter_actor_create_pango_context (ClutterActor *self)
{
ClutterMainContext *ctx;
PangoContext *retval;
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL);
ctx = CLUTTER_CONTEXT ();
retval = _clutter_context_create_pango_context (ctx);
return retval;
}

View File

@ -31,6 +31,8 @@
/* clutter-actor.h */ /* clutter-actor.h */
#include <glib-object.h> #include <glib-object.h>
#include <pango/pango.h>
#include <clutter/clutter-color.h> #include <clutter/clutter-color.h>
#include <clutter/clutter-fixed.h> #include <clutter/clutter-fixed.h>
#include <clutter/clutter-types.h> #include <clutter/clutter-types.h>
@ -420,6 +422,8 @@ void clutter_actor_set_opacity (ClutterActor
guint8 opacity); guint8 opacity);
guint8 clutter_actor_get_opacity (ClutterActor *self); guint8 clutter_actor_get_opacity (ClutterActor *self);
guint8 clutter_actor_get_paint_opacity (ClutterActor *self); guint8 clutter_actor_get_paint_opacity (ClutterActor *self);
gboolean clutter_actor_get_paint_visibility (ClutterActor *self);
void clutter_actor_set_name (ClutterActor *self, void clutter_actor_set_name (ClutterActor *self,
const gchar *name); const gchar *name);
@ -559,7 +563,10 @@ void clutter_actor_apply_relative_transform_to_point (ClutterActor *self,
const ClutterVertex *point, const ClutterVertex *point,
ClutterVertex *vertex); ClutterVertex *vertex);
gboolean clutter_actor_get_paint_visibility (ClutterActor *self); void clutter_actor_grab_key_focus (ClutterActor *self);
PangoContext *clutter_actor_get_pango_context (ClutterActor *self);
PangoContext *clutter_actor_create_pango_context (ClutterActor *self);
G_END_DECLS G_END_DECLS

View File

@ -395,6 +395,9 @@ clutter_alpha_set_timeline (ClutterAlpha *alpha,
priv = alpha->priv; priv = alpha->priv;
if (priv->timeline == timeline)
return;
if (priv->timeline) if (priv->timeline)
{ {
g_signal_handlers_disconnect_by_func (priv->timeline, g_signal_handlers_disconnect_by_func (priv->timeline,
@ -565,13 +568,13 @@ clutter_alpha_set_mode (ClutterAlpha *alpha,
priv = alpha->priv; priv = alpha->priv;
priv->mode = mode;
/* sanity check to avoid getting an out of sync enum/function mapping */ /* sanity check to avoid getting an out of sync enum/function mapping */
g_assert (animation_modes[mode].mode == mode); g_assert (animation_modes[mode].mode == mode);
if (G_LIKELY (animation_modes[mode].func != NULL)) if (G_LIKELY (animation_modes[mode].func != NULL))
clutter_alpha_set_func (alpha, animation_modes[mode].func, NULL, NULL); clutter_alpha_set_func (alpha, animation_modes[mode].func, NULL, NULL);
priv->mode = mode;
g_object_notify (G_OBJECT (alpha), "mode"); g_object_notify (G_OBJECT (alpha), "mode");
} }

View File

@ -739,6 +739,8 @@ clutter_animation_set_actor (ClutterAnimation *animation,
priv = animation->priv; priv = animation->priv;
g_object_ref (actor);
if (priv->actor) if (priv->actor)
{ {
g_object_weak_unref (G_OBJECT (animation), g_object_weak_unref (G_OBJECT (animation),
@ -750,7 +752,7 @@ clutter_animation_set_actor (ClutterAnimation *animation,
g_object_unref (priv->actor); g_object_unref (priv->actor);
} }
priv->actor = g_object_ref (actor); priv->actor = actor;
g_object_weak_ref (G_OBJECT (animation), g_object_weak_ref (G_OBJECT (animation),
on_animation_weak_notify, on_animation_weak_notify,
priv->actor); priv->actor);
@ -780,12 +782,11 @@ clutter_animation_get_actor (ClutterAnimation *animation)
} }
static inline void static inline void
clutter_animation_set_mode_internal (ClutterAnimation *animation) clutter_animation_set_mode_internal (ClutterAnimation *animation,
ClutterAlpha *alpha)
{ {
ClutterAnimationPrivate *priv = animation->priv; ClutterAnimationPrivate *priv = animation->priv;
ClutterAlpha *alpha;
alpha = clutter_animation_get_alpha (animation);
if (alpha) if (alpha)
clutter_alpha_set_mode (alpha, priv->mode); clutter_alpha_set_mode (alpha, priv->mode);
} }
@ -810,7 +811,7 @@ clutter_animation_set_mode (ClutterAnimation *animation,
priv = animation->priv; priv = animation->priv;
priv->mode = mode; priv->mode = mode;
clutter_animation_set_mode_internal (animation); clutter_animation_set_mode_internal (animation, priv->alpha);
g_object_notify (G_OBJECT (animation), "mode"); g_object_notify (G_OBJECT (animation), "mode");
} }
@ -968,6 +969,9 @@ clutter_animation_set_timeline (ClutterAnimation *animation,
priv = animation->priv; priv = animation->priv;
if (timeline && priv->timeline == timeline)
return;
g_object_freeze_notify (G_OBJECT (animation)); g_object_freeze_notify (G_OBJECT (animation));
if (priv->timeline) if (priv->timeline)
@ -1048,6 +1052,19 @@ clutter_animation_set_alpha (ClutterAnimation *animation,
priv = animation->priv; priv = animation->priv;
if (!alpha)
{
ClutterTimeline *timeline;
timeline = clutter_animation_get_timeline (animation);
alpha = clutter_alpha_new ();
clutter_alpha_set_timeline (alpha, timeline);
clutter_animation_set_mode_internal (animation, alpha);
}
g_object_ref_sink (alpha);
if (priv->alpha) if (priv->alpha)
{ {
if (priv->alpha_notify_id) if (priv->alpha_notify_id)
@ -1058,18 +1075,7 @@ clutter_animation_set_alpha (ClutterAnimation *animation,
priv->alpha = NULL; priv->alpha = NULL;
} }
if (!alpha) priv->alpha = alpha;
{
ClutterTimeline *timeline;
timeline = clutter_animation_get_timeline (animation);
alpha = clutter_alpha_new ();
clutter_alpha_set_timeline (alpha, timeline);
clutter_animation_set_mode_internal (animation);
}
priv->alpha = g_object_ref_sink (alpha);
priv->alpha_notify_id = priv->alpha_notify_id =
g_signal_connect (alpha, "notify::alpha", g_signal_connect (alpha, "notify::alpha",

View File

@ -44,10 +44,13 @@
#include "clutter-backend.h" #include "clutter-backend.h"
#include "clutter-debug.h" #include "clutter-debug.h"
#include "clutter-fixed.h" #include "clutter-fixed.h"
#include "clutter-marshal.h"
#include "clutter-private.h" #include "clutter-private.h"
G_DEFINE_ABSTRACT_TYPE (ClutterBackend, clutter_backend, G_TYPE_OBJECT); G_DEFINE_ABSTRACT_TYPE (ClutterBackend, clutter_backend, G_TYPE_OBJECT);
#define DEFAULT_FONT_NAME "Sans 10"
#define CLUTTER_BACKEND_GET_PRIVATE(obj) \ #define CLUTTER_BACKEND_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_BACKEND, ClutterBackendPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_BACKEND, ClutterBackendPrivate))
@ -60,11 +63,24 @@ struct _ClutterBackendPrivate
ClutterFixed resolution; ClutterFixed resolution;
cairo_font_options_t *font_options; cairo_font_options_t *font_options;
gchar *font_name;
}; };
enum
{
RESOLUTION_CHANGED,
FONT_CHANGED,
LAST_SIGNAL
};
static guint backend_signals[LAST_SIGNAL] = { 0, };
static void static void
clutter_backend_dispose (GObject *gobject) clutter_backend_dispose (GObject *gobject)
{ {
ClutterBackendPrivate *priv = CLUTTER_BACKEND (gobject)->priv;
ClutterMainContext *clutter_context; ClutterMainContext *clutter_context;
clutter_context = clutter_context_get_default (); clutter_context = clutter_context_get_default ();
@ -76,6 +92,8 @@ clutter_backend_dispose (GObject *gobject)
clutter_context->events_queue = NULL; clutter_context->events_queue = NULL;
} }
g_free (priv->font_name);
clutter_backend_set_font_options (CLUTTER_BACKEND (gobject), NULL); clutter_backend_set_font_options (CLUTTER_BACKEND (gobject), NULL);
G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject); G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject);
@ -89,6 +107,24 @@ clutter_backend_class_init (ClutterBackendClass *klass)
gobject_class->dispose = clutter_backend_dispose; gobject_class->dispose = clutter_backend_dispose;
g_type_class_add_private (gobject_class, sizeof (ClutterBackendPrivate)); g_type_class_add_private (gobject_class, sizeof (ClutterBackendPrivate));
backend_signals[RESOLUTION_CHANGED] =
g_signal_new (I_("resolution-changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterBackendClass, resolution_changed),
NULL, NULL,
clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
backend_signals[FONT_CHANGED] =
g_signal_new (I_("font-changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterBackendClass, font_changed),
NULL, NULL,
clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
} }
static void static void
@ -388,8 +424,9 @@ clutter_backend_set_resolution (ClutterBackend *backend,
priv->resolution = fixed_dpi; priv->resolution = fixed_dpi;
if (CLUTTER_CONTEXT ()->font_map) if (CLUTTER_CONTEXT ()->font_map)
cogl_pango_font_map_set_resolution (CLUTTER_CONTEXT ()->font_map, cogl_pango_font_map_set_resolution (CLUTTER_CONTEXT ()->font_map, dpi);
COGL_FIXED_TO_FLOAT (fixed_dpi));
g_signal_emit (backend, backend_signals[RESOLUTION_CHANGED], 0);
} }
/** /**
@ -445,6 +482,8 @@ clutter_backend_set_font_options (ClutterBackend *backend,
priv->font_options = cairo_font_options_copy (options); priv->font_options = cairo_font_options_copy (options);
else else
priv->font_options = NULL; priv->font_options = NULL;
g_signal_emit (backend, backend_signals[FONT_CHANGED], 0);
} }
} }
@ -482,3 +521,63 @@ clutter_backend_get_font_options (ClutterBackend *backend)
return priv->font_options; return priv->font_options;
} }
/**
* clutter_backend_set_font_name:
* @backend: a #ClutterBackend
* @font_name: the name of the font
*
* Sets the default font to be used by Clutter. The @font_name string
* must either be %NULL, which means that the font name from the
* default #ClutterBackend will be used; or be something that can
* be parsed by the pango_font_description_from_string() function.
*
* Since: 1.0
*/
void
clutter_backend_set_font_name (ClutterBackend *backend,
const gchar *font_name)
{
ClutterBackendPrivate *priv;
g_return_if_fail (CLUTTER_IS_BACKEND (backend));
priv = backend->priv;
g_free (priv->font_name);
if (font_name == NULL || *font_name == '\0')
priv->font_name = g_strdup (DEFAULT_FONT_NAME);
else
priv->font_name = g_strdup (font_name);
g_signal_emit (backend, backend_signals[FONT_CHANGED], 0);
}
/**
* clutter_backend_get_font_name:
* @backend: a #ClutterBackend
*
* Retrieves the default font name as set by
* clutter_backend_set_font_name().
*
* Return value: the font name for the backend. The returned string is
* owned by the #ClutterBackend and should never be modified or freed
*
* Since: 1.0
*/
G_CONST_RETURN gchar *
clutter_backend_get_font_name (ClutterBackend *backend)
{
ClutterBackendPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), NULL);
priv = backend->priv;
if (G_LIKELY (priv->font_name))
return priv->font_name;
priv->font_name = g_strdup (DEFAULT_FONT_NAME);
return priv->font_name;
}

View File

@ -30,6 +30,8 @@
#include <cairo.h> #include <cairo.h>
#include <glib-object.h> #include <glib-object.h>
#include <pango/pango.h>
#include <clutter/clutter-actor.h> #include <clutter/clutter-actor.h>
#include <clutter/clutter-stage.h> #include <clutter/clutter-stage.h>
#include <clutter/clutter-event.h> #include <clutter/clutter-event.h>
@ -77,6 +79,10 @@ struct _ClutterBackendClass
ClutterStage *stage); ClutterStage *stage);
void (* ensure_context) (ClutterBackend *backend, void (* ensure_context) (ClutterBackend *backend,
ClutterStage *stage); ClutterStage *stage);
/* signals */
void (* resolution_changed) (ClutterBackend *backend);
void (* font_changed) (ClutterBackend *backend);
}; };
GType clutter_backend_get_type (void) G_GNUC_CONST; GType clutter_backend_get_type (void) G_GNUC_CONST;
@ -95,6 +101,9 @@ guint clutter_backend_get_double_click_distance (ClutterBackend
void clutter_backend_set_font_options (ClutterBackend *backend, void clutter_backend_set_font_options (ClutterBackend *backend,
cairo_font_options_t *options); cairo_font_options_t *options);
cairo_font_options_t *clutter_backend_get_font_options (ClutterBackend *backend); cairo_font_options_t *clutter_backend_get_font_options (ClutterBackend *backend);
void clutter_backend_set_font_name (ClutterBackend *backend,
const gchar *font_name);
G_CONST_RETURN gchar *clutter_backend_get_font_name (ClutterBackend *backend);
G_END_DECLS G_END_DECLS

View File

@ -619,7 +619,7 @@ clutter_behaviour_rotate_get_boundsx (ClutterBehaviourRotate *rotate,
priv = rotate->priv; priv = rotate->priv;
if (angle_start); if (angle_start)
*angle_start = priv->angle_start; *angle_start = priv->angle_start;
if (angle_end) if (angle_end)

View File

@ -570,6 +570,9 @@ clutter_behaviour_set_alpha (ClutterBehaviour *behave,
priv = behave->priv; priv = behave->priv;
if (alpha)
g_object_ref_sink (alpha);
if (priv->notify_id) if (priv->notify_id)
{ {
CLUTTER_NOTE (BEHAVIOUR, "removing previous notify-id (%d)", CLUTTER_NOTE (BEHAVIOUR, "removing previous notify-id (%d)",
@ -590,7 +593,6 @@ clutter_behaviour_set_alpha (ClutterBehaviour *behave,
if (alpha) if (alpha)
{ {
priv->alpha = alpha; priv->alpha = alpha;
g_object_ref_sink (priv->alpha);
priv->notify_id = g_signal_connect (priv->alpha, "notify::alpha", priv->notify_id = g_signal_connect (priv->alpha, "notify::alpha",
G_CALLBACK(notify_cb), G_CALLBACK(notify_cb),

View File

@ -476,10 +476,129 @@ clutter_binding_pool_install_closure (ClutterBindingPool *pool,
g_hash_table_insert (pool->entries_hash, entry, entry); g_hash_table_insert (pool->entries_hash, entry, entry);
} }
gchar ** /**
clutter_binding_pool_list_actions (ClutterBindingPool *pool) * clutter_binding_pool_override_action:
* @pool: a #ClutterBindingPool
* @key_val: key symbol
* @modifiers: bitmask of modifiers
* @callback: function to be called when the action is activated
* @data: data to be passed to @callback
* @notify: function to be called when the action is removed
* from the pool
*
* Allows overriding the action for @key_val and @modifiers inside a
* #ClutterBindingPool. See clutter_binding_pool_install_action().
*
* When an action has been activated using clutter_binding_pool_activate()
* the passed @callback will be invoked (with @data).
*
* Actions can be blocked with clutter_binding_pool_block_action()
* and then unblocked using clutter_binding_pool_unblock_action().
*
* Since: 1.0
*/
void
clutter_binding_pool_override_action (ClutterBindingPool *pool,
guint key_val,
ClutterModifierType modifiers,
GCallback callback,
gpointer data,
GDestroyNotify notify)
{ {
return NULL; ClutterBindingEntry *entry;
GClosure *closure;
g_return_if_fail (pool != NULL);
g_return_if_fail (key_val != 0);
g_return_if_fail (callback != NULL);
entry = binding_pool_lookup_entry (pool, key_val, modifiers);
if (G_UNLIKELY (entry == NULL))
{
g_warning ("There is no action for the given key symbol "
"of %d (modifiers: %d) installed inside the "
"binding pool.",
key_val, modifiers);
return;
}
if (entry->closure)
{
g_closure_unref (entry->closure);
entry->closure = NULL;
}
closure = g_cclosure_new (callback, data, (GClosureNotify) notify);
entry->closure = g_closure_ref (closure);
g_closure_sink (closure);
if (G_CLOSURE_NEEDS_MARSHAL (closure))
{
GClosureMarshal marshal;
marshal = clutter_marshal_BOOLEAN__STRING_UINT_ENUM;
g_closure_set_marshal (closure, marshal);
}
}
/**
* clutter_binding_pool_override_closure:
* @pool: a #ClutterBindingPool
* @key_val: key symbol
* @modifiers: bitmask of modifiers
* @closure: a #GClosure
*
* A #GClosure variant of clutter_binding_pool_override_action().
*
* Allows overriding the action for @key_val and @modifiers inside a
* #ClutterBindingPool. See clutter_binding_pool_install_closure().
*
* When an action has been activated using clutter_binding_pool_activate()
* the passed @callback will be invoked (with @data).
*
* Actions can be blocked with clutter_binding_pool_block_action()
* and then unblocked using clutter_binding_pool_unblock_action().
*
* Since: 1.0
*/
void
clutter_binding_pool_override_closure (ClutterBindingPool *pool,
guint key_val,
ClutterModifierType modifiers,
GClosure *closure)
{
ClutterBindingEntry *entry;
g_return_if_fail (pool != NULL);
g_return_if_fail (key_val != 0);
g_return_if_fail (closure != NULL);
entry = binding_pool_lookup_entry (pool, key_val, modifiers);
if (G_UNLIKELY (entry == NULL))
{
g_warning ("There is no action for the given key symbol "
"of %d (modifiers: %d) installed inside the "
"binding pool.",
key_val, modifiers);
return;
}
if (entry->closure)
{
g_closure_unref (entry->closure);
entry->closure = NULL;
}
entry->closure = g_closure_ref (closure);
g_closure_sink (closure);
if (G_CLOSURE_NEEDS_MARSHAL (closure))
{
GClosureMarshal marshal;
marshal = clutter_marshal_BOOLEAN__STRING_UINT_ENUM;
g_closure_set_marshal (closure, marshal);
}
} }
/** /**
@ -531,6 +650,7 @@ clutter_binding_pool_remove_action (ClutterBindingPool *pool,
ClutterModifierType modifiers) ClutterModifierType modifiers)
{ {
ClutterBindingEntry remove_entry = { 0, }; ClutterBindingEntry remove_entry = { 0, };
GSList *l;
g_return_if_fail (pool != NULL); g_return_if_fail (pool != NULL);
g_return_if_fail (key_val != 0); g_return_if_fail (key_val != 0);
@ -540,6 +660,18 @@ clutter_binding_pool_remove_action (ClutterBindingPool *pool,
remove_entry.key_val = key_val; remove_entry.key_val = key_val;
remove_entry.modifiers = modifiers; remove_entry.modifiers = modifiers;
for (l = pool->entries; l != NULL; l = l->data)
{
ClutterBindingEntry *e = l->data;
if (e->key_val == remove_entry.key_val &&
e->modifiers == remove_entry.modifiers)
{
pool->entries = g_slist_remove_link (pool->entries, l);
break;
}
}
g_hash_table_remove (pool->entries_hash, &remove_entry); g_hash_table_remove (pool->entries_hash, &remove_entry);
} }

View File

@ -72,8 +72,17 @@ void clutter_binding_pool_install_closure (ClutterBindingPool
guint key_val, guint key_val,
ClutterModifierType modifiers, ClutterModifierType modifiers,
GClosure *closure); GClosure *closure);
void clutter_binding_pool_override_action (ClutterBindingPool *pool,
guint key_val,
ClutterModifierType modifiers,
GCallback callback,
gpointer data,
GDestroyNotify notify);
void clutter_binding_pool_override_closure (ClutterBindingPool *pool,
guint key_val,
ClutterModifierType modifiers,
GClosure *closure);
gchar ** clutter_binding_pool_list_actions (ClutterBindingPool *pool);
G_CONST_RETURN gchar *clutter_binding_pool_find_action (ClutterBindingPool *pool, G_CONST_RETURN gchar *clutter_binding_pool_find_action (ClutterBindingPool *pool,
guint key_val, guint key_val,
ClutterModifierType modifiers); ClutterModifierType modifiers);

View File

@ -221,6 +221,9 @@ set_parent_texture (ClutterCloneTexture *ctexture,
ClutterActor *actor = CLUTTER_ACTOR (ctexture); ClutterActor *actor = CLUTTER_ACTOR (ctexture);
gboolean was_visible = CLUTTER_ACTOR_IS_VISIBLE (ctexture); gboolean was_visible = CLUTTER_ACTOR_IS_VISIBLE (ctexture);
if (priv->parent_texture == texture)
return;
if (priv->parent_texture) if (priv->parent_texture)
{ {
g_object_unref (priv->parent_texture); g_object_unref (priv->parent_texture);

File diff suppressed because it is too large Load Diff

View File

@ -1,165 +0,0 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
* Neil Jagdish Patel <njp@o-hand.com
*
* Copyright (C) 2006 OpenedHand
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_ENTRY_H__
#define __CLUTTER_ENTRY_H__
#include <clutter/clutter-actor.h>
#include <clutter/clutter-color.h>
#include <clutter/clutter-event.h>
#include <pango/pango.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_ENTRY (clutter_entry_get_type ())
#define CLUTTER_ENTRY(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
CLUTTER_TYPE_ENTRY, ClutterEntry))
#define CLUTTER_ENTRY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), \
CLUTTER_TYPE_ENTRY, ClutterEntryClass))
#define CLUTTER_IS_ENTRY(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
CLUTTER_TYPE_ENTRY))
#define CLUTTER_IS_ENTRY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
CLUTTER_TYPE_ENTRY))
#define CLUTTER_ENTRY_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
CLUTTER_TYPE_ENTRY, ClutterEntryClass))
typedef struct _ClutterEntry ClutterEntry;
typedef struct _ClutterEntryClass ClutterEntryClass;
typedef struct _ClutterEntryPrivate ClutterEntryPrivate;
struct _ClutterEntry
{
/*< private >*/
ClutterActor parent_instance;
ClutterEntryPrivate *priv;
};
/**
* ClutterEntryClass:
* @paint_cursor: virtual function for subclasses to use to draw a custom
* cursor instead of the default one
* @text_changed: signal class handler for ClutterEntry::text-changed
* @cursor_event: signal class handler for ClutterEntry::cursor-event
* @activate: signal class handler for ClutterEntry::activate
*
* Class fo entry actors.
*
* Since: 0.4
*/
struct _ClutterEntryClass
{
/*< private >*/
ClutterActorClass parent_class;
/*< public >*/
/* vfuncs, not signals */
void (* paint_cursor) (ClutterEntry *entry);
/* signals */
void (* text_changed) (ClutterEntry *entry);
void (* cursor_event) (ClutterEntry *entry,
ClutterGeometry *geometry);
void (* activate) (ClutterEntry *entry);
/*< private >*/
/* padding for future */
void (*_clutter_entry_1) (void);
void (*_clutter_entry_2) (void);
void (*_clutter_entry_3) (void);
void (*_clutter_entry_4) (void);
};
GType clutter_entry_get_type (void) G_GNUC_CONST;
ClutterActor * clutter_entry_new (void);
ClutterActor * clutter_entry_new_full (const gchar *font_name,
const gchar *text,
const ClutterColor *color);
ClutterActor * clutter_entry_new_with_text (const gchar *font_name,
const gchar *text);
void clutter_entry_set_text (ClutterEntry *entry,
const gchar *text);
G_CONST_RETURN gchar *clutter_entry_get_text (ClutterEntry *entry);
void clutter_entry_set_font_name (ClutterEntry *entry,
const gchar *font_name);
G_CONST_RETURN gchar *clutter_entry_get_font_name (ClutterEntry *entry);
void clutter_entry_set_color (ClutterEntry *entry,
const ClutterColor *color);
void clutter_entry_get_color (ClutterEntry *entry,
ClutterColor *color);
PangoLayout * clutter_entry_get_layout (ClutterEntry *entry);
void clutter_entry_set_alignment (ClutterEntry *entry,
PangoAlignment alignment);
PangoAlignment clutter_entry_get_alignment (ClutterEntry *entry);
void clutter_entry_set_cursor_position (ClutterEntry *entry,
gint position);
gint clutter_entry_get_cursor_position (ClutterEntry *entry);
void clutter_entry_insert_unichar (ClutterEntry *entry,
gunichar wc);
void clutter_entry_delete_chars (ClutterEntry *entry,
guint len);
void clutter_entry_insert_text (ClutterEntry *entry,
const gchar *text,
gssize position);
void clutter_entry_delete_text (ClutterEntry *entry,
gssize start_pos,
gssize end_pos);
void clutter_entry_set_visible_cursor (ClutterEntry *entry,
gboolean visible);
gboolean clutter_entry_get_visible_cursor (ClutterEntry *entry);
void clutter_entry_set_visibility (ClutterEntry *entry,
gboolean visible);
gboolean clutter_entry_get_visibility (ClutterEntry *entry);
void clutter_entry_set_invisible_char (ClutterEntry *entry,
gunichar wc);
gunichar clutter_entry_get_invisible_char (ClutterEntry *entry);
void clutter_entry_set_max_length (ClutterEntry *entry,
gint max);
gint clutter_entry_get_max_length (ClutterEntry *entry);
#ifndef CLUTTER_DISABLE_DEPRECATED
void clutter_entry_handle_key_event (ClutterEntry *entry,
ClutterKeyEvent *kev);
#endif
G_END_DECLS
#endif /* __CLUTTER_ENTRY_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,128 +0,0 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
*
* Copyright (C) 2006 OpenedHand
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_LABEL_H__
#define __CLUTTER_LABEL_H__
#include <clutter/clutter-actor.h>
#include <clutter/clutter-color.h>
#include <pango/pango.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_LABEL (clutter_label_get_type ())
#define CLUTTER_LABEL(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
CLUTTER_TYPE_LABEL, ClutterLabel))
#define CLUTTER_LABEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), \
CLUTTER_TYPE_LABEL, ClutterLabelClass))
#define CLUTTER_IS_LABEL(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
CLUTTER_TYPE_LABEL))
#define CLUTTER_IS_LABEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
CLUTTER_TYPE_LABEL))
#define CLUTTER_LABEL_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
CLUTTER_TYPE_LABEL, ClutterLabelClass))
typedef struct _ClutterLabel ClutterLabel;
typedef struct _ClutterLabelClass ClutterLabelClass;
typedef struct _ClutterLabelPrivate ClutterLabelPrivate;
struct _ClutterLabel
{
ClutterActor parent;
/*< private >*/
ClutterLabelPrivate *priv;
};
struct _ClutterLabelClass
{
/*< private >*/
ClutterActorClass parent_class;
void (*_clutter_label_1) (void);
void (*_clutter_label_2) (void);
void (*_clutter_label_3) (void);
void (*_clutter_label_4) (void);
};
GType clutter_label_get_type (void) G_GNUC_CONST;
ClutterActor * clutter_label_new (void);
ClutterActor* clutter_label_new_full (const gchar *font_name,
const gchar *text,
const ClutterColor *color);
ClutterActor * clutter_label_new_with_text (const gchar *font_name,
const gchar *text);
void clutter_label_set_text (ClutterLabel *label,
const gchar *text);
G_CONST_RETURN gchar *clutter_label_get_text (ClutterLabel *label);
void clutter_label_set_font_name (ClutterLabel *label,
const gchar *font_name);
G_CONST_RETURN gchar *clutter_label_get_font_name (ClutterLabel *label);
void clutter_label_set_color (ClutterLabel *label,
const ClutterColor *color);
void clutter_label_get_color (ClutterLabel *label,
ClutterColor *color);
void clutter_label_set_ellipsize (ClutterLabel *label,
PangoEllipsizeMode mode);
PangoEllipsizeMode clutter_label_get_ellipsize (ClutterLabel *label);
void clutter_label_set_line_wrap (ClutterLabel *label,
gboolean wrap);
gboolean clutter_label_get_line_wrap (ClutterLabel *label);
void clutter_label_set_line_wrap_mode (ClutterLabel *label,
PangoWrapMode wrap_mode);
PangoWrapMode clutter_label_get_line_wrap_mode (ClutterLabel *label);
PangoLayout * clutter_label_get_layout (ClutterLabel *label);
void clutter_label_set_attributes (ClutterLabel *label,
PangoAttrList *attrs);
PangoAttrList * clutter_label_get_attributes (ClutterLabel *label);
void clutter_label_set_use_markup (ClutterLabel *label,
gboolean setting);
gboolean clutter_label_get_use_markup (ClutterLabel *label);
void clutter_label_set_alignment (ClutterLabel *label,
PangoAlignment alignment);
PangoAlignment clutter_label_get_alignment (ClutterLabel *label);
void clutter_label_set_justify (ClutterLabel *label,
gboolean justify);
gboolean clutter_label_get_justify (ClutterLabel *label);
G_END_DECLS
#endif /* __CLUTTER_LABEL_H__ */

View File

@ -69,6 +69,8 @@ static guint clutter_default_fps = 60;
static guint clutter_main_loop_level = 0; static guint clutter_main_loop_level = 0;
static GSList *main_loops = NULL; static GSList *main_loops = NULL;
static PangoDirection clutter_text_direction = PANGO_DIRECTION_LTR;
guint clutter_debug_flags = 0; /* global clutter debug flag */ guint clutter_debug_flags = 0; /* global clutter debug flag */
#ifdef CLUTTER_ENABLE_DEBUG #ifdef CLUTTER_ENABLE_DEBUG
@ -401,23 +403,100 @@ _clutter_do_pick (ClutterStage *stage,
return clutter_get_actor_by_gid (id); return clutter_get_actor_by_gid (id);
} }
static PangoDirection
clutter_get_text_direction (void)
{
PangoDirection dir = PANGO_DIRECTION_LTR;
const gchar *direction;
direction = g_getenv ("CLUTTER_TEXT_DIRECTION");
if (direction && *direction != '\0')
{
if (strcmp (direction, "rtl") == 0)
dir = PANGO_DIRECTION_RTL;
else if (strcmp (direction, "ltr") == 0)
dir = PANGO_DIRECTION_LTR;
}
else
{
/* Translate to default:RTL if you want your widgets
* to be RTL, otherwise translate to default:LTR.
*
* Do *not* translate it to "predefinito:LTR": if it
* it isn't default:LTR or default:RTL it will not work
*/
char *e = _("default:LTR");
if (strcmp (e, "default:RTL") == 0)
dir = PANGO_DIRECTION_RTL;
else if (strcmp (e, "default:LTR") == 0)
dir = PANGO_DIRECTION_LTR;
else
g_warning ("Whoever translated default:LTR did so wrongly.");
}
return dir;
}
static void
update_pango_context (ClutterBackend *backend,
PangoContext *context)
{
PangoFontDescription *font_desc;
cairo_font_options_t *font_options;
const gchar *font_name;
gdouble resolution;
/* update the text direction */
pango_context_set_base_dir (context, clutter_text_direction);
/* get the configuration for the PangoContext from the backend */
font_name = clutter_backend_get_font_name (backend);
font_options = clutter_backend_get_font_options (backend);
resolution = clutter_backend_get_resolution (backend);
font_desc = pango_font_description_from_string (font_name);
if (resolution < 0)
resolution = 96.0; /* fall back */
pango_context_set_font_description (context, font_desc);
pango_cairo_context_set_font_options (context, font_options);
pango_cairo_context_set_resolution (context, resolution);
pango_font_description_free (font_desc);
}
PangoContext *
_clutter_context_get_pango_context (ClutterMainContext *self)
{
if (G_UNLIKELY (self->pango_context == NULL))
{
PangoContext *context;
context = cogl_pango_font_map_create_context (self->font_map);
self->pango_context = context;
g_signal_connect (self->backend, "resolution-changed",
G_CALLBACK (update_pango_context),
self->pango_context);
g_signal_connect (self->backend, "font-changed",
G_CALLBACK (update_pango_context),
self->pango_context);
}
update_pango_context (self->backend, self->pango_context);
return self->pango_context;
}
PangoContext * PangoContext *
_clutter_context_create_pango_context (ClutterMainContext *self) _clutter_context_create_pango_context (ClutterMainContext *self)
{ {
PangoContext *context; PangoContext *context;
gdouble resolution;
cairo_font_options_t *font_options;
resolution = clutter_backend_get_resolution (self->backend);
if (resolution < 0)
resolution = 96.0; /* fall back */
context = cogl_pango_font_map_create_context (self->font_map); context = cogl_pango_font_map_create_context (self->font_map);
update_pango_context (self->backend, context);
pango_cairo_context_set_resolution (context, resolution);
font_options = clutter_backend_get_font_options (self->backend);
pango_cairo_context_set_font_options (context, font_options);
return context; return context;
} }
@ -1004,6 +1083,17 @@ clutter_get_timestamp (void)
#endif #endif
} }
static gboolean
clutter_arg_direction_cb (const char *key,
const char *value,
gpointer user_data)
{
clutter_text_direction =
(strcmp (value, "rtl") == 0) ? PANGO_DIRECTION_RTL
: PANGO_DIRECTION_LTR;
return TRUE;
}
#ifdef CLUTTER_ENABLE_DEBUG #ifdef CLUTTER_ENABLE_DEBUG
static gboolean static gboolean
@ -1077,6 +1167,8 @@ clutter_init_real (GError **error)
cogl_pango_font_map_set_resolution (ctx->font_map, resolution); cogl_pango_font_map_set_resolution (ctx->font_map, resolution);
cogl_pango_font_map_set_use_mipmapping (ctx->font_map, TRUE); cogl_pango_font_map_set_use_mipmapping (ctx->font_map, TRUE);
clutter_text_direction = clutter_get_text_direction ();
/* Stage will give us a GL Context etc */ /* Stage will give us a GL Context etc */
stage = clutter_stage_get_default (); stage = clutter_stage_get_default ();
if (!stage) if (!stage)
@ -1142,16 +1234,19 @@ clutter_init_real (GError **error)
static GOptionEntry clutter_args[] = { static GOptionEntry clutter_args[] = {
{ "clutter-show-fps", 0, 0, G_OPTION_ARG_NONE, &clutter_show_fps, { "clutter-show-fps", 0, 0, G_OPTION_ARG_NONE, &clutter_show_fps,
"Show frames per second", NULL }, N_("Show frames per second"), NULL },
{ "clutter-default-fps", 0, 0, G_OPTION_ARG_INT, &clutter_default_fps, { "clutter-default-fps", 0, 0, G_OPTION_ARG_INT, &clutter_default_fps,
"Default frame rate", "FPS" }, N_("Default frame rate"), "FPS" },
{ "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &clutter_fatal_warnings, { "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &clutter_fatal_warnings,
"Make all warnings fatal", NULL }, N_("Make all warnings fatal"), NULL },
{ "clutter-text-direction", 0, 0, G_OPTION_ARG_CALLBACK,
clutter_arg_direction_cb,
N_("Direction for the text"), "DIRECTION" },
#ifdef CLUTTER_ENABLE_DEBUG #ifdef CLUTTER_ENABLE_DEBUG
{ "clutter-debug", 0, 0, G_OPTION_ARG_CALLBACK, clutter_arg_debug_cb, { "clutter-debug", 0, 0, G_OPTION_ARG_CALLBACK, clutter_arg_debug_cb,
"Clutter debugging flags to set", "FLAGS" }, N_("Clutter debugging flags to set"), "FLAGS" },
{ "clutter-no-debug", 0, 0, G_OPTION_ARG_CALLBACK, clutter_arg_no_debug_cb, { "clutter-no-debug", 0, 0, G_OPTION_ARG_CALLBACK, clutter_arg_no_debug_cb,
"Clutter debugging flags to unset", "FLAGS" }, N_("Clutter debugging flags to unset"), "FLAGS" },
#endif /* CLUTTER_ENABLE_DEBUG */ #endif /* CLUTTER_ENABLE_DEBUG */
{ NULL, }, { NULL, },
}; };
@ -1294,13 +1389,14 @@ clutter_get_option_group (void)
context = clutter_context_get_default (); context = clutter_context_get_default ();
group = g_option_group_new ("clutter", group = g_option_group_new ("clutter",
"Clutter Options", _("Clutter Options"),
"Show Clutter Options", _("Show Clutter Options"),
NULL, NULL,
NULL); NULL);
g_option_group_set_parse_hooks (group, pre_parse_hook, post_parse_hook); g_option_group_set_parse_hooks (group, pre_parse_hook, post_parse_hook);
g_option_group_add_entries (group, clutter_args); g_option_group_add_entries (group, clutter_args);
g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
/* add backend-specific options */ /* add backend-specific options */
_clutter_backend_add_options (context->backend, group); _clutter_backend_add_options (context->backend, group);
@ -2118,6 +2214,9 @@ clutter_base_init (void)
initialised = TRUE; initialised = TRUE;
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
/* initialise GLib type system */ /* initialise GLib type system */
g_type_init (); g_type_init ();

View File

@ -38,6 +38,8 @@
#include <glib.h> #include <glib.h>
#include "pango/cogl-pango.h"
#include "clutter-backend.h" #include "clutter-backend.h"
#include "clutter-event.h" #include "clutter-event.h"
#include "clutter-feature.h" #include "clutter-feature.h"
@ -45,7 +47,6 @@
#include "clutter-stage-manager.h" #include "clutter-stage-manager.h"
#include "clutter-stage-window.h" #include "clutter-stage-window.h"
#include "clutter-stage.h" #include "clutter-stage.h"
#include "pango/cogl-pango.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -125,6 +126,7 @@ struct _ClutterMainContext
gint fb_r_mask, fb_g_mask, fb_b_mask; gint fb_r_mask, fb_g_mask, fb_b_mask;
gint fb_r_mask_used, fb_g_mask_used, fb_b_mask_used; gint fb_r_mask_used, fb_g_mask_used, fb_b_mask_used;
PangoContext *pango_context; /* Global Pango context */
CoglPangoFontMap *font_map; /* Global font map */ CoglPangoFontMap *font_map; /* Global font map */
GSList *input_devices; /* For extra input devices, i.e GSList *input_devices; /* For extra input devices, i.e
@ -134,6 +136,7 @@ struct _ClutterMainContext
#define CLUTTER_CONTEXT() (clutter_context_get_default ()) #define CLUTTER_CONTEXT() (clutter_context_get_default ())
ClutterMainContext *clutter_context_get_default (void); ClutterMainContext *clutter_context_get_default (void);
PangoContext *_clutter_context_create_pango_context (ClutterMainContext *self); PangoContext *_clutter_context_create_pango_context (ClutterMainContext *self);
PangoContext *_clutter_context_get_pango_context (ClutterMainContext *self);
#define CLUTTER_PRIVATE_FLAGS(a) (((ClutterActor *) (a))->private_flags) #define CLUTTER_PRIVATE_FLAGS(a) (((ClutterActor *) (a))->private_flags)
#define CLUTTER_SET_PRIVATE_FLAGS(a,f) (CLUTTER_PRIVATE_FLAGS (a) |= (f)) #define CLUTTER_SET_PRIVATE_FLAGS(a,f) (CLUTTER_PRIVATE_FLAGS (a) |= (f))

View File

@ -1201,7 +1201,7 @@ clutter_stage_read_pixels (ClutterStage *stage,
/* The y co-ordinate should be given in OpenGL's coordinate system /* The y co-ordinate should be given in OpenGL's coordinate system
so 0 is the bottom row */ so 0 is the bottom row */
y = stage_height - 1 - y - height; y = stage_height - y - height;
glFinish (); glFinish ();

3757
clutter/clutter-text.c Normal file

File diff suppressed because it is too large Load Diff

198
clutter/clutter-text.h Normal file
View File

@ -0,0 +1,198 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2008 Intel Corporation.
*
* Authored By: Øyvind Kolås <pippin@o-hand.com>
* Emmanuele Bassi <ebassi@linux.intel.com>
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_TEXT_H__
#define __CLUTTER_TEXT_H__
#include <clutter/clutter-actor.h>
#include <pango/pango.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_TEXT (clutter_text_get_type ())
#define CLUTTER_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_TEXT, ClutterText))
#define CLUTTER_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_TEXT, ClutterTextClass))
#define CLUTTER_IS_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_TEXT))
#define CLUTTER_IS_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_TEXT))
#define CLUTTER_TEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_TEXT, ClutterTextClass))
typedef struct _ClutterText ClutterText;
typedef struct _ClutterTextPrivate ClutterTextPrivate;
typedef struct _ClutterTextClass ClutterTextClass;
/**
* ClutterText:
*
* The #ClutterText struct contains only private data.
*
* Since: 1.0
*/
struct _ClutterText
{
/*< private >*/
ClutterActor parent_instance;
ClutterTextPrivate *priv;
};
/**
* ClutterTextClass:
* @text_changed: class handler for the #ClutterText::text-changed signal
* @activate: class handler for the #ClutterText::activate signal
* @cursor_event: class handler for the #ClutterText::cursor_event signal
*
* The #ClutterTextClass struct contains only private data.
*
* Since: 1.0
*/
struct _ClutterTextClass
{
/*< private >*/
ClutterActorClass parent_class;
/*< public >*/
/* signals, not vfuncs */
void (* text_changed) (ClutterText *self);
void (* activate) (ClutterText *self);
void (* cursor_event) (ClutterText *self,
const ClutterGeometry *geometry);
/*< private >*/
/* padding for future expansion */
void (* _clutter_reserved1) (void);
void (* _clutter_reserved2) (void);
void (* _clutter_reserved3) (void);
void (* _clutter_reserved4) (void);
void (* _clutter_reserved5) (void);
void (* _clutter_reserved6) (void);
void (* _clutter_reserved7) (void);
void (* _clutter_reserved8) (void);
};
GType clutter_text_get_type (void) G_GNUC_CONST;
ClutterActor * clutter_text_new (void);
ClutterActor * clutter_text_new_full (const gchar *font_name,
const gchar *text,
const ClutterColor *color);
ClutterActor * clutter_text_new_with_text (const gchar *font_name,
const gchar *text);
G_CONST_RETURN gchar *clutter_text_get_text (ClutterText *self);
void clutter_text_set_text (ClutterText *self,
const gchar *text);
PangoLayout * clutter_text_get_layout (ClutterText *self);
void clutter_text_set_color (ClutterText *self,
const ClutterColor *color);
void clutter_text_get_color (ClutterText *self,
ClutterColor *color);
void clutter_text_set_font_name (ClutterText *self,
const gchar *font_name);
G_CONST_RETURN gchar *clutter_text_get_font_name (ClutterText *self);
void clutter_text_set_ellipsize (ClutterText *self,
PangoEllipsizeMode mode);
PangoEllipsizeMode clutter_text_get_ellipsize (ClutterText *self);
void clutter_text_set_line_wrap (ClutterText *self,
gboolean line_wrap);
gboolean clutter_text_get_line_wrap (ClutterText *self);
void clutter_text_set_line_wrap_mode (ClutterText *self,
PangoWrapMode wrap_mode);
PangoWrapMode clutter_text_get_line_wrap_mode (ClutterText *self);
PangoLayout * clutter_text_get_layout (ClutterText *self);
void clutter_text_set_attributes (ClutterText *self,
PangoAttrList *attrs);
PangoAttrList * clutter_text_get_attributes (ClutterText *self);
void clutter_text_set_use_markup (ClutterText *self,
gboolean setting);
gboolean clutter_text_get_use_markup (ClutterText *self);
void clutter_text_set_alignment (ClutterText *self,
PangoAlignment alignment);
PangoAlignment clutter_text_get_alignment (ClutterText *self);
void clutter_text_set_justify (ClutterText *self,
gboolean justify);
gboolean clutter_text_get_justify (ClutterText *self);
void clutter_text_insert_unichar (ClutterText *self,
gunichar wc);
void clutter_text_delete_chars (ClutterText *self,
guint n_chars);
void clutter_text_insert_text (ClutterText *self,
const gchar *text,
gssize position);
void clutter_text_delete_text (ClutterText *self,
gssize start_pos,
gssize end_pos);
gchar * clutter_text_get_chars (ClutterText *self,
gssize start_pos,
gssize end_pos);
void clutter_text_set_editable (ClutterText *self,
gboolean editable);
gboolean clutter_text_get_editable (ClutterText *self);
void clutter_text_set_activatable (ClutterText *self,
gboolean activatable);
gboolean clutter_text_get_activatable (ClutterText *self);
gint clutter_text_get_cursor_position (ClutterText *self);
void clutter_text_set_cursor_position (ClutterText *self,
gint position);
void clutter_text_set_cursor_visible (ClutterText *self,
gboolean cursor_visible);
gboolean clutter_text_get_cursor_visible (ClutterText *self);
void clutter_text_set_cursor_color (ClutterText *self,
const ClutterColor *color);
void clutter_text_get_cursor_color (ClutterText *self,
ClutterColor *color);
void clutter_text_set_cursor_size (ClutterText *self,
gint size);
guint clutter_text_get_cursor_size (ClutterText *self);
void clutter_text_set_selectable (ClutterText *self,
gboolean selectable);
gboolean clutter_text_get_selectable (ClutterText *self);
void clutter_text_set_selection_bound (ClutterText *self,
gint selection_bound);
gint clutter_text_get_selection_bound (ClutterText *self);
void clutter_text_set_selection (ClutterText *self,
gssize start_pos,
gssize end_pos);
gchar * clutter_text_get_selection (ClutterText *self);
void clutter_text_set_password_char (ClutterText *self,
gunichar wc);
gunichar clutter_text_get_password_char (ClutterText *self);
void clutter_text_set_max_length (ClutterText *self,
gint max);
gint clutter_text_get_max_length (ClutterText *self);
void clutter_text_set_single_line_mode (ClutterText *self,
gboolean single_line);
gboolean clutter_text_get_single_line_mode (ClutterText *self);
gboolean clutter_text_activate (ClutterText *self);
G_END_DECLS
#endif /* __CLUTTER_TEXT_H__ */

View File

@ -417,7 +417,8 @@ clutter_texture_set_fbo_projection (ClutterActor *self)
ClutterTexturePrivate *priv = CLUTTER_TEXTURE (self)->priv; ClutterTexturePrivate *priv = CLUTTER_TEXTURE (self)->priv;
ClutterVertex verts[4]; ClutterVertex verts[4];
ClutterFixed viewport[4]; ClutterFixed viewport[4];
ClutterFixed x_min, x_max, y_min, y_max; ClutterUnit x_min, x_max, y_min, y_max;
ClutterFixed tx_min, tx_max, ty_min, ty_max;
ClutterPerspective perspective; ClutterPerspective perspective;
ClutterStage *stage; ClutterStage *stage;
ClutterFixed tan_angle, near_size; ClutterFixed tan_angle, near_size;
@ -450,20 +451,25 @@ clutter_texture_set_fbo_projection (ClutterActor *self)
/* Convert the coordinates back to [-1,1] range */ /* Convert the coordinates back to [-1,1] range */
cogl_get_viewport (viewport); cogl_get_viewport (viewport);
x_min = COGL_FIXED_DIV (x_min, viewport[2]) * 2 - COGL_FIXED_1;
x_max = COGL_FIXED_DIV (x_max, viewport[2]) * 2 - COGL_FIXED_1; tx_min = COGL_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (x_min), viewport[2])
y_min = COGL_FIXED_DIV (y_min, viewport[3]) * 2 - COGL_FIXED_1; * 2 - COGL_FIXED_1;
y_max = COGL_FIXED_DIV (y_max, viewport[3]) * 2 - COGL_FIXED_1; tx_max = COGL_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (x_max), viewport[2])
* 2 - COGL_FIXED_1;
ty_min = COGL_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (y_min), viewport[3])
* 2 - COGL_FIXED_1;
ty_max = COGL_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (y_max), viewport[3])
* 2 - COGL_FIXED_1;
/* Set up a projection matrix so that the actor will be projected as /* Set up a projection matrix so that the actor will be projected as
if it was drawn at its original location */ if it was drawn at its original location */
tan_angle = clutter_tani (CLUTTER_ANGLE_FROM_DEGX (perspective.fovy / 2)); tan_angle = cogl_angle_tan (COGL_ANGLE_FROM_DEGX (perspective.fovy / 2));
near_size = COGL_FIXED_MUL (perspective.z_near, tan_angle); near_size = COGL_FIXED_MUL (perspective.z_near, tan_angle);
cogl_frustum (COGL_FIXED_MUL (x_min, near_size), cogl_frustum (COGL_FIXED_MUL (tx_min, near_size),
COGL_FIXED_MUL (x_max, near_size), COGL_FIXED_MUL (tx_max, near_size),
COGL_FIXED_MUL (-y_min, near_size), COGL_FIXED_MUL (-ty_min, near_size),
COGL_FIXED_MUL (-y_max, near_size), COGL_FIXED_MUL (-ty_max, near_size),
perspective.z_near, perspective.z_far); perspective.z_near, perspective.z_far);
} }
@ -544,8 +550,10 @@ clutter_texture_paint (ClutterActor *self)
/* Restore the perspective matrix using cogl_perspective so that /* Restore the perspective matrix using cogl_perspective so that
the inverse matrix will be right */ the inverse matrix will be right */
cogl_perspective (perspective.fovy, perspective.aspect, cogl_perspective (perspective.fovy,
perspective.z_near, perspective.z_far); perspective.aspect,
perspective.z_near,
perspective.z_far);
/* If there is a shader on top of the shader stack, turn it back on. */ /* If there is a shader on top of the shader stack, turn it back on. */
if (shader) if (shader)

View File

@ -47,14 +47,12 @@
#include "clutter-container.h" #include "clutter-container.h"
#include "clutter-deprecated.h" #include "clutter-deprecated.h"
#include "clutter-effect.h" #include "clutter-effect.h"
#include "clutter-entry.h"
#include "clutter-event.h" #include "clutter-event.h"
#include "clutter-feature.h" #include "clutter-feature.h"
#include "clutter-frame-source.h" #include "clutter-frame-source.h"
#include "clutter-group.h" #include "clutter-group.h"
#include "clutter-interval.h" #include "clutter-interval.h"
#include "clutter-keysyms.h" #include "clutter-keysyms.h"
#include "clutter-label.h"
#include "clutter-list-model.h" #include "clutter-list-model.h"
#include "clutter-main.h" #include "clutter-main.h"
#include "clutter-media.h" #include "clutter-media.h"
@ -69,6 +67,7 @@
#include "clutter-stage.h" #include "clutter-stage.h"
#include "clutter-stage-manager.h" #include "clutter-stage-manager.h"
#include "clutter-texture.h" #include "clutter-texture.h"
#include "clutter-text.h"
#include "clutter-timeline.h" #include "clutter-timeline.h"
#include "clutter-timeout-pool.h" #include "clutter-timeout-pool.h"
#include "clutter-types.h" #include "clutter-types.h"

View File

@ -385,6 +385,29 @@ void cogl_texture_polygon (CoglHandle handle,
CoglTextureVertex *vertices, CoglTextureVertex *vertices,
gboolean use_color); gboolean use_color);
/**
* cogl_texture_multiple_rectangles:
* @handle: a @CoglHandle.
* @verts: an array of vertices
* @n_rects: number of rectangles to draw
*
* Draws a series of rectangles in the same way that
* cogl_texture_rectangle() does. In some situations it can give a
* significant performance boost to use this function rather than
* calling cogl_texture_rectangle() separately for each rectangle.
*
* @verts should point to an array of #CoglFixed<!-- -->s with
* @n_rects * 8 elements. Each group of 8 values corresponds to the
* parameters x1, y1, x2, y2, tx1, ty1, tx2 and ty2 and have the same
* meaning as in cogl_texture_rectangle().
*
* Since: 1.0
*/
void cogl_texture_multiple_rectangles
(CoglHandle handle,
const CoglFixed *verts,
guint n_rects);
G_END_DECLS G_END_DECLS
#endif /* __COGL_TEXTURE_H__ */ #endif /* __COGL_TEXTURE_H__ */

View File

@ -56,8 +56,10 @@ cogl_create_context ()
_context->last_path = 0; _context->last_path = 0;
_context->texture_handles = NULL; _context->texture_handles = NULL;
_context->texture_vertices_size = 0; _context->texture_vertices = g_array_new (FALSE, FALSE,
_context->texture_vertices = NULL; sizeof (CoglTextureGLVertex));
_context->texture_indices = g_array_new (FALSE, FALSE,
sizeof (GLushort));
_context->fbo_handles = NULL; _context->fbo_handles = NULL;
_context->draw_buffer = COGL_WINDOW_BUFFER; _context->draw_buffer = COGL_WINDOW_BUFFER;
@ -148,6 +150,11 @@ cogl_destroy_context ()
if (_context->program_handles) if (_context->program_handles)
g_array_free (_context->program_handles, TRUE); g_array_free (_context->program_handles, TRUE);
if (_context->texture_vertices)
g_array_free (_context->texture_vertices, TRUE);
if (_context->texture_indices)
g_array_free (_context->texture_indices, TRUE);
g_free (_context); g_free (_context);
} }

View File

@ -63,8 +63,14 @@ typedef struct
/* Textures */ /* Textures */
GArray *texture_handles; GArray *texture_handles;
CoglTextureGLVertex *texture_vertices; GArray *texture_vertices;
gulong texture_vertices_size; GArray *texture_indices;
/* The gl texture number that the above vertices apply to. This to
detect when a different slice is encountered so that the vertices
can be flushed */
GLuint texture_current;
GLenum texture_target;
GLenum texture_wrap_mode;
/* Framebuffer objects */ /* Framebuffer objects */
GArray *fbo_handles; GArray *fbo_handles;

View File

@ -1911,6 +1911,95 @@ cogl_texture_get_data (CoglHandle handle,
return byte_size; return byte_size;
} }
static void
_cogl_texture_flush_vertices (void)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (ctx->texture_vertices->len > 0)
{
int needed_indices;
CoglTextureGLVertex *p
= (CoglTextureGLVertex *) ctx->texture_vertices->data;
/* The indices are always the same sequence regardless of the
vertices so we only need to change it if there are more
vertices than ever before */
needed_indices = ctx->texture_vertices->len / 4 * 6;
if (needed_indices > ctx->texture_indices->len)
{
int old_len = ctx->texture_indices->len;
int vert_num = old_len / 6 * 4;
int i;
GLushort *q;
/* Add two triangles for each quad to the list of
indices. That makes six new indices but two of the
vertices in the triangles are shared. */
g_array_set_size (ctx->texture_indices, needed_indices);
q = &g_array_index (ctx->texture_indices, GLushort, old_len);
for (i = old_len;
i < ctx->texture_indices->len;
i += 6, vert_num += 4)
{
*(q++) = vert_num + 0;
*(q++) = vert_num + 1;
*(q++) = vert_num + 3;
*(q++) = vert_num + 1;
*(q++) = vert_num + 2;
*(q++) = vert_num + 3;
}
}
GE( glVertexPointer (2, GL_FLOAT,
sizeof (CoglTextureGLVertex), p->v ) );
GE( glTexCoordPointer (2, GL_FLOAT,
sizeof (CoglTextureGLVertex), p->t ) );
GE( glBindTexture (ctx->texture_target, ctx->texture_current) );
GE( ctx->pf_glDrawRangeElements (GL_TRIANGLES,
0, ctx->texture_vertices->len - 1,
needed_indices,
GL_UNSIGNED_SHORT,
ctx->texture_indices->data) );
g_array_set_size (ctx->texture_vertices, 0);
}
}
static void
_cogl_texture_add_quad_vertices (GLfloat x1, GLfloat y1,
GLfloat x2, GLfloat y2,
GLfloat tx1, GLfloat ty1,
GLfloat tx2, GLfloat ty2)
{
CoglTextureGLVertex *p;
GLushort first_vert;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Add the four vertices of the quad to the list of queued
vertices */
first_vert = ctx->texture_vertices->len;
g_array_set_size (ctx->texture_vertices, first_vert + 4);
p = &g_array_index (ctx->texture_vertices, CoglTextureGLVertex, first_vert);
p->v[0] = x1; p->v[1] = y1;
p->t[0] = tx1; p->t[1] = ty1;
p++;
p->v[0] = x1; p->v[1] = y2;
p->t[0] = tx1; p->t[1] = ty2;
p++;
p->v[0] = x2; p->v[1] = y2;
p->t[0] = tx2; p->t[1] = ty2;
p++;
p->v[0] = x2; p->v[1] = y1;
p->t[0] = tx2; p->t[1] = ty1;
p++;
}
static void static void
_cogl_texture_quad_sw (CoglTexture *tex, _cogl_texture_quad_sw (CoglTexture *tex,
CoglFixed x1, CoglFixed x1,
@ -1931,11 +2020,7 @@ _cogl_texture_quad_sw (CoglTexture *tex,
CoglFixed slice_tx2 , slice_ty2; CoglFixed slice_tx2 , slice_ty2;
CoglFixed slice_qx1 , slice_qy1; CoglFixed slice_qx1 , slice_qy1;
CoglFixed slice_qx2 , slice_qy2; CoglFixed slice_qx2 , slice_qy2;
GLfloat tex_coords[8];
GLfloat quad_coords[8];
GLuint gl_handle; GLuint gl_handle;
gulong enable_flags = (COGL_ENABLE_VERTEX_ARRAY
| COGL_ENABLE_TEXCOORD_ARRAY);
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -1943,26 +2028,13 @@ _cogl_texture_quad_sw (CoglTexture *tex,
printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n"); printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n");
#endif #endif
/* Prepare GL state */
if (tex->gl_target == CGL_TEXTURE_RECTANGLE_ARB)
enable_flags |= COGL_ENABLE_TEXTURE_RECT;
else
enable_flags |= COGL_ENABLE_TEXTURE_2D;
if (ctx->color_alpha < 255
|| tex->bitmap.format & COGL_A_BIT)
{
enable_flags |= COGL_ENABLE_BLEND;
}
if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
cogl_enable (enable_flags);
/* We can't use hardware repeat so we need to set clamp to edge /* We can't use hardware repeat so we need to set clamp to edge
otherwise it might pull in edge pixels from the other side */ otherwise it might pull in edge pixels from the other side */
if (ctx->texture_vertices->len > 0
&& ctx->texture_wrap_mode != GL_CLAMP_TO_EDGE)
_cogl_texture_flush_vertices ();
_cogl_texture_set_wrap_mode_parameter (tex, GL_CLAMP_TO_EDGE); _cogl_texture_set_wrap_mode_parameter (tex, GL_CLAMP_TO_EDGE);
ctx->texture_wrap_mode = GL_CLAMP_TO_EDGE;
/* If the texture coordinates are backwards then swap both the /* If the texture coordinates are backwards then swap both the
geometry and texture coordinates so that the texture will be geometry and texture coordinates so that the texture will be
@ -1987,9 +2059,6 @@ _cogl_texture_quad_sw (CoglTexture *tex,
ty2 = temp; ty2 = temp;
} }
GE( glTexCoordPointer (2, GL_FLOAT, 0, tex_coords) );
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords) );
/* Scale ratio from texture to quad widths */ /* Scale ratio from texture to quad widths */
tw = COGL_FIXED_FROM_INT (tex->bitmap.width); tw = COGL_FIXED_FROM_INT (tex->bitmap.width);
th = COGL_FIXED_FROM_INT (tex->bitmap.height); th = COGL_FIXED_FROM_INT (tex->bitmap.height);
@ -2087,24 +2156,22 @@ _cogl_texture_quad_sw (CoglTexture *tex,
iter_y.index * iter_x.array->len + iter_y.index * iter_x.array->len +
iter_x.index); iter_x.index);
GE( glBindTexture (tex->gl_target, gl_handle) ); /* If we're using a different texture from the one already queued
then flush the vertices */
if (ctx->texture_vertices->len > 0
&& gl_handle != ctx->texture_current)
_cogl_texture_flush_vertices ();
ctx->texture_target = tex->gl_target;
ctx->texture_current = gl_handle;
#define CFX_F COGL_FIXED_TO_FLOAT _cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (slice_qx1),
COGL_FIXED_TO_FLOAT (slice_qy1),
/* Draw textured quad */ COGL_FIXED_TO_FLOAT (slice_qx2),
tex_coords[0] = CFX_F(slice_tx1); tex_coords[1] = CFX_F(slice_ty2); COGL_FIXED_TO_FLOAT (slice_qy2),
tex_coords[2] = CFX_F(slice_tx2); tex_coords[3] = CFX_F(slice_ty2); COGL_FIXED_TO_FLOAT (slice_tx1),
tex_coords[4] = CFX_F(slice_tx1); tex_coords[5] = CFX_F(slice_ty1); COGL_FIXED_TO_FLOAT (slice_ty1),
tex_coords[6] = CFX_F(slice_tx2); tex_coords[7] = CFX_F(slice_ty1); COGL_FIXED_TO_FLOAT (slice_tx2),
COGL_FIXED_TO_FLOAT (slice_ty2));
quad_coords[0] = CFX_F(slice_qx1); quad_coords[1] = CFX_F(slice_qy2);
quad_coords[2] = CFX_F(slice_qx2); quad_coords[3] = CFX_F(slice_qy2);
quad_coords[4] = CFX_F(slice_qx1); quad_coords[5] = CFX_F(slice_qy1);
quad_coords[6] = CFX_F(slice_qx2); quad_coords[7] = CFX_F(slice_qy1);
GE (glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
#undef CFX_F
} }
} }
} }
@ -2120,13 +2187,10 @@ _cogl_texture_quad_hw (CoglTexture *tex,
CoglFixed tx2, CoglFixed tx2,
CoglFixed ty2) CoglFixed ty2)
{ {
GLfloat tex_coords[8];
GLfloat quad_coords[8];
GLuint gl_handle; GLuint gl_handle;
CoglTexSliceSpan *x_span; CoglTexSliceSpan *x_span;
CoglTexSliceSpan *y_span; CoglTexSliceSpan *y_span;
gulong enable_flags = (COGL_ENABLE_VERTEX_ARRAY GLenum wrap_mode;
| COGL_ENABLE_TEXCOORD_ARRAY);
#if COGL_DEBUG #if COGL_DEBUG
printf("=== Drawing Tex Quad (Hardware Tiling Mode) ===\n"); printf("=== Drawing Tex Quad (Hardware Tiling Mode) ===\n");
@ -2134,24 +2198,6 @@ _cogl_texture_quad_hw (CoglTexture *tex,
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Prepare GL state */
if (tex->gl_target == CGL_TEXTURE_RECTANGLE_ARB)
enable_flags |= COGL_ENABLE_TEXTURE_RECT;
else
enable_flags |= COGL_ENABLE_TEXTURE_2D;
if (ctx->color_alpha < 255
|| tex->bitmap.format & COGL_A_BIT)
{
enable_flags |= COGL_ENABLE_BLEND;
}
if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
cogl_enable (enable_flags);
/* If the texture coords are all in the range [0,1] then we want to /* If the texture coords are all in the range [0,1] then we want to
clamp the coords to the edge otherwise it can pull in edge pixels clamp the coords to the edge otherwise it can pull in edge pixels
from the wrong side when scaled */ from the wrong side when scaled */
@ -2159,16 +2205,24 @@ _cogl_texture_quad_hw (CoglTexture *tex,
&& tx2 >= 0 && tx2 <= COGL_FIXED_1 && tx2 >= 0 && tx2 <= COGL_FIXED_1
&& ty1 >= 0 && ty1 <= COGL_FIXED_1 && ty1 >= 0 && ty1 <= COGL_FIXED_1
&& ty2 >= 0 && ty2 <= COGL_FIXED_1) && ty2 >= 0 && ty2 <= COGL_FIXED_1)
_cogl_texture_set_wrap_mode_parameter (tex, GL_CLAMP_TO_EDGE); wrap_mode = GL_CLAMP_TO_EDGE;
else else
_cogl_texture_set_wrap_mode_parameter (tex, GL_REPEAT); wrap_mode = GL_REPEAT;
GE( glTexCoordPointer (2, GL_FLOAT, 0, tex_coords) );
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords) );
/* Pick and bind opengl texture object */ /* Pick and bind opengl texture object */
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, 0); gl_handle = g_array_index (tex->slice_gl_handles, GLuint, 0);
GE( glBindTexture (tex->gl_target, gl_handle) );
/* If we're using a different texture from the one already queued
then flush the vertices */
if (ctx->texture_vertices->len > 0
&& (gl_handle != ctx->texture_current
|| ctx->texture_wrap_mode != wrap_mode))
_cogl_texture_flush_vertices ();
ctx->texture_target = tex->gl_target;
ctx->texture_current = gl_handle;
ctx->texture_wrap_mode = wrap_mode;
_cogl_texture_set_wrap_mode_parameter (tex, wrap_mode);
/* Don't include the waste in the texture coordinates */ /* Don't include the waste in the texture coordinates */
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0); x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0);
@ -2189,36 +2243,26 @@ _cogl_texture_quad_hw (CoglTexture *tex,
ty2 *= y_span->size; ty2 *= y_span->size;
} }
#define CFX_F(x) COGL_FIXED_TO_FLOAT(x) _cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (x1),
COGL_FIXED_TO_FLOAT (y1),
/* Draw textured quad */ COGL_FIXED_TO_FLOAT (x2),
tex_coords[0] = CFX_F(tx1); tex_coords[1] = CFX_F(ty2); COGL_FIXED_TO_FLOAT (y2),
tex_coords[2] = CFX_F(tx2); tex_coords[3] = CFX_F(ty2); COGL_FIXED_TO_FLOAT (tx1),
tex_coords[4] = CFX_F(tx1); tex_coords[5] = CFX_F(ty1); COGL_FIXED_TO_FLOAT (ty1),
tex_coords[6] = CFX_F(tx2); tex_coords[7] = CFX_F(ty1); COGL_FIXED_TO_FLOAT (tx2),
COGL_FIXED_TO_FLOAT (ty2));
quad_coords[0] = CFX_F(x1); quad_coords[1] = CFX_F(y2);
quad_coords[2] = CFX_F(x2); quad_coords[3] = CFX_F(y2);
quad_coords[4] = CFX_F(x1); quad_coords[5] = CFX_F(y1);
quad_coords[6] = CFX_F(x2); quad_coords[7] = CFX_F(y1);
GE (glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
#undef CFX_F
} }
void void
cogl_texture_rectangle (CoglHandle handle, cogl_texture_multiple_rectangles (CoglHandle handle,
CoglFixed x1, const CoglFixed *verts,
CoglFixed y1, guint n_rects)
CoglFixed x2,
CoglFixed y2,
CoglFixed tx1,
CoglFixed ty1,
CoglFixed tx2,
CoglFixed ty2)
{ {
CoglTexture *tex; CoglTexture *tex;
gulong enable_flags = (COGL_ENABLE_VERTEX_ARRAY
| COGL_ENABLE_TEXCOORD_ARRAY);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Check if valid texture */ /* Check if valid texture */
if (!cogl_is_texture (handle)) if (!cogl_is_texture (handle))
@ -2235,22 +2279,73 @@ cogl_texture_rectangle (CoglHandle handle,
if (tex->slice_gl_handles->len == 0) if (tex->slice_gl_handles->len == 0)
return; return;
if (tx1 == tx2 || ty1 == ty2) /* Prepare GL state */
return; if (tex->gl_target == CGL_TEXTURE_RECTANGLE_ARB)
enable_flags |= COGL_ENABLE_TEXTURE_RECT;
else
enable_flags |= COGL_ENABLE_TEXTURE_2D;
/* If there is only one GL texture and either the texture is NPOT if (ctx->color_alpha < 255
(no waste) or all of the coordinates are in the range [0,1] then || tex->bitmap.format & COGL_A_BIT)
we can use hardware tiling */ enable_flags |= COGL_ENABLE_BLEND;
if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
cogl_enable (enable_flags);
g_array_set_size (ctx->texture_vertices, 0);
while (n_rects-- > 0)
{
if (verts[4] != verts[6] && verts[5] != verts[7])
{
/* If there is only one GL texture and either the texture is
NPOT (no waste) or all of the coordinates are in the
range [0,1] then we can use hardware tiling */
if (tex->slice_gl_handles->len == 1 if (tex->slice_gl_handles->len == 1
&& ((cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) && ((cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)
&& tex->gl_target == GL_TEXTURE_2D) && tex->gl_target == GL_TEXTURE_2D)
|| (tx1 >= 0 && tx1 <= COGL_FIXED_1 || (verts[4] >= 0 && verts[4] <= COGL_FIXED_1
&& tx2 >= 0 && tx2 <= COGL_FIXED_1 && verts[6] >= 0 && verts[6] <= COGL_FIXED_1
&& ty1 >= 0 && ty1 <= COGL_FIXED_1 && verts[5] >= 0 && verts[5] <= COGL_FIXED_1
&& ty2 >= 0 && ty2 <= COGL_FIXED_1))) && verts[7] >= 0 && verts[7] <= COGL_FIXED_1)))
_cogl_texture_quad_hw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2); _cogl_texture_quad_hw (tex, verts[0],verts[1], verts[2],verts[3],
verts[4],verts[5], verts[6],verts[7]);
else else
_cogl_texture_quad_sw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2); _cogl_texture_quad_sw (tex, verts[0],verts[1], verts[2],verts[3],
verts[4],verts[5], verts[6],verts[7]);
}
verts += 8;
}
_cogl_texture_flush_vertices ();
}
void
cogl_texture_rectangle (CoglHandle handle,
CoglFixed x1,
CoglFixed y1,
CoglFixed x2,
CoglFixed y2,
CoglFixed tx1,
CoglFixed ty1,
CoglFixed tx2,
CoglFixed ty2)
{
CoglFixed verts[8];
verts[0] = x1;
verts[1] = y1;
verts[2] = x2;
verts[3] = y2;
verts[4] = tx1;
verts[5] = ty1;
verts[6] = tx2;
verts[7] = ty2;
cogl_texture_multiple_rectangles (handle, verts, 1);
} }
void void
@ -2299,22 +2394,8 @@ cogl_texture_polygon (CoglHandle handle,
/* Make sure there is enough space in the global texture vertex /* Make sure there is enough space in the global texture vertex
array. This is used so we can render the polygon with a single array. This is used so we can render the polygon with a single
call to OpenGL but still support any number of vertices */ call to OpenGL but still support any number of vertices */
if (ctx->texture_vertices_size < n_vertices) g_array_set_size (ctx->texture_vertices, n_vertices);
{ p = (CoglTextureGLVertex *) ctx->texture_vertices->data;
guint nsize = ctx->texture_vertices_size;
if (nsize == 0)
nsize = 1;
do
nsize *= 2;
while (nsize < n_vertices);
ctx->texture_vertices_size = nsize;
ctx->texture_vertices = g_realloc (ctx->texture_vertices,
nsize
* sizeof (CoglTextureGLVertex));
}
/* Prepare GL state */ /* Prepare GL state */
enable_flags = (COGL_ENABLE_VERTEX_ARRAY enable_flags = (COGL_ENABLE_VERTEX_ARRAY
@ -2332,14 +2413,12 @@ cogl_texture_polygon (CoglHandle handle,
if (use_color) if (use_color)
{ {
enable_flags |= COGL_ENABLE_COLOR_ARRAY; enable_flags |= COGL_ENABLE_COLOR_ARRAY;
GE( glColorPointer (4, GL_UNSIGNED_BYTE, sizeof (CoglTextureGLVertex), GE( glColorPointer (4, GL_UNSIGNED_BYTE,
ctx->texture_vertices[0].c) ); sizeof (CoglTextureGLVertex), p->c) );
} }
GE( glVertexPointer (3, GL_FLOAT, sizeof (CoglTextureGLVertex), GE( glVertexPointer (3, GL_FLOAT, sizeof (CoglTextureGLVertex), p->v ) );
ctx->texture_vertices[0].v) ); GE( glTexCoordPointer (2, GL_FLOAT, sizeof (CoglTextureGLVertex), p->t ) );
GE( glTexCoordPointer (2, GL_FLOAT, sizeof (CoglTextureGLVertex),
ctx->texture_vertices[0].t) );
cogl_enable (enable_flags); cogl_enable (enable_flags);
@ -2362,9 +2441,11 @@ cogl_texture_polygon (CoglHandle handle,
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, tex_num++); gl_handle = g_array_index (tex->slice_gl_handles, GLuint, tex_num++);
p = (CoglTextureGLVertex *) ctx->texture_vertices->data;
/* Convert the vertices into an array of GLfloats ready to pass to /* Convert the vertices into an array of GLfloats ready to pass to
OpenGL */ OpenGL */
for (i = 0, p = ctx->texture_vertices; i < n_vertices; i++, p++) for (i = 0; i < n_vertices; i++, p++)
{ {
CoglFixed tx, ty; CoglFixed tx, ty;

View File

@ -59,8 +59,10 @@ cogl_create_context ()
_context->last_path = 0; _context->last_path = 0;
_context->texture_handles = NULL; _context->texture_handles = NULL;
_context->texture_vertices_size = 0; _context->texture_vertices = g_array_new (FALSE, FALSE,
_context->texture_vertices = NULL; sizeof (CoglTextureGLVertex));
_context->texture_indices = g_array_new (FALSE, FALSE,
sizeof (GLushort));
_context->fbo_handles = NULL; _context->fbo_handles = NULL;
_context->program_handles = NULL; _context->program_handles = NULL;
@ -104,7 +106,9 @@ cogl_destroy_context ()
#endif #endif
if (_context->texture_vertices) if (_context->texture_vertices)
g_free (_context->texture_vertices); g_array_free (_context->texture_vertices, TRUE);
if (_context->texture_indices)
g_array_free (_context->texture_indices, TRUE);
if (_context->texture_handles) if (_context->texture_handles)
g_array_free (_context->texture_handles, TRUE); g_array_free (_context->texture_handles, TRUE);

View File

@ -65,8 +65,13 @@ typedef struct
/* Textures */ /* Textures */
GArray *texture_handles; GArray *texture_handles;
CoglTextureGLVertex *texture_vertices; GArray *texture_vertices;
gulong texture_vertices_size; GArray *texture_indices;
/* The gl texture number that the above vertices apply to. This to
detect when a different slice is encountered so that the vertices
can be flushed */
GLuint texture_current;
GLenum texture_target;
/* Framebuffer objects */ /* Framebuffer objects */
GArray *fbo_handles; GArray *fbo_handles;

View File

@ -2047,6 +2047,94 @@ cogl_texture_get_data (CoglHandle handle,
return byte_size; return byte_size;
} }
static void
_cogl_texture_flush_vertices (void)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (ctx->texture_vertices->len > 0)
{
int needed_indices;
CoglTextureGLVertex *p
= (CoglTextureGLVertex *) ctx->texture_vertices->data;
/* The indices are always the same sequence regardless of the
vertices so we only need to change it if there are more
vertices than ever before */
needed_indices = ctx->texture_vertices->len / 4 * 6;
if (needed_indices > ctx->texture_indices->len)
{
int old_len = ctx->texture_indices->len;
int vert_num = old_len / 6 * 4;
int i;
GLushort *q;
/* Add two triangles for each quad to the list of
indices. That makes six new indices but two of the
vertices in the triangles are shared. */
g_array_set_size (ctx->texture_indices, needed_indices);
q = &g_array_index (ctx->texture_indices, GLushort, old_len);
for (i = old_len;
i < ctx->texture_indices->len;
i += 6, vert_num += 4)
{
*(q++) = vert_num + 0;
*(q++) = vert_num + 1;
*(q++) = vert_num + 3;
*(q++) = vert_num + 1;
*(q++) = vert_num + 2;
*(q++) = vert_num + 3;
}
}
GE( glVertexPointer (2, GL_FLOAT,
sizeof (CoglTextureGLVertex), p->v ) );
GE( glTexCoordPointer (2, GL_FLOAT,
sizeof (CoglTextureGLVertex), p->t ) );
GE( glBindTexture (ctx->texture_target, ctx->texture_current) );
GE( glDrawElements (GL_TRIANGLES,
needed_indices,
GL_UNSIGNED_SHORT,
ctx->texture_indices->data) );
g_array_set_size (ctx->texture_vertices, 0);
}
}
static void
_cogl_texture_add_quad_vertices (GLfloat x1, GLfloat y1,
GLfloat x2, GLfloat y2,
GLfloat tx1, GLfloat ty1,
GLfloat tx2, GLfloat ty2)
{
CoglTextureGLVertex *p;
GLushort first_vert;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Add the four vertices of the quad to the list of queued
vertices */
first_vert = ctx->texture_vertices->len;
g_array_set_size (ctx->texture_vertices, first_vert + 4);
p = &g_array_index (ctx->texture_vertices, CoglTextureGLVertex, first_vert);
p->v[0] = x1; p->v[1] = y1;
p->t[0] = tx1; p->t[1] = ty1;
p++;
p->v[0] = x1; p->v[1] = y2;
p->t[0] = tx1; p->t[1] = ty2;
p++;
p->v[0] = x2; p->v[1] = y2;
p->t[0] = tx2; p->t[1] = ty2;
p++;
p->v[0] = x2; p->v[1] = y1;
p->t[0] = tx2; p->t[1] = ty1;
p++;
}
static void static void
_cogl_texture_quad_sw (CoglTexture *tex, _cogl_texture_quad_sw (CoglTexture *tex,
CoglFixed x1, CoglFixed x1,
@ -2067,12 +2155,7 @@ _cogl_texture_quad_sw (CoglTexture *tex,
CoglFixed slice_tx2 , slice_ty2; CoglFixed slice_tx2 , slice_ty2;
CoglFixed slice_qx1 , slice_qy1; CoglFixed slice_qx1 , slice_qy1;
CoglFixed slice_qx2 , slice_qy2; CoglFixed slice_qx2 , slice_qy2;
GLfloat tex_coords[8];
GLfloat quad_coords[8];
GLuint gl_handle; GLuint gl_handle;
gulong enable_flags = (COGL_ENABLE_TEXTURE_2D
| COGL_ENABLE_VERTEX_ARRAY
| COGL_ENABLE_TEXCOORD_ARRAY);
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -2080,19 +2163,6 @@ _cogl_texture_quad_sw (CoglTexture *tex,
printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n"); printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n");
#endif #endif
/* Prepare GL state */
if (ctx->color_alpha < 255
|| tex->bitmap.format & COGL_A_BIT)
{
enable_flags |= COGL_ENABLE_BLEND;
}
if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
cogl_enable (enable_flags);
/* If the texture coordinates are backwards then swap both the /* If the texture coordinates are backwards then swap both the
geometry and texture coordinates so that the texture will be geometry and texture coordinates so that the texture will be
flipped but we can still use the same algorithm to iterate the flipped but we can still use the same algorithm to iterate the
@ -2116,9 +2186,6 @@ _cogl_texture_quad_sw (CoglTexture *tex,
ty2 = temp; ty2 = temp;
} }
GE( glTexCoordPointer (2, GL_FLOAT, 0, tex_coords) );
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords) );
/* Scale ratio from texture to quad widths */ /* Scale ratio from texture to quad widths */
tw = COGL_FIXED_FROM_INT (tex->bitmap.width); tw = COGL_FIXED_FROM_INT (tex->bitmap.width);
th = COGL_FIXED_FROM_INT (tex->bitmap.height); th = COGL_FIXED_FROM_INT (tex->bitmap.height);
@ -2168,7 +2235,6 @@ _cogl_texture_quad_sw (CoglTexture *tex,
slice_ty1 /= iter_y.span->size; slice_ty1 /= iter_y.span->size;
slice_ty2 /= iter_y.span->size; slice_ty2 /= iter_y.span->size;
/* Iterate until whole quad width covered */ /* Iterate until whole quad width covered */
for (_cogl_span_iter_begin (&iter_x, tex->slice_x_spans, for (_cogl_span_iter_begin (&iter_x, tex->slice_x_spans,
first_tx, tx1, tx2) ; first_tx, tx1, tx2) ;
@ -2211,25 +2277,22 @@ _cogl_texture_quad_sw (CoglTexture *tex,
iter_y.index * iter_x.array->len + iter_y.index * iter_x.array->len +
iter_x.index); iter_x.index);
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target, gl_handle, /* If we're using a different texture from the one already queued
tex->gl_intformat) ); then flush the vertices */
if (ctx->texture_vertices->len > 0
&& gl_handle != ctx->texture_current)
_cogl_texture_flush_vertices ();
ctx->texture_target = tex->gl_target;
ctx->texture_current = gl_handle;
#define CFX_F COGL_FIXED_TO_FLOAT _cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (slice_qx1),
COGL_FIXED_TO_FLOAT (slice_qy1),
/* Draw textured quad */ COGL_FIXED_TO_FLOAT (slice_qx2),
tex_coords[0] = CFX_F(slice_tx1); tex_coords[1] = CFX_F(slice_ty2); COGL_FIXED_TO_FLOAT (slice_qy2),
tex_coords[2] = CFX_F(slice_tx2); tex_coords[3] = CFX_F(slice_ty2); COGL_FIXED_TO_FLOAT (slice_tx1),
tex_coords[4] = CFX_F(slice_tx1); tex_coords[5] = CFX_F(slice_ty1); COGL_FIXED_TO_FLOAT (slice_ty1),
tex_coords[6] = CFX_F(slice_tx2); tex_coords[7] = CFX_F(slice_ty1); COGL_FIXED_TO_FLOAT (slice_tx2),
COGL_FIXED_TO_FLOAT (slice_ty2));
quad_coords[0] = CFX_F(slice_qx1); quad_coords[1] = CFX_F(slice_qy2);
quad_coords[2] = CFX_F(slice_qx2); quad_coords[3] = CFX_F(slice_qy2);
quad_coords[4] = CFX_F(slice_qx1); quad_coords[5] = CFX_F(slice_qy1);
quad_coords[6] = CFX_F(slice_qx2); quad_coords[7] = CFX_F(slice_qy1);
GE (glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
#undef CFX_F
} }
} }
} }
@ -2245,14 +2308,9 @@ _cogl_texture_quad_hw (CoglTexture *tex,
CoglFixed tx2, CoglFixed tx2,
CoglFixed ty2) CoglFixed ty2)
{ {
GLfloat tex_coords[8];
GLfloat quad_coords[8];
GLuint gl_handle; GLuint gl_handle;
CoglTexSliceSpan *x_span; CoglTexSliceSpan *x_span;
CoglTexSliceSpan *y_span; CoglTexSliceSpan *y_span;
gulong enable_flags = (COGL_ENABLE_TEXTURE_2D
| COGL_ENABLE_VERTEX_ARRAY
| COGL_ENABLE_TEXCOORD_ARRAY);
#if COGL_DEBUG #if COGL_DEBUG
printf("=== Drawing Tex Quad (Hardware Tiling Mode) ===\n"); printf("=== Drawing Tex Quad (Hardware Tiling Mode) ===\n");
@ -2260,25 +2318,16 @@ _cogl_texture_quad_hw (CoglTexture *tex,
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Prepare GL state */
if (ctx->color_alpha < 255
|| tex->bitmap.format & COGL_A_BIT)
{
enable_flags |= COGL_ENABLE_BLEND;
}
if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
cogl_enable (enable_flags);
GE( glTexCoordPointer (2, GL_FLOAT, 0, tex_coords) );
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords) );
/* Pick and bind opengl texture object */ /* Pick and bind opengl texture object */
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, 0); gl_handle = g_array_index (tex->slice_gl_handles, GLuint, 0);
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target, gl_handle,
tex->gl_intformat) ); /* If we're using a different texture from the one already queued
then flush the vertices */
if (ctx->texture_vertices->len > 0
&& gl_handle != ctx->texture_current)
_cogl_texture_flush_vertices ();
ctx->texture_target = tex->gl_target;
ctx->texture_current = gl_handle;
/* Don't include the waste in the texture coordinates */ /* Don't include the waste in the texture coordinates */
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0); x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0);
@ -2290,36 +2339,27 @@ _cogl_texture_quad_hw (CoglTexture *tex,
ty1 = ty1 * (y_span->size - y_span->waste) / y_span->size; ty1 = ty1 * (y_span->size - y_span->waste) / y_span->size;
ty2 = ty2 * (y_span->size - y_span->waste) / y_span->size; ty2 = ty2 * (y_span->size - y_span->waste) / y_span->size;
#define CFX_F(x) COGL_FIXED_TO_FLOAT(x) _cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (x1),
COGL_FIXED_TO_FLOAT (y1),
/* Draw textured quad */ COGL_FIXED_TO_FLOAT (x2),
tex_coords[0] = CFX_F(tx1); tex_coords[1] = CFX_F(ty2); COGL_FIXED_TO_FLOAT (y2),
tex_coords[2] = CFX_F(tx2); tex_coords[3] = CFX_F(ty2); COGL_FIXED_TO_FLOAT (tx1),
tex_coords[4] = CFX_F(tx1); tex_coords[5] = CFX_F(ty1); COGL_FIXED_TO_FLOAT (ty1),
tex_coords[6] = CFX_F(tx2); tex_coords[7] = CFX_F(ty1); COGL_FIXED_TO_FLOAT (tx2),
COGL_FIXED_TO_FLOAT (ty2));
quad_coords[0] = CFX_F(x1); quad_coords[1] = CFX_F(y2);
quad_coords[2] = CFX_F(x2); quad_coords[3] = CFX_F(y2);
quad_coords[4] = CFX_F(x1); quad_coords[5] = CFX_F(y1);
quad_coords[6] = CFX_F(x2); quad_coords[7] = CFX_F(y1);
GE (glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
#undef CFX_F
} }
void void
cogl_texture_rectangle (CoglHandle handle, cogl_texture_multiple_rectangles (CoglHandle handle,
CoglFixed x1, const CoglFixed *verts,
CoglFixed y1, guint n_rects)
CoglFixed x2,
CoglFixed y2,
CoglFixed tx1,
CoglFixed ty1,
CoglFixed tx2,
CoglFixed ty2)
{ {
CoglTexture *tex; CoglTexture *tex;
gulong enable_flags = (COGL_ENABLE_VERTEX_ARRAY
| COGL_ENABLE_TEXCOORD_ARRAY
| COGL_ENABLE_TEXTURE_2D);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Check if valid texture */ /* Check if valid texture */
if (!cogl_is_texture (handle)) if (!cogl_is_texture (handle))
@ -2336,30 +2376,68 @@ cogl_texture_rectangle (CoglHandle handle,
if (tex->slice_gl_handles->len == 0) if (tex->slice_gl_handles->len == 0)
return; return;
if (tx1 == tx2 || ty1 == ty2) /* Prepare GL state */
return; if (ctx->color_alpha < 255
|| tex->bitmap.format & COGL_A_BIT)
enable_flags |= COGL_ENABLE_BLEND;
/* Pick tiling mode according to hw support */ if (ctx->enable_backface_culling)
if (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
&& tex->slice_gl_handles->len == 1)
cogl_enable (enable_flags);
g_array_set_size (ctx->texture_vertices, 0);
while (n_rects-- > 0)
{ {
_cogl_texture_quad_hw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2); if (verts[4] != verts[6] && verts[5] != verts[7])
}
else
{ {
/* If there is only one GL texture and either the texture is
NPOT (no waste) or all of the coordinates are in the
range [0,1] then we can use hardware tiling */
if (tex->slice_gl_handles->len == 1 if (tex->slice_gl_handles->len == 1
&& tx1 >= -COGL_FIXED_1 && ((cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)
&& tx2 <= COGL_FIXED_1 && tex->gl_target == GL_TEXTURE_2D)
&& ty1 >= -COGL_FIXED_1 || (verts[4] >= 0 && verts[4] <= COGL_FIXED_1
&& ty2 <= COGL_FIXED_1) && verts[6] >= 0 && verts[6] <= COGL_FIXED_1
{ && verts[5] >= 0 && verts[5] <= COGL_FIXED_1
_cogl_texture_quad_hw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2); && verts[7] >= 0 && verts[7] <= COGL_FIXED_1)))
} _cogl_texture_quad_hw (tex, verts[0],verts[1], verts[2],verts[3],
verts[4],verts[5], verts[6],verts[7]);
else else
_cogl_texture_quad_sw (tex, verts[0],verts[1], verts[2],verts[3],
verts[4],verts[5], verts[6],verts[7]);
}
verts += 8;
}
_cogl_texture_flush_vertices ();
}
void
cogl_texture_rectangle (CoglHandle handle,
CoglFixed x1,
CoglFixed y1,
CoglFixed x2,
CoglFixed y2,
CoglFixed tx1,
CoglFixed ty1,
CoglFixed tx2,
CoglFixed ty2)
{ {
_cogl_texture_quad_sw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2); CoglFixed verts[8];
}
} verts[0] = x1;
verts[1] = y1;
verts[2] = x2;
verts[3] = y2;
verts[4] = tx1;
verts[5] = ty1;
verts[6] = tx2;
verts[7] = ty2;
cogl_texture_multiple_rectangles (handle, verts, 1);
} }
void void
@ -2405,22 +2483,8 @@ cogl_texture_polygon (CoglHandle handle,
/* Make sure there is enough space in the global texture vertex /* Make sure there is enough space in the global texture vertex
array. This is used so we can render the polygon with a single array. This is used so we can render the polygon with a single
call to OpenGL but still support any number of vertices */ call to OpenGL but still support any number of vertices */
if (ctx->texture_vertices_size < n_vertices) g_array_set_size (ctx->texture_vertices, n_vertices);
{ p = (CoglTextureGLVertex *) ctx->texture_vertices->data;
guint nsize = ctx->texture_vertices_size;
if (nsize == 0)
nsize = 1;
do
nsize *= 2;
while (nsize < n_vertices);
ctx->texture_vertices_size = nsize;
ctx->texture_vertices = g_realloc (ctx->texture_vertices,
nsize
* sizeof (CoglTextureGLVertex));
}
/* Prepare GL state */ /* Prepare GL state */
enable_flags = (COGL_ENABLE_TEXTURE_2D enable_flags = (COGL_ENABLE_TEXTURE_2D
@ -2447,14 +2511,12 @@ cogl_texture_polygon (CoglHandle handle,
if (use_color) if (use_color)
{ {
enable_flags |= COGL_ENABLE_COLOR_ARRAY; enable_flags |= COGL_ENABLE_COLOR_ARRAY;
GE( glColorPointer (4, GL_UNSIGNED_BYTE, sizeof (CoglTextureGLVertex), GE( glColorPointer (4, GL_UNSIGNED_BYTE,
ctx->texture_vertices[0].c) ); sizeof (CoglTextureGLVertex), p->c) );
} }
GE( glVertexPointer (3, GL_FLOAT, sizeof (CoglTextureGLVertex), GE( glVertexPointer (3, GL_FLOAT, sizeof (CoglTextureGLVertex), p->v ) );
ctx->texture_vertices[0].v) ); GE( glTexCoordPointer (2, GL_FLOAT, sizeof (CoglTextureGLVertex), p->t ) );
GE( glTexCoordPointer (2, GL_FLOAT, sizeof (CoglTextureGLVertex),
ctx->texture_vertices[0].t) );
cogl_enable (enable_flags); cogl_enable (enable_flags);
@ -2464,7 +2526,7 @@ cogl_texture_polygon (CoglHandle handle,
/* Convert the vertices into an array of GLfloats ready to pass to /* Convert the vertices into an array of GLfloats ready to pass to
OpenGL */ OpenGL */
for (i = 0, p = ctx->texture_vertices; i < n_vertices; i++, p++) for (i = 0; i < n_vertices; i++, p++)
{ {
#define CFX_F COGL_FIXED_TO_FLOAT #define CFX_F COGL_FIXED_TO_FLOAT

View File

@ -29,6 +29,8 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#include <glib/gi18n-lib.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <fcntl.h> #include <fcntl.h>
@ -150,7 +152,7 @@ static const GOptionEntry entries[] =
{ "vblank", 0, { "vblank", 0,
0, 0,
G_OPTION_ARG_STRING, &clutter_vblank_name, G_OPTION_ARG_STRING, &clutter_vblank_name,
"VBlank method to be used (none, dri or glx)", "METHOD" N_("VBlank method to be used (none, dri or glx)"), "METHOD"
}, },
{ NULL } { NULL }
}; };

View File

@ -51,6 +51,10 @@ struct _CoglPangoRenderer
CoglPangoGlyphCache *mipmapped_glyph_cache; CoglPangoGlyphCache *mipmapped_glyph_cache;
gboolean use_mipmapping; gboolean use_mipmapping;
/* Array of rectangles to draw from the current texture */
GArray *glyph_rectangles;
CoglHandle glyph_texture;
}; };
struct _CoglPangoRendererClass struct _CoglPangoRendererClass
@ -58,6 +62,46 @@ struct _CoglPangoRendererClass
PangoRendererClass class_instance; PangoRendererClass class_instance;
}; };
static void
cogl_pango_renderer_glyphs_end (CoglPangoRenderer *priv)
{
if (priv->glyph_rectangles->len > 0)
{
CoglFixed *rectangles = (CoglFixed *) priv->glyph_rectangles->data;
cogl_texture_multiple_rectangles (priv->glyph_texture, rectangles,
priv->glyph_rectangles->len / 8);
g_array_set_size (priv->glyph_rectangles, 0);
}
}
static void
cogl_pango_renderer_draw_glyph (CoglPangoRenderer *priv,
CoglPangoGlyphCacheValue *cache_value,
CoglFixed x1,
CoglFixed y1)
{
CoglFixed x2, y2;
CoglFixed *p;
if (priv->glyph_rectangles->len > 0
&& priv->glyph_texture != cache_value->texture)
cogl_pango_renderer_glyphs_end (priv);
priv->glyph_texture = cache_value->texture;
x2 = x1 + CLUTTER_INT_TO_FIXED (cache_value->draw_width);
y2 = y1 + CLUTTER_INT_TO_FIXED (cache_value->draw_height);
g_array_set_size (priv->glyph_rectangles, priv->glyph_rectangles->len + 8);
p = &g_array_index (priv->glyph_rectangles, CoglFixed,
priv->glyph_rectangles->len - 8);
*(p++) = x1; *(p++) = y1;
*(p++) = x2; *(p++) = y2;
*(p++) = cache_value->tx1; *(p++) = cache_value->ty1;
*(p++) = cache_value->tx2; *(p++) = cache_value->ty2;
}
#define COGL_PANGO_UNIT_TO_FIXED(x) ((x) << (COGL_FIXED_Q - 10)) #define COGL_PANGO_UNIT_TO_FIXED(x) ((x) << (COGL_FIXED_Q - 10))
static void cogl_pango_renderer_finalize (GObject *object); static void cogl_pango_renderer_finalize (GObject *object);
@ -89,6 +133,7 @@ cogl_pango_renderer_init (CoglPangoRenderer *priv)
priv->glyph_cache = cogl_pango_glyph_cache_new (FALSE); priv->glyph_cache = cogl_pango_glyph_cache_new (FALSE);
priv->mipmapped_glyph_cache = cogl_pango_glyph_cache_new (TRUE); priv->mipmapped_glyph_cache = cogl_pango_glyph_cache_new (TRUE);
priv->use_mipmapping = FALSE; priv->use_mipmapping = FALSE;
priv->glyph_rectangles = g_array_new (FALSE, FALSE, sizeof (CoglFixed));
} }
static void static void
@ -111,6 +156,7 @@ cogl_pango_renderer_finalize (GObject *object)
cogl_pango_glyph_cache_free (priv->mipmapped_glyph_cache); cogl_pango_glyph_cache_free (priv->mipmapped_glyph_cache);
cogl_pango_glyph_cache_free (priv->glyph_cache); cogl_pango_glyph_cache_free (priv->glyph_cache);
g_array_free (priv->glyph_rectangles, TRUE);
G_OBJECT_CLASS (cogl_pango_renderer_parent_class)->finalize (object); G_OBJECT_CLASS (cogl_pango_renderer_parent_class)->finalize (object);
} }
@ -454,6 +500,7 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer,
int xi, int xi,
int yi) int yi)
{ {
CoglPangoRenderer *priv = (CoglPangoRenderer *) renderer;
CoglPangoGlyphCacheValue *cache_value; CoglPangoGlyphCacheValue *cache_value;
int i; int i;
@ -474,6 +521,8 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer,
{ {
PangoFontMetrics *metrics; PangoFontMetrics *metrics;
cogl_pango_renderer_glyphs_end (priv);
if (font == NULL || if (font == NULL ||
(metrics = pango_font_get_metrics (font, NULL)) == NULL) (metrics = pango_font_get_metrics (font, NULL)) == NULL)
{ {
@ -503,10 +552,14 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer,
gi->glyph); gi->glyph);
if (cache_value == NULL) if (cache_value == NULL)
{
cogl_pango_renderer_glyphs_end (priv);
cogl_pango_renderer_draw_box (COGL_FIXED_TO_INT (x), cogl_pango_renderer_draw_box (COGL_FIXED_TO_INT (x),
COGL_FIXED_TO_INT (y), COGL_FIXED_TO_INT (y),
PANGO_UNKNOWN_GLYPH_WIDTH, PANGO_UNKNOWN_GLYPH_WIDTH,
PANGO_UNKNOWN_GLYPH_HEIGHT); PANGO_UNKNOWN_GLYPH_HEIGHT);
}
else else
{ {
CoglFixed width, height; CoglFixed width, height;
@ -517,15 +570,12 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer,
width = x + COGL_FIXED_FROM_INT (cache_value->draw_width); width = x + COGL_FIXED_FROM_INT (cache_value->draw_width);
height = y + COGL_FIXED_FROM_INT (cache_value->draw_height); height = y + COGL_FIXED_FROM_INT (cache_value->draw_height);
/* Render the glyph from the texture */ cogl_pango_renderer_draw_glyph (priv, cache_value, x, y);
cogl_texture_rectangle (cache_value->texture,
x, y,
width, height,
cache_value->tx1, cache_value->ty1,
cache_value->tx2, cache_value->ty2);
} }
} }
xi += gi->geometry.width; xi += gi->geometry.width;
} }
cogl_pango_renderer_glyphs_end (priv);
} }

View File

@ -23,6 +23,8 @@
#include "config.h" #include "config.h"
#endif #endif
#include <glib/gi18n-lib.h>
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
@ -235,18 +237,18 @@ static const GOptionEntry entries[] =
"display", 0, "display", 0,
G_OPTION_FLAG_IN_MAIN, G_OPTION_FLAG_IN_MAIN,
G_OPTION_ARG_STRING, &clutter_display_name, G_OPTION_ARG_STRING, &clutter_display_name,
"X display to use", "DISPLAY" N_("X display to use"), "DISPLAY"
}, },
{ {
"screen", 0, "screen", 0,
G_OPTION_FLAG_IN_MAIN, G_OPTION_FLAG_IN_MAIN,
G_OPTION_ARG_INT, &clutter_screen, G_OPTION_ARG_INT, &clutter_screen,
"X screen to use", "SCREEN" N_("X screen to use"), "SCREEN"
}, },
{ "synch", 0, { "synch", 0,
0, 0,
G_OPTION_ARG_NONE, &clutter_synchronise, G_OPTION_ARG_NONE, &clutter_synchronise,
"Make X calls synchronous", NULL, N_("Make X calls synchronous"), NULL,
}, },
{ NULL } { NULL }
}; };

View File

@ -580,7 +580,7 @@ AC_ARG_ENABLE([maintainer-flags],
enable_maintainer_flags=maintainer_flags_default) enable_maintainer_flags=maintainer_flags_default)
if test "x$enable_maintainer_flags" = "xyes"; then if test "x$enable_maintainer_flags" = "xyes"; then
CPPFLAGS="$CPPFLAGS -Werror -Wall -Wshadow -Wcast-align -Wno-uninitialized" CPPFLAGS="$CPPFLAGS -Werror -Wall -Wshadow -Wcast-align -Wno-uninitialized -Wempty-body -Wformat-security -Winit-self"
fi fi
@ -637,6 +637,7 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
ALL_LINGUAS="" ALL_LINGUAS=""
AM_GLIB_GNU_GETTEXT AM_GLIB_GNU_GETTEXT
GLIB_DEFINE_LOCALEDIR(LOCALEDIR)
AC_CONFIG_FILES([ AC_CONFIG_FILES([
Makefile Makefile

View File

@ -55,6 +55,7 @@ CFILE_GLOB=$(top_srcdir)/clutter/*.c
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
IGNORE_HFILES=\ IGNORE_HFILES=\
clutter.h \ clutter.h \
clutter-bezier.h \
clutter-debug.h \ clutter-debug.h \
clutter-deprecated.h \ clutter-deprecated.h \
clutter-enum-types.h \ clutter-enum-types.h \

View File

@ -58,8 +58,7 @@
<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-cairo-texture.xml"/>
<xi:include href="xml/clutter-label.xml"/> <xi:include href="xml/clutter-text.xml"/>
<xi:include href="xml/clutter-entry.xml"/>
</chapter> </chapter>
<chapter> <chapter>

View File

@ -66,48 +66,6 @@ clutter_unit_get_type
clutter_param_unit_get_type clutter_param_unit_get_type
</SECTION> </SECTION>
<SECTION>
<FILE>clutter-label</FILE>
<TITLE>ClutterLabel</TITLE>
ClutterLabel
ClutterLabelClass
clutter_label_new
clutter_label_new_with_text
clutter_label_new_full
clutter_label_set_text
clutter_label_get_text
clutter_label_set_font_name
clutter_label_get_font_name
clutter_label_set_color
clutter_label_get_color
clutter_label_set_ellipsize
clutter_label_get_ellipsize
clutter_label_set_line_wrap
clutter_label_get_line_wrap
clutter_label_set_line_wrap_mode
clutter_label_get_line_wrap_mode
clutter_label_get_layout
clutter_label_set_attributes
clutter_label_get_attributes
clutter_label_set_use_markup
clutter_label_get_use_markup
clutter_label_set_alignment
clutter_label_get_alignment
clutter_label_get_justify
clutter_label_set_justify
<SUBSECTION Standard>
CLUTTER_LABEL
CLUTTER_IS_LABEL
CLUTTER_TYPE_LABEL
CLUTTER_LABEL_CLASS
CLUTTER_IS_LABEL_CLASS
CLUTTER_LABEL_GET_CLASS
<SUBSECTION Private>
ClutterLabelPrivate
clutter_label_get_type
</SECTION>
<SECTION> <SECTION>
<FILE>clutter-behaviour</FILE> <FILE>clutter-behaviour</FILE>
<TITLE>ClutterBehaviour</TITLE> <TITLE>ClutterBehaviour</TITLE>
@ -476,6 +434,11 @@ clutter_actor_get_scalex
clutter_actor_set_rotationx clutter_actor_set_rotationx
clutter_actor_get_rotationx clutter_actor_get_rotationx
<SUBSECTION>
clutter_actor_grab_key_focus
clutter_actor_get_pango_context
clutter_actor_create_pango_context
<SUBSECTION Standard> <SUBSECTION Standard>
CLUTTER_TYPE_GEOMETRY CLUTTER_TYPE_GEOMETRY
CLUTTER_TYPE_ACTOR_BOX CLUTTER_TYPE_ACTOR_BOX
@ -698,6 +661,8 @@ ClutterPathCallback
ClutterPathNodeType ClutterPathNodeType
clutter_path_new clutter_path_new
clutter_path_new_with_description clutter_path_new_with_description
<SUBSECTION>
clutter_path_add_move_to clutter_path_add_move_to
clutter_path_add_rel_move_to clutter_path_add_rel_move_to
clutter_path_add_line_to clutter_path_add_line_to
@ -708,6 +673,8 @@ 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_add_cairo_path
<SUBSECTION>
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
@ -736,11 +703,9 @@ CLUTTER_PATH_CLASS
CLUTTER_IS_PATH CLUTTER_IS_PATH
CLUTTER_IS_PATH_CLASS CLUTTER_IS_PATH_CLASS
CLUTTER_PATH_GET_CLASS CLUTTER_PATH_GET_CLASS
CLUTTER_BEZIER_MAX_LENGTH
CLUTTER_PATH_RELATIVE CLUTTER_PATH_RELATIVE
<SUBSECTION Private> <SUBSECTION Private>
ClutterBezier
ClutterPathPrivate ClutterPathPrivate
clutter_path_get_type clutter_path_get_type
clutter_path_node_get_type clutter_path_node_get_type
@ -869,14 +834,16 @@ clutter_behaviour_ellipse_get_type
<FILE>clutter-backend</FILE> <FILE>clutter-backend</FILE>
<TITLE>ClutterBackend</TITLE> <TITLE>ClutterBackend</TITLE>
clutter_get_default_backend clutter_get_default_backend
clutter_backend_get_resolution
clutter_backend_set_resolution clutter_backend_set_resolution
clutter_backend_get_double_click_time clutter_backend_get_resolution
clutter_backend_set_double_click_time clutter_backend_set_double_click_time
clutter_backend_get_double_click_distance clutter_backend_get_double_click_time
clutter_backend_set_double_click_distance clutter_backend_set_double_click_distance
clutter_backend_get_double_click_distance
clutter_backend_set_font_options clutter_backend_set_font_options
clutter_backend_get_font_options clutter_backend_get_font_options
clutter_backend_set_font_name
clutter_backend_get_font_name
<SUBSECTION Standard> <SUBSECTION Standard>
CLUTTER_BACKEND CLUTTER_BACKEND
CLUTTER_IS_BACKEND CLUTTER_IS_BACKEND
@ -1219,50 +1186,6 @@ CLUTTER_COGL
CLUTTER_NO_FPU CLUTTER_NO_FPU
</SECTION> </SECTION>
<SECTION>
<FILE>clutter-entry</FILE>
<TITLE>ClutterEntry</TITLE>
ClutterEntry
ClutterEntryClass
clutter_entry_new
clutter_entry_new_with_text
clutter_entry_new_full
clutter_entry_set_text
clutter_entry_get_text
clutter_entry_set_font_name
clutter_entry_get_font_name
clutter_entry_set_color
clutter_entry_get_color
clutter_entry_get_layout
clutter_entry_set_alignment
clutter_entry_get_alignment
clutter_entry_set_cursor_position
clutter_entry_get_cursor_position
clutter_entry_handle_key_event
clutter_entry_insert_unichar
clutter_entry_delete_chars
clutter_entry_insert_text
clutter_entry_delete_text
clutter_entry_set_visible_cursor
clutter_entry_get_visible_cursor
clutter_entry_set_visibility
clutter_entry_get_visibility
clutter_entry_set_invisible_char
clutter_entry_get_invisible_char
clutter_entry_set_max_length
clutter_entry_get_max_length
<SUBSECTION Standard>
CLUTTER_ENTRY
CLUTTER_IS_ENTRY
CLUTTER_TYPE_ENTRY
CLUTTER_ENTRY_CLASS
CLUTTER_IS_ENTRY_CLASS
CLUTTER_ENTRY_GET_CLASS
<SUBSECTION Private>
ClutterEntryPrivate
clutter_entry_get_type
</SECTION>
<SECTION> <SECTION>
<FILE>clutter-effect</FILE> <FILE>clutter-effect</FILE>
<TITLE>Clutter Effects</TITLE> <TITLE>Clutter Effects</TITLE>
@ -1533,23 +1456,25 @@ clutter_shader_release
clutter_shader_is_compiled clutter_shader_is_compiled
clutter_shader_set_is_enabled clutter_shader_set_is_enabled
clutter_shader_get_is_enabled clutter_shader_get_is_enabled
clutter_shader_set_uniform_1f
<SUBSECTION>
clutter_shader_set_uniform clutter_shader_set_uniform
clutter_shader_get_cogl_program clutter_shader_get_cogl_program
clutter_shader_get_cogl_fragment_shader clutter_shader_get_cogl_fragment_shader
clutter_shader_get_cogl_vertex_shader clutter_shader_get_cogl_vertex_shader
clutter_shader_set_uniform_1f
<SUBSECTION> <SUBSECTION>
CLUTTER_VALUE_HOLDS_SHADER_FLOAT
ClutterShaderFloat ClutterShaderFloat
CLUTTER_VALUE_HOLDS_SHADER_FLOAT
clutter_value_set_shader_float clutter_value_set_shader_float
clutter_value_get_shader_float clutter_value_get_shader_float
CLUTTER_VALUE_HOLDS_SHADER_INT
ClutterShaderInt ClutterShaderInt
CLUTTER_VALUE_HOLDS_SHADER_INT
clutter_value_set_shader_int clutter_value_set_shader_int
clutter_value_get_shader_int clutter_value_get_shader_int
CLUTTER_VALUE_HOLDS_SHADER_MATRIX
ClutterShaderMatrix ClutterShaderMatrix
CLUTTER_VALUE_HOLDS_SHADER_MATRIX
clutter_value_set_shader_matrix clutter_value_set_shader_matrix
clutter_value_get_shader_matrix clutter_value_get_shader_matrix
@ -1572,6 +1497,9 @@ clutter_shader_float_get_type
clutter_shader_int_get_type clutter_shader_int_get_type
clutter_shader_matrix_get_type clutter_shader_matrix_get_type
clutter_shader_error_quark clutter_shader_error_quark
clutter_shader_float_get_type
clutter_shader_int_get_type
clutter_shader_matrix_get_type
</SECTION> </SECTION>
<SECTION> <SECTION>
@ -1638,8 +1566,8 @@ clutter_interval_set_interval
clutter_interval_get_interval clutter_interval_get_interval
<SUBSECTION> <SUBSECTION>
clutter_interval_validate
clutter_interval_compute_value clutter_interval_compute_value
clutter_interval_validate
<SUBSECTION Standard> <SUBSECTION Standard>
CLUTTER_TYPE_INTERVAL CLUTTER_TYPE_INTERVAL
@ -1668,7 +1596,8 @@ clutter_binding_pool_find
<SUBSECTION> <SUBSECTION>
clutter_binding_pool_install_action clutter_binding_pool_install_action
clutter_binding_pool_install_closure clutter_binding_pool_install_closure
clutter_binding_pool_list_actions clutter_binding_pool_override_action
clutter_binding_pool_override_closure
clutter_binding_pool_find_action clutter_binding_pool_find_action
clutter_binding_pool_remove_action clutter_binding_pool_remove_action
clutter_binding_pool_block_action clutter_binding_pool_block_action
@ -1679,8 +1608,8 @@ clutter_binding_pool_activate
</SECTION> </SECTION>
<SECTION> <SECTION>
<TITLE>ClutterCairoTexture</TITLE>
<FILE>clutter-cairo-texture</FILE> <FILE>clutter-cairo-texture</FILE>
<TITLE>ClutterCairoTexture</TITLE>
ClutterCairoTexture ClutterCairoTexture
ClutterCairoTextureClass ClutterCairoTextureClass
clutter_cairo_texture_new clutter_cairo_texture_new
@ -1705,4 +1634,82 @@ CLUTTER_CAIRO_TEXTURE_GET_CLASS
<SUBSECTION Private> <SUBSECTION Private>
ClutterCairoTexturePrivate ClutterCairoTexturePrivate
clutter_cairo_texture_get_type clutter_cairo_texture_get_type
<SECTION>
<TITLE>ClutterText</TITLE>
<FILE>clutter-text</FILE>
ClutterText
ClutterTextClass
clutter_text_new
clutter_text_new_full
clutter_text_new_with_text
<SUBSECTION>
clutter_text_set_text
clutter_text_get_text
clutter_text_set_activatable
clutter_text_get_activatable
clutter_text_set_alignment
clutter_text_get_alignment
clutter_text_set_attributes
clutter_text_get_attributes
clutter_text_set_color
clutter_text_get_color
clutter_text_set_ellipsize
clutter_text_get_ellipsize
clutter_text_set_font_name
clutter_text_get_font_name
clutter_text_set_password_char
clutter_text_get_password_char
clutter_text_set_justify
clutter_text_get_justify
clutter_text_get_layout
clutter_text_set_line_wrap
clutter_text_get_line_wrap
clutter_text_set_line_wrap_mode
clutter_text_get_line_wrap_mode
clutter_text_set_max_length
clutter_text_get_max_length
clutter_text_set_selectable
clutter_text_get_selectable
clutter_text_set_selection
clutter_text_get_selection
clutter_text_set_selection_bound
clutter_text_get_selection_bound
clutter_text_set_single_line_mode
clutter_text_get_single_line_mode
clutter_text_set_use_markup
clutter_text_get_use_markup
<SUBSECTION>
clutter_text_set_editable
clutter_text_get_editable
clutter_text_insert_text
clutter_text_insert_unichar
clutter_text_delete_chars
clutter_text_delete_text
clutter_text_get_chars
clutter_text_set_cursor_color
clutter_text_get_cursor_color
clutter_text_set_cursor_position
clutter_text_get_cursor_position
clutter_text_set_cursor_visible
clutter_text_get_cursor_visible
clutter_text_set_cursor_size
clutter_text_get_cursor_size
<SUBSECTION>
clutter_text_activate
<SUBSECTION Standard>
CLUTTER_IS_TEXT
CLUTTER_IS_TEXT_CLASS
CLUTTER_TEXT
CLUTTER_TEXT_CLASS
CLUTTER_TEXT_GET_CLASS
CLUTTER_TYPE_TEXT
<SUBSECTION Private>
ClutterTextPrivate
clutter_text_get_type
</SECTION> </SECTION>

View File

@ -6,7 +6,6 @@ clutter_stage_get_type
clutter_rectangle_get_type clutter_rectangle_get_type
clutter_texture_get_type clutter_texture_get_type
clutter_clone_texture_get_type clutter_clone_texture_get_type
clutter_label_get_type
clutter_timeline_get_type clutter_timeline_get_type
clutter_media_get_type clutter_media_get_type
clutter_behaviour_get_type clutter_behaviour_get_type
@ -19,7 +18,6 @@ clutter_path_get_type
clutter_behaviour_rotate_get_type clutter_behaviour_rotate_get_type
clutter_behaviour_scale_get_type clutter_behaviour_scale_get_type
clutter_backend_get_type clutter_backend_get_type
clutter_entry_get_type
clutter_script_get_type clutter_script_get_type
clutter_scriptable_get_type clutter_scriptable_get_type
clutter_model_get_type clutter_model_get_type
@ -29,3 +27,4 @@ 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 clutter_cairo_texture_get_type
clutter_text_get_type

View File

@ -120,6 +120,7 @@ cogl_texture_set_region
cogl_texture_ref cogl_texture_ref
cogl_texture_unref cogl_texture_unref
cogl_texture_rectangle cogl_texture_rectangle
cogl_texture_multiple_rectangles
cogl_texture_polygon cogl_texture_polygon
</SECTION> </SECTION>

View File

@ -0,0 +1,14 @@
clutter/clutter-actor.c
clutter/clutter-behaviour.c
clutter/clutter-color.c
clutter/clutter-container.c
clutter/clutter-event.c
clutter/clutter-fixed.c
clutter/clutter-fixed.h
clutter/clutter-main.c
clutter/clutter-stage-window.c
clutter/clutter-stage.c
clutter/clutter-texture.c
clutter/clutter-units.c
clutter/glx/clutter-backend-glx.c
clutter/x11/clutter-backend-x11.c

View File

View File

@ -17,14 +17,14 @@ test_conformance_SOURCES = \
test-mesh-mutability.c \ test-mesh-mutability.c \
test-path.c \ test-path.c \
test-pick.c \ test-pick.c \
test-label-cache.c \
test-clutter-entry.c \
test-clutter-rectangle.c \ test-clutter-rectangle.c \
test-clutter-fixed.c \ test-clutter-fixed.c \
test-actor-invariants.c \ test-actor-invariants.c \
test-paint-opacity.c \ test-paint-opacity.c \
test-backface-culling.c \ test-backface-culling.c \
test-binding-pool.c \ test-binding-pool.c \
test-clutter-text.c \
test-text-cache.c \
$(NULL) $(NULL)
# For convenience, this provides a way to easily run individual unit tests: # For convenience, this provides a way to easily run individual unit tests:

View File

@ -260,9 +260,9 @@ on_activate (KeyGroup *key_group,
ClutterActor *child, ClutterActor *child,
gpointer data) gpointer data)
{ {
gint index = GPOINTER_TO_INT (data); gint _index = GPOINTER_TO_INT (data);
g_assert_cmpint (key_group->selected_index, ==, index); g_assert_cmpint (key_group->selected_index, ==, _index);
} }
void void

View File

@ -1,370 +0,0 @@
#include <glib.h>
#include <clutter/clutter.h>
#include <string.h>
#include "test-conform-common.h"
typedef struct {
gunichar unichar;
const char bytes[6];
gint nbytes;
} TestData;
const TestData
test_data[] = {
{ 0xe4, "\xc3\xa4", 2 }, /* LATIN SMALL LETTER A WITH DIAERESIS */
{ 0x2665, "\xe2\x99\xa5", 3 } /* BLACK HEART SUIT */
};
void
test_entry_utf8_validation (TestConformSimpleFixture *fixture,
gconstpointer data)
{
int i;
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
{
const TestData *t = &test_data[i];
gunichar unichar;
char bytes[6];
int nbytes;
g_assert (g_unichar_validate (t->unichar));
nbytes = g_unichar_to_utf8 (t->unichar, bytes);
bytes[nbytes] = '\0';
g_assert (nbytes == t->nbytes);
g_assert (memcmp (t->bytes, bytes, nbytes) == 0);
unichar = g_utf8_get_char_validated (bytes, nbytes);
g_assert (unichar == t->unichar);
}
}
static int
get_nbytes (ClutterEntry *entry)
{
const char *s = clutter_entry_get_text (entry);
return strlen (s);
}
static int
get_nchars (ClutterEntry *entry)
{
const char *s = clutter_entry_get_text (entry);
g_assert (g_utf8_validate (s, -1, NULL));
return g_utf8_strlen (s, -1);
}
#define DONT_MOVE_CURSOR (-2)
static void
insert_unichar (ClutterEntry *entry, gunichar unichar, int position)
{
if (position > DONT_MOVE_CURSOR)
{
clutter_entry_set_cursor_position (entry, position);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, position);
}
clutter_entry_insert_unichar (entry, unichar);
}
void
test_entry_empty (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
g_assert (clutter_entry_get_text (entry) == NULL);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
void
test_entry_set_empty (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
/* annoyingly slightly different from initially empty */
clutter_entry_set_text (entry, "");
g_assert_cmpint (get_nchars (entry), ==, 0);
g_assert_cmpint (get_nbytes (entry), ==, 0);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
void
test_entry_set_text (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
clutter_entry_set_text (entry, "abcdef");
g_assert_cmpint (get_nchars (entry), ==, 6);
g_assert_cmpint (get_nbytes (entry), ==, 6);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
clutter_entry_set_cursor_position (entry, 5);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 5);
clutter_entry_set_text (entry, "");
/* FIXME: cursor position should be -1?
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
*/
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
void
test_entry_append_some (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
{
const TestData *t = &test_data[i];
int j;
for (j = 1; j <= 4; j++)
{
insert_unichar (entry, t->unichar, DONT_MOVE_CURSOR);
g_assert_cmpint (get_nchars (entry), ==, j);
g_assert_cmpint (get_nbytes (entry), ==, j * t->nbytes);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
}
clutter_entry_set_text (entry, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
void
test_entry_prepend_some (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
{
const TestData *t = &test_data[i];
int j;
clutter_entry_insert_unichar (entry, t->unichar);
g_assert_cmpint (get_nchars (entry), ==, 1);
g_assert_cmpint (get_nbytes (entry), ==, 1 * t->nbytes);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
for (j = 2; j <= 4; j++)
{
insert_unichar (entry, t->unichar, 0);
g_assert_cmpint (get_nchars (entry), ==, j);
g_assert_cmpint (get_nbytes (entry), ==, j * t->nbytes);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 1);
}
clutter_entry_set_text (entry, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
void
test_entry_insert (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
{
const TestData *t = &test_data[i];
clutter_entry_insert_unichar (entry, t->unichar);
clutter_entry_insert_unichar (entry, t->unichar);
insert_unichar (entry, t->unichar, 1);
g_assert_cmpint (get_nchars (entry), ==, 3);
g_assert_cmpint (get_nbytes (entry), ==, 3 * t->nbytes);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 2);
clutter_entry_set_text (entry, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
void
test_entry_delete_chars (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
{
const TestData *t = &test_data[i];
int j;
for (j = 0; j < 4; j++)
clutter_entry_insert_unichar (entry, t->unichar);
clutter_entry_set_cursor_position (entry, 2);
clutter_entry_delete_chars (entry, 1);
g_assert_cmpint (get_nchars (entry), ==, 3);
g_assert_cmpint (get_nbytes (entry), ==, 3 * t->nbytes);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 1);
clutter_entry_set_cursor_position (entry, 2);
clutter_entry_delete_chars (entry, 1);
g_assert_cmpint (get_nchars (entry), ==, 2);
g_assert_cmpint (get_nbytes (entry), ==, 2 * t->nbytes);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 1);
clutter_entry_set_text (entry, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
void
test_entry_delete_text (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
{
const TestData *t = &test_data[i];
int j;
for (j = 0; j < 4; j++)
clutter_entry_insert_unichar (entry, t->unichar);
clutter_entry_set_cursor_position (entry, 3);
clutter_entry_delete_text (entry, 2, 4);
g_assert_cmpint (get_nchars (entry), ==, 2);
g_assert_cmpint (get_nbytes (entry), ==, 2 * t->nbytes);
/* FIXME: cursor position should be -1?
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
*/
clutter_entry_set_text (entry, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
static void
init_event (ClutterKeyEvent *event)
{
event->type = CLUTTER_KEY_PRESS;
event->time = 0; /* not needed */
event->flags = CLUTTER_EVENT_FLAG_SYNTHETIC;
event->stage = NULL; /* not needed */
event->source = NULL; /* not needed */
event->modifier_state = 0;
event->hardware_keycode = 0; /* not needed */
}
static void
send_keyval (ClutterEntry *entry, int keyval)
{
ClutterKeyEvent event;
init_event (&event);
event.keyval = keyval;
event.unicode_value = 0; /* should be ignored for cursor keys etc. */
clutter_entry_handle_key_event (entry, &event);
}
static inline void
send_unichar (ClutterEntry *entry, gunichar unichar)
{
ClutterKeyEvent event;
init_event (&event);
event.keyval = 0; /* should be ignored for printable characters */
event.unicode_value = unichar;
clutter_entry_handle_key_event (entry, &event);
}
void
test_entry_cursor (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
{
const TestData *t = &test_data[i];
int j;
for (j = 0; j < 4; ++j)
clutter_entry_insert_unichar (entry, t->unichar);
clutter_entry_set_cursor_position (entry, 2);
/* test cursor moves and is clamped */
send_keyval (entry, CLUTTER_Left);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 1);
send_keyval (entry, CLUTTER_Left);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 0);
send_keyval (entry, CLUTTER_Left);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 0);
/* delete text containing the cursor */
clutter_entry_set_cursor_position (entry, 3);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 3);
clutter_entry_delete_text (entry, 2, 4);
send_keyval (entry, CLUTTER_Left);
/* FIXME: cursor position should be -1?
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
*/
clutter_entry_set_text (entry, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
void
test_entry_event (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
{
const TestData *t = &test_data[i];
send_unichar (entry, t->unichar);
g_assert_cmpint (get_nchars (entry), ==, 1);
g_assert_cmpint (get_nbytes (entry), ==, 1 * t->nbytes);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
clutter_entry_set_text (entry, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}

View File

@ -0,0 +1,431 @@
#include <glib.h>
#include <clutter/clutter.h>
#include <string.h>
#include "test-conform-common.h"
typedef struct {
gunichar unichar;
const char bytes[6];
gint nbytes;
} TestData;
static const TestData
test_text_data[] = {
{ 0xe4, "\xc3\xa4", 2 }, /* LATIN SMALL LETTER A WITH DIAERESIS */
{ 0x2665, "\xe2\x99\xa5", 3 } /* BLACK HEART SUIT */
};
void
test_text_utf8_validation (TestConformSimpleFixture *fixture,
gconstpointer data)
{
int i;
for (i = 0; i < G_N_ELEMENTS (test_text_data); i++)
{
const TestData *t = &test_text_data[i];
gunichar unichar;
char bytes[6];
int nbytes;
g_assert (g_unichar_validate (t->unichar));
nbytes = g_unichar_to_utf8 (t->unichar, bytes);
bytes[nbytes] = '\0';
g_assert (nbytes == t->nbytes);
g_assert (memcmp (t->bytes, bytes, nbytes) == 0);
unichar = g_utf8_get_char_validated (bytes, nbytes);
g_assert (unichar == t->unichar);
}
}
static int
get_nbytes (ClutterText *text)
{
const char *s = clutter_text_get_text (text);
return strlen (s);
}
static int
get_nchars (ClutterText *text)
{
const char *s = clutter_text_get_text (text);
g_assert (g_utf8_validate (s, -1, NULL));
return g_utf8_strlen (s, -1);
}
#define DONT_MOVE_CURSOR (-2)
static void
insert_unichar (ClutterText *text, gunichar unichar, int position)
{
if (position > DONT_MOVE_CURSOR)
{
clutter_text_set_cursor_position (text, position);
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, position);
}
clutter_text_insert_unichar (text, unichar);
}
void
test_text_empty (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
g_assert_cmpstr (clutter_text_get_text (text), ==, "");
g_assert_cmpint (*clutter_text_get_text (text), ==, '\0');
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
clutter_actor_destroy (CLUTTER_ACTOR (text));
}
void
test_text_set_empty (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
/* annoyingly slightly different from initially empty */
clutter_text_set_text (text, "");
g_assert_cmpint (get_nchars (text), ==, 0);
g_assert_cmpint (get_nbytes (text), ==, 0);
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
clutter_actor_destroy (CLUTTER_ACTOR (text));
}
void
test_text_set_text (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
clutter_text_set_text (text, "abcdef");
g_assert_cmpint (get_nchars (text), ==, 6);
g_assert_cmpint (get_nbytes (text), ==, 6);
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
clutter_text_set_cursor_position (text, 5);
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 5);
/* FIXME: cursor position should be -1?
clutter_text_set_text (text, "");
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
*/
clutter_actor_destroy (CLUTTER_ACTOR (text));
}
void
test_text_append_some (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_text_data); i++)
{
const TestData *t = &test_text_data[i];
int j;
for (j = 1; j <= 4; j++)
{
insert_unichar (text, t->unichar, DONT_MOVE_CURSOR);
g_assert_cmpint (get_nchars (text), ==, j);
g_assert_cmpint (get_nbytes (text), ==, j * t->nbytes);
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
}
clutter_text_set_text (text, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (text));
}
void
test_text_prepend_some (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_text_data); i++)
{
const TestData *t = &test_text_data[i];
int j;
clutter_text_insert_unichar (text, t->unichar);
g_assert_cmpint (get_nchars (text), ==, 1);
g_assert_cmpint (get_nbytes (text), ==, 1 * t->nbytes);
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
for (j = 2; j <= 4; j++)
{
insert_unichar (text, t->unichar, 0);
g_assert_cmpint (get_nchars (text), ==, j);
g_assert_cmpint (get_nbytes (text), ==, j * t->nbytes);
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 1);
}
clutter_text_set_text (text, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (text));
}
void
test_text_insert (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_text_data); i++)
{
const TestData *t = &test_text_data[i];
clutter_text_insert_unichar (text, t->unichar);
clutter_text_insert_unichar (text, t->unichar);
insert_unichar (text, t->unichar, 1);
g_assert_cmpint (get_nchars (text), ==, 3);
g_assert_cmpint (get_nbytes (text), ==, 3 * t->nbytes);
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 2);
clutter_text_set_text (text, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (text));
}
void
test_text_delete_chars (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_text_data); i++)
{
const TestData *t = &test_text_data[i];
int j;
for (j = 0; j < 4; j++)
clutter_text_insert_unichar (text, t->unichar);
clutter_text_set_cursor_position (text, 2);
clutter_text_delete_chars (text, 1);
g_assert_cmpint (get_nchars (text), ==, 3);
g_assert_cmpint (get_nbytes (text), ==, 3 * t->nbytes);
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 1);
clutter_text_set_cursor_position (text, 2);
clutter_text_delete_chars (text, 1);
g_assert_cmpint (get_nchars (text), ==, 2);
g_assert_cmpint (get_nbytes (text), ==, 2 * t->nbytes);
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 1);
clutter_text_set_text (text, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (text));
}
void
test_text_get_chars (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
gchar *chars;
clutter_text_set_text (text, "00abcdef11");
g_assert_cmpint (get_nchars (text), ==, 10);
g_assert_cmpint (get_nbytes (text), ==, 10);
g_assert_cmpstr (clutter_text_get_text (text), ==, "00abcdef11");
chars = clutter_text_get_chars (text, 2, -1);
g_assert_cmpstr (chars, ==, "abcdef11");
g_free (chars);
chars = clutter_text_get_chars (text, 0, 8);
g_assert_cmpstr (chars, ==, "00abcdef");
g_free (chars);
chars = clutter_text_get_chars (text, 2, 8);
g_assert_cmpstr (chars, ==, "abcdef");
g_free (chars);
chars = clutter_text_get_chars (text, 8, 12);
g_assert_cmpstr (chars, ==, "11");
g_free (chars);
clutter_actor_destroy (CLUTTER_ACTOR (text));
}
void
test_text_delete_text (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_text_data); i++)
{
const TestData *t = &test_text_data[i];
int j;
for (j = 0; j < 4; j++)
clutter_text_insert_unichar (text, t->unichar);
clutter_text_set_cursor_position (text, 3);
clutter_text_delete_text (text, 2, 4);
g_assert_cmpint (get_nchars (text), ==, 2);
g_assert_cmpint (get_nbytes (text), ==, 2 * t->nbytes);
/* FIXME: cursor position should be -1?
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
*/
clutter_text_set_text (text, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (text));
}
void
test_text_password_char (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
g_assert_cmpint (clutter_text_get_password_char (text), ==, 0);
clutter_text_set_text (text, "hello");
g_assert_cmpstr (clutter_text_get_text (text), ==, "hello");
clutter_text_set_password_char (text, '*');
g_assert_cmpint (clutter_text_get_password_char (text), ==, '*');
g_assert_cmpstr (clutter_text_get_text (text), ==, "hello");
clutter_actor_destroy (CLUTTER_ACTOR (text));
}
static void
init_event (ClutterKeyEvent *event)
{
event->type = CLUTTER_KEY_PRESS;
event->time = 0; /* not needed */
event->flags = CLUTTER_EVENT_FLAG_SYNTHETIC;
event->stage = NULL; /* not needed */
event->source = NULL; /* not needed */
event->modifier_state = 0;
event->hardware_keycode = 0; /* not needed */
}
static void
send_keyval (ClutterText *text, int keyval)
{
ClutterKeyEvent event;
init_event (&event);
event.keyval = keyval;
event.unicode_value = 0; /* should be ignored for cursor keys etc. */
clutter_actor_event (CLUTTER_ACTOR (text), (ClutterEvent *) &event, FALSE);
}
static void
send_unichar (ClutterText *text, gunichar unichar)
{
ClutterKeyEvent event;
init_event (&event);
event.keyval = 0; /* should be ignored for printable characters */
event.unicode_value = unichar;
clutter_actor_event (CLUTTER_ACTOR (text), (ClutterEvent *) &event, FALSE);
}
void
test_text_cursor (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
int i;
/* only editable entries listen to events */
clutter_text_set_editable (text, TRUE);
for (i = 0; i < G_N_ELEMENTS (test_text_data); i++)
{
const TestData *t = &test_text_data[i];
int j;
for (j = 0; j < 4; ++j)
clutter_text_insert_unichar (text, t->unichar);
clutter_text_set_cursor_position (text, 2);
/* test cursor moves and is clamped */
send_keyval (text, CLUTTER_Left);
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 1);
send_keyval (text, CLUTTER_Left);
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 0);
send_keyval (text, CLUTTER_Left);
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 0);
/* delete text containing the cursor */
clutter_text_set_cursor_position (text, 3);
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 3);
clutter_text_delete_text (text, 2, 4);
send_keyval (text, CLUTTER_Left);
/* FIXME: cursor position should be -1?
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
*/
clutter_text_set_text (text, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (text));
}
void
test_text_event (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
int i;
/* only editable entries listen to events */
clutter_text_set_editable (text, TRUE);
for (i = 0; i < G_N_ELEMENTS (test_text_data); i++)
{
const TestData *t = &test_text_data[i];
send_unichar (text, t->unichar);
g_assert_cmpint (get_nchars (text), ==, 1);
g_assert_cmpint (get_nbytes (text), ==, 1 * t->nbytes);
g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
clutter_text_set_text (text, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (text));
}

View File

@ -68,22 +68,21 @@ main (int argc, char **argv)
TEST_CONFORM_SIMPLE ("/picking", test_pick); TEST_CONFORM_SIMPLE ("/picking", test_pick);
TEST_CONFORM_SIMPLE ("/label", test_label_cache); /* ClutterText */
TEST_CONFORM_SIMPLE ("/text", test_text_utf8_validation);
TEST_CONFORM_SIMPLE ("/entry", test_entry_utf8_validation); TEST_CONFORM_SIMPLE ("/text", test_text_empty);
TEST_CONFORM_SIMPLE ("/entry", test_entry_empty); TEST_CONFORM_SIMPLE ("/text", test_text_set_empty);
TEST_CONFORM_SIMPLE ("/entry", test_entry_set_empty); TEST_CONFORM_SIMPLE ("/text", test_text_set_text);
TEST_CONFORM_SIMPLE ("/entry", test_entry_set_text); TEST_CONFORM_SIMPLE ("/text", test_text_append_some);
TEST_CONFORM_SIMPLE ("/text", test_text_prepend_some);
TEST_CONFORM_SIMPLE ("/entry", test_entry_append_some); TEST_CONFORM_SIMPLE ("/text", test_text_insert);
TEST_CONFORM_SIMPLE ("/entry", test_entry_prepend_some); TEST_CONFORM_SIMPLE ("/text", test_text_delete_chars);
TEST_CONFORM_SIMPLE ("/entry", test_entry_insert); TEST_CONFORM_SIMPLE ("/text", test_text_delete_text);
TEST_CONFORM_SIMPLE ("/text", test_text_cursor);
TEST_CONFORM_SIMPLE ("/entry", test_entry_delete_chars); TEST_CONFORM_SIMPLE ("/text", test_text_event);
TEST_CONFORM_SIMPLE ("/entry", test_entry_delete_text); TEST_CONFORM_SIMPLE ("/text", test_text_get_chars);
TEST_CONFORM_SIMPLE ("/text", test_text_cache);
TEST_CONFORM_SIMPLE ("/entry", test_entry_cursor); TEST_CONFORM_SIMPLE ("/text", test_text_password_char);
TEST_CONFORM_SIMPLE ("/entry", test_entry_event);
TEST_CONFORM_SIMPLE ("/rectangle", test_rect_set_size); TEST_CONFORM_SIMPLE ("/rectangle", test_rect_set_size);
TEST_CONFORM_SIMPLE ("/rectangle", test_rect_set_color); TEST_CONFORM_SIMPLE ("/rectangle", test_rect_set_color);

View File

@ -14,12 +14,12 @@ test_label_opacity (TestConformSimpleFixture *fixture,
stage = clutter_stage_get_default (); stage = clutter_stage_get_default ();
label = clutter_label_new_with_text ("Sans 18px", "Label, 50% opacity"); label = clutter_text_new_with_text ("Sans 18px", "Label, 50% opacity");
clutter_label_set_color (CLUTTER_LABEL (label), &label_color); clutter_text_set_color (CLUTTER_TEXT (label), &label_color);
if (g_test_verbose ()) if (g_test_verbose ())
g_print ("label 50%%.get_color()/1\n"); g_print ("label 50%%.get_color()/1\n");
clutter_label_get_color (CLUTTER_LABEL (label), &color_check); clutter_text_get_color (CLUTTER_TEXT (label), &color_check);
g_assert (color_check.alpha == label_color.alpha); g_assert (color_check.alpha == label_color.alpha);
clutter_container_add (CLUTTER_CONTAINER (stage), label, NULL); clutter_container_add (CLUTTER_CONTAINER (stage), label, NULL);
@ -27,12 +27,16 @@ test_label_opacity (TestConformSimpleFixture *fixture,
if (g_test_verbose ()) if (g_test_verbose ())
g_print ("label 50%%.get_color()/2\n"); g_print ("label 50%%.get_color()/2\n");
clutter_label_get_color (CLUTTER_LABEL (label), &color_check); clutter_text_get_color (CLUTTER_TEXT (label), &color_check);
g_assert (color_check.alpha == label_color.alpha); g_assert (color_check.alpha == label_color.alpha);
if (g_test_verbose ()) if (g_test_verbose ())
g_print ("label 50%%.get_paint_opacity() = %d\n", g_print ("label 50%%.get_paint_opacity()/1\n");
clutter_actor_get_paint_opacity (label)); g_assert (clutter_actor_get_paint_opacity (label) == 255);
if (g_test_verbose ())
g_print ("label 50%%.get_paint_opacity()/2\n");
clutter_actor_set_opacity (label, 128);
g_assert (clutter_actor_get_paint_opacity (label) == 128); g_assert (clutter_actor_get_paint_opacity (label) == 128);
clutter_actor_destroy (label); clutter_actor_destroy (label);
@ -66,8 +70,7 @@ test_rectangle_opacity (TestConformSimpleFixture *fixture,
g_assert (color_check.alpha == rect_color.alpha); g_assert (color_check.alpha == rect_color.alpha);
if (g_test_verbose ()) if (g_test_verbose ())
g_print ("rect 100%%.get_paint_opacity() = %d\n", g_print ("rect 100%%.get_paint_opacity()\n");
clutter_actor_get_paint_opacity (rect));
g_assert (clutter_actor_get_paint_opacity (rect) == 255); g_assert (clutter_actor_get_paint_opacity (rect) == 255);
clutter_actor_destroy (rect); clutter_actor_destroy (rect);
@ -91,25 +94,24 @@ test_paint_opacity (TestConformSimpleFixture *fixture,
clutter_actor_set_position (group1, 10, 30); clutter_actor_set_position (group1, 10, 30);
clutter_actor_show (group1); clutter_actor_show (group1);
label = clutter_label_new_with_text ("Sans 18px", "Label+Group, 25% opacity"); label = clutter_text_new_with_text ("Sans 18px", "Label+Group, 25% opacity");
clutter_label_set_color (CLUTTER_LABEL (label), &label_color); clutter_text_set_color (CLUTTER_TEXT (label), &label_color);
if (g_test_verbose ()) if (g_test_verbose ())
g_print ("label 50%% + group 50%%.get_color()/1\n"); g_print ("label 50%% + group 50%%.get_color()/1\n");
clutter_label_get_color (CLUTTER_LABEL (label), &color_check); clutter_text_get_color (CLUTTER_TEXT (label), &color_check);
g_assert (color_check.alpha == label_color.alpha); g_assert (color_check.alpha == label_color.alpha);
clutter_container_add (CLUTTER_CONTAINER (group1), label, NULL); clutter_container_add (CLUTTER_CONTAINER (group1), label, NULL);
if (g_test_verbose ()) if (g_test_verbose ())
g_print ("label 50%% + group 50%%.get_color()/2\n"); g_print ("label 50%% + group 50%%.get_color()/2\n");
clutter_label_get_color (CLUTTER_LABEL (label), &color_check); clutter_text_get_color (CLUTTER_TEXT (label), &color_check);
g_assert (color_check.alpha == label_color.alpha); g_assert (color_check.alpha == label_color.alpha);
if (g_test_verbose ()) if (g_test_verbose ())
g_print ("label 50%% + group 50%%.get_paint_opacity() = %d\n", g_print ("label 50%% + group 50%%.get_paint_opacity() = 128\n");
clutter_actor_get_paint_opacity (label)); g_assert (clutter_actor_get_paint_opacity (label) == 128);
g_assert (clutter_actor_get_paint_opacity (label) == 64);
clutter_actor_destroy (label); clutter_actor_destroy (label);
@ -133,9 +135,7 @@ test_paint_opacity (TestConformSimpleFixture *fixture,
g_assert (color_check.alpha == rect_color.alpha); g_assert (color_check.alpha == rect_color.alpha);
if (g_test_verbose ()) if (g_test_verbose ())
g_print ("rect 100%%.get_paint_opacity() = %d\n", g_print ("rect 100%%.get_paint_opacity()\n");
clutter_actor_get_paint_opacity (rect));
g_assert (clutter_actor_get_paint_opacity (rect) == 128); g_assert (clutter_actor_get_paint_opacity (rect) == 128);
clutter_actor_destroy (rect); clutter_actor_destroy (rect);

View File

@ -34,7 +34,7 @@ on_paint (ClutterActor *label, CallbackData *data)
/* Check whether the layout used for this paint is different from /* Check whether the layout used for this paint is different from
the layout used for the last paint */ the layout used for the last paint */
new_layout = clutter_label_get_layout (CLUTTER_LABEL (data->label)); new_layout = clutter_text_get_layout (CLUTTER_TEXT (data->label));
data->layout_changed = data->old_layout != new_layout; data->layout_changed = data->old_layout != new_layout;
if (data->old_layout) if (data->old_layout)
@ -71,7 +71,17 @@ check_result (CallbackData *data, const char *note,
if (memcmp (&test_extents, &data->label_extents, sizeof (PangoRectangle))) if (memcmp (&test_extents, &data->label_extents, sizeof (PangoRectangle)))
{ {
if (g_test_verbose ()) if (g_test_verbose ())
g_print ("extents are different, "); g_print ("extents are different: expected: %d, %d, %d, %d "
"-> text: %d, %d, %d, %d\n",
test_extents.x / 1024,
test_extents.y / 1024,
test_extents.width / 1024,
test_extents.height / 1024,
data->label_extents.x / 1024,
data->label_extents.y / 1024,
data->label_extents.width / 1024,
data->label_extents.height / 1024);
fail = TRUE; fail = TRUE;
} }
else else
@ -119,29 +129,29 @@ do_tests (CallbackData *data)
PangoAttribute *attr; PangoAttribute *attr;
/* TEST 1: change the text */ /* TEST 1: change the text */
clutter_label_set_text (CLUTTER_LABEL (data->label), "Counter 0"); clutter_text_set_text (CLUTTER_TEXT (data->label), "Counter 0");
pango_layout_set_text (data->test_layout, "Counter 0", -1); pango_layout_set_text (data->test_layout, "Counter 0", -1);
check_result (data, "Change text", TRUE); g_assert (check_result (data, "Change text", TRUE) == FALSE);
/* TEST 2: change a single character */ /* TEST 2: change a single character */
clutter_label_set_text (CLUTTER_LABEL (data->label), "Counter 1"); clutter_text_set_text (CLUTTER_TEXT (data->label), "Counter 1");
pango_layout_set_text (data->test_layout, "Counter 1", -1); pango_layout_set_text (data->test_layout, "Counter 1", -1);
check_result (data, "Change a single character", TRUE); g_assert (check_result (data, "Change a single character", TRUE) == FALSE);
/* TEST 3: move the label */ /* TEST 3: move the label */
clutter_actor_set_position (data->label, 10, 0); clutter_actor_set_position (data->label, 10, 0);
check_result (data, "Move the label", FALSE); g_assert (check_result (data, "Move the label", FALSE) == FALSE);
/* TEST 4: change the font */ /* TEST 4: change the font */
clutter_label_set_font_name (CLUTTER_LABEL (data->label), "Serif 15"); clutter_text_set_font_name (CLUTTER_TEXT (data->label), "Serif 15");
fd = pango_font_description_from_string ("Serif 15"); fd = pango_font_description_from_string ("Serif 15");
pango_layout_set_font_description (data->test_layout, fd); pango_layout_set_font_description (data->test_layout, fd);
pango_font_description_free (fd); pango_font_description_free (fd);
check_result (data, "Change the font", TRUE); g_assert (check_result (data, "Change the font", TRUE) == FALSE);
/* TEST 5: change the color */ /* TEST 5: change the color */
clutter_label_set_color (CLUTTER_LABEL (data->label), &red); clutter_text_set_color (CLUTTER_TEXT (data->label), &red);
check_result (data, "Change the color", FALSE); g_assert (check_result (data, "Change the color", FALSE) == FALSE);
/* TEST 6: change the attributes */ /* TEST 6: change the attributes */
attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD); attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
@ -150,23 +160,23 @@ do_tests (CallbackData *data)
attr_list = pango_attr_list_new (); attr_list = pango_attr_list_new ();
pango_attr_list_insert (attr_list, attr); pango_attr_list_insert (attr_list, attr);
attr_list_copy = pango_attr_list_copy (attr_list); attr_list_copy = pango_attr_list_copy (attr_list);
clutter_label_set_attributes (CLUTTER_LABEL (data->label), attr_list); clutter_text_set_attributes (CLUTTER_TEXT (data->label), attr_list);
pango_layout_set_attributes (data->test_layout, attr_list_copy); pango_layout_set_attributes (data->test_layout, attr_list_copy);
pango_attr_list_unref (attr_list_copy); pango_attr_list_unref (attr_list_copy);
pango_attr_list_unref (attr_list); pango_attr_list_unref (attr_list);
check_result (data, "Change the attributes", TRUE); g_assert (check_result (data, "Change the attributes", TRUE) == FALSE);
/* TEST 7: change the text again */ /* TEST 7: change the text again */
clutter_label_set_attributes (CLUTTER_LABEL (data->label), NULL); clutter_text_set_attributes (CLUTTER_TEXT (data->label), NULL);
clutter_label_set_text (CLUTTER_LABEL (data->label), long_text); clutter_text_set_text (CLUTTER_TEXT (data->label), long_text);
pango_layout_set_attributes (data->test_layout, NULL); pango_layout_set_attributes (data->test_layout, NULL);
pango_layout_set_text (data->test_layout, long_text, -1); pango_layout_set_text (data->test_layout, long_text, -1);
check_result (data, "Change the text again", TRUE); g_assert (check_result (data, "Change the text again", TRUE) == FALSE);
/* TEST 8: enable markup */ /* TEST 8: enable markup */
clutter_label_set_use_markup (CLUTTER_LABEL (data->label), TRUE); clutter_text_set_use_markup (CLUTTER_TEXT (data->label), TRUE);
pango_layout_set_markup (data->test_layout, long_text, -1); pango_layout_set_markup (data->test_layout, long_text, -1);
check_result (data, "Enable markup", TRUE); g_assert (check_result (data, "Enable markup", TRUE) == FALSE);
/* This part can't be a test because Clutter won't restrict the /* This part can't be a test because Clutter won't restrict the
width if wrapping and ellipsizing is disabled so the extents will width if wrapping and ellipsizing is disabled so the extents will
@ -178,39 +188,39 @@ do_tests (CallbackData *data)
force_redraw (data); force_redraw (data);
/* TEST 9: enable ellipsize */ /* TEST 9: enable ellipsize */
clutter_label_set_ellipsize (CLUTTER_LABEL (data->label), clutter_text_set_ellipsize (CLUTTER_TEXT (data->label),
PANGO_ELLIPSIZE_END); PANGO_ELLIPSIZE_END);
pango_layout_set_ellipsize (data->test_layout, PANGO_ELLIPSIZE_END); pango_layout_set_ellipsize (data->test_layout, PANGO_ELLIPSIZE_END);
check_result (data, "Enable ellipsize", TRUE); g_assert (check_result (data, "Enable ellipsize", TRUE) == FALSE);
clutter_label_set_ellipsize (CLUTTER_LABEL (data->label), clutter_text_set_ellipsize (CLUTTER_TEXT (data->label),
PANGO_ELLIPSIZE_NONE); PANGO_ELLIPSIZE_NONE);
pango_layout_set_ellipsize (data->test_layout, PANGO_ELLIPSIZE_NONE); pango_layout_set_ellipsize (data->test_layout, PANGO_ELLIPSIZE_NONE);
force_redraw (data); force_redraw (data);
/* TEST 10: enable line wrap */ /* TEST 10: enable line wrap */
clutter_label_set_line_wrap (CLUTTER_LABEL (data->label), TRUE); clutter_text_set_line_wrap (CLUTTER_TEXT (data->label), TRUE);
pango_layout_set_wrap (data->test_layout, PANGO_WRAP_WORD); pango_layout_set_wrap (data->test_layout, PANGO_WRAP_WORD);
check_result (data, "Enable line wrap", TRUE); g_assert (check_result (data, "Enable line wrap", TRUE) == FALSE);
/* TEST 11: change wrap mode */ /* TEST 11: change wrap mode */
clutter_label_set_line_wrap_mode (CLUTTER_LABEL (data->label), clutter_text_set_line_wrap_mode (CLUTTER_TEXT (data->label),
PANGO_WRAP_CHAR); PANGO_WRAP_CHAR);
pango_layout_set_wrap (data->test_layout, PANGO_WRAP_CHAR); pango_layout_set_wrap (data->test_layout, PANGO_WRAP_CHAR);
check_result (data, "Change wrap mode", TRUE); g_assert (check_result (data, "Change wrap mode", TRUE) == FALSE);
/* TEST 12: enable justify */ /* TEST 12: enable justify */
clutter_label_set_justify (CLUTTER_LABEL (data->label), TRUE); clutter_text_set_justify (CLUTTER_TEXT (data->label), TRUE);
pango_layout_set_justify (data->test_layout, TRUE); pango_layout_set_justify (data->test_layout, TRUE);
/* Pango appears to have a bug which means that you can't change the /* Pango appears to have a bug which means that you can't change the
justification after setting the text but this fixes it. justification after setting the text but this fixes it.
See http://bugzilla.gnome.org/show_bug.cgi?id=551865 */ See http://bugzilla.gnome.org/show_bug.cgi?id=551865 */
pango_layout_context_changed (data->test_layout); pango_layout_context_changed (data->test_layout);
check_result (data, "Enable justify", TRUE); g_assert (check_result (data, "Enable justify", TRUE) == FALSE);
/* TEST 13: change alignment */ /* TEST 13: change alignment */
clutter_label_set_alignment (CLUTTER_LABEL (data->label), PANGO_ALIGN_RIGHT); clutter_text_set_alignment (CLUTTER_TEXT (data->label), PANGO_ALIGN_RIGHT);
pango_layout_set_alignment (data->test_layout, PANGO_ALIGN_RIGHT); pango_layout_set_alignment (data->test_layout, PANGO_ALIGN_RIGHT);
check_result (data, "Change alignment", TRUE); g_assert (check_result (data, "Change alignment", TRUE) == FALSE);
clutter_main_quit (); clutter_main_quit ();
@ -218,7 +228,7 @@ do_tests (CallbackData *data)
} }
static PangoLayout * static PangoLayout *
make_layout_like_label (ClutterLabel *label) make_layout_like_label (ClutterText *label)
{ {
PangoLayout *label_layout, *new_layout; PangoLayout *label_layout, *new_layout;
PangoContext *context; PangoContext *context;
@ -226,7 +236,7 @@ make_layout_like_label (ClutterLabel *label)
/* Make another layout using the same context as the layout from the /* Make another layout using the same context as the layout from the
label */ label */
label_layout = clutter_label_get_layout (label); label_layout = clutter_text_get_layout (label);
context = pango_layout_get_context (label_layout); context = pango_layout_get_context (label_layout);
new_layout = pango_layout_new (context); new_layout = pango_layout_new (context);
fd = pango_font_description_from_string (TEST_FONT); fd = pango_font_description_from_string (TEST_FONT);
@ -237,7 +247,7 @@ make_layout_like_label (ClutterLabel *label)
} }
void void
test_label_cache (TestConformSimpleFixture *fixture, test_text_cache (TestConformSimpleFixture *fixture,
gconstpointer _data) gconstpointer _data)
{ {
CallbackData data; CallbackData data;
@ -246,9 +256,9 @@ test_label_cache (TestConformSimpleFixture *fixture,
data.stage = clutter_stage_get_default (); data.stage = clutter_stage_get_default ();
data.label = clutter_label_new_with_text (TEST_FONT, ""); data.label = clutter_text_new_with_text (TEST_FONT, "");
data.test_layout = make_layout_like_label (CLUTTER_LABEL (data.label)); data.test_layout = make_layout_like_label (CLUTTER_TEXT (data.label));
g_signal_connect (data.label, "paint", G_CALLBACK (on_paint), &data); g_signal_connect (data.label, "paint", G_CALLBACK (on_paint), &data);

View File

@ -6,7 +6,6 @@ UNIT_TESTS = \
test-scale.c \ test-scale.c \
test-actors.c \ test-actors.c \
test-behave.c \ test-behave.c \
test-entry.c \
test-project.c \ test-project.c \
test-perspective.c \ test-perspective.c \
test-rotate.c \ test-rotate.c \
@ -22,7 +21,6 @@ UNIT_TESTS = \
test-unproject.c \ test-unproject.c \
test-viewport.c \ test-viewport.c \
test-fbo.c \ test-fbo.c \
test-opacity.c \
test-multistage.c \ test-multistage.c \
test-cogl-primitives.c \ test-cogl-primitives.c \
test-cogl-tex-tile.c \ test-cogl-tex-tile.c \
@ -39,7 +37,9 @@ UNIT_TESTS = \
test-layout.c \ test-layout.c \
test-animation.c \ test-animation.c \
test-easing.c \ test-easing.c \
test-binding-pool.c test-binding-pool.c \
test-text.c \
test-text-field.c
if X11_TESTS if X11_TESTS
UNIT_TESTS += test-pixmap.c UNIT_TESTS += test-pixmap.c

View File

@ -122,7 +122,7 @@ on_paint (ClutterActor *actor, CallbackData *data)
{ {
int i; int i;
ClutterGeometry stage_size; ClutterGeometry stage_size;
guint hand_width, hand_height; gint hand_width, hand_height;
GSList *node; GSList *node;
clutter_actor_get_allocation_geometry (data->stage, &stage_size); clutter_actor_get_allocation_geometry (data->stage, &stage_size);
@ -305,8 +305,8 @@ test_clip_main (int argc, char **argv)
data.hand = cogl_texture_new_from_file ("redhand.png", 64, FALSE, data.hand = cogl_texture_new_from_file ("redhand.png", 64, FALSE,
COGL_PIXEL_FORMAT_ANY, NULL); COGL_PIXEL_FORMAT_ANY, NULL);
label = clutter_label_new_with_text ("Sans 12px", instructions); label = clutter_text_new_with_text ("Sans 12px", instructions);
clutter_label_set_line_wrap (CLUTTER_LABEL (label), TRUE); clutter_text_set_line_wrap (CLUTTER_TEXT (label), TRUE);
clutter_actor_set_width (label, clutter_actor_get_width (data.stage) - 310); clutter_actor_set_width (label, clutter_actor_get_width (data.stage) - 310);
clutter_actor_set_y (label, clutter_actor_set_y (label,
clutter_actor_get_height (data.stage) clutter_actor_get_height (data.stage)

View File

@ -297,16 +297,16 @@ frame_cb (ClutterTimeline *timeline,
} }
static void static void
update_toggle_text (ClutterLabel *button, gboolean val) update_toggle_text (ClutterText *button, gboolean val)
{ {
clutter_label_set_text (button, val ? "Enabled" : "Disabled"); clutter_text_set_text (button, val ? "Enabled" : "Disabled");
} }
static gboolean static gboolean
on_toggle_click (ClutterActor *button, ClutterEvent *event, on_toggle_click (ClutterActor *button, ClutterEvent *event,
gboolean *toggle_val) gboolean *toggle_val)
{ {
update_toggle_text (CLUTTER_LABEL (button), *toggle_val = !*toggle_val); update_toggle_text (CLUTTER_TEXT (button), *toggle_val = !*toggle_val);
return TRUE; return TRUE;
} }
@ -315,12 +315,12 @@ static ClutterActor *
make_toggle (const char *label_text, gboolean *toggle_val) make_toggle (const char *label_text, gboolean *toggle_val)
{ {
ClutterActor *group = clutter_group_new (); ClutterActor *group = clutter_group_new ();
ClutterActor *label = clutter_label_new_with_text ("Sans 14", label_text); ClutterActor *label = clutter_text_new_with_text ("Sans 14", label_text);
ClutterActor *button = clutter_label_new_with_text ("Sans 14", ""); ClutterActor *button = clutter_text_new_with_text ("Sans 14", "");
clutter_actor_set_reactive (button, TRUE); clutter_actor_set_reactive (button, TRUE);
update_toggle_text (CLUTTER_LABEL (button), *toggle_val); update_toggle_text (CLUTTER_TEXT (button), *toggle_val);
clutter_actor_set_position (button, clutter_actor_get_width (label) + 10, 0); clutter_actor_set_position (button, clutter_actor_get_width (label) + 10, 0);
clutter_container_add (CLUTTER_CONTAINER (group), label, button, NULL); clutter_container_add (CLUTTER_CONTAINER (group), label, button, NULL);
@ -373,7 +373,7 @@ test_cogl_tex_polygon_main (int argc, char *argv[])
clutter_actor_set_position (filtering_toggle, 0, clutter_actor_set_position (filtering_toggle, 0,
clutter_actor_get_y (slicing_toggle) clutter_actor_get_y (slicing_toggle)
- clutter_actor_get_height (filtering_toggle)); - clutter_actor_get_height (filtering_toggle));
note = clutter_label_new_with_text ("Sans 10", "<- Click to change"); note = clutter_text_new_with_text ("Sans 10", "<- Click to change");
clutter_actor_set_position (note, clutter_actor_set_position (note,
clutter_actor_get_width (filtering_toggle) + 10, clutter_actor_get_width (filtering_toggle) + 10,
(clutter_actor_get_height (stage) (clutter_actor_get_height (stage)

View File

@ -26,7 +26,7 @@ raise_top (gpointer ignored)
static ClutterActor * static ClutterActor *
clone_box (ClutterTexture *original) clone_box (ClutterTexture *original)
{ {
guint width, height; gint width, height;
ClutterActor *group; ClutterActor *group;
ClutterActor *clone; ClutterActor *clone;
@ -83,10 +83,10 @@ janus_group (const gchar *front_text,
group = clutter_group_new (); group = clutter_group_new ();
rectangle = clutter_rectangle_new_with_color (&slide_color); rectangle = clutter_rectangle_new_with_color (&slide_color);
front = clutter_label_new_with_text ("Sans 50px", front_text); front = clutter_text_new_with_text ("Sans 50px", front_text);
back = clutter_label_new_with_text ("Sans 50px", back_text); back = clutter_text_new_with_text ("Sans 50px", back_text);
clutter_label_set_color (CLUTTER_LABEL (front), &red); clutter_text_set_color (CLUTTER_TEXT (front), &red);
clutter_label_set_color (CLUTTER_LABEL (back), &green); clutter_text_set_color (CLUTTER_TEXT (back), &green);
clutter_actor_get_size (front, &width, &height); clutter_actor_get_size (front, &width, &height);
clutter_actor_get_size (back, &width2, &height2); clutter_actor_get_size (back, &width2, &height2);
@ -134,7 +134,7 @@ test_depth_main (int argc, char *argv[])
clutter_stage_add (stage, group); clutter_stage_add (stage, group);
clutter_actor_show (group); clutter_actor_show (group);
label = clutter_label_new_with_text ("Mono 26", "Clutter"); label = clutter_text_new_with_text ("Mono 26", "Clutter");
clutter_actor_set_position (label, 120, 200); clutter_actor_set_position (label, 120, 200);
clutter_actor_show (label); clutter_actor_show (label);

View File

@ -41,7 +41,7 @@ on_button_press (ClutterActor *actor,
current_mode + 1, current_mode + 1,
n_easing_modes); n_easing_modes);
clutter_label_set_text (CLUTTER_LABEL (easing_mode_label), text); clutter_text_set_text (CLUTTER_TEXT (easing_mode_label), text);
g_free (text); g_free (text);
clutter_actor_get_size (main_stage, &stage_width, &stage_height); clutter_actor_get_size (main_stage, &stage_width, &stage_height);
@ -97,10 +97,10 @@ test_easing_main (int argc, char *argv[])
current_mode + 1, current_mode + 1,
n_easing_modes); n_easing_modes);
label = clutter_label_new (); label = clutter_text_new ();
clutter_container_add_actor (CLUTTER_CONTAINER (stage), label); clutter_container_add_actor (CLUTTER_CONTAINER (stage), label);
clutter_label_set_font_name (CLUTTER_LABEL (label), "Sans 18px"); clutter_text_set_font_name (CLUTTER_TEXT (label), "Sans 18px");
clutter_label_set_text (CLUTTER_LABEL (label), text); clutter_text_set_text (CLUTTER_TEXT (label), text);
clutter_actor_get_size (label, &label_width, &label_height); clutter_actor_get_size (label, &label_width, &label_height);
clutter_actor_set_position (label, clutter_actor_set_position (label,
stage_width - label_width - 10, stage_width - label_width - 10,

View File

@ -43,9 +43,9 @@ make_source(void)
clutter_group_add (source, actor); clutter_group_add (source, actor);
actor = clutter_label_new_with_text ("Sans Bold 50px", "Clutter"); actor = clutter_text_new_with_text ("Sans Bold 50px", "Clutter");
clutter_label_set_color (CLUTTER_LABEL (actor), &yellow); clutter_text_set_color (CLUTTER_TEXT (actor), &yellow);
clutter_actor_set_y (actor, clutter_actor_get_height(source) + 5); clutter_actor_set_y (actor, clutter_actor_get_height(source) + 5);
clutter_group_add (source, actor); clutter_group_add (source, actor);

View File

@ -787,7 +787,7 @@ test_layout_main (int argc, char *argv[])
clutter_container_add_actor (CLUTTER_CONTAINER (stage), box); clutter_container_add_actor (CLUTTER_CONTAINER (stage), box);
instructions = clutter_label_new_with_text ("Sans 14", instructions = clutter_text_new_with_text ("Sans 14",
"<b>Instructions:</b>\n" "<b>Instructions:</b>\n"
"a - add a new item\n" "a - add a new item\n"
"d - remove last item\n" "d - remove last item\n"
@ -799,7 +799,7 @@ test_layout_main (int argc, char *argv[])
"s - use transformed box\n" "s - use transformed box\n"
"q - quit"); "q - quit");
clutter_label_set_use_markup (CLUTTER_LABEL (instructions), TRUE); clutter_text_set_use_markup (CLUTTER_TEXT (instructions), TRUE);
clutter_actor_set_position (instructions, 450, 10); clutter_actor_set_position (instructions, 450, 10);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), instructions); clutter_container_add_actor (CLUTTER_CONTAINER (stage), instructions);

View File

@ -50,10 +50,10 @@ on_button_press (ClutterActor *actor,
clutter_container_add_actor (CLUTTER_CONTAINER (new_stage), tex); clutter_container_add_actor (CLUTTER_CONTAINER (new_stage), tex);
stage_label = g_strdup_printf ("<b>Stage: %d</b>", ++n_stages); stage_label = g_strdup_printf ("<b>Stage: %d</b>", ++n_stages);
label = clutter_label_new_with_text ("Mono 12", stage_label); label = clutter_text_new_with_text ("Mono 12", stage_label);
clutter_label_set_color (CLUTTER_LABEL (label), &white); clutter_text_set_color (CLUTTER_TEXT (label), &white);
clutter_label_set_use_markup (CLUTTER_LABEL (label), TRUE); clutter_text_set_use_markup (CLUTTER_TEXT (label), TRUE);
width = (clutter_actor_get_width (new_stage) width = (clutter_actor_get_width (new_stage)
- clutter_actor_get_width (label)) / 2; - clutter_actor_get_width (label)) / 2;
height = (clutter_actor_get_height (new_stage) height = (clutter_actor_get_height (new_stage)
@ -110,7 +110,7 @@ test_multistage_main (int argc, char *argv[])
G_CALLBACK (on_button_press), G_CALLBACK (on_button_press),
NULL); NULL);
label = clutter_label_new_with_text ("Mono 16", "Default stage"); label = clutter_text_new_with_text ("Mono 16", "Default stage");
width = (clutter_actor_get_width (stage_default) width = (clutter_actor_get_width (stage_default)
- clutter_actor_get_width (label)) - clutter_actor_get_width (label))
/ 2; / 2;

View File

@ -1,116 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <glib.h>
#include <gmodule.h>
#include <clutter/clutter.h>
G_MODULE_EXPORT int
test_opacity_main (int argc, char *argv[])
{
ClutterActor *stage, *group1, *group2, *label, *rect;
ClutterColor label_color = { 255, 0, 0, 128 };
ClutterColor rect_color = { 0, 0, 255, 255 };
ClutterColor color_check = { 0, };
clutter_init (&argc, &argv);
stage = clutter_stage_get_default ();
label = clutter_label_new_with_text ("Sans 18px", "Label, 50% opacity");
clutter_label_set_color (CLUTTER_LABEL (label), &label_color);
g_print ("label 50%%.get_color()/1\n");
clutter_label_get_color (CLUTTER_LABEL (label), &color_check);
g_assert (color_check.alpha == label_color.alpha);
clutter_container_add (CLUTTER_CONTAINER (stage), label, NULL);
clutter_actor_set_position (label, 10, 10);
g_print ("label 50%%.get_color()/2\n");
clutter_label_get_color (CLUTTER_LABEL (label), &color_check);
g_assert (color_check.alpha == label_color.alpha);
g_print ("label 50%%.get_paint_opacity() = %d\n",
clutter_actor_get_paint_opacity (label));
g_assert (clutter_actor_get_paint_opacity (label) == 128);
clutter_actor_show (label);
group1 = clutter_group_new ();
clutter_actor_set_opacity (group1, 128);
clutter_container_add (CLUTTER_CONTAINER (stage), group1, NULL);
clutter_actor_set_position (group1, 10, 30);
clutter_actor_show (group1);
label = clutter_label_new_with_text ("Sans 18px", "Label+Group, 25% opacity");
clutter_label_set_color (CLUTTER_LABEL (label), &label_color);
g_print ("label 50%% + group 50%%.get_color()/1\n");
clutter_label_get_color (CLUTTER_LABEL (label), &color_check);
g_assert (color_check.alpha == label_color.alpha);
clutter_container_add (CLUTTER_CONTAINER (group1), label, NULL);
g_print ("label 50%% + group 50%%.get_color()/2\n");
clutter_label_get_color (CLUTTER_LABEL (label), &color_check);
g_assert (color_check.alpha == label_color.alpha);
g_print ("label 50%% + group 50%%.get_paint_opacity() = %d\n",
clutter_actor_get_paint_opacity (label));
g_assert (clutter_actor_get_paint_opacity (label) == 64);
clutter_actor_show (label);
group2 = clutter_group_new ();
clutter_container_add (CLUTTER_CONTAINER (group1), group2, NULL);
clutter_actor_set_position (group2, 10, 60);
clutter_actor_show (group2);
rect = clutter_rectangle_new_with_color (&rect_color);
clutter_actor_set_size (rect, 128, 128);
g_print ("rect 100%% + group 100%% + group 50%%.get_color()/1\n");
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
g_assert (color_check.alpha == rect_color.alpha);
clutter_container_add (CLUTTER_CONTAINER (group2), rect, NULL);
g_print ("rect 100%% + group 100%% + group 50%%.get_color()/2\n");
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
g_assert (color_check.alpha == rect_color.alpha);
g_print ("rect 100%%.get_paint_opacity() = %d\n",
clutter_actor_get_paint_opacity (rect));
g_assert (clutter_actor_get_paint_opacity (rect) == 128);
clutter_actor_show (rect);
rect = clutter_rectangle_new_with_color (&rect_color);
clutter_actor_set_size (rect, 128, 128);
clutter_actor_set_position (rect, 150, 90);
g_print ("rect 100%%.get_color()/1\n");
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
g_assert (color_check.alpha == rect_color.alpha);
clutter_container_add (CLUTTER_CONTAINER (stage), rect, NULL);
g_print ("rect 100%%.get_color()/2\n");
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
g_assert (color_check.alpha == rect_color.alpha);
g_print ("rect 100%%.get_paint_opacity() = %d\n",
clutter_actor_get_paint_opacity (rect));
g_assert (clutter_actor_get_paint_opacity (rect) == 255);
clutter_actor_show (rect);
clutter_actor_show_all (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -224,8 +224,8 @@ test_project_main (int argc, char *argv[])
clutter_actor_set_rotation (rect, CLUTTER_Y_AXIS, 60, 0, 0, 0); clutter_actor_set_rotation (rect, CLUTTER_Y_AXIS, 60, 0, 0, 0);
clutter_group_add (CLUTTER_GROUP (main_stage), rect); clutter_group_add (CLUTTER_GROUP (main_stage), rect);
label = clutter_label_new_with_text ("Mono 8pt", "Drag the blue rectangles"); label = clutter_text_new_with_text ("Mono 8pt", "Drag the blue rectangles");
clutter_label_set_color (CLUTTER_LABEL (label), &white); clutter_text_set_color (CLUTTER_TEXT (label), &white);
clutter_actor_set_position (label, 10, 10); clutter_actor_set_position (label, 10, 10);
clutter_group_add (CLUTTER_GROUP (main_stage), label); clutter_group_add (CLUTTER_GROUP (main_stage), label);

View File

@ -45,7 +45,7 @@ on_idle (gpointer data)
font_names[rand () % FONT_NAME_COUNT], font_names[rand () % FONT_NAME_COUNT],
rand () % (MAX_FONT_SIZE - MIN_FONT_SIZE) + MIN_FONT_SIZE); rand () % (MAX_FONT_SIZE - MIN_FONT_SIZE) + MIN_FONT_SIZE);
label = clutter_label_new_with_text (font_name, text); label = clutter_text_new_with_text (font_name, text);
if (clutter_actor_get_height (label) > line_height) if (clutter_actor_get_height (label) > line_height)
line_height = clutter_actor_get_height (label); line_height = clutter_actor_get_height (label);

View File

@ -33,8 +33,8 @@ test_rotate_main (int argc, char *argv[])
clutter_actor_show (hand); clutter_actor_show (hand);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), hand); clutter_container_add_actor (CLUTTER_CONTAINER (stage), hand);
label = clutter_label_new_with_text ("Mono 16", "The Wonder of the Spinning Hand"); label = clutter_text_new_with_text ("Mono 16", "The Wonder of the Spinning Hand");
clutter_label_set_alignment (CLUTTER_LABEL (label), PANGO_ALIGN_CENTER); clutter_text_set_alignment (CLUTTER_TEXT (label), PANGO_ALIGN_CENTER);
clutter_actor_set_position (label, 150, 150); clutter_actor_set_position (label, 150, 150);
clutter_actor_set_size (label, 500, 100); clutter_actor_set_size (label, 500, 100);
clutter_actor_show (label); clutter_actor_show (label);

View File

@ -29,7 +29,7 @@ set_next_gravity (ClutterActor *actor)
eclass = g_type_class_ref (CLUTTER_TYPE_GRAVITY); eclass = g_type_class_ref (CLUTTER_TYPE_GRAVITY);
evalue = g_enum_get_value (eclass, gravity); evalue = g_enum_get_value (eclass, gravity);
clutter_label_set_text (CLUTTER_LABEL (label), evalue->value_nick); clutter_text_set_text (CLUTTER_TEXT (label), evalue->value_nick);
g_type_class_unref (eclass); g_type_class_unref (eclass);
if (++gindex >= G_N_ELEMENTS (gravities)) if (++gindex >= G_N_ELEMENTS (gravities))
@ -59,8 +59,8 @@ test_scale_main (int argc, char *argv[])
clutter_group_add (CLUTTER_GROUP (stage), rect); clutter_group_add (CLUTTER_GROUP (stage), rect);
label = clutter_label_new_with_text ("Sans 20px", ""); label = clutter_text_new_with_text ("Sans 20px", "");
clutter_label_set_color (CLUTTER_LABEL (label), clutter_text_set_color (CLUTTER_TEXT (label),
&(ClutterColor) { 0xff, 0xff, 0xff, 0xff }); &(ClutterColor) { 0xff, 0xff, 0xff, 0xff });
clutter_actor_set_position (label, clutter_actor_set_position (label,
clutter_actor_get_x (rect), clutter_actor_get_x (rect),

View File

@ -354,7 +354,7 @@ test_shader_main (gint argc, gchar *argv[])
if (!child2) if (!child2)
g_error("pixbuf load failed: %s", error ? error->message : "Unknown"); g_error("pixbuf load failed: %s", error ? error->message : "Unknown");
child3 = clutter_rectangle_new (); child3 = clutter_rectangle_new ();
child4 = clutter_label_new_with_text ("Sans 20px", "Shady stuff"); child4 = clutter_text_new_with_text ("Sans 20px", "Shady stuff");
clutter_rectangle_set_color (child3, &color); clutter_rectangle_set_color (child3, &color);
clutter_actor_set_size (child3, 50, 50); clutter_actor_set_size (child3, 50, 50);

View File

@ -23,14 +23,14 @@ make_label (void)
gchar *text; gchar *text;
gchar *argv[] = { "ls", "--help", NULL }; gchar *argv[] = { "ls", "--help", NULL };
label = clutter_label_new (); label = clutter_text_new ();
clutter_label_set_font_name (CLUTTER_LABEL (label), "Sans 10"); clutter_text_set_font_name (CLUTTER_TEXT (label), "Sans 10");
if (g_spawn_sync (NULL, argv, NULL, if (g_spawn_sync (NULL, argv, NULL,
G_SPAWN_STDERR_TO_DEV_NULL | G_SPAWN_SEARCH_PATH, G_SPAWN_STDERR_TO_DEV_NULL | G_SPAWN_SEARCH_PATH,
NULL, NULL, &text, NULL, NULL, NULL)) NULL, NULL, &text, NULL, NULL, NULL))
{ {
clutter_label_set_text (CLUTTER_LABEL (label), text); clutter_text_set_text (CLUTTER_TEXT (label), text);
g_free (text); g_free (text);
} }

View File

@ -0,0 +1,117 @@
#include <stdlib.h>
#include <gmodule.h>
#include <clutter/clutter.h>
#define FONT "Mono Bold 14px"
static void
on_entry_paint (ClutterActor *actor,
gpointer data)
{
ClutterActorBox allocation = { 0, };
ClutterUnit width, height;
clutter_actor_get_allocation_box (actor, &allocation);
width = allocation.x2 - allocation.x1;
height = allocation.y2 - allocation.y1;
cogl_set_source_color4ub (255, 255, 255, 255);
cogl_path_round_rectangle (0, 0,
CLUTTER_UNITS_TO_FIXED (width),
CLUTTER_UNITS_TO_FIXED (height),
COGL_FIXED_FROM_INT (4),
COGL_ANGLE_FROM_DEG (1.0));
cogl_path_stroke ();
}
static void
on_entry_activate (ClutterText *text,
gpointer data)
{
g_print ("Text activated: %s\n", clutter_text_get_text (text));
}
static ClutterActor *
create_label (const ClutterColor *color,
const gchar *text)
{
ClutterActor *retval = clutter_text_new_full (FONT, text, color);
clutter_text_set_editable (CLUTTER_TEXT (retval), FALSE);
clutter_text_set_selectable (CLUTTER_TEXT (retval), FALSE);
return retval;
}
static ClutterActor *
create_entry (const ClutterColor *color,
const gchar *text,
gunichar password_char,
gint max_length)
{
ClutterActor *retval = clutter_text_new_full (FONT, text, color);
ClutterColor selection = { 0, };
clutter_actor_set_width (retval, 200);
clutter_actor_set_reactive (retval, TRUE);
clutter_color_darken (color, &selection);
clutter_text_set_editable (CLUTTER_TEXT (retval), TRUE);
clutter_text_set_selectable (CLUTTER_TEXT (retval), TRUE);
clutter_text_set_activatable (CLUTTER_TEXT (retval), TRUE);
clutter_text_set_single_line_mode (CLUTTER_TEXT (retval), TRUE);
clutter_text_set_password_char (CLUTTER_TEXT (retval), password_char);
clutter_text_set_cursor_color (CLUTTER_TEXT (retval), &selection);
clutter_text_set_max_length (CLUTTER_TEXT (retval), max_length);
g_signal_connect (retval, "activate",
G_CALLBACK (on_entry_activate),
NULL);
g_signal_connect (retval, "paint",
G_CALLBACK (on_entry_paint),
NULL);
return retval;
}
G_MODULE_EXPORT gint
test_text_field_main (gint argc,
gchar **argv)
{
ClutterActor *stage;
ClutterActor *text;
ClutterColor entry_color = {0x33, 0xff, 0x33, 0xff};
ClutterColor label_color = {0xff, 0xff, 0xff, 0xff};
ClutterColor background_color = {0x00, 0x00, 0x00, 0xff};
gint height;
clutter_init (&argc, &argv);
stage = clutter_stage_get_default ();
clutter_stage_set_color (CLUTTER_STAGE (stage), &background_color);
text = create_label (&label_color, "Input field: ");
clutter_actor_set_position (text, 10, 10);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), text);
height = clutter_actor_get_height (text);
text = create_entry (&entry_color, "some text", 0, 0);
clutter_actor_set_position (text, 200, 10);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), text);
text = create_label (&label_color, "Password field: ");
clutter_actor_set_position (text, 10, height + 12);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), text);
text = create_entry (&entry_color, "password", '*', 8);
clutter_actor_set_position (text, 200, height + 12);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), text);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,89 @@
#include <stdlib.h>
#include <gmodule.h>
#include <clutter/clutter.h>
#define FONT "Mono Bold 22px"
static gchar *runes =
"ᚠᛇᚻ᛫ᛒᛦᚦ᛫ᚠᚱᚩᚠᚢᚱ᛫ᚠᛁᚱᚪ᛫ᚷᛖᚻᚹᛦᛚᚳᚢᛗ\n"
"ᛋᚳᛖᚪᛚ᛫ᚦᛖᚪᚻ᛫ᛗᚪᚾᚾᚪ᛫ᚷᛖᚻᚹᛦᛚᚳ᛫ᛗᛁᚳᛚᚢᚾ᛫ᚻᛦᛏ᛫ᛞᚫᛚᚪᚾ\n"
"ᚷᛁᚠ᛫ᚻᛖ᛫ᚹᛁᛚᛖ᛫ᚠᚩᚱ᛫ᛞᚱᛁᚻᛏᚾᛖ᛫ᛞᚩᛗᛖᛋ᛫ᚻᛚᛇᛏᚪᚾ᛬\n";
static void
cursor_event (ClutterText *text,
ClutterGeometry *geometry)
{
gint y;
y = clutter_actor_get_y (CLUTTER_ACTOR (text));
if (y + geometry->y < 50)
{
clutter_actor_set_y (CLUTTER_ACTOR (text), y + 100);
}
else if (y + geometry->y > 720)
{
clutter_actor_set_y (CLUTTER_ACTOR (text), y - 100);
}
}
G_MODULE_EXPORT gint
test_text_main (gint argc,
gchar **argv)
{
ClutterActor *stage;
ClutterActor *text;
ClutterColor text_color = { 0x33, 0xff, 0x33, 0xff };
ClutterColor cursor_color = { 0xff, 0x33, 0x33, 0xff };
ClutterColor background_color = { 0x00, 0x00, 0x00, 0xff };
clutter_init (&argc, &argv);
stage = clutter_stage_get_default ();
clutter_stage_set_color (CLUTTER_STAGE (stage), &background_color);
text = clutter_text_new_full (FONT, "·", &text_color);
clutter_container_add (CLUTTER_CONTAINER (stage), text, NULL);
clutter_actor_set_position (text, 40, 30);
clutter_actor_set_width (text, 1024);
clutter_text_set_line_wrap (CLUTTER_TEXT (text), TRUE);
clutter_actor_set_reactive (text, TRUE);
clutter_stage_set_key_focus (CLUTTER_STAGE (stage), text);
clutter_text_set_editable (CLUTTER_TEXT (text), TRUE);
clutter_text_set_selectable (CLUTTER_TEXT (text), TRUE);
clutter_text_set_cursor_color (CLUTTER_TEXT (text), &cursor_color);
if (argv[1])
{
GError *error = NULL;
gchar *utf8;
g_file_get_contents (argv[1], &utf8, NULL, &error);
if (error)
{
utf8 = g_strconcat ("Unable to open '", argv[1], "':\n",
error->message,
NULL);
g_error_free (error);
}
clutter_text_set_text (CLUTTER_TEXT (text), utf8);
}
else
clutter_text_set_text (CLUTTER_TEXT (text), runes);
g_signal_connect (text, "cursor-event", G_CALLBACK (cursor_event), NULL);
clutter_actor_set_size (stage, 1024, 768);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -42,7 +42,7 @@ test_thread_done_idle (gpointer user_data)
g_print ("Thread completed\n"); g_print ("Thread completed\n");
clutter_label_set_text (CLUTTER_LABEL (data->label), "Completed"); clutter_text_set_text (CLUTTER_TEXT (data->label), "Completed");
clutter_timeline_stop (data->timeline); clutter_timeline_stop (data->timeline);
test_thread_data_free (data); test_thread_data_free (data);
@ -67,7 +67,7 @@ update_label_idle (gpointer data)
text = g_strdup_printf ("Count to %d", update->count); text = g_strdup_printf ("Count to %d", update->count);
clutter_label_set_text (CLUTTER_LABEL (update->thread_data->label), text); clutter_text_set_text (CLUTTER_TEXT (update->thread_data->label), text);
clutter_actor_set_width (update->thread_data->label, -1); clutter_actor_set_width (update->thread_data->label, -1);
if (update->count == 0) if (update->count == 0)
@ -151,7 +151,7 @@ on_key_press_event (ClutterStage *stage,
switch (clutter_key_event_symbol (event)) switch (clutter_key_event_symbol (event))
{ {
case CLUTTER_s: case CLUTTER_s:
clutter_label_set_text (CLUTTER_LABEL (help_label), "Press 'q' to quit"); clutter_text_set_text (CLUTTER_TEXT (help_label), "Press 'q' to quit");
clutter_timeline_start (timeline); clutter_timeline_start (timeline);
@ -191,10 +191,10 @@ test_threads_main (int argc, char *argv[])
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
clutter_actor_set_size (stage, 600, 300); clutter_actor_set_size (stage, 600, 300);
count_label = clutter_label_new_with_text ("Mono 12", "Counter"); count_label = clutter_text_new_with_text ("Mono 12", "Counter");
clutter_actor_set_position (count_label, 350, 50); clutter_actor_set_position (count_label, 350, 50);
help_label = clutter_label_new_with_text ("Mono 12", "Press 's' to start"); help_label = clutter_text_new_with_text ("Mono 12", "Press 's' to start");
clutter_actor_set_position (help_label, 50, 50); clutter_actor_set_position (help_label, 50, 50);
rect = clutter_rectangle_new_with_color (&rect_color); rect = clutter_rectangle_new_with_color (&rect_color);

View File

@ -5,13 +5,15 @@
#include <string.h> #include <string.h>
#include <gmodule.h> #include <gmodule.h>
ClutterActor *label;
#define RECT_L 200 #define RECT_L 200
#define RECT_T 150 #define RECT_T 150
#define RECT_W 320 #define RECT_W 320
#define RECT_H 240 #define RECT_H 240
static ClutterActor *test_rectangle = NULL;
static ClutterActor *label = NULL;
static gboolean static gboolean
on_event (ClutterStage *stage, on_event (ClutterStage *stage,
ClutterEvent *event, ClutterEvent *event,
@ -29,7 +31,6 @@ on_event (ClutterStage *stage,
actor = clutter_stage_get_actor_at_pos (stage, x, y); actor = clutter_stage_get_actor_at_pos (stage, x, y);
if (clutter_actor_transform_stage_point (actor, if (clutter_actor_transform_stage_point (actor,
CLUTTER_UNITS_FROM_DEVICE (x), CLUTTER_UNITS_FROM_DEVICE (x),
CLUTTER_UNITS_FROM_DEVICE (y), CLUTTER_UNITS_FROM_DEVICE (y),
@ -37,7 +38,7 @@ on_event (ClutterStage *stage,
{ {
gchar *txt; gchar *txt;
if (actor != CLUTTER_ACTOR (stage)) if (actor == test_rectangle)
txt = g_strdup_printf ("Click on rectangle\n" txt = g_strdup_printf ("Click on rectangle\n"
"Screen coords: [%d, %d]\n" "Screen coords: [%d, %d]\n"
"Local coords : [%d, %d]", "Local coords : [%d, %d]",
@ -52,12 +53,11 @@ on_event (ClutterStage *stage,
CLUTTER_UNITS_TO_DEVICE (xu2), CLUTTER_UNITS_TO_DEVICE (xu2),
CLUTTER_UNITS_TO_DEVICE (yu2)); CLUTTER_UNITS_TO_DEVICE (yu2));
clutter_label_set_text (CLUTTER_LABEL (label), txt); clutter_text_set_text (CLUTTER_TEXT (label), txt);
g_free (txt); g_free (txt);
} }
else else
clutter_label_set_text (CLUTTER_LABEL (label), clutter_text_set_text (CLUTTER_TEXT (label), "Unprojection failed.");
"Unprojection failed.");
} }
break; break;
@ -77,7 +77,7 @@ test_unproject_main (int argc, char *argv[])
int i, rotate_x = 0, rotate_y = 60, rotate_z = 0; int i, rotate_x = 0, rotate_y = 60, rotate_z = 0;
ClutterColor stage_clr = { 0x0, 0x0, 0x0, 0xff }, ClutterColor stage_clr = { 0x0, 0x0, 0x0, 0xff },
white = { 0xff, 0xff, 0xff, 0xff }, white = { 0xff, 0xff, 0xff, 0xff },
blue = { 0, 0xff, 0xff, 0xff }; blue = { 0x0, 0xff, 0xff, 0xff };
for (i = 0; i < argc; ++i) for (i = 0; i < argc; ++i)
{ {
@ -95,11 +95,12 @@ test_unproject_main (int argc, char *argv[])
} }
else if (!strncmp (argv[i], "--help", 6)) else if (!strncmp (argv[i], "--help", 6))
{ {
printf ("%s [--rotage-x=degrees] [--rotage-y=degrees] " g_print ("%s [--rotage-x=degrees] "
"[--rotage-y=degrees] "
"[--rotage-z=degrees]\n", "[--rotage-z=degrees]\n",
argv[0]); argv[0]);
exit (0); return EXIT_FAILURE;
} }
} }
@ -117,6 +118,7 @@ test_unproject_main (int argc, char *argv[])
clutter_actor_set_rotation (rect, CLUTTER_Y_AXIS, rotate_y, 0, 0, 0); clutter_actor_set_rotation (rect, CLUTTER_Y_AXIS, rotate_y, 0, 0, 0);
clutter_actor_set_rotation (rect, CLUTTER_Z_AXIS, rotate_z, 0, 0, 0); clutter_actor_set_rotation (rect, CLUTTER_Z_AXIS, rotate_z, 0, 0, 0);
clutter_group_add (CLUTTER_GROUP (stage), rect); clutter_group_add (CLUTTER_GROUP (stage), rect);
test_rectangle = rect;
txt = g_strdup_printf ("Rectangle: L %d, R %d, T %d, B %d\n" txt = g_strdup_printf ("Rectangle: L %d, R %d, T %d, B %d\n"
"Rotation : x %d, y %d, z %d", "Rotation : x %d, y %d, z %d",
@ -124,8 +126,8 @@ test_unproject_main (int argc, char *argv[])
RECT_T, RECT_T + RECT_H, RECT_T, RECT_T + RECT_H,
rotate_x, rotate_y, rotate_z); rotate_x, rotate_y, rotate_z);
label0 = clutter_label_new_with_text ("Mono 8pt", txt); label0 = clutter_text_new_with_text ("Mono 8pt", txt);
clutter_label_set_color (CLUTTER_LABEL (label0), &white); clutter_text_set_color (CLUTTER_TEXT (label0), &white);
clutter_actor_set_position (label0, 10, 10); clutter_actor_set_position (label0, 10, 10);
clutter_group_add (CLUTTER_GROUP (stage), label0); clutter_group_add (CLUTTER_GROUP (stage), label0);
@ -133,9 +135,9 @@ test_unproject_main (int argc, char *argv[])
g_free (txt); g_free (txt);
label = label =
clutter_label_new_with_text ("Mono 8pt", "Click around!"); clutter_text_new_with_text ("Mono 8pt", "Click around!");
clutter_label_set_color (CLUTTER_LABEL (label), &blue); clutter_text_set_color (CLUTTER_TEXT (label), &blue);
clutter_actor_set_position (label, 10, 50); clutter_actor_set_position (label, 10, 50);
clutter_group_add (CLUTTER_GROUP (stage), label); clutter_group_add (CLUTTER_GROUP (stage), label);
@ -146,5 +148,8 @@ test_unproject_main (int argc, char *argv[])
clutter_main(); clutter_main();
test_rectangle = NULL;
label = NULL;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -80,14 +80,14 @@ main (int argc, char *argv[])
scale = 1.0; scale = 1.0;
} }
label = clutter_label_new_with_text (font_name, text); label = clutter_text_new_with_text (font_name, text);
clutter_label_set_color (CLUTTER_LABEL (label), &label_color); clutter_text_set_color (CLUTTER_TEXT (label), &label_color);
clutter_actor_set_position (label, (1.0*STAGE_WIDTH/COLS)*col, clutter_actor_set_position (label, (1.0*STAGE_WIDTH/COLS)*col,
(1.0*STAGE_HEIGHT/ROWS)*row); (1.0*STAGE_HEIGHT/ROWS)*row);
/*clutter_actor_set_clip (label, 0,0, (1.0*STAGE_WIDTH/COLS), /*clutter_actor_set_clip (label, 0,0, (1.0*STAGE_WIDTH/COLS),
(1.0*STAGE_HEIGHT/ROWS));*/ (1.0*STAGE_HEIGHT/ROWS));*/
clutter_actor_set_scale (label, scale, scale); clutter_actor_set_scale (label, scale, scale);
clutter_label_set_line_wrap (CLUTTER_LABEL (label), FALSE); clutter_text_set_line_wrap (CLUTTER_TEXT (label), FALSE);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), label); clutter_container_add_actor (CLUTTER_CONTAINER (stage), label);
} }
} }

View File

@ -10,6 +10,12 @@ libdisable_npots_la_SOURCES = disable-npots.c
libdisable_npots_la_LIBADD = -ldl libdisable_npots_la_LIBADD = -ldl
INCLUDES = \
-I$(top_srcdir)/clutter \
-I$(top_builddir)/clutter \
$(CLUTTER_CFLAGS) \
-D_GNU_SOURCE
all-local : disable-npots.sh all-local : disable-npots.sh
clean-local : clean-local :

View File

@ -4,13 +4,22 @@
* overrides glGetString and removes the extension strings. * overrides glGetString and removes the extension strings.
*/ */
#include <GL/gl.h> /* This is just included to get the right GL header */
#include <cogl/cogl.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <ctype.h> #include <ctype.h>
/* If RTLD_NEXT isn't available then try just using NULL */
#ifdef RTLD_NEXT
#define LIB_HANDLE RTLD_NEXT
#else
#define LIB_HANDLE NULL
#endif
typedef const GLubyte * (* GetStringFunc) (GLenum name); typedef const GLubyte * (* GetStringFunc) (GLenum name);
static const char * const bad_strings[] static const char * const bad_strings[]
@ -23,16 +32,14 @@ const GLubyte *
glGetString (GLenum name) glGetString (GLenum name)
{ {
const GLubyte *ret = NULL; const GLubyte *ret = NULL;
static void *gl_lib = NULL;
static GetStringFunc func = NULL; static GetStringFunc func = NULL;
static GLubyte *extensions = NULL; static GLubyte *extensions = NULL;
if (gl_lib == NULL if (func == NULL
&& (gl_lib = dlopen ("libGL.so", RTLD_LAZY)) == NULL) && (func = (GetStringFunc) dlsym (LIB_HANDLE, "glGetString")) == NULL)
fprintf (stderr, "dlopen: %s\n", dlerror ());
else if (func == NULL
&& (func = (GetStringFunc) dlsym (gl_lib, "glGetString")) == NULL)
fprintf (stderr, "dlsym: %s\n", dlerror ()); fprintf (stderr, "dlsym: %s\n", dlerror ());
else if (func == glGetString)
fprintf (stderr, "dlsym returned the wrapper of glGetString\n");
else else
{ {
ret = (* func) (name); ret = (* func) (name);