diff options
author | Matthias Clasen <mclasen@redhat.com> | 2019-07-09 12:49:51 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2019-07-18 16:19:58 -0700 |
commit | d5984cd7423723817b4c04846fda2011cf53b80f (patch) | |
tree | 907c41e6a814bf6e1d2d0ec2bf93488f30ea7cab /pango/shape.c | |
parent | 2bcf7a63cd0abc61f4dc610a70c54c8fafb64d57 (diff) | |
download | pango-d5984cd7423723817b4c04846fda2011cf53b80f.tar.gz |
Switch to using harfbuzz for shaping
Drop internal shape engine uses and call
_pango_fc_shape directly. This makes us
use harfbuzz for shaping, on all backends.
Diffstat (limited to 'pango/shape.c')
-rw-r--r-- | pango/shape.c | 134 |
1 files changed, 73 insertions, 61 deletions
diff --git a/pango/shape.c b/pango/shape.c index 1d056f6c..9117138c 100644 --- a/pango/shape.c +++ b/pango/shape.c @@ -35,6 +35,8 @@ #include "pango-glyph.h" #include "pango-engine-private.h" +#include "pangofc-private.h" + #include <string.h> /** @@ -62,6 +64,55 @@ pango_shape (const gchar *text, pango_shape_full (text, length, text, length, analysis, glyphs); } +static void +fallback_shape (const char *text, + unsigned int length, + const PangoAnalysis *analysis, + PangoGlyphString *glyphs) +{ + int n_chars; + const char *p; + int cluster = 0; + int i; + + n_chars = text ? pango_utf8_strlen (text, length) : 0; + + pango_glyph_string_set_size (glyphs, n_chars); + + p = text; + for (i = 0; i < n_chars; i++) + { + gunichar wc; + PangoGlyph glyph; + PangoRectangle logical_rect; + + wc = g_utf8_get_char (p); + + if (g_unichar_type (wc) != G_UNICODE_NON_SPACING_MARK) + cluster = p - text; + + if (pango_is_zero_width (wc)) + glyph = PANGO_GLYPH_EMPTY; + else + glyph = PANGO_GET_UNKNOWN_GLYPH (wc); + + pango_font_get_glyph_extents (analysis->font, glyph, NULL, &logical_rect); + + glyphs->glyphs[i].glyph = glyph; + + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + glyphs->glyphs[i].geometry.width = logical_rect.width; + + glyphs->log_clusters[i] = cluster; + + p = g_utf8_next_char (p); + } + + if (analysis->level & 1) + pango_glyph_string_reverse_range (glyphs, 0, glyphs->num_glyphs); +} + /** * pango_shape_full: * @item_text: valid UTF-8 text to shape. @@ -111,59 +162,42 @@ pango_shape_full (const gchar *item_text, g_return_if_fail (paragraph_text <= item_text); g_return_if_fail (paragraph_text + paragraph_length >= item_text + item_length); - if (G_LIKELY (analysis->shape_engine && analysis->font)) + if (analysis->font) { - _pango_engine_shape_shape (analysis->shape_engine, analysis->font, - item_text, item_length, - paragraph_text, paragraph_length, - analysis, glyphs); + _pango_fc_shape (analysis->font, + item_text, item_length, + analysis, glyphs, + paragraph_text, paragraph_length); if (G_UNLIKELY (glyphs->num_glyphs == 0)) { /* If a font has been correctly chosen, but no glyphs are output, - * there's probably something wrong with the shaper, or the font. + * there's probably something wrong with the font. * * Trying to be informative, we print out the font description, - * shaper name, and the text, but to not flood the terminal with + * and the text, but to not flood the terminal with * zillions of the message, we set a flag to only err once per - * font/engine pair. - * - * To do the flag fast, we use the engine qname to qflag the font, - * but also the font description to flag the engine. This is - * supposed to be fast to check, but also avoid writing out - * duplicate warnings when a new PangoFont is created. + * font. */ - GType engine_type = G_OBJECT_TYPE (analysis->shape_engine); - GQuark warned_quark = g_type_qname (engine_type); + GQuark warned_quark = g_quark_from_static_string ("pango-shape-fail-warned"); if (!g_object_get_qdata (G_OBJECT (analysis->font), warned_quark)) { - PangoFontDescription *desc; - char *font_name; - const char *engine_name; - - desc = pango_font_describe (analysis->font); - font_name = pango_font_description_to_string (desc); - pango_font_description_free (desc); - - if (!g_object_get_data (G_OBJECT (analysis->shape_engine), font_name)) - { - engine_name = g_type_name (engine_type); - if (!engine_name) - engine_name = "(unknown)"; + PangoFontDescription *desc; + char *font_name; - g_warning ("shaping failure, expect ugly output. shape-engine='%s', font='%s', text='%.*s'", - engine_name, font_name, item_length, item_text); + desc = pango_font_describe (analysis->font); + font_name = pango_font_description_to_string (desc); + pango_font_description_free (desc); - g_object_set_data_full (G_OBJECT (analysis->shape_engine), font_name, - GINT_TO_POINTER (1), NULL); - } + g_warning ("shaping failure, expect ugly output. font='%s', text='%.*s'", + font_name, item_length, item_text); - g_free (font_name); + g_free (font_name); - g_object_set_qdata_full (G_OBJECT (analysis->font), warned_quark, - GINT_TO_POINTER (1), NULL); - } + g_object_set_qdata (G_OBJECT (analysis->font), warned_quark, + GINT_TO_POINTER (1)); + } } } else @@ -171,12 +205,7 @@ pango_shape_full (const gchar *item_text, if (G_UNLIKELY (!glyphs->num_glyphs)) { - PangoEngineShape *fallback_engine = _pango_get_fallback_shaper (); - - _pango_engine_shape_shape (fallback_engine, analysis->font, - item_text, item_length, - paragraph_text, paragraph_length, - analysis, glyphs); + fallback_shape (item_text, item_length, analysis, glyphs); if (G_UNLIKELY (!glyphs->num_glyphs)) return; } @@ -210,24 +239,7 @@ pango_shape_full (const gchar *item_text, if (G_UNLIKELY ((analysis->level & 1) && glyphs->log_clusters[0] < glyphs->log_clusters[glyphs->num_glyphs - 1])) { - /* Warn once per shaper */ - static GQuark warned_quark = 0; /* MT-safe */ - - if (!warned_quark) - warned_quark = g_quark_from_static_string ("pango-shape-warned"); - - if (analysis->shape_engine && !g_object_get_qdata (G_OBJECT (analysis->shape_engine), warned_quark)) - { - GType engine_type = G_OBJECT_TYPE (analysis->shape_engine); - const char *engine_name = g_type_name (engine_type); - if (!engine_name) - engine_name = "(unknown)"; - - g_warning ("Expected RTL run but shape-engine='%s' returned LTR. Fixing.", engine_name); - - g_object_set_qdata_full (G_OBJECT (analysis->shape_engine), warned_quark, - GINT_TO_POINTER (1), NULL); - } + g_warning ("Expected RTL run but got LTR. Fixing."); /* *Fix* it so we don't crash later */ pango_glyph_string_reverse_range (glyphs, 0, glyphs->num_glyphs); |