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 <neil@linux.intel.com>

(cherry picked from commit bba2defe8c08a498b2dcb84bcf5b5a33f16eed27)

Note: API changes were reverting in cherry-picking this patch
This commit is contained in:
Robert Bragg 2012-05-10 12:16:03 +01:00
parent cd7b15b7df
commit 579db9083d
8 changed files with 552 additions and 299 deletions

View File

@ -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 ();
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -1,11 +1,10 @@
/*
* Clutter.
* Cogl
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
* 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 <http://www.gnu.org/licenses/>.
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
*
* Authors:
* Neil Roberts <neil@linux.intel.com>
* Robert Bragg <robert@linux.intel.com>
* Matthew Allum <mallum@openedhand.com>
*/
#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

View File

@ -1,11 +1,10 @@
/*
* Clutter.
* Cogl
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
* 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 <http://www.gnu.org/licenses/>.
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
*
* Authors:
* Neil Roberts <neil@linux.intel.com>
* Robert Bragg <robert@linux.intel.com>
* Matthew Allum <mallum@openedhand.com>
*/
#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);

View File

@ -1,11 +1,10 @@
/*
* Clutter.
* Cogl
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
* 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 <http://www.gnu.org/licenses/>.
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
* Authors:
* Neil Roberts <neil@linux.intel.com>
* Robert Bragg <robert@linux.intel.com>
* Matthew Allum <mallum@openedhand.com>
*/
#ifndef __PANGO_CLUTTER_H__
#define __PANGO_CLUTTER_H__
#ifndef __COGL_PANGO_H__
#define __COGL_PANGO_H__
#include <glib-object.h>
#include <pango/pango.h>
@ -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__ */