Commit 07e34cb0 authored by Jim Blandy's avatar Jim Blandy

* xdisp.c (display_text_line): Apply faces to characters

	according to overlays and text properties; use
	compute_char_face and compute_glyph_face to figure out what
	face to use, and where a new face starts.
	* xterm.c (dumpglyphs): Use the upper bits of the glyphs to decide
	which frame face to use.  Call GLYPH_FOLLOW_ALIASES to make sure
	we're implementing the glyph table properly.  If we're not using
	the default or mode line face, call intern_face to find a display
	face for the frame face selected by the glyph code.  Implement
	underlining.  Remove the `font' argument; we have to derive this
	from the frame and face anyway.  Change all callers.
	* disptab.h (GLYPH_FOLLOW_ALIASES): New macro.

	* xterm.c (x_destroy_window): Call free_frame_faces.
parent 9c7bb45f
...@@ -395,65 +395,42 @@ XTcursor_to (row, col) ...@@ -395,65 +395,42 @@ XTcursor_to (row, col)
WINDOW is the x-window to output to. LEFT and TOP are starting coords. WINDOW is the x-window to output to. LEFT and TOP are starting coords.
HL is 1 if this text is highlighted, 2 if the cursor is on it. HL is 1 if this text is highlighted, 2 if the cursor is on it.
FONT is the default font to use (for glyphs whose font-code is 0). */ FONT is the default font to use (for glyphs whose font-code is 0).
static void Since the display generation code is responsible for calling
dumpglyphs (f, left, top, gp, n, hl, font) compute_char_face and compute_glyph_face on everything it puts in
struct frame *f; the display structure, we can assume that the face code on each
int left, top; glyph is a valid index into FRAME_FACES (f), and the one to which
register GLYPH *gp; /* Points to first GLYPH. */ we can actually apply intern_face. */
register int n; /* Number of glyphs to display. */
int hl;
FONT_TYPE *font;
{
register int len;
Window window = FRAME_X_WINDOW (f);
GC drawing_gc = (hl == 2 ? f->display.x->cursor_gc
: (hl ? f->display.x->reverse_gc
: f->display.x->normal_gc));
if (sizeof (GLYPH) == sizeof (XChar2b)) #if 1
XDrawImageString16 (x_current_display, window, drawing_gc, /* This is the multi-face code. */
left, top + FONT_BASE (font), (XChar2b *) gp, n);
else if (sizeof (GLYPH) == sizeof (unsigned char))
XDrawImageString (x_current_display, window, drawing_gc,
left, top + FONT_BASE (font), (char *) gp, n);
else
/* What size of glyph ARE you using? And does X have a function to
draw them? */
abort ();
}
#if 0
static void static void
dumpglyphs (f, left, top, gp, n, hl, font) dumpglyphs (f, left, top, gp, n, hl)
struct frame *f; struct frame *f;
int left, top; int left, top;
register GLYPH *gp; /* Points to first GLYPH. */ register GLYPH *gp; /* Points to first GLYPH. */
register int n; /* Number of glyphs to display. */ register int n; /* Number of glyphs to display. */
int hl; int hl;
FONT_TYPE *font;
{ {
char buf[f->width]; /* Holds characters to be displayed. */ /* Holds characters to be displayed. */
char *buf = (char *) alloca (f->width * sizeof (*buf));
register char *cp; /* Steps through buf[]. */ register char *cp; /* Steps through buf[]. */
register int tlen = GLYPH_TABLE_LENGTH; register int tlen = GLYPH_TABLE_LENGTH;
register Lisp_Object *tbase = GLYPH_TABLE_BASE; register Lisp_Object *tbase = GLYPH_TABLE_BASE;
Window window = FRAME_X_WINDOW (f); Window window = FRAME_X_WINDOW (f);
int cursor_pixel = f->display.x->cursor_pixel;
int fg_pixel = f->display.x->foreground_pixel;
int bg_pixel = f->display.x->background_pixel;
int intborder = f->display.x->internal_border_width;
while (n) extern struct face *intern_face (/* FRAME_PTR, struct face * */);
while (n > 0)
{ {
/* Get the face-code of the next GLYPH. */ /* Get the face-code of the next GLYPH. */
int cf, len; int cf, len;
int g = *gp; int g = *gp;
while (GLYPH_ALIAS_P (tbase, tlen, g)) GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
g = GLYPH_ALIAS (tbase, g); cf = GLYPH_FACE (g);
cf = g >> 8;
/* Find the run of consecutive glyphs with the same face-code. /* Find the run of consecutive glyphs with the same face-code.
Extract their character codes into BUF. */ Extract their character codes into BUF. */
...@@ -461,12 +438,11 @@ dumpglyphs (f, left, top, gp, n, hl, font) ...@@ -461,12 +438,11 @@ dumpglyphs (f, left, top, gp, n, hl, font)
while (n > 0) while (n > 0)
{ {
g = *gp; g = *gp;
while (GLYPH_ALIAS_P (tbase, tlen, g)) GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
g = GLYPH_ALIAS (tbase, g); if (GLYPH_FACE (g) != cf)
if ((g >> 8) != cf)
break; break;
*cp++ = 0377 & g; *cp++ = GLYPH_CHAR (g);
--n; --n;
++gp; ++gp;
} }
...@@ -476,65 +452,96 @@ dumpglyphs (f, left, top, gp, n, hl, font) ...@@ -476,65 +452,96 @@ dumpglyphs (f, left, top, gp, n, hl, font)
/* Now output this run of chars, with the font and pixel values /* Now output this run of chars, with the font and pixel values
determined by the face code CF. */ determined by the face code CF. */
if (cf == 0) {
{ struct face *face = FRAME_DEFAULT_FACE (f);
#ifdef HAVE_X11 FONT_TYPE *font = FACE_FONT (face);
GC GC_cursor = f->display.x->cursor_gc; GC gc = FACE_GC (face);
GC GC_reverse = f->display.x->reverse_gc;
GC GC_normal = f->display.x->normal_gc; if (cf != 0)
{
XDrawImageString (x_current_display, window, /* The face codes on the glyphs must be valid indices into the
(hl == 2 frame's face table. */
? GC_cursor if (cf < 0 || cf >= FRAME_N_FACES (f))
: (hl ? GC_reverse : GC_normal)), abort ();
left, top + FONT_BASE (font), buf, len);
#else /* ! defined (HAVE_X11) */ if (cf == 1)
XText (window, left, top, face = FRAME_MODE_LINE_FACE (f);
buf, else
len, face = intern_face (FRAME_FACES (f) [cf]);
font->id, font = FACE_FONT (face);
(hl == 2 gc = FACE_GC (face);
? (cursor_pixel == fg_pixel ? bg_pixel : fg_pixel) }
: hl ? bg_pixel : fg_pixel), else if (hl == 0)
(hl == 2 ? cursor_pixel ;
: hl ? fg_pixel : bg_pixel)); else if (hl == 1)
#endif /* ! defined (HAVE_X11) */ {
} face = FRAME_MODE_LINE_FACE (f);
else font = FACE_FONT (face);
gc = FACE_GC (face);
}
else if (hl == 2)
{
gc = (f->display.x->cursor_gc);
}
XDrawImageString (x_current_display, window, gc,
left, top + FONT_BASE (font), buf, len);
left += len * FONT_WIDTH (font);
/* We should probably check for XA_UNDERLINE_POSITION and
XA_UNDERLINE_THICKNESS properties on the font, but let's
just get the thing working, and come back to that. */
{ {
#ifdef HAVE_X11 int underline_position = 2;
if (FACE_IS_FONT (cf))
XDrawImageString (x_current_display, FRAME_X_WINDOW (f), if (font->descent < underline_position)
FACE_GC (cf), underline_position = font->descent;
left, top + FONT_BASE (FACE_FONT (cf)),
buf, len); if (face->underline)
else if (FACE_IS_IMAGE (cf)) XFillRectangle (x_current_display, FRAME_X_WINDOW (f),
XCopyPlane (x_current_display, FACE_IMAGE (cf), FACE_GC (face),
FRAME_X_WINDOW (f), left, (top
f->display.x->normal_gc, + FONT_BASE (font)
0, 0, + underline_position),
FACE_IMAGE_WIDTH (cf), len * FONT_WIDTH (font), 1);
FACE_IMAGE_HEIGHT (cf), left, top);
else
abort ();
#else /* ! defined (HAVE_X11) */
register struct face *fp = x_face_table[cf];
XText (window, left, top,
buf,
len,
fp->font->id,
(hl == 2
? (cursor_pixel == fp->fg ? fp->bg : fp->fg)
: hl ? fp->bg : fp->fg),
(hl == 2 ? cursor_pixel
: hl ? fp->fg : fp->bg));
#endif /* ! defined (HAVE_X11) */
} }
left += len * FONT_WIDTH (font);
left += len * FONT_WIDTH (font);
}
} }
} }
#endif /* ! 0 */ #endif /* 1 */
#if 0
/* This is the old single-face code. */
static void
dumpglyphs (f, left, top, gp, n, hl, font)
struct frame *f;
int left, top;
register GLYPH *gp; /* Points to first GLYPH. */
register int n; /* Number of glyphs to display. */
int hl;
FONT_TYPE *font;
{
register int len;
Window window = FRAME_X_WINDOW (f);
GC drawing_gc = (hl == 2 ? f->display.x->cursor_gc
: (hl ? f->display.x->reverse_gc
: f->display.x->normal_gc));
if (sizeof (GLYPH) == sizeof (XChar2b))
XDrawImageString16 (x_current_display, window, drawing_gc,
left, top + FONT_BASE (font), (XChar2b *) gp, n);
else if (sizeof (GLYPH) == sizeof (unsigned char))
XDrawImageString (x_current_display, window, drawing_gc,
left, top + FONT_BASE (font), (char *) gp, n);
else
/* What size of glyph ARE you using? And does X have a function to
draw them? */
abort ();
}
#endif
/* Output some text at the nominal frame cursor position. /* Output some text at the nominal frame cursor position.
Advance the cursor over the text. Advance the cursor over the text.
...@@ -567,7 +574,7 @@ XTwrite_glyphs (start, len) ...@@ -567,7 +574,7 @@ XTwrite_glyphs (start, len)
dumpglyphs (f, dumpglyphs (f,
CHAR_TO_PIXEL_COL (f, curs_x), CHAR_TO_PIXEL_COL (f, curs_x),
CHAR_TO_PIXEL_ROW (f, curs_y), CHAR_TO_PIXEL_ROW (f, curs_y),
start, len, highlight, f->display.x->font); start, len, highlight);
/* If we drew on top of the cursor, note that it is turned off. */ /* If we drew on top of the cursor, note that it is turned off. */
if (curs_y == f->phys_cursor_y if (curs_y == f->phys_cursor_y
...@@ -1081,7 +1088,7 @@ dumprectangle (f, left, top, cols, rows) ...@@ -1081,7 +1088,7 @@ dumprectangle (f, left, top, cols, rows)
CHAR_TO_PIXEL_COL (f, left), CHAR_TO_PIXEL_COL (f, left),
CHAR_TO_PIXEL_ROW (f, y), CHAR_TO_PIXEL_ROW (f, y),
line, min (cols, active_frame->used[y] - left), line, min (cols, active_frame->used[y] - left),
active_frame->highlight[y], f->display.x->font); active_frame->highlight[y]);
} }
/* Turn the cursor on if we turned it off. */ /* Turn the cursor on if we turned it off. */
...@@ -3312,7 +3319,7 @@ x_draw_single_glyph (f, row, column, glyph, highlight) ...@@ -3312,7 +3319,7 @@ x_draw_single_glyph (f, row, column, glyph, highlight)
dumpglyphs (f, dumpglyphs (f,
CHAR_TO_PIXEL_COL (f, column), CHAR_TO_PIXEL_COL (f, column),
CHAR_TO_PIXEL_ROW (f, row), CHAR_TO_PIXEL_ROW (f, row),
&glyph, 1, highlight, f->display.x->font); &glyph, 1, highlight);
} }
static void static void
...@@ -4278,6 +4285,7 @@ x_destroy_window (f) ...@@ -4278,6 +4285,7 @@ x_destroy_window (f)
if (f->display.x->icon_desc != 0) if (f->display.x->icon_desc != 0)
XDestroyWindow (XDISPLAY f->display.x->icon_desc); XDestroyWindow (XDISPLAY f->display.x->icon_desc);
XDestroyWindow (XDISPLAY f->display.x->window_desc); XDestroyWindow (XDISPLAY f->display.x->window_desc);
free_frame_faces (f);
XFlushQueue (); XFlushQueue ();
xfree (f->display.x); xfree (f->display.x);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment