Index: basic/basic-xft.c
===================================================================
RCS file: /cvs/gnome/pango/modules/basic/basic-xft.c,v
retrieving revision 1.11
diff -u -r1.11 basic-xft.c
--- basic/basic-xft.c	26 Jul 2002 23:12:53 -0000	1.11
+++ basic/basic-xft.c	25 Oct 2002 01:10:25 -0000
@@ -37,7 +37,8 @@
   { 0x10a0, 0x10ff, "*" }, /* Georgian */
   { 0x1200, 0x16ff, "*" }, /* Ethiopic,Cherokee,Canadian,Ogham,Runic */
   { 0x1e00, 0x1fff, "*" },
-  { 0x2000, 0x9fff, "*" },
+  { 0x2000, 0x302d, "*" },
+  { 0x3030, 0x9fff, "*" },
   { 0xac00, 0xd7a3, "kr" },
   { 0xf900, 0xfa0b, "kr" },
   { 0xff00, 0xffe3, "*" },
Index: hangul/hangul-defs.h
===================================================================
RCS file: /cvs/gnome/pango/modules/hangul/hangul-defs.h,v
retrieving revision 1.1
diff -u -r1.1 hangul-defs.h
--- hangul/hangul-defs.h	31 Jul 2002 19:08:14 -0000	1.1
+++ hangul/hangul-defs.h	25 Oct 2002 01:10:25 -0000
@@ -46,9 +46,14 @@
 #define VFILL 0x1160
 #define TFILL 0x11A7
 
+#define HTONE1 0x302E
+#define HTONE2 0x302F
+
 #define IS_L(wc) (wc >= LBASE && wc <= LEND)
 #define IS_V(wc) (wc >= VFILL && wc <= VEND)
 #define IS_T(wc) (wc >= TBASE && wc <= TEND)
+#define IS_M(wc) ((wc) == HTONE1 || (wc) == HTONE2)
+
 
 /* jamo which can be composited as a Hangul syllable */
 #define IS_L_S(wc) (wc >= LBASE && wc < LBASE + LCOUNT)
Index: hangul/hangul-xft.c
===================================================================
RCS file: /cvs/gnome/pango/modules/hangul/hangul-xft.c,v
retrieving revision 1.4
diff -u -r1.4 hangul-xft.c
--- hangul/hangul-xft.c	15 Oct 2002 09:50:26 -0000	1.4
+++ hangul/hangul-xft.c	25 Oct 2002 01:10:26 -0000
@@ -34,6 +34,7 @@
 static PangoEngineRange hangul_ranges[] = {
   /* Language characters */
   { 0x1100, 0x11FF, "*" }, /* Hangul Jamo */
+  { HTONE1, HTONE2, "*" }, /* Hangul Tone Marks */
 };
 
 static PangoEngineInfo script_engines[] = {
@@ -59,16 +60,98 @@
   glyphs->glyphs[i].geometry.width = logical_rect.width;
 }
 
+/* Add a Hangul tone mark glyph in a glyph string.
+ * Non-spacing glyph works pretty much automatically.
+ * Spacing-glyph takes some care:
+ *   1. Make a room for a tone mark at the beginning(leftmost end) of a cluster 
+ *   to attach it to.
+ *   2. Adjust x_offset so that it is drawn to the left of a cluster.
+ *   3. Set the logical width to zero. 
+ */
+
+static void
+set_glyph_tone (PangoFont *font, PangoGlyphString *glyphs, int i, 
+		            int offset, PangoGlyph glyph)
+{
+  PangoRectangle logical_rect, ink_rect;
+  PangoRectangle logical_rect_cluster;
+
+  glyphs->glyphs[i].glyph = glyph;
+  glyphs->glyphs[i].geometry.y_offset = 0;
+  glyphs->log_clusters[i] = offset;
+
+  pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, 
+				&ink_rect, &logical_rect);
+  if (logical_rect.width)
+    if ( i ) /* we have info. on the preceding glyphs in a glyph string */
+      {
+        int j = i - 1;
+        while ( j >= 0 && glyphs->log_clusters[j] == glyphs->log_clusters[i-1] ) 
+	  j--;
+        pango_glyph_string_extents_range (glyphs, j + 1, i - 1, font, 
+				          NULL, &logical_rect_cluster); 
+
+        glyphs->glyphs[i].geometry.x_offset = - logical_rect_cluster.width - 
+					        ink_rect.width - logical_rect.width;
+        glyphs->glyphs[j+1].geometry.width += ink_rect.width;
+        glyphs->glyphs[j+1].geometry.x_offset += ink_rect.width;
+      }
+    else 
+        /* tone mark comes in by itself. make a rough guess. the cursor position
+	 * will be off. 
+	 */
+        glyphs->glyphs[i].geometry.x_offset = - 1.08 * logical_rect.width;
+  else
+    glyphs->glyphs[i].geometry.x_offset = 0;
+
+  glyphs->glyphs[i].geometry.width = 0;
+
+}
+
 #define find_char pango_xft_font_get_glyph
 
 static void
