Index: modules/indic/indic-ot.c
===================================================================
--- modules/indic/indic-ot.c	(revision 1)
+++ modules/indic/indic-ot.c	(working copy)
@@ -31,11 +31,13 @@
  * use or other dealings in this Software without prior written
  * authorization of the copyright holder.
  */
-
+#include <glib.h>
 #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);
+}
Index: modules/indic/indic-ot.h
===================================================================
--- modules/indic/indic-ot.h	(revision 1)
+++ modules/indic/indic-ot.h	(working copy)
@@ -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 */
 
Index: modules/indic/indic-fc.c
===================================================================
--- modules/indic/indic-fc.c	(revision 1)
+++ modules/indic/indic-fc.c	(working copy)
@@ -24,7 +24,7 @@
 #include "config.h"
 
 #include <string.h>
-
+#include <glib.h>
 #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);
+  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);
 
-  n_glyphs  = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_shape_engine->classTable, wc_out, indices, tags, &mprefixups);
-
   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);
Index: pango/pango-ot-ruleset.c
===================================================================
--- pango/pango-ot-ruleset.c	(revision 1)
+++ pango/pango-ot-ruleset.c	(working copy)
@@ -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.
Index: pango/opentype/hb-buffer.c
===================================================================
--- pango/opentype/hb-buffer.c	(revision 1)
+++ pango/opentype/hb-buffer.c	(working copy)
@@ -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 (i<sylstart+syllength) {
+  srcglyph=&srcbuf->in_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
Index: pango/opentype/hb-buffer.h
===================================================================
--- pango/opentype/hb-buffer.h	(revision 1)
+++ pango/opentype/hb-buffer.h	(working copy)
@@ -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 */
Index: pango/opentype/hb-buffer-private.h
===================================================================
--- pango/opentype/hb-buffer-private.h	(revision 1)
+++ pango/opentype/hb-buffer-private.h	(working copy)
@@ -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 */
Index: pango/pango-ot.h
===================================================================
--- pango/pango-ot.h	(revision 1)
+++ pango/pango-ot.h	(working copy)
@@ -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
Index: pango/pangoft2.def
===================================================================
--- pango/pangoft2.def	(revision 1)
+++ pango/pangoft2.def	(working copy)
@@ -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
Index: pango/pango-ot-private.h
===================================================================
--- pango/pango-ot-private.h	(revision 1)
+++ pango/pango-ot-private.h	(working copy)
@@ -23,7 +23,6 @@
 #define __PANGO_OT_PRIVATE_H__
 
 #include <glib-object.h>
-
 #include <pango/pango-ot.h>
 #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);
Index: pango/pango-ot-info.c
===================================================================
--- pango/pango-ot-info.c	(revision 1)
+++ pango/pango-ot-info.c	(working copy)
@@ -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,7 +563,77 @@
     }
 }
 
+
 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,
 			    PangoOTBuffer        *buffer)
