(struct MInputContext): Fix typo in comment.
[m17n/m17n-lib.git] / src / fontset.c
index f054199..6cb9d7d 100644 (file)
@@ -1,5 +1,5 @@
 /* fontset.c -- fontset module.
-   Copyright (C) 2003, 2004
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H15PRO112
 
@@ -17,7 +17,7 @@
 
    You should have received a copy of the GNU Lesser General Public
    License along with the m17n library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    02111-1307, USA.  */
 
 /***en
@@ -74,6 +74,8 @@
 #include "font.h"
 #include "fontset.h"
 
+static int mdebug_flag = MDEBUG_FONTSET;
+
 static M17NObjectArray fontset_table;
 
 struct MFontset
@@ -298,13 +300,15 @@ realize_fontset_elements (MFrame *frame, MRealizedFontset *realized)
 {
   MFontset *fontset = realized->fontset;
   MPlist *per_script, *per_charset, *font_group;
-  MPlist *plist, *pl, *p;
+  MPlist *plist, *p;
 
   realized->per_script = per_script = mplist ();
   /* The actual elements of per_script are realized on demand.  */
 #if 0
   MPLIST_DO (plist, fontset->per_script)
     {
+      MPlist *pl;
+
       per_lang = mplist ();
       per_script = mplist_add (per_script, MPLIST_KEY (plist), per_lang);
       MPLIST_DO (pl, MPLIST_PLIST (plist))
@@ -319,11 +323,11 @@ realize_fontset_elements (MFrame *frame, MRealizedFontset *realized)
 #endif
 
   realized->per_charset = per_charset = mplist ();
-  MPLIST_DO (pl, fontset->per_charset)
+  MPLIST_DO (plist, fontset->per_charset)
     {
       font_group = mplist ();
       per_charset = mplist_add (per_charset, MPLIST_KEY (plist), font_group);
-      MPLIST_DO (p, MPLIST_PLIST (pl))
+      MPLIST_DO (p, MPLIST_PLIST (plist))
        font_group = mplist_add (font_group, MPLIST_KEY (p), MPLIST_VAL (p));
     }
   realized->fallback = font_group = mplist ();
@@ -580,9 +584,15 @@ try_font_list (MFrame *frame, MFontList *font_list, MFont *request,
       /* Check if this font can display all glyphs.  */
       for (j = 0; j < *num; j++)
        {
-         int c = g[j].type == GLYPH_CHAR ? g[j].c : ' ';
+         int c = g[j].type == GLYPH_CHAR ? g[j].g.c : ' ';
+         MFLT *flt;
+         MCharTable *coverage;
+
          if (layouter != Mt
-             ? mfont__flt_encode_char (layouter, c) == MCHAR_INVALID_CODE
+             ? ((flt = mflt_get (layouter))
+                ? (coverage = mflt_coverage (flt),
+                   ! mchartable_lookup (coverage, c))
+                : 0)
              : ! mfont__has_char (frame, font, &font_list->object, c))
            break;
        }
@@ -590,6 +600,8 @@ try_font_list (MFrame *frame, MFontList *font_list, MFont *request,
        continue;
       if (j == *num || !all)
        {
+         MCharTable *coverage = NULL;
+
          /* We found a font that can display the requested range of
             glyphs.  */
          if (font->type == MFONT_TYPE_REALIZED)
@@ -602,15 +614,22 @@ try_font_list (MFrame *frame, MFontList *font_list, MFont *request,
              font_list->fonts[i].font = (MFont *) rfont;
            }
          rfont->layouter = layouter == Mt ? Mnil : layouter;
+         if (rfont->layouter)
+           {
+             MFLT *flt = mflt_get (rfont->layouter);
+
+             if (flt)
+               coverage = mflt_coverage (flt);
+           }
          *num = j;
          for (j = 0; j < *num; j++)
            {
-             int c = g[j].type == GLYPH_CHAR ? g[j].c : ' ';
+             int c = g[j].type == GLYPH_CHAR ? g[j].g.c : ' ';
 
-             g[j].code = (rfont->layouter
-                          ? mfont__flt_encode_char (rfont->layouter, c)
-                          : mfont__encode_char (frame, (MFont *) rfont,
-                                                &font_list->object, c));
+             g[j].g.code = (coverage
+                            ? (unsigned ) mchartable_lookup (coverage, c)
+                            : mfont__encode_char (frame, (MFont *) rfont,
+                                                  &font_list->object, c));
            }
          return rfont;
        }
@@ -735,6 +754,17 @@ mfont__lookup_fontset (MRealizedFontset *realized, MGlyph *g, int *num,
   MPlist *plist;
   MRealizedFont *rfont = NULL;
 
+  if (MDEBUG_FLAG ())
+    {
+      int i;
+
+      MDEBUG_PRINT1 (" [FONTSET] fontset looking up for %s:",
+                    script ? script->name : "none");
+      for (i = 0; i < *num; i++)
+       MDEBUG_PRINT1 (" U+%04X", g[i].g.c);
+      MDEBUG_PRINT ("\n");
+    }
+
   if (realized->tick != realized->fontset->tick)
     update_fontset_elements (realized);
 
@@ -742,17 +772,15 @@ mfont__lookup_fontset (MRealizedFontset *realized, MGlyph *g, int *num,
       && (per_charset = mplist_get (realized->per_charset, charset)) != NULL
       && (rfont = try_font_group (realized, &realized->request, per_charset,
                                  g, num, size)))
-    return rfont;
+    goto done;
 
   if (script != Mnil)
     {
       MFont request = realized->request;
 
       if (script != Mlatin)
-       /* These are not appropriate for non-Latin scripts.  */
-       request.property[MFONT_FOUNDRY]
-         = request.property[MFONT_FAMILY]
-         = request.property[MFONT_REGISTRY] = 0;
+       /* This is not appropriate for non-Latin scripts.  */
+       request.property[MFONT_REGISTRY] = 0;
 
       per_script = mplist_get (realized->per_script, script);
       if (! per_script)
@@ -773,8 +801,10 @@ mfont__lookup_fontset (MRealizedFontset *realized, MGlyph *g, int *num,
       if ((per_lang = mplist_get (per_script, language))
          && (rfont = try_font_group (realized, &request, per_lang,
                                      g, num, size)))
-       return rfont;
+       goto done;
 
+      if (per_lang && *num > 1)
+       *num = 1;
       if (language == Mt)
        {
          /* Try the above (3) */
@@ -783,7 +813,7 @@ mfont__lookup_fontset (MRealizedFontset *realized, MGlyph *g, int *num,
                && (rfont = try_font_group (realized, &request,
                                            MPLIST_PLIST (plist),
                                            g, num, size)))
-             return rfont;
+             goto done;
        }
       else
        {
@@ -791,8 +821,10 @@ mfont__lookup_fontset (MRealizedFontset *realized, MGlyph *g, int *num,
          if ((per_lang = mplist_get (per_script, Mt))
              && (rfont = try_font_group (realized, &request, per_lang,
                                          g, num, size)))
-           return rfont;
+           goto done;
 
+         if (per_lang && *num > 1)
+           *num = 1;
          /* Then try the above (3) */
          MPLIST_DO (plist, per_script)
            if (MPLIST_KEY (plist) != language
@@ -800,10 +832,10 @@ mfont__lookup_fontset (MRealizedFontset *realized, MGlyph *g, int *num,
                && (rfont = try_font_group (realized, &request,
                                            MPLIST_PLIST (plist),
                                            g, num, size)))
-             return rfont;
+             goto done;
        }
       if (ignore_fallback)
-       return NULL;
+       goto done;
     }
 
   if (language != Mnil)
@@ -819,30 +851,25 @@ mfont__lookup_fontset (MRealizedFontset *realized, MGlyph *g, int *num,
        if ((per_lang = mplist_get (MPLIST_PLIST (plist), language))
            && (rfont = try_font_group (realized, &request, per_lang,
                                        g, num, size)))
-         return rfont;
+         goto done;
       }
 
   /* Try fallback fonts.  */
-  if ((rfont = try_font_group (realized, &realized->request,
-                              realized->fallback, g, num, size)))
-    return rfont;
-
-  return NULL;
-
-  /* At last try all fonts.  */
-  MPLIST_DO (per_script, realized->per_script)
+  rfont = try_font_group (realized, &realized->request,
+                         realized->fallback, g, num, size);
+ done:
+  if (MDEBUG_FLAG ())
     {
-      MPLIST_DO (per_lang, MPLIST_PLIST (per_script))
-       if ((rfont = try_font_group (realized, &realized->request,
-                                    MPLIST_PLIST (per_lang), g, num, size)))
-         return rfont;
+      if (rfont)
+       {
+         MSymbol family = mfont_get_prop (rfont->font, Mfamily);
+         MDEBUG_PRINT1 (" [FONTSET] found %s\n", family->name);
+       }
+      else
+       MDEBUG_PRINT (" [FONTSET] not found\n");
     }
-  MPLIST_DO (per_charset, realized->per_charset)
-    if ((rfont = try_font_group (realized, &realized->request,
-                                MPLIST_PLIST (per_charset), g, num, size)))
-      return rfont;
 
-  return NULL;
+  return rfont;
 }
 
 MRealizedFont *
@@ -884,11 +911,12 @@ mfontset__get_font (MFrame *frame, MFontset *fontset,
   if (best)
     *best = 0;
 
+  if (language == Mnil)
+    language = Mt;
+
   if (script != Mnil)
     {
       per_script = get_per_script (fontset, script);
-      if (language == Mnil)
-       language = Mt;
       if ((per_lang = mplist_get (per_script, language))
          && (rfont = get_font_from_group (frame, per_lang, font)))
        {
@@ -924,7 +952,7 @@ mfontset__get_font (MFrame *frame, MFontset *fontset,
        }
     }
 
-  if (language != Mnil)
+  if (language != Mt)
     MPLIST_DO (per_script, fontset->per_script)
       {
        if ((per_lang = mplist_get (MPLIST_PLIST (per_script), language))
@@ -1162,7 +1190,7 @@ mfontset_copy (MFontset *fontset, char *name)
     are removed from the group.
 
     If $LAYOUTER_NAME is not @c Mnil, it must be a symbol representing
-    a @ref flt (font layout table).  In that case, if $FONT is
+    a @ref mdbFLT (font layout table).  In that case, if $FONT is
     selected for drawing an M-text, that font layout table is used to
     generate a glyph code sequence from a character sequence.
 
@@ -1199,7 +1227,7 @@ mfontset_copy (MFontset *fontset, char *name)
     ¤¬Éé¤Ê¤é¤Ð¡¢ºÇÄã¤ÎÍ¥ÀèÅÙ¤ò»ý¤Ä¡£$HOW ¤¬ 0 ¤Ê¤é¤Ð¡¢$FONT 
     ¤Ï´ØÏ¢ÉÕ¤±¤é¤ì¤¿¤â¤Î¤ËÂФ¹¤ëÍ£°ì¤ÎÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤È¤Ê¤ê¡¢Â¾¤Î¥Õ¥©¥ó¥È¤Ï¥°¥ë¡¼¥×¤«¤é¼è¤ê½ü¤«¤ì¤ë¡£
 
-    $LAYOUTER_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢@ref flt 
+    $LAYOUTER_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢@ref mdbFLT 
     ¡Ê¥Õ¥©¥ó¥È¥ì¥¤¥¢¥¦¥È¥Æ¡¼¥Ö¥ë¡Ë¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£¥·¥ó¥Ü¥ë¤Ç¤¢¤ì¤Ð¡¢$FONT ¤òÍѤ¤¤Æ
     M-text ¤òɽ¼¨¤¹¤ëºÝ¤Ë¤Ï¡¢¤½¤Î¥Õ¥©¥ó¥È¥ì¥¤¥¢¥¦¥È¥Æ¡¼¥Ö¥ë¤ò»È¤Ã¤Æʸ»úÎ󤫤饰¥ê¥Õ¥³¡¼¥ÉÎó¤òÀ¸À®¤¹¤ë¡£
 
@@ -1422,17 +1450,19 @@ mfontset_lookup (MFontset *fontset,
 /***en
     @brief Dump a fontset.
 
-    The mdebug_dump_fontset () function prints fontset $FONTSET in a human readable
-    way to the stderr.  $INDENT specifies how many columns to indent
-    the lines but the first one.
+    The mdebug_dump_fontset () function prints fontset $FONTSET in a
+    human readable way to the stderr or to what specified by the
+    environment variable MDEBUG_OUTPUT_FILE.  $INDENT specifies how
+    many columns to indent the lines but the first one.
 
     @return
     This function returns $FONTSET.  */
 /***ja
     @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤ò¥À¥ó¥×¤¹¤ë.
 
-    ´Ø¿ô mdebug_dump_face () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤ò stderr 
-    ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
+    ´Ø¿ô mdebug_dump_face () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤òɸ½à¥¨¥é¡¼½ÐÎÏ
+    ¤â¤·¤¯¤Ï´Ä¶­ÊÑ¿ô MDEBUG_DUMP_FONT ¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë¿Í´Ö¤Ë²ÄÆÉ
+    ¤Ê·Á¤Ç½ÐÎϤ¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
 
     @return
     ¤³¤Î´Ø¿ô¤Ï $FONTSET ¤òÊÖ¤¹¡£  */
@@ -1446,48 +1476,50 @@ mdebug_dump_fontset (MFontset *fontset, int indent)
   memset (prefix, 32, indent);
   prefix[indent] = 0;
 
-  fprintf (stderr, "(fontset %s", fontset->name->name);
+  fprintf (mdebug__output, "(fontset %s", fontset->name->name);
   if (fontset->per_script)
     MPLIST_DO (plist, fontset->per_script)
       {
-       fprintf (stderr, "\n  %s(%s", prefix, MPLIST_KEY (plist)->name);
+       fprintf (mdebug__output, "\n  %s(%s", prefix, MPLIST_KEY (plist)->name);
        MPLIST_DO (pl, MPLIST_PLIST (plist))
          {
-           fprintf (stderr, "\n    %s(%s", prefix, MPLIST_KEY (pl)->name);
+           fprintf (mdebug__output, "\n    %s(%s", prefix,
+                    MPLIST_KEY (pl)->name);
            MPLIST_DO (p, MPLIST_PLIST (pl))
              {
-               fprintf (stderr, "\n      %s(0x%X %s ", prefix,
+               fprintf (mdebug__output, "\n      %s(0x%X %s ", prefix,
                         (unsigned) MPLIST_VAL (p),
                         MPLIST_KEY (p)->name);
                mdebug_dump_font (MPLIST_VAL (p));
-               fprintf (stderr, ")");
+               fprintf (mdebug__output, ")");
              }
-           fprintf (stderr, ")");
+           fprintf (mdebug__output, ")");
          }
-       fprintf (stderr, ")");
+       fprintf (mdebug__output, ")");
       }
   if (fontset->per_charset)
     MPLIST_DO (pl, fontset->per_charset)
       {
-       fprintf (stderr, "\n  %s(%s", prefix, MPLIST_KEY (pl)->name);
+       fprintf (mdebug__output, "\n  %s(%s", prefix, MPLIST_KEY (pl)->name);
        MPLIST_DO (p, MPLIST_PLIST (pl))
          {
-           fprintf (stderr, "\n    %s(%s ", prefix, MPLIST_KEY (p)->name);
+           fprintf (mdebug__output, "\n    %s(%s ", prefix,
+                    MPLIST_KEY (p)->name);
            mdebug_dump_font (MPLIST_VAL (p));
-           fprintf (stderr, ")");
+           fprintf (mdebug__output, ")");
          }
-       fprintf (stderr, ")");
+       fprintf (mdebug__output, ")");
       }
 
   if (fontset->fallback)
     MPLIST_DO (p, fontset->fallback)
       {
-       fprintf (stderr, "\n  %s(%s ", prefix, MPLIST_KEY (p)->name);
+       fprintf (mdebug__output, "\n  %s(%s ", prefix, MPLIST_KEY (p)->name);
        mdebug_dump_font (MPLIST_VAL (p));
-       fprintf (stderr, ")");
+       fprintf (mdebug__output, ")");
       }
 
-  fprintf (stderr, ")");
+  fprintf (mdebug__output, ")");
   return fontset;
 }