clutter: Move TextNode to a separate header

By moving it into clutter/pango, we can make it optional along with all
the pango usages. See the next commits.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4106>
This commit is contained in:
Bilal Elmoussaoui 2024-11-12 13:43:02 +01:00 committed by Marge Bot
parent 2c308caf72
commit c15bb5d49c
7 changed files with 263 additions and 183 deletions

View File

@ -27,10 +27,7 @@
#include "clutter/clutter-paint-node-private.h"
#include <pango/pango.h>
#include "cogl/cogl.h"
#include "clutter/pango/clutter-pango-private.h"
#include "clutter/clutter-actor-private.h"
#include "clutter/clutter-blur-private.h"
#include "clutter/clutter-debug.h"
@ -701,172 +698,6 @@ clutter_texture_node_new (CoglTexture *texture,
return (ClutterPaintNode *) tnode;
}
/**
* ClutterTextNode:
*/
struct _ClutterTextNode
{
ClutterPaintNode parent_instance;
PangoLayout *layout;
CoglColor color;
};
/**
* ClutterTextNodeClass:
*
* The `ClutterTextNodeClass` structure is an opaque
* type whose contents cannot be directly accessed.
*/
struct _ClutterTextNodeClass
{
ClutterPaintNodeClass parent_class;
};
G_DEFINE_TYPE (ClutterTextNode, clutter_text_node, CLUTTER_TYPE_PAINT_NODE)
static void
clutter_text_node_finalize (ClutterPaintNode *node)
{
ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node);
g_clear_object (&tnode->layout);
CLUTTER_PAINT_NODE_CLASS (clutter_text_node_parent_class)->finalize (node);
}
static gboolean
clutter_text_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node);
return tnode->layout != NULL;
}
static void
clutter_text_node_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node);
ClutterColorState *color_state =
clutter_paint_context_get_color_state (paint_context);
ClutterColorState *target_color_state =
clutter_paint_context_get_target_color_state (paint_context);
ClutterContext *context = _clutter_context_get_default ();
PangoRectangle extents;
CoglFramebuffer *fb;
guint i;
if (node->operations == NULL)
return;
fb = get_target_framebuffer (node, paint_context);
pango_layout_get_pixel_extents (tnode->layout, NULL, &extents);
for (i = 0; i < node->operations->len; i++)
{
const ClutterPaintOperation *op;
float op_width, op_height;
gboolean clipped = FALSE;
op = &g_array_index (node->operations, ClutterPaintOperation, i);
switch (op->opcode)
{
case PAINT_OP_TEX_RECT:
op_width = op->op.texrect[2] - op->op.texrect[0];
op_height = op->op.texrect[3] - op->op.texrect[1];
/* if the primitive size was smaller than the layout,
* we clip the layout when drawin, to avoid spilling
* it out
*/
if (extents.width > op_width ||
extents.height > op_height)
{
cogl_framebuffer_push_rectangle_clip (fb,
op->op.texrect[0],
op->op.texrect[1],
op->op.texrect[2],
op->op.texrect[3]);
clipped = TRUE;
}
clutter_show_layout (context,
fb,
tnode->layout,
op->op.texrect[0],
op->op.texrect[1],
&tnode->color,
color_state,
target_color_state);
if (clipped)
cogl_framebuffer_pop_clip (fb);
break;
case PAINT_OP_TEX_RECTS:
case PAINT_OP_MULTITEX_RECT:
case PAINT_OP_PRIMITIVE:
case PAINT_OP_INVALID:
break;
}
}
}
static void
clutter_text_node_class_init (ClutterTextNodeClass *klass)
{
ClutterPaintNodeClass *node_class = CLUTTER_PAINT_NODE_CLASS (klass);
node_class->pre_draw = clutter_text_node_pre_draw;
node_class->draw = clutter_text_node_draw;
node_class->finalize = clutter_text_node_finalize;
}
static void
clutter_text_node_init (ClutterTextNode *self)
{
cogl_color_init_from_4f (&self->color, 0.0, 0.0, 0.0, 1.0);
}
/**
* clutter_text_node_new:
* @layout: (allow-none): a #PangoLayout, or %NULL
* @color: (allow-none): the color used to paint the layout,
* or %NULL
*
* Creates a new #ClutterPaintNode that will paint a #PangoLayout
* with the given color.
*
* This function takes a reference on the passed @layout, so it
* is safe to call g_object_unref() after it returns.
*
* Return value: (transfer full): the newly created #ClutterPaintNode.
* Use clutter_paint_node_unref() when done
*/
ClutterPaintNode *
clutter_text_node_new (PangoLayout *layout,
const CoglColor *color)
{
ClutterTextNode *res;
g_return_val_if_fail (layout == NULL || PANGO_IS_LAYOUT (layout), NULL);
res = _clutter_paint_node_create (CLUTTER_TYPE_TEXT_NODE);
if (layout != NULL)
res->layout = g_object_ref (layout);
if (color != NULL)
res->color = *color;
return (ClutterPaintNode *) res;
}
/**
* ClutterClipNode:
*/

