emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

antialiasing for emacs


From: Chris Gray
Subject: antialiasing for emacs
Date: Thu, 24 Jul 2003 13:37:33 -0700
User-agent: Gnus/5.1002 (Gnus v5.10.2) Emacs/21.3 (gnu/linux)

Hi,

I have put together antialiasing support for GNU emacs on X.  At this
point it is pretty slow[1] and there seem to be a couple of bugs still
left to work out (starting gnus and info both cause bad things to
happen).  However, in the spirit of "release early and often", the
code is attached.  

I have not yet added the appropriate tests to configure.in and the
Makefile needs to be modified appropriately if you want to test this
out.  

Cheers,
Chris

[1] The slowness is because I can't trust the attributes of a face not
to change.  If there was a different face for the cursor than the rest
of the text (instead of simply changing the GC), the story would be
different. 



===File ~/src/emacs/src/emacs.diff==========================
? emacs.diff
Index: dispextern.h
===================================================================
RCS file: /cvsroot/emacs/emacs/src/dispextern.h,v
retrieving revision 1.153
diff -u -r1.153 dispextern.h
--- dispextern.h        24 May 2003 21:56:19 -0000      1.153
+++ dispextern.h        23 Jul 2003 02:07:19 -0000
@@ -31,6 +31,11 @@
 #include <X11/Intrinsic.h>
 #endif /* USE_X_TOOLKIT */
 
+#define HAVE_XFT
+#ifdef HAVE_XFT
+#include <X11/Xft/Xft.h>
+#endif
+
 #else /* !HAVE_X_WINDOWS */
 
 /* X-related stuff used by non-X gui code. */
@@ -1330,6 +1335,13 @@
   /* Background stipple or bitmap used for this face.  This is
      an id as returned from load_pixmap.  */
   int stipple;
+
+#ifdef HAVE_XFT
+  XftFont *xftfont;
+  XftColor xftforeground;
+  XftColor xftbackground;
+  XftDraw *draw;
+#endif
 
 #else /* not HAVE_WINDOW_SYSTEM */
 
Index: xfaces.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/xfaces.c,v
retrieving revision 1.281
diff -u -r1.281 xfaces.c
--- xfaces.c    26 Jun 2003 21:18:45 -0000      1.281
+++ xfaces.c    23 Jul 2003 02:07:26 -0000
@@ -5094,6 +5094,51 @@
       face->gc = x_create_gc (f, mask, &xgcv);
       UNBLOCK_INPUT;
     }
+#ifdef HAVE_XFT
+  //  BLOCK_INPUT;
+  if (face->draw == 0)
+    {  
+      XWindowAttributes atts;
+      XGetWindowAttributes (FRAME_X_DISPLAY(f), FRAME_X_WINDOW(f), &atts);
+      face->draw = XftDrawCreate (FRAME_X_DISPLAY(f), 
+                                (Drawable) FRAME_X_WINDOW(f), 
+                                atts.visual, atts.colormap);
+    }
+  if (face->font != 0 && face->xftfont == 0)
+    {
+      char *name;
+      XFontStruct *fs = face->font;
+      Atom value;
+      XGetFontProperty (fs, XA_FONT, &value);
+      name = (char *) XGetAtomName(FRAME_X_DISPLAY (f), value);
+      //XFree (fs);
+
+      face->xftfont = XftFontOpenXlfd (FRAME_X_DISPLAY (f), 
DefaultScreen(FRAME_X_DISPLAY(f)), name);
+      xassert(face->xftfont);
+      XFree (name);
+    }
+  {
+    XWindowAttributes atts;
+    XColor newcolor;
+    XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &atts);
+    face->xftforeground.pixel = face->foreground;
+    newcolor.pixel = face->foreground;
+    XQueryColor (FRAME_X_DISPLAY (f), atts.colormap, &newcolor);
+    face->xftforeground.color.red = newcolor.red;
+    face->xftforeground.color.green = newcolor.green;
+    face->xftforeground.color.blue = newcolor.blue;
+    face->xftforeground.color.alpha = 0xffff;
+    face->xftbackground.pixel = face->background;
+    newcolor.pixel = face->background;
+    XQueryColor (FRAME_X_DISPLAY (f), atts.colormap, &newcolor);
+    face->xftbackground.color.red = newcolor.red;
+    face->xftbackground.color.green = newcolor.green;
+    face->xftbackground.color.blue = newcolor.blue;
+    face->xftbackground.color.alpha = 0xffff;
+  }
+  // UNBLOCK_INPUT;
+
+#endif /* HAVE_XFT */
 #endif /* HAVE_WINDOW_SYSTEM */
 }
 
