From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Chris Gray Newsgroups: gmane.emacs.devel Subject: antialiasing for emacs Date: Thu, 24 Jul 2003 13:37:33 -0700 Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: <87u19bbr02.fsf@chicolini.ods.org> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: main.gmane.org 1059079223 19743 80.91.224.249 (24 Jul 2003 20:40:23 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Thu, 24 Jul 2003 20:40:23 +0000 (UTC) Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Thu Jul 24 22:40:17 2003 Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by main.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 19fmsf-00057l-00 for ; Thu, 24 Jul 2003 22:40:05 +0200 Original-Received: from monty-python.gnu.org ([199.232.76.173]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 19fnAw-0006Hg-00 for ; Thu, 24 Jul 2003 22:58:58 +0200 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.20) id 19fmtc-00073S-E1 for emacs-devel@quimby.gnus.org; Thu, 24 Jul 2003 16:41:04 -0400 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.20) id 19fmsk-0006nZ-TO for emacs-devel@gnu.org; Thu, 24 Jul 2003 16:40:10 -0400 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.20) id 19fmsM-0006Qp-SC for emacs-devel@gnu.org; Thu, 24 Jul 2003 16:39:48 -0400 Original-Received: from mail.interchange.ubc.ca ([137.82.27.15]) by monty-python.gnu.org with esmtp (Exim 4.20) id 19fmqH-0005Qu-Mk for emacs-devel@gnu.org; Thu, 24 Jul 2003 16:37:37 -0400 Original-Received: from n241-227.wireless.ubc.ca ([142.103.241.227] helo=chicolini) by mail.interchange.ubc.ca with esmtp (Exim 4.20) id 19fmqF-0003ZF-8p for emacs-devel@gnu.org; Thu, 24 Jul 2003 13:37:35 -0700 Original-To: emacs-devel@gnu.org Mail-Copies-To: nobody User-Agent: Gnus/5.1002 (Gnus v5.10.2) Emacs/21.3 (gnu/linux) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.2 Precedence: list List-Id: Emacs development discussions. List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:15698 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:15698 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 #endif /* USE_X_TOOLKIT */ +#define HAVE_XFT +#ifdef HAVE_XFT +#include +#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. ============================================================