When drawing underlines, join up adjacent runs where possible, so we don't

Wed Jun  4 19:42:17 2003  Owen Taylor  <otaylor@redhat.com>

        * gdk/gdkpango.c (gdk_draw_layout_line_with_colors):
        When drawing underlines, join up adjacent runs
        where possible, so we don't get changes in
        shaper/font/etc. breaking underlines. (#103662,
        Kang Jeong-Hee)
This commit is contained in:
Owen Taylor 2003-06-04 23:47:23 +00:00 committed by Owen Taylor
parent 0f635335e2
commit f9a478644e
6 changed files with 152 additions and 34 deletions

View File

@ -1,3 +1,11 @@
Wed Jun 4 19:42:17 2003 Owen Taylor <otaylor@redhat.com>
* gdk/gdkpango.c (gdk_draw_layout_line_with_colors):
When drawing underlines, join up adjacent runs
where possible, so we don't get changes in
shaper/font/etc. breaking underlines. (#103662,
Kang Jeong-Hee)
Wed Jun 4 19:22:58 2003 Jonathan Blandford <jrb@redhat.com>
* gtk/gtktreemodelsort.c (gtk_tree_model_sort_level_find_insert):

View File

@ -1,3 +1,11 @@
Wed Jun 4 19:42:17 2003 Owen Taylor <otaylor@redhat.com>
* gdk/gdkpango.c (gdk_draw_layout_line_with_colors):
When drawing underlines, join up adjacent runs
where possible, so we don't get changes in
shaper/font/etc. breaking underlines. (#103662,
Kang Jeong-Hee)
Wed Jun 4 19:22:58 2003 Jonathan Blandford <jrb@redhat.com>
* gtk/gtktreemodelsort.c (gtk_tree_model_sort_level_find_insert):

View File

@ -1,3 +1,11 @@
Wed Jun 4 19:42:17 2003 Owen Taylor <otaylor@redhat.com>
* gdk/gdkpango.c (gdk_draw_layout_line_with_colors):
When drawing underlines, join up adjacent runs
where possible, so we don't get changes in
shaper/font/etc. breaking underlines. (#103662,
Kang Jeong-Hee)
Wed Jun 4 19:22:58 2003 Jonathan Blandford <jrb@redhat.com>
* gtk/gtktreemodelsort.c (gtk_tree_model_sort_level_find_insert):

View File

@ -1,3 +1,11 @@
Wed Jun 4 19:42:17 2003 Owen Taylor <otaylor@redhat.com>
* gdk/gdkpango.c (gdk_draw_layout_line_with_colors):
When drawing underlines, join up adjacent runs
where possible, so we don't get changes in
shaper/font/etc. breaking underlines. (#103662,
Kang Jeong-Hee)
Wed Jun 4 19:22:58 2003 Jonathan Blandford <jrb@redhat.com>
* gtk/gtktreemodelsort.c (gtk_tree_model_sort_level_find_insert):

View File

@ -1,3 +1,11 @@
Wed Jun 4 19:42:17 2003 Owen Taylor <otaylor@redhat.com>
* gdk/gdkpango.c (gdk_draw_layout_line_with_colors):
When drawing underlines, join up adjacent runs
where possible, so we don't get changes in
shaper/font/etc. breaking underlines. (#103662,
Kang Jeong-Hee)
Wed Jun 4 19:22:58 2003 Jonathan Blandford <jrb@redhat.com>
* gtk/gtktreemodelsort.c (gtk_tree_model_sort_level_find_insert):

View File

