*** empty log message ***
[m17n/m17n-test.git] / flt.c
diff --git a/flt.c b/flt.c
index ae17b48..963209b 100644 (file)
--- a/flt.c
+++ b/flt.c
 #include <otf.h>
 #define PROGNAME "flt-otf"
 
-#else  /* defined (FLT_HB) */
+#elif defined (FLT_HB)
 
 #include <m17n-flt.h>
 #include <harfbuzz.h>
 #define PROGNAME "flt-hb"
 
+#else (defined (FLT_PANGO))
+
+#include <m17n-flt.h>
+#include <pango/pango-engine.h>
+#include <pango/pango-ot.h>
+#include <pango/pango-utils.h>
+
 #endif
 
 static FT_Library ft_library;
@@ -130,12 +137,19 @@ close_font (MFLTFont *font)
 int
 flt (MText *mt, int from, int to, MFLTFont *font, char *flt_name)
 {
+  MDrawControl control;
+
+  memset (&control, 0, sizeof (MDrawControl));
+  control.two_dimensional = 1;
+  control.enable_bidi = 1;
+  control.anti_alias = 1;
+  /*control.disable_caching = 1;*/
   mtext_put_prop (mt, from, to, Mfont, font->font);
-  mdraw_text_extents (frame, mt, from, to, NULL, NULL, NULL, NULL);
+  mdraw_text_extents (frame, mt, from, to, &control, NULL, NULL, NULL);
   return 0;
 }
 
-#else  /* FLT_OTF or FLT_HB */
+#elif defined (FLT_OTF) || defined (FLT_HB)
 
 typedef struct {
   MFLTFont font;
@@ -272,7 +286,7 @@ encode_features (char *str, int count, unsigned *features)
 }
 
 int
