summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@gnome.org>2006-09-11 16:22:33 +0000
committerBehdad Esfahbod <behdad@src.gnome.org>2006-09-11 16:22:33 +0000
commitb8fac1bfdd04bd0daa078c15e24116efca14f616 (patch)
treeb36b67abd7743e900e1c377295b8a24a295a719d /pango
parent0e89584a6683c8b9c929ccbac28e43838a3085f5 (diff)
downloadpango-b8fac1bfdd04bd0daa078c15e24116efca14f616.tar.gz
Bug 347146 – underline/overstrike spaces
2006-09-11 Behdad Esfahbod <behdad@gnome.org> Bug 347146 – underline/overstrike spaces * pango/pango-renderer.c (add_underline), (add_strikethrough), (pango_renderer_draw_layout_line): Use logical extents for x and width of underline/strikethrough, such that trailing spaces are correctly handled. * pango/pango-layout.c (pango_layout_run_get_extents): Use logical rect for underline/strikethrough, and reflect that in run ink extents. * pango/pango-layout.c (pango_layout_line_get_extents): Don't let runs with empty ink extents affect total ink extents.
Diffstat (limited to 'pango')
-rw-r--r--pango/pango-layout.c60
-rw-r--r--pango/pango-renderer.c30
2 files changed, 63 insertions, 27 deletions
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 456ca648..1389e000 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -47,6 +47,7 @@ struct _Extents
struct _ItemProperties
{
PangoUnderline uline;
+ gboolean strikethrough;
gint rise;
gint letter_spacing;
gboolean shape_set;
@@ -3960,6 +3961,9 @@ pango_layout_run_get_extents (PangoLayoutRun *run,
if (!run_logical && run->item->analysis.centered_baseline)
run_logical = &logical;
+ if (!run_logical && (properties.uline != PANGO_UNDERLINE_NONE || properties.strikethrough))
+ run_logical = &logical;
+
if (properties.shape_set)
imposed_extents (run->item->num_chars,
properties.shape_ink_rect,
@@ -3969,33 +3973,55 @@ pango_layout_run_get_extents (PangoLayoutRun *run,
pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
run_ink, run_logical);
- if (properties.uline != PANGO_UNDERLINE_NONE)
+ if (run_ink && (properties.uline != PANGO_UNDERLINE_NONE || properties.strikethrough))
{
PangoFontMetrics *metrics = pango_font_get_metrics (run->item->analysis.font,
run->item->analysis.language);
int underline_thickness = pango_font_metrics_get_underline_thickness (metrics);
int underline_position = pango_font_metrics_get_underline_position (metrics);
+ int strikethrough_thickness = pango_font_metrics_get_strikethrough_thickness (metrics);
+ int strikethrough_position = pango_font_metrics_get_strikethrough_position (metrics);
+
+ int new_pos;
+
+ /* the underline/strikethrough takes x,width of logical_rect. reflect
+ * that into ink_rect.
+ */
+ new_pos = MIN (run_ink->x, run_logical->x);
+ run_ink->width = MAX (run_ink->x + run_ink->width, run_logical->x + run_logical->width) - new_pos;
+ run_ink->x = new_pos;
+
+ /* We should better handle the case of height==0 in the following cases.
+ * If run_ink->height == 0, we should adjust run_ink->y appropriately.
+ */
+
+ if (properties.strikethrough)
+ {
+ if (run_ink->height == 0)
+ {
+ run_ink->height = strikethrough_thickness;
+ run_ink->y = -strikethrough_position;
+ }
+ }
switch (properties.uline)
{
case PANGO_UNDERLINE_ERROR:
- if (run_ink)
- run_ink->height = MAX (run_ink->height,
- 3 * underline_thickness - underline_position - run_ink->y);
+ run_ink->height = MAX (run_ink->height,
+ 3 * underline_thickness - underline_position - run_ink->y);
break;
case PANGO_UNDERLINE_SINGLE:
- if (run_ink)
- run_ink->height = MAX (run_ink->height,
- underline_thickness - underline_position - run_ink->y);
+ run_ink->height = MAX (run_ink->height,
+ underline_thickness - underline_position - run_ink->y);
break;
case PANGO_UNDERLINE_DOUBLE:
- if (run_ink)
- run_ink->height = MAX (run_ink->height,
- 3 * underline_thickness - underline_position - run_ink->y);
+ run_ink->height = MAX (run_ink->height,
+ 3 * underline_thickness - underline_position - run_ink->y);
break;
case PANGO_UNDERLINE_LOW:
- if (run_ink)
- run_ink->height += 2 * underline_thickness;
+ run_ink->height += 2 * underline_thickness;
+ break;
+ case PANGO_UNDERLINE_NONE:
break;
default:
g_critical ("unknown underline mode");
@@ -4073,11 +4099,12 @@ pango_layout_line_get_extents (PangoLayoutLine *line,
if (ink_rect)
{
- if (tmp_list == line->runs)
+ if (ink_rect->width == 0 || ink_rect->height == 0)
{
*ink_rect = run_ink;
+ ink_rect->x += x_pos;
}
- else
+ else if (run_ink.width != 0 && run_ink.height != 0)
{
new_pos = MIN (ink_rect->x, x_pos + run_ink.x);
ink_rect->width = MAX (ink_rect->x + ink_rect->width,
@@ -4390,6 +4417,7 @@ pango_layout_get_item_properties (PangoItem *item,
GSList *tmp_list = item->analysis.extra_attrs;
properties->uline = PANGO_UNDERLINE_NONE;
+ properties->strikethrough = FALSE;
properties->letter_spacing = 0;
properties->rise = 0;
properties->shape_set = FALSE;
@@ -4406,6 +4434,10 @@ pango_layout_get_item_properties (PangoItem *item,
properties->uline = ((PangoAttrInt *)attr)->value;
break;
+ case PANGO_ATTR_STRIKETHROUGH:
+ properties->strikethrough = ((PangoAttrInt *)attr)->value;
+ break;
+
case PANGO_ATTR_RISE:
properties->rise = ((PangoAttrInt *)attr)->value;
break;
diff --git a/pango/pango-renderer.c b/pango/pango-renderer.c
index f54e1282..7d165f82 100644
--- a/pango/pango-renderer.c
+++ b/pango/pango-renderer.c
@@ -289,7 +289,8 @@ add_underline (PangoRenderer *renderer,
PangoFontMetrics *metrics,
int base_x,
int base_y,
- PangoRectangle *ink_rect)
+ PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect)
{
PangoRectangle *current_rect = &state->underline_rect;
PangoRectangle new_rect;
@@ -297,8 +298,8 @@ add_underline (PangoRenderer *renderer,
int underline_thickness = pango_font_metrics_get_underline_thickness (metrics);
int underline_position = pango_font_metrics_get_underline_position (metrics);
- new_rect.x = base_x + ink_rect->x;
- new_rect.width = ink_rect->width;
+ new_rect.x = base_x + logical_rect->x;
+ new_rect.width = logical_rect->width;
new_rect.height = underline_thickness;
new_rect.y = base_y;
@@ -316,14 +317,13 @@ add_underline (PangoRenderer *renderer,
new_rect.y += ink_rect->y + ink_rect->height + underline_thickness;
break;
}
+ int new_pos;
if (renderer->underline == state->underline &&
new_rect.y == current_rect->y &&
new_rect.height == current_rect->height)
{
- current_rect->y = new_rect.y;
current_rect->width = new_rect.x + new_rect.width - current_rect->x;
- current_rect->height = new_rect.height;
}
else
{
@@ -340,7 +340,8 @@ add_strikethrough (PangoRenderer *renderer,
PangoFontMetrics *metrics,
int base_x,
int base_y,
- PangoRectangle *ink_rect)
+ PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect)
{
PangoRectangle *current_rect = &state->strikethrough_rect;
PangoRectangle new_rect;
@@ -348,8 +349,8 @@ add_strikethrough (PangoRenderer *renderer,
int strikethrough_thickness = pango_font_metrics_get_strikethrough_thickness (metrics);
int strikethrough_position = pango_font_metrics_get_strikethrough_position (metrics);
- new_rect.x = base_x + ink_rect->x;
- new_rect.width = ink_rect->width;
+ new_rect.x = base_x + logical_rect->x;
+ new_rect.width = logical_rect->width;
new_rect.y = base_y - strikethrough_position;
new_rect.height = strikethrough_thickness;
@@ -357,9 +358,7 @@ add_strikethrough (PangoRenderer *renderer,
new_rect.y == current_rect->y &&
new_rect.height == current_rect->height)
{
- current_rect->y = new_rect.y;
current_rect->width = new_rect.x + new_rect.width - current_rect->x;
- current_rect->height = new_rect.height;
}
else
{
@@ -493,13 +492,18 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer,
{
ink_rect = shape_attr->ink_rect;
logical_rect = shape_attr->logical_rect;
+ ink = &ink_rect;
+ logical = &logical_rect;
glyph_string_width = shape_attr->logical_rect.width;
}
else
{
if (renderer->underline != PANGO_UNDERLINE_NONE ||
renderer->strikethrough)
- ink = &ink_rect;
+ {
+ ink = &ink_rect;
+ logical = &logical_rect;
+ }
pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
ink, logical);
if (logical)
@@ -550,12 +554,12 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer,
if (renderer->underline != PANGO_UNDERLINE_NONE)
add_underline (renderer, &state,metrics,
x + x_off, y - rise,
- &ink_rect);
+ ink, logical);
if (renderer->strikethrough)
add_strikethrough (renderer, &state, metrics,
x + x_off, y - rise,
- &ink_rect);
+ ink, logical);
pango_font_metrics_unref (metrics);
}