(compose_glyph_string): When the script `inherited' and
[m17n/m17n-lib.git] / src / draw.c
index 976b58b..f5b23cf 100644 (file)
@@ -1,5 +1,5 @@
 /* draw.c -- drawing module.
-   Copyright (C) 2003, 2004, 2005, 2006
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H15PRO112
 
@@ -176,7 +176,7 @@ visual_order (MGlyphString *gstring)
 
   memcpy (glyphs, gstring->glyphs, sizeof (MGlyph) * gstring->used);
 
-  for (i = gidx = 0; i < gstring->used; gidx++)
+  for (i = gidx = 0; i < gstring->used - 1; gidx++)
     {
       int level = glyphs[i].bidi_level;
       
@@ -238,39 +238,23 @@ visual_order (MGlyphString *gstring)
     }
 }
 
-#if 0
-static void
-reorder_combining_chars (MGlyphString *gstring, int from, int to)
+static MSymbol
+font_id (MFLTFont *font)
 {
-  MGlyph *g, *gbeg = MGLYPH (from + 1), *gend = MGLYPH (to), temp;
-  int reordered = 1;
-  
-  while (reordered)
-    {
-      reordered = 0;
-      for (g = gbeg; g != gend; g++)
-       if (COMBINING_CODE_CLASS (g->combining_code) > 0
-           && (COMBINING_CODE_CLASS (g[-1].combining_code)
-               > COMBINING_CODE_CLASS (g->combining_code)))
-         {
-           reordered = 1;
-           temp = *g;
-           *g = g[-1];
-           g[-1] = temp;
-         }
-    }
+  return ((MFLTFontForRealized *) font)->rfont->id;
 }
-#endif
 
 static int
-run_flt (MGlyphString *gstring, int from, int to, MRealizedFont *rfont,
-        MSymbol layouter)
+run_flt (MGlyphString *gstring, int from, int to, MRealizedFace *rface)
 {
+  MRealizedFont *rfont = rface->rfont;
+  MSymbol layouter = rface->layouter;
   MFLTGlyphString flt_gstr;
   MFLTFontForRealized font;
   MFLT *flt;
   int from_pos = MGLYPH (from)->g.from;
   int len = to - from;
+  int catcode;
   int i;
 
   flt = mflt_get (layouter);
@@ -288,6 +272,9 @@ run_flt (MGlyphString *gstring, int from, int to, MRealizedFont *rfont,
   font.font.drive_otf = rfont->driver->drive_otf;
   font.font.internal = NULL;
   font.rfont = rfont;
+  mflt_font_id = font_id;
+  mflt_iterate_otf_feature = rfont->driver->iterate_otf_feature;
+  mflt_try_otf = rfont->driver->try_otf;
   for (i = 0; i < 3; i++)
     {
       to = mflt_run (&flt_gstr, from, to, &font.font, flt);
@@ -299,7 +286,7 @@ run_flt (MGlyphString *gstring, int from, int to, MRealizedFont *rfont,
     }
   if (from + len != to)
     gstring->used += to - (from + len);
-  for (i = from; i < to; i++)
+  for (i = from, catcode = -1; i < to; i++)
     {
       MGlyph *g = MGLYPH (i);
 
@@ -313,6 +300,18 @@ run_flt (MGlyphString *gstring, int from, int to, MRealizedFont *rfont,
       g->g.rbearing >>= 6;
       g->g.xoff >>= 6;
       g->g.yoff >>= 6;
+      g->rface = rface;
+      if (catcode < 0 || g->g.from != g[-1].g.from)
+       {
+         MSymbol category = mchar_get_prop (g->g.c, Mcategory);
+
+         catcode = (category == McatCf
+                    ? GLYPH_CATEGORY_FORMATTER
+                    : category != Mnil && MSYMBOL_NAME (category)[0] == 'M'
+                    ? GLYPH_CATEGORY_MODIFIER
+                    : GLYPH_CATEGORY_NORMAL);
+       }
+      g->category = catcode;
     }
   return to;
 }
@@ -462,7 +461,7 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
                {
                  MSymbol category = mchar_get_prop (g[-1].g.c, Mcategory);
 
-                 if (MSYMBOL_NAME (category)[0] != 'Z')
+                 if (category != Mnil && MSYMBOL_NAME (category)[0] != 'Z')
                    this_script = script;
                }
            }
@@ -484,6 +483,8 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
                    break;
                  }
            }
+         if (this_script == Minherited || this_script == Mcommon)
+           this_script = (MSymbol) mchar_get_prop (c, Mblock);
        }
 
       pos = g->g.from;
@@ -541,8 +542,8 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
                                             NULL, prev->g.c)
                         != MCHAR_INVALID_CODE))
                {
-                 start--, prev--;
                  prev->rface->rfont = this->rface->rfont;
+                 start--, prev--;
                }
 
              for (g++;
@@ -556,8 +557,7 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
                                != MCHAR_INVALID_CODE))));
                   i++, g++)
                g->rface->rfont = this->rface->rfont;
-             i = run_flt (gstring, start, i, this->rface->rfont,
-                          this->rface->layouter);
+             i = run_flt (gstring, start, i, this->rface);
            }
          else
            {
@@ -566,10 +566,13 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
                     && g->g.c >= 0x100
                     && g->category == GLYPH_CATEGORY_MODIFIER
                     && g->rface->rfont
-                    && g->rface->rfont->layouter == Mnil)
+                    && g->rface->layouter == Mnil)
                i++, g++;
              if (start + 1 < i)
-               run_flt (gstring, start, i, this->rface->rfont, Mcombining);
+               {
+                 this->rface->layouter = Mcombining;
+                 run_flt (gstring, start, i, this->rface);
+               }
              else
                mfont__get_metric (gstring, start, i);
            }
@@ -1511,6 +1514,7 @@ get_gstring (MFrame *frame, MText *mt, int pos, int to, MDrawControl *control)
              || memcmp (control, &gstring->control,
                         (char *) (&control->with_cursor)
                         - (char *) (control))
+             || control->cursor_pos != gstring->control.cursor_pos
              || control->cursor_width != gstring->control.cursor_width
              || control->cursor_bidi != gstring->control.cursor_bidi)
            {
@@ -1744,7 +1748,11 @@ mdraw__init ()
   MbidiS = msymbol ("S");
   MbidiNSM = msymbol ("NSM");
 #ifdef HAVE_FRIBIDI
+#if FRIBIDI_INTERFACE_VERSION < 3
   fribidi_set_mirroring (TRUE);
+#else
+  fribidi_set_mirroring (1);
+#endif
 #endif
 
   M_break_at_space = msymbol ("bs");
@@ -1753,6 +1761,8 @@ mdraw__init ()
   M_kinsoku_bol = msymbol ("kb");
   M_kinsoku_eol = msymbol ("ke");
 
+  mflt_enable_new_feature = 1;
+
   return 0;
 }
 
@@ -1959,7 +1969,7 @@ mdraw_text (MFrame *frame, MDrawWindow win, int x, int y,
 
     @return
     ½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mdraw_image_text () ¤Ï 0 
-    ¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #m_errro ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
+    ¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
 
     @latexonly \IPAlabel{mdraw_image_text} @endlatexonly   */
 
@@ -1995,7 +2005,7 @@ mdraw_image_text (MFrame *frame, MDrawWindow win, int x, int y,
     this function also follows what specified in the drawing control
     object $CONTROL.
 
-    For instance, if <two_dimensional> of $CONTROL is nonzero, this
+    For instance, if \<two_dimensional\> of $CONTROL is nonzero, this
     function draw an M-text 2-dimensionally, i.e., newlines in M-text
     breaks lines and the following characters are drawn in the next
     line.  See the documentation of the structure @ MDrawControl for
@@ -2011,7 +2021,7 @@ mdraw_image_text (MFrame *frame, MDrawWindow win, int x, int y,
     ¥Æ¥­¥¹¥È¤ÎÉÁ²èÊýË¡¤Ï mdraw_text () ¤È¤Û¤ÜƱ¤¸¤Ç¤¢¤ë¤¬¡¢¤³¤Î´Ø¿ô¤ÏÉÁ²èÀ©¸æÍѤΥª¥Ö¥¸¥§¥¯¥È
     $CONTROL ¤Î»Ø¼¨¤Ë¤â½¾¤¦ÅÀ¤¬°Û¤Ê¤Ã¤Æ¤¤¤ë¡£
 
-    ¤¿¤È¤¨¤Ð $CONTROL ¤Î <two_dimensional> ¤¬¥¼¥í¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 
+    ¤¿¤È¤¨¤Ð $CONTROL ¤Î \<two_dimensional\> ¤¬¥¼¥í¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 
     M-text ¤ò2¼¡¸µÅª¤ËÉÁ¤¯¡£¤¹¤Ê¤ï¤Á M-text Ãæ¤Î²þ¹Ô¤Ç¹Ô¤ò²þ¤á¡¢Â³¤¯Ê¸»ú¤Ï¼¡¤Î¹Ô¤ËÉÁ¤¯¡£¾ÜºÙ¤Ï¹½Â¤ÂÎ
     @ MDrawControl ¤ÎÀâÌÀ¤ò»²¾È¤¹¤ë¤³¤È¡£*/
 
@@ -2729,10 +2739,14 @@ mdraw_glyph_list (MFrame *frame, MText *mt, int from, int to,
          if (g->rface->rfont)
            {
              glyphs->font = (MFont *) g->rface->rfont;
+#ifdef HAVE_FREETYPE
              glyphs->font_type
                = (glyphs->font->source == MFONT_SOURCE_X ? Mx
                   : g->rface->rfont->driver == &mfont__ft_driver ? Mfreetype
                   : Mxft);
+#else  /* not HAVE_FREETYPE */
+             glyphs->font_type = Mx;
+#endif /* not HAVE_FREETYPE */
              glyphs->fontp = g->rface->rfont->fontp;
            }
          else
@@ -2823,7 +2837,8 @@ int mdraw_line_break_option;
     character, and incremented each time when a long line is broken
     because of the width limit.
 
-    @return This function returns a character position to break the
+    @return 
+    This function returns a character position to break the
     line.
 */