-drive_otf (MFLTFont *font, MFLT_OTF_Spec *spec,
+drive_otf (MFLTFont *font, MFLTOtfSpec *spec,
           MFLTGlyphString *in, int from, int to,
           MFLTGlyphString *out, MFLTGlyphAdjustment *adjustment)
 {
@@ -345,9 +359,16 @@ drive_otf (MFLTFont *font, MFLT_OTF_Spec *spec,
       for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; i++, otfg++)
        {
          MFLTGlyph *g = out->glyphs + out->used;
+         int j;
 
          *g = in->glyphs[from + otfg->f.index.from];
-         g->c = otfg->c;
+         g->c = 0;
+         for (j = from + otfg->f.index.from; j <= from + otfg->f.index.to; j++)
+           if (in->glyphs[j].code == otfg->glyph_id)
+             {
+               g->c = in->glyphs[j].c;
+               break;
+             }
          g->code = otfg->glyph_id;
          out->used++;
        }
@@ -415,7 +436,7 @@ drive_otf (MFLTFont *font, MFLT_OTF_Spec *spec,
                  adjustment[i].yadv
                    += otfg->f.f1.value->YAdvance * y_scale / 0x10000;
                if (format & OTF_YAdvDevice)
-                 adjustment[i].xadv
+                 adjustment[i].yadv
                    += DEVICE_DELTA (otfg->f.f1.value->YAdvDevice, y_ppem);
                adjustment[i].set = 1;
              }
@@ -690,8 +711,8 @@ const HB_FontClass hb_fontClass = {
     getPointInOutline, getGlyphMetrics, getFontMetric
 };
 
-HB_Error
-setup_features (int gsubp, FontInfoHB *font_info, MFLT_OTF_Spec *spec,
+void
+setup_features (int gsubp, FontInfoHB *font_info, MFLTOtfSpec *spec,
                FeatureInfo *info)
 {
   int count, preordered;
@@ -706,18 +727,18 @@ setup_features (int gsubp, FontInfoHB *font_info, MFLT_OTF_Spec *spec,
     {
       if (! font_info->gsub)
        {
-         if ((err = load_gsub (font_info)) != HB_Err_Ok)
-           return err;
+         if (load_gsub (font_info) != HB_Err_Ok)
+           return;
        }
-      if ((err = HB_GSUB_Select_Script (font_info->gsub, spec->script, &script))
+      if (HB_GSUB_Select_Script (font_info->gsub, spec->script, &script)
          != HB_Err_Ok)
-       return err;
+       return;
       if (spec->langsys)
        {
-         if ((err = HB_GSUB_Select_Language (font_info->gsub, spec->langsys,
-                                             script, &langsys, &req_feature))
+         if (HB_GSUB_Select_Language (font_info->gsub, spec->langsys,
+                                      script, &langsys, &req_feature)
              != HB_Err_Ok)
-           return err;
+           return;
        }
       else
        langsys = req_feature = 0xFFFF;
@@ -728,18 +749,18 @@ setup_features (int gsubp, FontInfoHB *font_info, MFLT_OTF_Spec *spec,
     {
       if (! font_info->gpos)
        {
-         if ((err = load_gpos (font_info)) != HB_Err_Ok)
-           return err;
+         if (load_gpos (font_info) != HB_Err_Ok)
+           return;
        }
-      if ((err = HB_GPOS_Select_Script (font_info->gpos, spec->script, &script))
+      if (HB_GPOS_Select_Script (font_info->gpos, spec->script, &script)
          != HB_Err_Ok)
-       return err;
+       return;
       if (spec->langsys)
        {
-         if ((err = HB_GPOS_Select_Language (font_info->gpos, spec->langsys,
-                                             script, &langsys, &req_feature))
+         if (HB_GPOS_Select_Language (font_info->gpos, spec->langsys,
+                                      script, &langsys, &req_feature)
              != HB_Err_Ok)
-           return err;
+           return;
        }
       else
        langsys = req_feature = 0xFFFF;
@@ -750,13 +771,12 @@ setup_features (int gsubp, FontInfoHB *font_info, MFLT_OTF_Spec *spec,
   for (preordered = 0; preordered < count; preordered++)
     if (features[preordered] == 0)
       {
-       if ((err = (gsubp
-                   ? HB_GSUB_Query_Features (font_info->gsub, script, langsys,
-                                             &feature_list)
-                   : HB_GPOS_Query_Features (font_info->gpos, script, langsys,
-                                             &feature_list)))
+       if ((gsubp ? HB_GSUB_Query_Features (font_info->gsub, script, langsys,
+                                            &feature_list)
+            : HB_GPOS_Query_Features (font_info->gpos, script, langsys,
+                                      &feature_list))
            != HB_Err_Ok)
-         return err;
+         return;
        break;
       }
   if (feature_list)
@@ -768,11 +788,10 @@ setup_features (int gsubp, FontInfoHB *font_info, MFLT_OTF_Spec *spec,
   if (req_feature != 0xFFFF)
     info->indices[i++] = req_feature;
   for (j = 0; j < preordered; j++)
-    if ((err = (gsubp
-               ? HB_GSUB_Select_Feature (font_info->gsub, features[j],
-                                         script, langsys, &index)
-               : HB_GPOS_Select_Feature (font_info->gpos, features[j],
-                                         script, langsys, &index)))
+    if ((gsubp ? HB_GSUB_Select_Feature (font_info->gsub, features[j],
+                                        script, langsys, &index)
+        : HB_GPOS_Select_Feature (font_info->gpos, features[j],
+                                  script, langsys, &index))
        == HB_Err_Ok)
       info->indices[i++] = index;
   if (feature_list)
@@ -787,15 +806,14 @@ setup_features (int gsubp, FontInfoHB *font_info, MFLT_OTF_Spec *spec,
                                           script, langsys, &index)
                 : HB_GPOS_Select_Feature (font_info->gpos, feature_list[j],
                                           script, langsys, &index))
-               == FT_Err_Ok))
+               == HB_Err_Ok))
          info->indices[i++] = index;
       }
   info->count = i;
-  return HB_Err_Ok;
 }
 
 GsubGposInfo *
-setup_otf_spec (MFLTFont *font, MFLT_OTF_Spec *spec)
+setup_otf_spec (MFLTFont *font, MFLTOtfSpec *spec)
 {
   FontInfoHB *font_info = (FontInfoHB *) font;
   GsubGposInfo *ginfo;
@@ -807,15 +825,13 @@ setup_otf_spec (MFLTFont *font, MFLT_OTF_Spec *spec)
     return (ginfo->gsub.count + ginfo->gpos.count > 0 ? ginfo : NULL);
   ginfo = calloc (1, sizeof (GsubGposInfo));
   mplist_push (font_info->otf_spec_cache, spec->sym, ginfo);
-  if (setup_features (1, font_info, spec, &(ginfo->gsub)) != HB_Err_Ok)
-    return NULL;
-  if (setup_features (0, font_info, spec, &(ginfo->gpos)) != HB_Err_Ok)
-    return NULL;
+  setup_features (1, font_info, spec, &(ginfo->gsub));
+  setup_features (0, font_info, spec, &(ginfo->gpos));
   return ginfo;
 }
 
 int
-drive_otf (MFLTFont *font, MFLT_OTF_Spec *spec,
+drive_otf (MFLTFont *font, MFLTOtfSpec *spec,
           MFLTGlyphString *in, int from, int to,
           MFLTGlyphString *out, MFLTGlyphAdjustment *adjustment)
 {
@@ -826,7 +842,6 @@ drive_otf (MFLTFont *font, MFLT_OTF_Spec *spec,
   GsubGposInfo *ginfo;
   HB_UShort *apply_order_save;
   HB_UShort apply_count_save;
-  int apply_saved = 0;
   int gpos_applied = 0;
   HB_Error err;
 
@@ -851,10 +866,11 @@ drive_otf (MFLTFont *font, MFLT_OTF_Spec *spec,
        goto simple_copy;
       apply_order_save = font_info->gsub->FeatureList.ApplyOrder;
       apply_count_save = font_info->gsub->FeatureList.ApplyCount;
-      apply_saved = 1;
       font_info->gsub->FeatureList.ApplyOrder = ginfo->gsub.indices;
       font_info->gsub->FeatureList.ApplyCount = ginfo->gsub.count;
       err = HB_GSUB_Apply_String (font_info->gsub, buf);
+      font_info->gsub->FeatureList.ApplyOrder = apply_order_save;
+      font_info->gsub->FeatureList.ApplyCount = apply_count_save;
       if (err != HB_Err_Ok && err != HB_Err_Not_Covered)
        goto simple_copy;
       if (out->used + buf->in_length > out->allocated)
@@ -864,26 +880,18 @@ drive_otf (MFLTFont *font, MFLT_OTF_Spec *spec,
   if (ginfo->gpos.count > 0
       && (font_info->gpos || load_gpos (font_info) == HB_Err_Ok))
     {
-      if (! apply_saved)
-       {
-         apply_order_save = font_info->gsub->FeatureList.ApplyOrder;
-         apply_count_save = font_info->gsub->FeatureList.ApplyCount;
-         apply_saved = 1;
-       }
+      apply_order_save = font_info->gpos->FeatureList.ApplyOrder;
+      apply_count_save = font_info->gpos->FeatureList.ApplyCount;
       font_info->gpos->FeatureList.ApplyOrder = ginfo->gpos.indices;
       font_info->gpos->FeatureList.ApplyCount = ginfo->gpos.count;
       err = HB_GPOS_Apply_String (&font_info->hb_font, font_info->gpos,
                                  FT_LOAD_DEFAULT, buf, FALSE, FALSE);
+      font_info->gpos->FeatureList.ApplyOrder = apply_order_save;
+      font_info->gpos->FeatureList.ApplyCount = apply_count_save;
       if (err == HB_Err_Ok)
        gpos_applied = 1;
     }
 
-  if (apply_saved)
-    {
-      font_info->gsub->FeatureList.ApplyOrder = apply_order_save;
-      font_info->gsub->FeatureList.ApplyCount = apply_count_save;
-    }
-
   gidx = out->used;
 
   for (i = 0; i < buf->in_length; i++)
@@ -972,6 +980,45 @@ close_font (MFLTFont *font)
 }
 
 #endif
+
+#else  /* (defined (FLT_PANGO) */
+
+typedef struct {
+  MFLTFont font;
+  PangoFcFont pango_fc_font;
+} FontInfoPango;
+
+int
+get_glyph_id (MFLTFont *font, MFLTGlyph *g)
+{
+  FontInfoPango *font_info = (FontInfoPango *) font;
+  PangoGlyph pg = pango_fc_font_get_glyph (font_info->pango_fc_font, g->c);
+
+  return (pg ? (int) pg : -1);
+}
+
+int
+get_metric (MFLTFont *font, MFLTGlyphString *gstring, int form, int to)
+{
+  FontInfoPango *font_info = (FontInfoPango *) font;
+  PangoFcFont fc_font = font_info->pango_fc_font;
+  int i;
+
+  for (i = from; i < to; i++)
+    {
+      PangoRectangle inc, logical;
+
+      pango_font_get_glyph_extents ((PangoFont *) fc_font,
+                                   gstring->glyphs[i].code, &inc, &logical);
+      g->lbearing = inc.x;
+      g->rbearing = inc.x + inc.width;
+      g->xadv = logical.width;
+      g->yadv = 0;
+      g->ascent = - inc.y;
+      g->descent = inc.height + inc.y;
+    }
+}
+
 #endif
 
 int