diff --git a/clutter/pango/Makefile.am b/clutter/pango/Makefile.am index 1d2d22402..e567e3ba2 100644 --- a/clutter/pango/Makefile.am +++ b/clutter/pango/Makefile.am @@ -1,4 +1,5 @@ source_c = \ + cogl-pango-display-list.c \ cogl-pango-fontmap.c \ cogl-pango-render.c \ cogl-pango-glyph-cache.c @@ -6,6 +7,7 @@ source_c = \ source_h = cogl-pango.h source_h_priv = \ + cogl-pango-display-list.h \ cogl-pango-private.h \ cogl-pango-glyph-cache.h diff --git a/clutter/pango/cogl-pango-display-list.c b/clutter/pango/cogl-pango-display-list.c new file mode 100644 index 000000000..b87b609f9 --- /dev/null +++ b/clutter/pango/cogl-pango-display-list.c @@ -0,0 +1,356 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Neil Roberts + * + * Copyright (C) 2009 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 . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "cogl-pango-display-list.h" + +typedef enum +{ + COGL_PANGO_DISPLAY_LIST_TEXTURE, + COGL_PANGO_DISPLAY_LIST_RECTANGLE, + COGL_PANGO_DISPLAY_LIST_TRAPEZOID +} CoglPangoDisplayListNodeType; + +typedef struct _CoglPangoDisplayListNode CoglPangoDisplayListNode; +typedef struct _CoglPangoDisplayListVertex CoglPangoDisplayListVertex; + +#ifdef HAVE_CLUTTER_GLX +#define COGL_PANGO_DISPLAY_LIST_DRAW_MODE GL_QUADS +#else +/* GLES doesn't support GL_QUADS so we use GL_TRIANGLES instead */ +#define COGL_PANGO_DISPLAY_LIST_DRAW_MODE GL_TRIANGLES +#endif + +struct _CoglPangoDisplayList +{ + CoglColor color; + GSList *nodes; + GSList *last_node; +}; + +struct _CoglPangoDisplayListNode +{ + CoglPangoDisplayListNodeType type; + + CoglColor color; + + union + { + struct + { + /* The texture to render these coords from */ + CoglHandle texture; + /* Array of vertex data to render out of this texture */ + GArray *verts; + /* A VBO representing those vertices */ + CoglHandle vertex_buffer; + } texture; + + struct + { + float x_1, y_1; + float x_2, y_2; + } rectangle; + + struct + { + float y_1; + float x_11; + float x_21; + float y_2; + float x_12; + float x_22; + } trapezoid; + } d; +}; + +struct _CoglPangoDisplayListVertex +{ + float x, y, t_x, t_y; +}; + +CoglPangoDisplayList * +_cogl_pango_display_list_new (void) +{ + return g_slice_new0 (CoglPangoDisplayList); +} + +static void +_cogl_pango_display_list_append_node (CoglPangoDisplayList *dl, + CoglPangoDisplayListNode *node) +{ + if (dl->last_node) + dl->last_node = dl->last_node->next = g_slist_prepend (NULL, node); + else + dl->last_node = dl->nodes = g_slist_prepend (NULL, node); +} + +void +_cogl_pango_display_list_set_color (CoglPangoDisplayList *dl, + const CoglColor *color) +{ + dl->color = *color; +} + +void +_cogl_pango_display_list_add_texture (CoglPangoDisplayList *dl, + CoglHandle texture, + float x_1, float y_1, + float x_2, float y_2, + float tx_1, float ty_1, + float tx_2, float ty_2) +{ + CoglPangoDisplayListNode *node; + CoglPangoDisplayListVertex *verts; + + /* Add to the last node if it is a texture node with the same + target texture */ + if (dl->last_node + && (node = dl->last_node->data)->type == COGL_PANGO_DISPLAY_LIST_TEXTURE + && node->d.texture.texture == texture + && !memcmp (&dl->color, &node->color, sizeof (CoglColor))) + { + /* Get rid of the vertex buffer so that it will be recreated */ + if (node->d.texture.vertex_buffer != COGL_INVALID_HANDLE) + { + cogl_vertex_buffer_unref (node->d.texture.vertex_buffer); + node->d.texture.vertex_buffer = COGL_INVALID_HANDLE; + } + } + else + { + /* Otherwise create a new node */ + node = g_slice_new (CoglPangoDisplayListNode); + + node->type = COGL_PANGO_DISPLAY_LIST_TEXTURE; + node->color = dl->color; + node->d.texture.texture = cogl_texture_ref (texture); + node->d.texture.verts + = g_array_new (FALSE, FALSE, sizeof (CoglPangoDisplayListVertex)); + node->d.texture.vertex_buffer = COGL_INVALID_HANDLE; + + _cogl_pango_display_list_append_node (dl, node); + } + + g_array_set_size (node->d.texture.verts, + node->d.texture.verts->len + 4); + verts = &g_array_index (node->d.texture.verts, + CoglPangoDisplayListVertex, + node->d.texture.verts->len - 4); + + verts->x = x_1; + verts->y = y_1; + verts->t_x = tx_1; + verts->t_y = ty_1; + verts++; + verts->x = x_1; + verts->y = y_2; + verts->t_x = tx_1; + verts->t_y = ty_2; + verts++; + verts->x = x_2; + verts->y = y_2; + verts->t_x = tx_2; + verts->t_y = ty_2; + verts++; + verts->x = x_2; + verts->y = y_1; + verts->t_x = tx_2; + verts->t_y = ty_1; + +#ifndef HAVE_CLUTTER_GLX + + /* GLES doesn't support GL_QUADS so we use GL_TRIANGLES instead with + two extra vertices per quad. FIXME: It might be better to use + indexed elements here but cogl vertex buffers don't currently + support storing the indices */ + + g_array_set_size (node->d.texture.verts, + node->d.texture.verts->len + 2); + verts = &g_array_index (node->d.texture.verts, + CoglPangoDisplayListVertex, + node->d.texture.verts->len - 6); + + verts[4] = verts[0]; + verts[5] = verts[2]; + +#endif /* HAVE_CLUTTER_GLX */ +} + +void +_cogl_pango_display_list_add_rectangle (CoglPangoDisplayList *dl, + float x_1, float y_1, + float x_2, float y_2) +{ + CoglPangoDisplayListNode *node = g_slice_new (CoglPangoDisplayListNode); + + node->type = COGL_PANGO_DISPLAY_LIST_RECTANGLE; + node->color = dl->color; + node->d.rectangle.x_1 = x_1; + node->d.rectangle.y_1 = y_1; + node->d.rectangle.x_2 = x_2; + node->d.rectangle.y_2 = y_2; + + _cogl_pango_display_list_append_node (dl, node); +} + +void +_cogl_pango_display_list_add_trapezoid (CoglPangoDisplayList *dl, + float y_1, + float x_11, + float x_21, + float y_2, + float x_12, + float x_22) +{ + CoglPangoDisplayListNode *node = g_slice_new (CoglPangoDisplayListNode); + + node->type = COGL_PANGO_DISPLAY_LIST_TRAPEZOID; + node->color = dl->color; + node->d.trapezoid.y_1 = y_1; + node->d.trapezoid.x_11 = x_11; + node->d.trapezoid.x_21 = x_21; + node->d.trapezoid.y_2 = y_2; + node->d.trapezoid.x_12 = x_12; + node->d.trapezoid.x_22 = x_22; + + _cogl_pango_display_list_append_node (dl, node); +} + +static void +_cogl_pango_display_list_render_texture (CoglHandle material, + CoglPangoDisplayListNode *node) +{ + cogl_material_set_layer (material, 0, node->d.texture.texture); + cogl_material_set_color (material, &node->color); + cogl_set_source (material); + + if (node->d.texture.vertex_buffer == COGL_INVALID_HANDLE) + { + CoglHandle vb = cogl_vertex_buffer_new (node->d.texture.verts->len); + + cogl_vertex_buffer_add (vb, "gl_Vertex", 2, GL_FLOAT, FALSE, + sizeof (CoglPangoDisplayListVertex), + &g_array_index (node->d.texture.verts, + CoglPangoDisplayListVertex, 0).x); + cogl_vertex_buffer_add (vb, "gl_MultiTexCoord0", 2, GL_FLOAT, FALSE, + sizeof (CoglPangoDisplayListVertex), + &g_array_index (node->d.texture.verts, + CoglPangoDisplayListVertex, + 0).t_x); + cogl_vertex_buffer_submit (vb); + + node->d.texture.vertex_buffer = vb; + } + + cogl_vertex_buffer_draw (node->d.texture.vertex_buffer, + COGL_PANGO_DISPLAY_LIST_DRAW_MODE, + 0, node->d.texture.verts->len); +} + +void +_cogl_pango_display_list_render (CoglPangoDisplayList *dl, + CoglHandle glyph_material, + CoglHandle solid_material) +{ + GSList *l; + + for (l = dl->nodes; l; l = l->next) + { + CoglPangoDisplayListNode *node = l->data; + + switch (node->type) + { + case COGL_PANGO_DISPLAY_LIST_TEXTURE: + _cogl_pango_display_list_render_texture (glyph_material, node); + break; + + case COGL_PANGO_DISPLAY_LIST_RECTANGLE: + cogl_material_set_color (solid_material, &node->color); + cogl_set_source (solid_material); + cogl_rectangle (node->d.rectangle.x_1, + node->d.rectangle.y_1, + node->d.rectangle.x_2, + node->d.rectangle.y_2); + break; + + case COGL_PANGO_DISPLAY_LIST_TRAPEZOID: + { + float points[8]; + + points[0] = node->d.trapezoid.x_11; + points[1] = node->d.trapezoid.y_1; + points[2] = node->d.trapezoid.x_12; + points[3] = node->d.trapezoid.y_2; + points[4] = node->d.trapezoid.x_22; + points[5] = node->d.trapezoid.y_2; + points[6] = node->d.trapezoid.x_21; + points[7] = node->d.trapezoid.y_1; + + cogl_material_set_color (solid_material, &node->color); + cogl_set_source (solid_material); + cogl_path_polygon (points, 4); + cogl_path_fill (); + } + break; + } + } +} + +static void +_cogl_pango_display_list_node_free (CoglPangoDisplayListNode *node) +{ + if (node->type == COGL_PANGO_DISPLAY_LIST_TEXTURE) + { + g_array_free (node->d.texture.verts, TRUE); + if (node->d.texture.texture != COGL_INVALID_HANDLE) + cogl_texture_unref (node->d.texture.texture); + if (node->d.texture.vertex_buffer != COGL_INVALID_HANDLE) + cogl_vertex_buffer_unref (node->d.texture.vertex_buffer); + } + + g_slice_free (CoglPangoDisplayListNode, node); +} + +void +_cogl_pango_display_list_clear (CoglPangoDisplayList *dl) +{ + g_slist_foreach (dl->nodes, (GFunc) _cogl_pango_display_list_node_free, NULL); + g_slist_free (dl->nodes); + dl->nodes = NULL; + dl->last_node = NULL; +} + +void +_cogl_pango_display_list_free (CoglPangoDisplayList *dl) +{ + _cogl_pango_display_list_clear (dl); + g_slice_free (CoglPangoDisplayList, dl); +} diff --git a/clutter/pango/cogl-pango-display-list.h b/clutter/pango/cogl-pango-display-list.h new file mode 100644 index 000000000..a2b123208 --- /dev/null +++ b/clutter/pango/cogl-pango-display-list.h @@ -0,0 +1,68 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Neil Roberts + * + * Copyright (C) 2009 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 . + */ + +#ifndef __COGL_PANGO_DISPLAY_LIST_H__ +#define __COGL_PANGO_DISPLAY_LIST_H__ + +#include +#include + +G_BEGIN_DECLS + +typedef struct _CoglPangoDisplayList CoglPangoDisplayList; + +CoglPangoDisplayList *_cogl_pango_display_list_new (void); + +void _cogl_pango_display_list_set_color (CoglPangoDisplayList *dl, + const CoglColor *color); + +void _cogl_pango_display_list_add_texture (CoglPangoDisplayList *dl, + CoglHandle texture, + float x_1, float y_1, + float x_2, float y_2, + float tx_1, float ty_1, + float tx_2, float ty_2); + +void _cogl_pango_display_list_add_rectangle (CoglPangoDisplayList *dl, + float x_1, float y_1, + float x_2, float y_2); + +void _cogl_pango_display_list_add_trapezoid (CoglPangoDisplayList *dl, + float y_1, + float x_11, + float x_21, + float y_2, + float x_12, + float x_22); + +void _cogl_pango_display_list_render (CoglPangoDisplayList *dl, + CoglHandle glyph_material, + CoglHandle solid_material); + +void _cogl_pango_display_list_clear (CoglPangoDisplayList *dl); + +void _cogl_pango_display_list_free (CoglPangoDisplayList *dl); + +G_END_DECLS + +#endif /* __COGL_PANGO_DISPLAY_LIST_H__ */ diff --git a/clutter/pango/cogl-pango-render.c b/clutter/pango/cogl-pango-render.c index ba9395b21..99dd40d3f 100644 --- a/clutter/pango/cogl-pango-render.c +++ b/clutter/pango/cogl-pango-render.c @@ -36,6 +36,7 @@ #include "cogl-pango-private.h" #include "cogl-pango-glyph-cache.h" +#include "cogl-pango-display-list.h" struct _CoglPangoRenderer { @@ -55,9 +56,8 @@ struct _CoglPangoRenderer gboolean use_mipmapping; - /* Array of rectangles to draw from the current texture */ - GArray *glyph_rectangles; - CoglHandle glyph_texture; + /* The current display list that is being built */ + CoglPangoDisplayList *display_list; }; struct _CoglPangoRendererClass @@ -65,19 +65,18 @@ struct _CoglPangoRendererClass PangoRendererClass class_instance; }; -static void -cogl_pango_renderer_glyphs_end (CoglPangoRenderer *priv) +typedef struct _CoglPangoRendererQdata CoglPangoRendererQdata; + +/* An instance of this struct gets attached to each PangoLayout to + cache the VBO and to detect changes to the layout */ +struct _CoglPangoRendererQdata { - if (priv->glyph_rectangles->len > 0) - { - float *rectangles = (float *) priv->glyph_rectangles->data; - cogl_material_set_layer (priv->glyph_material, 0, priv->glyph_texture); - cogl_set_source (priv->glyph_material); - cogl_rectangles_with_texture_coords (rectangles, - priv->glyph_rectangles->len / 8); - g_array_set_size (priv->glyph_rectangles, 0); - } -} + /* The cache of the geometry for the layout */ + CoglPangoDisplayList *display_list; + /* A reference to the first line of the layout. This is just used to + detect changes */ + PangoLayoutLine *first_line; +}; static void cogl_pango_renderer_draw_glyph (CoglPangoRenderer *priv, @@ -86,25 +85,19 @@ cogl_pango_renderer_draw_glyph (CoglPangoRenderer *priv, float y1) { float x2, y2; - float *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; + g_return_if_fail (priv->display_list != NULL); x2 = x1 + (float) cache_value->draw_width; y2 = y1 + (float) cache_value->draw_height; - g_array_set_size (priv->glyph_rectangles, priv->glyph_rectangles->len + 8); - p = &g_array_index (priv->glyph_rectangles, float, - 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; + _cogl_pango_display_list_add_texture (priv->display_list, + cache_value->texture, + x1, y1, x2, y2, + cache_value->tx1, + cache_value->ty1, + cache_value->tx2, + cache_value->ty2); } static void cogl_pango_renderer_finalize (GObject *object); @@ -168,7 +161,6 @@ cogl_pango_renderer_init (CoglPangoRenderer *priv) priv->glyph_cache = cogl_pango_glyph_cache_new (FALSE); priv->mipmapped_glyph_cache = cogl_pango_glyph_cache_new (TRUE); priv->use_mipmapping = FALSE; - priv->glyph_rectangles = g_array_new (FALSE, FALSE, sizeof (float)); } static void @@ -191,7 +183,6 @@ cogl_pango_renderer_finalize (GObject *object) cogl_pango_glyph_cache_free (priv->mipmapped_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); } @@ -213,6 +204,27 @@ cogl_pango_get_renderer_from_context (PangoContext *context) return COGL_PANGO_RENDERER (renderer); } +static GQuark +cogl_pango_render_get_qdata_key (void) +{ + static GQuark key = 0; + + if (G_UNLIKELY (key == 0)) + key = g_quark_from_static_string ("CoglPangoDisplayList"); + + return key; +} + +static void +cogl_pango_render_qdata_destroy (CoglPangoRendererQdata *qdata) +{ + if (qdata->display_list) + _cogl_pango_display_list_free (qdata->display_list); + if (qdata->first_line) + pango_layout_line_unref (qdata->first_line); + g_slice_free (CoglPangoRendererQdata, qdata); +} + /** * cogl_pango_render_layout_subpixel: * @layout: a #PangoLayout @@ -232,17 +244,67 @@ cogl_pango_render_layout_subpixel (PangoLayout *layout, const CoglColor *color, int flags) { - PangoContext *context; - CoglPangoRenderer *priv; + PangoContext *context; + CoglPangoRenderer *priv; + CoglPangoRendererQdata *qdata; context = pango_layout_get_context (layout); priv = cogl_pango_get_renderer_from_context (context); if (G_UNLIKELY (!priv)) return; - priv->color = *color; + qdata = g_object_get_qdata (G_OBJECT (layout), + cogl_pango_render_get_qdata_key ()); - pango_renderer_draw_layout (PANGO_RENDERER (priv), layout, x, y); + if (qdata == NULL) + { + qdata = g_slice_new0 (CoglPangoRendererQdata); + g_object_set_qdata_full (G_OBJECT (layout), + cogl_pango_render_get_qdata_key (), + qdata, + (GDestroyNotify) + cogl_pango_render_qdata_destroy); + } + + /* Check if the layout has changed since the last build of the + display list. This trick was suggested by Behdad Esfahbod here: + http://mail.gnome.org/archives/gtk-i18n-list/2009-May/msg00019.html */ + if (qdata->display_list && qdata->first_line + && qdata->first_line->layout != layout) + { + _cogl_pango_display_list_free (qdata->display_list); + qdata->display_list = NULL; + } + + if (qdata->display_list == NULL) + { + qdata->display_list = _cogl_pango_display_list_new (); + + priv->color = *color; + priv->display_list = qdata->display_list; + pango_renderer_draw_layout (PANGO_RENDERER (priv), layout, 0, 0); + priv->display_list = NULL; + } + + cogl_push_matrix (); + cogl_translate (x / (gfloat) PANGO_SCALE, y / (gfloat) PANGO_SCALE, 0); + _cogl_pango_display_list_render (qdata->display_list, + priv->glyph_material, + priv->solid_material); + cogl_pop_matrix (); + + /* Keep a reference to the first line of the layout so we can detect + changes */ + if (qdata->first_line) + { + pango_layout_line_unref (qdata->first_line); + qdata->first_line = NULL; + } + if (pango_layout_get_line_count (layout) > 0) + { + qdata->first_line = pango_layout_get_line (layout, 0); + pango_layout_line_ref (qdata->first_line); + } } /** @@ -296,9 +358,19 @@ cogl_pango_render_layout_line (PangoLayoutLine *line, if (G_UNLIKELY (!priv)) return; + priv->display_list = _cogl_pango_display_list_new (); priv->color = *color; pango_renderer_draw_layout_line (PANGO_RENDERER (priv), line, x, y); + + cogl_material_set_color (priv->glyph_material, color); + cogl_material_set_color (priv->solid_material, color); + _cogl_pango_display_list_render (priv->display_list, + priv->glyph_material, + priv->solid_material); + + _cogl_pango_display_list_free (priv->display_list); + priv->display_list = NULL; } void @@ -444,8 +516,7 @@ cogl_pango_renderer_set_color_for_part (PangoRenderer *renderer, else color = priv->color; - cogl_material_set_color (priv->solid_material, &color); - cogl_material_set_color (priv->glyph_material, &color); + _cogl_pango_display_list_set_color (priv->display_list, &color); } static void @@ -457,12 +528,13 @@ cogl_pango_renderer_draw_box (PangoRenderer *renderer, { CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); - cogl_set_source (priv->solid_material); - cogl_path_rectangle (x, - y - height, - x + width, - y); - cogl_path_stroke (); + g_return_if_fail (priv->display_list != NULL); + + _cogl_pango_display_list_add_rectangle (priv->display_list, + x, + y - height, + x + width, + y); } static void @@ -500,6 +572,8 @@ cogl_pango_renderer_draw_rectangle (PangoRenderer *renderer, CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); float x1, x2, y1, y2; + g_return_if_fail (priv->display_list != NULL); + cogl_pango_renderer_set_color_for_part (renderer, part); cogl_pango_renderer_get_device_units (renderer, @@ -509,8 +583,8 @@ cogl_pango_renderer_draw_rectangle (PangoRenderer *renderer, x + width, y + height, &x2, &y2); - cogl_set_source (priv->solid_material); - cogl_rectangle (x1, y1, x2, y2); + _cogl_pango_display_list_add_rectangle (priv->display_list, + x1, y1, x2, y2); } static void @@ -526,6 +600,8 @@ cogl_pango_renderer_draw_trapezoid (PangoRenderer *renderer, CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); float points[8]; + g_return_if_fail (priv->display_list != NULL); + points[0] = (x11); points[1] = (y1); points[2] = (x12); @@ -537,9 +613,13 @@ cogl_pango_renderer_draw_trapezoid (PangoRenderer *renderer, cogl_pango_renderer_set_color_for_part (renderer, part); - cogl_set_source (priv->solid_material); - cogl_path_polygon (points, 4); - cogl_path_fill (); + _cogl_pango_display_list_add_trapezoid (priv->display_list, + y1, + x11, + x21, + y2, + x12, + x22); } static void @@ -570,8 +650,6 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer, { PangoFontMetrics *metrics; - cogl_pango_renderer_glyphs_end (priv); - if (font == NULL || (metrics = pango_font_get_metrics (font, NULL)) == NULL) { @@ -603,15 +681,11 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer, gi->glyph); if (cache_value == NULL) - { - cogl_pango_renderer_glyphs_end (priv); - - cogl_pango_renderer_draw_box (renderer, - x, - y, - PANGO_UNKNOWN_GLYPH_WIDTH, - PANGO_UNKNOWN_GLYPH_HEIGHT); - } + cogl_pango_renderer_draw_box (renderer, + x, + y, + PANGO_UNKNOWN_GLYPH_WIDTH, + PANGO_UNKNOWN_GLYPH_HEIGHT); else { float width, height; @@ -628,6 +702,4 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer, xi += gi->geometry.width; } - - cogl_pango_renderer_glyphs_end (priv); }