diff options
-rw-r--r-- | pango/fonts.c | 10 | ||||
-rw-r--r-- | pango/meson.build | 2 | ||||
-rw-r--r-- | pango/pango-context.c | 124 | ||||
-rw-r--r-- | pango/pango-font-private.h | 3 | ||||
-rw-r--r-- | pango/pango-font.h | 2 | ||||
-rw-r--r-- | pango/pango-item.h | 4 | ||||
-rw-r--r-- | pango/pangocoretext.c | 41 | ||||
-rw-r--r-- | pango/pangofc-font.c | 45 | ||||
-rw-r--r-- | pango/pangofc-private.h | 9 | ||||
-rw-r--r-- | pango/pangofc-shape.c | 77 | ||||
-rw-r--r-- | pango/pangohb-private.h | 41 | ||||
-rw-r--r-- | pango/pangowin32.c | 44 | ||||
-rw-r--r-- | pango/shape.c | 134 | ||||
-rw-r--r-- | tests/test-shape.c | 4 |
14 files changed, 170 insertions, 370 deletions
diff --git a/pango/fonts.c b/pango/fonts.c index 10e5463d..2cfab161 100644 --- a/pango/fonts.c +++ b/pango/fonts.c @@ -1720,20 +1720,14 @@ pango_font_get_coverage (PangoFont *font, * language tag and character point. * * Return value: (transfer none): the best matching shaper. + * Deprecated: Shape engines are no longer used **/ PangoEngineShape * pango_font_find_shaper (PangoFont *font, PangoLanguage *language, guint32 ch) { - PangoEngineShape* shaper; - - if (G_UNLIKELY (!font)) - return NULL; - - shaper = PANGO_FONT_GET_CLASS (font)->find_shaper (font, language, ch); - - return shaper; + return NULL; } /** diff --git a/pango/meson.build b/pango/meson.build index 4ca062ec..cfbf8a9a 100644 --- a/pango/meson.build +++ b/pango/meson.build @@ -26,6 +26,7 @@ pango_sources = [ 'pango-utils.c', 'reorder-items.c', 'shape.c', + 'pangofc-shape.c', ] pango_headers = [ @@ -175,7 +176,6 @@ if build_pangoft2 'pangofc-font.c', 'pangofc-fontmap.c', 'pangofc-decoder.c', - 'pangofc-shape.c', 'pangoft2.c', ] diff --git a/pango/pango-context.c b/pango/pango-context.c index 44f3c3c0..1f31c268 100644 --- a/pango/pango-context.c +++ b/pango/pango-context.c @@ -617,7 +617,7 @@ advance_attr_iterator_to (PangoAttrIterator *iterator, } /*************************************************************************** - * We cache the results of character,fontset => font,shaper in a hash table + * We cache the results of character,fontset => font in a hash table ***************************************************************************/ typedef struct { @@ -650,7 +650,7 @@ get_font_cache (PangoFontset *fontset) static GQuark cache_quark = 0; /* MT-safe */ if (G_UNLIKELY (!cache_quark)) - cache_quark = g_quark_from_static_string ("pango-shaper-font-cache"); + cache_quark = g_quark_from_static_string ("pango-font-cache"); retry: cache = g_object_get_qdata (G_OBJECT (fontset), cache_quark); @@ -1137,46 +1137,39 @@ copy_attr_slist (GSList *attr_slist) } static void -itemize_state_fill_shaper (ItemizeState *state, - PangoEngineShape *shape_engine, - PangoFont *font) +itemize_state_fill_font (ItemizeState *state, + PangoFont *font) { GList *l; for (l = state->result; l; l = l->next) { PangoItem *item = l->data; - if (item->analysis.shape_engine) - break; + if (item->analysis.font) + break; if (font) item->analysis.font = g_object_ref (font); - else - item->analysis.font = NULL; - item->analysis.shape_engine = shape_engine; } } static void -itemize_state_add_character (ItemizeState *state, - PangoEngineShape *shape_engine, - PangoFont *font, - gboolean force_break, - const char *pos) +itemize_state_add_character (ItemizeState *state, + PangoFont *font, + gboolean force_break, + const char *pos) { if (state->item) { - if (!state->item->analysis.shape_engine && shape_engine) + if (!state->item->analysis.font && font) { - itemize_state_fill_shaper (state, shape_engine, font); + itemize_state_fill_font (state, font); } - else if (state->item->analysis.shape_engine && !shape_engine) + else if (state->item->analysis.font && !font) { font = state->item->analysis.font; - shape_engine = state->item->analysis.shape_engine; } if (!force_break && - state->item->analysis.shape_engine == shape_engine && state->item->analysis.font == font) { state->item->num_chars++; @@ -1190,7 +1183,6 @@ itemize_state_add_character (ItemizeState *state, state->item->offset = pos - state->text; state->item->length = 0; state->item->num_chars = 1; - state->item->analysis.shape_engine = shape_engine; if (font) g_object_ref (font); @@ -1289,36 +1281,17 @@ get_base_font (ItemizeState *state) return state->base_font; } -static PangoScript -get_script (ItemizeState *state) -{ - /* Always use a basic shaper for vertical layout (ie, east/west gravity) - * as none of our script shapers support vertical shaping right now. - * - * XXX Should move the knowledge into the shaper interface. - */ - - if (PANGO_GRAVITY_IS_VERTICAL (state->resolved_gravity)) - return PANGO_SCRIPT_COMMON; - else - return state->script; -} - static gboolean -get_shaper_and_font (ItemizeState *state, - gunichar wc, - PangoEngineShape **shape_engine, - PangoFont **font) +get_font (ItemizeState *state, + gunichar wc, + PangoFont **font) { GetFontInfo info; /* We'd need a separate cache when fallback is disabled, but since lookup * with fallback disabled is faster anyways, we just skip caching */ if (state->enable_fallback && font_cache_get (state->cache, wc, font)) - { - *shape_engine = pango_font_find_shaper (*font, state->derived_lang, wc); return TRUE; - } info.lang = state->derived_lang; info.wc = wc; @@ -1330,7 +1303,6 @@ get_shaper_and_font (ItemizeState *state, get_font_foreach (NULL, get_base_font (state), &info); *font = info.font; - *shape_engine = pango_font_find_shaper (*font, state->derived_lang, wc); /* skip caching if fallback disabled (see above) */ if (state->enable_fallback) @@ -1444,21 +1416,6 @@ itemize_state_update_for_new_run (ItemizeState *state) } } -static const char * -string_from_script (PangoScript script) -{ - static GEnumClass *class = NULL; /* MT-safe */ - GEnumValue *value; - if (g_once_init_enter (&class)) - g_once_init_leave(&class, (gpointer)g_type_class_ref (G_TYPE_UNICODE_SCRIPT)); - - value = g_enum_get_value (class, script); - if (!value) - return string_from_script (PANGO_SCRIPT_INVALID_CODE); - - return value->value_nick; -} - static void itemize_state_process_run (ItemizeState *state) { @@ -1480,7 +1437,6 @@ itemize_state_process_run (ItemizeState *state) { gunichar wc = g_utf8_get_char (p); gboolean is_forced_break = (wc == '\t' || wc == LINE_SEPARATOR); - PangoEngineShape *shape_engine; PangoFont *font; GUnicodeType type; @@ -1506,16 +1462,14 @@ itemize_state_process_run (ItemizeState *state) (wc >= 0xfe00u && wc <= 0xfe0fu) || (wc >= 0xe0100u && wc <= 0xe01efu))) { - shape_engine = NULL; font = NULL; } else { - get_shaper_and_font (state, wc, &shape_engine, &font); + get_font (state, wc, &font); } - itemize_state_add_character (state, - shape_engine, font, + itemize_state_add_character (state, font, is_forced_break || last_was_forced_break, p); @@ -1524,34 +1478,28 @@ itemize_state_process_run (ItemizeState *state) /* Finish the final item from the current segment */ state->item->length = (p - state->text) - state->item->offset; - if (!state->item->analysis.shape_engine) + if (!state->item->analysis.font) { - PangoEngineShape *shape_engine; PangoFont *font; - if (G_UNLIKELY (!get_shaper_and_font (state, ' ', &shape_engine, &font))) - { - /* If no shaper was found, warn only once per fontmap/script pair */ - PangoFontMap *fontmap = state->context->font_map; - const char *script_name = string_from_script (get_script (state)); - - if (!g_object_get_data (G_OBJECT (fontmap), script_name)) - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - g_warning ("failed to choose a font, expect ugly output. engine-type='%s', script='%s'", - pango_font_map_get_shape_engine_type (fontmap), - script_name); -G_GNUC_END_IGNORE_DEPRECATIONS - - g_object_set_data_full (G_OBJECT (fontmap), script_name, - GINT_TO_POINTER (1), NULL); - } - - shape_engine = _pango_get_fallback_shaper (); - font = NULL; - } + if (G_UNLIKELY (!get_font (state, ' ', &font))) + { + /* If no font was found, warn once per fontmap/script pair */ + PangoFontMap *fontmap = state->context->font_map; + const char *script_name = g_enum_to_string (G_TYPE_UNICODE_SCRIPT, state->script); + + if (!g_object_get_data (G_OBJECT (fontmap), script_name)) + { + g_warning ("failed to choose a font, expect ugly output. script='%s'", + script_name); - itemize_state_fill_shaper (state, shape_engine, font); + g_object_set_data_full (G_OBJECT (fontmap), script_name, + GINT_TO_POINTER (1), NULL); + } + + font = NULL; + } + itemize_state_fill_font (state, font); } state->item = NULL; } diff --git a/pango/pango-font-private.h b/pango/pango-font-private.h index 029bef99..8817bc02 100644 --- a/pango/pango-font-private.h +++ b/pango/pango-font-private.h @@ -164,9 +164,6 @@ struct _PangoFontClass PangoFontDescription *(*describe) (PangoFont *font); PangoCoverage * (*get_coverage) (PangoFont *font, PangoLanguage *language); - PangoEngineShape * (*find_shaper) (PangoFont *font, - PangoLanguage *language, - guint32 ch); void (*get_glyph_extents) (PangoFont *font, PangoGlyph glyph, PangoRectangle *ink_rect, diff --git a/pango/pango-font.h b/pango/pango-font.h index cec7efc6..ec4a7dea 100644 --- a/pango/pango-font.h +++ b/pango/pango-font.h @@ -470,7 +470,7 @@ PangoFontDescription *pango_font_describe_with_absolute_size (PangoFont * PANGO_AVAILABLE_IN_ALL PangoCoverage * pango_font_get_coverage (PangoFont *font, PangoLanguage *language); -PANGO_AVAILABLE_IN_ALL +PANGO_DEPRECATED_IN_1_44 PangoEngineShape * pango_font_find_shaper (PangoFont *font, PangoLanguage *language, guint32 ch); diff --git a/pango/pango-item.h b/pango/pango-item.h index 55be4c67..2a7bcb2a 100644 --- a/pango/pango-item.h +++ b/pango/pango-item.h @@ -52,8 +52,8 @@ typedef struct _PangoItem PangoItem; /** * PangoAnalysis: - * @shape_engine: the engine for doing rendering-system-dependent processing. - * @lang_engine: the engine for doing rendering-system-independent processing. + * @shape_engine: unused + * @lang_engine: unused * @font: the font for this segment. * @level: the bidirectional level for this segment. * @gravity: the glyph orientation for this segment (A #PangoGravity). diff --git a/pango/pangocoretext.c b/pango/pangocoretext.c index 5faac64c..4975ade2 100644 --- a/pango/pangocoretext.c +++ b/pango/pangocoretext.c @@ -161,46 +161,6 @@ pango_core_text_font_get_coverage (PangoFont *font, return pango_coverage_ref (priv->coverage); } -/* Wrap shaper in PangoEngineShape to pass it through old API, - * from times when there were modules and engines. */ -typedef PangoEngineShape PangoCoreTextShapeEngine; -typedef PangoEngineShapeClass PangoCoreTextShapeEngineClass; -static GType pango_core_text_shape_engine_get_type (void) G_GNUC_CONST; -G_DEFINE_TYPE (PangoCoreTextShapeEngine, pango_core_text_shape_engine, PANGO_TYPE_ENGINE_SHAPE); -static void -_pango_core_text_shape_engine_shape (PangoEngineShape *engine G_GNUC_UNUSED, - PangoFont *font, - const char *item_text, - unsigned int item_length, - const PangoAnalysis *analysis, - PangoGlyphString *glyphs, - const char *paragraph_text, - unsigned int paragraph_length) -{ - _pango_core_text_shape (font, item_text, item_length, analysis, glyphs, - paragraph_text, paragraph_length); -} -static void -pango_core_text_shape_engine_class_init (PangoEngineShapeClass *class) -{ - class->script_shape = _pango_core_text_shape_engine_shape; -} -static void -pango_core_text_shape_engine_init (PangoEngineShape *object) -{ -} - -static PangoEngineShape * -pango_core_text_font_find_shaper (PangoFont *font, - PangoLanguage *language G_GNUC_UNUSED, - guint32 ch) -{ - static PangoEngineShape *shaper; - if (g_once_init_enter (&shaper)) - g_once_init_leave (&shaper, g_object_new (pango_core_text_shape_engine_get_type(), NULL)); - return shaper; -} - static PangoFontMap * pango_core_text_font_get_font_map (PangoFont *font) { @@ -246,7 +206,6 @@ pango_core_text_font_class_init (PangoCoreTextFontClass *class) font_class->describe = pango_core_text_font_describe; /* font_class->describe_absolute is left virtual for PangoCairoCoreTextFont. */ font_class->get_coverage = pango_core_text_font_get_coverage; - font_class->find_shaper = pango_core_text_font_find_shaper; font_class->get_font_map = pango_core_text_font_get_font_map; font_class->create_hb_font = pango_core_text_font_create_hb_font; } diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c index 22f6df0c..17119436 100644 --- a/pango/pangofc-font.c +++ b/pango/pangofc-font.c @@ -42,7 +42,6 @@ #include "pangofc-font-private.h" #include "pangofc-fontmap.h" #include "pangofc-private.h" -#include "pango-engine.h" #include "pango-layout.h" #include "pango-impl-utils.h" @@ -76,9 +75,6 @@ static void pango_fc_font_get_property (GObject *objec guint prop_id, GValue *value, GParamSpec *pspec); -static PangoEngineShape * pango_fc_font_find_shaper (PangoFont *font, - PangoLanguage *language, - guint32 ch); static PangoCoverage * pango_fc_font_get_coverage (PangoFont *font, PangoLanguage *language); static PangoFontMetrics * pango_fc_font_get_metrics (PangoFont *font, @@ -113,7 +109,6 @@ pango_fc_font_class_init (PangoFcFontClass *class) object_class->get_property = pango_fc_font_get_property; font_class->describe = pango_fc_font_describe; font_class->describe_absolute = pango_fc_font_describe_absolute; - font_class->find_shaper = pango_fc_font_find_shaper; font_class->get_coverage = pango_fc_font_get_coverage; font_class->get_metrics = pango_fc_font_get_metrics; font_class->get_font_map = pango_fc_font_get_font_map; @@ -297,46 +292,6 @@ pango_fc_font_describe_absolute (PangoFont *font) return desc; } -/* Wrap shaper in PangoEngineShape to pass it through old API, - * from times when there were modules and engines. */ -typedef PangoEngineShape PangoFcShapeEngine; -typedef PangoEngineShapeClass PangoFcShapeEngineClass; -static GType pango_fc_shape_engine_get_type (void) G_GNUC_CONST; -G_DEFINE_TYPE (PangoFcShapeEngine, pango_fc_shape_engine, PANGO_TYPE_ENGINE_SHAPE); -static void -_pango_fc_shape_engine_shape (PangoEngineShape *engine G_GNUC_UNUSED, - PangoFont *font, - const char *item_text, - unsigned int item_length, - const PangoAnalysis *analysis, - PangoGlyphString *glyphs, - const char *paragraph_text, - unsigned int paragraph_length) -{ - _pango_fc_shape (font, item_text, item_length, analysis, glyphs, - paragraph_text, paragraph_length); -} -static void -pango_fc_shape_engine_class_init (PangoEngineShapeClass *class) -{ - class->script_shape = _pango_fc_shape_engine_shape; -} -static void -pango_fc_shape_engine_init (PangoEngineShape *object) -{ -} - -static PangoEngineShape * -pango_fc_font_find_shaper (PangoFont *font G_GNUC_UNUSED, - PangoLanguage *language, - guint32 ch) -{ - static PangoEngineShape *shaper; - if (g_once_init_enter (&shaper)) - g_once_init_leave (&shaper, g_object_new (pango_fc_shape_engine_get_type(), NULL)); - return shaper; -} - static PangoCoverage * pango_fc_font_get_coverage (PangoFont *font, PangoLanguage *language G_GNUC_UNUSED) diff --git a/pango/pangofc-private.h b/pango/pangofc-private.h index 8d281ad8..27b96df4 100644 --- a/pango/pangofc-private.h +++ b/pango/pangofc-private.h @@ -78,15 +78,6 @@ _PANGO_EXTERN PangoFontMetrics *pango_fc_font_create_base_metrics_for_context (PangoFcFont *font, PangoContext *context); -void -_pango_fc_shape (PangoFont *font, - const char *item_text, - unsigned int item_length, - const PangoAnalysis *analysis, - PangoGlyphString *glyphs, - const char *paragraph_text, - unsigned int paragraph_length); - G_END_DECLS #endif /* __PANGOFC_PRIVATE_H__ */ diff --git a/pango/pangofc-shape.c b/pango/pangofc-shape.c index 59b90c40..910ff4d7 100644 --- a/pango/pangofc-shape.c +++ b/pango/pangofc-shape.c @@ -26,10 +26,9 @@ #include <string.h> #include <math.h> -#include "pangofc-private.h" -#include "pangofc-font-private.h" -#include "pangofc-fontmap-private.h" -#include <hb-ft.h> +#include "pangohb-private.h" +#include "pango-impl-utils.h" + #include <hb-glib.h> /* cache a single hb_buffer_t */ @@ -114,13 +113,13 @@ apply_extra_attributes (GSList *attrs, } void -_pango_fc_shape (PangoFont *font, - const char *item_text, - unsigned int item_length, - const PangoAnalysis *analysis, - PangoGlyphString *glyphs, - const char *paragraph_text, - unsigned int paragraph_length) +pango_hb_shape (PangoFont *font, + const char *item_text, + unsigned int item_length, + const PangoAnalysis *analysis, + PangoGlyphString *glyphs, + const char *paragraph_text, + unsigned int paragraph_length) { hb_font_t *hb_font; hb_buffer_t *hb_buffer; @@ -202,61 +201,5 @@ _pango_fc_shape (PangoFont *font, hb_position++; } - if (PANGO_IS_FC_FONT (font)) - { - PangoFcFont *fc_font = PANGO_FC_FONT (font); - if (fc_font->is_hinted) - { - double x_scale_inv, y_scale_inv; - double x_scale, y_scale; - PangoFcFontKey *key; - - x_scale_inv = y_scale_inv = 1.0; - key = _pango_fc_font_get_font_key (fc_font); - if (key) - { - const PangoMatrix *matrix = pango_fc_font_key_get_matrix (key); - pango_matrix_get_font_scale_factors (matrix, &x_scale_inv, &y_scale_inv); - } - if (PANGO_GRAVITY_IS_IMPROPER (analysis->gravity)) - { - x_scale_inv = -x_scale_inv; - y_scale_inv = -y_scale_inv; - } - x_scale = 1. / x_scale_inv; - y_scale = 1. / y_scale_inv; - - if (x_scale == 1.0 && y_scale == 1.0) - { - for (i = 0; i < num_glyphs; i++) - infos[i].geometry.width = PANGO_UNITS_ROUND (infos[i].geometry.width); - } - else - { -#if 0 - if (PANGO_GRAVITY_IS_VERTICAL (analysis->gravity)) - { - /* XXX */ - double tmp = x_scale; - x_scale = y_scale; - y_scale = -tmp; - } -#endif -#define HINT(value, scale_inv, scale) (PANGO_UNITS_ROUND ((int) ((value) * scale)) * scale_inv) -#define HINT_X(value) HINT ((value), x_scale, x_scale_inv) -#define HINT_Y(value) HINT ((value), y_scale, y_scale_inv) - for (i = 0; i < num_glyphs; i++) - { - infos[i].geometry.width = HINT_X (infos[i].geometry.width); - infos[i].geometry.x_offset = HINT_X (infos[i].geometry.x_offset); - infos[i].geometry.y_offset = HINT_Y (infos[i].geometry.y_offset); - } -#undef HINT_Y -#undef HINT_X -#undef HINT - } - } - } - release_buffer (hb_buffer, free_buffer); } diff --git a/pango/pangohb-private.h b/pango/pangohb-private.h new file mode 100644 index 00000000..217bdb28 --- /dev/null +++ b/pango/pangohb-private.h @@ -0,0 +1,41 @@ +/* Pango + * pangohb-private.h: Private routines for using harfbuzz + * + * Copyright (C) 2019 Red Hat Software + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __PANGOHB_PRIVATE_H__ +#define __PANGOHB_PRIVATE_H__ + +#include <pango-font.h> +#include <pango-item.h> +#include <pango-glyph.h> + +G_BEGIN_DECLS + +void pango_hb_shape (PangoFont *font, + const char *item_text, + unsigned int item_length, + const PangoAnalysis *analysis, + PangoGlyphString *glyphs, + const char *paragraph_text, + unsigned int paragraph_length); + +G_END_DECLS + +#endif /* __PANGOHB_PRIVATE_H__ */ diff --git a/pango/pangowin32.c b/pango/pangowin32.c index 32f050e2..86c698d1 100644 --- a/pango/pangowin32.c +++ b/pango/pangowin32.c @@ -62,9 +62,6 @@ static PangoCoverage *pango_win32_font_get_coverage (PangoFont static void pango_win32_font_calc_coverage (PangoFont *font, PangoCoverage *coverage, PangoLanguage *lang); -static PangoEngineShape *pango_win32_font_find_shaper (PangoFont *font, - PangoLanguage *lang, - guint32 ch); static void pango_win32_font_get_glyph_extents (PangoFont *font, PangoGlyph glyph, PangoRectangle *ink_rect, @@ -206,7 +203,6 @@ _pango_win32_font_class_init (PangoWin32FontClass *class) font_class->describe = pango_win32_font_describe; font_class->describe_absolute = pango_win32_font_describe_absolute; font_class->get_coverage = pango_win32_font_get_coverage; - font_class->find_shaper = pango_win32_font_find_shaper; font_class->get_glyph_extents = pango_win32_font_get_glyph_extents; font_class->get_metrics = pango_win32_font_get_metrics; font_class->get_font_map = pango_win32_font_get_font_map; @@ -938,46 +934,6 @@ pango_win32_font_get_coverage (PangoFont *font, return coverage; } -/* Wrap shaper in PangoEngineShape to pass it through old API, - * from times when there were modules and engines. */ -typedef PangoEngineShape PangoWin32ShapeEngine; -typedef PangoEngineShapeClass PangoWin32ShapeEngineClass; -static GType pango_win32_shape_engine_get_type (void) G_GNUC_CONST; -G_DEFINE_TYPE (PangoWin32ShapeEngine, pango_win32_shape_engine, PANGO_TYPE_ENGINE_SHAPE); -static void -_pango_win32_shape_engine_shape (PangoEngineShape *engine G_GNUC_UNUSED, - PangoFont *font, - const char *item_text, - unsigned int item_length, - const PangoAnalysis *analysis, - PangoGlyphString *glyphs, - const char *paragraph_text, - unsigned int paragraph_length) -{ - _pango_win32_shape (font, item_text, item_length, analysis, glyphs, - paragraph_text, paragraph_length); -} -static void -pango_win32_shape_engine_class_init (PangoEngineShapeClass *class) -{ - class->script_shape = _pango_win32_shape_engine_shape; -} -static void -pango_win32_shape_engine_init (PangoEngineShape *object) -{ -} - -static PangoEngineShape * -pango_win32_font_find_shaper (PangoFont *font, - PangoLanguage *lang, - guint32 ch) -{ - static PangoEngineShape *shaper; - if (g_once_init_enter (&shaper)) - g_once_init_leave (&shaper, g_object_new (pango_win32_shape_engine_get_type(), NULL)); - return shaper; -} - /* Utility functions */ /** diff --git a/pango/shape.c b/pango/shape.c index 1d056f6c..14078e47 100644 --- a/pango/shape.c +++ b/pango/shape.c @@ -35,6 +35,8 @@ #include "pango-glyph.h" #include "pango-engine-private.h" +#include "pangohb-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_hb_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); diff --git a/tests/test-shape.c b/tests/test-shape.c index acce5a03..1cf52044 100644 --- a/tests/test-shape.c +++ b/tests/test-shape.c @@ -294,6 +294,10 @@ main (int argc, char *argv[]) path = g_test_build_filename (G_TEST_DIST, "shape", NULL); dir = g_dir_open (path, 0, &error); g_free (path); + + if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + return 0; + g_assert_no_error (error); while ((name = g_dir_read_name (dir)) != NULL) { |