diff -u pango1.0-1.28.0/debian/changelog pango1.0-1.28.0/debian/changelog --- pango1.0-1.28.0/debian/changelog +++ pango1.0-1.28.0/debian/changelog @@ -1,3 +1,11 @@ +pango1.0 (1.28.0-0ubuntu3~ppa1) lucid; urgency=low + + * Patch for indic-rendering issues (cleaned up code to comply with glib) Telugu, Kannada and other languages(maybe) + - Bugs fixed: + Bug 579398 - [te_IN] Incorrect akhand formation for U+0C15,U+0C3E,U+0C37,U+0C47 + Bug 604060 -[kn_IN] Pango doesn't render 0c95+0ccd+0c95+0c97 combination properly + + -- Arjuna Rao Chavala Wed, 19 Aug 2010 11:50:00 +0530 pango1.0 (1.28.0-0ubuntu2) lucid; urgency=low * debian/control.in: diff -u pango1.0-1.28.0/debian/libpango1.0-0.symbols pango1.0-1.28.0/debian/libpango1.0-0.symbols --- pango1.0-1.28.0/debian/libpango1.0-0.symbols +++ pango1.0-1.28.0/debian/libpango1.0-0.symbols @@ -511,6 +511,7 @@ pango_ot_ruleset_new_from_description@Base 1.18.0 pango_ot_ruleset_position@Base 1.14.0 pango_ot_ruleset_substitute@Base 1.14.0 + pango_ot_ruleset_substitute_syl@Base 1.28.0 pango_ot_tag_from_language@Base 1.18.0 pango_ot_tag_from_script@Base 1.18.0 pango_ot_tag_to_language@Base 1.18.0 only in patch2: unchanged: --- pango1.0-1.28.0.orig/pango/pango-ot-info.c +++ pango1.0-1.28.0/pango/pango-ot-info.c @@ -23,6 +23,7 @@ #include "pango-ot-private.h" #include "pango-impl-utils.h" + #include FT_TRUETYPE_TABLES_H static void pango_ot_info_class_init (GObjectClass *object_class); @@ -562,6 +563,76 @@ } } + +void +_pango_ot_info_substitute_syl (const PangoOTInfo *info, + const PangoOTRuleset *ruleset, + PangoOTBuffer *buffer, const GArray *sylindices) +{ + unsigned int i; + gint j,syllength=0,sylstart=0,isylstart=0,isyllength=0; + hb_buffer_t *sylbuf=NULL, *outbuf=NULL; + hb_direction_t direction; + direction=hb_buffer_get_direction (buffer->buffer); +for (j=0;j<(*sylindices).len; j++) { + syllength= g_array_index (sylindices,gint ,j)-sylstart; +//create sylbuf and outbuf + sylbuf= hb_buffer_create (32); + hb_buffer_set_direction (sylbuf,direction); + if (j==0) { + outbuf= hb_buffer_create (32); + hb_buffer_set_direction (outbuf,direction); + } +//copy from input buffer + hb_buffer_copy(buffer->buffer,sylbuf,sylstart,syllength); +//code for usual substitute logic but with sylbuf + for (i = 0; i < ruleset->rules->len; i++) + { + PangoOTRule *rule = &g_array_index (ruleset->rules, PangoOTRule, i); + hb_mask_t mask; + unsigned int lookup_count, j; + unsigned int lookup_indexes[1000]; + + if (rule->table_type != PANGO_OT_TABLE_GSUB) + continue; + + mask = rule->property_bit; + lookup_count = G_N_ELEMENTS (lookup_indexes); + hb_ot_layout_feature_get_lookup_indexes (info->hb_face, + HB_OT_TAG_GSUB, + rule->feature_index, + &lookup_count, + lookup_indexes); + + lookup_count = MIN (G_N_ELEMENTS (lookup_indexes), lookup_count); + for (j = 0; j < lookup_count; j++) + hb_ot_layout_substitute_lookup (info->hb_face, + sylbuf, + lookup_indexes[j], + rule->property_bit); + } +//update outbuf + isylstart=0; + isyllength=hb_buffer_get_len (sylbuf); + hb_buffer_copy(sylbuf,outbuf,isylstart,isyllength); + + hb_buffer_destroy (sylbuf); + sylstart=g_array_index(sylindices,gint, j); +} + //copy outbuf to inbuf + if (outbuf!=NULL) { + +//free local buffers + hb_buffer_clear (buffer->buffer); + hb_buffer_set_direction (buffer->buffer,direction); + isylstart=0; + isyllength=hb_buffer_get_len (outbuf); + hb_buffer_copy(outbuf,buffer->buffer,isylstart,isyllength); + hb_buffer_destroy (outbuf); + + } +} + void _pango_ot_info_position (const PangoOTInfo *info, const PangoOTRuleset *ruleset, only in patch2: unchanged: --- pango1.0-1.28.0.orig/pango/pango-ot-private.h +++ pango1.0-1.28.0/pango/pango-ot-private.h @@ -23,7 +23,6 @@ #define __PANGO_OT_PRIVATE_H__ #include - #include #include "opentype/hb-ot.h" #include "opentype/hb-glib.h" @@ -92,6 +91,9 @@ void _pango_ot_info_substitute (const PangoOTInfo *info, const PangoOTRuleset *ruleset, PangoOTBuffer *buffer); +void _pango_ot_info_substitute_syl (const PangoOTInfo *info, + const PangoOTRuleset *ruleset, + PangoOTBuffer *buffer, const GArray *sylindices); void _pango_ot_info_position (const PangoOTInfo *info, const PangoOTRuleset *ruleset, PangoOTBuffer *buffer); only in patch2: unchanged: --- pango1.0-1.28.0.orig/pango/pango-ot.h +++ pango1.0-1.28.0/pango/pango-ot.h @@ -176,6 +176,8 @@ guint *n_gpos_features); void pango_ot_ruleset_substitute (const PangoOTRuleset *ruleset, PangoOTBuffer *buffer); +void pango_ot_ruleset_substitute_syl (const PangoOTRuleset *ruleset, + PangoOTBuffer *buffer, const GArray *sylindices); void pango_ot_ruleset_position (const PangoOTRuleset *ruleset, PangoOTBuffer *buffer); PangoScript pango_ot_tag_to_script (PangoOTTag script_tag) G_GNUC_CONST; @@ -189,7 +191,7 @@ PangoOTRulesetDescription *pango_ot_ruleset_description_copy (const PangoOTRulesetDescription *desc); void pango_ot_ruleset_description_free (PangoOTRulesetDescription *desc); - + #endif /* PANGO_ENABLE_ENGINE */ G_END_DECLS only in patch2: unchanged: --- pango1.0-1.28.0.orig/pango/pangoft2.def +++ pango1.0-1.28.0/pango/pangoft2.def @@ -79,6 +79,7 @@ pango_ot_ruleset_new_from_description pango_ot_ruleset_position pango_ot_ruleset_substitute + pango_ot_ruleset_substitute_syl pango_ot_tag_from_language pango_ot_tag_from_script pango_ot_tag_to_language only in patch2: unchanged: --- pango1.0-1.28.0.orig/pango/pango-ot-ruleset.c +++ pango1.0-1.28.0/pango/pango-ot-ruleset.c @@ -491,6 +491,26 @@ } /** + * pango_ot_ruleset_substitute_syl: + * @ruleset: a #PangoOTRuleset. + * @buffer: a #PangoOTBuffer. + * + * Performs the OpenType GSUB substitution on @buffer using the features + * in @ruleset + * + * Since: 1.28.X + **/ +void +pango_ot_ruleset_substitute_syl (const PangoOTRuleset *ruleset, + PangoOTBuffer *buffer, const GArray *sylindices) +{ + g_return_if_fail (PANGO_IS_OT_RULESET (ruleset)); + g_return_if_fail (ruleset->info != NULL); + +// _pango_ot_info_substitute (ruleset->info, ruleset, buffer); + _pango_ot_info_substitute_syl (ruleset->info, ruleset, buffer, sylindices); +} +/** * pango_ot_ruleset_position: * @ruleset: a #PangoOTRuleset. * @buffer: a #PangoOTBuffer. only in patch2: unchanged: --- pango1.0-1.28.0.orig/pango/opentype/hb-buffer.c +++ pango1.0-1.28.0/pango/opentype/hb-buffer.c @@ -179,7 +179,11 @@ buffer->direction = direction; } - +hb_direction_t +hb_buffer_get_direction (hb_buffer_t *buffer) +{ + return buffer->direction ; +} /* HarfBuzz-Internal API */ void @@ -514,3 +518,63 @@ ADD_UTF (uint32_t); #undef UTF_NEXT } + +//does not use already defined copy operations, as we want raw copy +void +hb_buffer_copy(hb_buffer_t *srcbuf,hb_buffer_t *destbuf, gint sylstart, gint syllength) +{ + gint i=0; + i=sylstart; + hb_internal_glyph_info_t *srcglyph,*destglyph; + hb_glyph_position_t *srcglyph_pos,*destglyph_pos; + while (iin_string[i]; +//ensure space for glyph + hb_buffer_ensure (destbuf, destbuf->in_length + 1); + destglyph = &destbuf->in_string[destbuf->in_length]; + destglyph_pos=hb_buffer_get_glyph_positions (destbuf); + destglyph_pos+=destbuf->in_length; + destbuf->in_length++; +//copy glyph info + _hb_buffer_copy_glyph (srcglyph, destglyph,destbuf->max_lig_id); +//copy glyph position + srcglyph_pos=hb_buffer_get_glyph_positions (srcbuf); + srcglyph_pos+=i; + if(srcglyph_pos!=NULL && destglyph_pos!=NULL) + hb_buffer_copy_glyph_pos(srcglyph_pos,destglyph_pos); + i++; + } +_hb_buffer_copy_flags(srcbuf, destbuf); +} + +void +_hb_buffer_copy_glyph (hb_internal_glyph_info_t *srcglyph,hb_internal_glyph_info_t *destglyph, gint prevbuf_max_lig_id) +{ + destglyph->codepoint = srcglyph->codepoint; + destglyph->mask = srcglyph->mask; + destglyph->cluster = srcglyph->cluster; + destglyph->component = srcglyph->component; + if(srcglyph->lig_id>0) + destglyph->lig_id = srcglyph->lig_id+prevbuf_max_lig_id; + else + destglyph->lig_id = srcglyph->lig_id; + destglyph->gproperty = srcglyph->gproperty; +} +void + hb_buffer_copy_glyph_pos (hb_glyph_position_t *srcglyph_pos, hb_glyph_position_t *destglyph_pos) +{ + destglyph_pos->x_pos = srcglyph_pos->x_pos; + destglyph_pos->y_pos = srcglyph_pos->y_pos; + destglyph_pos->x_advance = srcglyph_pos->x_advance; + destglyph_pos->y_advance = srcglyph_pos->y_advance; + destglyph_pos->new_advance = srcglyph_pos->new_advance; + destglyph_pos->cursive_chain= srcglyph_pos->cursive_chain; + destglyph_pos->x_pos = srcglyph_pos->x_pos; +} +//to update dest buffer flags +void +_hb_buffer_copy_flags(hb_buffer_t *srcbuf, hb_buffer_t *destbuf) +{ + destbuf->have_output = destbuf->have_output|srcbuf->have_output; + destbuf->max_lig_id += srcbuf->max_lig_id; +} \ No newline at end of file only in patch2: unchanged: --- pango1.0-1.28.0.orig/pango/opentype/hb-buffer.h +++ pango1.0-1.28.0/pango/opentype/hb-buffer.h @@ -146,7 +146,11 @@ hb_glyph_position_t * hb_buffer_get_glyph_positions (hb_buffer_t *buffer); - +//addl functions for syllable level buffer GSUBs +void +hb_buffer_copy(hb_buffer_t *srcbuffer, hb_buffer_t *destbuf, int isylstart, int isyllength); +void +hb_buffer_copy_glyph_pos (hb_glyph_position_t *srcglyph_pos, hb_glyph_position_t *destglyph_pos); HB_END_DECLS #endif /* HB_BUFFER_H */ only in patch2: unchanged: --- pango1.0-1.28.0.orig/pango/opentype/hb-buffer-private.h +++ pango1.0-1.28.0/pango/opentype/hb-buffer-private.h @@ -130,6 +130,11 @@ #define OUT_GLYPH(pos) (buffer->out_string[(pos)].codepoint) #define OUT_INFO(pos) (&buffer->out_string[(pos)]) +void +_hb_buffer_copy_glyph (hb_internal_glyph_info_t *srcglyph, hb_internal_glyph_info_t *destglyph,gint prevbuf_max_lig_id); +void +_hb_buffer_copy_flags(hb_buffer_t *srcbuffer,hb_buffer_t *destbuf); + HB_END_DECLS #endif /* HB_BUFFER_PRIVATE_H */ only in patch2: unchanged: --- pango1.0-1.28.0.orig/modules/indic/indic-ot.h +++ pango1.0-1.28.0/modules/indic/indic-ot.h @@ -230,6 +230,7 @@ glong indic_ot_find_syllable(const IndicOTClassTable *class_table, const gunichar *chars, glong prev, glong char_count); glong indic_ot_reorder(const gunichar *chars, const glong *utf8_offsets, glong char_count, const IndicOTClassTable *class_table, gunichar *out_chars, glong *char_indices, gulong *char_tags, MPreFixups **outMPreFixups); +glong indic_ot_reorder_syl(const gunichar *chars, const glong *utf8_offsets, glong char_count, const IndicOTClassTable *class_table, gunichar *out_chars, glong *char_indices, gulong *char_tags, MPreFixups **outMPreFixups, GArray **sylindices); #endif /* PANGO_ENABLE_ENGINE */ only in patch2: unchanged: --- pango1.0-1.28.0.orig/modules/indic/indic-fc.c +++ pango1.0-1.28.0/modules/indic/indic-fc.c @@ -24,7 +24,7 @@ #include "config.h" #include - +#include #include "indic-ot.h" #include "pango-engine.h" @@ -227,7 +227,7 @@ glong *indices = NULL; IndicEngineFc *indic_shape_engine = NULL; MPreFixups *mprefixups; - + GArray *sylindices=NULL; g_return_if_fail (font != NULL); g_return_if_fail (text != NULL); g_return_if_fail (length >= 0); @@ -242,18 +242,21 @@ wc_in = expand_text (text, length, &utf8_offsets, &n_chars); - n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_shape_engine->classTable, NULL, NULL, NULL, NULL); +// n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_shape_engine->classTable, NULL, NULL, NULL, NULL); + n_glyphs = indic_ot_reorder_syl (wc_in, utf8_offsets, n_chars, indic_shape_engine->classTable, NULL, NULL, NULL, NULL,NULL); wc_out = g_new (gunichar, n_glyphs); indices = g_new (glong, n_glyphs); tags = g_new (gulong, n_glyphs); - - n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_shape_engine->classTable, wc_out, indices, tags, &mprefixups); + sylindices= g_array_new (FALSE, TRUE, sizeof (gint)); +// n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_shape_engine->classTable, wc_out, indices, tags, &mprefixups); + n_glyphs = indic_ot_reorder_syl (wc_in, utf8_offsets, n_chars, indic_shape_engine->classTable, wc_out, indices, tags, &mprefixups,&sylindices); pango_glyph_string_set_size (glyphs, n_glyphs); buffer = pango_ot_buffer_new (fc_font); pango_ot_buffer_set_rtl (buffer, analysis->level % 2 != 0); + set_glyphs(font, wc_out, tags, n_glyphs, buffer, (indic_shape_engine->classTable->scriptFlags & SF_PROCESS_ZWJ) != 0); @@ -272,15 +275,14 @@ ruleset = pango_ot_ruleset_get_for_description (pango_ot_info_get (face), &desc); /* do gsub processing */ - pango_ot_ruleset_substitute (ruleset, buffer); +// pango_ot_ruleset_substitute (ruleset, buffer); + pango_ot_ruleset_substitute_syl (ruleset, buffer, sylindices); - /* Fix pre-modifiers for some scripts before base consonant */ - if (mprefixups) + if (mprefixups) { indic_mprefixups_apply (mprefixups, buffer); indic_mprefixups_free (mprefixups); } - /* do gpos processing */ pango_ot_ruleset_position (ruleset, buffer); @@ -293,6 +295,7 @@ pango_fc_font_unlock_face (fc_font); pango_ot_buffer_destroy (buffer); + g_array_free(sylindices,TRUE); g_free (tags); g_free (indices); g_free (wc_out); only in patch2: unchanged: --- pango1.0-1.28.0.orig/modules/indic/indic-ot.c +++ pango1.0-1.28.0/modules/indic/indic-ot.c @@ -31,11 +31,13 @@ * use or other dealings in this Software without prior written * authorization of the copyright holder. */ - +#include #include "config.h" #include "indic-ot.h" #include "mprefixups.h" + + /* * FIXME: should the IndicOutput stuff be moved * to a separate .h and .c file just to keep the @@ -519,3 +521,321 @@ return getOutputIndex(&output); } + +/* syllable indices capture version of indic_ot_reorder */ +glong indic_ot_reorder_syl(const gunichar *chars, const glong *utf8_offsets, glong char_count, const IndicOTClassTable *class_table, gunichar *out_chars, glong *char_indices, gulong *char_tags, MPreFixups **outMPreFixups, GArray **sylindices) +{ + MPreFixups *mpreFixups = NULL; + Output output; + glong i, prev = 0; + gboolean last_in_word = FALSE; + gint extraction_call=0, countsyl=0; + gint outindex=0; + if( out_chars!=NULL) extraction_call=1; + if (outMPreFixups && (class_table->scriptFlags & SF_MPRE_FIXUP)) { + mpreFixups = indic_mprefixups_new (char_count); + } + + initOutput(&output, utf8_offsets, out_chars, char_indices, char_tags, mpreFixups); + + while (prev < char_count) { + glong syllable = indic_ot_find_syllable(class_table, chars, prev, char_count); + + glong matra, vmabove, vmpost = syllable; + + while (vmpost > prev && indic_ot_is_vm_post(class_table, chars[vmpost - 1])) { + vmpost -= 1; + } + + vmabove = vmpost; + while (vmabove > prev && indic_ot_is_vm_above(class_table, chars[vmabove - 1])) { + vmabove -= 1; + } + + matra = vmabove - 1; + initMatra(&output, prev, blwf_p, !last_in_word); + while (noteMatra(&output, class_table, chars[matra]) && + matra != prev) + matra--; + + last_in_word = TRUE; + switch (indic_ot_get_char_class(class_table, chars[prev]) & CF_CLASS_MASK) { + case CC_RESERVED: + last_in_word = FALSE; + /* Fall through */ + case CC_INDEPENDENT_VOWEL: + case CC_ZERO_WIDTH_MARK: + for (i = prev; i < syllable; i += 1) { + writeChar(&output, chars[i], /*i*/ prev, blwf_p); + } + + break; + + case CC_MODIFYING_MARK_ABOVE: + case CC_MODIFYING_MARK_POST: + case CC_NUKTA: + case CC_VIRAMA: + /* patch for rendering fix for Malayalam SAMVRUTHOKARA by suresh */ + if (chars[prev - 1] == 0x0D41) { + writeChar(&output, chars[prev], prev, blwf_p); + break; + } + /* end patch */ + + case CC_AL_LAKUNA: + writeChar(&output, C_DOTTED_CIRCLE, prev, blwf_p); + writeChar(&output, chars[prev], prev, blwf_p); + break; + + case CC_DEPENDENT_VOWEL: + writeMpre(&output); + writeChar(&output, C_DOTTED_CIRCLE, prev, blwf_p); + writeMbelow(&output); + writeMabove(&output); + writeMpost(&output); + writeLengthMark(&output); + writeAlLakuna(&output); + break; + + case CC_CONSONANT: + case CC_CONSONANT_WITH_NUKTA: + { + guint32 length = vmabove - prev; + glong lastConsonant = vmabove - 1; + glong baseLimit = prev; + glong baseConsonant, postBase, postBaseLimit; + gboolean seenVattu, seenBelowBaseForm, supressVattu; + glong bcSpan; + + /* Check for REPH at front of syllable */ + if (length > 2 && indic_ot_is_reph(class_table, chars[prev]) && indic_ot_is_virama(class_table, chars[prev + 1])) { + baseLimit += 2; + + /* Check for eyelash RA, if the script supports it */ + if ((class_table->scriptFlags & SF_EYELASH_RA) != 0 && + chars[baseLimit] == C_SIGN_ZWJ) { + if (length > 3) { + baseLimit += 1; + } else { + baseLimit -= 2; + } + } + } + + while (lastConsonant > baseLimit && !indic_ot_is_consonant(class_table, chars[lastConsonant])) { + lastConsonant -= 1; + } + + baseConsonant = lastConsonant; + postBase = lastConsonant + 1; + + postBaseLimit = class_table->scriptFlags & SF_POST_BASE_LIMIT_MASK; + seenVattu = false; + seenBelowBaseForm = false; + supressVattu = true; + + while (baseConsonant > baseLimit) { + IndicOTCharClass charClass = indic_ot_get_char_class(class_table, chars[baseConsonant]); + + if (IS_CONSONANT(charClass)) { + if (postBaseLimit == 0 || seenVattu || + (baseConsonant > baseLimit && !indic_ot_is_virama(class_table, chars[baseConsonant - 1])) || + !HAS_POST_OR_BELOW_BASE_FORM(charClass)) { + break; + } + + seenVattu = IS_VATTU(charClass); + + if (HAS_POST_BASE_FORM(charClass)) { + if (seenBelowBaseForm) { + break; + } + + postBase = baseConsonant; + } else if (HAS_BELOW_BASE_FORM(charClass)) { + seenBelowBaseForm = true; + } + + postBaseLimit -= 1; + } + + baseConsonant -= 1; + } + + /* Write Mpre */ + writeMpre(&output); + + /* Write eyelash RA */ + /* NOTE: baseLimit == prev + 3 iff eyelash RA present... */ + if (baseLimit == prev + 3) { + writeChar(&output, chars[prev], prev, half_p); + writeChar(&output, chars[prev + 1], prev /*+ 1*/, half_p); + writeChar(&output, chars[prev + 2], prev /*+ 2*/, half_p); + } + + /* write any pre-base consonants */ + supressVattu = true; + + for (i = baseLimit; i < baseConsonant; i += 1) { + gunichar ch = chars[i]; + /* Applying blwf to the first consonant doesn't makes sense + * since the below-form follows the consonant that it is + * put under */ + gulong tag = (i == baseLimit) ? half_p : blwf_p; + IndicOTCharClass charClass = indic_ot_get_char_class(class_table, ch); + + if (IS_CONSONANT(charClass)) { + if (IS_VATTU(charClass) && supressVattu) { + tag = nukt_p; + } + else if ((i + 2 < baseConsonant) && (chars[i + 2] == C_SIGN_ZWNJ)) { + tag = nukt_p; + } + + supressVattu = IS_VATTU(charClass); + } else if (IS_VIRAMA(charClass) && chars[i + 1] == C_SIGN_ZWNJ) + { + tag = nukt_p; + } + + writeChar(&output, ch, /*i*/ prev, tag); + } + + bcSpan = baseConsonant + 1; + + if (bcSpan < vmabove && indic_ot_is_nukta(class_table, chars[bcSpan])) { + bcSpan += 1; + } + + if (baseConsonant == lastConsonant && bcSpan < vmabove && indic_ot_is_virama(class_table, chars[bcSpan])) { + bcSpan += 1; + + if (bcSpan < vmabove && chars[bcSpan] == C_SIGN_ZWNJ) { + bcSpan += 1; + } + } + + /* note the base consonant for post-GSUB fixups */ + noteBaseConsonant(&output); + + /* write base consonant */ + for (i = baseConsonant; i < bcSpan; i += 1) { + writeChar(&output, chars[i], /*i*/ prev, nukt_p); + } + + if ((class_table->scriptFlags & SF_MATRAS_AFTER_BASE) != 0) { + gboolean is_for_0C48 = FALSE; + if (output.fOutChars != NULL) { /*for 0x0C48 of Telugu*/ + int t; + for (t = prev; t < syllable; t++) { + if (chars[t] == 0x0C48) { + writeMabove(&output); + writeMbelow(&output); + writeMpost(&output); + + is_for_0C48 = TRUE; + break; + } + } + } + + if (!is_for_0C48) { + writeMbelow(&output); + writeMabove(&output); + writeMpost(&output); + } + } + + /* write below-base consonants */ + if (baseConsonant != lastConsonant) { + for (i = bcSpan + 1; i < postBase; i += 1) { + writeChar(&output, chars[i], /*i*/ prev, blwf_p); + } + + if (postBase > lastConsonant) { + /* write halant that was after base consonant */ + writeChar(&output, chars[bcSpan], /*bcSpan*/ prev, blwf_p); + } + } + + /* write Mbelow, Mabove */ + if ((class_table->scriptFlags & SF_MATRAS_AFTER_BASE) == 0) { + writeMbelow(&output); + writeMabove(&output); + } + + if ((class_table->scriptFlags & SF_REPH_AFTER_BELOW) != 0) { + if (baseLimit == prev + 2) { + writeChar(&output, chars[prev], prev, rphf_p); + writeChar(&output, chars[prev + 1], prev /*+ 1*/, rphf_p); + } + + /* write VMabove */ + for (i = vmabove; i < vmpost; i += 1) { + writeChar(&output, chars[i], /*i*/ prev, blwf_p); + } + } + + /* write post-base consonants */ + if (baseConsonant != lastConsonant) { + if (postBase <= lastConsonant) { + for (i = postBase; i <= lastConsonant; i += 1) { + writeChar(&output, chars[i], /*i*/ prev, pstf_p); + } + + /* write halant that was after base consonant */ + writeChar(&output, chars[bcSpan], /*bcSpan*/ prev, blwf_p); + } + + /* write the training halant, if there is one */ + if (lastConsonant < matra && indic_ot_is_virama(class_table, chars[matra])) { + writeChar(&output, chars[matra], /*matra*/ prev, nukt_p); + } + } + + /* write Mpost */ + if ((class_table->scriptFlags & SF_MATRAS_AFTER_BASE) == 0) { + writeMpost(&output); + } + + writeLengthMark(&output); + writeAlLakuna(&output); + + /* write reph */ + if ((class_table->scriptFlags & SF_REPH_AFTER_BELOW) == 0) { + if (baseLimit == prev + 2) { + writeChar(&output, chars[prev], prev, rphf_p); + writeChar(&output, chars[prev + 1], prev /*+ 1*/, rphf_p); + } + + /* write VMabove */ + for (i = vmabove; i < vmpost; i += 1) { + writeChar(&output, chars[i], /*i*/ prev, blwf_p); + } + } + + /* write VMpost */ + for (i = vmpost; i < syllable; i += 1) { + writeChar(&output, chars[i], /*i*/ prev, blwf_p); + } + + break; + } + + default: + break; + } + if (extraction_call) { + countsyl++; + outindex= getOutputIndex(&output); + *sylindices=g_array_append_val(*sylindices,outindex); + } + prev = syllable; + } + + if (outMPreFixups) { + *outMPreFixups = mpreFixups; + } + + return getOutputIndex(&output); +}