Allow specifying the font for the em conversion

Currently, the conversion from em to units is done by using the
default font name inside the backend. For actors using their own
font/text layout we need a way to specify the font name along
with the quantity we wish to transform.
This commit is contained in:
Emmanuele Bassi 2009-05-07 14:16:01 +01:00
parent 8ec1c3e2fb
commit f2c25fd4f7
4 changed files with 115 additions and 39 deletions

View File

@ -103,55 +103,74 @@ clutter_backend_dispose (GObject *gobject)
G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject);
}
static inline void
update_units_per_em (ClutterBackend *backend)
static ClutterUnit
get_units_per_em (ClutterBackend *backend,
PangoFontDescription *font_desc)
{
ClutterBackendPrivate *priv = backend->priv;
const gchar *font_name;
ClutterUnit units_per_em = -1.0;
gboolean free_font_desc = FALSE;
gdouble dpi;
font_name = clutter_backend_get_font_name (backend);
dpi = clutter_backend_get_resolution (backend);
if (G_LIKELY (font_name != NULL && *font_name != '\0'))
if (font_desc == NULL)
{
PangoFontDescription *font_desc;
gdouble font_size = 0;
const gchar *font_name = clutter_backend_get_font_name (backend);
font_desc = pango_font_description_from_string (font_name);
if (G_LIKELY (font_desc != NULL))
if (G_LIKELY (font_name != NULL && *font_name != '\0'))
{
gint pango_size;
gboolean is_absolute;
pango_size = pango_font_description_get_size (font_desc);
is_absolute =
pango_font_description_get_size_is_absolute (font_desc);
if (!is_absolute)
font_size = ((gdouble) font_size) / PANGO_SCALE;
pango_font_description_free (font_desc);
font_desc = pango_font_description_from_string (font_name);
free_font_desc = TRUE;
}
}
/* 10 points at 96 DPI is 12 pixels */
priv->units_per_em = 1.2f * font_size
* dpi
/ 96.0f;
if (font_desc != NULL)
{
gdouble font_size = 0;
gint pango_size;
gboolean is_absolute;
pango_size = pango_font_description_get_size (font_desc);
is_absolute = pango_font_description_get_size_is_absolute (font_desc);
/* "absolute" means "device units" (usually, pixels); otherwise,
* it means logical units (points)
*/
if (is_absolute)
font_size = (gdouble) pango_size / PANGO_SCALE;
else
font_size = (gdouble) pango_size / PANGO_SCALE
* dpi
/ 96.0f;
/* 10 points at 96 DPI is 13.3 pixels */
units_per_em = (1.2f * font_size)
* dpi
/ 96.0f;
}
else
priv->units_per_em = -1.0f;
units_per_em = -1.0f;
if (free_font_desc)
pango_font_description_free (font_desc);
return units_per_em;
}
static void
clutter_backend_real_resolution_changed (ClutterBackend *backend)
{
update_units_per_em (backend);
backend->priv->units_per_em = get_units_per_em (backend, NULL);
CLUTTER_NOTE (BACKEND, "Units per em: %.2f", backend->priv->units_per_em);
}
static void
clutter_backend_real_font_changed (ClutterBackend *backend)
{
update_units_per_em (backend);
backend->priv->units_per_em = get_units_per_em (backend, NULL);
CLUTTER_NOTE (BACKEND, "Units per em: %.2f", backend->priv->units_per_em);
}
static void
@ -361,7 +380,8 @@ _clutter_backend_init_events (ClutterBackend *backend)
}
gfloat
_clutter_backend_get_units_per_em (ClutterBackend *backend)
_clutter_backend_get_units_per_em (ClutterBackend *backend,
PangoFontDescription *font_desc)
{
ClutterBackendPrivate *priv;
@ -369,8 +389,12 @@ _clutter_backend_get_units_per_em (ClutterBackend *backend)
priv = backend->priv;
if (G_UNLIKELY (priv->units_per_em < 0))
update_units_per_em (backend);
/* recompute for the font description, but do not cache the result */
if (font_desc != NULL)
return get_units_per_em (backend, font_desc);
if (priv->units_per_em < 0)
priv->units_per_em = get_units_per_em (backend, NULL);
return priv->units_per_em;
}
@ -603,6 +627,8 @@ clutter_backend_get_font_options (ClutterBackend *backend)
cairo_font_options_set_antialias (priv->font_options,
CAIRO_ANTIALIAS_DEFAULT);
g_signal_emit (backend, backend_signals[FONT_CHANGED], 0);
return priv->font_options;
}
@ -662,7 +688,12 @@ clutter_backend_get_font_name (ClutterBackend *backend)
if (G_LIKELY (priv->font_name))
return priv->font_name;
/* if we have never been called then we need to set the
* default font and update everything that relies on the
* ::font-changed signal
*/
priv->font_name = g_strdup (DEFAULT_FONT_NAME);
g_signal_emit (backend, backend_signals[FONT_CHANGED], 0);
return priv->font_name;
}

