*** empty log message ***
[m17n/m17n-test.git] / flt.c
diff --git a/flt.c b/flt.c
index 5b5c9c4..5cf2479 100644 (file)
--- a/flt.c
+++ b/flt.c
@@ -9,11 +9,13 @@
 #if defined (FLT_GUI)
 
 #include <m17n-gui.h>
+#include <m17n-misc.h>
 #define PROGNAME "flt-gui"
 
 #elif defined (FLT_OTF)
 
 #include <m17n-flt.h>
+#include <m17n-misc.h>
 #include <otf.h>
 #define PROGNAME "flt-otf"
 
@@ -26,6 +28,7 @@
 #else  /* (defined (FLT_PANGO)) */
 
 #include <m17n-flt.h>
+#include <m17n-misc.h>
 #define PANGO_ENABLE_ENGINE
 #define PANGO_ENABLE_BACKEND
 #include <pango/pango.h>
@@ -119,7 +122,7 @@ struct _MFLTFont
 {
   int x_ppem, y_ppem;
   void (*get_glyph_id) (void);
-  void (*get_metric) (void);
+  void (*get_metrics) (void);
   void (*suitable_p) (void);
   void (*drive_otf) (void);
   MFont *font;
@@ -127,7 +130,7 @@ struct _MFLTFont
 };
 
 void get_glyph_id (void) {}
-void get_metric (void) {}
+void get_metrics (void) {}
 void suitable_p (void) {}
 void drive_otf (void) {}
 
@@ -177,34 +180,46 @@ typedef struct {
 } FontInfo;
 
 int
-get_glyph_id (MFLTFont *font, MFLTGlyph *g)
+get_glyph_id (MFLTFont *font, MFLTGlyphString *gstring, int from, int to)
 {
   FT_Face face = ((FontInfo *) font)->face;
 
-  g->code = FT_Get_Char_Index (face, g->code);
+  for (; from < to; from++)
+    {
+      MFLTGlyph *g = gstring->glyphs + from;
 
-  return (g->code ? 0 : -1);
+      if (! g->encoded
+         && ! (g->code = FT_Get_Char_Index (face, g->code)))
+       return -1;
+      g->encoded = 1;
+    }
+  return 0;
 }
 
 int 
-get_metric (MFLTFont *font, MFLTGlyphString *gstring, int from, int to)
+get_metrics (MFLTFont *font, MFLTGlyphString *gstring, int from, int to)
 {
   FT_Face face = ((FontInfo *) font)->face;
 
   for (; from < to; from++)
     {
       MFLTGlyph *g = gstring->glyphs + from;
-      FT_Glyph_Metrics *metrics;
 
-      if (FT_Load_Glyph (face, g->code, FT_LOAD_DEFAULT))
-       return -1;
-      metrics = &face->glyph->metrics;
-      g->lbearing = metrics->horiBearingX;
-      g->rbearing = metrics->horiBearingX + metrics->width;
-      g->xadv = metrics->horiAdvance;
-      g->yadv = metrics->vertAdvance;
-      g->ascent = metrics->horiBearingY;
-      g->descent = metrics->height - metrics->horiBearingY;
+      if (! g->measured)
+       {
+         FT_Glyph_Metrics *metrics;
+
+         if (FT_Load_Glyph (face, g->code, FT_LOAD_DEFAULT))
+           return -1;
+         metrics = &face->glyph->metrics;
+         g->lbearing = metrics->horiBearingX;
+         g->rbearing = metrics->horiBearingX + metrics->width;
+         g->xadv = metrics->horiAdvance;
+         g->yadv = metrics->vertAdvance;
+         g->ascent = metrics->horiBearingY;
+         g->descent = metrics->height - metrics->horiBearingY;
+         g->measured = 1;
+       }
     }
   return 0;
 }
@@ -372,7 +387,11 @@ drive_otf (MFLTFont *font, MFLTOtfSpec *spec,
                g->c = in->glyphs[j].c;
                break;
              }
-         g->code = otfg->glyph_id;
+         if (g->code != otfg->glyph_id)
+           {
+             g->code = otfg->glyph_id;
+             g->measured = 0;
+           }
          out->used++;
        }
     }
@@ -384,8 +403,6 @@ drive_otf (MFLTFont *font, MFLTOtfSpec *spec,
        out->glyphs[out->used++] = in->glyphs[from + i];
     }
 