+render_tone (PangoFont *font, gunichar tone, PangoGlyphString *glyphs, 
+             int *n_glyphs, int cluster_offset)
+{
+  int index;
+
+
+  index = find_char(font, tone);
+  pango_glyph_string_set_size (glyphs, *n_glyphs + 1);
+  if (index)
+    {
+      set_glyph_tone (font, glyphs, *n_glyphs, cluster_offset, index);
+    }
+  else 
+    {  /* fall back : HTONE1(0x302e) => '·', HTONE2(0x302f) => ':' */
+      index = find_char(font, tone == HTONE1 ? 0x00b7 : 0x003a);
+      if (index)
+        {
+          set_glyph_tone (font, glyphs, *n_glyphs, cluster_offset, index);
+        }
+      else 
+        set_glyph (font, glyphs, *n_glyphs, cluster_offset,
+                   pango_xft_font_get_unknown_glyph (font, index));
+    }
+  (*n_glyphs)++;
+}
+
+
+static void
 render_syllable (PangoFont *font, gunichar *text, int length,
 		 PangoGlyphString *glyphs, int *n_glyphs, int cluster_offset)
 {
   int index;
-  gunichar wc;
+  gunichar wc,tone;
   int i, j, composed;
 
+  tone = text[length-1];
+  if (IS_M (tone)) 
+    length--;
+  else
+    tone = 0;
+
   if (length >= 3 && IS_L_S(text[0]) && IS_V_S(text[1]) && IS_T_S(text[2]))
     composed = 3;
   else if (length >= 2 && IS_L_S(text[0]) && IS_V_S(text[1]))
@@ -124,6 +207,8 @@
 	  (*n_glyphs)++;
 	}
     }
+    if (tone) 
+      render_tone(font, tone, glyphs, n_glyphs, cluster_offset);
 }
 
 static void 
@@ -157,7 +242,8 @@
       if (n_jamos != 0 &&
 	  ((IS_T (jamos[n_jamos - 1]) && IS_L (wc)) ||
 	   (IS_V (jamos[n_jamos - 1]) && IS_L (wc)) ||
-	   (IS_T (jamos[n_jamos - 1]) && IS_V (wc))))
+	   (IS_T (jamos[n_jamos - 1]) && IS_V (wc)) ||
+	   (IS_M (jamos[n_jamos - 1]) && (IS_L (wc) || IS_V (wc) || IS_T (wc)))))
 	{
 	  /* Draw a syllable. */
 	  render_syllable (font, jamos, n_jamos, glyphs,
@@ -165,6 +251,19 @@
 	  n_jamos = 0;
 	  start = p;
 	}
+      else if (n_jamos != 0 && IS_M (jamos[n_jamos - 1]) && IS_M (wc))
+	{
+	  render_syllable (font, jamos, n_jamos, glyphs,
+			   &n_glyphs, start - text);
+	  n_jamos = 0;
+	  /* skip M's other than the 1st one in a series of M's */
+          p = g_utf8_next_char (p);
+	  if ( ++i < n_chars )
+            wc = g_utf8_get_char (p);
+	  else 
+	    break;
+	  start = p;
+	}
       
       if (n_jamos == max_jamos)
 	{
@@ -201,6 +300,9 @@
      _exactly_, I sure.  */
   for (i = 0x1100; i <= 0x11FF; i++)
     pango_coverage_set (result, i, PANGO_COVERAGE_FALLBACK);
+  pango_coverage_set (result, HTONE1, PANGO_COVERAGE_FALLBACK);
+  pango_coverage_set (result, HTONE2, PANGO_COVERAGE_FALLBACK);
+
   return result;
 }
 
