summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKhaled Hosny <khaledhosny@eglug.org>2015-08-18 16:04:16 +0200
committerKhaled Hosny <khaledhosny@eglug.org>2015-08-18 16:27:55 +0200
commit25976af86f2db722eb75c8d3015888cd5cad2efb (patch)
tree4f170ca4fcaa4051b96e25d03ac906209329ab3b
parent8971ffd1e953341e18b8303e787a16263d68c50b (diff)
downloadpango-25976af86f2db722eb75c8d3015888cd5cad2efb.tar.gz
Use grapheme boundaries in justify_clusters()
Instead of relying on the fact that marks have the same cluster number as their bases, which will change in the next commit.
-rw-r--r--pango/pango-layout.c77
1 files changed, 46 insertions, 31 deletions
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 862ae8b3..fa6fbc53 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -5167,6 +5167,10 @@ static void
justify_clusters (PangoLayoutLine *line,
ParaBreakState *state)
{
+ const gchar *text = line->layout->text;
+ const PangoLogAttr *log_attrs = line->layout->log_attrs;
+
+ int offset;
int total_remaining_width, total_gaps = 0;
int added_so_far, gaps_so_far;
gboolean is_hinted;
@@ -5188,52 +5192,63 @@ justify_clusters (PangoLayoutLine *line,
added_so_far = 0;
gaps_so_far = 0;
+ offset = state->line_start_offset;
for (run_iter = line->runs; run_iter; run_iter = run_iter->next)
{
PangoLayoutRun *run = run_iter->data;
PangoGlyphString *glyphs = run->glyphs;
gboolean is_first_gap = TRUE;
+ PangoGlyphItemIter cluster_iter;
+ gboolean have_cluster;
- int i;
-
- for (i = 0; i < glyphs->num_glyphs; i++)
+ for (have_cluster = pango_glyph_item_iter_init_start (&cluster_iter, run, text);
+ have_cluster;
+ have_cluster = pango_glyph_item_iter_next_cluster (&cluster_iter))
{
- if (!glyphs->glyphs[i].attr.is_cluster_start)
- continue;
+ int i;
+ int dir;
- /* also don't expand zero-width spaces at the end of runs */
- if (glyphs->glyphs[i].geometry.width == 0)
- {
- if (i == glyphs->num_glyphs -1)
- continue;
+ /* don't expand in the middle of graphemes */
+ if (!log_attrs[offset + cluster_iter.start_char].is_cursor_position)
+ continue;
- if (i == 0 && glyphs->num_glyphs > 1 && glyphs->glyphs[i+1].attr.is_cluster_start)
- continue;
- }
+ dir = (cluster_iter.start_glyph < cluster_iter.end_glyph) ? 1 : -1;
+ for (i = cluster_iter.start_glyph; i != cluster_iter.end_glyph; i += dir)
+ {
+ /* also don't expand zero-width spaces at the end of runs */
+ if (glyphs->glyphs[i].geometry.width == 0)
+ {
+ if (i == glyphs->num_glyphs -1)
+ continue;
- if (is_first_gap)
- {
- is_first_gap = FALSE;
- continue;
- }
+ if (i == 0 && glyphs->num_glyphs > 1 && glyphs->glyphs[i+1].attr.is_cluster_start)
+ continue;
+ }
+
+ if (is_first_gap)
+ {
+ is_first_gap = FALSE;
+ continue;
+ }
- gaps_so_far++;
+ gaps_so_far++;
- if (mode == ADJUST)
- {
- int adjustment, space_left, space_right;
+ if (mode == ADJUST)
+ {
+ int adjustment, space_left, space_right;
- adjustment = (gaps_so_far * total_remaining_width) / total_gaps - added_so_far;
- if (is_hinted)
- adjustment = PANGO_UNITS_ROUND (adjustment);
- /* distribute to before/after */
- distribute_letter_spacing (adjustment, &space_left, &space_right);
+ adjustment = (gaps_so_far * total_remaining_width) / total_gaps - added_so_far;
+ if (is_hinted)
+ adjustment = PANGO_UNITS_ROUND (adjustment);
+ /* distribute to before/after */
+ distribute_letter_spacing (adjustment, &space_left, &space_right);
- glyphs->glyphs[i-1].geometry.width += space_left ;
- glyphs->glyphs[i ].geometry.width += space_right;
- glyphs->glyphs[i ].geometry.x_offset += space_right;
+ glyphs->glyphs[i-1].geometry.width += space_left ;
+ glyphs->glyphs[i ].geometry.width += space_right;
+ glyphs->glyphs[i ].geometry.x_offset += space_right;
- added_so_far += adjustment;
+ added_so_far += adjustment;
+ }
}
}
}