-  font->get_metric (font, out, gidx, out->used);
-
   if (gpos_features)
     {
       FT_Face face;
@@ -490,7 +507,7 @@ drive_otf (MFLTFont *font, MFLTOtfSpec *spec,
   return to;
 
  simple_copy:
-  font->get_metric (font, in, from, to);
+  font->get_metrics (font, in, from, to);
   for (i = 0; i < len; i++)
     {
       MFLTGlyph *g = in->glyphs + (from + i);
@@ -900,7 +917,11 @@ drive_otf (MFLTFont *font, MFLTOtfSpec *spec,
       out->glyphs[out->used] = in->glyphs[hg->cluster];
       g = out->glyphs + out->used++;
       if (g->code != hg->gindex)
-       g->c = 0, g->code = hg->gindex;
+       {
+         g->c = 0;
+         g->code = hg->gindex;
+         g->measured = 0;
+       }
       adjustment[i].set = gpos_applied;
       if (gpos_applied)
        {
@@ -997,19 +1018,27 @@ typedef struct {
 } FontInfoPango;
 
 int
-get_glyph_id (MFLTFont *font, MFLTGlyph *g)
+get_glyph_id (MFLTFont *font, MFLTGlyphString *gstring, int from, int to)
 {
   FontInfoPango *font_info = (FontInfoPango *) font;
 
-  g->code = pango_fc_font_get_glyph (font_info->pango_font, g->code);
-  return (g->code ? 0 : -1);
+  for (; from < to; from++)
+    {
+      MFLTGlyph *g = gstring->glyphs + from;
+
+      if (! g->encoded
+         && ! (g->code = pango_fc_font_get_glyph (font_info->pango_font,
+                                                  g->code)))
+       return -1;
+      g->encoded = 1;
+    }
+  return 0;
 }
 
 #define PANGO_SCALE_TO_26_6 (PANGO_SCALE / (1<<6))
 
-#if 0
 int
-get_metric (MFLTFont *font, MFLTGlyphString *gstring, int from, int to)
+get_metrics (MFLTFont *font, MFLTGlyphString *gstring, int from, int to)
 {
   FontInfoPango *font_info = (FontInfoPango *) font;
   int i;
@@ -1017,22 +1046,25 @@ get_metric (MFLTFont *font, MFLTGlyphString *gstring, int from, int to)
   for (i = from; i < to; i++)
     {
       MFLTGlyph *g = gstring->glyphs + from;
-      PangoRectangle inc, logical;
 
-      pango_font_get_glyph_extents (PANGO_FONT (font_info->pango_font),
-                                   gstring->glyphs[i].code, &inc, &logical);
-      g->lbearing = inc.x / PANGO_SCALE_TO_26_6;
-      g->rbearing = (inc.x + inc.width) / PANGO_SCALE_TO_26_6;
-      g->xadv = logical.width / PANGO_SCALE_TO_26_6;
-      g->yadv = 0;
-      g->ascent = - inc.y / PANGO_SCALE_TO_26_6;
-      g->descent = (inc.height + inc.y) / PANGO_SCALE_TO_26_6;
+      if (! g->measured)
+       {
+         PangoRectangle inc, logical;
+
+         pango_font_get_glyph_extents (PANGO_FONT (font_info->pango_font),
+                                       gstring->glyphs[i].code, &inc, &logical);
+         g->lbearing = inc.x / PANGO_SCALE_TO_26_6;
+         g->rbearing = (inc.x + inc.width) / PANGO_SCALE_TO_26_6;
+         g->xadv = logical.width / PANGO_SCALE_TO_26_6;
+         g->yadv = 0;
+         g->ascent = - inc.y / PANGO_SCALE_TO_26_6;
+         g->descent = (inc.height + inc.y) / PANGO_SCALE_TO_26_6;
+         g->measured = 1;
+       }
     }
   return 0;
 }
-#else
-int (*get_metric) (MFLTFont *font, MFLTGlyphString *gstring, int from, int to) = NULL;
-#endif
+
 
 #ifndef PANGO_OT_DEFAULT_LANGUAGE
 #define PANGO_OT_DEFAULT_LANGUAGE ((guint) 0xFFFF)
@@ -1176,7 +1208,11 @@ drive_otf (MFLTFont *font, MFLTOtfSpec *spec,
       out->glyphs[out->used] = in->glyphs[glyphs->log_clusters[i]];
       g = out->glyphs + out->used++;
       if (g->code != glyph_info->glyph)
-       g->c = 0, g->code = glyph_info->glyph;
+       {
+         g->c = 0;
+         g->code = glyph_info->glyph;
+         g->measured = 0;
+       }
       g->xoff = glyph_info->geometry.x_offset / PANGO_SCALE_TO_26_6;
       g->yoff = glyph_info->geometry.y_offset / PANGO_SCALE_TO_26_6;
       g->xadv = glyph_info->geometry.width / PANGO_SCALE_TO_26_6;
@@ -1324,6 +1360,7 @@ main (int argc, char **argv)
   MText *mt;
   MFLTFont *font;
   int len, i, j;
+  unsigned char *buf;
 
   if (argc < 3)
     {
@@ -1343,10 +1380,17 @@ main (int argc, char **argv)
       exit (1);
     }
   font->get_glyph_id = get_glyph_id;
-  font->get_metric = get_metric;
+  font->get_metrics = get_metrics;
   font->drive_otf = drive_otf;
 
-  mt = mconv_decode_stream (msymbol ("utf-8"), stdin);
+  i = 0;
+  buf = malloc (4096);
+  while ((j = fread (buf + i, 1, 4096, stdin)) == 4096)
+    {
+      i += 4096;
+      buf = realloc (buf, i + 4096);
+    }
+  mt = mtext_from_data (buf, i, MTEXT_FORMAT_UTF_8);
   len = mtext_len (mt);
   for (i = 0, j = mtext_character (mt, i, len, '\n'); i < len;
        i = j + 1, j = mtext_character (mt, i, len, '\n'))
@@ -1364,6 +1408,7 @@ main (int argc, char **argv)
       i = j;
     }
   m17n_object_unref (mt);
+  free (buf);
   close_font (font);
   M17N_FINI ();
   return 0;