all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Chris Gray <cmg@cs.ubc.ca>
Subject: antialiasing for emacs
Date: Thu, 24 Jul 2003 13:37:33 -0700	[thread overview]
Message-ID: <87u19bbr02.fsf@chicolini.ods.org> (raw)


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	other threads:[~2003-07-24 20:37 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-07-24 20:37 Chris Gray [this message]
2003-07-25  2:02 ` antialiasing for emacs Miles Bader
2003-07-25 19:07   ` Chris Gray
2003-07-27 22:33     ` Miles Bader
2003-07-28 20:04       ` Stefan Monnier
2003-07-28 20:22         ` Chris Gray
2003-08-13 10:48           ` Miles Bader
2003-07-30 20:31         ` Richard Stallman
2003-07-31 14:35           ` Stefan Monnier
2003-07-27  4:28 ` Marcelo Toledo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87u19bbr02.fsf@chicolini.ods.org \
    --to=cmg@cs.ubc.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.