mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 11:32:04 +00:00
Bug 993 - Underline colors are sometimes wrong
* clutter/pango/pangoclutter-render.c: Fixed so that instead of trying to set the color in prepare_run it uses draw_glyphs to draw groups of glyphs and requests the color for each part from Pango.
This commit is contained in:
parent
d88d2a6061
commit
114148bab5
@ -1,3 +1,12 @@
|
|||||||
|
2008-06-27 Neil Roberts <neil@o-hand.com>
|
||||||
|
|
||||||
|
Bug 993 - Underline colors are sometimes wrong
|
||||||
|
|
||||||
|
* clutter/pango/pangoclutter-render.c: Fixed so that instead
|
||||||
|
of trying to set the color in prepare_run it uses draw_glyphs
|
||||||
|
to draw groups of glyphs and requests the color for each part
|
||||||
|
from Pango.
|
||||||
|
|
||||||
2008-06-26 Emmanuele Bassi <ebassi@openedhand.com>
|
2008-06-26 Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
|
||||||
* clutter/clutter-actor.c:
|
* clutter/clutter-actor.c:
|
||||||
|
@ -62,12 +62,14 @@ struct _PangoClutterRendererClass
|
|||||||
PangoRendererClass class_instance;
|
PangoRendererClass class_instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define CLUTTER_PANGO_UNIT_TO_FIXED(x) ((x) << (CFX_Q - 10))
|
||||||
|
|
||||||
static void pango_clutter_renderer_finalize (GObject *object);
|
static void pango_clutter_renderer_finalize (GObject *object);
|
||||||
static void pango_clutter_renderer_draw_glyph (PangoRenderer *renderer,
|
static void pango_clutter_renderer_draw_glyphs (PangoRenderer *renderer,
|
||||||
PangoFont *font,
|
PangoFont *font,
|
||||||
PangoGlyph glyph,
|
PangoGlyphString *glyphs,
|
||||||
double x,
|
int x,
|
||||||
double y);
|
int y);
|
||||||
static void pango_clutter_renderer_draw_rectangle (PangoRenderer *renderer,
|
static void pango_clutter_renderer_draw_rectangle (PangoRenderer *renderer,
|
||||||
PangoRenderPart part,
|
PangoRenderPart part,
|
||||||
int x,
|
int x,
|
||||||
@ -82,8 +84,6 @@ static void pango_clutter_renderer_draw_trapezoid (PangoRenderer *renderer,
|
|||||||
double y2,
|
double y2,
|
||||||
double x12,
|
double x12,
|
||||||
double x22);
|
double x22);
|
||||||
static void pango_clutter_renderer_prepare_run (PangoRenderer *renderer,
|
|
||||||
PangoLayoutRun *run);
|
|
||||||
|
|
||||||
static GObjectClass *parent_class = NULL;
|
static GObjectClass *parent_class = NULL;
|
||||||
|
|
||||||
@ -108,10 +108,9 @@ pango_clutter_renderer_class_init (PangoClutterRendererClass *klass)
|
|||||||
|
|
||||||
object_class->finalize = pango_clutter_renderer_finalize;
|
object_class->finalize = pango_clutter_renderer_finalize;
|
||||||
|
|
||||||
renderer_class->draw_glyph = pango_clutter_renderer_draw_glyph;
|
renderer_class->draw_glyphs = pango_clutter_renderer_draw_glyphs;
|
||||||
renderer_class->draw_rectangle = pango_clutter_renderer_draw_rectangle;
|
renderer_class->draw_rectangle = pango_clutter_renderer_draw_rectangle;
|
||||||
renderer_class->draw_trapezoid = pango_clutter_renderer_draw_trapezoid;
|
renderer_class->draw_trapezoid = pango_clutter_renderer_draw_trapezoid;
|
||||||
renderer_class->prepare_run = pango_clutter_renderer_prepare_run;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -315,6 +314,27 @@ pango_clutter_ensure_glyph_cache_for_layout (PangoLayout *layout)
|
|||||||
pango_layout_iter_free (iter);
|
pango_layout_iter_free (iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pango_clutter_renderer_set_color_for_part (PangoRenderer *renderer,
|
||||||
|
PangoRenderPart part)
|
||||||
|
{
|
||||||
|
PangoColor *pango_color = pango_renderer_get_color (renderer, part);
|
||||||
|
PangoClutterRenderer *priv = PANGO_CLUTTER_RENDERER (renderer);
|
||||||
|
ClutterColor clutter_color;
|
||||||
|
|
||||||
|
if (pango_color)
|
||||||
|
{
|
||||||
|
clutter_color.red = pango_color->red >> 8;
|
||||||
|
clutter_color.green = pango_color->green >> 8;
|
||||||
|
clutter_color.blue = pango_color->blue >> 8;
|
||||||
|
clutter_color.alpha = priv->color.alpha;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
clutter_color = priv->color;
|
||||||
|
|
||||||
|
cogl_color (&clutter_color);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pango_clutter_renderer_draw_box (int x, int y,
|
pango_clutter_renderer_draw_box (int x, int y,
|
||||||
int width, int height)
|
int width, int height)
|
||||||
@ -326,6 +346,30 @@ pango_clutter_renderer_draw_box (int x, int y,
|
|||||||
cogl_path_stroke ();
|
cogl_path_stroke ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pango_clutter_renderer_get_device_units (PangoRenderer *renderer,
|
||||||
|
int xin,
|
||||||
|
int yin,
|
||||||
|
ClutterFixed *xout,
|
||||||
|
ClutterFixed *yout)
|
||||||
|
{
|
||||||
|
const PangoMatrix *matrix;
|
||||||
|
|
||||||
|
if ((matrix = pango_renderer_get_matrix (renderer)))
|
||||||
|
{
|
||||||
|
/* Convert user-space coords to device coords */
|
||||||
|
*xout = CLUTTER_FLOAT_TO_FIXED ((xin * matrix->xx + yin * matrix->xy)
|
||||||
|
/ PANGO_SCALE + matrix->x0);
|
||||||
|
*yout = CLUTTER_FLOAT_TO_FIXED ((yin * matrix->yy + xin * matrix->yx)
|
||||||
|
/ PANGO_SCALE + matrix->y0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*xout = CLUTTER_PANGO_UNIT_TO_FIXED (xin);
|
||||||
|
*yout = CLUTTER_PANGO_UNIT_TO_FIXED (yin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pango_clutter_renderer_draw_rectangle (PangoRenderer *renderer,
|
pango_clutter_renderer_draw_rectangle (PangoRenderer *renderer,
|
||||||
PangoRenderPart part,
|
PangoRenderPart part,
|
||||||
@ -334,28 +378,16 @@ pango_clutter_renderer_draw_rectangle (PangoRenderer *renderer,
|
|||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
float x1, x2, y1, y2;
|
ClutterFixed x1, x2, y1, y2;
|
||||||
const PangoMatrix *matrix;
|
|
||||||
|
|
||||||
if ((matrix = pango_renderer_get_matrix (renderer)))
|
pango_clutter_renderer_set_color_for_part (renderer, part);
|
||||||
{
|
|
||||||
/* Convert user-space coords to device coords */
|
|
||||||
x1 = (x * matrix->xx + y * matrix->xy) / PANGO_SCALE + matrix->x0;
|
|
||||||
x2 = ((x + width) * matrix->xx + (y + height) * matrix->xy)
|
|
||||||
/ PANGO_SCALE + matrix->x0;
|
|
||||||
y1 = (y * matrix->yy + x * matrix->yx) / PANGO_SCALE + matrix->y0;
|
|
||||||
y2 = ((y + height) * matrix->yy + (x + width) * matrix->yx)
|
|
||||||
/ PANGO_SCALE + matrix->y0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
x1 = x / PANGO_SCALE;
|
|
||||||
x2 = (x + width) / PANGO_SCALE;
|
|
||||||
y1 = y / PANGO_SCALE;
|
|
||||||
y2 = (y + height) / PANGO_SCALE;
|
|
||||||
}
|
|
||||||
|
|
||||||
cogl_rectangle (x1, y1, x2 - x1, y2 - y1);
|
pango_clutter_renderer_get_device_units (renderer, x, y,
|
||||||
|
&x1, &y1);
|
||||||
|
pango_clutter_renderer_get_device_units (renderer, x + width, y + height,
|
||||||
|
&x2, &y2);
|
||||||
|
|
||||||
|
cogl_rectanglex (x1, y1, x2 - x1, y2 - y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -379,110 +411,84 @@ pango_clutter_renderer_draw_trapezoid (PangoRenderer *renderer,
|
|||||||
points[6] = CLUTTER_FLOAT_TO_FIXED (x21);
|
points[6] = CLUTTER_FLOAT_TO_FIXED (x21);
|
||||||
points[7] = points[1];
|
points[7] = points[1];
|
||||||
|
|
||||||
|
pango_clutter_renderer_set_color_for_part (renderer, part);
|
||||||
cogl_path_polygon (points, 4);
|
cogl_path_polygon (points, 4);
|
||||||
cogl_path_fill ();
|
cogl_path_fill ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pango_clutter_renderer_draw_glyph (PangoRenderer *renderer,
|
pango_clutter_renderer_draw_glyphs (PangoRenderer *renderer,
|
||||||
PangoFont *font,
|
PangoFont *font,
|
||||||
PangoGlyph glyph,
|
PangoGlyphString *glyphs,
|
||||||
double xd,
|
int xi,
|
||||||
double yd)
|
int yi)
|
||||||
{
|
{
|
||||||
PangoClutterGlyphCacheValue *cache_value;
|
PangoClutterGlyphCacheValue *cache_value;
|
||||||
ClutterFixed x = CLUTTER_FLOAT_TO_FIXED ((float) xd);
|
int i;
|
||||||
ClutterFixed y = CLUTTER_FLOAT_TO_FIXED ((float) yd);
|
|
||||||
|
|
||||||
if ((glyph & PANGO_GLYPH_UNKNOWN_FLAG))
|
pango_clutter_renderer_set_color_for_part (renderer,
|
||||||
|
PANGO_RENDER_PART_FOREGROUND);
|
||||||
|
|
||||||
|
for (i = 0; i < glyphs->num_glyphs; i++)
|
||||||
{
|
{
|
||||||
PangoFontMetrics *metrics;
|
PangoGlyphInfo *gi = glyphs->glyphs + i;
|
||||||
|
ClutterFixed x, y;
|
||||||
|
|
||||||
if (font == NULL
|
pango_clutter_renderer_get_device_units (renderer,
|
||||||
|| (metrics = pango_font_get_metrics (font, NULL)) == NULL)
|
xi + gi->geometry.x_offset,
|
||||||
pango_clutter_renderer_draw_box (CLUTTER_FIXED_TO_INT (x),
|
yi + gi->geometry.y_offset,
|
||||||
CLUTTER_FIXED_TO_INT (y),
|
&x, &y);
|
||||||
PANGO_UNKNOWN_GLYPH_WIDTH,
|
|
||||||
PANGO_UNKNOWN_GLYPH_HEIGHT);
|
if ((gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG))
|
||||||
|
{
|
||||||
|
PangoFontMetrics *metrics;
|
||||||
|
|
||||||
|
if (font == NULL
|
||||||
|
|| (metrics = pango_font_get_metrics (font, NULL)) == NULL)
|
||||||
|
pango_clutter_renderer_draw_box (CLUTTER_FIXED_TO_INT (x),
|
||||||
|
CLUTTER_FIXED_TO_INT (y),
|
||||||
|
PANGO_UNKNOWN_GLYPH_WIDTH,
|
||||||
|
PANGO_UNKNOWN_GLYPH_HEIGHT);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pango_clutter_renderer_draw_box (CLUTTER_FIXED_TO_INT (x),
|
||||||
|
CLUTTER_FIXED_TO_INT (y),
|
||||||
|
metrics->approximate_char_width
|
||||||
|
/ PANGO_SCALE,
|
||||||
|
metrics->ascent / PANGO_SCALE);
|
||||||
|
|
||||||
|
pango_font_metrics_unref (metrics);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pango_clutter_renderer_draw_box (CLUTTER_FIXED_TO_INT (x),
|
/* Get the texture containing the glyph. This will create
|
||||||
CLUTTER_FIXED_TO_INT (y),
|
the cache entry if there isn't already one */
|
||||||
metrics->approximate_char_width
|
cache_value
|
||||||
/ PANGO_SCALE,
|
= pango_clutter_renderer_get_cached_glyph (renderer, font,
|
||||||
metrics->ascent / PANGO_SCALE);
|
gi->glyph);
|
||||||
|
|
||||||
pango_font_metrics_unref (metrics);
|
if (cache_value == NULL)
|
||||||
|
pango_clutter_renderer_draw_box (CLUTTER_FIXED_TO_INT (x),
|
||||||
|
CLUTTER_FIXED_TO_INT (y),
|
||||||
|
PANGO_UNKNOWN_GLYPH_WIDTH,
|
||||||
|
PANGO_UNKNOWN_GLYPH_HEIGHT);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x += CLUTTER_INT_TO_FIXED (cache_value->draw_x);
|
||||||
|
y += CLUTTER_INT_TO_FIXED (cache_value->draw_y);
|
||||||
|
|
||||||
|
/* Render the glyph from the texture */
|
||||||
|
cogl_texture_rectangle (cache_value->texture, x, y,
|
||||||
|
x + CLUTTER_INT_TO_FIXED (cache_value
|
||||||
|
->draw_width),
|
||||||
|
y + CLUTTER_INT_TO_FIXED (cache_value
|
||||||
|
->draw_height),
|
||||||
|
cache_value->tx1, cache_value->ty1,
|
||||||
|
cache_value->tx2, cache_value->ty2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
xi += gi->geometry.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the texture containing the glyph. This will create the cache
|
|
||||||
entry if there isn't already one */
|
|
||||||
cache_value = pango_clutter_renderer_get_cached_glyph (renderer, font, glyph);
|
|
||||||
|
|
||||||
if (cache_value == NULL)
|
|
||||||
{
|
|
||||||
pango_clutter_renderer_draw_box (CLUTTER_FIXED_TO_INT (x),
|
|
||||||
CLUTTER_FIXED_TO_INT (y),
|
|
||||||
PANGO_UNKNOWN_GLYPH_WIDTH,
|
|
||||||
PANGO_UNKNOWN_GLYPH_HEIGHT);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
x += CLUTTER_INT_TO_FIXED (cache_value->draw_x);
|
|
||||||
y += CLUTTER_INT_TO_FIXED (cache_value->draw_y);
|
|
||||||
|
|
||||||
/* Render the glyph from the texture */
|
|
||||||
cogl_texture_rectangle (cache_value->texture, x, y,
|
|
||||||
x + CLUTTER_INT_TO_FIXED (cache_value->draw_width),
|
|
||||||
y + CLUTTER_INT_TO_FIXED (cache_value->draw_height),
|
|
||||||
cache_value->tx1, cache_value->ty1,
|
|
||||||
cache_value->tx2, cache_value->ty2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
pango_clutter_renderer_prepare_run (PangoRenderer *renderer,
|
|
||||||
PangoLayoutRun *run)
|
|
||||||
{
|
|
||||||
GSList *node;
|
|
||||||
PangoColor *fg = NULL;
|
|
||||||
ClutterColor col;
|
|
||||||
PangoClutterRenderer *priv = PANGO_CLUTTER_RENDERER (renderer);
|
|
||||||
|
|
||||||
for (node = run->item->analysis.extra_attrs; node; node = node->next)
|
|
||||||
{
|
|
||||||
PangoAttribute *attr = node->data;
|
|
||||||
|
|
||||||
switch (attr->klass->type)
|
|
||||||
{
|
|
||||||
case PANGO_ATTR_FOREGROUND:
|
|
||||||
fg = &((PangoAttrColor *) attr)->color;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fg)
|
|
||||||
{
|
|
||||||
col.red = (fg->red * 255) / 65535;
|
|
||||||
col.green = (fg->green * 255) / 65535;
|
|
||||||
col.blue = (fg->blue * 255) / 65535;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
col.red = priv->color.red;
|
|
||||||
col.green = priv->color.green;
|
|
||||||
col.blue = priv->color.blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
col.alpha = priv->color.alpha;
|
|
||||||
|
|
||||||
cogl_color (&col);
|
|
||||||
|
|
||||||
/* Chain up */
|
|
||||||
(* PANGO_RENDERER_CLASS (parent_class)->prepare_run) (renderer, run);
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user