View File

@ -88,20 +88,6 @@ GType clutter_pipeline_node_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT
ClutterPaintNode * clutter_pipeline_node_new (CoglPipeline *pipeline);
#define CLUTTER_TYPE_TEXT_NODE (clutter_text_node_get_type ())
#define CLUTTER_TEXT_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_TEXT_NODE, ClutterTextNode))
#define CLUTTER_IS_TEXT_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_TEXT_NODE))
typedef struct _ClutterTextNode ClutterTextNode;
typedef struct _ClutterTextNodeClass ClutterTextNodeClass;
CLUTTER_EXPORT
GType clutter_text_node_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT
ClutterPaintNode * clutter_text_node_new (PangoLayout *layout,
const CoglColor *color);
#define CLUTTER_TYPE_ACTOR_NODE (clutter_actor_node_get_type ())
#define CLUTTER_ACTOR_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTOR_NODE, ClutterActorNode))
#define CLUTTER_IS_ACTOR_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTOR_NODE))

View File

@ -41,6 +41,7 @@
#include "clutter/clutter-stage.h"
#include "clutter/pango/clutter-text-node.h"
#include "clutter/clutter-stage-accessible-private.h"
#include "clutter/clutter-action-private.h"
#include "clutter/clutter-actor-private.h"

View File

@ -107,4 +107,6 @@
#include "clutter/clutter-virtual-input-device.h"
#include "clutter/clutter-zoom-action.h"
#include "clutter/pango/clutter-text-node.h"
#undef __CLUTTER_H_INSIDE__

View File

