Mercurial > emacs
changeset 90554:d0351223b22a
(ftxfont_create_gcs): New function.
(ftxfont_draw_bitmap): Fix arg to ftfont_driver.get_bitmap.
(ftxfont_draw_backgrond): Fix filling region.
(ftxfont_default_fid): New function.
(ftxfont_open): Set xfotn->fid to the return value of
ftxfont_default_fid.
(ftxfont_prepare_face): Use ftxfont_create_gcs to create GCs.
(ftxfont_done_face): Free only GCs that are created by
ftxfont_create_gcs.
(ftxfont_draw): If face->gc != s->gc, create proper GCs.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Fri, 28 Jul 2006 12:44:45 +0000 |
parents | 0265187804a5 |
children | 45553626fa76 |
files | src/ftxfont.c |
diffstat | 1 files changed, 111 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ftxfont.c Fri Jul 28 12:40:43 2006 +0000 +++ b/src/ftxfont.c Fri Jul 28 12:44:45 2006 +0000 @@ -40,10 +40,56 @@ static Lisp_Object Qftx; /* Prototypes for helper function. */ +static int ftxfont_create_gcs P_ ((FRAME_PTR, GC *, + unsigned long, unsigned long)); static int ftxfont_draw_bitmap P_ ((FRAME_PTR, GC *, struct font *, unsigned, int, int, XPoint *, int, int *n)); static void ftxfont_draw_backgrond P_ ((FRAME_PTR, struct font *, GC, int, int, int)); +static Font ftxfont_default_fid P_ ((FRAME_PTR)); + +/* Create 6 GCs for antialiasing by interpolating colors FOREGROUND + and BACKGROUND. GCS[0] is closest to BACKGROUND, and GCS[5] is + closest to FOREGROUND. */ + +static int +ftxfont_create_gcs (f, gcs, foreground, background) + FRAME_PTR f; + GC *gcs; + unsigned long foreground, background; +{ + XColor colors[3]; + XGCValues xgcv; + int i; + + colors[0].pixel = foreground; + colors[1].pixel = background; + + BLOCK_INPUT; + XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, 2); + for (i = 1; i < 7; i++) + { + colors[2].red = (colors[0].red * i + colors[1].red * (8 - i)) / 8; + colors[2].green = (colors[0].green * i + colors[1].green * (8 - i)) / 8; + colors[2].blue = (colors[0].blue * i + colors[1].blue * (8 - i)) / 8; + if (! x_alloc_nearest_color (f, FRAME_X_COLORMAP (f), &colors[2])) + break; + xgcv.foreground = colors[2].pixel; + gcs[i - 1] = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), + GCForeground, &xgcv); + } + UNBLOCK_INPUT; + + if (i < 7) + { + BLOCK_INPUT; + for (i--; i >= 0; i--) + XFreeGC (FRAME_X_DISPLAY (f), gcs[i]); + UNBLOCK_INPUT; + return -1; + } + return 0; +} static int ftxfont_draw_bitmap (f, gc, font, code, x, y, p, size, n) @@ -59,7 +105,7 @@ unsigned char *b; int i, j; - if (ftfont_driver.get_bitmap (font, code, &bitmap, 1) < 0) + if (ftfont_driver.get_bitmap (font, code, &bitmap, size > 0x100 ? 1 : 8) < 0) return 0; for (i = 0, b = bitmap.buffer; i < bitmap.rows; i++, b += bitmap.pitch) @@ -121,10 +167,33 @@ GCForeground | GCBackground, &xgcv); XSetForeground (FRAME_X_DISPLAY (f), gc, xgcv.background); XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc, - x, y - font->ascent, width, font->font.height); + x, y - font->ascent, width, y + font->descent); XSetForeground (FRAME_X_DISPLAY (f), gc, xgcv.foreground); } +/* Return the default Font ID on frame F. */ + +static Font +ftxfont_default_fid (f) + FRAME_PTR f; +{ + static int fid_known; + static Font fid; + + if (! fid_known) + { + fid = XLoadFont (FRAME_X_DISPLAY (f), "fixed"); + if (! fid) + { + fid = XLoadFont (FRAME_X_DISPLAY (f), "*"); + if (! fid) + abort (); + } + fid_known = 1; + } + return fid; +} + /* Prototypes for font-driver methods. */ static Lisp_Object ftxfont_list P_ ((Lisp_Object, Lisp_Object)); static struct font *ftxfont_open P_ ((FRAME_PTR, Lisp_Object, int)); @@ -172,7 +241,7 @@ return NULL; } - xfont->fid = FRAME_FONT (f)->fid; + xfont->fid = ftxfont_default_fid (f); xfont->ascent = font->ascent; xfont->descent = font->descent; xfont->max_bounds.width = font->font.size; @@ -218,7 +287,8 @@ FRAME_PTR f; struct face *face; { - GC gc[6]; + struct font *font = (struct font *) face->font_info; + GC gcs[6]; XColor colors[3]; XGCValues xgcv; unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures; @@ -226,32 +296,18 @@ face->extra = NULL; - /* Here, we create 6 more GCs to simulate anti-aliasing. */ - BLOCK_INPUT; - XGetGCValues (FRAME_X_DISPLAY (f), face->gc, mask, &xgcv); - colors[0].pixel = face->foreground; - colors[1].pixel = face->background; - XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, 2); - for (i = 1; i < 7; i++) - { - colors[2].red = (colors[0].red * i + colors[1].red * (7 - i)) / 7; - colors[2].green = (colors[0].green * i + colors[1].green * (7 - i)) / 7; - colors[2].blue = (colors[0].blue * i + colors[1].blue * (7 - i)) / 7; - if (! x_alloc_nearest_color (f, FRAME_X_COLORMAP (f), &colors[2])) - break; - xgcv.foreground = colors[2].pixel; - gc[i - 1] = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - mask, &xgcv); - } - UNBLOCK_INPUT; + if (! font->scalable) + return 0; - if (i < 7) - return -1; + if (ftxfont_create_gcs (f, gcs, face->foreground, face->background) < 0) + /* Give up antialiasing. */ + return 0; + face->extra = malloc (sizeof (GC) * 7); if (! face->extra) return -1; for (i = 0; i < 6; i++) - ((GC *) face->extra)[i] = gc[i]; + ((GC *) face->extra)[i] = gcs[i]; ((GC *) face->extra)[i] = face->gc; return 0; } @@ -266,7 +322,7 @@ int i; BLOCK_INPUT; - for (i = 0; i < 7; i++) + for (i = 0; i < 6; i++) XFreeGC (FRAME_X_DISPLAY (f), ((GC *) face->extra)[i]); UNBLOCK_INPUT; free (face->extra); @@ -281,12 +337,13 @@ { FRAME_PTR f = s->f; struct face *face = s->face; - struct font *font = (struct font *) face->font; + struct font *font = (struct font *) face->font_info; XPoint p[0x700]; int n[7]; unsigned *code; int len = to - from; int i; + GC *gcs; n[0] = n[1] = n[2] = n[3] = n[4] = n[5] = n[6] = 0; @@ -299,26 +356,46 @@ code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8) | XCHAR2B_BYTE2 (s->char2b + from + i)); - if (! face->extra) + gcs = face->extra; + if (gcs && face->gc != s->gc) { + /* We are drawing for cursor or for mouse highlighting, and + can't use the prepared GCs. */ + XGCValues xgcv; + unsigned long mask = GCForeground | GCBackground; + + gcs = alloca (sizeof (GC) * 7); + XGetGCValues (FRAME_X_DISPLAY (f), s->gc, mask, &xgcv); + if (ftxfont_create_gcs (f, gcs, xgcv.foreground, xgcv.background) < 0) + gcs = NULL; + gcs[6] = s->gc; + } + + if (! gcs) + { + /* We are drawing with a bitmap font which doesn't use + antialiasing. */ for (i = 0; i < len; i++) - x += ftxfont_draw_bitmap (f, &face->gc, font, code[i], x, y, + x += ftxfont_draw_bitmap (f, &s->gc, font, code[i], x, y, p, 0x700, n); if (n[0] > 0) XDrawPoints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - face->gc, p, n[0], CoordModeOrigin); + s->gc, p, n[0], CoordModeOrigin); } else { - GC *gc = face->extra; - + /* We are drawing with a scalable font which use + antialiasing. */ for (i = 0; i < len; i++) - x += ftxfont_draw_bitmap (f, &face->gc, font, code[i], x, y, + x += ftxfont_draw_bitmap (f, gcs, font, code[i], x, y, p, 0x100, n); for (i = 0; i < 7; i++) if (n[i] > 0) XDrawPoints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - gc[i], p + 0x100 * i, n[i], CoordModeOrigin); + gcs[i], p + 0x100 * i, n[i], CoordModeOrigin); + if (face->gc != s->gc) + for (i = 0; i < 6; i++) + XFreeGC (FRAME_X_DISPLAY (f), gcs[i]); } UNBLOCK_INPUT;