diff --git a/src/Makefile.am b/src/Makefile.am index 13107b9..b68d14b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -52,6 +52,7 @@ HBSOURCES += \ hb-ot-shape.cc \ hb-ot-shape-complex-arabic.cc \ hb-ot-shape-complex-arabic-table.h \ + hb-ot-shape-complex-mongolian.cc \ hb-ot-shape-complex-private.hh \ hb-ot-shape-private.hh \ hb-ot-tag.c \ diff --git a/src/hb-ot-shape-complex-mongolian.cc b/src/hb-ot-shape-complex-mongolian.cc new file mode 100644 index 0000000..5406917 --- /dev/null +++ b/src/hb-ot-shape-complex-mongolian.cc @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2010 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Erdene-Ochir Tuguldur + */ + +#include "hb-ot-shape-complex-private.hh" + +HB_BEGIN_DECLS + + +/* buffer var allocations */ +#define mongolian_shaping_action() var2.u32 /* mongolian shaping action */ + + +/* + * Bits used in the joining tables + */ +enum { + JOINING_TYPE_U = 0, // non joining + /* We don't have JOINING_TYPE_L and JOINING_TYPE_R since mongolian letters are dual joining. */ + JOINING_TYPE_D = 1, + JOINING_TYPE_C = JOINING_TYPE_D, + NUM_STATE_MACHINE_COLS = 2, + JOINING_TYPE_T = 3 +}; + +/* + * Joining types: + */ + +static unsigned int get_joining_type (hb_codepoint_t u, hb_category_t gen_cat) +{ + if (likely (0x1800 <= u && u <= 0x18AA)) { + if (likely (u == 0x1807 || u == 0x180A)) { + /* sibe syllable boundary marker and mongolian niragu */ + return JOINING_TYPE_D; + } + if (likely (0x180B <= u && u <= 0x180D)) { + /* mongolian free variation selectors */ + return JOINING_TYPE_T; + } + if (likely (0x1820 <= u && u <= 0x1877)) { + /* letters */ + return JOINING_TYPE_D; + } + if (likely (0x1880 <= u && u <= 0x18AA)) { + /* Ali Gali letters */ + return JOINING_TYPE_D; + } + return JOINING_TYPE_U; + } + + if (unlikely ((u & ~(0x200C^0x200D)) == 0x200C)) { + return u == 0x200C ? JOINING_TYPE_U : JOINING_TYPE_C; + } + + return ((1<map.add_bool_feature (mongolian_features[i], false); +} + +void +_hb_ot_shape_complex_setup_masks_mongolian (hb_ot_shape_context_t *c) +{ + unsigned int count = c->buffer->len; + unsigned int prev = 0, state = 0; + + for (unsigned int i = 0; i < count; i++) + { + unsigned int this_type = get_joining_type (c->buffer->info[i].codepoint, (hb_category_t) c->buffer->info[i].general_category()); + + if (unlikely (this_type == JOINING_TYPE_T)) { + c->buffer->info[i].mongolian_shaping_action() = NONE; + continue; + } + + const mongolian_state_table_entry *entry = &mongolian_state_table[state][this_type]; + + if (entry->prev_action != NONE) + c->buffer->info[prev].mongolian_shaping_action() = entry->prev_action; + + c->buffer->info[i].mongolian_shaping_action() = entry->curr_action; + + prev = i; + state = entry->next_state; + } + + hb_mask_t mask_array[TOTAL_NUM_FEATURES + 1] = {0}; + for (unsigned int i = 0; i < NUM_FEATURES; i++) + mask_array[i] = c->plan->map.get_1_mask (mongolian_features[i]); + + for (unsigned int i = 0; i < count; i++) + c->buffer->info[i].mask |= mask_array[c->buffer->info[i].mongolian_shaping_action()]; +} + + +HB_END_DECLS diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh index a3796b4..55d0fd6 100644 --- a/src/hb-ot-shape-complex-private.hh +++ b/src/hb-ot-shape-complex-private.hh @@ -42,6 +42,8 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props) case HB_SCRIPT_NKO: case HB_SCRIPT_SYRIAC: return hb_ot_complex_shaper_arabic; + case HB_SCRIPT_MONGOLIAN: + return hb_ot_complex_shaper_mongolian; default: return hb_ot_complex_shaper_none; @@ -58,7 +60,8 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props) * Shapers should use plan->map to add their features. */ -HB_INTERNAL void _hb_ot_shape_complex_collect_features_arabic (hb_ot_shape_plan_t *plan, const hb_segment_properties_t *props); +HB_INTERNAL void _hb_ot_shape_complex_collect_features_arabic (hb_ot_shape_plan_t *plan, const hb_segment_properties_t *props); +HB_INTERNAL void _hb_ot_shape_complex_collect_features_mongolian (hb_ot_shape_plan_t *plan, const hb_segment_properties_t *props); static inline void hb_ot_shape_complex_collect_features (hb_ot_shape_plan_t *plan, @@ -66,6 +69,7 @@ hb_ot_shape_complex_collect_features (hb_ot_shape_plan_t *plan, { switch (plan->shaper) { case hb_ot_complex_shaper_arabic: _hb_ot_shape_complex_collect_features_arabic (plan, props); return; + case hb_ot_complex_shaper_mongolian: _hb_ot_shape_complex_collect_features_mongolian (plan, props); return; case hb_ot_complex_shaper_none: default: return; } } @@ -79,12 +83,14 @@ hb_ot_shape_complex_collect_features (hb_ot_shape_plan_t *plan, */ HB_INTERNAL void _hb_ot_shape_complex_setup_masks_arabic (hb_ot_shape_context_t *c); +HB_INTERNAL void _hb_ot_shape_complex_setup_masks_mongolian (hb_ot_shape_context_t *c); static inline void hb_ot_shape_complex_setup_masks (hb_ot_shape_context_t *c) { switch (c->plan->shaper) { - case hb_ot_complex_shaper_arabic: _hb_ot_shape_complex_setup_masks_arabic (c); return; + case hb_ot_complex_shaper_arabic: _hb_ot_shape_complex_setup_masks_arabic (c); return; + case hb_ot_complex_shaper_mongolian: _hb_ot_shape_complex_setup_masks_mongolian (c); return; case hb_ot_complex_shaper_none: default: return; } } diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh index deaec97..20370b9 100644 --- a/src/hb-ot-shape-private.hh +++ b/src/hb-ot-shape-private.hh @@ -43,7 +43,8 @@ HB_BEGIN_DECLS enum hb_ot_complex_shaper_t { hb_ot_complex_shaper_none, - hb_ot_complex_shaper_arabic + hb_ot_complex_shaper_arabic, + hb_ot_complex_shaper_mongolian };