diff options
| author | Jim Blandy | 1993-05-10 00:26:32 +0000 |
|---|---|---|
| committer | Jim Blandy | 1993-05-10 00:26:32 +0000 |
| commit | 07e34cb0a9b06e5eedabea65beec45f94594196c (patch) | |
| tree | a8b144f8541ed058d6fcac0dba2179172644ac89 | |
| parent | 9c7bb45ff3f5a5306ae7a9a203fbb81007733aa4 (diff) | |
| download | emacs-07e34cb0a9b06e5eedabea65beec45f94594196c.tar.gz emacs-07e34cb0a9b06e5eedabea65beec45f94594196c.zip | |
* 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.
| -rw-r--r-- | src/xterm.c | 210 |
1 files changed, 109 insertions, 101 deletions
diff --git a/src/xterm.c b/src/xterm.c index d5ed6dfe19a..97ebb079acf 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -395,65 +395,42 @@ XTcursor_to (row, col) | |||
| 395 | WINDOW is the x-window to output to. LEFT and TOP are starting coords. | 395 | WINDOW is the x-window to output to. LEFT and TOP are starting coords. |
| 396 | HL is 1 if this text is highlighted, 2 if the cursor is on it. | 396 | HL is 1 if this text is highlighted, 2 if the cursor is on it. |
| 397 | 397 | ||
| 398 | FONT is the default font to use (for glyphs whose font-code is 0). */ | 398 | FONT is the default font to use (for glyphs whose font-code is 0). |
| 399 | 399 | ||
| 400 | static void | 400 | Since the display generation code is responsible for calling |
| 401 | dumpglyphs (f, left, top, gp, n, hl, font) | 401 | compute_char_face and compute_glyph_face on everything it puts in |
| 402 | struct frame *f; | 402 | the display structure, we can assume that the face code on each |
| 403 | int left, top; | 403 | glyph is a valid index into FRAME_FACES (f), and the one to which |
| 404 | register GLYPH *gp; /* Points to first GLYPH. */ | 404 | we can actually apply intern_face. */ |
| 405 | register int n; /* Number of glyphs to display. */ | ||
| 406 | int hl; | ||
| 407 | FONT_TYPE *font; | ||
| 408 | { | ||
| 409 | register int len; | ||
| 410 | Window window = FRAME_X_WINDOW (f); | ||
| 411 | GC drawing_gc = (hl == 2 ? f->display.x->cursor_gc | ||
| 412 | : (hl ? f->display.x->reverse_gc | ||
| 413 | : f->display.x->normal_gc)); | ||
| 414 | 405 | ||
| 415 | if (sizeof (GLYPH) == sizeof (XChar2b)) | 406 | #if 1 |
| 416 | XDrawImageString16 (x_current_display, window, drawing_gc, | 407 | /* This is the multi-face code. */ |
| 417 | left, top + FONT_BASE (font), (XChar2b *) gp, n); | ||
| 418 | else if (sizeof (GLYPH) == sizeof (unsigned char)) | ||
| 419 | XDrawImageString (x_current_display, window, drawing_gc, | ||
| 420 | left, top + FONT_BASE (font), (char *) gp, n); | ||
| 421 | else | ||
| 422 | /* What size of glyph ARE you using? And does X have a function to | ||
| 423 | draw them? */ | ||
| 424 | abort (); | ||
| 425 | } | ||
| 426 | 408 | ||
| 427 | #if 0 | ||
| 428 | static void | 409 | static void |
| 429 | dumpglyphs (f, left, top, gp, n, hl, font) | 410 | dumpglyphs (f, left, top, gp, n, hl) |
| 430 | struct frame *f; | 411 | struct frame *f; |
| 431 | int left, top; | 412 | int left, top; |
| 432 | register GLYPH *gp; /* Points to first GLYPH. */ | 413 | register GLYPH *gp; /* Points to first GLYPH. */ |
| 433 | register int n; /* Number of glyphs to display. */ | 414 | register int n; /* Number of glyphs to display. */ |
| 434 | int hl; | 415 | int hl; |
| 435 | FONT_TYPE *font; | ||
| 436 | { | 416 | { |
| 437 | char buf[f->width]; /* Holds characters to be displayed. */ | 417 | /* Holds characters to be displayed. */ |
| 418 | char *buf = (char *) alloca (f->width * sizeof (*buf)); | ||
| 438 | register char *cp; /* Steps through buf[]. */ | 419 | register char *cp; /* Steps through buf[]. */ |
| 439 | register int tlen = GLYPH_TABLE_LENGTH; | 420 | register int tlen = GLYPH_TABLE_LENGTH; |
| 440 | register Lisp_Object *tbase = GLYPH_TABLE_BASE; | 421 | register Lisp_Object *tbase = GLYPH_TABLE_BASE; |
| 441 | Window window = FRAME_X_WINDOW (f); | 422 | Window window = FRAME_X_WINDOW (f); |
| 442 | int cursor_pixel = f->display.x->cursor_pixel; | ||
| 443 | int fg_pixel = f->display.x->foreground_pixel; | ||
| 444 | int bg_pixel = f->display.x->background_pixel; | ||
| 445 | int intborder = f->display.x->internal_border_width; | ||
| 446 | 423 | ||
| 447 | while (n) | 424 | extern struct face *intern_face (/* FRAME_PTR, struct face * */); |
| 425 | |||
| 426 | while (n > 0) | ||
| 448 | { | 427 | { |
| 449 | /* Get the face-code of the next GLYPH. */ | 428 | /* Get the face-code of the next GLYPH. */ |
| 450 | int cf, len; | 429 | int cf, len; |
| 451 | int g = *gp; | 430 | int g = *gp; |
| 452 | 431 | ||
| 453 | while (GLYPH_ALIAS_P (tbase, tlen, g)) | 432 | GLYPH_FOLLOW_ALIASES (tbase, tlen, g); |
| 454 | g = GLYPH_ALIAS (tbase, g); | 433 | cf = GLYPH_FACE (g); |
| 455 | |||
| 456 | cf = g >> 8; | ||
| 457 | 434 | ||
| 458 | /* Find the run of consecutive glyphs with the same face-code. | 435 | /* Find the run of consecutive glyphs with the same face-code. |
| 459 | Extract their character codes into BUF. */ | 436 | Extract their character codes into BUF. */ |
| @@ -461,12 +438,11 @@ dumpglyphs (f, left, top, gp, n, hl, font) | |||
| 461 | while (n > 0) | 438 | while (n > 0) |
| 462 | { | 439 | { |
| 463 | g = *gp; | 440 | g = *gp; |
| 464 | while (GLYPH_ALIAS_P (tbase, tlen, g)) | 441 | GLYPH_FOLLOW_ALIASES (tbase, tlen, g); |
| 465 | g = GLYPH_ALIAS (tbase, g); | 442 | if (GLYPH_FACE (g) != cf) |
| 466 | if ((g >> 8) != cf) | ||
| 467 | break; | 443 | break; |
| 468 | 444 | ||
| 469 | *cp++ = 0377 & g; | 445 | *cp++ = GLYPH_CHAR (g); |
| 470 | --n; | 446 | --n; |
| 471 | ++gp; | 447 | ++gp; |
| 472 | } | 448 | } |
| @@ -476,65 +452,96 @@ dumpglyphs (f, left, top, gp, n, hl, font) | |||
| 476 | 452 | ||
| 477 | /* Now output this run of chars, with the font and pixel values | 453 | /* Now output this run of chars, with the font and pixel values |
| 478 | determined by the face code CF. */ | 454 | determined by the face code CF. */ |
| 479 | if (cf == 0) | 455 | { |
| 480 | { | 456 | struct face *face = FRAME_DEFAULT_FACE (f); |
| 481 | #ifdef HAVE_X11 | 457 | FONT_TYPE *font = FACE_FONT (face); |
| 482 | GC GC_cursor = f->display.x->cursor_gc; | 458 | GC gc = FACE_GC (face); |
| 483 | GC GC_reverse = f->display.x->reverse_gc; | 459 | |
| 484 | GC GC_normal = f->display.x->normal_gc; | 460 | if (cf != 0) |
| 485 | 461 | { | |
| 486 | XDrawImageString (x_current_display, window, | 462 | /* The face codes on the glyphs must be valid indices into the |
| 487 | (hl == 2 | 463 | frame's face table. */ |
| 488 | ? GC_cursor | 464 | if (cf < 0 || cf >= FRAME_N_FACES (f)) |
| 489 | : (hl ? GC_reverse : GC_normal)), | 465 | abort (); |
| 490 | left, top + FONT_BASE (font), buf, len); | 466 | |
| 491 | #else /* ! defined (HAVE_X11) */ | 467 | if (cf == 1) |
| 492 | XText (window, left, top, | 468 | face = FRAME_MODE_LINE_FACE (f); |
| 493 | buf, | 469 | else |
| 494 | len, | 470 | face = intern_face (FRAME_FACES (f) [cf]); |
| 495 | font->id, | 471 | font = FACE_FONT (face); |
| 496 | (hl == 2 | 472 | gc = FACE_GC (face); |
| 497 | ? (cursor_pixel == fg_pixel ? bg_pixel : fg_pixel) | 473 | } |
| 498 | : hl ? bg_pixel : fg_pixel), | 474 | else if (hl == 0) |
| 499 | (hl == 2 ? cursor_pixel | 475 | ; |
| 500 | : hl ? fg_pixel : bg_pixel)); | 476 | else if (hl == 1) |
| 501 | #endif /* ! defined (HAVE_X11) */ | 477 | { |
| 502 | } | 478 | face = FRAME_MODE_LINE_FACE (f); |
| 503 | else | 479 | font = FACE_FONT (face); |
| 480 | gc = FACE_GC (face); | ||
| 481 | } | ||
| 482 | else if (hl == 2) | ||
| 483 | { | ||
| 484 | gc = (f->display.x->cursor_gc); | ||
| 485 | } | ||
| 486 | |||
| 487 | XDrawImageString (x_current_display, window, gc, | ||
| 488 | left, top + FONT_BASE (font), buf, len); | ||
| 489 | left += len * FONT_WIDTH (font); | ||
| 490 | |||
| 491 | /* We should probably check for XA_UNDERLINE_POSITION and | ||
| 492 | XA_UNDERLINE_THICKNESS properties on the font, but let's | ||
| 493 | just get the thing working, and come back to that. */ | ||
| 504 | { | 494 | { |
| 505 | #ifdef HAVE_X11 | 495 | int underline_position = 2; |
| 506 | if (FACE_IS_FONT (cf)) | 496 | |
| 507 | XDrawImageString (x_current_display, FRAME_X_WINDOW (f), | 497 | if (font->descent < underline_position) |
| 508 | FACE_GC (cf), | 498 | underline_position = font->descent; |
| 509 | left, top + FONT_BASE (FACE_FONT (cf)), | 499 | |
| 510 | buf, len); | 500 | if (face->underline) |
| 511 | else if (FACE_IS_IMAGE (cf)) | 501 | XFillRectangle (x_current_display, FRAME_X_WINDOW (f), |
| 512 | XCopyPlane (x_current_display, FACE_IMAGE (cf), | 502 | FACE_GC (face), |
| 513 | FRAME_X_WINDOW (f), | 503 | left, (top |
| 514 | f->display.x->normal_gc, | 504 | + FONT_BASE (font) |
| 515 | 0, 0, | 505 | + underline_position), |
| 516 | FACE_IMAGE_WIDTH (cf), | 506 | len * FONT_WIDTH (font), 1); |
| 517 | FACE_IMAGE_HEIGHT (cf), left, top); | ||
| 518 | else | ||
| 519 | abort (); | ||
| 520 | #else /* ! defined (HAVE_X11) */ | ||
| 521 | register struct face *fp = x_face_table[cf]; | ||
| 522 | |||
| 523 | XText (window, left, top, | ||
| 524 | buf, | ||
| 525 | len, | ||
| 526 | fp->font->id, | ||
| 527 | (hl == 2 | ||
| 528 | ? (cursor_pixel == fp->fg ? fp->bg : fp->fg) | ||
| 529 | : hl ? fp->bg : fp->fg), | ||
| 530 | (hl == 2 ? cursor_pixel | ||
| 531 | : hl ? fp->fg : fp->bg)); | ||
| 532 | #endif /* ! defined (HAVE_X11) */ | ||
| 533 | } | 507 | } |
| 534 | left += len * FONT_WIDTH (font); | 508 | |
| 509 | left += len * FONT_WIDTH (font); | ||
| 510 | } | ||
| 535 | } | 511 | } |
| 536 | } | 512 | } |
| 537 | #endif /* ! 0 */ | 513 | #endif /* 1 */ |
| 514 | |||
| 515 | #if 0 | ||
| 516 | /* This is the old single-face code. */ | ||
| 517 | |||
| 518 | static void | ||
| 519 | dumpglyphs (f, left, top, gp, n, hl, font) | ||
| 520 | struct frame *f; | ||
| 521 | int left, top; | ||
| 522 | register GLYPH *gp; /* Points to first GLYPH. */ | ||
| 523 | register int n; /* Number of glyphs to display. */ | ||
| 524 | int hl; | ||
| 525 | FONT_TYPE *font; | ||
| 526 | { | ||
| 527 | register int len; | ||
| 528 | Window window = FRAME_X_WINDOW (f); | ||
| 529 | GC drawing_gc = (hl == 2 ? f->display.x->cursor_gc | ||
| 530 | : (hl ? f->display.x->reverse_gc | ||
| 531 | : f->display.x->normal_gc)); | ||
| 532 | |||
| 533 | if (sizeof (GLYPH) == sizeof (XChar2b)) | ||
| 534 | XDrawImageString16 (x_current_display, window, drawing_gc, | ||
| 535 | left, top + FONT_BASE (font), (XChar2b *) gp, n); | ||
| 536 | else if (sizeof (GLYPH) == sizeof (unsigned char)) | ||
| 537 | XDrawImageString (x_current_display, window, drawing_gc, | ||
| 538 | left, top + FONT_BASE (font), (char *) gp, n); | ||
| 539 | else | ||
| 540 | /* What size of glyph ARE you using? And does X have a function to | ||
| 541 | draw them? */ | ||
| 542 | abort (); | ||
| 543 | } | ||
| 544 | #endif | ||
| 538 | 545 | ||
| 539 | /* Output some text at the nominal frame cursor position. | 546 | /* Output some text at the nominal frame cursor position. |
| 540 | Advance the cursor over the text. | 547 | Advance the cursor over the text. |
| @@ -567,7 +574,7 @@ XTwrite_glyphs (start, len) | |||
| 567 | dumpglyphs (f, | 574 | dumpglyphs (f, |
| 568 | CHAR_TO_PIXEL_COL (f, curs_x), | 575 | CHAR_TO_PIXEL_COL (f, curs_x), |
| 569 | CHAR_TO_PIXEL_ROW (f, curs_y), | 576 | CHAR_TO_PIXEL_ROW (f, curs_y), |
| 570 | start, len, highlight, f->display.x->font); | 577 | start, len, highlight); |
| 571 | 578 | ||
| 572 | /* If we drew on top of the cursor, note that it is turned off. */ | 579 | /* If we drew on top of the cursor, note that it is turned off. */ |
| 573 | if (curs_y == f->phys_cursor_y | 580 | if (curs_y == f->phys_cursor_y |
| @@ -1081,7 +1088,7 @@ dumprectangle (f, left, top, cols, rows) | |||
| 1081 | CHAR_TO_PIXEL_COL (f, left), | 1088 | CHAR_TO_PIXEL_COL (f, left), |
| 1082 | CHAR_TO_PIXEL_ROW (f, y), | 1089 | CHAR_TO_PIXEL_ROW (f, y), |
| 1083 | line, min (cols, active_frame->used[y] - left), | 1090 | line, min (cols, active_frame->used[y] - left), |
| 1084 | active_frame->highlight[y], f->display.x->font); | 1091 | active_frame->highlight[y]); |
| 1085 | } | 1092 | } |
| 1086 | 1093 | ||
| 1087 | /* Turn the cursor on if we turned it off. */ | 1094 | /* Turn the cursor on if we turned it off. */ |
| @@ -3312,7 +3319,7 @@ x_draw_single_glyph (f, row, column, glyph, highlight) | |||
| 3312 | dumpglyphs (f, | 3319 | dumpglyphs (f, |
| 3313 | CHAR_TO_PIXEL_COL (f, column), | 3320 | CHAR_TO_PIXEL_COL (f, column), |
| 3314 | CHAR_TO_PIXEL_ROW (f, row), | 3321 | CHAR_TO_PIXEL_ROW (f, row), |
| 3315 | &glyph, 1, highlight, f->display.x->font); | 3322 | &glyph, 1, highlight); |
| 3316 | } | 3323 | } |
| 3317 | 3324 | ||
| 3318 | static void | 3325 | static void |
| @@ -4278,6 +4285,7 @@ x_destroy_window (f) | |||
| 4278 | if (f->display.x->icon_desc != 0) | 4285 | if (f->display.x->icon_desc != 0) |
| 4279 | XDestroyWindow (XDISPLAY f->display.x->icon_desc); | 4286 | XDestroyWindow (XDISPLAY f->display.x->icon_desc); |
| 4280 | XDestroyWindow (XDISPLAY f->display.x->window_desc); | 4287 | XDestroyWindow (XDISPLAY f->display.x->window_desc); |
| 4288 | free_frame_faces (f); | ||
| 4281 | XFlushQueue (); | 4289 | XFlushQueue (); |
| 4282 | 4290 | ||
| 4283 | xfree (f->display.x); | 4291 | xfree (f->display.x); |