Index: pango/pango-layout.c =================================================================== RCS file: /cvs/gnome/pango/pango/pango-layout.c,v retrieving revision 1.143 diff -p -u -r1.143 pango-layout.c --- pango/pango-layout.c 4 Nov 2005 23:55:37 -0000 1.143 +++ pango/pango-layout.c 9 Nov 2005 04:50:22 -0000 @@ -19,6 +19,7 @@ * Boston, MA 02111-1307, USA. */ +#include #include /* For pango_shape() */ #include #include @@ -134,6 +135,7 @@ static void pango_layout_get_item_proper ItemProperties *properties); static void pango_layout_finalize (GObject *object); +static void pango_layout_ensure_log_attrs (PangoLayout *layout); G_DEFINE_TYPE (PangoLayout, pango_layout, G_TYPE_OBJECT) @@ -152,6 +154,7 @@ pango_layout_init (PangoLayout *layout) layout->auto_dir = TRUE; layout->log_attrs = NULL; + layout->log_attrs_initialized = FALSE; layout->lines = NULL; layout->tab_width = -1; @@ -964,6 +967,7 @@ pango_layout_get_log_attrs (PangoLayout g_return_if_fail (layout != NULL); pango_layout_check_lines (layout); + pango_layout_ensure_log_attrs (layout); if (attrs) { @@ -1064,6 +1068,8 @@ pango_layout_line_index_to_x (PangoLayou GSList *run_list = line->runs; int width = 0; + pango_layout_ensure_log_attrs (layout); + while (run_list) { PangoLayoutRun *run = run_list->data; @@ -1326,6 +1332,8 @@ pango_layout_move_cursor_visually (Pango gboolean off_start = FALSE; gboolean off_end = FALSE; + pango_layout_ensure_log_attrs (layout); + g_return_if_fail (layout != NULL); g_return_if_fail (old_index >= 0 && old_index <= layout->length); g_return_if_fail (old_index < layout->length || old_trailing == 0); @@ -2691,6 +2699,14 @@ shape_run (PangoLayoutLine *line, if (state->properties.letter_spacing) { PangoGlyphItem glyph_item; + +/* +XXX -- fprintf (stderr, "letter spacing!!\n"); + if (!layout->log_attrs_initialized) + get_items_log_attrs (start, state->items, + layout->log_attrs + state->start_offset, + delim_len); +*/ glyph_item.item = item; glyph_item.glyphs = glyphs; @@ -2990,7 +3006,7 @@ process_line (PangoLayout *layout, switch (result) { case BREAK_ALL_FIT: - if (can_break_in (layout, state->start_offset, old_num_chars, first_item_in_line)) + if (old_remaining_width >= 0 && can_break_in (layout, state->start_offset, old_num_chars, first_item_in_line)) { have_break = TRUE; break_remaining_width = old_remaining_width; @@ -3267,9 +3283,13 @@ pango_layout_check_lines (PangoLayout *l attrs, iter); - get_items_log_attrs (start, state.items, - layout->log_attrs + start_offset, - delim_len); + if (layout->ellipsize != PANGO_ELLIPSIZE_NONE && layout->width >= 0) + { + get_items_log_attrs (start, state.items, + layout->log_attrs + start_offset, + delim_len); + layout->log_attrs_initialized = TRUE; + } if (state.items) { @@ -3429,6 +3449,7 @@ pango_layout_line_x_to_index (PangoLayou return FALSE; layout = line->layout; + pango_layout_ensure_log_attrs (layout); /* Find the last index in the line */ @@ -5236,3 +5257,107 @@ pango_layout_iter_get_layout_extents (P if (logical_rect) *logical_rect = iter->logical_rect; } + +static void +pango_layout_ensure_log_attrs (PangoLayout *layout) +{ + const char *start; + gboolean done = FALSE; + int start_offset; + PangoAttrList *attrs; + PangoAttrList *no_shape_attrs; + PangoAttrIterator *iter; + PangoDirection prev_base_dir = PANGO_DIRECTION_NEUTRAL, base_dir = PANGO_DIRECTION_NEUTRAL; + + if (layout->log_attrs_initialized) return; + layout->log_attrs_initialized = TRUE; + + attrs = pango_layout_get_effective_attributes (layout); + no_shape_attrs = filter_no_shape_attributes (attrs); + iter = pango_attr_list_get_iterator (attrs); + + start_offset = 0; + start = layout->text; + + /* Find the first strong direction of the text */ + if (layout->auto_dir) + { + prev_base_dir = pango_find_base_dir (layout->text, layout->length); + if (prev_base_dir == PANGO_DIRECTION_NEUTRAL) + prev_base_dir = pango_context_get_base_dir (layout->context); + } + else + base_dir = pango_context_get_base_dir (layout->context); + + do + { + int delim_len; + const char *end; + int delimiter_index, next_para_index; + ParaBreakState state; + + if (layout->single_paragraph) + { + delimiter_index = layout->length; + next_para_index = layout->length; + } + else + { + pango_find_paragraph_boundary (start, + (layout->text + layout->length) - start, + &delimiter_index, + &next_para_index); + } + + g_assert (next_para_index >= delimiter_index); + + if (layout->auto_dir) + { + base_dir = pango_find_base_dir (start, delimiter_index); + + /* Propagate the base direction for neutral paragraphs */ + if (base_dir == PANGO_DIRECTION_NEUTRAL) + base_dir = prev_base_dir; + else + prev_base_dir = base_dir; + } + + end = start + delimiter_index; + + delim_len = next_para_index - delimiter_index; + + if (end == (layout->text + layout->length)) + done = TRUE; + + g_assert (end <= (layout->text + layout->length)); + g_assert (start <= (layout->text + layout->length)); + g_assert (delim_len < 4); /* PS is 3 bytes */ + g_assert (delim_len >= 0); + + state.attrs = attrs; + state.items = pango_itemize_with_base_dir (layout->context, + base_dir, + layout->text, + start - layout->text, + end - start, + attrs, + iter); + + get_items_log_attrs (start, state.items, + layout->log_attrs + start_offset, + delim_len); + + while (state.items) + state.items = g_list_delete_link (state.items, state.items); + + if (!done) + start_offset += g_utf8_strlen (start, (end - start) + delim_len); + + start = end + delim_len; + } + while (!done); + + pango_attr_iterator_destroy (iter); + pango_attr_list_unref (attrs); +} +