diff options
Diffstat (limited to 'pango')
-rw-r--r-- | pango/pango-ot-buffer.c | 132 | ||||
-rw-r--r-- | pango/pango-ot-info.c | 55 | ||||
-rw-r--r-- | pango/pango-ot-private.h | 2 | ||||
-rw-r--r-- | pango/pangofc-private.h | 3 |
4 files changed, 60 insertions, 132 deletions
diff --git a/pango/pango-ot-buffer.c b/pango/pango-ot-buffer.c index cf88c191..2d8d6e62 100644 --- a/pango/pango-ot-buffer.c +++ b/pango/pango-ot-buffer.c @@ -234,48 +234,6 @@ swap_range (PangoGlyphString *glyphs, int start, int end) } } -static void -apply_gpos (PangoGlyphString *glyphs, - hb_glyph_position_t *positions, - gboolean is_hinted, - gboolean rtl) -{ - int i; - - for (i = 0; i < glyphs->num_glyphs; i++) - { - int adjustment; - - adjustment = PANGO_UNITS_26_6(positions[i].x_advance); - - if (is_hinted) - adjustment = PANGO_UNITS_ROUND (adjustment); - - if (positions[i].new_advance) - glyphs->glyphs[i].geometry.width = adjustment; - else - glyphs->glyphs[i].geometry.width += adjustment; - - - if (positions[i].back) - { - int j, back = i - positions[i].back; - glyphs->glyphs[i].geometry.x_offset += glyphs->glyphs[back].geometry.x_offset; - glyphs->glyphs[i].geometry.y_offset += glyphs->glyphs[back].geometry.y_offset; - - if (rtl) - for (j = back + 1; j <= i; j++) - glyphs->glyphs[i].geometry.x_offset += glyphs->glyphs[j].geometry.width; - else - for (j = back; j < i; j++) - glyphs->glyphs[i].geometry.x_offset -= glyphs->glyphs[j].geometry.width; - } - - glyphs->glyphs[i].geometry.x_offset += PANGO_UNITS_26_6(positions[i].x_offset); - glyphs->glyphs[i].geometry.y_offset -= PANGO_UNITS_26_6(positions[i].y_offset); - } -} - /** * pango_ot_buffer_output * @buffer: a #PangoOTBuffer @@ -291,81 +249,43 @@ void pango_ot_buffer_output (const PangoOTBuffer *buffer, PangoGlyphString *glyphs) { - FT_Face face; - hb_face_t *hb_face; unsigned int i; int last_cluster; - unsigned int len; - PangoOTGlyph *otglyphs; - hb_glyph_position_t *positions; - - face = pango_fc_font_lock_face (buffer->font); - g_assert (face); - - pango_ot_buffer_get_glyphs (buffer, &otglyphs, (int *) &len); + unsigned int num_glyphs; + hb_buffer_t *hb_buffer = buffer->buffer; + gboolean is_hinted = buffer->font->is_hinted; + hb_glyph_info_t *hb_glyph; + hb_glyph_position_t *hb_position; /* Copy glyphs into output glyph string */ - pango_glyph_string_set_size (glyphs, len); - + num_glyphs = hb_buffer_get_length (hb_buffer); + hb_glyph = hb_buffer_get_glyph_infos (hb_buffer); + hb_position = hb_buffer_get_glyph_positions (hb_buffer); + pango_glyph_string_set_size (glyphs, num_glyphs); last_cluster = -1; - for (i = 0; i < len; i++) + for (i = 0; i < num_glyphs; i++) { - PangoOTGlyph *otglyph = &otglyphs[i]; - - glyphs->glyphs[i].glyph = otglyph->glyph; - - glyphs->log_clusters[i] = otglyph->cluster; - if (glyphs->log_clusters[i] != last_cluster) - glyphs->glyphs[i].attr.is_cluster_start = 1; - else - glyphs->glyphs[i].attr.is_cluster_start = 0; + int advance; + glyphs->glyphs[i].glyph = hb_glyph->codepoint; + glyphs->log_clusters[i] = hb_glyph->cluster; + glyphs->glyphs[i].attr.is_cluster_start = glyphs->log_clusters[i] != last_cluster; last_cluster = glyphs->log_clusters[i]; - } - - hb_face = _pango_ot_info_get_hb_face (pango_ot_info_get (face)); - - /* Apply default positioning */ - for (i = 0; i < (unsigned int)glyphs->num_glyphs; i++) - { - if (glyphs->glyphs[i].glyph) - { - PangoRectangle logical_rect; - - if (buffer->zero_width_marks && - hb_ot_layout_get_glyph_class (hb_face, glyphs->glyphs[i].glyph) == HB_OT_LAYOUT_GLYPH_CLASS_MARK) - { - glyphs->glyphs[i].geometry.width = 0; - } - else - { - pango_font_get_glyph_extents ((PangoFont *)buffer->font, glyphs->glyphs[i].glyph, NULL, &logical_rect); - glyphs->glyphs[i].geometry.width = logical_rect.width; - } - } - else - glyphs->glyphs[i].geometry.width = 0; - - glyphs->glyphs[i].geometry.x_offset = 0; - glyphs->glyphs[i].geometry.y_offset = 0; - } + advance = PANGO_UNITS_26_6(hb_position->x_advance); + if (is_hinted) + advance = PANGO_UNITS_ROUND (advance); + glyphs->glyphs[i].geometry.width = advance; + glyphs->glyphs[i].geometry.x_offset = PANGO_UNITS_26_6 (hb_position->x_offset); + glyphs->glyphs[i].geometry.y_offset = -PANGO_UNITS_26_6 (hb_position->y_offset); - positions = hb_buffer_get_glyph_positions (buffer->buffer); - if (buffer->applied_gpos) - { - apply_gpos (glyphs, positions, buffer->font->is_hinted, buffer->rtl); - if (buffer->rtl) - swap_range (glyphs, 0, glyphs->num_glyphs); - } - else - { - if (buffer->rtl) - swap_range (glyphs, 0, glyphs->num_glyphs); - /* FIXME we should only do this if the 'kern' feature was requested */ - pango_fc_font_kern_glyphs (buffer->font, glyphs); + hb_glyph++; + hb_position++; } - pango_fc_font_unlock_face (buffer->font); + if (buffer->rtl) + swap_range (glyphs, 0, glyphs->num_glyphs); + if (!buffer->applied_gpos) + pango_fc_font_kern_glyphs (buffer->font, glyphs); } diff --git a/pango/pango-ot-info.c b/pango/pango-ot-info.c index 39129dfb..eeb39443 100644 --- a/pango/pango-ot-info.c +++ b/pango/pango-ot-info.c @@ -528,11 +528,11 @@ _pango_ot_info_position (const PangoOTInfo *info, const PangoOTRuleset *ruleset, PangoOTBuffer *buffer) { - unsigned int i; + unsigned int i, num_glyphs; gboolean is_hinted; hb_font_t *hb_font; - - hb_buffer_clear_positions (buffer->buffer); + hb_glyph_info_t *hb_glyph; + hb_glyph_position_t *hb_position; /* XXX reuse hb_font */ hb_font = hb_font_create (); @@ -544,6 +544,31 @@ _pango_ot_info_position (const PangoOTInfo *info, is_hinted ? info->face->size->metrics.x_ppem : 0, is_hinted ? info->face->size->metrics.y_ppem : 0); + + /* Apply default positioning */ + num_glyphs = hb_buffer_get_length (buffer->buffer); + hb_glyph = hb_buffer_get_glyph_infos (buffer->buffer); + hb_position = hb_buffer_get_glyph_positions (buffer->buffer); + + hb_buffer_clear_positions (buffer->buffer); + for (i = 0; i < num_glyphs; i++) + { + if (hb_glyph->codepoint && + (!buffer->zero_width_marks || + hb_ot_layout_get_glyph_class (info->hb_face, hb_glyph->codepoint) != HB_OT_LAYOUT_GLYPH_CLASS_MARK)) + { + PangoRectangle logical_rect; + pango_font_get_glyph_extents ((PangoFont *) buffer->font, hb_glyph->codepoint, NULL, &logical_rect); + hb_position->x_advance = PANGO_UNITS_TO_26_6 (logical_rect.width); + } + else + hb_position->x_advance = 0; + + hb_glyph++; + hb_position++; + } + + for (i = 0; i < ruleset->rules->len; i++) { PangoOTRule *rule = &g_array_index (ruleset->rules, PangoOTRule, i); @@ -572,28 +597,8 @@ _pango_ot_info_position (const PangoOTInfo *info, buffer->applied_gpos = TRUE; } - if (buffer->applied_gpos) - { - unsigned int i, j; - unsigned int len = hb_buffer_get_len (buffer->buffer); - hb_glyph_position_t *positions = hb_buffer_get_glyph_positions (buffer->buffer); - - /* First handle all left-to-right connections */ - for (j = 0; j < len; j++) - { - if (positions[j].cursive_chain > 0) - positions[j].y_offset += positions[j - positions[j].cursive_chain].y_offset; - } - - /* Then handle all right-to-left connections */ - for (i = len; i > 0; i--) - { - j = i - 1; - - if (positions[j].cursive_chain < 0) - positions[j].y_offset += positions[j - positions[j].cursive_chain].y_offset; - } - } + if (buffer->applied_gpos) + hb_ot_layout_position_finish (info->hb_face, hb_font, buffer->buffer); hb_font_destroy (hb_font); } diff --git a/pango/pango-ot-private.h b/pango/pango-ot-private.h index 7891b1cb..1911512e 100644 --- a/pango/pango-ot-private.h +++ b/pango/pango-ot-private.h @@ -29,6 +29,8 @@ #include <hb-ft.h> #include <hb-glib.h> +#include "pangofc-private.h" + G_BEGIN_DECLS typedef struct _PangoOTInfoClass PangoOTInfoClass; diff --git a/pango/pangofc-private.h b/pango/pangofc-private.h index 0612a692..b5fab578 100644 --- a/pango/pangofc-private.h +++ b/pango/pangofc-private.h @@ -61,7 +61,8 @@ struct _PangoFcCmapCache (((d) >= 0) ? \ ((d) + PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6 : \ ((d) - PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6) -#define PANGO_UNITS_26_6(d) (PANGO_SCALE_26_6 * (d)) +#define PANGO_UNITS_26_6(d) ((d) * PANGO_SCALE_26_6) +#define PANGO_UNITS_TO_26_6(d) ((d) / PANGO_SCALE_26_6) void _pango_fc_font_shutdown (PangoFcFont *fcfont); |