From 579db9083de35387544a15ecc8f35f54a084f4cf Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Thu, 10 May 2012 12:16:03 +0100 Subject: [PATCH] cogl-pango: Updates to no longer require a default context This updates the Cogl Pango api to no longer require a default context and also cleans up the public api a bit. The CoglPangoRenderer type has been made private to be consistent with other pango backends where the renderer is merely an implementation detail. The drawing apis such as cogl_pango_render_layout where made more consistent with other pango backend apis so we now have replacements like cogl_pango_show_layout(). Reviewed-by: Neil Roberts (cherry picked from commit bba2defe8c08a498b2dcb84bcf5b5a33f16eed27) Note: API changes were reverting in cherry-picking this patch --- cogl-pango/cogl-pango-display-list.c | 55 ++--- cogl-pango/cogl-pango-display-list.h | 59 +++--- cogl-pango/cogl-pango-fontmap.c | 182 +++++++---------- cogl-pango/cogl-pango-pipeline-cache.c | 18 +- cogl-pango/cogl-pango-pipeline-cache.h | 3 +- cogl-pango/cogl-pango-private.h | 39 +++- cogl-pango/cogl-pango-render.c | 268 ++++++++++++++++--------- cogl-pango/cogl-pango.h | 227 ++++++++++++++++++--- 8 files changed, 552 insertions(+), 299 deletions(-) diff --git a/cogl-pango/cogl-pango-display-list.c b/cogl-pango/cogl-pango-display-list.c index 64012be1d..6a88befca 100644 --- a/cogl-pango/cogl-pango-display-list.c +++ b/cogl-pango/cogl-pango-display-list.c @@ -236,17 +236,24 @@ _cogl_pango_display_list_add_trapezoid (CoglPangoDisplayList *dl, } static void -emit_rectangles_through_journal (CoglPangoDisplayListNode *node) +emit_rectangles_through_journal (CoglFramebuffer *fb, + CoglPipeline *pipeline, + CoglPangoDisplayListNode *node) { - cogl_rectangles_with_texture_coords ((float *) - node->d.texture.rectangles->data, - node->d.texture.rectangles->len); + const float *rectangles = (const float *)node->d.texture.rectangles->data; + + cogl_framebuffer_draw_textured_rectangles (fb, + pipeline, + rectangles, + node->d.texture.rectangles->len); } static void -emit_vertex_buffer_geometry (CoglPangoDisplayListNode *node) +emit_vertex_buffer_geometry (CoglFramebuffer *fb, + CoglPipeline *pipeline, + CoglPangoDisplayListNode *node) { - _COGL_GET_CONTEXT (ctx, NO_RETVAL); + CoglContext *ctx = fb->context; /* It's expensive to go through the Cogl journal for large runs * of text in part because the journal transforms the quads in software @@ -366,13 +373,15 @@ emit_vertex_buffer_geometry (CoglPangoDisplayListNode *node) cogl_object_unref (attributes[1]); } - cogl_framebuffer_draw_primitive (cogl_get_draw_framebuffer (), - cogl_get_source (), + cogl_framebuffer_draw_primitive (fb, + pipeline, node->d.texture.primitive); } static void -_cogl_pango_display_list_render_texture (CoglPangoDisplayListNode *node) +_cogl_framebuffer_draw_display_list_texture (CoglFramebuffer *fb, + CoglPipeline *pipeline, + CoglPangoDisplayListNode *node) { /* For small runs of text like icon labels, we can get better performance * going through the Cogl journal since text may then be batched together @@ -380,13 +389,14 @@ _cogl_pango_display_list_render_texture (CoglPangoDisplayListNode *node) /* FIXME: 25 is a number I plucked out of thin air; it would be good * to determine this empirically! */ if (node->d.texture.rectangles->len < 25) - emit_rectangles_through_journal (node); + emit_rectangles_through_journal (fb, pipeline, node); else - emit_vertex_buffer_geometry (node); + emit_vertex_buffer_geometry (fb, pipeline, node); } void -_cogl_pango_display_list_render (CoglPangoDisplayList *dl, +_cogl_pango_display_list_render (CoglFramebuffer *fb, + CoglPangoDisplayList *dl, const CoglColor *color) { GSList *l; @@ -421,28 +431,27 @@ _cogl_pango_display_list_render (CoglPangoDisplayList *dl, cogl_color_premultiply (&draw_color); cogl_pipeline_set_color (node->pipeline, &draw_color); - cogl_push_source (node->pipeline); switch (node->type) { case COGL_PANGO_DISPLAY_LIST_TEXTURE: - _cogl_pango_display_list_render_texture (node); + _cogl_framebuffer_draw_display_list_texture (fb, node->pipeline, node); break; case COGL_PANGO_DISPLAY_LIST_RECTANGLE: - cogl_rectangle (node->d.rectangle.x_1, - node->d.rectangle.y_1, - node->d.rectangle.x_2, - node->d.rectangle.y_2); + cogl_framebuffer_draw_rectangle (fb, + node->pipeline, + 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: { - CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); float points[8]; CoglPath *path; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); + CoglContext *ctx = fb->context; points[0] = node->d.trapezoid.x_11; points[1] = node->d.trapezoid.y_1; @@ -455,13 +464,11 @@ _cogl_pango_display_list_render (CoglPangoDisplayList *dl, path = cogl_path_new (); cogl_path_polygon (path, points, 4); - cogl_framebuffer_fill_path (framebuffer, node->pipeline, path); + cogl_framebuffer_fill_path (fb, node->pipeline, path); cogl_object_unref (path); } break; } - - cogl_pop_source (); } } diff --git a/cogl-pango/cogl-pango-display-list.h b/cogl-pango/cogl-pango-display-list.h index 98c821ddb..28ac4fd24 100644 --- a/cogl-pango/cogl-pango-display-list.h +++ b/cogl-pango/cogl-pango-display-list.h @@ -32,37 +32,48 @@ COGL_BEGIN_DECLS typedef struct _CoglPangoDisplayList CoglPangoDisplayList; -CoglPangoDisplayList *_cogl_pango_display_list_new (CoglPangoPipelineCache *); +CoglPangoDisplayList * +_cogl_pango_display_list_new (CoglPangoPipelineCache *); -void _cogl_pango_display_list_set_color_override (CoglPangoDisplayList *dl, - const CoglColor *color); -void _cogl_pango_display_list_remove_color_override (CoglPangoDisplayList *dl); +void +_cogl_pango_display_list_set_color_override (CoglPangoDisplayList *dl, + const CoglColor *color); -void _cogl_pango_display_list_add_texture (CoglPangoDisplayList *dl, - CoglTexture *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_remove_color_override (CoglPangoDisplayList *dl); -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_texture (CoglPangoDisplayList *dl, + CoglTexture *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_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_add_rectangle (CoglPangoDisplayList *dl, + float x_1, float y_1, + float x_2, float y_2); -void _cogl_pango_display_list_render (CoglPangoDisplayList *dl, - const CoglColor *color); +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_clear (CoglPangoDisplayList *dl); +void +_cogl_pango_display_list_render (CoglFramebuffer *framebuffer, + CoglPangoDisplayList *dl, + const CoglColor *color); -void _cogl_pango_display_list_free (CoglPangoDisplayList *dl); +void +_cogl_pango_display_list_clear (CoglPangoDisplayList *dl); + +void +_cogl_pango_display_list_free (CoglPangoDisplayList *dl); COGL_END_DECLS diff --git a/cogl-pango/cogl-pango-fontmap.c b/cogl-pango/cogl-pango-fontmap.c index f272f80d5..0f475f95f 100644 --- a/cogl-pango/cogl-pango-fontmap.c +++ b/cogl-pango/cogl-pango-fontmap.c @@ -45,165 +45,131 @@ #include "cogl-pango.h" #include "cogl-pango-private.h" +#include "cogl-util.h" +#include "cogl/cogl-context-private.h" -static GQuark cogl_pango_font_map_get_renderer_key (void) G_GNUC_CONST; +static GQuark cogl_pango_font_map_get_priv_key (void) G_GNUC_CONST; + +typedef struct _CoglPangoFontMapPriv +{ + CoglContext *ctx; + PangoRenderer *renderer; +} CoglPangoFontMapPriv; + +static void +free_priv (gpointer data) +{ + CoglPangoFontMapPriv *priv = data; + + cogl_object_unref (priv->ctx); + cogl_object_unref (priv->renderer); + + g_free (priv); +} -/** - * cogl_pango_font_map_new: - * - * Creates a new font map. - * - * Return value: (transfer full): the newly created #PangoFontMap - * - * Since: 1.0 - */ PangoFontMap * cogl_pango_font_map_new (void) { - return pango_cairo_font_map_new (); + PangoFontMap *fm = pango_cairo_font_map_new (); + CoglPangoFontMapPriv *priv = g_new0 (CoglPangoFontMapPriv, 1); + + _COGL_GET_CONTEXT (context, NULL); + + priv->ctx = cogl_object_ref (context); + + /* XXX: The public pango api doesn't let us sub-class + * PangoCairoFontMap so we attach our own private data using qdata + * for now. */ + g_object_set_qdata_full (G_OBJECT (fm), + cogl_pango_font_map_get_priv_key (), + priv, + free_priv); + + return fm; } -/** - * cogl_pango_font_map_create_context: - * @fm: a #CoglPangoFontMap - * - * Creates a new #PangoContext from the passed font map. - * - * Return value: (transfer full): the newly created #PangoContext - * - * Since: 1.0 - */ PangoContext * cogl_pango_font_map_create_context (CoglPangoFontMap *fm) { - g_return_val_if_fail (COGL_PANGO_IS_FONT_MAP (fm), NULL); + _COGL_RETURN_VAL_IF_FAIL (COGL_PANGO_IS_FONT_MAP (fm), NULL); /* We can just directly use the pango context from the Cairo font map */ return pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fm)); } -/** - * cogl_pango_font_map_get_renderer: - * @fm: a #CoglPangoFontMap - * - * Retrieves the #CoglPangoRenderer for the passed font map. - * - * Return value: (transfer none): a #PangoRenderer - * - * Since: 1.0 - */ +static CoglPangoFontMapPriv * +_cogl_pango_font_map_get_priv (CoglPangoFontMap *fm) +{ + return g_object_get_qdata (G_OBJECT (fm), + cogl_pango_font_map_get_priv_key ()); +} + +PangoRenderer * +_cogl_pango_font_map_get_renderer (CoglPangoFontMap *fm) +{ + CoglPangoFontMapPriv *priv = _cogl_pango_font_map_get_priv (fm); + if (G_UNLIKELY (!priv->renderer)) + priv->renderer = _cogl_pango_renderer_new (priv->ctx); + return priv->renderer; +} + PangoRenderer * cogl_pango_font_map_get_renderer (CoglPangoFontMap *fm) { - PangoRenderer *renderer; - - g_return_val_if_fail (COGL_PANGO_IS_FONT_MAP (fm), NULL); - - /* We want to keep a cached pointer to the renderer from the font - map instance but as we don't have a proper subclass we have to - store it in the object data instead */ - - renderer = g_object_get_qdata (G_OBJECT (fm), - cogl_pango_font_map_get_renderer_key ()); - - if (G_UNLIKELY (renderer == NULL)) - { - renderer = g_object_new (COGL_PANGO_TYPE_RENDERER, NULL); - g_object_set_qdata_full (G_OBJECT (fm), - cogl_pango_font_map_get_renderer_key (), - renderer, - g_object_unref); - } - - return renderer; + return _cogl_pango_font_map_get_renderer (fm); +} + +CoglContext * +_cogl_pango_font_map_get_cogl_context (CoglPangoFontMap *fm) +{ + CoglPangoFontMapPriv *priv = _cogl_pango_font_map_get_priv (fm); + return priv->ctx; } -/** - * cogl_pango_font_map_set_resolution: - * @font_map: a #CoglPangoFontMap - * @dpi: DPI to set - * - * Sets the resolution to be used by @font_map at @dpi. - * - * Since: 1.0 - */ void cogl_pango_font_map_set_resolution (CoglPangoFontMap *font_map, double dpi) { - g_return_if_fail (COGL_PANGO_IS_FONT_MAP (font_map)); + _COGL_RETURN_IF_FAIL (COGL_PANGO_IS_FONT_MAP (font_map)); pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (font_map), dpi); } -/** - * cogl_pango_font_map_clear_glyph_cache: - * @fm: a #CoglPangoFontMap - * - * Clears the glyph cache for @fm. - * - * Since: 1.0 - */ void cogl_pango_font_map_clear_glyph_cache (CoglPangoFontMap *fm) { - PangoRenderer *renderer; - - renderer = cogl_pango_font_map_get_renderer (fm); + PangoRenderer *renderer = _cogl_pango_font_map_get_renderer (fm); _cogl_pango_renderer_clear_glyph_cache (COGL_PANGO_RENDERER (renderer)); } -/** - * cogl_pango_font_map_set_use_mipmapping: - * @fm: a #CoglPangoFontMap - * @value: %TRUE to enable the use of mipmapping - * - * Sets whether the renderer for the passed font map should use - * mipmapping when rendering a #PangoLayout. - * - * Since: 1.0 - */ void cogl_pango_font_map_set_use_mipmapping (CoglPangoFontMap *fm, CoglBool value) { - CoglPangoRenderer *renderer; + PangoRenderer *renderer = _cogl_pango_font_map_get_renderer (fm); - renderer = COGL_PANGO_RENDERER (cogl_pango_font_map_get_renderer (fm)); - - _cogl_pango_renderer_set_use_mipmapping (renderer, value); + _cogl_pango_renderer_set_use_mipmapping (COGL_PANGO_RENDERER (renderer), + value); } -/** - * cogl_pango_font_map_get_use_mipmapping: - * @fm: a #CoglPangoFontMap - * - * Retrieves whether the #CoglPangoRenderer used by @fm will - * use mipmapping when rendering the glyphs. - * - * Return value: %TRUE if mipmapping is used, %FALSE otherwise. - * - * Since: 1.0 - */ CoglBool cogl_pango_font_map_get_use_mipmapping (CoglPangoFontMap *fm) { - CoglPangoRenderer *renderer; + PangoRenderer *renderer = _cogl_pango_font_map_get_renderer (fm); - renderer = COGL_PANGO_RENDERER (cogl_pango_font_map_get_renderer (fm)); - - return _cogl_pango_renderer_get_use_mipmapping (renderer); + return + _cogl_pango_renderer_get_use_mipmapping (COGL_PANGO_RENDERER (renderer)); } static GQuark -cogl_pango_font_map_get_renderer_key (void) +cogl_pango_font_map_get_priv_key (void) { - static GQuark renderer_key = 0; + static GQuark priv_key = 0; - if (G_UNLIKELY (renderer_key == 0)) - renderer_key = g_quark_from_static_string ("CoglPangoFontMap"); + if (G_UNLIKELY (priv_key == 0)) + priv_key = g_quark_from_static_string ("CoglPangoFontMap"); - return renderer_key; + return priv_key; } diff --git a/cogl-pango/cogl-pango-pipeline-cache.c b/cogl-pango/cogl-pango-pipeline-cache.c index 13f1e2ad4..11cbb64aa 100644 --- a/cogl-pango/cogl-pango-pipeline-cache.c +++ b/cogl-pango/cogl-pango-pipeline-cache.c @@ -39,6 +39,8 @@ typedef struct _CoglPangoPipelineCacheEntry CoglPangoPipelineCacheEntry; struct _CoglPangoPipelineCache { + CoglContext *ctx; + GHashTable *hash_table; CoglPipeline *base_texture_alpha_pipeline; @@ -79,10 +81,13 @@ _cogl_pango_pipeline_cache_value_destroy (void *data) } CoglPangoPipelineCache * -_cogl_pango_pipeline_cache_new (CoglBool use_mipmapping) +_cogl_pango_pipeline_cache_new (CoglContext *ctx, + CoglBool use_mipmapping) { CoglPangoPipelineCache *cache = g_new (CoglPangoPipelineCache, 1); + cache->ctx = cogl_object_ref (ctx); + /* The key is the pipeline pointer. A reference is taken when the pipeline is used as a key so we should unref it again in the destroy function */ @@ -107,9 +112,8 @@ get_base_texture_rgba_pipeline (CoglPangoPipelineCache *cache) { CoglPipeline *pipeline; - _COGL_GET_CONTEXT (ctx, NULL); - - pipeline = cache->base_texture_rgba_pipeline = cogl_pipeline_new (ctx); + pipeline = cache->base_texture_rgba_pipeline = + cogl_pipeline_new (cache->ctx); cogl_pipeline_set_layer_wrap_mode (pipeline, 0, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); @@ -205,10 +209,8 @@ _cogl_pango_pipeline_cache_get (CoglPangoPipelineCache *cache, } else { - _COGL_GET_CONTEXT (ctx, NULL); - entry->texture = NULL; - entry->pipeline = cogl_pipeline_new (ctx); + entry->pipeline = cogl_pipeline_new (cache->ctx); } /* Add a weak reference to the pipeline so we can remove it from the @@ -240,5 +242,7 @@ _cogl_pango_pipeline_cache_free (CoglPangoPipelineCache *cache) g_hash_table_destroy (cache->hash_table); + cogl_object_unref (cache->ctx); + g_free (cache); } diff --git a/cogl-pango/cogl-pango-pipeline-cache.h b/cogl-pango/cogl-pango-pipeline-cache.h index 7d43f7176..615eaf991 100644 --- a/cogl-pango/cogl-pango-pipeline-cache.h +++ b/cogl-pango/cogl-pango-pipeline-cache.h @@ -36,7 +36,8 @@ COGL_BEGIN_DECLS typedef struct _CoglPangoPipelineCache CoglPangoPipelineCache; CoglPangoPipelineCache * -_cogl_pango_pipeline_cache_new (CoglBool use_mipmapping); +_cogl_pango_pipeline_cache_new (CoglContext *ctx, + CoglBool use_mipmapping); /* Returns a pipeline that can be used to render glyphs in the given texture. The pipeline has a new reference so it is up to the caller diff --git a/cogl-pango/cogl-pango-private.h b/cogl-pango/cogl-pango-private.h index 6d0e2fb39..49c94a58d 100644 --- a/cogl-pango/cogl-pango-private.h +++ b/cogl-pango/cogl-pango-private.h @@ -1,11 +1,10 @@ /* - * Clutter. + * Cogl * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum + * An object oriented GL/GLES Abstraction/Utility Layer * * Copyright (C) 2008 OpenedHand + * Copyright (C) 2012 Intel Corporation. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +17,14 @@ * 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 . + * License along with this library. If not, see + * . + * + * + * Authors: + * Neil Roberts + * Robert Bragg + * Matthew Allum */ #ifndef __COGL_PANGO_PRIVATE_H__ @@ -28,10 +34,25 @@ COGL_BEGIN_DECLS -void _cogl_pango_renderer_clear_glyph_cache (CoglPangoRenderer *renderer); -void _cogl_pango_renderer_set_use_mipmapping (CoglPangoRenderer *renderer, - CoglBool value); -CoglBool _cogl_pango_renderer_get_use_mipmapping (CoglPangoRenderer *renderer); +PangoRenderer * +_cogl_pango_renderer_new (CoglContext *context); + +void +_cogl_pango_renderer_clear_glyph_cache (CoglPangoRenderer *renderer); + +void +_cogl_pango_renderer_set_use_mipmapping (CoglPangoRenderer *renderer, + CoglBool value); +CoglBool +_cogl_pango_renderer_get_use_mipmapping (CoglPangoRenderer *renderer); + + + +CoglContext * +_cogl_pango_font_map_get_cogl_context (CoglPangoFontMap *fm); + +PangoRenderer * +_cogl_pango_font_map_get_renderer (CoglPangoFontMap *fm); COGL_END_DECLS diff --git a/cogl-pango/cogl-pango-render.c b/cogl-pango/cogl-pango-render.c index b1f1f6e65..6c63ee64b 100644 --- a/cogl-pango/cogl-pango-render.c +++ b/cogl-pango/cogl-pango-render.c @@ -1,11 +1,10 @@ /* - * Clutter. + * Cogl * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum + * An object oriented GL/GLES Abstraction/Utility Layer * * Copyright (C) 2008 OpenedHand + * Copyright (C) 2012 Intel Corporation. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +17,14 @@ * 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 . + * License along with this library. If not, see + * . + * + * + * Authors: + * Neil Roberts + * Robert Bragg + * Matthew Allum */ #ifdef HAVE_CONFIG_H @@ -41,6 +47,14 @@ #include "cogl-pango-glyph-cache.h" #include "cogl-pango-display-list.h" +enum +{ + PROP_0, + + PROP_COGL_CONTEXT, + PROP_LAST +}; + typedef struct { CoglPangoGlyphCache *glyph_cache; @@ -51,6 +65,8 @@ struct _CoglPangoRenderer { PangoRenderer parent_instance; + CoglContext *ctx; + /* Two caches of glyphs as textures and their corresponding pipeline caches, one with mipmapped textures and one without */ CoglPangoRendererCaches no_mipmap_caches; @@ -67,11 +83,11 @@ struct _CoglPangoRendererClass PangoRendererClass class_instance; }; -typedef struct _CoglPangoRendererQdata CoglPangoRendererQdata; +typedef struct _CoglPangoLayoutQdata CoglPangoLayoutQdata; /* An instance of this struct gets attached to each PangoLayout to cache the VBO and to detect changes to the layout */ -struct _CoglPangoRendererQdata +struct _CoglPangoLayoutQdata { CoglPangoRenderer *renderer; /* The cache of the geometry for the layout */ @@ -94,6 +110,13 @@ typedef struct float x1, y1, x2, y2; } CoglPangoRendererSliceCbData; +PangoRenderer * +_cogl_pango_renderer_new (CoglContext *context) +{ + return PANGO_RENDERER (g_object_new (COGL_PANGO_TYPE_RENDERER, + "context", context, NULL)); +} + static void cogl_pango_renderer_slice_cb (CoglTexture *texture, const float *slice_coords, @@ -126,7 +149,7 @@ cogl_pango_renderer_draw_glyph (CoglPangoRenderer *priv, { CoglPangoRendererSliceCbData data; - g_return_if_fail (priv->display_list != NULL); + _COGL_RETURN_IF_FAIL (priv->display_list != NULL); data.display_list = priv->display_list; data.x1 = x1; @@ -151,6 +174,7 @@ cogl_pango_renderer_draw_glyph (CoglPangoRenderer *priv, &data); } +static void cogl_pango_renderer_dispose (GObject *object); static void cogl_pango_renderer_finalize (GObject *object); static void cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer, PangoFont *font, @@ -177,15 +201,46 @@ G_DEFINE_TYPE (CoglPangoRenderer, cogl_pango_renderer, PANGO_TYPE_RENDERER); static void cogl_pango_renderer_init (CoglPangoRenderer *priv) { - priv->no_mipmap_caches.pipeline_cache = - _cogl_pango_pipeline_cache_new (FALSE); - priv->mipmap_caches.pipeline_cache = - _cogl_pango_pipeline_cache_new (TRUE); +} - priv->no_mipmap_caches.glyph_cache = cogl_pango_glyph_cache_new (FALSE); - priv->mipmap_caches.glyph_cache = cogl_pango_glyph_cache_new (TRUE); +static void +_cogl_pango_renderer_constructed (GObject *gobject) +{ + CoglPangoRenderer *renderer = COGL_PANGO_RENDERER (gobject); + CoglContext *ctx = renderer->ctx; - _cogl_pango_renderer_set_use_mipmapping (priv, FALSE); + renderer->no_mipmap_caches.pipeline_cache = + _cogl_pango_pipeline_cache_new (ctx, FALSE); + renderer->mipmap_caches.pipeline_cache = + _cogl_pango_pipeline_cache_new (ctx, TRUE); + + renderer->no_mipmap_caches.glyph_cache = cogl_pango_glyph_cache_new (FALSE); + renderer->mipmap_caches.glyph_cache = cogl_pango_glyph_cache_new (TRUE); + + _cogl_pango_renderer_set_use_mipmapping (renderer, FALSE); + + if (G_OBJECT_CLASS (cogl_pango_renderer_parent_class)->constructed) + G_OBJECT_CLASS (cogl_pango_renderer_parent_class)->constructed (gobject); +} + +static void +cogl_pango_renderer_set_property (GObject *object, + unsigned int prop_id, + const GValue *value, + GParamSpec *pspec) +{ + CoglPangoRenderer *renderer = COGL_PANGO_RENDERER (object); + + switch (prop_id) + { + case PROP_COGL_CONTEXT: + renderer->ctx = g_value_get_pointer (value); + cogl_object_ref (renderer->ctx); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void @@ -193,14 +248,39 @@ cogl_pango_renderer_class_init (CoglPangoRendererClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass); + GParamSpec *pspec; + object_class->set_property = cogl_pango_renderer_set_property; + object_class->constructed = _cogl_pango_renderer_constructed; + object_class->dispose = cogl_pango_renderer_dispose; object_class->finalize = cogl_pango_renderer_finalize; + pspec = g_param_spec_pointer ("context", + "Context", + "The Cogl Context", + G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS | + G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_property (object_class, PROP_COGL_CONTEXT, pspec); + renderer_class->draw_glyphs = cogl_pango_renderer_draw_glyphs; renderer_class->draw_rectangle = cogl_pango_renderer_draw_rectangle; renderer_class->draw_trapezoid = cogl_pango_renderer_draw_trapezoid; } +static void +cogl_pango_renderer_dispose (GObject *object) +{ + CoglPangoRenderer *priv = COGL_PANGO_RENDERER (object); + + if (priv->ctx) + { + cogl_object_unref (priv->ctx); + priv->ctx = NULL; + } +} + static void cogl_pango_renderer_finalize (GObject *object) { @@ -218,22 +298,24 @@ cogl_pango_renderer_finalize (GObject *object) static CoglPangoRenderer * cogl_pango_get_renderer_from_context (PangoContext *context) { - PangoFontMap *font_map; - PangoRenderer *renderer; - CoglPangoFontMap *font_map_priv; + PangoFontMap *font_map; + CoglPangoFontMap *cogl_font_map; + PangoRenderer *renderer; font_map = pango_context_get_font_map (context); g_return_val_if_fail (COGL_PANGO_IS_FONT_MAP (font_map), NULL); - font_map_priv = COGL_PANGO_FONT_MAP (font_map); - renderer = cogl_pango_font_map_get_renderer (font_map_priv); + cogl_font_map = COGL_PANGO_FONT_MAP (font_map); + + renderer = _cogl_pango_font_map_get_renderer (cogl_font_map); + g_return_val_if_fail (COGL_PANGO_IS_RENDERER (renderer), NULL); return COGL_PANGO_RENDERER (renderer); } static GQuark -cogl_pango_render_get_qdata_key (void) +cogl_pango_layout_get_qdata_key (void) { static GQuark key = 0; @@ -244,7 +326,7 @@ cogl_pango_render_get_qdata_key (void) } static void -cogl_pango_render_qdata_forget_display_list (CoglPangoRendererQdata *qdata) +cogl_pango_layout_qdata_forget_display_list (CoglPangoLayoutQdata *qdata) { if (qdata->display_list) { @@ -254,7 +336,7 @@ cogl_pango_render_qdata_forget_display_list (CoglPangoRendererQdata *qdata) _cogl_pango_glyph_cache_remove_reorganize_callback (caches->glyph_cache, - (GHookFunc) cogl_pango_render_qdata_forget_display_list, + (GHookFunc) cogl_pango_layout_qdata_forget_display_list, qdata); _cogl_pango_display_list_free (qdata->display_list); @@ -264,36 +346,24 @@ cogl_pango_render_qdata_forget_display_list (CoglPangoRendererQdata *qdata) } static void -cogl_pango_render_qdata_destroy (CoglPangoRendererQdata *qdata) +cogl_pango_render_qdata_destroy (CoglPangoLayoutQdata *qdata) { - cogl_pango_render_qdata_forget_display_list (qdata); + cogl_pango_layout_qdata_forget_display_list (qdata); if (qdata->first_line) pango_layout_line_unref (qdata->first_line); - g_slice_free (CoglPangoRendererQdata, qdata); + g_slice_free (CoglPangoLayoutQdata, qdata); } -/** - * cogl_pango_render_layout_subpixel: - * @layout: a #PangoLayout - * @x: FIXME - * @y: FIXME - * @color: color to use when rendering the layout - * @flags: flags to pass to the renderer - * - * FIXME - * - * Since: 1.0 - */ void -cogl_pango_render_layout_subpixel (PangoLayout *layout, - int x, - int y, - const CoglColor *color, - int flags) +cogl_pango_show_layout (CoglFramebuffer *fb, + PangoLayout *layout, + float x, + float y, + const CoglColor *color) { - PangoContext *context; - CoglPangoRenderer *priv; - CoglPangoRendererQdata *qdata; + PangoContext *context; + CoglPangoRenderer *priv; + CoglPangoLayoutQdata *qdata; context = pango_layout_get_context (layout); priv = cogl_pango_get_renderer_from_context (context); @@ -301,14 +371,14 @@ cogl_pango_render_layout_subpixel (PangoLayout *layout, return; qdata = g_object_get_qdata (G_OBJECT (layout), - cogl_pango_render_get_qdata_key ()); + cogl_pango_layout_get_qdata_key ()); if (qdata == NULL) { - qdata = g_slice_new0 (CoglPangoRendererQdata); + qdata = g_slice_new0 (CoglPangoLayoutQdata); qdata->renderer = priv; g_object_set_qdata_full (G_OBJECT (layout), - cogl_pango_render_get_qdata_key (), + cogl_pango_layout_get_qdata_key (), qdata, (GDestroyNotify) cogl_pango_render_qdata_destroy); @@ -321,7 +391,7 @@ cogl_pango_render_layout_subpixel (PangoLayout *layout, ((qdata->first_line && qdata->first_line->layout != layout) || qdata->mipmapping_used != priv->use_mipmapping)) - cogl_pango_render_qdata_forget_display_list (qdata); + cogl_pango_layout_qdata_forget_display_list (qdata); if (qdata->display_list == NULL) { @@ -338,7 +408,7 @@ cogl_pango_render_layout_subpixel (PangoLayout *layout, we can rebuild the display list */ _cogl_pango_glyph_cache_add_reorganize_callback (caches->glyph_cache, - (GHookFunc) cogl_pango_render_qdata_forget_display_list, + (GHookFunc) cogl_pango_layout_qdata_forget_display_list, qdata); priv->display_list = qdata->display_list; @@ -348,11 +418,14 @@ cogl_pango_render_layout_subpixel (PangoLayout *layout, qdata->mipmapping_used = priv->use_mipmapping; } - cogl_push_matrix (); - cogl_translate (x / (gfloat) PANGO_SCALE, y / (gfloat) PANGO_SCALE, 0); - _cogl_pango_display_list_render (qdata->display_list, + cogl_framebuffer_push_matrix (fb); + cogl_framebuffer_translate (fb, x, y, 0); + + _cogl_pango_display_list_render (fb, + qdata->display_list, color); - cogl_pop_matrix (); + + cogl_framebuffer_pop_matrix (fb); /* Keep a reference to the first line of the layout so we can detect changes */ @@ -368,24 +441,26 @@ cogl_pango_render_layout_subpixel (PangoLayout *layout, } } -/** - * cogl_pango_render_layout: - * @layout: a #PangoLayout - * @x: X coordinate to render the layout at - * @y: Y coordinate to render the layout at - * @color: color to use when rendering the layout - * @flags: flags to pass to the renderer - * - * Renders @layout. - * - * Since: 1.0 - */ void -cogl_pango_render_layout (PangoLayout *layout, - int x, - int y, +cogl_pango_render_layout_subpixel (PangoLayout *layout, + int x, + int y, + const CoglColor *color, + int flags) +{ + cogl_pango_show_layout (cogl_get_draw_framebuffer (), + layout, + x / (float) PANGO_SCALE, + y / (float) PANGO_SCALE, + color); +} + +void +cogl_pango_render_layout (PangoLayout *layout, + int x, + int y, const CoglColor *color, - int flags) + int flags) { cogl_pango_render_layout_subpixel (layout, x * PANGO_SCALE, @@ -394,26 +469,18 @@ cogl_pango_render_layout (PangoLayout *layout, flags); } -/** - * cogl_pango_render_layout_line: - * @line: a #PangoLayoutLine - * @x: X coordinate to render the line at - * @y: Y coordinate to render the line at - * @color: color to use when rendering the line - * - * Renders @line at the given coordinates using the given color. - * - * Since: 1.0 - */ void -cogl_pango_render_layout_line (PangoLayoutLine *line, - int x, - int y, - const CoglColor *color) +cogl_pango_show_layout_line (CoglFramebuffer *fb, + PangoLayoutLine *line, + float x, + float y, + const CoglColor *color) { PangoContext *context; CoglPangoRenderer *priv; CoglPangoRendererCaches *caches; + int pango_x = x * PANGO_SCALE; + int pango_y = y * PANGO_SCALE; context = pango_layout_get_context (line->layout); priv = cogl_pango_get_renderer_from_context (context); @@ -428,15 +495,30 @@ cogl_pango_render_layout_line (PangoLayoutLine *line, _cogl_pango_ensure_glyph_cache_for_layout_line (line); - pango_renderer_draw_layout_line (PANGO_RENDERER (priv), line, x, y); + pango_renderer_draw_layout_line (PANGO_RENDERER (priv), line, + pango_x, pango_y); - _cogl_pango_display_list_render (priv->display_list, + _cogl_pango_display_list_render (fb, + priv->display_list, color); _cogl_pango_display_list_free (priv->display_list); priv->display_list = NULL; } +void +cogl_pango_render_layout_line (PangoLayoutLine *line, + int x, + int y, + const CoglColor *color) +{ + cogl_pango_show_layout_line (cogl_get_draw_framebuffer (), + line, + x / (float) PANGO_SCALE, + y / (float) PANGO_SCALE, + color); +} + void _cogl_pango_renderer_clear_glyph_cache (CoglPangoRenderer *renderer) { @@ -489,7 +571,7 @@ cogl_pango_renderer_set_dirty_glyph (PangoFont *font, /* Glyphs that don't take up any space will end up without a texture. These should never become dirty so they shouldn't end up here */ - g_return_if_fail (value->texture != NULL); + _COGL_RETURN_IF_FAIL (value->texture != NULL); if (cogl_texture_get_format (value->texture) == COGL_PIXEL_FORMAT_A_8) { @@ -617,7 +699,7 @@ cogl_pango_ensure_glyph_cache_for_layout (PangoLayout *layout) context = pango_layout_get_context (layout); priv = cogl_pango_get_renderer_from_context (context); - g_return_if_fail (PANGO_IS_LAYOUT (layout)); + _COGL_RETURN_IF_FAIL (PANGO_IS_LAYOUT (layout)); if ((iter = pango_layout_get_iter (layout)) == NULL) return; @@ -671,7 +753,7 @@ cogl_pango_renderer_draw_box (PangoRenderer *renderer, { CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); - g_return_if_fail (priv->display_list != NULL); + _COGL_RETURN_IF_FAIL (priv->display_list != NULL); _cogl_pango_display_list_add_rectangle (priv->display_list, x, @@ -715,7 +797,7 @@ 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_RETURN_IF_FAIL (priv->display_list != NULL); cogl_pango_renderer_set_color_for_part (renderer, part); @@ -743,7 +825,7 @@ cogl_pango_renderer_draw_trapezoid (PangoRenderer *renderer, CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); float points[8]; - g_return_if_fail (priv->display_list != NULL); + _COGL_RETURN_IF_FAIL (priv->display_list != NULL); points[0] = (x11); points[1] = (y1); diff --git a/cogl-pango/cogl-pango.h b/cogl-pango/cogl-pango.h index 4b30897c5..227a0c41c 100644 --- a/cogl-pango/cogl-pango.h +++ b/cogl-pango/cogl-pango.h @@ -1,11 +1,10 @@ /* - * Clutter. + * Cogl * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum + * An object oriented GL/GLES Abstraction/Utility Layer * * Copyright (C) 2008 OpenedHand + * Copyright (C) 2012 Intel Corporation. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,11 +17,17 @@ * 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 . + * License along with this library. If not, see + * . + * + * Authors: + * Neil Roberts + * Robert Bragg + * Matthew Allum */ -#ifndef __PANGO_CLUTTER_H__ -#define __PANGO_CLUTTER_H__ +#ifndef __COGL_PANGO_H__ +#define __COGL_PANGO_H__ #include #include @@ -41,19 +46,159 @@ COGL_BEGIN_DECLS typedef PangoCairoFontMap CoglPangoFontMap; -PangoFontMap * cogl_pango_font_map_new (void); -PangoContext * cogl_pango_font_map_create_context (CoglPangoFontMap *fm); -void cogl_pango_font_map_set_resolution (CoglPangoFontMap *font_map, - double dpi); -void cogl_pango_font_map_clear_glyph_cache (CoglPangoFontMap *fm); -void cogl_pango_ensure_glyph_cache_for_layout (PangoLayout *layout); -void cogl_pango_font_map_set_use_mipmapping (CoglPangoFontMap *fm, - CoglBool value); -CoglBool cogl_pango_font_map_get_use_mipmapping (CoglPangoFontMap *fm); -PangoRenderer *cogl_pango_font_map_get_renderer (CoglPangoFontMap *fm); +/** + * cogl_pango_font_map_new: + * @context: A #CoglContext + * + * Creates a new font map. + * + * Return value: (transfer full): the newly created #PangoFontMap + * + * Since: 2.0 + */ +PangoFontMap * +cogl_pango_font_map_new (void); + +/** + * cogl_pango_font_map_create_context: + * @font_map: a #CoglPangoFontMap + * + * Create a #PangoContext for the given @font_map. + * + * Returns: the newly created context: free with g_object_unref(). + */ +PangoContext * +cogl_pango_font_map_create_context (CoglPangoFontMap *font_map); + +/** + * cogl_pango_font_map_set_resolution: + * @font_map: a #CoglPangoFontMap + * @dpi: The resolution in "dots per inch". (Physical inches aren't + * actually involved; the terminology is conventional.) + * + * Sets the resolution for the @font_map. This is a scale factor + * between points specified in a #PangoFontDescription and Cogl units. + * The default value is %96, meaning that a 10 point font will be 13 + * units high. (10 * 96. / 72. = 13.3). + * + * Since: 2.0 + */ +void +cogl_pango_font_map_set_resolution (CoglPangoFontMap *font_map, + double dpi); + +/** + * cogl_pango_font_map_clear_glyph_cache: + * @font_map: a #CoglPangoFontMap + * + * Clears the glyph cache for @font_map. + * + * Since: 1.0 + */ +void +cogl_pango_font_map_clear_glyph_cache (CoglPangoFontMap *font_map); + +/** + * cogl_pango_ensure_glyph_cache_for_layout: + * @layout: A #PangoLayout + * + * This updates any internal glyph cache textures as necessary to be + * able to render the given @layout. + * + * This api should be used to avoid mid-scene modifications of + * glyph-cache textures which can lead to undefined rendering results. + * + * Since: 1.0 + */ +void +cogl_pango_ensure_glyph_cache_for_layout (PangoLayout *layout); + +/** + * cogl_pango_font_map_set_use_mipmapping: + * @font_map: a #CoglPangoFontMap + * @value: %TRUE to enable the use of mipmapping + * + * Sets whether the renderer for the passed font map should use + * mipmapping when rendering a #PangoLayout. + * + * Since: 1.0 + */ +void +cogl_pango_font_map_set_use_mipmapping (CoglPangoFontMap *font_map, + CoglBool value); + +/** + * cogl_pango_font_map_get_use_mipmapping: + * @font_map: a #CoglPangoFontMap + * + * Retrieves whether the #CoglPangoRenderer used by @font_map will use + * mipmapping when rendering the glyphs. + * + * Return value: %TRUE if mipmapping is used, %FALSE otherwise. + * + * Since: 1.0 + */ +CoglBool +cogl_pango_font_map_get_use_mipmapping (CoglPangoFontMap *font_map); + +/** + * cogl_pango_font_map_get_renderer: + * @font_map: a #CoglPangoFontMap + * + * Retrieves the #CoglPangoRenderer for the passed @font_map. + * + * Return value: (transfer none): a #PangoRenderer + * + * Since: 1.0 + */ +PangoRenderer * +cogl_pango_font_map_get_renderer (CoglPangoFontMap *font_map); + +/** + * cogl_pango_show_layout: + * @framebuffer: A #CoglFramebuffer to draw too. + * @layout: a #PangoLayout + * @x: X coordinate to render the layout at + * @y: Y coordinate to render the layout at + * @color: color to use when rendering the layout + * + * Draws a solidly coloured @layout on the given @framebuffer at (@x, + * @y) within the @framebuffer's current model-view coordinate + * space. + * + * Since: 2.0 + */ +void +cogl_pango_show_layout (CoglFramebuffer *framebuffer, + PangoLayout *layout, + float x, + float y, + const CoglColor *color); + +/** + * cogl_pango_render_layout_line: + * @framebuffer: A #CoglFramebuffer to draw too. + * @line: a #PangoLayoutLine + * @x: X coordinate to render the line at + * @y: Y coordinate to render the line at + * @color: color to use when rendering the line + * + * Draws a solidly coloured @line on the given @framebuffer at (@x, + * @y) within the @framebuffer's current model-view coordinate + * space. + * + * Since: 2.0 + */ +void +cogl_pango_show_layout_line (CoglFramebuffer *framebuffer, + PangoLayoutLine *line, + float x, + float y, + const CoglColor *color); + #define COGL_PANGO_TYPE_RENDERER (cogl_pango_renderer_get_type ()) -#define COGL_PANGO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_PANGO_TYPE_RENDERER, CoglPangoRenderer)) +#define COGL_PANGO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_PANGO_TYPE_RENDERER, CoglPangoRenderer)) #define COGL_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_PANGO_TYPE_RENDERER, CoglPangoRendererClass)) #define COGL_PANGO_IS_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_PANGO_TYPE_RENDERER)) #define COGL_PANGO_IS_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_PANGO_TYPE_RENDERER)) @@ -65,21 +210,37 @@ typedef struct _CoglPangoRendererClass CoglPangoRendererClass; GType cogl_pango_renderer_get_type (void) G_GNUC_CONST; -void cogl_pango_render_layout_subpixel (PangoLayout *layout, - int x, - int y, - const CoglColor *color, - int flags); -void cogl_pango_render_layout (PangoLayout *layout, - int x, - int y, - const CoglColor *color, - int flags); -void cogl_pango_render_layout_line (PangoLayoutLine *line, - int x, - int y, - const CoglColor *color); +void +cogl_pango_render_layout_subpixel (PangoLayout *layout, + int x, + int y, + const CoglColor *color, + int flags); + +void +cogl_pango_render_layout (PangoLayout *layout, + int x, + int y, + const CoglColor *color, + int flags); + +/** + * cogl_pango_render_layout_line: + * @line: a #PangoLayoutLine + * @x: X coordinate to render the line at + * @y: Y coordinate to render the line at + * @color: color to use when rendering the line + * + * Renders @line at the given coordinates using the given color. + * + * Since: 1.0 + */ +void +cogl_pango_render_layout_line (PangoLayoutLine *line, + int x, + int y, + const CoglColor *color); COGL_END_DECLS -#endif /* __PANGO_CLUTTER_H__ */ +#endif /* __COGL_PANGO_H__ */