From 3286fc0e9adc3f2874c9409e7fdb09e4d2b7dda1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 16 Mar 2011 14:53:32 -0300 Subject: [PATCH] Let hb_shape() guess script and direction... - Rename HB_SCRIPT_INVALID_CODE to HB_SCRIPT_INVALID - Add HB_DIRECTION_INVALID - Make hb_script_get_horizontal_direction() public - Make hb_shape() guess script from buffer text (first non-common non-inherit script) if buffer script is set to HB_SCRIPT_INVALID (this is NOT the default.) - Make hb_shape() guess direction from buffer script if buffer direction is set to HB_DIRECTION_INVALID (this is NOT the default.) - Make hb-view.c set INVALID script and direction on the buffer. The above changes are meant to make hb-view fairly useful for uni-script uni-direction text. The guessing behavior however is NOT the default of hb_shape() and must be asked for explicitly. This is intended, because the guess is not a suitable substitute to full-fledged bidi and script segmentation. It's just a testing tool. --- src/hb-common.h | 3 ++- src/hb-icu.c | 2 +- src/hb-ot-shape.cc | 3 ++- src/hb-shape.cc | 52 +++++++++++++++++++++++++++++++++++----- src/hb-unicode-private.h | 4 ---- src/hb-unicode.c | 2 +- src/hb-unicode.h | 8 ++++++- src/hb-view.c | 4 ++-- 8 files changed, 61 insertions(+), 17 deletions(-) diff --git a/src/hb-common.h b/src/hb-common.h index 1dd02cbdd..ebb10b3c7 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -78,7 +78,8 @@ typedef uint32_t hb_mask_t; typedef void (*hb_destroy_func_t) (void *user_data); typedef enum _hb_direction_t { - HB_DIRECTION_LTR, + HB_DIRECTION_INVALID = -1, + HB_DIRECTION_LTR = 0, HB_DIRECTION_RTL, HB_DIRECTION_TTB, HB_DIRECTION_BTT diff --git a/src/hb-icu.c b/src/hb-icu.c index 601ef611d..49230dfce 100644 --- a/src/hb-icu.c +++ b/src/hb-icu.c @@ -118,7 +118,7 @@ hb_icu_get_script (hb_codepoint_t unicode) U_ICU_VERSION_MAJOR_NUM > (major) || (U_ICU_VERSION_MAJOR_NUM == (major) && U_ICU_VERSION_MINOR_NUM >= (minor)) #define MATCH_SCRIPT(C) case USCRIPT_##C: return HB_SCRIPT_##C #define MATCH_SCRIPT2(C1, C2) case USCRIPT_##C1: return HB_SCRIPT_##C2 - MATCH_SCRIPT (INVALID_CODE); + MATCH_SCRIPT (COMMON); /* Zyyy */ MATCH_SCRIPT (INHERITED); /* Qaai */ MATCH_SCRIPT (ARABIC); /* Arab */ diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 92c392558..e6b3f3e1c 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -64,6 +64,7 @@ hb_ot_shape_collect_features (hb_ot_shape_plan_t *plan, break; case HB_DIRECTION_TTB: case HB_DIRECTION_BTT: + case HB_DIRECTION_INVALID: default: break; } @@ -170,7 +171,7 @@ hb_ensure_native_direction (hb_ot_shape_context_t *c) /* TODO vertical */ if (HB_DIRECTION_IS_HORIZONTAL (direction) && - direction != _hb_script_get_horizontal_direction (c->buffer->props.script)) + direction != hb_script_get_horizontal_direction (c->buffer->props.script)) { hb_buffer_reverse_clusters (c->buffer); c->buffer->props.direction = HB_DIRECTION_REVERSE (c->buffer->props.direction); diff --git a/src/hb-shape.cc b/src/hb-shape.cc index a73977b46..0a6f1dc56 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -39,12 +39,12 @@ HB_BEGIN_DECLS -void -hb_shape (hb_font_t *font, - hb_face_t *face, - hb_buffer_t *buffer, - hb_feature_t *features, - unsigned int num_features) +static void +hb_shape_internal (hb_font_t *font, + hb_face_t *face, + hb_buffer_t *buffer, + hb_feature_t *features, + unsigned int num_features) { #if 0 && defined(HAVE_GRAPHITE) hb_blob_t *silf_blob; @@ -61,5 +61,45 @@ hb_shape (hb_font_t *font, hb_ot_shape (font, face, buffer, features, num_features); } +void +hb_shape (hb_font_t *font, + hb_face_t *face, + hb_buffer_t *buffer, + hb_feature_t *features, + unsigned int num_features) +{ + hb_segment_properties_t orig_props; + + orig_props = buffer->props; + + /* If script is set to INVALID, guess from buffer contents */ + if (buffer->props.script == HB_SCRIPT_INVALID) { + hb_unicode_get_script_func_t get_script = buffer->unicode->v.get_script; + unsigned int count = buffer->len; + for (unsigned int i = 0; i < count; i++) { + hb_script_t script = get_script (buffer->info[i].codepoint); + if (likely (script > HB_SCRIPT_INHERITED)) { + buffer->props.script = script; + break; + } + } + } + + /* If direction is set to INVALID, guess from script */ + if (buffer->props.direction == HB_DIRECTION_INVALID) { + buffer->props.direction = hb_script_get_horizontal_direction (buffer->props.script); + } + + /* If language is not set, use default language from locale */ + if (buffer->props.language == NULL) { + /* TODO get_default_for_script? using $LANGUAGE */ + //buffer->props.language = hb_language_get_default (); + } + + hb_shape_internal (font, face, buffer, features, num_features); + + buffer->props = orig_props; +} + HB_END_DECLS diff --git a/src/hb-unicode-private.h b/src/hb-unicode-private.h index 419404b87..52d1b9b0b 100644 --- a/src/hb-unicode-private.h +++ b/src/hb-unicode-private.h @@ -55,10 +55,6 @@ struct _hb_unicode_funcs_t { extern HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_nil; -HB_INTERNAL hb_direction_t -_hb_script_get_horizontal_direction (hb_script_t script); - - HB_END_DECLS #endif /* HB_UNICODE_PRIVATE_H */ diff --git a/src/hb-unicode.c b/src/hb-unicode.c index 2ab308b69..98b7bc52a 100644 --- a/src/hb-unicode.c +++ b/src/hb-unicode.c @@ -352,7 +352,7 @@ const hb_direction_t horiz_dir[] = #undef RTL hb_direction_t -_hb_script_get_horizontal_direction (hb_script_t script) +hb_script_get_horizontal_direction (hb_script_t script) { if (unlikely ((unsigned int) script >= ARRAY_LENGTH (horiz_dir))) return HB_DIRECTION_LTR; diff --git a/src/hb-unicode.h b/src/hb-unicode.h index 43b04ca99..7b1393114 100644 --- a/src/hb-unicode.h +++ b/src/hb-unicode.h @@ -70,7 +70,8 @@ typedef enum /* Unicode Script property */ typedef enum { /* ISO 15924 code */ - HB_SCRIPT_INVALID_CODE = -1, + HB_SCRIPT_INVALID = -1, + HB_SCRIPT_COMMON = 0, /* Zyyy */ HB_SCRIPT_INHERITED, /* Qaai */ HB_SCRIPT_ARABIC, /* Arab */ @@ -289,6 +290,11 @@ hb_unicode_get_eastasian_width (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); +/* Misc functions */ + +hb_direction_t +hb_script_get_horizontal_direction (hb_script_t script); + HB_END_DECLS #endif /* HB_UNICODE_H */ diff --git a/src/hb-view.c b/src/hb-view.c index 5c0c48c8b..b5fb6704c 100644 --- a/src/hb-view.c +++ b/src/hb-view.c @@ -184,8 +184,8 @@ _hb_cr_text_glyphs (cairo_t *cr, hb_buffer_set_unicode_funcs (hb_buffer, hb_glib_get_unicode_funcs ()); hb_buffer_add_utf8 (hb_buffer, text, len, 0, len); - /* hb_buffer_set_script (hb_buffer, HB_SCRIPT_LATIN); */ - /* hb_buffer_set_direction (hb_buffer, HB_DIRECTION_LTR); */ + hb_buffer_set_script (hb_buffer, HB_SCRIPT_INVALID); + hb_buffer_set_direction (hb_buffer, HB_DIRECTION_INVALID); hb_buffer_set_language (hb_buffer, hb_language_from_string (language)); hb_shape (hb_font, hb_face, hb_buffer, NULL, 0);