@ -163,6 +163,37 @@ gdk_pango_context_set_colormap (PangoContext *context,
}
}
static void
draw_underline (GdkDrawable *drawable,
GdkGC *gc,
PangoUnderline uline,
int baseline_y,
int low_y,
int start_x,
int end_x)
{
switch (uline)
{
case PANGO_UNDERLINE_NONE:
break;
case PANGO_UNDERLINE_DOUBLE:
gdk_draw_line (drawable, gc,
start_x, baseline_y + 3,
end_x, baseline_y + 3);
/* Fall through */
case PANGO_UNDERLINE_SINGLE:
gdk_draw_line (drawable, gc,
start_x, baseline_y + 1,
end_x, baseline_y + 1);
break;
case PANGO_UNDERLINE_LOW:
gdk_draw_line (drawable, gc,
start_x, low_y + 1,
end_x, low_y + 1);
break;
}
}
/**
* gdk_draw_layout_line_with_colors:
* @drawable: the drawable on which to draw the line
@ -195,6 +226,15 @@ gdk_draw_layout_line_with_colors (GdkDrawable *drawable,
gint rise = 0;
gboolean embossed;
GdkBitmap *stipple;
PangoUnderline last_uline = PANGO_UNDERLINE_NONE;
gint uline_start_x = 0;
gint uline_end_x = 0;
gint uline_end_x_extended = 0;
gint last_risen_y = 0;
gint low_y = G_MININT;
GdkGC *last_fg_gc = NULL;
gboolean last_fg_set = FALSE;
PangoColor last_fg_color;
g_return_if_fail (GDK_IS_DRAWABLE (drawable));
g_return_if_fail (GDK_IS_GC (gc));
@ -206,7 +246,7 @@ gdk_draw_layout_line_with_colors (GdkDrawable *drawable,
while (tmp_list)
{
PangoUnderline uline = PANGO_UNDERLINE_NONE;
PangoUnderline this_uline = PANGO_UNDERLINE_NONE;
PangoLayoutRun *run = tmp_list->data;
PangoColor fg_color, bg_color;
gboolean strike, fg_set, bg_set, shape_set;
@ -215,7 +255,7 @@ gdk_draw_layout_line_with_colors (GdkDrawable *drawable,
tmp_list = tmp_list->next;
gdk_pango_get_item_properties (run->item, &uline,
gdk_pango_get_item_properties (run->item, &this_uline,
&strike,
&rise,
&fg_color, &fg_set,
@ -231,7 +271,7 @@ gdk_draw_layout_line_with_colors (GdkDrawable *drawable,
if (!shape_set)
{
if (uline == PANGO_UNDERLINE_NONE)
if (this_uline == PANGO_UNDERLINE_NONE)
pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
NULL, &logical_rect);
else
@ -281,7 +321,7 @@ gdk_draw_layout_line_with_colors (GdkDrawable *drawable,
}
else
fg_gc = gc;
if (!shape_set)
{
gint gx, gy;
@ -304,36 +344,58 @@ gdk_draw_layout_line_with_colors (GdkDrawable *drawable,
gx, gy,
run->glyphs);
}
switch (uline)
if (this_uline != last_uline ||
risen_y != last_risen_y ||
fg_set != last_fg_set ||
(fg_set && (last_fg_color.red != fg_color.red ||
last_fg_color.green != fg_color.green ||
last_fg_color.blue != fg_color.blue)))
{
case PANGO_UNDERLINE_NONE:
break;
case PANGO_UNDERLINE_DOUBLE:
gdk_draw_line (drawable, fg_gc,
x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
risen_y + 3,
x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
risen_y + 3);
/* Fall through */
case PANGO_UNDERLINE_SINGLE:
gdk_draw_line (drawable, fg_gc,
x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
risen_y + 1,
x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
risen_y + 1);
break;
case PANGO_UNDERLINE_LOW:
gdk_draw_line (drawable, fg_gc,
x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
risen_y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 1,
x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
risen_y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 1);
break;
/* If only color changes, the underlines extend to the edge
* of the logical rectangle so they join up; otherwise they
* go 1 pixel beyond the ink rectangle. This doesn't work
* for low underlines (they will be at a different y anyways),
* so they follow the normal path.
*/
gboolean extend_uline = (this_uline == last_uline &&
this_uline != PANGO_UNDERLINE_LOW &&
risen_y == last_risen_y);
/* Starting a new underline run
*/
if (last_uline != PANGO_UNDERLINE_NONE)
{
draw_underline (drawable, last_fg_gc, last_uline,
last_risen_y, low_y,
uline_start_x,
extend_uline ? uline_end_x_extended : uline_end_x);
}
if (this_uline != PANGO_UNDERLINE_NONE)
{
if (extend_uline)
uline_start_x = x + x_off / PANGO_SCALE;
else
uline_start_x = x + (x_off + ink_rect.x) / PANGO_SCALE - 1;
low_y = G_MININT;
}
}
/* Update current underline segment information
*/
if (this_uline != PANGO_UNDERLINE_NONE)
{
uline_end_x = x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE;
uline_end_x_extended = x + (x_off + logical_rect.x + logical_rect.width) / PANGO_SCALE - 1;
}
if (this_uline == PANGO_UNDERLINE_LOW)
low_y = MAX (low_y, risen_y + (ink_rect.y + ink_rect.height) / PANGO_SCALE);
if (strike)
{
{
int centerline = logical_rect.y + logical_rect.height / 2;
gdk_draw_line (drawable, fg_gc,
@ -341,13 +403,29 @@ gdk_draw_layout_line_with_colors (GdkDrawable *drawable,
risen_y + centerline / PANGO_SCALE,
x + (x_off + logical_rect.x + logical_rect.width) / PANGO_SCALE + 1,
risen_y + centerline / PANGO_SCALE);
}
if (fg_gc != gc)
gdk_pango_free_gc (context, fg_gc);
}
if (last_fg_gc != gc && last_fg_gc)
gdk_pango_free_gc (context, last_fg_gc);
last_risen_y = risen_y;
last_uline = this_uline;
last_fg_gc = fg_gc;
last_fg_set = fg_set;
if (fg_set)
last_fg_color = fg_color;
x_off += logical_rect.width;
}
/* Finish off any remaining underlines
*/
if (last_uline != PANGO_UNDERLINE_NONE)
draw_underline (drawable, last_fg_gc, last_uline, last_risen_y, low_y,
uline_start_x, uline_end_x);
if (last_fg_gc != gc && last_fg_gc)
gdk_pango_free_gc (context, last_fg_gc);
}
/**