From f90163fecc2f1e10ea1c800c2ac3045b485398bd Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 15 Aug 2007 19:23:54 +0000 Subject: [PATCH] =?utf8?q?Bug=20467056=20=E2=80=93=20Shape=20attribute=20h?= =?utf8?q?andling=20is=20not=20consistent?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 2007-08-15 Behdad Esfahbod Bug 467056 – Shape attribute handling is not consistent * pango/pango-impl-utils.h: * pango/pango-layout.c (pango_layout_line_index_to_x), (shape_run), (pango_layout_line_x_to_index), (pango_layout_run_get_extents), (update_run): * pango/pango-renderer.c (pango_renderer_draw_layout_line): * pango/pango-utils.c (_pango_shape_shape), (_pango_shape_get_extents): Fix handling of extents for shaped runs. Previsouly a shaped run with more than one character was not correctly positioned. svn path=/trunk/; revision=2401 --- ChangeLog | 14 ++++++ pango/pango-impl-utils.h | 15 +++++- pango/pango-layout.c | 121 +++++------------------------------------------ pango/pango-renderer.c | 10 ++-- pango/pango-utils.c | 77 ++++++++++++++++++++++++++++++ 5 files changed, 123 insertions(+), 114 deletions(-) diff --git a/ChangeLog b/ChangeLog index 45af68b..d1447d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2007-08-15 Behdad Esfahbod + + Bug 467056 – Shape attribute handling is not consistent + + * pango/pango-impl-utils.h: + * pango/pango-layout.c (pango_layout_line_index_to_x), (shape_run), + (pango_layout_line_x_to_index), (pango_layout_run_get_extents), + (update_run): + * pango/pango-renderer.c (pango_renderer_draw_layout_line): + * pango/pango-utils.c (_pango_shape_shape), + (_pango_shape_get_extents): + Fix handling of extents for shaped runs. Previsouly a shaped run + with more than one character was not correctly positioned. + 2007-08-14 Behdad Esfahbod Bug 466755 – pango hangul is crashing in gnome-about because it is diff --git a/pango/pango-impl-utils.h b/pango/pango-impl-utils.h index 2f71dad..1f60d84 100644 --- a/pango/pango-impl-utils.h +++ b/pango/pango-impl-utils.h @@ -24,7 +24,7 @@ #define __PANGO_IMPL_UTILS_H__ #include -#include +#include G_BEGIN_DECLS @@ -94,6 +94,19 @@ extern PangoWarningHistory _pango_warning_history; #define I_(string) g_intern_static_string (string) +/* Some functions for handling PANGO_ATTR_SHAPE */ +void _pango_shape_shape (const char *text, + gint n_chars, + PangoRectangle *shape_ink, + PangoRectangle *shape_logical, + PangoGlyphString *glyphs); + +void _pango_shape_get_extents (gint n_chars, + PangoRectangle *shape_ink, + PangoRectangle *shape_logical, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect); + G_END_DECLS #endif /* __PANGO_IMPL_UTILS_H__ */ diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 82d8ba5..75af389 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -1367,7 +1367,7 @@ pango_layout_line_index_to_x (PangoLayoutLine *line, if (properties.shape_set) { if (x_pos) - *x_pos = width + (trailing > 0 ? properties.shape_logical_rect->width : 0); + *x_pos = width + (trailing > 0 ? pango_glyph_string_get_width (run->glyphs) : 0); } else { @@ -1405,10 +1405,7 @@ pango_layout_line_index_to_x (PangoLayoutLine *line, return; } - if (!properties.shape_set) - width += pango_glyph_string_get_width (run->glyphs); - else - width += properties.shape_logical_rect->width; + width += pango_glyph_string_get_width (run->glyphs); run_list = run_list->next; } @@ -2629,79 +2626,6 @@ pango_layout_line_leaked (PangoLayoutLine *line) } -/************************************************ - * Some functions for handling PANGO_ATTR_SHAPE * - ************************************************/ - -static void -imposed_shape (const char *text, - gint n_chars, - PangoRectangle *shape_ink, - PangoRectangle *shape_logical, - PangoGlyphString *glyphs) -{ - int i; - const char *p; - - pango_glyph_string_set_size (glyphs, n_chars); - - for (i=0, p = text; i < n_chars; i++, p = g_utf8_next_char (p)) - { - glyphs->glyphs[i].glyph = PANGO_GLYPH_EMPTY; - glyphs->glyphs[i].geometry.x_offset = 0; - glyphs->glyphs[i].geometry.y_offset = 0; - glyphs->glyphs[i].geometry.width = shape_logical->width; - glyphs->glyphs[i].attr.is_cluster_start = 1; - - glyphs->log_clusters[i] = p - text; - } -} - -static void -imposed_extents (gint n_chars, - PangoRectangle *shape_ink, - PangoRectangle *shape_logical, - PangoRectangle *ink_rect, - PangoRectangle *logical_rect) -{ - if (n_chars > 0) - { - if (ink_rect) - { - ink_rect->x = MIN (shape_ink->x, shape_ink->x + shape_logical->width * (n_chars - 1)); - ink_rect->width = MAX (shape_ink->width, shape_ink->width + shape_logical->width * (n_chars - 1)); - ink_rect->y = shape_ink->y; - ink_rect->height = shape_ink->height; - } - if (logical_rect) - { - logical_rect->x = MIN (shape_logical->x, shape_logical->x + shape_logical->width * (n_chars - 1)); - logical_rect->width = MAX (shape_logical->width, shape_logical->width + shape_logical->width * (n_chars - 1)); - logical_rect->y = shape_logical->y; - logical_rect->height = shape_logical->height; - } - } - else - { - if (ink_rect) - { - ink_rect->x = 0; - ink_rect->y = 0; - ink_rect->width = 0; - ink_rect->height = 0; - } - - if (logical_rect) - { - logical_rect->x = 0; - logical_rect->y = 0; - logical_rect->width = 0; - logical_rect->height = 0; - } - } -} - - /***************** * Line Breaking * *****************/ @@ -3048,9 +2972,9 @@ shape_run (PangoLayoutLine *line, else { if (state->properties.shape_set) - imposed_shape (layout->text + item->offset, item->num_chars, - state->properties.shape_ink_rect, state->properties.shape_logical_rect, - glyphs); + _pango_shape_shape (layout->text + item->offset, item->num_chars, + state->properties.shape_ink_rect, state->properties.shape_logical_rect, + glyphs); else pango_shape (layout->text + item->offset, item->length, &item->analysis, glyphs); @@ -3955,10 +3879,7 @@ pango_layout_line_x_to_index (PangoLayoutLine *line, pango_layout_get_item_properties (run->item, &properties); - if (properties.shape_set) - logical_width = properties.shape_logical_rect->width; - else - logical_width = pango_glyph_string_get_width (run->glyphs); + logical_width = pango_glyph_string_get_width (run->glyphs); if (x_pos >= start_pos && x_pos < start_pos + logical_width) { @@ -4281,26 +4202,6 @@ pango_layout_line_get_empty_extents (PangoLayoutLine *line, } } -static int -pango_layout_run_get_width (PangoLayoutRun *run) -{ - ItemProperties properties; - - pango_layout_get_item_properties (run->item, &properties); - - if (properties.shape_set) { - PangoRectangle run_logical; - - imposed_extents (run->item->num_chars, - properties.shape_ink_rect, - properties.shape_logical_rect, - NULL, &run_logical); - - return run_logical.width; - } else - return pango_glyph_string_get_width (run->glyphs); -} - static void pango_layout_run_get_extents (PangoLayoutRun *run, PangoRectangle *run_ink, @@ -4321,10 +4222,10 @@ pango_layout_run_get_extents (PangoLayoutRun *run, run_logical = &logical; if (properties.shape_set) - imposed_extents (run->item->num_chars, - properties.shape_ink_rect, - properties.shape_logical_rect, - run_ink, run_logical); + _pango_shape_get_extents (run->item->num_chars, + properties.shape_ink_rect, + properties.shape_logical_rect, + run_ink, run_logical); else pango_glyph_string_extents (run->glyphs, run->item->analysis.font, run_ink, run_logical); @@ -5244,7 +5145,7 @@ update_run (PangoLayoutIter *iter, if (iter->run) { - iter->run_width = pango_layout_run_get_width (iter->run); + iter->run_width = pango_glyph_string_get_width (iter->run->glyphs); } else { diff --git a/pango/pango-renderer.c b/pango/pango-renderer.c index 9dc1198..6d13411 100644 --- a/pango/pango-renderer.c +++ b/pango/pango-renderer.c @@ -427,6 +427,7 @@ draw_shaped_glyphs (PangoRenderer *renderer, } } + /** * pango_renderer_draw_layout_line: * @renderer: a #PangoRenderer @@ -490,11 +491,14 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer, if (shape_attr) { - 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; + _pango_shape_get_extents (run->glyphs->num_glyphs, + &shape_attr->ink_rect, + &shape_attr->logical_rect, + ink, + logical); + glyph_string_width = logical->width; } else { diff --git a/pango/pango-utils.c b/pango/pango-utils.c index 39ade73..3f36478 100644 --- a/pango/pango-utils.c +++ b/pango/pango-utils.c @@ -1641,3 +1641,80 @@ pango_extents_to_pixels (PangoRectangle *ink_rect, logical_rect->height = PANGO_PIXELS (orig_y + logical_rect->height) - logical_rect->y; } } + + + + + +/********************************************************* + * Some internal functions for handling PANGO_ATTR_SHAPE * + ********************************************************/ + +void +_pango_shape_shape (const char *text, + gint n_chars, + PangoRectangle *shape_ink, + PangoRectangle *shape_logical, + PangoGlyphString *glyphs) +{ + int i; + const char *p; + + pango_glyph_string_set_size (glyphs, n_chars); + + for (i=0, p = text; i < n_chars; i++, p = g_utf8_next_char (p)) + { + glyphs->glyphs[i].glyph = PANGO_GLYPH_EMPTY; + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + glyphs->glyphs[i].geometry.width = shape_logical->width; + glyphs->glyphs[i].attr.is_cluster_start = 1; + + glyphs->log_clusters[i] = p - text; + } +} + +void +_pango_shape_get_extents (gint n_chars, + PangoRectangle *shape_ink, + PangoRectangle *shape_logical, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect) +{ + if (n_chars > 0) + { + if (ink_rect) + { + ink_rect->x = MIN (shape_ink->x, shape_ink->x + shape_logical->width * (n_chars - 1)); + ink_rect->width = MAX (shape_ink->width, shape_ink->width + shape_logical->width * (n_chars - 1)); + ink_rect->y = shape_ink->y; + ink_rect->height = shape_ink->height; + } + if (logical_rect) + { + logical_rect->x = MIN (shape_logical->x, shape_logical->x + shape_logical->width * (n_chars - 1)); + logical_rect->width = MAX (shape_logical->width, shape_logical->width + shape_logical->width * (n_chars - 1)); + logical_rect->y = shape_logical->y; + logical_rect->height = shape_logical->height; + } + } + else + { + if (ink_rect) + { + ink_rect->x = 0; + ink_rect->y = 0; + ink_rect->width = 0; + ink_rect->height = 0; + } + + if (logical_rect) + { + logical_rect->x = 0; + logical_rect->y = 0; + logical_rect->width = 0; + logical_rect->height = 0; + } + } +} + -- 2.7.4