View File

@ -193,7 +193,8 @@ void _clutter_backend_init_events (ClutterBackend *backend);
ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend);
gfloat _clutter_backend_get_units_per_em (ClutterBackend *backend);
gfloat _clutter_backend_get_units_per_em (ClutterBackend *backend,
PangoFontDescription *font_desc);
void _clutter_feature_init (void);

View File

@ -169,11 +169,52 @@ clutter_units_pt (gdouble pt)
ClutterUnit
clutter_units_em (gdouble em)
{
ClutterBackend *backend;
ClutterBackend *backend = clutter_get_default_backend ();
backend = clutter_get_default_backend ();
return em * _clutter_backend_get_units_per_em (backend, NULL);
}
return em * _clutter_backend_get_units_per_em (backend);
/**
* clutter_units_em_for_font:
* @font_name: the font name and size
* @em: em to convert
*
* Converts a value in em to #ClutterUnit<!-- -->s at the
* current DPI for the given font name.
*
* The @font_name string must be in a format that
* pango_font_description_from_string() can parse, like
* for clutter_text_set_font_name() or clutter_backend_set_font_name().
*
* Return value: the value in units
*
* Since: 1.0
*/
ClutterUnit
clutter_units_em_for_font (const gchar *font_name,
gdouble em)
{
ClutterBackend *backend = clutter_get_default_backend ();
if (font_name == NULL || *font_name == '\0')
return em * _clutter_backend_get_units_per_em (backend, NULL);
else
{
PangoFontDescription *font_desc;
gfloat res;
font_desc = pango_font_description_from_string (font_name);
if (font_desc == NULL)
res = -1.0;
else
{
res = em * _clutter_backend_get_units_per_em (backend, font_desc);
pango_font_description_free (font_desc);
}
return res;
}
}
/**

View File

@ -32,7 +32,8 @@
#define __CLUTTER_UNITS_H__
#include <glib-object.h>
#include <clutter/clutter-fixed.h>
#include <cogl/cogl.h>
G_BEGIN_DECLS
@ -192,10 +193,12 @@ typedef float ClutterUnit;
*/
#define CLUTTER_UNITS_FROM_EM(x) (clutter_units_em (x))
ClutterUnit clutter_units_mm (gdouble mm);
ClutterUnit clutter_units_pt (gdouble pt);
ClutterUnit clutter_units_em (gdouble em);
ClutterUnit clutter_units_pixels (gint px);
ClutterUnit clutter_units_mm (gdouble mm);
ClutterUnit clutter_units_pt (gdouble pt);
ClutterUnit clutter_units_em (gdouble em);
ClutterUnit clutter_units_em_for_font (const gchar *font_name,
gdouble em);
ClutterUnit clutter_units_pixels (gint px);
gint clutter_units_to_pixels (ClutterUnit units);