*** empty log message ***
[m17n/m17n-lib.git] / src / draw.c
index c97c8c1..033b69e 100644 (file)
@@ -34,7 +34,7 @@
     ways, which provides powerful 2-dimensional layouting
     facility.  */
 
-/***ja
+/***oldja
     @addtogroup m17nDraw
     @brief M-text É½¼¨¤Î¤¿¤á¤Î m17n-gui API
 
@@ -79,6 +79,8 @@ static MSymbol Mlatin, Minherited;
 /* Special categories */
 static MSymbol McatCc, McatCf;
 
+static MSymbol Mdepth;
+
 \f
 /* Glyph-string composer.  */
 
@@ -127,8 +129,7 @@ visual_order (MGlyphString *gstring)
        levels[size] = 0;
       idx[size] = GLYPH_INDEX (g);
       logical[size++] = g++->c;
-      while (g->type != GLYPH_ANCHOR
-            && g->combining_code)
+      while (g->type != GLYPH_ANCHOR && g->combining_code)
        g++;
     }
 
@@ -170,7 +171,6 @@ visual_order (MGlyphString *gstring)
     {
       int j = indices[i];
       int k = idx[j];
-      int pos = glyphs[k].pos;
 
       glyphs[k].bidi_level = levels[j];
 #ifdef HAVE_FRIBIDI
@@ -185,8 +185,7 @@ visual_order (MGlyphString *gstring)
 #endif /* not HAVE_FRIBIDI */
       *(MGLYPH (gidx)) = glyphs[k];
       for (gidx++, k++;
-          (k < gstring->used - 1
-           && (glyphs[k].pos == pos || glyphs[k].combining_code));
+          k < gstring->used - 1 && glyphs[k].combining_code;
           gidx++, k++)
        {
          glyphs[k].bidi_level = levels[j];
@@ -237,8 +236,8 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
   MRealizedFace *rface = default_rface;
   int non_ascii_found;
   int size = gstring->control.fixed_width;
-  int ignore_formatting_char = gstring->control.ignore_formatting_char;
   int i, limit;
+  int last;
 
   MLIST_RESET (gstring);
   gstring->from = from;
@@ -254,7 +253,7 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
   APPEND_GLYPH (gstring, g_tmp);
 
   stop = face_change = charset_change = language_change = pos = from;
-  g = gstring->glyphs + gstring->used;
+  last = 0;
   non_ascii_found = 0;
   while (1)
     {
@@ -276,24 +275,21 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
       else
        {
          g_tmp.category = mchar_get_prop (c, Mcategory);
-         if (ignore_formatting_char && g_tmp.category == McatCf)
-           g_tmp.type = GLYPH_SPACE, this_script = Mnil;
-         else
-           {
-             g_tmp.type = GLYPH_CHAR;
-             this_script = (MSymbol) mchar_get_prop (c, Mscript);
-             if (this_script == Minherited)
-               this_script = script;
-           }
+         g_tmp.type = GLYPH_CHAR;
+         this_script = (MSymbol) mchar_get_prop (c, Mscript);
+         if (this_script == Minherited)
+           this_script = script;
        }
 
-      if (pos == stop || script != this_script || g->type != g_tmp.type)
+      if (pos == stop || script != this_script
+         || MGLYPH (last)->type != g_tmp.type)
        {
+         g = MGLYPH (last);
          if (non_ascii_found && g->type == GLYPH_CHAR)
            while (g < gstring->glyphs + gstring->used)
              g = mface__for_chars (script, language, charset,
                                    g, gstring->glyphs + gstring->used, size);
-         g = gstring->glyphs + gstring->used;
+         last = gstring->used;
          non_ascii_found = 0;
          script = this_script;
          if (pos == to)
@@ -320,7 +316,9 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
                                         language, charset, size)
                       : default_rface);
            }
-         stop = language_change;
+         stop = to;
+         if (stop > language_change)
+           stop = language_change;
          if (stop > charset_change)
            stop = charset_change;
          if (face_change < stop)
@@ -336,12 +334,12 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
        non_ascii_found = 1;
       else if (g_tmp.type == GLYPH_CHAR && (c <= 32 || c == 127))
        {
-         g_tmp.c = '^';
+         g_tmp.code = '^';
          APPEND_GLYPH (gstring, g_tmp);
          if (c < ' ')
-           g_tmp.c += 0x40;
+           g_tmp.code = g_tmp.c + 0x40;
          else
-           g_tmp.c = '?';
+           g_tmp.code = '?';
        }
       APPEND_GLYPH (gstring, g_tmp);
       if (c == '\n'
@@ -369,17 +367,31 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to,
       if (this->type == GLYPH_CHAR && this->rface->rfont)
        {
          int start = i++;
-         MGlyph *tmp = gstring->glyphs + i;
 
          if (this->rface->rfont->layouter != Mnil)
            {
-             while ((tmp->type == GLYPH_CHAR || tmp->type == GLYPH_SPACE)
-                    && tmp->rface->rfont == this->rface->rfont
-                    && tmp->code != MCHAR_INVALID_CODE)
-               i++, tmp++;
-             i = mfont__flt_run (gstring, start, i,
-                                 this->rface->rfont->layouter,
-                                 this->rface->ascii_rface);
+             MGlyph *prev;
+             unsigned code;
+
+             for (prev = MGLYPH (start - 1);
+                  (prev->type == GLYPH_CHAR
+                   && prev->category == McatCf
+                   && (code = mfont__encode_char (this->rface->rfont, prev->c)
+                       != MCHAR_INVALID_CODE));
+                  start--, prev--)
+               prev->code = code;
+
+             for (g++;
+                  (g->type == GLYPH_CHAR
+                   && (g->rface->rfont == this->rface->rfont
+                       || (g->category == McatCf
+                           && ((code = mfont__encode_char (this->rface->rfont,
+                                                           g->c))
+                               != MCHAR_INVALID_CODE))));
+                  i++, g++)
+               if (g->rface->rfont != this->rface->rfont)
+                 g->code = code;
+             i = mfont__flt_run (gstring, start, i, this->rface);
            }
          else
            {
@@ -474,6 +486,8 @@ layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to)
   g_physical_descent = gstring->physical_descent;
   g_width = g_lbearing = g_rbearing = 0;
 
+  mfont__get_metric (gstring, from, to);
+
   while (g < last_g)
     {
       MGlyph *base = g++;
@@ -481,7 +495,6 @@ layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to)
       int size = rfont->font.property[MFONT_SIZE];
       int width, lbearing, rbearing;
 
-      mfont__get_metric (rfont, base);
       if (g == last_g || ! g->combining_code)
        {
          /* No combining.  */
@@ -541,7 +554,6 @@ layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to)
              else if (end < g->to)
                end = g->to;
                
-             mfont__get_metric (rfont, g);
              g->xoff = left + (width * base_x - g->width * add_x) / 2 + off_x;
              if (g->xoff < left)
                left = g->xoff;
@@ -572,6 +584,8 @@ layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to)
 
          base->ascent = - top;
          base->descent = bottom;
+         base->lbearing = lbearing;
+         base->rbearing = rbearing;
          if (left < - base->width)
            {
              base->xoff = - base->width - left;
@@ -629,6 +643,7 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring)
   int width;
   MFaceBoxProp *box;
   int box_line_height = 0;
+  int ignore_formatting_char = control->ignore_formatting_char;
 
   gstring->ascent = gstring->descent = 0;
   gstring->physical_ascent = gstring->physical_descent = 0;
@@ -691,6 +706,9 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring)
            }
        }
 
+      if (g->category == McatCf && ignore_formatting_char)
+       g->type = GLYPH_SPACE;
+
       if (g->type == GLYPH_CHAR)
        {
          MRealizedFace *rface = g->rface;
@@ -702,7 +720,8 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring)
            if (! rfont != ! g->rface->rfont
                || box != g->rface->box
                || ((fromg->code == MCHAR_INVALID_CODE)
-                   != (g->code == MCHAR_INVALID_CODE)))
+                   != (g->code == MCHAR_INVALID_CODE))
+               || (g->category == McatCf && ignore_formatting_char))
              break;
          if (rfont && fromg->code != MCHAR_INVALID_CODE)
            {
@@ -1125,7 +1144,8 @@ render_glyphs (MFrame *frame, MDrawWindow win, int x, int y, int width,
       rect.x += rect.width;
       if (rect.x < x + width)
        {
-         while (g != gend && x + width - gend[-1].width >= rect.x)
+         while (g != gend
+                && (x + width - gend[-1].width + gend[-1].lbearing >= rect.x))
            {
              width -= (--gend)->width;
              while (! gend->enabled && g != gend)
@@ -1341,7 +1361,8 @@ free_gstring (void *object)
 static MGlyphString scratch_gstring;
 
 static MGlyphString *
-alloc_gstring (MText *mt, int pos, MDrawControl *control, int line, int y)
+alloc_gstring (MFrame *frame, MText *mt, int pos, MDrawControl *control,
+              int line, int y)
 {
   MGlyphString *gstring;
 
@@ -1364,6 +1385,10 @@ alloc_gstring (MText *mt, int pos, MDrawControl *control, int line, int y)
     (*control->format) (line, y, &(gstring->indent), &(gstring->width_limit));
   else
     gstring->width_limit = control->max_line_width;
+  gstring->anti_alias = control->anti_alias;
+  if (gstring->anti_alias
+      && (unsigned) mwin__device_get_prop (frame->device, Mdepth) < 8)
+    gstring->anti_alias = 0;
   return gstring;
 }
 
@@ -1489,7 +1514,7 @@ get_gstring (MFrame *frame, MText *mt, int pos, int to, MDrawControl *control)
          beg = pos;
          end = to;
        }
-      gstring = alloc_gstring (mt, beg, control, line, y);
+      gstring = alloc_gstring (frame, mt, beg, control, line, y);
       compose_glyph_string (frame, mt, beg, end, gstring);
       layout_glyph_string (frame, gstring);
       end = gstring->to;
@@ -1503,7 +1528,8 @@ get_gstring (MFrame *frame, MText *mt, int pos, int to, MDrawControl *control)
          while (gst->to < end)
            {
              line++, y += gst->height;
-             gst->next = alloc_gstring (mt, gst->from, control, line, y);
+             gst->next = alloc_gstring (frame, mt, gst->from, control,
+                                        line, y);
              gst->next->top = gstring;
              compose_glyph_string (frame, mt, gst->to, end, gst->next);
              gst = gst->next;
@@ -1625,7 +1651,7 @@ dump_combining_code (int code)
   else if (off_y < 0)
     sprintf (work + 2, "%d", off_y);
   else if (off_x == 0)
-    sprintf (work + 2, "-");
+    sprintf (work + 2, ".");
   p = work + strlen (work);
   if (off_x > 0)
     sprintf (p, ">%d", off_x);
@@ -1679,6 +1705,7 @@ mdraw__init ()
 
   McatCc = msymbol ("Cc");
   McatCf = msymbol ("Cf");
+  Mdepth = msymbol ("depth");
 
   MbidiR = msymbol ("R");
   MbidiAL = msymbol ("AL");
@@ -1776,7 +1803,7 @@ mdraw__fini ()
     error is detected, it returns -1 and assigns an error code to the
     external variable @c merror_code.  */
 
-/***ja
+/***oldja
     @brief ¥¦¥£¥ó¥É¥¦¤Ë M-text ¤òɽ¼¨¤¹¤ë
 
     ´Ø¿ô mdraw_text () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤ÎºÂɸ 
@@ -1878,7 +1905,7 @@ mdraw_text (MFrame *frame, MDrawWindow win, int x, int y,
     If an error is detected, it returns -1 and assigns an error code
     to the external variable @c merror_code.  */
 
-/***ja
+/***oldja
     @brief ¥Ç¥£¥¹¥×¥ì¥¤¤ËM-text ¤ò²èÁü¤È¤·¤ÆÉÁ¤¯
 
     ´Ø¿ô mdraw_image_text () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¤Î¥¦¥£¥ó¥É¥¦ $WIN ¤Î
@@ -1981,7 +2008,7 @@ mdraw_text_with_control (MFrame *frame, MDrawWindow win, int x, int y,
     the widest line.  If an error occurs, it returns -1 and assigns an
     error code to the external variable @c merror_code.  */
 
-/***ja
+/***oldja
     @brief ¥Æ¥­¥¹¥È¤ÎÉý¤ò·×»»¤¹¤ë
 
     ´Ø¿ô mdraw_text_extents () ¤Ï¡¢M-text $MT ¤Î $FROM ¤«¤é $TO ¤Þ¤Ç¤ò
@@ -2232,7 +2259,7 @@ mdraw_text_per_char_extents (MFrame *frame,
     maximum X-coordinate, it returns the character position of the
     last character drawn on the line $Y.  */
 
-/***ja
+/***oldja
     @brief »ØÄꤷ¤¿ºÂɸ¤Ë¤¢¤ëʸ»ú¤Î°ÌÃÖ¤òÆÀ¤ë
 
     ´Ø¿ô mdraw_coordinates_position () ¤Ï¡¢
@@ -2511,7 +2538,7 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos,
     of the textitems to be drawn and $NITEMS is the number of
     textimtems in the array.  */
 
-/***ja
+/***oldja
     @brief textitem ¤òɽ¼¨¤¹¤ë
 
     ´Ø¿ô mdraw_text_items () ¤Ï¡¢°ì¸Ä°Ê¾å¤Î¥Æ¥­¥¹¥È¥¢¥¤¥Æ¥à¤ò¡¢¥Õ¥ì¡¼
@@ -2597,7 +2624,7 @@ mdraw_default_line_break (MText *mt, int pos,
     computes the extents of the overall text and stores the results in
     the members of the structure pointed to by $OVERALL_RETURN  */
 
-/***ja
+/***oldja
     @brief M-text ¤Îʸ»úËè¤Î¾ðÊó¤òÆÀ¤ë
 
     ´Ø¿ô mdraw_per_char_extents () ¤Ï¡¢M-text $MT Ãæ¤Î³Æʸ»ú¤Îɽ¼¨ÈÏ°Ï