Include "database.h".
authorhanda <handa>
Mon, 3 Sep 2007 00:33:30 +0000 (00:33 +0000)
committerhanda <handa>
Mon, 3 Sep 2007 00:33:30 +0000 (00:33 +0000)
(struct _MFLT): New struct.
(list_flt): New function.
(load_flt): Don't update flt_list.
(get_font_layout_table): Use flt_list.
(m17n_init_flt): Don't initialize flt_list.
(m17n_fini_flt): Adjusted for the change of flt_list.
(mflt_find): New function.
(mflt_run): Fix debug printing.

src/m17n-flt.c

index d89e6bb..a3690b9 100644 (file)
@@ -49,6 +49,7 @@
 #include "mtext.h"
 #include "symbol.h"
 #include "plist.h"
+#include "database.h"
 #include "internal-flt.h"
 
 /* Font Layouter */
@@ -445,8 +446,81 @@ typedef struct
 
 typedef MPlist MFontLayoutTable; /* t vs FontLayoutStage */
 
+struct _MFLT
+{
+  MSymbol name;
+  MSymbol family;
+  MFLTOtfSpec otf;
+  MPlist *stages;
+};
+
 /* Font layout table loader */
 
+static int parse_otf_command (MSymbol symbol, MFLTOtfSpec *spec);
+
+static int
+list_flt ()
+{
+  MPlist *plist = mdatabase_list (Mfont, Mlayouter, Mnil, Mnil);
+  MPlist *pl;
+
+  flt_list = mplist ();
+  MPLIST_DO (pl, plist)
+    {
+      MDatabase *mdb = MPLIST_VAL (pl);
+      MSymbol *tags = mdatabase_tag (mdb);
+      MPlist *properties = mdatabase__props (mdb), *p;
+      MFLT *flt;
+
+      if (! MSTRUCT_CALLOC_SAFE (flt))
+       goto memfull;
+      flt->name = tags[2];
+      mplist_push (flt_list, flt->name, flt);
+      if (properties)
+       MPLIST_DO (properties, properties)
+         {
+           MSymbol sym = Mnil;
+           char *otf_spec;
+
+           if (! MPLIST_PLIST_P (properties))
+             continue;
+           p = MPLIST_PLIST (properties);
+           if (! MPLIST_SYMBOL_P (p))
+             continue;
+           if (MPLIST_SYMBOL (p) != Mfont)
+             continue;
+           p = MPLIST_NEXT (p);
+           if (! MPLIST_PLIST_P (p))
+             continue;
+           p = MPLIST_PLIST (p);
+           if (! MPLIST_SYMBOL_P (p))
+             continue;
+           p = MPLIST_NEXT (p);
+           if (! MPLIST_SYMBOL_P (p))
+             continue;
+           flt->family = MPLIST_SYMBOL (p);
+           MPLIST_DO (p, MPLIST_NEXT (p))
+             if (MPLIST_SYMBOL_P (p))
+               sym = MPLIST_SYMBOL (p);
+           if (sym
+               && (otf_spec = MSYMBOL_NAME (sym))
+               && otf_spec[0] == ':' && otf_spec[1] == 'o'
+               && otf_spec[2] == 't' && otf_spec[3] == 'f')
+             {
+               if (parse_otf_command (sym, &flt->otf) == -2)
+                 goto memfull;
+             }
+         }
+    }
+  M17N_OBJECT_UNREF (plist);
+  return 0;
+
+ memfull:
+  M17N_OBJECT_UNREF (plist);  
+  M17N_OBJECT_UNREF (flt_list);
+  MERROR (MERROR_MEMORY, -1);
+}
+
 /* Load a category table from PLIST.  PLIST has this form:
       PLIST ::= ( FROM-CODE TO-CODE ? CATEGORY-CHAR ) *
 */
@@ -1162,7 +1236,6 @@ load_flt (MSymbol layouter_name)
 
  finish:
   M17N_OBJECT_UNREF (top);
-  mplist_add (flt_list, layouter_name, layouter);
   return layouter;
 }
 
