From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: Antialiased text on X11 Date: Sat, 19 Mar 2005 11:31:35 -0500 Message-ID: <871xab1u3d.fsf-monnier+emacs@gnu.org> References: <20050310231530.GH3992@boetes.org> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: sea.gmane.org 1111250187 15210 80.91.229.2 (19 Mar 2005 16:36:27 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Sat, 19 Mar 2005 16:36:27 +0000 (UTC) Cc: snogglethorpe@gmail.com, emacs-devel@gnu.org, Ali Ijaz Sheikh , miles@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Mar 19 17:36:26 2005 Original-Received: from lists.gnu.org ([199.232.76.165]) by ciao.gmane.org with esmtp (Exim 4.43) id 1DCgvZ-0006Ys-MC for ged-emacs-devel@m.gmane.org; Sat, 19 Mar 2005 17:36:06 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1DChCF-00085P-Oq for ged-emacs-devel@m.gmane.org; Sat, 19 Mar 2005 11:53:07 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1DCh7k-00052h-Ve for emacs-devel@gnu.org; Sat, 19 Mar 2005 11:48:29 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1DCh7S-0004sP-0I for emacs-devel@gnu.org; Sat, 19 Mar 2005 11:48:26 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1DCh7R-0004ry-E1 for emacs-devel@gnu.org; Sat, 19 Mar 2005 11:48:09 -0500 Original-Received: from [209.226.175.34] (helo=tomts13-srv.bellnexxia.net) by monty-python.gnu.org with esmtp (Exim 4.34) id 1DCgrR-00032T-Mw; Sat, 19 Mar 2005 11:31:38 -0500 Original-Received: from alfajor ([67.68.217.141]) by tomts13-srv.bellnexxia.net (InterMail vM.5.01.06.10 201-253-122-130-110-20040306) with ESMTP id <20050319163136.VIVT1899.tomts13-srv.bellnexxia.net@alfajor>; Sat, 19 Mar 2005 11:31:36 -0500 Original-Received: by alfajor (Postfix, from userid 1000) id C93282FEB3; Sat, 19 Mar 2005 11:31:35 -0500 (EST) Original-To: "Jan D." In-Reply-To: (Jan D.'s message of "Sat, 19 Mar 2005 07:27:38 +0100") User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org X-MailScanner-To: ged-emacs-devel@m.gmane.org Xref: news.gmane.org gmane.emacs.devel:34778 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:34778 --=-=-= > I have started on Xft support, but it is really something for the release > after the next, so I don't spend much time on it yet. I can confirm your > reasoning, the Emacs font-selection machinery is indeed the most tricky > part, I have not done that fully, so I can't change font yet. But part of > the problem is that the Xft font selection is entirely new compared to the > old X font selection. Feel free to put it on an Arch branch somewhere, or a branch in the CVS ;-) > I am doing an Xft solution, I did not find the talked about Xft branch, so > I started from scratch. The main reason for doing this is that I wanted to > use the GTK file selection dialog, but since that dialog displays all fonts, > including antialiased, Emacs can currently not use it. I don't think you wasted your time, but in case you're interested, I've appended a patch I extracted from that xft branch at some point. I had some trouble extracting the patch, so there might be some missing bits and some unrelated extra bits. It surely doesn't compile. Stefan --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=xft-2.patch Seulement dans xft-base/src: .arch-ids Seulement dans xft-base/src: bitmaps Seulement dans xft-base/src: ChangeLog Seulement dans xft-base/src: ChangeLog.1 Seulement dans xft-base/src: ChangeLog.2 Seulement dans xft-base/src: ChangeLog.3 Seulement dans xft-base/src: ChangeLog.4 Seulement dans xft-base/src: ChangeLog.5 Seulement dans xft-base/src: ChangeLog.6 Seulement dans xft-base/src: ChangeLog.7 Seulement dans xft-base/src: ChangeLog.8 Seulement dans xft-base/src: ChangeLog.9 Seulement dans xft/src.xft: config.h Seulement dans xft-base/src: config.in Seulement dans xft-base/src: COPYING Seulement dans xft-base/src: .cvsignore Seulement dans xft-base/src: cxux-crt0.s Seulement dans xft-base/src: .dbxinit diff -u --recursive xft-base/src/dispextern.h xft/src.xft/dispextern.h --- xft-base/src/dispextern.h 2005-03-10 18:22:52.123027247 -0500 +++ xft/src.xft/dispextern.h 2005-03-10 18:18:01.264178566 -0500 @@ -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. */ @@ -1092,6 +1097,7 @@ /* Font in which this string is to be drawn. */ XFontStruct *font; + XftFont *xftfont; /* Font info for this string. */ struct font_info *font_info; @@ -1368,6 +1374,16 @@ an id as returned from load_pixmap. */ int stipple; +#ifdef HAVE_XFT + XftFont *xftfont; + XftColor xftforeground; + XftColor xftbackground; + XftDraw *draw; +#endif + + /* Reverse the foreground and background to make the cursor */ + int reverse_color; + #else /* not HAVE_WINDOW_SYSTEM */ /* Dummy. */ diff -u --recursive xft-base/src/dispnew.c xft/src.xft/dispnew.c Seulement dans xft/src.xft: epaths.h Seulement dans xft-base/src: epaths.in diff -u --recursive xft-base/src/fontset.c xft/src.xft/fontset.c diff -u --recursive xft-base/src/frame.c xft/src.xft/frame.c Seulement dans xft-base/src: .gdbinit Seulement dans xft-base/src: .gdbinit-union diff -u --recursive xft-base/src/keyboard.c xft/src.xft/keyboard.c Seulement dans xft-base/src: m Seulement dans xft/src.xft: Makefile.c Seulement dans xft-base/src: Makefile.in Seulement dans xft-base/src: makefile.nt Seulement dans xft-base/src: makefile.w32-in Seulement dans xft-base/src: README Seulement dans xft-base/src: s Seulement dans xft-base/src: stamp-h.in Seulement dans xft-base/src: temacs.opt diff -u --recursive xft-base/src/window.c xft/src.xft/window.c diff -u --recursive xft-base/src/xdisp.c xft/src.xft/xdisp.c --- xft-base/src/xdisp.c 2005-03-10 18:22:58.088270349 -0500 +++ xft/src.xft/xdisp.c 2005-03-10 18:18:05.170337510 -0500 @@ -17332,10 +17233,10 @@ default font, but record the fact that we couldn't load it in the glyph string so that we can draw rectangles for the characters of the glyph string. */ - if (s->font == NULL) + if (0 && s->font == NULL) { s->font_not_found_p = 1; - s->font = FRAME_FONT (s->f); + s->xftfont = FRAME_FONT (s->f); } /* Adjust base line for subscript/superscript text. */ @@ -17399,17 +17300,17 @@ ++glyph; } - s->font = s->face->font; + s->xftfont = s->face->xftfont; s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); /* If the specified font could not be loaded, use the frame's font, but record the fact that we couldn't load it in S->font_not_found_p so that we can draw rectangles for the characters of the glyph string. */ - if (s->font == NULL || glyph_not_available_p) + if (0 && (s->font == NULL || glyph_not_available_p)) { s->font_not_found_p = 1; - s->font = FRAME_FONT (s->f); + s->xftfont = FRAME_FONT (s->f); } /* Adjust base line for subscript/superscript text. */ @@ -18433,7 +18320,7 @@ double *res; struct it *it; Lisp_Object prop; - XFontStruct *font; + XftFont *font; int width_p; { double pixels; @@ -18601,7 +18488,7 @@ int ascent = 0; double tem; struct face *face = FACE_FROM_ID (it->f, it->face_id); - XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f); + XftFont *font = face->xftfont ? face->xftfont : FRAME_FONT (it->f); PREPARE_FACE_FOR_DISPLAY (it->f, face); @@ -18726,7 +18613,7 @@ if (it->what == IT_CHARACTER) { XChar2b char2b; - XFontStruct *font; + XftFont *font; struct face *face = FACE_FROM_ID (it->f, it->face_id); XCharStruct *pcm; int font_not_found_p; @@ -18770,7 +18657,7 @@ /* Get font to use. Encode IT->char_to_display. */ get_char_face_and_encoding (it->f, it->char_to_display, it->face_id, &char2b, it->multibyte_p, 0); - font = face->font; + font = face->xftfont; /* When no suitable font found, use the default font. */ font_not_found_p = font == NULL; @@ -18921,8 +18808,8 @@ from the charset width; this is what old redisplay code did. */ - pcm = rif->per_char_metric (font, &char2b, - FONT_TYPE_FOR_MULTIBYTE (font, it->c)); + pcm = rif->per_char_metric (font, &char2b, + FONT_TYPE_FOR_MULTIBYTE (font, it->c)); if (font_not_found_p || !pcm) { @@ -18982,7 +18869,7 @@ /* Note: A composition is represented as one glyph in the glyph matrix. There are no padding glyphs. */ XChar2b char2b; - XFontStruct *font; + XftFont *font; struct face *face = FACE_FROM_ID (it->f, it->face_id); XCharStruct *pcm; int font_not_found_p; @@ -19006,7 +18893,7 @@ face = FACE_FROM_ID (it->f, it->face_id); get_char_face_and_encoding (it->f, it->char_to_display, it->face_id, &char2b, it->multibyte_p, 0); - font = face->font; + font = face->xftfont; /* When no suitable font found, use the default font. */ font_not_found_p = font == NULL; @@ -19095,7 +18982,7 @@ face = FACE_FROM_ID (it->f, face_id); get_char_face_and_encoding (it->f, ch, face->id, &char2b, it->multibyte_p, 0); - font = face->font; + font = face->xftfont; if (font == NULL) { font = FRAME_FONT (it->f); diff -u --recursive xft-base/src/xfaces.c xft/src.xft/xfaces.c --- xft-base/src/xfaces.c 2005-03-10 18:22:58.188274425 -0500 +++ xft/src.xft/xfaces.c 2005-03-10 18:18:04.915327133 -0500 @@ -1063,7 +1063,8 @@ /* Free the font. */ BLOCK_INPUT; #ifdef HAVE_X_WINDOWS - XFreeFont (dpyinfo->display, font_info->font); + // FIXME -- cmg + //XFreeFont (dpyinfo->display, font_info->font); #endif #ifdef WINDOWSNT w32_unload_font (dpyinfo, font_info->font); @@ -5146,7 +5147,7 @@ if (face->font) { #ifdef HAVE_X_WINDOWS - xgcv.font = face->font->fid; + //xgcv.font = face->font->fid; #endif #ifdef WINDOWSNT xgcv.font = face->font; @@ -5154,7 +5155,7 @@ #ifdef MAC_OS xgcv.font = face->font; #endif - mask |= GCFont; + //mask |= GCFont; } BLOCK_INPUT; @@ -5169,6 +5170,53 @@ 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 = "-adobe-helvetica-medium-r-narrow--*-*-*-*-*-0-iso8859-1"; + /* + char *name; + XFontStruct *fs = face->font; + Atom value; + XGetFontProperty (fs, XA_FONT, &value); + name = (char *) XGetAtomName(FRAME_X_DISPLAY (f), value); + */ + + 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 */ } @@ -6879,6 +6927,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; diff -u --recursive xft-base/src/xfns.c xft/src.xft/xfns.c --- xft-base/src/xfns.c 2005-03-10 18:22:58.232276218 -0500 +++ xft/src.xft/xfns.c 2005-03-10 18:18:05.279341946 -0500 @@ -3041,14 +3042,14 @@ Note that many default values are used. */ /* Normal video */ - gc_values.font = FRAME_FONT (f)->fid; + //gc_values.font = FRAME_FONT (f)->fid; gc_values.foreground = f->output_data.x->foreground_pixel; gc_values.background = f->output_data.x->background_pixel; gc_values.line_width = 0; /* Means 1 using fast algorithm. */ f->output_data.x->normal_gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - GCLineWidth | GCFont | GCForeground | GCBackground, + GCLineWidth | /* GCFont | */ GCForeground | GCBackground, &gc_values); /* Reverse video style. */ @@ -3057,7 +3058,7 @@ f->output_data.x->reverse_gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - GCFont | GCForeground | GCBackground | GCLineWidth, + /*GCFont |*/ GCForeground | GCBackground | GCLineWidth, &gc_values); /* Cursor has cursor-color background, background-color foreground. */ @@ -3070,7 +3071,7 @@ cursor_bits, 16, 16); f->output_data.x->cursor_gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - (GCFont | GCForeground | GCBackground + (/*GCFont | */GCForeground | GCBackground | GCFillStyle /* | GCStipple */ | GCLineWidth), &gc_values); @@ -3483,7 +3484,7 @@ "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN); x_default_parameter (f, parms, Qcursor_type, Qbox, "cursorType", "CursorType", RES_TYPE_SYMBOL); - x_default_parameter (f, parms, Qscroll_bar_width, Qnil, + x_default_parameter (f, parms, Qscroll_bar_width, make_number(0), "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER); @@ -3492,6 +3493,7 @@ FRAME_LINES (f). */ width = FRAME_COLS (f); height = FRAME_LINES (f); + height = 40; SET_FRAME_COLS (f, 0); FRAME_LINES (f) = 0; @@ -4221,7 +4223,8 @@ for (i = 0; i < dpyinfo->n_fonts; i++) if (dpyinfo->font_table[i].name) { - XFreeFont (dpyinfo->display, dpyinfo->font_table[i].font); + // FIXME: should free -- cmg + //XFreeFont (dpyinfo->display, dpyinfo->font_table[i].font); } x_destroy_all_bitmaps (dpyinfo); diff -u --recursive xft-base/src/xmenu.c xft/src.xft/xmenu.c diff -u --recursive xft-base/src/xterm.c xft/src.xft/xterm.c --- xft-base/src/xterm.c 2005-03-10 18:22:58.385282453 -0500 +++ xft/src.xft/xterm.c 2005-03-10 18:18:05.390346462 -0500 @@ -184,6 +184,10 @@ int x_use_underline_position_properties; +/* Non-zero means use Xft for anti-aliased fonts */ + +int x_use_xft; + /* This is a chain of structures for all the X displays currently in use. */ @@ -287,7 +291,7 @@ extern Lisp_Object Vx_no_window_manager; -extern Lisp_Object Qeql; +extern Lisp_Object Qface, Qmouse_face, Qeql; extern int errno; @@ -326,7 +330,7 @@ void x_wm_set_window_state P_ ((struct frame *, int)); void x_wm_set_icon_pixmap P_ ((struct frame *, int)); void x_initialize P_ ((void)); -static void x_font_min_bounds P_ ((XFontStruct *, int *, int *)); +static void x_font_min_bounds P_ ((XftFont *, int *, int *)); static int x_compute_min_glyph_bounds P_ ((struct frame *)); static void x_update_end P_ ((struct frame *)); static void XTframe_up_to_date P_ ((struct frame *)); @@ -788,13 +778,31 @@ static XCharStruct * x_per_char_metric (font, char2b, font_type) - XFontStruct *font; + XftFont *font; XChar2b *char2b; int font_type; /* unused on X */ { /* The result metric information. */ - XCharStruct *pcm = NULL; + static XCharStruct pcm; + XGlyphInfo extents; + Display *dpy; + XftChar16 ch; + if (NILP(x_display_name_list)) return NULL; + dpy = x_display_info_for_name(XCAR(XCAR(x_display_name_list)))->display; + + ch = (char2b->byte1 << 8) | char2b->byte2; + BLOCK_INPUT; + XftTextExtents16 (dpy, font, (XftChar16 *) &ch, 1, &extents); + UNBLOCK_INPUT; + pcm.ascent = font->ascent; + pcm.descent = font->descent; + pcm.lbearing = 0; + pcm.rbearing = 0; + pcm.width = extents.xOff; + //XCloseDisplay(dpy); + return &pcm; +#if 0 xassert (font && char2b); if (font->per_char != NULL) @@ -852,6 +860,7 @@ return ((pcm == NULL || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)) ? NULL : pcm); +#endif } @@ -866,7 +875,9 @@ int *two_byte_p; { int charset = CHAR_CHARSET (c); - XFontStruct *font = font_info->font; + return 0; +#if 0 + XftFont *font = font_info->font; /* FONT_INFO may define a scheme by which to encode byte1 and byte2. This may be either a program in a special encoder language or a @@ -913,9 +924,10 @@ } if (two_byte_p) - *two_byte_p = ((XFontStruct *) (font_info->font))->max_byte1 > 0; + *two_byte_p = ((XftFont *) (font_info->font))->max_byte1 > 0; return FONT_TYPE_UNKNOWN; +#endif } @@ -955,7 +967,7 @@ int, int, int, XRectangle *)); #if GLYPH_DEBUG -static void x_check_font P_ ((struct frame *, XFontStruct *)); +static void x_check_font P_ ((struct frame *, XftFont *)); #endif @@ -966,7 +978,10 @@ x_set_cursor_gc (s) struct glyph_string *s; { - if (s->font == FRAME_FONT (s->f) + //s->face = FACE_FROM_ID(s->f, CURSOR_FACE_ID); + s->gc = s->f->output_data.x->cursor_gc; + return; + if (s->xftfont == FRAME_FONT (s->f) && s->face->background == FRAME_BACKGROUND_PIXEL (s->f) && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f) && !s->cmp) @@ -997,9 +1012,9 @@ } IF_DEBUG (x_check_font (s->f, s->font)); - xgcv.font = s->font->fid; + //xgcv.font = s->font->fid; xgcv.graphics_exposures = False; - mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures; + mask = GCForeground | GCBackground | /*GCFont |*/ GCGraphicsExposures; if (FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc) XChangeGC (s->display, FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc, @@ -1090,6 +1105,7 @@ if (s->hl == DRAW_NORMAL_TEXT) { + s->face->reverse_color = 0; s->gc = s->face->gc; s->stippled_p = s->face->stipple != 0; } @@ -1100,6 +1116,7 @@ } else if (s->hl == DRAW_CURSOR) { + s->face->reverse_color = 1; x_set_cursor_gc (s); s->stippled_p = 0; } @@ -1202,7 +1219,7 @@ XSetFillStyle (s->display, s->gc, FillSolid); s->background_filled_p = 1; } - else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width + else if (FONT_HEIGHT (s->xftfont) < s->height - 2 * box_line_width || s->font_not_found_p || s->extends_to_end_of_line_p || force_p) @@ -1216,6 +1233,61 @@ } +#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; +#ifdef DEBUG_XFT_HEIGHTS + bgcolor->pixel = 0xff00; + newcolor.pixel = 0xff00; +#else + bgcolor->pixel = vals.background; + newcolor.pixel = vals.background; +#endif + 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. */ static void @@ -1266,28 +1338,93 @@ if (s->for_overlaps_p || (s->background_filled_p && s->hl != DRAW_CURSOR)) { - /* 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); +#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); + } + else + { +#ifdef HAVE_XFT + XftColor *foreground; + + //x_get_colors_from_gc (s, &foreground, NULL); + foreground = &(s->face->xftforeground); + 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); + 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 - XDrawImageString (s->display, s->window, s->gc, x, - s->ybase - boff, char1b, s->nchars); + { +#ifdef HAVE_XFT + XftColor *foreground, *background; + + //x_get_colors_from_gc (s, &foreground, &background); + if (!s->face->reverse_color) { + foreground = &(s->face->xftforeground); + background = &(s->face->xftbackground); + } else { + foreground = &(s->face->xftbackground); + background = &(s->face->xftforeground); + } + 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; + int a, d; + XGlyphInfo extents; + XftTextExtents8 (s->display, s->face->xftfont, char1b, s->nchars, &extents); + width = extents.xOff; + height = s->face->xftfont->ascent + s->face->xftfont->descent; + a = s->face->xftfont->ascent; + d = s->face->xftfont->descent; + + XftDrawRect (s->face->draw, background, x, s->ybase - a, width, height); + XftDrawString8 (s->face->draw, foreground, s->face->xftfont, x, s->ybase, char1b, s->nchars); + } +#endif + } } - if (s->face->overstrike) + if (0 && s->face->overstrike) { /* For overstriking (to simulate bold-face), draw the characters again shifted to the right by one pixel. */ + printf("overstrike\n"); if (s->two_byte_p) XDrawString16 (s->display, s->window, s->gc, x + 1, s->ybase - boff, s->char2b, s->nchars); @@ -2615,8 +2752,9 @@ unsigned long tem, h; int y; + // FIXME -- cmg /* Get the underline thickness. Default is 1 pixel. */ - if (!XGetFontProperty (s->font, XA_UNDERLINE_THICKNESS, &h)) + //if (!XGetFontProperty (s->font, XA_UNDERLINE_THICKNESS, &h)) h = 1; /* Get the underline position. This is the recommended @@ -2627,12 +2765,15 @@ ROUND ((maximum descent) / 2), with ROUND(x) = floor (x + 0.5) */ + /* FIXME -- cmg + if (x_use_underline_position_properties && XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &tem)) y = s->ybase + (long) tem; else if (s->face->font) y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2; else + */ y = s->y + s->height - h; if (s->face->underline_defaulted_p) @@ -4772,7 +4913,7 @@ left + VERTICAL_SCROLL_BAR_WIDTH_TRIM, top, width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2, - height, + 1, /* Border width, depth, class, and visual. */ 0, CopyFromParent, @@ -4993,6 +5134,9 @@ width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f); height = window_height; + // FIXME -- cmg + width = 2 * FRAME_COLUMN_WIDTH (f); + /* Compute the left edge of the scroll bar area. */ left = WINDOW_SCROLL_BAR_AREA_X (w); @@ -5026,8 +5170,11 @@ left, top, width, height, False); UNBLOCK_INPUT; } - - bar = x_scroll_bar_create (w, top, sb_left, sb_width, height); + // FIXME -- cmg + //bar = x_scroll_bar_create (w, top, sb_left, 10 /*sb_width*/, height); + BLOCK_INPUT; + bar = x_scroll_bar_create (w, top, sb_left, 10, height); + UNBLOCK_INPUT; } else { @@ -5118,6 +5265,11 @@ wc.y = top; wc.width = sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2; wc.height = height; + + wc.x = 10; + wc.y = 1; + wc.height = 10; + wc.width = 10; XConfigureWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar), mask, &wc); } @@ -7939,52 +8073,27 @@ struct frame *f; register char *fontname; { - struct font_info *fontp - = FS_LOAD_FONT (f, 0, fontname, -1); - - if (!fontp) - return Qnil; - - FRAME_FONT (f) = (XFontStruct *) (fontp->font); - FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset; + //FRAME_FONT(f) = XftFontOpenXlfd (FRAME_X_DISPLAY (f), DefaultScreen (FRAME_X_DISPLAY (f)), fontname); + char *foo = "-adobe-helvetica-medium-r-narrow--*-*-*-*-*-0-iso8859-1"; + FcPattern *pat; + XftFont *fon; + + //pat = XftXlfdParse (foo, 1, 0); + //if(!pat) return Qnil; + fon = XftFontOpenXlfd (FRAME_X_DISPLAY (f), DefaultScreen (FRAME_X_DISPLAY (f)), fontname); + //fon = XftFontOpenPattern (FRAME_X_DISPLAY (f), pat); + if(!fon) return Qnil; + FRAME_FONT(f) = fon; + //free(pat); + FRAME_BASELINE_OFFSET (f) = 0; FRAME_FONTSET (f) = -1; - FRAME_COLUMN_WIDTH (f) = FONT_WIDTH (FRAME_FONT (f)); + FRAME_COLUMN_WIDTH (f) = FONT_WIDTH (FRAME_FONT (f)) + 2; FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (FRAME_FONT (f)); - - compute_fringe_widths (f, 1); - - /* Compute the scroll bar width in character columns. */ - if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0) - { - int wid = FRAME_COLUMN_WIDTH (f); - FRAME_CONFIG_SCROLL_BAR_COLS (f) - = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid-1) / wid; - } - else - { - int wid = FRAME_COLUMN_WIDTH (f); - FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid; - } - - /* Now make the frame display the given font. */ - if (FRAME_X_WINDOW (f) != 0) - { - XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc, - FRAME_FONT (f)->fid); - XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->reverse_gc, - FRAME_FONT (f)->fid); - XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, - FRAME_FONT (f)->fid); - - /* Don't change the size of a tip frame; there's no point in - doing it because it's done in Fx_show_tip, and it leads to - problems because the tip frame has no widget. */ - if (NILP (tip_frame) || XFRAME (tip_frame) != f) - x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); - } - - return build_string (fontp->full_name); + FRAME_BASELINE_OFFSET (f) = 0; + if (FRAME_X_WINDOW (f) != 0) + x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); + return FRAME_FONT (f) ? build_string (fontname) : Qnil; } /* Give frame F the fontset named FONTSETNAME as its default font, and @@ -9496,288 +9604,14 @@ int size; int maxnames; { - Lisp_Object list = Qnil, patterns, newlist = Qnil, key = Qnil; - Lisp_Object tem, second_best; - struct x_display_info *dpyinfo - = f ? FRAME_X_DISPLAY_INFO (f) : x_display_list; - Display *dpy = dpyinfo->display; - int try_XLoadQueryFont = 0; - int count; - int allow_auto_scaled_font = 0; - - if (size < 0) - { - allow_auto_scaled_font = 1; - size = 0; - } - - patterns = Fassoc (pattern, Valternate_fontname_alist); - if (NILP (patterns)) - patterns = Fcons (pattern, Qnil); - - if (maxnames == 1 && !size) - /* We can return any single font matching PATTERN. */ - try_XLoadQueryFont = 1; - - for (; CONSP (patterns); patterns = XCDR (patterns)) - { - int num_fonts; - char **names = NULL; - - pattern = XCAR (patterns); - /* See if we cached the result for this particular query. - The cache is an alist of the form: - ((((PATTERN . MAXNAMES) . SCALABLE) (FONTNAME . WIDTH) ...) ...) */ - tem = XCDR (dpyinfo->name_list_element); - key = Fcons (Fcons (pattern, make_number (maxnames)), - allow_auto_scaled_font ? Qt : Qnil); - list = Fassoc (key, tem); - if (!NILP (list)) - { - list = Fcdr_safe (list); - /* We have a cashed list. Don't have to get the list again. */ - goto label_cached; - } - - /* At first, put PATTERN in the cache. */ - - BLOCK_INPUT; - count = x_catch_errors (dpy); - - if (try_XLoadQueryFont) - { - XFontStruct *font; - unsigned long value; - - font = XLoadQueryFont (dpy, SDATA (pattern)); - if (x_had_errors_p (dpy)) - { - /* This error is perhaps due to insufficient memory on X - server. Let's just ignore it. */ - font = NULL; - x_clear_errors (dpy); - } - - if (font - && XGetFontProperty (font, XA_FONT, &value)) - { - char *name = (char *) XGetAtomName (dpy, (Atom) value); - int len = strlen (name); - char *tmp; - - /* If DXPC (a Differential X Protocol Compressor) - Ver.3.7 is running, XGetAtomName will return null - string. We must avoid such a name. */ - if (len == 0) - try_XLoadQueryFont = 0; - else - { - num_fonts = 1; - names = (char **) alloca (sizeof (char *)); - /* Some systems only allow alloca assigned to a - simple var. */ - tmp = (char *) alloca (len + 1); names[0] = tmp; - bcopy (name, names[0], len + 1); - XFree (name); - } - } - else - try_XLoadQueryFont = 0; - - if (font) - XFreeFont (dpy, font); - } - - if (!try_XLoadQueryFont) - { - /* We try at least 10 fonts because XListFonts will return - auto-scaled fonts at the head. */ - if (maxnames < 0) - { - int limit; - - for (limit = 500;;) - { - names = XListFonts (dpy, SDATA (pattern), limit, &num_fonts); - if (num_fonts == limit) - { - BLOCK_INPUT; - XFreeFontNames (names); - UNBLOCK_INPUT; - limit *= 2; - } - else - break; - } - } - else - names = XListFonts (dpy, SDATA (pattern), max (maxnames, 10), - &num_fonts); - - if (x_had_errors_p (dpy)) - { - /* This error is perhaps due to insufficient memory on X - server. Let's just ignore it. */ - names = NULL; - x_clear_errors (dpy); - } - } - - x_uncatch_errors (dpy, count); - UNBLOCK_INPUT; - - if (names) - { - int i; - - /* Make a list of all the fonts we got back. - Store that in the font cache for the display. */ - for (i = 0; i < num_fonts; i++) - { - int width = 0; - char *p = names[i]; - int average_width = -1, resx = 0, dashes = 0; - - /* Count the number of dashes in NAMES[I]. If there are - 14 dashes, the field value following 9th dash - (RESOLUTION_X) is nonzero, and the field value - following 12th dash (AVERAGE_WIDTH) is 0, this is a - auto-scaled font which is usually too ugly to be used - for editing. Let's ignore it. */ - while (*p) - if (*p++ == '-') - { - dashes++; - if (dashes == 7) /* PIXEL_SIZE field */ - width = atoi (p); - else if (dashes == 9) - resx = atoi (p); - else if (dashes == 12) /* AVERAGE_WIDTH field */ - average_width = atoi (p); - } - - if (allow_auto_scaled_font - || dashes < 14 || average_width != 0 || resx == 0) - { - tem = build_string (names[i]); - if (NILP (Fassoc (tem, list))) - { - if (STRINGP (Vx_pixel_size_width_font_regexp) - && ((fast_c_string_match_ignore_case - (Vx_pixel_size_width_font_regexp, names[i])) - >= 0)) - /* We can set the value of PIXEL_SIZE to the - width of this font. */ - list = Fcons (Fcons (tem, make_number (width)), list); - else - /* For the moment, width is not known. */ - list = Fcons (Fcons (tem, Qnil), list); - } - } - } - - if (!try_XLoadQueryFont) - { - BLOCK_INPUT; - XFreeFontNames (names); - UNBLOCK_INPUT; - } - } - - /* Now store the result in the cache. */ - XSETCDR (dpyinfo->name_list_element, - Fcons (Fcons (key, list), XCDR (dpyinfo->name_list_element))); - - label_cached: - if (NILP (list)) continue; /* Try the remaining alternatives. */ - - newlist = second_best = Qnil; - /* Make a list of the fonts that have the right width. */ - for (; CONSP (list); list = XCDR (list)) - { - int found_size; - - tem = XCAR (list); - - if (!CONSP (tem) || NILP (XCAR (tem))) - continue; - if (!size) - { - newlist = Fcons (XCAR (tem), newlist); - continue; - } - - if (!INTEGERP (XCDR (tem))) - { - /* Since we have not yet known the size of this font, we - must try slow function call XLoadQueryFont. */ - XFontStruct *thisinfo; - - BLOCK_INPUT; - count = x_catch_errors (dpy); - thisinfo = XLoadQueryFont (dpy, - SDATA (XCAR (tem))); - if (x_had_errors_p (dpy)) - { - /* This error is perhaps due to insufficient memory on X - server. Let's just ignore it. */ - thisinfo = NULL; - x_clear_errors (dpy); - } - x_uncatch_errors (dpy, count); - UNBLOCK_INPUT; - - if (thisinfo) - { - XSETCDR (tem, - (thisinfo->min_bounds.width == 0 - ? make_number (0) - : make_number (thisinfo->max_bounds.width))); - BLOCK_INPUT; - XFreeFont (dpy, thisinfo); - UNBLOCK_INPUT; - } - else - /* For unknown reason, the previous call of XListFont had - returned a font which can't be opened. Record the size - as 0 not to try to open it again. */ - XSETCDR (tem, make_number (0)); - } - - found_size = XINT (XCDR (tem)); - if (found_size == size) - newlist = Fcons (XCAR (tem), newlist); - else if (found_size > 0) - { - if (NILP (second_best)) - second_best = tem; - else if (found_size < size) - { - if (XINT (XCDR (second_best)) > size - || XINT (XCDR (second_best)) < found_size) - second_best = tem; - } - else - { - if (XINT (XCDR (second_best)) > size - && XINT (XCDR (second_best)) > found_size) - second_best = tem; - } - } - } - if (!NILP (newlist)) - break; - else if (!NILP (second_best)) - { - newlist = Fcons (XCAR (second_best), Qnil); - break; - } - } - - return newlist; + Lisp_Object list; + Lisp_Object str; + str = build_string("-adobe-helvetica-medium-r-normal--14-140-75-75-p-77-iso8859-1"); + list = Fcons(str, Qnil); + list = Fcons(build_string("fixed"), list); + return list; } - #if GLYPH_DEBUG /* Check that FONT is valid on frame F. It is if it can be found in F's @@ -9786,7 +9620,7 @@ static void x_check_font (f, font) struct frame *f; - XFontStruct *font; + XftFont *font; { int i; struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); @@ -9804,24 +9638,27 @@ #endif /* GLYPH_DEBUG != 0 */ /* Set *W to the minimum width, *H to the minimum font height of FONT. - Note: There are (broken) X fonts out there with invalid XFontStruct + Note: There are (broken) X fonts out there with invalid XftFont min_bounds contents. For example, handa@etl.go.jp reports that "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts have font->min_bounds.width == 0. */ static INLINE void x_font_min_bounds (font, w, h) - XFontStruct *font; + XftFont *font; int *w, *h; { *h = FONT_HEIGHT (font); - *w = font->min_bounds.width; + //*w = font->min_bounds.width; + *w = font->max_advance_width; /* Try to handle the case where FONT->min_bounds has invalid contents. Since the only font known to have invalid min_bounds is fixed-width, use max_bounds if min_bounds seems to be invalid. */ +#if 0 if (*w <= 0) *w = font->max_bounds.width; +#endif } @@ -9837,7 +9674,7 @@ { int i; struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); - XFontStruct *font; + XftFont *font; int old_width = dpyinfo->smallest_char_width; int old_height = dpyinfo->smallest_font_height; @@ -9850,8 +9687,8 @@ struct font_info *fontp = dpyinfo->font_table + i; int w, h; - font = (XFontStruct *) fontp->font; - xassert (font != (XFontStruct *) ~0); + font = (XftFont *) fontp->font; + xassert (font != (XftFont *) ~0); x_font_min_bounds (font, &w, &h); dpyinfo->smallest_font_height = min (dpyinfo->smallest_font_height, h); @@ -9882,6 +9719,7 @@ Lisp_Object font_names; int count; +#if 0 /* Get a list of all the fonts that match this name. Once we have a list of matching fonts, we compare them against the fonts we already have by comparing names. */ @@ -9901,11 +9739,11 @@ SDATA (XCAR (tail))))) return (dpyinfo->font_table + i); } - +#endif /* Load the font and add it to the table. */ { char *full_name; - XFontStruct *font; + XftFont *font; struct font_info *fontp; unsigned long value; int i; @@ -9920,7 +9758,8 @@ BLOCK_INPUT; count = x_catch_errors (FRAME_X_DISPLAY (f)); - font = (XFontStruct *) XLoadQueryFont (FRAME_X_DISPLAY (f), fontname); + //font = (XftFont *) XLoadQueryFont (FRAME_X_DISPLAY (f), fontname); + font = XftFontOpenXlfd (FRAME_X_DISPLAY (f), DefaultScreen(FRAME_X_DISPLAY(f)), fontname); if (x_had_errors_p (FRAME_X_DISPLAY (f))) { /* This error is perhaps due to insufficient memory on X @@ -9961,6 +9800,7 @@ fontp->name = (char *) xmalloc (strlen (fontname) + 1); bcopy (fontname, fontp->name, strlen (fontname) + 1); +#if 0 /* Try to get the full name of FONT. Put it in FULL_NAME. */ full_name = 0; if (XGetFontProperty (font, XA_FONT, &value)) @@ -9994,8 +9834,12 @@ fontp->full_name = full_name; else fontp->full_name = fontp->name; +#else + fontp->full_name = fontp->name; +#endif - fontp->size = font->max_bounds.width; + //fontp->size = font->max_bounds.width; + fontp->size = font->max_advance_width; fontp->height = FONT_HEIGHT (font); if (NILP (font_names)) @@ -10035,6 +9879,7 @@ uses this font. So, we set information in fontp->encoding[1] which is never used by any charset. If mapping can't be decided, set FONT_ENCODING_NOT_DECIDED. */ +#if 0 fontp->encoding[1] = (font->max_byte1 == 0 /* 1-byte font */ @@ -10067,6 +9912,12 @@ fontp->default_ascent = (XGetFontProperty (font, dpyinfo->Xatom_MULE_DEFAULT_ASCENT, &value) ? (long) value : 0); +#else + fontp->encoding[1] = FONT_ENCODING_NOT_DECIDED; + fontp->baseline_offset = 0; + fontp->relative_compose = 0; + fontp->default_ascent = font->ascent; +#endif /* Set global flag fonts_changed_p to non-zero if the font loaded has a character with a smaller width than any other character @@ -10978,6 +10829,10 @@ to 4.1, set this to nil. */); x_use_underline_position_properties = 1; + DEFVAR_BOOL ("x-use-xft", &x_use_xft, + doc: /* *Non-nil means to use Xft for anti-aliasing */); + x_use_xft = 1; + DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars, doc: /* What X toolkit scroll bars Emacs uses. A value of nil means Emacs doesn't use X toolkit scroll bars. diff -u --recursive xft-base/src/xterm.h xft/src.xft/xterm.h --- xft-base/src/xterm.h 2005-03-10 18:22:58.409283431 -0500 +++ xft/src.xft/xterm.h 2005-03-10 18:18:05.413347398 -0500 @@ -26,6 +26,8 @@ #include #include +#include + #ifdef USE_X_TOOLKIT #include #include /* CoreP.h needs this */ @@ -99,7 +101,8 @@ #define WHITE_PIX_DEFAULT(f) WhitePixel (FRAME_X_DISPLAY (f), \ XScreenNumberOfScreen (FRAME_X_SCREEN (f))) -#define FONT_WIDTH(f) ((f)->max_bounds.width) +// FIXME -- cmg +#define FONT_WIDTH(f) ((f)->max_advance_width) #define FONT_HEIGHT(f) ((f)->ascent + (f)->descent) #define FONT_BASE(f) ((f)->ascent) #define FONT_DESCENT(f) ((f)->descent) @@ -503,7 +506,7 @@ int icon_bitmap; /* Default ASCII font of this frame. */ - XFontStruct *font; + XftFont *font; /* The baseline offset of the default ASCII font. */ int baseline_offset; @@ -730,6 +733,7 @@ /* Value is the smallest width of any character in any font on frame F. */ +#if 0 #define FRAME_SMALLEST_CHAR_WIDTH(F) \ FRAME_X_DISPLAY_INFO(F)->smallest_char_width @@ -737,6 +741,10 @@ #define FRAME_SMALLEST_FONT_HEIGHT(F) \ FRAME_X_DISPLAY_INFO(F)->smallest_font_height +#else +#define FRAME_SMALLEST_CHAR_WIDTH(F) 4 +#define FRAME_SMALLEST_FONT_HEIGHT(f) 3 +#endif /* Return a pointer to the image cache of frame F. */ --=-=-= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel --=-=-=--