summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pango/pango-glyph-item.c4
-rw-r--r--pango/pango-glyph-item.h10
-rw-r--r--pango/pango-layout-private.h5
-rw-r--r--pango/pango-layout.c94
-rw-r--r--pango/pango-renderer.c4
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