@@ -1183,9 +1256,15 @@ free_flt_stage (FontLayoutStage *stage)
 static MFontLayoutTable *
 get_font_layout_table (MSymbol layouter_name)
 {
-  MPlist *plist = mplist_find_by_key (flt_list, layouter_name);
-
-  return (plist ? MPLIST_VAL (plist) : load_flt (layouter_name));
+  MFLT *flt;
+
+  if (! flt_list
+      && list_flt () < 0)
+    return NULL;
+  flt = mplist_get (flt_list, layouter_name);
+  if (! flt->stages)
+    flt->stages = load_flt (layouter_name);
+  return flt->stages;
 }
 
 
@@ -1964,7 +2043,6 @@ m17n_init_flt (void)
   Mrange = msymbol ("range");
   Mfont = msymbol ("font");
   Mlayouter = msymbol ("layouter");
-  flt_list = mplist ();
 
   MDEBUG_POP_TIME ();
   MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize the flt modules."));
@@ -1986,18 +2064,21 @@ m17n_fini_flt (void)
   MDEBUG_PUSH_TIME ();
   MDEBUG_PUSH_TIME ();
 
-  MPLIST_DO (plist, flt_list)
+  if (flt_list)
     {
-      pl = MPLIST_PLIST (plist);
-      if (pl)
+      MPLIST_DO (plist, flt_list)
        {
-         MPLIST_DO (pl, MPLIST_NEXT (pl))
-           free_flt_stage (MPLIST_VAL (pl));
-         pl = MPLIST_PLIST (plist);
-         M17N_OBJECT_UNREF (pl);
+         MFLT *flt = MPLIST_VAL (plist);
+
+         if (flt->stages)
+           {
+             MPLIST_DO (pl, MPLIST_NEXT (flt->stages))
+               free_flt_stage (MPLIST_VAL (pl));
+             M17N_OBJECT_UNREF (flt->stages);
+           }
        }
+      M17N_OBJECT_UNREF (flt_list);
     }
-  M17N_OBJECT_UNREF (flt_list);
 
   MDEBUG_POP_TIME ();
   MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize the flt modules."));
@@ -2008,6 +2089,47 @@ m17n_fini_flt (void)
 /*** @} */ 
 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
 
+MFLT *
+mflt_find (MFLTGlyphString *gstring, int pos, MFLTFont *font, int *start)
+{
+  MPlist *plist;
+  MSymbol script;
+  int i;
+  static MSymbol Mcommon = NULL;
+
+  if (! Mcommon)
+    Mcommon = msymbol ("common");
+
+  for (i = pos; i < gstring->used; i++)
+    {
+      script = mchar_get_prop (GREF (gstring, i)->c, Mscript);
+      if (script != Minherited && script != Mcommon)
+       break;
+    }
+  if (i == gstring->used)
+    return NULL;
+  if (! flt_list
+      && list_flt () < 0)
+    return NULL;
+  MPLIST_DO (plist, flt_list)
+    {
+      MFLT *flt = MPLIST_VAL (plist);
+
+      if ((flt->otf.script == gstring->script
+          || ! flt->otf.script || ! gstring->script)
+         && (! font
+             || ! font->suitable_p
+             || font->suitable_p (font, flt->family, &flt->otf)))
+       {
+         if (! flt->stages
+             && ! (flt->stages = load_flt (flt->name)))
+           return NULL;
+         return flt;
+       }
+    }
+  return NULL;
+}
+
 int
 mflt_run (MFLTGlyphString *gstring, int from, int to,
          MFLTFont *font, MSymbol layouter_name)
@@ -2070,7 +2192,7 @@ mflt_run (MFLTGlyphString *gstring, int from, int to,
       for (i = from, j = 0; i < to; i++, j++)
        {
          if (j > 0 && j % 8 == 0)
-           MDEBUG_PRINT ("\n [FLT}          ");
+           MDEBUG_PRINT ("\n [FLT]          ");
          MDEBUG_PRINT1 (" %04X", GREF (gstring, i)->c);
        }
       MDEBUG_PRINT (")");