diff options
author | Behdad Esfahbod <behdad@gnome.org> | 2006-09-11 20:45:53 +0000 |
---|---|---|
committer | Behdad Esfahbod <behdad@src.gnome.org> | 2006-09-11 20:45:53 +0000 |
commit | e4a6c5565068357790f1af69049b4138620ca2e7 (patch) | |
tree | 9a6cf8945ca75e699eb57ac9a033eefcaf31d17e /pango | |
parent | 9ca216e3cf43307f5e5e84690936affc41697975 (diff) | |
download | pango-e4a6c5565068357790f1af69049b4138620ca2e7.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.
2006-09-10 Behdad Esfahbod <behdad@gnome.org>
Bug 352535 – Ink extents of empty glyph
* pango/pangocairo-fcfont.c
(pango_cairo_fc_font_get_glyph_extents): Return zero ink_rect for
PANGO_GLYPH_EMPTY.
Diffstat (limited to 'pango')
-rw-r--r-- | pango/pango-layout.c | 61 | ||||
-rw-r--r-- | pango/pango-renderer.c | 33 | ||||
-rw-r--r-- | pango/pangocairo-fcfont.c | 2 |
3 files changed, 66 insertions, 30 deletions
diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 2e4534f3..22e9bcca 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; @@ -3910,10 +3911,14 @@ pango_layout_run_get_extents (PangoLayoutRun *run, PangoRectangle *run_ink, PangoRectangle *run_logical) { + PangoRectangle logical; ItemProperties properties; pango_layout_get_item_properties (run->item, &properties); + 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, @@ -3923,33 +3928,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"); @@ -4024,11 +4051,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, @@ -4345,6 +4373,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; @@ -4361,6 +4390,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 c53f645d..5bf37a8e 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; @@ -321,9 +322,7 @@ add_underline (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 { @@ -340,7 +339,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 +348,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 +357,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 { @@ -479,7 +477,7 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer, gint rise; PangoLayoutRun *run = l->data; PangoAttrShape *shape_attr; - PangoRectangle ink_rect; + PangoRectangle ink_rect, logical_rect; pango_renderer_prepare_run (renderer, run); @@ -488,15 +486,20 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer, if (shape_attr) { ink_rect = shape_attr->ink_rect; + logical_rect = shape_attr->logical_rect; glyph_string_width = shape_attr->logical_rect.width; } else { if (renderer->underline != PANGO_UNDERLINE_NONE || renderer->strikethrough) + { pango_glyph_string_extents (run->glyphs, run->item->analysis.font, - &ink_rect, NULL); - glyph_string_width = pango_glyph_string_get_width (run->glyphs); + &ink_rect, &logical_rect); + glyph_string_width = logical_rect.width; + } + else + glyph_string_width = pango_glyph_string_get_width (run->glyphs); } state.logical_rect_end = x + x_off + glyph_string_width; @@ -537,12 +540,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_rect, &logical_rect); if (renderer->strikethrough) add_strikethrough (renderer, &state, metrics, x + x_off, y - rise, - &ink_rect); + &ink_rect, &logical_rect); pango_font_metrics_unref (metrics); } diff --git a/pango/pangocairo-fcfont.c b/pango/pangocairo-fcfont.c index 10be3c36..0312d4be 100644 --- a/pango/pangocairo-fcfont.c +++ b/pango/pangocairo-fcfont.c @@ -345,7 +345,7 @@ pango_cairo_fc_font_get_glyph_extents (PangoFont *font, if (glyph == PANGO_GLYPH_EMPTY) { if (ink_rect) - *ink_rect = cffont->font_extents; + ink_rect->x = ink_rect->y = ink_rect->width = ink_rect->height = 0; if (logical_rect) *logical_rect = cffont->font_extents; return; |