? modules/basic/aux-ot.c
? modules/basic/broken-basic-fc.c
Index: modules/basic/basic-fc.c
===================================================================
RCS file: /cvs/gnome/pango/modules/basic/basic-fc.c,v
retrieving revision 1.18
diff -u -p -u -r1.18 basic-fc.c
--- modules/basic/basic-fc.c	3 Aug 2003 21:57:27 -0000	1.18
+++ modules/basic/basic-fc.c	20 Sep 2003 23:10:08 -0000
@@ -26,6 +26,7 @@
 #include "pango-engine.h"
 #include "pango-utils.h"
 #include "pangofc-font.h"
+#include "pango-ot.h"
 
 #include "basic-common.h"
 
@@ -118,6 +119,128 @@ set_glyph (PangoFont        *font,
   glyphs->glyphs[i].geometry.width = logical_rect.width;
 }
 
+static void
+print_tag (FT_ULong tag)
+{
+  g_print ("%c%c%c%c", 
+           (unsigned char)(tag >> 24), (unsigned char)((tag & 0xff0000) >> 16),
+	   (unsigned char)((tag & 0xff00) >> 8), (unsigned char)(tag & 0xff));
+}
+
+static gchar scripts[][5] =
+{
+  "latn",
+  "cyrl",
+  "grek",
+  "armn",
+  "geor",
+  "runr",
+  "ogam"
+};
+
+static gchar gsub_features[][5] =
+{
+  "ccmp",
+  "liga",
+  "clig"
+};
+
+static gchar gpos_features[][5] =
+{
+  "kern",
+  "mark",
+  "mkmk"
+};
+
+/* returns true if kerning rule was applied */
+static gboolean
+apply_opentype_rules (FT_Face face, 
+                      PangoGlyphString *glyphs,
+                      int n_chars)
+{
+  PangoOTRuleset *ruleset = NULL;
+  PangoOTInfo *info = NULL;
+  gulong *properties;
+  gint i, j; 
+  gboolean did_kerning = FALSE;
+  
+  static GQuark ruleset_quark = 0;
+
+  info = pango_ot_info_get (face);
+  if (!info)
+    return FALSE;
+
+  if (!ruleset_quark)
+    ruleset_quark = g_quark_from_string ("pango-basic-ruleset");
+
+  ruleset = g_object_get_qdata (G_OBJECT (info), ruleset_quark);
+
+  if (!ruleset)
+    {
+      ruleset = pango_ot_ruleset_new (info);
+
+      for (i = 0; i < G_N_ELEMENTS (scripts); i++)
+        {
+          PangoOTTag script_tag = FT_MAKE_TAG (scripts[i][0], scripts[i][1], scripts[i][2], scripts[i][3]);
+          guint script_index;
+
+          if (pango_ot_info_find_script (info, PANGO_OT_TABLE_GPOS, script_tag, &script_index))
+            for (j = 0; j < G_N_ELEMENTS (gpos_features); j++)
+              {
+                PangoOTTag feature_tag = FT_MAKE_TAG (gpos_features[j][0], gpos_features[j][1], 
+                                                      gpos_features[j][2], gpos_features[j][3]);
+                guint feature_index;
+
+                /* 0xffff means default language */
+                if (pango_ot_info_find_feature (info, PANGO_OT_TABLE_GPOS, feature_tag, 
+                                                script_index, 0xffff, &feature_index))
+                  {
+                    pango_ot_ruleset_add_feature (ruleset, PANGO_OT_TABLE_GPOS, feature_index, 0xffff);
+                    if (feature_tag == FT_MAKE_TAG ('k', 'e', 'r', 'n'))
+                      did_kerning = TRUE;
+
+                    g_print ("basic-fc.c: apply_opentype_rules: adding feature: gpos ");
+                    print_tag (script_tag);
+                    g_print (" dflt ");
+                    print_tag (feature_tag);
+                    g_print ("\n");
+                  }
+              }
+
+          if (pango_ot_info_find_script (info, PANGO_OT_TABLE_GSUB, script_tag, &script_index))
+            for (j = 0; j < G_N_ELEMENTS (gsub_features); j++)
+              {
+                PangoOTTag feature_tag = FT_MAKE_TAG (gsub_features[j][0], gsub_features[j][1], 
+                                                      gsub_features[j][2], gsub_features[j][3]);
+                guint feature_index;
+
+                /* 0xffff means default language */
+                if (pango_ot_info_find_feature (info, PANGO_OT_TABLE_GSUB, feature_tag, 
+                                                script_index, 0xffff, &feature_index))
+                  {
+                    pango_ot_ruleset_add_feature (ruleset, PANGO_OT_TABLE_GSUB, feature_index, 0xffff);
+
+                    g_print ("basic-fc.c: apply_opentype_rules: adding feature: gsub ");
+                    print_tag (script_tag);
+                    g_print (" dflt ");
+                    print_tag (feature_tag);
+                    g_print ("\n");
+                  }
+              }
+        }
+
+      g_object_set_qdata_full (G_OBJECT (info), ruleset_quark, ruleset, (GDestroyNotify) g_object_unref);
+    }
+
+  properties = g_new0 (gulong, n_chars);
+
+  pango_ot_ruleset_shape (ruleset, glyphs, properties);
+
+  g_free (properties);
+
+  return did_kerning;
+}
+
 static void 
 basic_engine_shape (PangoEngineShape *engine,
 		    PangoFont        *font,
@@ -130,6 +253,9 @@ basic_engine_shape (PangoEngineShape *en
   int n_chars;
   int i;
   const char *p;
+  gboolean did_opentype_kerning;
+
+  FT_Face face;
 
   g_return_if_fail (font != NULL);
   g_return_if_fail (text != NULL);
@@ -139,7 +265,7 @@ basic_engine_shape (PangoEngineShape *en
   n_chars = g_utf8_strlen (text, length);
   pango_glyph_string_set_size (glyphs, n_chars);
 
-  pango_fc_font_lock_face (fc_font);
+  face = pango_fc_font_lock_face (fc_font);
 
   p = text;
   for (i = 0; i < n_chars; i++)
@@ -199,6 +325,8 @@ basic_engine_shape (PangoEngineShape *en
       p = g_utf8_next_char (p);
     }
 
+  did_opentype_kerning = apply_opentype_rules (face, glyphs, n_chars);
+
   /* Simple bidi support; most bidi languages (Arabic, Hebrew, Syriac)
    * are in fact handled in other modules.
    */
@@ -222,7 +350,8 @@ basic_engine_shape (PangoEngineShape *en
 	}
     }
 
-  pango_fc_font_kern_glyphs (fc_font, glyphs);
+  if (!did_opentype_kerning)
+    pango_fc_font_kern_glyphs (fc_font, glyphs);
 
   pango_fc_font_unlock_face (fc_font);
 }
