michael@0: /* michael@0: * Copyright © 2011,2012 Google, Inc. michael@0: * michael@0: * This is part of HarfBuzz, a text shaping library. michael@0: * michael@0: * Permission is hereby granted, without written agreement and without michael@0: * license or royalty fees, to use, copy, modify, and distribute this michael@0: * software and its documentation for any purpose, provided that the michael@0: * above copyright notice and the following two paragraphs appear in michael@0: * all copies of this software. michael@0: * michael@0: * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR michael@0: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES michael@0: * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN michael@0: * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH michael@0: * DAMAGE. michael@0: * michael@0: * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, michael@0: * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND michael@0: * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS michael@0: * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO michael@0: * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. michael@0: * michael@0: * Google Author(s): Behdad Esfahbod michael@0: */ michael@0: michael@0: #ifndef HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH michael@0: #define HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH michael@0: michael@0: #include "hb-private.hh" michael@0: michael@0: %%{ michael@0: machine indic_syllable_machine; michael@0: alphtype unsigned char; michael@0: write data; michael@0: }%% michael@0: michael@0: %%{ michael@0: michael@0: # Same order as enum indic_category_t. Not sure how to avoid duplication. michael@0: X = 0; michael@0: C = 1; michael@0: V = 2; michael@0: N = 3; michael@0: H = 4; michael@0: ZWNJ = 5; michael@0: ZWJ = 6; michael@0: M = 7; michael@0: SM = 8; michael@0: VD = 9; michael@0: A = 10; michael@0: NBSP = 11; michael@0: DOTTEDCIRCLE = 12; michael@0: RS = 13; michael@0: Coeng = 14; michael@0: Repha = 15; michael@0: Ra = 16; michael@0: CM = 17; michael@0: Avag = 18; michael@0: CM2 = 31; michael@0: michael@0: c = (C | Ra); # is_consonant michael@0: n = ((ZWNJ?.RS)? (N.N?)?); # is_consonant_modifier michael@0: z = ZWJ|ZWNJ; # is_joiner michael@0: h = H | Coeng; # is_halant_or_coeng michael@0: reph = (Ra H | Repha); # possible reph michael@0: michael@0: cn = c.ZWJ?.n?; michael@0: forced_rakar = ZWJ H ZWJ Ra; michael@0: avagraha = Avag.N?; michael@0: matra_group = z{0,3}.M.N?.(H | forced_rakar)?; michael@0: syllable_tail2 = (SM.SM?.ZWNJ?)? (A.A?)? VD?; michael@0: syllable_tail = (Coeng (cn|V))? avagraha? syllable_tail2; michael@0: place_holder = NBSP | DOTTEDCIRCLE; michael@0: halant_group = (z?.h.(ZWJ.N?)?); michael@0: final_halant_group = halant_group | h.ZWNJ; michael@0: medial_group = CM?.CM2?; michael@0: halant_or_matra_group = (final_halant_group | (h.ZWJ)? matra_group{0,4}); michael@0: michael@0: michael@0: consonant_syllable = Repha? (cn.halant_group){0,4} cn medial_group halant_or_matra_group syllable_tail; michael@0: vowel_syllable = reph? V.n? (ZWJ | (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail); michael@0: standalone_cluster = reph? place_holder.n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail; michael@0: avagraha_cluster = avagraha syllable_tail2; michael@0: broken_cluster = reph? n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail; michael@0: other = any; michael@0: michael@0: main := |* michael@0: consonant_syllable => { found_syllable (consonant_syllable); }; michael@0: vowel_syllable => { found_syllable (vowel_syllable); }; michael@0: standalone_cluster => { found_syllable (standalone_cluster); }; michael@0: avagraha_cluster => { found_syllable (avagraha_cluster); }; michael@0: broken_cluster => { found_syllable (broken_cluster); }; michael@0: other => { found_syllable (non_indic_cluster); }; michael@0: *|; michael@0: michael@0: michael@0: }%% michael@0: michael@0: #define found_syllable(syllable_type) \ michael@0: HB_STMT_START { \ michael@0: if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ michael@0: for (unsigned int i = last; i < p+1; i++) \ michael@0: info[i].syllable() = (syllable_serial << 4) | syllable_type; \ michael@0: last = p+1; \ michael@0: syllable_serial++; \ michael@0: if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ michael@0: } HB_STMT_END michael@0: michael@0: static void michael@0: find_syllables (hb_buffer_t *buffer) michael@0: { michael@0: unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; michael@0: int cs; michael@0: hb_glyph_info_t *info = buffer->info; michael@0: %%{ michael@0: write init; michael@0: getkey info[p].indic_category(); michael@0: }%% michael@0: michael@0: p = 0; michael@0: pe = eof = buffer->len; michael@0: michael@0: unsigned int last = 0; michael@0: unsigned int syllable_serial = 1; michael@0: %%{ michael@0: write exec; michael@0: }%% michael@0: } michael@0: michael@0: #endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */