*** empty log message ***
authorhanda <handa>
Sun, 14 Mar 2004 23:54:56 +0000 (23:54 +0000)
committerhanda <handa>
Sun, 14 Mar 2004 23:54:56 +0000 (23:54 +0000)
src/m17n-X.c

index 2a33689..e357b06 100644 (file)
@@ -84,11 +84,32 @@ typedef struct
 /* Anchor of the chain of MDisplayInfo objects.  */
 static MPlist *display_info_list;
 
+
+/* Color value and the corresponding GC.  */
 typedef struct
 {
   unsigned int rgb;           /* (red << 16) | (green << 8) | blue */
   GC gc;
-} MColorGC;
+} RGB_GC;
+
+enum face_gc
+  {
+    MFACE_GC_NORMAL,
+    MFACE_GC_INVERSE,
+    MFACE_GC_HLINE,
+    MFACE_GC_BOX_TOP,
+    MFACE_GC_BOX_BOTTOM,
+    MFACE_GC_BOX_LEFT,
+    MFACE_GC_BOX_RIGHT,
+    MFACE_GCS
+  };
+
+typedef struct
+{
+  int rgb_fore;
+  int rgb_back;
+  GC gc[MFACE_GCS + 8];
+} GCInfo;
 
 struct MWDevice
 {
@@ -105,7 +126,7 @@ struct MWDevice
 
   Colormap cmap;
 
-  GC gc_fore, gc_back, gc_scratch;
+  GCInfo gc_info;
 
   /** List of pointers to realized faces on the frame.  */
   MPlist *realized_face_list;
@@ -124,18 +145,6 @@ static MSymbol M_iso8859_1, M_iso10646_1;
 #define FRAME_DISPLAY(frame) (frame->device->display_info->display)
 #define FRAME_SCREEN(frame) (frame->device->screen_num)
 
-enum face_gc
-  {
-    MFACE_GC_NORMAL,
-    MFACE_GC_INVERSE,
-    MFACE_GC_HLINE,
-    MFACE_GC_BOX_TOP,
-    MFACE_GC_BOX_BOTTOM,
-    MFACE_GC_BOX_LEFT,
-    MFACE_GC_BOX_RIGHT,
-    MFACE_GCS
-  };
-
 static void
 free_display_info (void *object)
 {
@@ -205,7 +214,7 @@ free_device (void *object)
   MPLIST_DO (plist, device->gc_list)
     {
       XFreeGC (device->display_info->display,
-              ((MColorGC *) MPLIST_VAL (plist))->gc);
+              ((RGB_GC *) MPLIST_VAL (plist))->gc);
       free (MPLIST_VAL (plist));
     }
   M17N_OBJECT_UNREF (device->gc_list);
@@ -732,9 +741,11 @@ set_region (MFrame *frame, GC gc, MDrawRegion region)
 {
   unsigned long valuemask = GCForeground;
 
-  XCopyGC (FRAME_DISPLAY (frame), gc, valuemask, frame->device->gc_scratch);
-  XSetRegion (FRAME_DISPLAY (frame), frame->device->gc_scratch, region);
-  return frame->device->gc_scratch;
+  XCopyGC (FRAME_DISPLAY (frame), gc, valuemask,
+          frame->device->gc_info.gc[MFACE_GCS]);
+  XSetRegion (FRAME_DISPLAY (frame), frame->device->gc_info.gc[MFACE_GCS],
+             region);
+  return frame->device->gc_info.gc[MFACE_GCS];
 }
 
 /* The X font driver function RENDER.  */
@@ -746,8 +757,8 @@ xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring,
   MRealizedFace *rface = from->rface;
   Display *display;
   XChar2b *code;
-  GC *gcs = rface->info;
-  GC gc = gcs[reverse ? MFACE_GC_INVERSE : MFACE_GC_NORMAL];
+  GC gc = ((GCInfo *) rface->info)->gc[reverse ? MFACE_GC_INVERSE
+                                      : MFACE_GC_NORMAL];
   MGlyph *g;
   int i;
 
@@ -1264,6 +1275,7 @@ mwin__open_device (MFrame *frame, MPlist *param)
     {
       unsigned long valuemask = GCForeground;
       XGCValues values;
+      XColor color;
 
       M17N_OBJECT (device, free_device, MERROR_WIN);
       device->display_info = disp_info;
@@ -1277,13 +1289,23 @@ mwin__open_device (MFrame *frame, MPlist *param)
       device->realized_face_list = mplist ();
       device->realized_fontset_list = mplist ();
       values.foreground = BlackPixel (display, screen_num);
-      device->gc_fore = XCreateGC (display, device->drawable,
-                                  valuemask, &values);
-      device->gc_scratch = XCreateGC (display, device->drawable,
-                                     valuemask, &values);
+      color.pixel = values.foreground;
+      XQueryColor (display, cmap, &color);
+      device->gc_info.rgb_fore
+       = (((color.red >> 8) << 16) | ((color.green >> 8) << 8)
+          | (color.blue >> 8));
+      device->gc_info.gc[MFACE_GC_NORMAL]
+       = XCreateGC (display, device->drawable, valuemask, &values);
+      device->gc_info.gc[MFACE_GCS]
+       = XCreateGC (display, device->drawable, valuemask, &values);
       values.foreground = WhitePixel (display, screen_num);
-      device->gc_back = XCreateGC (display, device->drawable,
-                                  valuemask, &values);
+      color.pixel = values.foreground;
+      XQueryColor (display, cmap, &color);
+      device->gc_info.rgb_back
+       = (((color.red >> 8) << 16) | ((color.green >> 8) << 8)
+          | (color.blue >> 8));
+      device->gc_info.gc[MFACE_GC_INVERSE]
+       = XCreateGC (display, device->drawable, valuemask, &values);
       device->gc_list = mplist ();
     }
 
@@ -1387,7 +1409,7 @@ struct {
 
 
 static GC
-get_gc (MFrame *frame, MSymbol color, int for_foreground)
+get_gc (MFrame *frame, MSymbol color, int for_foreground, int *rgb_ret)
 {
   MWDevice *device = frame->device;
   XColor xcolor;
@@ -1395,101 +1417,128 @@ get_gc (MFrame *frame, MSymbol color, int for_foreground)
   unsigned long valuemask = GCForeground;
   XGCValues values;
   GC gc;
-  MColorGC *color_gc;
-  unsigned int rgb;
+  RGB_GC *rgb_gc;
+  int rgb;
+
+  if (color == Mnil)
+    {
+      if (for_foreground)
+       rgb = device->gc_info.rgb_fore,
+         gc = device->gc_info.gc[MFACE_GC_NORMAL];
+      else
+       rgb = device->gc_info.rgb_back,
+         gc = device->gc_info.gc[MFACE_GC_INVERSE];
+      if (rgb_ret)
+       *rgb_ret = rgb;
+      return gc;
+    }
 
   if (! XParseColor (FRAME_DISPLAY (frame), device->cmap,
                     msymbol_name (color), &xcolor))
-    return (for_foreground ? device->gc_fore : device->gc_back);
+    goto no_color;
   rgb = (((xcolor.red >> 8) << 16) | ((xcolor.green >> 8) << 8)
         | (xcolor.blue >> 8));
+  if (rgb_ret)
+    *rgb_ret = rgb;
 
   MPLIST_DO (plist, device->gc_list)
     {
-      color_gc = MPLIST_VAL (plist);
+      rgb_gc = MPLIST_VAL (plist);
 
-      if (color_gc->rgb == rgb)
-       return color_gc->gc;
-      if (color_gc->rgb > rgb)
+      if (rgb_gc->rgb == rgb)
+       return rgb_gc->gc;
+      if (rgb_gc->rgb > rgb)
        break;
     }
   if (! XAllocColor (FRAME_DISPLAY (frame), device->cmap, &xcolor))
-    return (for_foreground ? device->gc_fore : device->gc_back);
+    goto no_color;
   values.foreground = xcolor.pixel;
   gc = XCreateGC (FRAME_DISPLAY (frame), device->drawable, valuemask, &values);
-  color_gc = malloc (sizeof (MColorGC));
-  color_gc->rgb = rgb;
-  color_gc->gc = gc;
-  mplist_push (plist, Mt, color_gc);
+  rgb_gc = malloc (sizeof (RGB_GC));
+  rgb_gc->rgb = rgb;
+  rgb_gc->gc = gc;
+  mplist_push (plist, Mt, rgb_gc);
   return gc;
+
+ no_color:
+  {
+    GCInfo *info = frame->rface ? frame->rface->info : &device->gc_info;
+
+    if (for_foreground)
+      {
+       if (rgb_ret)
+         *rgb_ret = info->rgb_fore;
+       gc = info->gc[MFACE_GC_NORMAL];
+      }
+    else
+      {
+       if (rgb_ret)
+         *rgb_ret = info->rgb_back;
+       gc = info->gc[MFACE_GC_INVERSE];
+      }
+  }
+  return (gc);
 }
 
 
 void
 mwin__realize_face (MRealizedFace *rface)
 {
-  MFrame *frame = rface->frame;
-  MSymbol foreground = rface->face.property[MFACE_FOREGROUND];
-  MSymbol background = rface->face.property[MFACE_BACKGROUND];
-  MFaceHLineProp *hline = rface->hline;
-  MFaceBoxProp *box = rface->box;
-  MFaceHookFunc func = (MFaceHookFunc) rface->face.property[MFACE_HOOK_FUNC];
-  GC *gcs;
-
-  MTABLE_CALLOC (gcs, MFACE_GCS + 1, MERROR_WIN);
-
-  gcs[MFACE_GC_NORMAL] = get_gc (frame, foreground, 1);
-  gcs[MFACE_GC_INVERSE] = get_gc (frame, background, 0);
-
-  if (rface->face.property[MFACE_VIDEOMODE] == Mreverse)
+  MFrame *frame;
+  MSymbol foreground, background;
+  MFaceHLineProp *hline;
+  MFaceBoxProp *box;
+  MFaceHookFunc func;
+  GCInfo *info;
+  XColor color;
+
+  if (rface != rface->ascii_rface)
     {
-      GC gc = gcs[MFACE_GC_NORMAL];
-      gcs[MFACE_GC_NORMAL] = gcs[MFACE_GC_INVERSE];
-      gcs[MFACE_GC_INVERSE] = gc;
+      rface->info = rface->ascii_rface->info;
+      return;
     }
 
-  if (rface == rface->ascii_rface)
-    {
-      /* This realized face is for ASCII.  Setup GCs for hline and
-        box.  */
-      if (hline && hline->color != foreground)
-       gcs[MFACE_GC_HLINE] = get_gc (frame, hline->color, 1);
+  frame = rface->frame;
+  foreground = rface->face.property[MFACE_FOREGROUND];
+  background = rface->face.property[MFACE_BACKGROUND];
+  hline = rface->hline;
+  box = rface->box;
+  func = (MFaceHookFunc) rface->face.property[MFACE_HOOK_FUNC];
 
-      if (box)
-       {
-         if (box->color_top)
-           gcs[MFACE_GC_BOX_TOP] = get_gc (frame, box->color_top, 1);
-         else
-           gcs[MFACE_GC_BOX_TOP] = gcs[MFACE_GC_NORMAL];
+  MSTRUCT_CALLOC (info, MERROR_WIN);
 
-         if (box->color_left && box->color_left != box->color_top)
-           gcs[MFACE_GC_BOX_LEFT] = get_gc (frame, box->color_left, 1);
-         else
-           gcs[MFACE_GC_BOX_LEFT] = gcs[MFACE_GC_BOX_TOP];
+  info->gc[MFACE_GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
+  info->gc[MFACE_GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
+  info->gc[MFACE_GCS] = info->gc[MFACE_GC_INVERSE];
+  info->gc[MFACE_GCS + 7] = info->gc[MFACE_GC_NORMAL];
 
-         if (box->color_bottom && box->color_bottom != box->color_top)
-           gcs[MFACE_GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1);
-         else
-           gcs[MFACE_GC_BOX_BOTTOM] = gcs[MFACE_GC_BOX_TOP];
+  if (hline && hline->color != foreground)
+    info->gc[MFACE_GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
 
-         if (box->color_right && box->color_right != box->color_top)
-           gcs[MFACE_GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1);
-         else
-           gcs[MFACE_GC_BOX_RIGHT] = gcs[MFACE_GC_BOX_BOTTOM];
-       }
-    }
-  else
+  if (box)
     {
-      /* This realized face is not for ASCII.  GCs for hline and box
-        are shared with that of the corresponding ASCII face.  */
-      GC *ascii_gcs = rface->ascii_rface->info;
-      int i;
+      if (box->color_top)
+       info->gc[MFACE_GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
+      else
+       info->gc[MFACE_GC_BOX_TOP] = info->gc[MFACE_GC_NORMAL];
+
+      if (box->color_left && box->color_left != box->color_top)
+       info->gc[MFACE_GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
+      else
+       info->gc[MFACE_GC_BOX_LEFT] = info->gc[MFACE_GC_BOX_TOP];
 
-      for (i = MFACE_GC_HLINE; i < MFACE_GCS; i++)
-       gcs[i] = ascii_gcs[i];
+      if (box->color_bottom && box->color_bottom != box->color_top)
+       info->gc[MFACE_GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
+      else
+       info->gc[MFACE_GC_BOX_BOTTOM] = info->gc[MFACE_GC_BOX_TOP];
+
+      if (box->color_right && box->color_right != box->color_top)
+       info->gc[MFACE_GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
+      else
+       info->gc[MFACE_GC_BOX_RIGHT] = info->gc[MFACE_GC_BOX_BOTTOM];
     }
 
-  rface->info = gcs;
+  rface->info = info;
   if (func)
     (func) (&(rface->face), rface->info, rface->face.property[MFACE_HOOK_ARG]);
 }
@@ -1507,8 +1556,8 @@ mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
                  int reverse,
                  int x, int y, int width, int height, MDrawRegion region)
 {
-  GC *gcs = rface->info;
-  GC gc = gcs[reverse ? MFACE_GC_NORMAL : MFACE_GC_INVERSE];
+  GC gc = ((GCInfo *) rface->info)->gc[reverse ? MFACE_GC_INVERSE
+                                      : MFACE_GC_NORMAL];
 
   if (region)
     gc = set_region (frame, gc, region);
@@ -1524,7 +1573,7 @@ mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
                 int x, int y, int width, MDrawRegion region)
 {
   enum MFaceHLineType type = rface->hline->type;
-  GC *gcs = rface->info;
+  GCInfo *info = rface->info;
   GC gc;
   int i;
 
@@ -1536,11 +1585,11 @@ mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
        ? y - ((gstring->ascent + gstring->descent) / 2)
        : y - gstring->text_ascent);
   if (reverse)
-    gc = gcs[MFACE_GC_INVERSE];
-  else if (gcs[MFACE_GC_HLINE])
-    gc = gcs[MFACE_GC_HLINE];
+    gc = info->gc[MFACE_GC_INVERSE];
+  else if (info->gc[MFACE_GC_HLINE])
+    gc = info->gc[MFACE_GC_HLINE];
   else
-    gc = gcs[MFACE_GC_NORMAL];
+    gc = info->gc[MFACE_GC_NORMAL];
 
   if (region)
     gc = set_region (frame, gc, region);
@@ -1558,7 +1607,7 @@ mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
   Display *display = FRAME_DISPLAY (frame);
   MRealizedFace *rface = g->rface;
   MFaceBoxProp *box = rface->box;
-  GC *gcs = rface->info;
+  GCInfo *info = rface->info;
   GC gc_top, gc_left, gc_right, gc_btm;
   int y0, y1;
   int i;
@@ -1568,12 +1617,12 @@ mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
   y1 = y + (gstring->text_descent
            + rface->box->inner_vmargin + rface->box->width - 1);
 
-  gc_top = gcs[MFACE_GC_BOX_TOP];
+  gc_top = info->gc[MFACE_GC_BOX_TOP];
   if (! gc_top)
-    gc_top = gcs[MFACE_GC_NORMAL];
+    gc_top = info->gc[MFACE_GC_NORMAL];
   if (region)
     gc_top = set_region (frame, gc_top, region);
-  gc_btm = gcs[MFACE_GC_BOX_BOTTOM];
+  gc_btm = info->gc[MFACE_GC_BOX_BOTTOM];
   if (! gc_btm)
     gc_btm = gc_top;
 
@@ -1599,7 +1648,7 @@ mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
       if (g->left_padding > 0)
        {
          /* Draw the left side.  */
-         gc_left = gcs[MFACE_GC_BOX_LEFT];
+         gc_left = info->gc[MFACE_GC_BOX_LEFT];
          if (! gc_left)
            gc_left = gc_top;
          else if (region)
@@ -1611,7 +1660,7 @@ mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
       else
        {
          /* Draw the right side.  */
-         gc_right = gcs[MFACE_GC_BOX_RIGHT];
+         gc_right = info->gc[MFACE_GC_BOX_RIGHT];
          if (! gc_right)
            gc_right = gc_top;
          else if (region)
@@ -1646,8 +1695,8 @@ mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
 {
   Display *display = FRAME_DISPLAY (frame);
   int i, j;
-  GC *gcs = rface->info;
-  GC gc = gcs[reverse ? MFACE_GC_INVERSE : MFACE_GC_NORMAL];
+  GC gc = ((GCInfo *) rface->info)->gc[reverse ? MFACE_GC_INVERSE
+                                      : MFACE_GC_NORMAL];
 
   if (region)
     gc = set_region (frame, gc, region);
@@ -1658,6 +1707,37 @@ mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
        XDrawPoint (display, (Window) win, gc, x + j, y + i);
 }
 
+
+static GC
+get_gc_for_anti_alias (MWDevice *device, GCInfo *info, int intensity)
+{
+  int rgb_fore = info->rgb_fore, rgb_back = info->rgb_back;
+  XColor color;
+
+  if (intensity == 0)
+    return info->gc[MFACE_GC_INVERSE];
+  if (intensity == 7)
+    return info->gc[MFACE_GC_NORMAL];
+
+  color.red = ((((rgb_fore & 0xFF0000) >> 16) * intensity
+               + ((rgb_back & 0xFF0000) >> 16) * (7 - intensity)) / 7) << 8;
+  color.green = ((((rgb_fore & 0xFF00) >> 8) * intensity
+                 + ((rgb_back & 0xFF00) >> 8) * (7 - intensity)) / 7) << 8;
+  color.blue = (((rgb_fore & 0xFF) * intensity
+                + (rgb_back & 0xFF) * (7 - intensity)) / 7) << 8;
+  if (XAllocColor (device->display_info->display, device->cmap, &color))
+    {
+      unsigned long valuemask = GCForeground;
+      XGCValues values;
+
+      values.foreground = color.pixel;
+      return XCreateGC (device->display_info->display, device->drawable,
+                       valuemask, &values);
+    }
+  return get_gc_for_anti_alias (device, info,
+                               (intensity < 4 ? --intensity : ++ intensity));
+}
+
 void
 mwin__draw_pixmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
                   int reverse, int x, int y,
@@ -1665,57 +1745,24 @@ mwin__draw_pixmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
                   MDrawRegion region)
 {
   Display *display = FRAME_DISPLAY (frame);
+  GCInfo *info = rface->info;
   int i, j;
-  GC *gcs = rface->info;
   GC gc;
-  unsigned long valuemask = GCForeground | GCBackground;
-  XGCValues values;
-  XColor fore_color, back_color, color;
-
-  XGetGCValues (FRAME_DISPLAY (frame), gc, valuemask, &values);
-  fore_color.pixel = values.foreground;
-  back_color.pixel = values.background;
-  XQueryColor (FRAME_DISPLAY (frame), frame->device->cmap, &fore_color);
-  XQueryColor (FRAME_DISPLAY (frame), frame->device->cmap, &back_color);
-
-  if (! gcs[MFACE_GCS])
-    {
-      GC *new_gcs;
-
-      MTABLE_CALLOC (new_gcs, MFACE_GCS + 6, MERROR_WIN);
-      memcpy (new_gcs, gcs, sizeof (GC) * MFACE_GCS);
-      for (i = 0; i < 6; i++)
-       {
-         
-       }
-
-    }
-
-  if (region)
-    gc = set_region (frame, gc, region);
-
-
 
   for (i = 0; i < height; i++, pmp += row_bytes)
     for (j = 0; j < width; j++)
       if (pmp[j])
        {
-         int fore_ratio = pmp[j] >> 5, back_ratio = 7 - fore_ratio;
-         
-         color = fore_color;
-         color.red = ((fore_color.red * fore_ratio) + (back_color.red * back_ratio)) / 7;
-         color.green = ((fore_color.green * fore_ratio) + (back_color.green * back_ratio)) / 7;
-         color.blue = ((fore_color.blue * fore_ratio) + (back_color.blue * back_ratio)) / 7;
-         if (XAllocColor (FRAME_DISPLAY (frame), frame->device->cmap, &color)
-             && fore_color.pixel != color.pixel)
-           {
-             XSetForeground (FRAME_DISPLAY (frame), gc, color.pixel);
-             fore_color.pixel = color.pixel;
-           }
+         int intensity = reverse ? (7 - (pmp[j] >> 5)) : (pmp[j] >> 5);
+         GC gc = info->gc[MFACE_GCS + intensity];
+
+         if (! gc)
+           gc = info->gc[MFACE_GCS + intensity]
+             = get_gc_for_anti_alias (frame->device, info, intensity);
+         if (region)
+           gc = set_region (frame, gc, region);
          XDrawPoint (display, (Window) win, gc, x + j, y + i);
        }
-  if (fore_color.pixel != values.foreground)
-    XSetForeground (FRAME_DISPLAY (frame), gc, values.foreground);
 }
 
 
@@ -1804,7 +1851,8 @@ mwin__dump_region (MDrawRegion region)
 void
 mwin__verify_region (MFrame *frame, MDrawRegion region)
 {
-  set_region (frame, ((GC *) frame->rface->info)[MFACE_GC_NORMAL], region);
+  set_region (frame, ((GCInfo *) frame->rface->info)->gc[MFACE_GC_NORMAL], 
+             region);
 }
 
 MDrawWindow
@@ -2052,12 +2100,12 @@ mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
   unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
   XGCValues values;
   Display *display = FRAME_DISPLAY (frame);
-  GC *gcs = rface->info;
+  GCInfo *info = rface->info;
   int i;
 
   for (i = 0; i <= MFACE_GC_INVERSE; i++)
     {
-      XGetGCValues (display, gcs[i], valuemask, &values);
+      XGetGCValues (display, info->gc[i], valuemask, &values);
       fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
               values.foreground, values.background);
       fprintf (stderr, "\n");