diff options
-rw-r--r-- | pango/pango-glyph-item.c | 4 | ||||
-rw-r--r-- | pango/pango-glyph-item.h | 10 | ||||
-rw-r--r-- | pango/pango-layout-private.h | 5 | ||||
-rw-r--r-- | pango/pango-layout.c | 94 | ||||
-rw-r--r-- | pango/pango-renderer.c | 4 |
5 files changed, 78 insertions, 39 deletions
diff --git a/pango/pango-glyph-item.c b/pango/pango-glyph-item.c index c64bfa13..7eb1737d 100644 --- a/pango/pango-glyph-item.c +++ b/pango/pango-glyph-item.c @@ -130,6 +130,8 @@ pango_glyph_item_split (PangoGlyphItem *orig, pango_glyph_string_set_size (orig->glyphs, orig->glyphs->num_glyphs - num_glyphs); new->y_offset = orig->y_offset; + new->start_x_offset = orig->start_x_offset; + new->end_x_offset = -orig->start_x_offset; return new; } @@ -157,6 +159,8 @@ pango_glyph_item_copy (PangoGlyphItem *orig) result->item = pango_item_copy (orig->item); result->glyphs = pango_glyph_string_copy (orig->glyphs); result->y_offset = orig->y_offset; + result->start_x_offset = orig->start_x_offset; + result->end_x_offset = orig->end_x_offset; return result; } diff --git a/pango/pango-glyph-item.h b/pango/pango-glyph-item.h index baea69fc..fd8951d2 100644 --- a/pango/pango-glyph-item.h +++ b/pango/pango-glyph-item.h @@ -33,8 +33,12 @@ G_BEGIN_DECLS * PangoGlyphItem: * @item: corresponding `PangoItem` * @glyphs: corresponding `PangoGlyphString` - * @baseline: shift of the baseline, relative to the - * containing lines baseline. Positive values shift upwards + * @y_offset: shift of the baseline, relative to the baseline + * of the containing line. Positive values shift upwards + * @start_x_offset: horizontal displacement to apply before the + * glyph item. Positive values shift right + * @end_x_offset: horizontal displacement to apply after th + * glyph item. Positive values shift right * * A `PangoGlyphItem` is a pair of a `PangoItem` and the glyphs * resulting from shaping the items text. @@ -50,6 +54,8 @@ struct _PangoGlyphItem PangoItem *item; PangoGlyphString *glyphs; int y_offset; + int start_x_offset; + int end_x_offset; }; #define PANGO_TYPE_GLYPH_ITEM (pango_glyph_item_get_type ()) diff --git a/pango/pango-layout-private.h b/pango/pango-layout-private.h index 1805e730..b9f9b137 100644 --- a/pango/pango-layout-private.h +++ b/pango/pango-layout-private.h @@ -112,11 +112,12 @@ struct _PangoLayoutIter Extents *line_extents; int line_index; - /* X position of the current run */ + /* Position of the current run */ int run_x; - /* Width of the current run */ + /* Width and end offset of the current run */ int run_width; + int end_x_offset; /* this run is left-to-right */ gboolean ltr; diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 6c1e2e5e..098e3a3e 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -6154,18 +6154,23 @@ justify_words (PangoLayoutLine *line, typedef struct { PangoAttribute *attr; - int shift; + int x_offset; + int y_offset; } BaselineItem; static void -collect_shifts (ParaBreakState *state, - PangoItem *item, - PangoItem *prev, - int *start_shift, - int *end_shift) -{ - *start_shift = 0; - *end_shift = 0; +collect_baseline_shift (ParaBreakState *state, + PangoItem *item, + PangoItem *prev, + int *start_x_offset, + int *start_y_offset, + int *end_x_offset, + int *end_y_offset) +{ + *start_x_offset = 0; + *start_y_offset = 0; + *end_x_offset = 0; + *end_y_offset = 0; for (GSList *l = item->analysis.extra_attrs; l; l = l->next) { @@ -6175,8 +6180,8 @@ collect_shifts (ParaBreakState *state, { int value = ((PangoAttrInt *)attr)->value; - *start_shift += value; - *end_shift -= value; + *start_y_offset += value; + *end_y_offset -= value; } else if (attr->klass->type == PANGO_ATTR_BASELINE_SHIFT) { @@ -6187,51 +6192,60 @@ collect_shifts (ParaBreakState *state, entry = g_new0 (BaselineItem, 1); entry->attr = attr; + state->baseline_shifts = g_list_prepend (state->baseline_shifts, entry); value = ((PangoAttrInt *)attr)->value; if (value > 1024 || value < -1024) { - entry->shift = value; + entry->y_offset = value; + /* FIXME: compute an x_offset from value to italic angle */ } else { - int superscript_shift = 0; - int subscript_shift = 0; - hb_font_t *hb_font; + int superscript_x_offset = 0; + int superscript_y_offset = 0; + int subscript_x_offset = 0; + int subscript_y_offset = 0; if (prev) { - hb_font = pango_font_get_hb_font (prev->analysis.font); - hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_OFFSET, &superscript_shift); - hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_OFFSET, &subscript_shift); + hb_font_t *hb_font = pango_font_get_hb_font (prev->analysis.font); + hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_OFFSET, &superscript_y_offset); + hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_OFFSET, &superscript_x_offset); + hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_OFFSET, &subscript_y_offset); + hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_OFFSET, &subscript_x_offset); } - if (superscript_shift == 0) - superscript_shift = 5000; - if (subscript_shift == 0) - subscript_shift = 5000; + if (superscript_y_offset == 0) + superscript_y_offset = 5000; + if (subscript_y_offset == 0) + subscript_y_offset = 5000; switch (value) { case PANGO_BASELINE_SHIFT_NONE: - entry->shift = 0; + entry->x_offset = 0; + entry->y_offset = 0; break; case PANGO_BASELINE_SHIFT_SUPERSCRIPT: - entry->shift = superscript_shift; + entry->x_offset = superscript_x_offset; + entry->y_offset = superscript_y_offset; break; case PANGO_BASELINE_SHIFT_SUBSCRIPT: - entry->shift = -subscript_shift; + entry->x_offset = subscript_x_offset; + entry->y_offset = -subscript_y_offset; break; default: g_assert_not_reached (); } } - *start_shift += entry->shift; - state->baseline_shifts = g_list_prepend (state->baseline_shifts, entry); + *start_x_offset += entry->x_offset; + *start_y_offset += entry->y_offset; } + if (attr->end_index == item->offset + item->length) { BaselineItem *entry = state->baseline_shifts->data; @@ -6239,7 +6253,10 @@ collect_shifts (ParaBreakState *state, if (attr->start_index == entry->attr->start_index && attr->end_index == entry->attr->end_index && ((PangoAttrInt *)attr)->value == ((PangoAttrInt *)entry->attr)->value) - *end_shift -= entry->shift; + { + *end_x_offset -= entry->x_offset; + *end_y_offset -= entry->y_offset; + } else g_warning ("Baseline attributes mismatch\n"); @@ -6251,7 +6268,7 @@ collect_shifts (ParaBreakState *state, } static void -apply_baseline_shifts (PangoLayoutLine *line, +apply_baseline_shift (PangoLayoutLine *line, ParaBreakState *state) { int y_offset = 0; @@ -6261,13 +6278,16 @@ apply_baseline_shifts (PangoLayoutLine *line, { PangoLayoutRun *run = l->data; PangoItem *item = run->item; + int start_x_offset, end_x_offset; int start_y_offset, end_y_offset; - collect_shifts (state, item, prev, &start_y_offset, &end_y_offset); + collect_baseline_shift (state, item, prev, &start_x_offset, &start_y_offset, &end_x_offset, &end_y_offset); y_offset += start_y_offset; run->y_offset = y_offset; + run->start_x_offset = start_x_offset; + run->end_x_offset = end_x_offset; y_offset += end_y_offset; @@ -6295,7 +6315,7 @@ pango_layout_line_postprocess (PangoLayoutLine *line, */ line->runs = g_slist_reverse (line->runs); - apply_baseline_shifts (line, state); + apply_baseline_shift (line, state); /* Ellipsize the line if necessary */ @@ -6543,16 +6563,22 @@ update_run (PangoLayoutIter *iter, if (iter->run_list_link == iter->line->runs) iter->run_x = line_ext->logical_rect.x; else - iter->run_x += iter->run_width; + { + iter->run_x += iter->end_x_offset + iter->run_width; + if (iter->run) + iter->run_x += iter->run->start_x_offset; + } if (iter->run) { iter->run_width = pango_glyph_string_get_width (iter->run->glyphs); + iter->end_x_offset = iter->run->end_x_offset; } else { /* The empty run at the end of a line */ iter->run_width = 0; + iter->end_x_offset = 0; } if (iter->run) @@ -7256,7 +7282,7 @@ pango_layout_iter_get_cluster_extents (PangoLayoutIter *iter, if (ink_rect) { - ink_rect->x += iter->cluster_x; + ink_rect->x += iter->cluster_x + iter->run->start_x_offset; ink_rect->y -= iter->run->y_offset; offset_y (iter, &ink_rect->y); } @@ -7264,7 +7290,7 @@ pango_layout_iter_get_cluster_extents (PangoLayoutIter *iter, if (logical_rect) { g_assert (logical_rect->width == iter->cluster_width); - logical_rect->x += iter->cluster_x; + logical_rect->x += iter->cluster_x + iter->run->start_x_offset; logical_rect->y -= iter->run->y_offset; offset_y (iter, &logical_rect->y); } diff --git a/pango/pango-renderer.c b/pango/pango-renderer.c index 231ebe7d..d47ba13a 100644 --- a/pango/pango-renderer.c +++ b/pango/pango-renderer.c @@ -580,7 +580,6 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer, gboolean got_overall = FALSE; PangoRectangle overall_rect; const char *text; - int y_off; g_return_if_fail (PANGO_IS_RENDERER_FAST (renderer)); @@ -612,6 +611,7 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer, PangoAttrShape *shape_attr; PangoRectangle ink_rect, *ink = NULL; PangoRectangle logical_rect, *logical = NULL; + int y_off; if (run->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE) logical = &logical_rect; @@ -651,6 +651,7 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer, state.logical_rect_end = x + x_off + glyph_string_width; + x_off += run->start_x_offset; y_off = run->y_offset; if (run->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE) @@ -730,6 +731,7 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer, draw_strikethrough (renderer, &state); x_off += glyph_string_width; + x_off += run->end_x_offset; } /* Finish off any remaining underlines |