@@ -6784,6 +6829,9 @@
     {
       bcopy (base_face, face, sizeof *face);
       face->gc = 0;
+#ifdef HAVE_XFT
+      face->xftfont = 0;
+#endif
 
       /* Don't try to free the colors copied bitwise from BASE_FACE.  */
       face->colors_copied_bitwise_p = 1;
Index: xterm.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/xterm.c,v
retrieving revision 1.802
diff -u -r1.802 xterm.c
--- xterm.c     17 Jul 2003 10:15:04 -0000      1.802
+++ xterm.c     23 Jul 2003 02:07:30 -0000
@@ -183,6 +183,12 @@
 
 int x_use_underline_position_properties;
 
+#ifdef HAVE_XFT
+/* Non-zero means use Xft for anti-aliased fonts */
+
+int x_use_xft;
+#endif
+
 /* This is a chain of structures for all the X displays currently in
    use.  */
 
@@ -1200,6 +1206,55 @@
     }
 }
 
+#ifdef HAVE_XFT
+
+/* Get the colors from the graphics context so that
+   we can render the xft colors correctly (without changing
+   too much old code).
+
+   FIXME: pretty much unnecessary if we are only going to be
+   using Xft.
+ */
+
+static void
+x_get_colors_from_gc (s, fgcolor, bgcolor)
+     struct glyph_string *s;
+     XftColor *fgcolor;
+     XftColor *bgcolor;
+{
+  GC gc = s->gc;
+  Drawable d = FRAME_X_WINDOW(s->f);
+  XGCValues vals;
+  XWindowAttributes info;
+
+  XGetWindowAttributes(FRAME_X_DISPLAY(s->f), (Window) d, &info);
+  XGetGCValues(FRAME_X_DISPLAY(s->f), gc, GCBackground | GCForeground, &vals);
+
+  if (fgcolor) 
+    {
+      XColor newcolor;
+      fgcolor->pixel = vals.foreground;
+      newcolor.pixel = vals.foreground;
+      XQueryColor(FRAME_X_DISPLAY(s->f), info.colormap, &newcolor);
+      fgcolor->color.red = newcolor.red;
+      fgcolor->color.green = newcolor.green;
+      fgcolor->color.blue = newcolor.blue;
+      fgcolor->color.alpha = 0xffff;
+    }
+  if (bgcolor) 
+    {
+      XColor newcolor;
+      bgcolor->pixel = vals.background;
+      newcolor.pixel = vals.background;
+      XQueryColor(FRAME_X_DISPLAY(s->f), info.colormap, &newcolor);
+      bgcolor->color.red = newcolor.red;
+      bgcolor->color.blue = newcolor.blue;
+      bgcolor->color.green = newcolor.green;
+      bgcolor->color.alpha = 0xffff;
+    }
+}
+
+#endif
 
 /* Draw the foreground of glyph string S.  */
 