@ -2,6 +2,7 @@ clutter_clutter_includesubdir = clutter_includesubdir / 'clutter'
clutter_clutter_includedir = clutter_includedir / 'clutter'
clutter_headers = [
'pango/clutter-text-node.h',
'clutter.h',
'clutter-action.h',
'clutter-actor-accessible.h',
@ -86,6 +87,7 @@ clutter_sources = [
'pango/clutter-pango-glyph-cache.c',
'pango/clutter-pango-pipeline-cache.c',
'pango/clutter-pango-render.c',
'pango/clutter-text-node.c',
'clutter-accessibility.c',
'clutter-action.c',
'clutter-actor-box.c',

View File

@ -0,0 +1,207 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#include "clutter/pango/clutter-text-node.h"
#include "clutter/pango/clutter-pango-private.h"
#include "clutter/clutter-paint-node-private.h"
#include "clutter/clutter-private.h"
/**
* ClutterTextNode:
*/
struct _ClutterTextNode
{
ClutterPaintNode parent_instance;
PangoLayout *layout;
CoglColor color;
};
/**
* ClutterTextNodeClass:
*
* The `ClutterTextNodeClass` structure is an opaque
* type whose contents cannot be directly accessed.
*/
struct _ClutterTextNodeClass
{
ClutterPaintNodeClass parent_class;
};
G_DEFINE_TYPE (ClutterTextNode, clutter_text_node, CLUTTER_TYPE_PAINT_NODE)
static void
clutter_text_node_finalize (ClutterPaintNode *node)
{
ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node);
g_clear_object (&tnode->layout);
CLUTTER_PAINT_NODE_CLASS (clutter_text_node_parent_class)->finalize (node);
}
static gboolean
clutter_text_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node);
return tnode->layout != NULL;
}
static CoglFramebuffer *
get_target_framebuffer (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
CoglFramebuffer *framebuffer;
framebuffer = clutter_paint_node_get_framebuffer (node);
if (framebuffer)
return framebuffer;
return clutter_paint_context_get_framebuffer (paint_context);
}
static void
clutter_text_node_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node);
ClutterColorState *color_state =
clutter_paint_context_get_color_state (paint_context);
ClutterColorState *target_color_state =
clutter_paint_context_get_target_color_state (paint_context);
ClutterContext *context = _clutter_context_get_default ();
PangoRectangle extents;
CoglFramebuffer *fb;
guint i;
if (node->operations == NULL)
return;
fb = get_target_framebuffer (node, paint_context);
pango_layout_get_pixel_extents (tnode->layout, NULL, &extents);
for (i = 0; i < node->operations->len; i++)
{
const ClutterPaintOperation *op;
float op_width, op_height;
gboolean clipped = FALSE;
op = &g_array_index (node->operations, ClutterPaintOperation, i);
switch (op->opcode)
{
case PAINT_OP_TEX_RECT:
op_width = op->op.texrect[2] - op->op.texrect[0];
op_height = op->op.texrect[3] - op->op.texrect[1];
/* if the primitive size was smaller than the layout,
* we clip the layout when drawin, to avoid spilling
* it out
*/
if (extents.width > op_width ||
extents.height > op_height)
{
cogl_framebuffer_push_rectangle_clip (fb,
op->op.texrect[0],
op->op.texrect[1],
op->op.texrect[2],
op->op.texrect[3]);
clipped = TRUE;
}
clutter_show_layout (context,
fb,
tnode->layout,
op->op.texrect[0],
op->op.texrect[1],
&tnode->color,
color_state,
target_color_state);
if (clipped)
cogl_framebuffer_pop_clip (fb);
break;
case PAINT_OP_TEX_RECTS:
case PAINT_OP_MULTITEX_RECT:
case PAINT_OP_PRIMITIVE:
case PAINT_OP_INVALID:
break;
}
}
}
static void
clutter_text_node_class_init (ClutterTextNodeClass *klass)
{
ClutterPaintNodeClass *node_class = CLUTTER_PAINT_NODE_CLASS (klass);
node_class->pre_draw = clutter_text_node_pre_draw;
node_class->draw = clutter_text_node_draw;
node_class->finalize = clutter_text_node_finalize;
}
static void
clutter_text_node_init (ClutterTextNode *self)
{
cogl_color_init_from_4f (&self->color, 0.0, 0.0, 0.0, 1.0);
}
/**
* clutter_text_node_new:
* @layout: (allow-none): a #PangoLayout, or %NULL
* @color: (allow-none): the color used to paint the layout,
* or %NULL
*
* Creates a new #ClutterPaintNode that will paint a #PangoLayout
* with the given color.
*
* This function takes a reference on the passed @layout, so it
* is safe to call g_object_unref() after it returns.
*
* Return value: (transfer full): the newly created #ClutterPaintNode.
* Use clutter_paint_node_unref() when done
*/
ClutterPaintNode *
clutter_text_node_new (PangoLayout *layout,
const CoglColor *color)
{
ClutterTextNode *res;
g_return_val_if_fail (layout == NULL || PANGO_IS_LAYOUT (layout), NULL);
res = _clutter_paint_node_create (CLUTTER_TYPE_TEXT_NODE);
if (layout != NULL)
res->layout = g_object_ref (layout);
if (color != NULL)
res->color = *color;
return (ClutterPaintNode *) res;
}

View File

@ -0,0 +1,51 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#pragma once
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <pango/pango.h>
#include "clutter/clutter-paint-nodes.h"
G_BEGIN_DECLS
#define CLUTTER_TYPE_TEXT_NODE (clutter_text_node_get_type ())
#define CLUTTER_TEXT_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_TEXT_NODE, ClutterTextNode))
#define CLUTTER_IS_TEXT_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_TEXT_NODE))
typedef struct _ClutterTextNode ClutterTextNode;
typedef struct _ClutterTextNodeClass ClutterTextNodeClass;
CLUTTER_EXPORT
GType clutter_text_node_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT
ClutterPaintNode * clutter_text_node_new (PangoLayout *layout,
const CoglColor *color);
G_END_DECLS