@@ -1251,22 +1306,75 @@
       if (s->for_overlaps_p
          || (s->background_filled_p && s->hl != DRAW_CURSOR))
        {
+#ifndef HAVE_XFT
+#define HAVE_XFT_VAL 0
+#else
+#define HAVE_XFT_VAL 1
+#endif
+         if (!x_use_xft || !(HAVE_XFT_VAL)) 
+           {
          /* Draw characters with 16-bit or 8-bit functions.  */
-         if (s->two_byte_p)
-           XDrawString16 (s->display, s->window, s->gc, x,
-                          s->ybase - boff, s->char2b, s->nchars);
-         else
-           XDrawString (s->display, s->window, s->gc, x,
-                        s->ybase - boff, char1b, s->nchars);
+             if (s->two_byte_p)
+               XDrawString16 (s->display, s->window, s->gc, x,
+                              s->ybase - boff, s->char2b, s->nchars);
+             else
+               XDrawString (s->display, s->window, s->gc, x,
+                            s->ybase - boff, char1b, s->nchars);
+           }
+         else 
+           {
+#ifdef HAVE_XFT
+             XftColor foreground;
+             
+             x_get_colors_from_gc (s, &foreground, NULL);
+             if (s->two_byte_p) 
+               XftDrawString16 (s->face->draw, &foreground, s->face->xftfont, 
x, s->ybase, (unsigned short *) s->char2b, s->nchars);
+             else
+               XftDrawString8 (s->face->draw, &foreground, s->face->xftfont, 
x, s->ybase, char1b, s->nchars);
+#endif
+           }
        }
       else
        {
-         if (s->two_byte_p)
-           XDrawImageString16 (s->display, s->window, s->gc, x,
-                               s->ybase - boff, s->char2b, s->nchars);
-         else
-           XDrawImageString (s->display, s->window, s->gc, x,
-                             s->ybase - boff, char1b, s->nchars);
+         if (!x_use_xft || !(HAVE_XFT_VAL))
+           {
+             if (s->two_byte_p)
+               XDrawImageString16 (s->display, s->window, s->gc, x,
+                                   s->ybase - boff, s->char2b, s->nchars);
+             else
+               XDrawImageString (s->display, s->window, s->gc, x,
+                                 s->ybase - boff, char1b, s->nchars);
+           }
+         else 
+           {
+#ifdef HAVE_XFT
+             XftColor foreground, background;
+
+             x_get_colors_from_gc (s, &foreground, &background);
+             if (s->two_byte_p)
+               {
+                 int width, height;
+                 XGlyphInfo extents;
+                 XftTextExtents16 (s->display, s->face->xftfont, (unsigned 
short *) s->char2b, s->nchars, &extents);
+                 width = extents.xOff;
+                 height = s->face->xftfont->ascent + s->face->xftfont->descent;
+
+                 XftDrawRect (s->face->draw, &background, x, s->ybase - 
s->face->xftfont->ascent, width, height);
+                 XftDrawString16 (s->face->draw, &foreground, 
s->face->xftfont, x, s->ybase, (unsigned short *) s->char2b, s->nchars);
+               }
+             else 
+               {
+                 int width, height;
+                 XGlyphInfo extents;
+                 XftTextExtents8 (s->display, s->face->xftfont, char1b, 
s->nchars, &extents);
+                 width = extents.xOff;
+                 height = s->face->xftfont->ascent + s->face->xftfont->descent 
- 3;
+
+                 XftDrawRect (s->face->draw, &background, x, s->ybase + 2 - 
s->face->xftfont->ascent, width, height);
+                 XftDrawString8 (s->face->draw, &foreground, s->face->xftfont, 
x, s->ybase, char1b, s->nchars);
+               }
+#endif
+           }
        }
 
       if (s->face->overstrike)
@@ -10810,6 +10918,12 @@
 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
 to 4.1, set this to nil.  */);
   x_use_underline_position_properties = 1;
+
+#ifdef HAVE_XFT
+  DEFVAR_BOOL ("x-use-xft", &x_use_xft,
+              doc: /* *Non-nil means to use Xft for anti-aliasing */);
+  x_use_xft = 1;
+#endif
 
   DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
     doc: /* What X toolkit scroll bars Emacs uses.
============================================================





reply via email to

[Prev in Thread] Current Thread [Next in Thread]