aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKarl Heuer1997-02-20 06:59:25 +0000
committerKarl Heuer1997-02-20 06:59:25 +0000
commitdc43ef945f98a6d5f90aa9e09ddd9d724f187856 (patch)
tree151c664f2fc55364a6ae0c3c94705947e02d1648 /src
parente6c7c98823ac95f36ca0c83653a8e33a88cc604e (diff)
downloademacs-dc43ef945f98a6d5f90aa9e09ddd9d724f187856.tar.gz
emacs-dc43ef945f98a6d5f90aa9e09ddd9d724f187856.zip
Include charset.h, ccl.h, and fontset.h.
(PER_CHAR_METRIC): New macro. (dumpglyphs): New argument CMPCHARP. Handle multibyte characters. (XTwrite_glyphs, redraw_previous_char, redraw_following_char): Supply argument CMPCHARP to dumpglyphs. (dumprectangle): Display whole glyph of wide-column characters. Supply argument CMPCHARP to dumpglyphs. (show_mouse_face): Supply argument CMPCHARP to dumpglyphs. (x_draw_box): Pay attention to wide-column characters. (x_draw_single_glyph): Supply argument CMPCHARP to dumpglyphs. (x_new_font): Call fs_load_font for actual font loading work. (x_new_fontset): New function. (x_get_font_info, x_list_fonts, x_load_font, x_query_font): New functions providing API to fontset handler. (x_term_init): Initialize several new members of struct x_display_info.
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c940
1 files changed, 733 insertions, 207 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 279906e2307..6bd821c1011 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -68,6 +68,9 @@ Boston, MA 02111-1307, USA. */
68/* Caused redefinition of DBL_DIG on Netbsd; seems not to be needed. */ 68/* Caused redefinition of DBL_DIG on Netbsd; seems not to be needed. */
69/* #include <sys/param.h> */ 69/* #include <sys/param.h> */
70 70
71#include "charset.h"
72#include "ccl.h"
73#include "fontset.h"
71#include "frame.h" 74#include "frame.h"
72#include "dispextern.h" 75#include "dispextern.h"
73#include "termhooks.h" 76#include "termhooks.h"
@@ -490,6 +493,19 @@ XTcursor_to (row, col)
490 } 493 }
491} 494}
492 495
496
497/* Return a pointer to per char metric information in FONT of a
498 character pointed by B (*XChar2b). */
499
500#define PER_CHAR_METRIC(font, b) \
501 ((font)->per_char \
502 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
503 + (((font)->min_byte1 || (font)->max_byte1) \
504 ? (((b)->byte1 - (font)->min_byte1) \
505 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
506 : 0)) \
507 : &((font)->max_bounds))
508
493/* Display a sequence of N glyphs found at GP. 509/* Display a sequence of N glyphs found at GP.
494 WINDOW is the x-window to output to. LEFT and TOP are starting coords. 510 WINDOW is the x-window to output to. LEFT and TOP are starting coords.
495 HL is 1 if this text is highlighted, 2 if the cursor is on it, 511 HL is 1 if this text is highlighted, 2 if the cursor is on it,
@@ -497,6 +513,11 @@ XTcursor_to (row, col)
497 JUST_FOREGROUND if 1 means draw only the foreground; 513 JUST_FOREGROUND if 1 means draw only the foreground;
498 don't alter the background. 514 don't alter the background.
499 515
516 CMPCHARP if non NULL is a pointer to the struct cmpchar_info, which
517 means drawing glyphs on the same column. This is set to non NULL
518 only when recursively called within dumpglyphs to draw a composite
519 character specified by CMPCHAR.
520
500 FONT is the default font to use (for glyphs whose font-code is 0). 521 FONT is the default font to use (for glyphs whose font-code is 0).
501 522
502 Since the display generation code is responsible for calling 523 Since the display generation code is responsible for calling
@@ -504,62 +525,122 @@ XTcursor_to (row, col)
504 the display structure, we can assume that the face code on each 525 the display structure, we can assume that the face code on each
505 glyph is a valid index into FRAME_COMPUTED_FACES (f), and the one 526 glyph is a valid index into FRAME_COMPUTED_FACES (f), and the one
506 to which we can actually apply intern_face. 527 to which we can actually apply intern_face.
507 Call this function with input blocked. */ 528 Call this function with input blocked.
529
530 Return overall pixel width of the drawn glyphs. */
508 531
509#if 1 532#if 1
510/* This is the multi-face code. */ 533/* This is the multi-face code. */
511 534
512static void 535static int
513dumpglyphs (f, left, top, gp, n, hl, just_foreground) 536dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
514 struct frame *f; 537 struct frame *f;
515 int left, top; 538 int left, top;
516 register GLYPH *gp; /* Points to first GLYPH. */ 539 register GLYPH *gp; /* Points to first GLYPH. */
517 register int n; /* Number of glyphs to display. */ 540 register int n; /* Number of glyphs to display. */
518 int hl; 541 int hl;
519 int just_foreground; 542 int just_foreground;
543 struct cmpchar_info *cmpcharp;
520{ 544{
521 /* Holds characters to be displayed. */ 545 /* Holds characters to be displayed. */
522 char *buf = (char *) alloca (FRAME_WINDOW_WIDTH (f) * sizeof (*buf)); 546 XChar2b *buf = (XChar2b *) alloca (FRAME_WINDOW_WIDTH (f) * sizeof (*buf));
523 register char *cp; /* Steps through buf[]. */ 547 register XChar2b *cp; /* Steps through buf[]. */
524 register int tlen = GLYPH_TABLE_LENGTH; 548 register int tlen = GLYPH_TABLE_LENGTH;
525 register Lisp_Object *tbase = GLYPH_TABLE_BASE; 549 register Lisp_Object *tbase = GLYPH_TABLE_BASE;
526 Window window = FRAME_X_WINDOW (f); 550 Window window = FRAME_X_WINDOW (f);
527 int orig_left = left; 551 int orig_left = left;
552 int gidx = 0;
553 int pixel_width;
528 554
529 while (n > 0) 555 while (n > 0)
530 { 556 {
531 /* Get the face-code of the next GLYPH. */ 557 /* Get the face-code of the next GLYPH. */
532 int cf, len; 558 int cf, len;
533 GLYPH g = *gp; 559 GLYPH g = *gp;
560 int ch, charset;
561 /* HIGHEST and LOWEST are used while drawing a composite
562 character. The meanings are described later. */
563 int highest, lowest;
534 564
535 GLYPH_FOLLOW_ALIASES (tbase, tlen, g); 565 GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
536 cf = FAST_GLYPH_FACE (g); 566 cf = (cmpcharp ? cmpcharp->face_work : FAST_GLYPH_FACE (g));
567 ch = FAST_GLYPH_CHAR (g);
568 charset = CHAR_CHARSET (ch);
569 if (charset == CHARSET_COMPOSITION)
570 {
571 /* We must draw components of the composite character on the
572 same column. */
573 cmpcharp = cmpchar_table[COMPOSITE_CHAR_ID (ch)];
574
575 /* Set the face in the slot for work. */
576 cmpcharp->face_work = cf;
577
578 /* We don't need the return value ... */
579 dumpglyphs (f, left, top, cmpcharp->glyph, cmpcharp->glyph_len,
580 hl, just_foreground, cmpcharp);
581 /* ... because the width of just drawn text can be
582 calculated as follows. */
583 left += FONT_WIDTH (f->output_data.x->font) * cmpcharp->width;
584
585 ++gp, --n;
586 while (gp && (*gp & GLYPH_MASK_PADDING)) ++gp, --n;
587 cmpcharp = NULL;
588 continue;
589 }
537 590
538 /* Find the run of consecutive glyphs with the same face-code. 591 /* Find the run of consecutive glyphs which can be drawn with
539 Extract their character codes into BUF. */ 592 the same GC (i.e. the same charset and the same face-code).
593 Extract their character codes into BUF.
594 If CMPCHARP is not NULL, face-code is not checked because we
595 use only the face specified in `cmpcharp->face_work'. */
540 cp = buf; 596 cp = buf;
541 while (n > 0) 597 while (n > 0)
542 { 598 {
599 int this_charset, c1, c2;
600
543 g = *gp; 601 g = *gp;
544 GLYPH_FOLLOW_ALIASES (tbase, tlen, g); 602 GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
545 if (FAST_GLYPH_FACE (g) != cf) 603 ch = FAST_GLYPH_CHAR (g);
604 SPLIT_CHAR (ch, this_charset, c1, c2);
605 if (this_charset != charset
606 || (cmpcharp == NULL && FAST_GLYPH_FACE (g) != cf))
546 break; 607 break;
547 608
548 *cp++ = FAST_GLYPH_CHAR (g); 609 if (c2)
549 --n; 610 cp->byte1 = c1, cp->byte2 = c2;
550 ++gp; 611 else
612 cp->byte1 = 0, cp->byte2 = c1;
613 ++cp;
614 ++gp, --n;
615 while (gp && (*gp & GLYPH_MASK_PADDING))
616 ++gp, --n;
551 } 617 }
552 618
553 /* LEN gets the length of the run. */ 619 /* LEN gets the length of the run. */
554 len = cp - buf; 620 len = cp - buf;
621 /* PIXEL_WIDTH get the pixcel width of the run. */
622 pixel_width
623 = (FONT_WIDTH (f->output_data.x->font)
624 * (cmpcharp ? cmpcharp->width : len * CHARSET_WIDTH (charset)));
555 625
556 /* Now output this run of chars, with the font and pixel values 626 /* Now output this run of chars, with the font and pixel values
557 determined by the face code CF. */ 627 determined by the face code CF. */
558 { 628 {
559 struct face *face = FRAME_DEFAULT_FACE (f); 629 struct face *face = FRAME_DEFAULT_FACE (f);
560 XFontStruct *font = FACE_FONT (face); 630 XFontStruct *font = NULL;
561 GC gc = FACE_GC (face); 631 GC gc;
562 int stippled = 0; 632 int stippled = 0;
633 /* A flag to tell if we have already filled background. We
634 fill background in advance in the following cases:
635 1) A face has stipple.
636 2) A height of font is different from that of the current line.
637 3) Drawing a composite character.
638 After filling background, we draw glyphs by XDrawString16. */
639 int background_filled;
640 /* Baseline position of a character, offset from TOP. */
641 int baseline;
642 /* The property value of `_MULE_RELATIVE_COMPOSE'. */
643 int relative_compose = 0;
563 644
564 /* HL = 3 means use a mouse face previously chosen. */ 645 /* HL = 3 means use a mouse face previously chosen. */
565 if (hl == 3) 646 if (hl == 3)
@@ -578,8 +659,6 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
578 face = FRAME_MODE_LINE_FACE (f); 659 face = FRAME_MODE_LINE_FACE (f);
579 else 660 else
580 face = intern_face (f, FRAME_COMPUTED_FACES (f) [cf]); 661 face = intern_face (f, FRAME_COMPUTED_FACES (f) [cf]);
581 font = FACE_FONT (face);
582 gc = FACE_GC (face);
583 if (FACE_STIPPLE (face)) 662 if (FACE_STIPPLE (face))
584 stippled = 1; 663 stippled = 1;
585 } 664 }
@@ -590,12 +669,78 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
590 else if (hl == 1) 669 else if (hl == 1)
591 { 670 {
592 face = FRAME_MODE_LINE_FACE (f); 671 face = FRAME_MODE_LINE_FACE (f);
593 font = FACE_FONT (face);
594 gc = FACE_GC (face);
595 if (FACE_STIPPLE (face)) 672 if (FACE_STIPPLE (face))
596 stippled = 1; 673 stippled = 1;
597 } 674 }
598 675
676 /* Setting appropriate font and gc for this charset. */
677 if (charset != CHARSET_ASCII)
678 {
679 int font_id;
680 int fontset = FACE_FONTSET (face);
681 struct font_info *fontp;
682
683 if ((fontset < 0 && (fontset = FRAME_FONTSET (f)) < 0)
684 || !(fontp = fs_load_font (f, FRAME_X_FONT_TABLE (f),
685 charset, NULL, fontset)))
686 goto font_not_found;
687
688 font = (XFontStruct *) (fontp->font);
689 gc = FACE_NON_ASCII_GC (face);
690 XSetFont (FRAME_X_DISPLAY (f), gc, font->fid);
691 if (font->max_byte1 != 0)
692 baseline = (f->output_data.x->line_height
693 + font->ascent - font->descent) / 2;
694 else
695 baseline = (f->output_data.x->font_baseline
696 - fontp->baseline_offset);
697 if (cmpcharp && cmpcharp->cmp_rule == NULL)
698 relative_compose = fontp->relative_compose;
699
700 /* We have to change code points in the following cases. */
701 if (fontp->font_encoder)
702 {
703 /* This font requires CCL program to calculate code
704 point of characters. */
705 struct ccl_program *ccl = fontp->font_encoder;
706
707 if (CHARSET_DIMENSION (charset) == 1)
708 for (cp = buf; cp < buf + len; cp++)
709 {
710 ccl->reg[0] = charset;
711 ccl->reg[1] = cp->byte2;
712 ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
713 cp->byte2 = ccl->reg[1];
714 }
715 else
716 for (cp = buf; cp < buf + len; cp++)
717 {
718 ccl->reg[0] = charset;
719 ccl->reg[1] = cp->byte1, ccl->reg[2] = cp->byte2;
720 ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
721 cp->byte1 = ccl->reg[1], cp->byte2 = ccl->reg[2];
722 }
723 }
724 else if (fontp->encoding[charset])
725 {
726 int enc = fontp->encoding[charset];
727
728 if ((enc == 1 || enc == 2) && CHARSET_DIMENSION (charset) == 2)
729 for (cp = buf; cp < buf + len; cp++)
730 cp->byte1 |= 0x80;
731 if (enc == 1 || enc == 3)
732 for (cp = buf; cp < buf + len; cp++)
733 cp->byte2 |= 0x80;
734 }
735 }
736 else
737 {
738 font = FACE_FONT (face);
739 baseline = FONT_BASE (font);
740 font_not_found:
741 gc = FACE_GC (face);
742 }
743
599#define FACE_DEFAULT (~0) 744#define FACE_DEFAULT (~0)
600 745
601 /* Now override that if the cursor's on this character. */ 746 /* Now override that if the cursor's on this character. */
@@ -604,9 +749,10 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
604 /* The cursor overrides stippling. */ 749 /* The cursor overrides stippling. */
605 stippled = 0; 750 stippled = 0;
606 751
607 if ((!face->font 752 if (!cmpcharp
608 || face->font == (XFontStruct *) FACE_DEFAULT 753 && (!font
609 || face->font == f->output_data.x->font) 754 || font == (XFontStruct *) FACE_DEFAULT
755 || font == f->output_data.x->font)
610 && face->background == f->output_data.x->background_pixel 756 && face->background == f->output_data.x->background_pixel
611 && face->foreground == f->output_data.x->foreground_pixel) 757 && face->foreground == f->output_data.x->foreground_pixel)
612 { 758 {
@@ -635,7 +781,10 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
635 xgcv.background = face->foreground; 781 xgcv.background = face->foreground;
636 xgcv.foreground = face->background; 782 xgcv.foreground = face->background;
637 } 783 }
638 xgcv.font = face->font->fid; 784 if (font)
785 xgcv.font = font->fid;
786 else
787 xgcv.font = FACE_FONT (face)->fid;
639 xgcv.graphics_exposures = 0; 788 xgcv.graphics_exposures = 0;
640 mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures; 789 mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
641 if (FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc) 790 if (FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc)
@@ -658,35 +807,130 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
658 if (font == (XFontStruct *) FACE_DEFAULT) 807 if (font == (XFontStruct *) FACE_DEFAULT)
659 font = f->output_data.x->font; 808 font = f->output_data.x->font;
660 809
661 if (just_foreground) 810 if (font && (just_foreground || (cmpcharp && gidx > 0)))
662 XDrawString (FRAME_X_DISPLAY (f), window, gc, 811 background_filled = 1;
663 left, top + FONT_BASE (font), buf, len); 812 else if (!font
813 || stippled
814 || f->output_data.x->line_height != FONT_HEIGHT (font)
815 || cmpcharp)
816 {
817 if (!stippled)
818 /* This is to fill a rectangle with background color. */
819 XSetStipple (FRAME_X_DISPLAY (f), gc,
820 FRAME_X_DISPLAY_INFO (f)->null_pixel);
821 /* Turn stipple on. */
822 XSetFillStyle (FRAME_X_DISPLAY (f), gc, FillOpaqueStippled);
823
824 /* Draw stipple or background color on background. */
825 XFillRectangle (FRAME_X_DISPLAY (f), window, gc,
826 left, top, pixel_width,
827 f->output_data.x->line_height);
828
829 /* Turn stipple off. */
830 XSetFillStyle (FRAME_X_DISPLAY (f), gc, FillSolid);
831
832 background_filled = 1;
833 if (cmpcharp)
834 /* To assure not to fill background while drawing
835 remaining components. */
836 just_foreground = 1;
837 }
664 else 838 else
839 background_filled = 0;
840
841 if (font)
665 { 842 {
666 if (stippled) 843 if (cmpcharp)
667 { 844 {
668 /* Turn stipple on. */ 845 XCharStruct *pcm; /* Pointer to per char metric info. */
669 XSetFillStyle (FRAME_X_DISPLAY (f), gc, FillOpaqueStippled); 846 int i;
670 847
671 /* Draw stipple on background. */ 848 if ((cmpcharp->cmp_rule || relative_compose)
672 XFillRectangle (FRAME_X_DISPLAY (f), window, gc, 849 && gidx == 0)
673 left, top, 850 {
674 FONT_WIDTH (font) * len, 851 /* This is the first character. Initialize variables.
675 FONT_HEIGHT (font)); 852 HIGHEST is the highest position of glyphs ever
853 written, LOWEST the lowest position. */
854 int x_offset = 0;
855
856 pcm = PER_CHAR_METRIC (font, buf);
857 highest = pcm->ascent + 1;
858 lowest = - pcm->descent;
859
860 if (cmpcharp->cmp_rule)
861 x_offset = (cmpcharp->col_offset[0]
862 * FONT_WIDTH (f->output_data.x->font));
863 /* Draw the first character at the normal position. */
864 XDrawString16 (FRAME_X_DISPLAY (f), window, gc,
865 left + x_offset, top + baseline, buf, 1);
866 i = 1;
867 gidx++;
868 }
869 else
870 i = 0;
676 871
677 /* Turn stipple off. */ 872 for (; i < len; i++, gidx++)
678 XSetFillStyle (FRAME_X_DISPLAY (f), gc, FillSolid); 873 {
874 int x_offset = 0, y_offset = 0;
679 875
680 /* Draw the text, solidly, onto the stipple pattern. */ 876 if (relative_compose)
681 XDrawString (FRAME_X_DISPLAY (f), window, gc, 877 {
682 left, top + FONT_BASE (font), buf, len); 878 pcm = PER_CHAR_METRIC (font, buf + i);
879 if (- pcm->descent >= relative_compose)
880 {
881 /* Draw above the current glyphs. */
882 y_offset = highest + pcm->descent;
883 highest += pcm->ascent + pcm->descent;
884 }
885 else if (pcm->ascent <= 0)
886 {
887 /* Draw beneath the current glyphs. */
888 y_offset = lowest - pcm->ascent;
889 lowest -= pcm->ascent + pcm->descent;
890 }
891 }
892 else if (cmpcharp->cmp_rule)
893 {
894 int gref = (cmpcharp->cmp_rule[gidx] - 0xA0) / 9;
895 int nref = (cmpcharp->cmp_rule[gidx] - 0xA0) % 9;
896 int bottom, top;
897
898 /* Re-encode GREF and NREF so that they specify
899 only Y-axis information:
900 0:top, 1:base, 2:bottom, 3:center */
901 gref = gref / 3 + (gref == 4) * 2;
902 nref = nref / 3 + (nref == 4) * 2;
903
904 pcm = PER_CHAR_METRIC (font, buf + i);
905 bottom = ((gref == 0 ? highest : gref == 1 ? 0
906 : gref == 2 ? lowest
907 : (highest + lowest) / 2)
908 - (nref == 0 ? pcm->ascent + pcm->descent
909 : nref == 1 ? pcm->descent : nref == 2 ? 0
910 : (pcm->ascent + pcm->descent) / 2));
911 top = bottom + (pcm->ascent + pcm->descent);
912 if (top > highest)
913 highest = top;
914 if (bottom < lowest)
915 lowest = bottom;
916 y_offset = bottom + pcm->descent;
917 x_offset = (cmpcharp->col_offset[gidx]
918 * FONT_WIDTH (f->output_data.x->font));
919 }
920 XDrawString16 (FRAME_X_DISPLAY (f), window, gc,
921 left + x_offset, top + baseline - y_offset,
922 buf + i, 1);
923 }
683 } 924 }
925 else if (background_filled)
926 XDrawString16 (FRAME_X_DISPLAY (f), window, gc,
927 left, top + baseline, buf, len);
684 else 928 else
685 XDrawImageString (FRAME_X_DISPLAY (f), window, gc, 929 XDrawImageString16 (FRAME_X_DISPLAY (f), window, gc,
686 left, top + FONT_BASE (font), buf, len); 930 left, top + baseline, buf, len);
687 931
688 /* Clear the rest of the line's height. */ 932 /* Clear the rest of the line's height. */
689 if (f->output_data.x->line_height != FONT_HEIGHT (font)) 933 if (f->output_data.x->line_height > FONT_HEIGHT (font))
690 XClearArea (FRAME_X_DISPLAY (f), window, left, 934 XClearArea (FRAME_X_DISPLAY (f), window, left,
691 top + FONT_HEIGHT (font), 935 top + FONT_HEIGHT (font),
692 FONT_WIDTH (font) * len, 936 FONT_WIDTH (font) * len,
@@ -694,42 +938,70 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
694 we have to clear. */ 938 we have to clear. */
695 f->output_data.x->line_height - FONT_HEIGHT (font), 939 f->output_data.x->line_height - FONT_HEIGHT (font),
696 False); 940 False);
697 }
698 941
699#if 0 /* Doesn't work, because it uses FRAME_CURRENT_GLYPHS, 942#if 0 /* Doesn't work, because it uses FRAME_CURRENT_GLYPHS,
700 which often is not up to date yet. */ 943 which often is not up to date yet. */
701 if (!just_foreground) 944 if (!just_foreground)
945 {
946 if (left == orig_left)
947 redraw_previous_char (f, PIXEL_TO_CHAR_COL (f, left),
948 PIXEL_TO_CHAR_ROW (f, top), hl == 1);
949 if (n == 0)
950 redraw_following_char (f, PIXEL_TO_CHAR_COL (f, left + len * FONT_WIDTH (font)),
951 PIXEL_TO_CHAR_ROW (f, top), hl == 1);
952 }
953#endif
954 }
955 else
702 { 956 {
703 if (left == orig_left) 957 /* There's no appropriate font for this glyph. Just show
704 redraw_previous_char (f, PIXEL_TO_CHAR_COL (f, left), 958 rectangles. */
705 PIXEL_TO_CHAR_ROW (f, top), hl == 1); 959
706 if (n == 0) 960 if (cmpcharp)
707 redraw_following_char (f, PIXEL_TO_CHAR_COL (f, left + len * FONT_WIDTH (font)), 961 XDrawRectangle
708 PIXEL_TO_CHAR_ROW (f, top), hl == 1); 962 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
963 left, top + 1,
964 pixel_width - 2, f->output_data.x->line_height - 3);
965 else
966 {
967 int left_offset;
968 int left_skip_step = (FONT_WIDTH (f->output_data.x->font)
969 * CHARSET_WIDTH (charset));
970
971 for (left_offset = 0; left_offset < pixel_width;
972 left_offset += left_skip_step)
973 XDrawRectangle
974 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
975 left + left_offset, top + 1,
976 left_skip_step - 2, f->output_data.x->line_height - 3);
977 }
709 } 978 }
710#endif 979
711
712 /* We should probably check for XA_UNDERLINE_POSITION and 980 /* We should probably check for XA_UNDERLINE_POSITION and
713 XA_UNDERLINE_THICKNESS properties on the font, but let's 981 XA_UNDERLINE_THICKNESS properties on the font, but let's
714 just get the thing working, and come back to that. */ 982 just get the thing working, and come back to that. */
715 { 983 {
716 int underline_position = 1; 984 /* Setting underline position based on the metric of the
985 current font results in shaky underline if it strides
986 over different fonts. So, we set the position based only
987 on the default font of this frame. */
988 int underline_position = f->output_data.x->font_baseline + 1;
717 989
718 if (font->descent <= underline_position) 990 if (underline_position >= f->output_data.x->line_height)
719 underline_position = font->descent - 1; 991 underline_position = f->output_data.x->line_height - 1;
720 992
721 if (face->underline) 993 if (face->underline)
722 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 994 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
723 FACE_GC (face), 995 FACE_GC (face),
724 left, (top 996 left, top + underline_position, pixel_width, 1);
725 + FONT_BASE (font)
726 + underline_position),
727 len * FONT_WIDTH (font), 1);
728 } 997 }
729 998
730 left += len * FONT_WIDTH (font); 999 if (!cmpcharp)
1000 left += pixel_width;
731 } 1001 }
732 } 1002 }
1003
1004 return (left - orig_left);
733} 1005}
734#endif /* 1 */ 1006#endif /* 1 */
735 1007
@@ -796,7 +1068,7 @@ XTwrite_glyphs (start, len)
796 dumpglyphs (f, 1068 dumpglyphs (f,
797 CHAR_TO_PIXEL_COL (f, curs_x), 1069 CHAR_TO_PIXEL_COL (f, curs_x),
798 CHAR_TO_PIXEL_ROW (f, curs_y), 1070 CHAR_TO_PIXEL_ROW (f, curs_y),
799 start, len, highlight, 0); 1071 start, len, highlight, 0, NULL);
800 1072
801 /* If we drew on top of the cursor, note that it is turned off. */ 1073 /* If we drew on top of the cursor, note that it is turned off. */
802 if (curs_y == f->phys_cursor_y 1074 if (curs_y == f->phys_cursor_y
@@ -923,7 +1195,7 @@ redraw_previous_char (f, x, y, highlight_flag)
923 dumpglyphs (f, CHAR_TO_PIXEL_COL (f, start_x), 1195 dumpglyphs (f, CHAR_TO_PIXEL_COL (f, start_x),
924 CHAR_TO_PIXEL_ROW (f, y), 1196 CHAR_TO_PIXEL_ROW (f, y),
925 &FRAME_CURRENT_GLYPHS (f)->glyphs[y][start_x], 1197 &FRAME_CURRENT_GLYPHS (f)->glyphs[y][start_x],
926 x - start_x, highlight_flag, 1); 1198 x - start_x, highlight_flag, 1, NULL);
927 } 1199 }
928} 1200}
929 1201
@@ -959,7 +1231,7 @@ redraw_following_char (f, x, y, highlight_flag)
959 dumpglyphs (f, CHAR_TO_PIXEL_COL (f, x), 1231 dumpglyphs (f, CHAR_TO_PIXEL_COL (f, x),
960 CHAR_TO_PIXEL_ROW (f, y), 1232 CHAR_TO_PIXEL_ROW (f, y),
961 &FRAME_CURRENT_GLYPHS (f)->glyphs[y][x], 1233 &FRAME_CURRENT_GLYPHS (f)->glyphs[y][x],
962 end_x - x, highlight_flag, 1); 1234 end_x - x, highlight_flag, 1, NULL);
963 } 1235 }
964} 1236}
965#endif /* 0 */ 1237#endif /* 0 */
@@ -1476,11 +1748,19 @@ dumprectangle (f, left, top, cols, rows)
1476 if (! active_frame->enable[y] || left > active_frame->used[y]) 1748 if (! active_frame->enable[y] || left > active_frame->used[y])
1477 continue; 1749 continue;
1478 1750
1751 while (*line & GLYPH_MASK_PADDING)
1752 {
1753 /* We must display the whole glyph of a wide-column
1754 character. */
1755 left--;
1756 line--;
1757 cols++;
1758 }
1479 dumpglyphs (f, 1759 dumpglyphs (f,
1480 CHAR_TO_PIXEL_COL (f, left), 1760 CHAR_TO_PIXEL_COL (f, left),
1481 CHAR_TO_PIXEL_ROW (f, y), 1761 CHAR_TO_PIXEL_ROW (f, y),
1482 line, min (cols, active_frame->used[y] - left), 1762 line, min (cols, active_frame->used[y] - left),
1483 active_frame->highlight[y], 0); 1763 active_frame->highlight[y], 0, NULL);
1484 } 1764 }
1485 1765
1486 /* Turn the cursor on if we turned it off. */ 1766 /* Turn the cursor on if we turned it off. */
@@ -2234,7 +2514,7 @@ show_mouse_face (dpyinfo, hl)
2234 FRAME_CURRENT_GLYPHS (f)->glyphs[i] + column, 2514 FRAME_CURRENT_GLYPHS (f)->glyphs[i] + column,
2235 endcolumn - column, 2515 endcolumn - column,
2236 /* Highlight with mouse face if hl > 0. */ 2516 /* Highlight with mouse face if hl > 0. */
2237 hl > 0 ? 3 : 0, 0); 2517 hl > 0 ? 3 : 0, 0, NULL);
2238 } 2518 }
2239 2519
2240 /* If we turned the cursor off, turn it back on. */ 2520 /* If we turned the cursor off, turn it back on. */
@@ -4254,7 +4534,13 @@ x_draw_box (f, x, y)
4254 int top = CHAR_TO_PIXEL_ROW (f, y); 4534 int top = CHAR_TO_PIXEL_ROW (f, y);
4255 int width = FONT_WIDTH (f->output_data.x->font); 4535 int width = FONT_WIDTH (f->output_data.x->font);
4256 int height = f->output_data.x->line_height; 4536 int height = f->output_data.x->line_height;
4537 int c = FAST_GLYPH_CHAR (f->phys_cursor_glyph);
4538 int charset = CHAR_CHARSET (c);
4257 4539
4540 /* If cursor is on a multi-column character, multiply WIDTH by columns. */
4541 width *= (charset == CHARSET_COMPOSITION
4542 ? cmpchar_table[COMPOSITE_CHAR_ID (c)]->width
4543 : CHARSET_WIDTH (charset));
4258 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 4544 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4259 f->output_data.x->cursor_gc, 4545 f->output_data.x->cursor_gc,
4260 left, top, width - 1, height - 1); 4546 left, top, width - 1, height - 1);
@@ -4293,7 +4579,7 @@ x_draw_single_glyph (f, row, column, glyph, highlight)
4293 dumpglyphs (f, 4579 dumpglyphs (f,
4294 CHAR_TO_PIXEL_COL (f, column), 4580 CHAR_TO_PIXEL_COL (f, column),
4295 CHAR_TO_PIXEL_ROW (f, row), 4581 CHAR_TO_PIXEL_ROW (f, row),
4296 &glyph, 1, highlight, 0); 4582 &glyph, 1, highlight, 0, NULL);
4297} 4583}
4298 4584
4299static void 4585static void
@@ -4825,140 +5111,17 @@ x_new_font (f, fontname)
4825 struct frame *f; 5111 struct frame *f;
4826 register char *fontname; 5112 register char *fontname;
4827{ 5113{
4828 int already_loaded; 5114 struct font_info *fontp
4829 int n_matching_fonts; 5115 = fs_load_font (f, FRAME_X_FONT_TABLE (f), CHARSET_ASCII, fontname, -1);
4830 XFontStruct *font_info;
4831 char **font_names;
4832
4833 /* Get a list of all the fonts that match this name. Once we
4834 have a list of matching fonts, we compare them against the fonts
4835 we already have by comparing font ids. */
4836 font_names = (char **) XListFonts (FRAME_X_DISPLAY (f), fontname,
4837 1024, &n_matching_fonts);
4838 /* Apparently it doesn't set n_matching_fonts to zero when it can't
4839 find any matches; font_names == 0 is the only clue. */
4840 if (! font_names)
4841 n_matching_fonts = 0;
4842
4843 /* Don't just give up if n_matching_fonts is 0.
4844 Apparently there's a bug on Suns: XListFontsWithInfo can
4845 fail to find a font, but XLoadQueryFont may still find it. */
4846
4847 /* See if we've already loaded a matching font. */
4848 already_loaded = -1;
4849 if (n_matching_fonts != 0)
4850 {
4851 int i, j;
4852
4853 for (i = 0; i < FRAME_X_DISPLAY_INFO (f)->n_fonts; i++)
4854 for (j = 0; j < n_matching_fonts; j++)
4855 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->font_table[i].name, font_names[j])
4856 || !strcmp (FRAME_X_DISPLAY_INFO (f)->font_table[i].full_name, font_names[j]))
4857 {
4858 already_loaded = i;
4859 fontname = FRAME_X_DISPLAY_INFO (f)->font_table[i].full_name;
4860 goto found_font;
4861 }
4862 }
4863 found_font:
4864
4865 /* If we have, just return it from the table. */
4866 if (already_loaded >= 0)
4867 f->output_data.x->font = FRAME_X_DISPLAY_INFO (f)->font_table[already_loaded].font;
4868 /* Otherwise, load the font and add it to the table. */
4869 else
4870 {
4871 int i;
4872 char *full_name;
4873 XFontStruct *font;
4874 int n_fonts;
4875
4876 /* Try to find a character-cell font in the list. */
4877#if 0
4878 /* A laudable goal, but this isn't how to do it. */
4879 for (i = 0; i < n_matching_fonts; i++)
4880 if (! font_info[i].per_char)
4881 break;
4882#else
4883 i = 0;
4884#endif
4885 5116
4886 /* See comment above. */ 5117 if (!fontp)
4887 if (n_matching_fonts != 0) 5118 return Qnil;
4888 fontname = font_names[i];
4889
4890 font = (XFontStruct *) XLoadQueryFont (FRAME_X_DISPLAY (f), fontname);
4891 if (! font)
4892 {
4893 /* Free the information from XListFonts. */
4894 if (n_matching_fonts)
4895 XFreeFontNames (font_names);
4896 return Qnil;
4897 }
4898
4899 /* Do we need to create the table? */
4900 if (FRAME_X_DISPLAY_INFO (f)->font_table_size == 0)
4901 {
4902 FRAME_X_DISPLAY_INFO (f)->font_table_size = 16;
4903 FRAME_X_DISPLAY_INFO (f)->font_table
4904 = (struct font_info *) xmalloc (FRAME_X_DISPLAY_INFO (f)->font_table_size
4905 * sizeof (struct font_info));
4906 }
4907 /* Do we need to grow the table? */
4908 else if (FRAME_X_DISPLAY_INFO (f)->n_fonts
4909 >= FRAME_X_DISPLAY_INFO (f)->font_table_size)
4910 {
4911 FRAME_X_DISPLAY_INFO (f)->font_table_size *= 2;
4912 FRAME_X_DISPLAY_INFO (f)->font_table
4913 = (struct font_info *) xrealloc (FRAME_X_DISPLAY_INFO (f)->font_table,
4914 (FRAME_X_DISPLAY_INFO (f)->font_table_size
4915 * sizeof (struct font_info)));
4916 }
4917
4918 /* Try to get the full name of FONT. Put it in full_name. */
4919 full_name = 0;
4920 for (i = 0; i < font->n_properties; i++)
4921 {
4922 if (FRAME_X_DISPLAY_INFO (f)->Xatom_FONT == font->properties[i].name)
4923 {
4924 char *name = XGetAtomName (FRAME_X_DISPLAY (f),
4925 (Atom) (font->properties[i].card32));
4926 char *p = name;
4927 int dashes = 0;
4928
4929 /* Count the number of dashes in the "full name".
4930 If it is too few, this isn't really the font's full name,
4931 so don't use it.
4932 In X11R4, the fonts did not come with their canonical names
4933 stored in them. */
4934 while (*p)
4935 {
4936 if (*p == '-')
4937 dashes++;
4938 p++;
4939 }
4940
4941 if (dashes >= 13)
4942 full_name = name;
4943
4944 break;
4945 }
4946 }
4947
4948 n_fonts = FRAME_X_DISPLAY_INFO (f)->n_fonts;
4949 FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].name = (char *) xmalloc (strlen (fontname) + 1);
4950 bcopy (fontname, FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].name, strlen (fontname) + 1);
4951 if (full_name != 0)
4952 FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].full_name = full_name;
4953 else
4954 FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].full_name = FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].name;
4955 f->output_data.x->font = FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].font = font;
4956 FRAME_X_DISPLAY_INFO (f)->n_fonts++;
4957
4958 if (full_name)
4959 fontname = full_name;
4960 }
4961 5119
5120 f->output_data.x->font = (XFontStruct *) (fontp->font);
5121 f->output_data.x->font_baseline
5122 = (f->output_data.x->font->ascent + fontp->baseline_offset);
5123 f->output_data.x->fontset = -1;
5124
4962 /* Compute the scroll bar width in character columns. */ 5125 /* Compute the scroll bar width in character columns. */
4963 if (f->scroll_bar_pixel_width > 0) 5126 if (f->scroll_bar_pixel_width > 0)
4964 { 5127 {
@@ -4986,17 +5149,44 @@ x_new_font (f, fontname)
4986 there are no faces yet, so this font's height is the line height. */ 5149 there are no faces yet, so this font's height is the line height. */
4987 f->output_data.x->line_height = FONT_HEIGHT (f->output_data.x->font); 5150 f->output_data.x->line_height = FONT_HEIGHT (f->output_data.x->font);
4988 5151
4989 { 5152 return build_string (fontp->full_name);
4990 Lisp_Object lispy_name; 5153}
5154
5155/* Give frame F the fontset named FONTSETNAME as its default font, and
5156 return the full name of that fontset. FONTSETNAME may be a wildcard
5157 pattern; in that case, we choose some font that fits the pattern.
5158 The return value shows which font we chose. */
4991 5159
4992 lispy_name = build_string (fontname); 5160Lisp_Object
5161x_new_fontset (f, fontsetname)
5162 struct frame *f;
5163 char *fontsetname;
5164{
5165 int fontset = fs_query_fontset (f, fontsetname);
5166 struct fontset_info *fontsetp;
5167 Lisp_Object result;
4993 5168
4994 /* Free the information from XListFonts. The data 5169 if (fontset < 0)
4995 we actually retain comes from XLoadQueryFont. */ 5170 return Qnil;
4996 XFreeFontNames (font_names);
4997 5171
4998 return lispy_name; 5172 fontsetp = FRAME_FONTSET_DATA (f)->fontset_table[fontset];
4999 } 5173
5174 if (!fontsetp->fontname[CHARSET_ASCII])
5175 /* This fontset doesn't contain ASCII font. */
5176 return Qnil;
5177
5178 result = x_new_font (f, fontsetp->fontname[CHARSET_ASCII]);
5179
5180 if (!STRINGP (result))
5181 /* Can't load ASCII font. */
5182 return Qnil;
5183
5184 /* Since x_new_font doesn't update any fontset information, do it now. */
5185 f->output_data.x->fontset = fontset;
5186 fs_load_font (f, FRAME_X_FONT_TABLE (f),
5187 CHARSET_ASCII, XSTRING (result)->data, fontset);
5188
5189 return build_string (fontsetname);
5000} 5190}
5001 5191
5002/* Calculate the absolute position in frame F 5192/* Calculate the absolute position in frame F
@@ -5896,6 +6086,326 @@ x_wm_set_icon_position (f, icon_x, icon_y)
5896} 6086}
5897 6087
5898 6088
6089/* Interface to fontset handler. */
6090
6091/* Return a pointer to struct font_info of font FONT_IDX of frame F. */
6092struct font_info *
6093x_get_font_info (f, font_idx)
6094 FRAME_PTR f;
6095 int font_idx;
6096{
6097 return (FRAME_X_FONT_TABLE (f) + font_idx);
6098}
6099
6100
6101/* Return a list of names of available fonts matching PATTERN on frame
6102 F. If SIZE is not 0, it is the size (maximum bound width) of fonts
6103 to be listed. Frame F NULL means we have not yet created any
6104 frame on X, and consult the first display in x_display_list.
6105 MAXNAMES sets a limit on how many fonts to match. */
6106
6107Lisp_Object
6108x_list_fonts (f, pattern, size, maxnames)
6109 FRAME_PTR f;
6110 Lisp_Object pattern;
6111 int size;
6112 int maxnames;
6113{
6114 Lisp_Object list, newlist, key;
6115 Display *dpy = f != NULL ? FRAME_X_DISPLAY (f) : x_display_list->display;
6116
6117 key = Fcons (pattern, make_number (maxnames));
6118
6119 if (f == NULL)
6120 list = Qnil;
6121 else
6122 /* See if we cached the result for this particular query. */
6123 list = Fassoc (key,
6124 XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr);
6125
6126 if (!NILP (list))
6127 list = XCONS (list)->cdr;
6128 else
6129 {
6130 /* At first, put PATTERN in the cache. */
6131 int num_fonts;
6132 char **names;
6133
6134 BLOCK_INPUT;
6135 names = XListFonts (dpy, XSTRING (pattern)->data, maxnames, &num_fonts);
6136 UNBLOCK_INPUT;
6137
6138 if (names)
6139 {
6140 int i;
6141 Lisp_Object tem;
6142
6143 /* Make a list of all the fonts we got back.
6144 Store that in the font cache for the display. */
6145 for (i = 0; i < num_fonts; i++)
6146 {
6147 char *p = names[i];
6148 int average_width = -1, dashes = 0, width = 0;
6149
6150 /* Count the number of dashes in NAMES[I]. If there are
6151 14 dashes, and the field value following 12th dash
6152 (AVERAGE_WIDTH) is 0, this is a auto-scaled font
6153 which is of no use. Let's ignore it. */
6154 while (*p)
6155 if (*p++ == '-')
6156 {
6157 dashes++;
6158 if (dashes == 7) /* PIXEL_SIZE field */
6159 width = atoi (p);
6160 else if (dashes == 12) /* AVERAGE_WIDTH field */
6161 average_width = atoi (p);
6162 }
6163 if (dashes < 14 || average_width != 0)
6164 {
6165 tem = build_string (names[i]);
6166 if (NILP (Fassoc (tem, list)))
6167 {
6168 if (STRINGP (Vx_pixel_size_width_font_regexp)
6169 && (fast_string_match_ignore_case
6170 (Vx_pixel_size_width_font_regexp, names[i])
6171 >= 0))
6172 /* We can set the value of PIXEL_SIZE to the
6173 width of this font. */
6174 list = Fcons (Fcons (tem, make_number (width)), list);
6175 else
6176 /* For the moment, width is not known. */
6177 list = Fcons (Fcons (tem, Qnil), list);
6178 }
6179 }
6180 }
6181 XFreeFontNames (names);
6182 }
6183
6184 if (f != NULL)
6185 XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr
6186 = Fcons (Fcons (key, list),
6187 XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr);
6188 }
6189
6190 if (NILP (list))
6191 return Qnil;
6192
6193 newlist = Qnil;
6194
6195 /* Make a list of the fonts that have the right width. */
6196 for (; CONSP (list); list = XCONS (list)->cdr)
6197 {
6198 Lisp_Object tem = XCONS (list)->car;
6199 int keeper;
6200
6201 if (!CONSP (tem) || NILP (XCONS (tem)->car))
6202 continue;
6203 if (!size)
6204 keeper = 1;
6205 else
6206 {
6207 if (!INTEGERP (XCONS (tem)->cdr))
6208 {
6209 XFontStruct *thisinfo;
6210
6211 BLOCK_INPUT;
6212 thisinfo = XLoadQueryFont (dpy,
6213 XSTRING (XCONS (tem)->car)->data);
6214 UNBLOCK_INPUT;
6215
6216 if (thisinfo)
6217 {
6218 XCONS (tem)->cdr = make_number (thisinfo->max_bounds.width);
6219 XFreeFont (dpy, thisinfo);
6220 }
6221 else
6222 XCONS (tem)->cdr = make_number (0);
6223 }
6224 keeper = XINT (XCONS (tem)->cdr) == size;
6225 }
6226 if (keeper)
6227 newlist = Fcons (XCONS (tem)->car, newlist);
6228 }
6229
6230 return newlist;
6231}
6232
6233/* Load font named FONTNAME of the size SIZE for frame F, and return a
6234 pointer to the structure font_info while allocating it dynamically.
6235 If SIZE is 0, load any size of font.
6236 If loading is failed, return NULL. */
6237
6238struct font_info *
6239x_load_font (f, fontname, size)
6240 struct frame *f;
6241 register char *fontname;
6242 int size;
6243{
6244 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
6245 Lisp_Object font_names;
6246
6247 /* Get a list of all the fonts that match this name. Once we
6248 have a list of matching fonts, we compare them against the fonts
6249 we already have by comparing names. */
6250 font_names = x_list_fonts (f, build_string (fontname), size, 256);
6251
6252 if (!NILP (font_names))
6253 {
6254 Lisp_Object tail;
6255 int i;
6256
6257 for (i = 0; i < dpyinfo->n_fonts; i++)
6258 for (tail = font_names; CONSP (tail); tail = XCONS (tail)->cdr)
6259 if (!strcmp (dpyinfo->font_table[i].name,
6260 XSTRING (XCONS (tail)->car)->data)
6261 || !strcmp (dpyinfo->font_table[i].full_name,
6262 XSTRING (XCONS (tail)->car)->data))
6263 return (dpyinfo->font_table + i);
6264 }
6265
6266 /* Load the font and add it to the table. */
6267 {
6268 char *full_name;
6269 XFontStruct *font;
6270 struct font_info *fontp;
6271 unsigned long value;
6272
6273 if (!NILP (font_names))
6274 fontname = XSTRING (XCONS (font_names)->car)->data;
6275
6276 BLOCK_INPUT;
6277 font = (XFontStruct *) XLoadQueryFont (FRAME_X_DISPLAY (f), fontname);
6278 UNBLOCK_INPUT;
6279 if (!font || (size && font->max_bounds.width != size))
6280 return NULL;
6281
6282 /* Do we need to create the table? */
6283 if (dpyinfo->font_table_size == 0)
6284 {
6285 dpyinfo->font_table_size = 16;
6286 dpyinfo->font_table
6287 = (struct font_info *) xmalloc (dpyinfo->font_table_size
6288 * sizeof (struct font_info));
6289 }
6290 /* Do we need to grow the table? */
6291 else if (dpyinfo->n_fonts
6292 >= dpyinfo->font_table_size)
6293 {
6294 dpyinfo->font_table_size *= 2;
6295 dpyinfo->font_table
6296 = (struct font_info *) xrealloc (dpyinfo->font_table,
6297 (dpyinfo->font_table_size
6298 * sizeof (struct font_info)));
6299 }
6300
6301 fontp = dpyinfo->font_table + dpyinfo->n_fonts;
6302
6303 /* Now fill in the slots of *FONTP. */
6304 BLOCK_INPUT;
6305 fontp->font = font;
6306 fontp->font_idx = dpyinfo->n_fonts;
6307 fontp->name = (char *) xmalloc (strlen (fontname) + 1);
6308 bcopy (fontname, fontp->name, strlen (fontname) + 1);
6309
6310 /* Try to get the full name of FONT. Put it in FULL_NAME. */
6311 full_name = 0;
6312 if (XGetFontProperty (font, XA_FONT, &value))
6313 {
6314 char *name = (char *) XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);
6315 char *p = name;
6316 int dashes = 0;
6317
6318 /* Count the number of dashes in the "full name".
6319 If it is too few, this isn't really the font's full name,
6320 so don't use it.
6321 In X11R4, the fonts did not come with their canonical names
6322 stored in them. */
6323 while (*p)
6324 {
6325 if (*p == '-')
6326 dashes++;
6327 p++;
6328 }
6329
6330 if (dashes >= 13)
6331 {
6332 full_name = (char *) xmalloc (p - name + 1);
6333 bcopy (name, full_name, p - name + 1);
6334 }
6335
6336 XFree (name);
6337 }
6338
6339 if (full_name != 0)
6340 fontp->full_name = full_name;
6341 else
6342 fontp->full_name = fontp->name;
6343
6344 fontp->size = font->max_bounds.width;
6345 fontp->height = font->ascent + font->descent;
6346
6347 /* The slot `encoding' specifies how to map a character
6348 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
6349 the font code-points (0x20..0x7F, 0xA0..0xFF, 0x2020..0x7F7F,
6350 0xA0A0..0xFFFF, 0x20A0..0x7FFF, or 0xA020..0xFF7F). For the
6351 moment, we don't know which charset uses this font. So, we set
6352 informatoin in fontp->encoding[1] which is never used by any
6353 charset. If mapping can't be decided, set -1. */
6354 fontp->encoding[1]
6355 = (font->max_byte1 == 0
6356 /* 1-byte font */
6357 ? (font->min_char_or_byte2 < 0x80
6358 ? (font->max_char_or_byte2 < 0x80
6359 ? 0 /* 0x20..0x7F */
6360 : -1) /* 0x20..0xFF (can't decide) */
6361 : 1) /* 0xA0..0xFF */
6362 /* 2-byte font */
6363 : (font->min_byte1 < 0x80
6364 ? (font->max_byte1 < 0x80
6365 ? (font->min_char_or_byte2 < 0x80
6366 ? (font->max_char_or_byte2 < 0x80
6367 ? 0 /* 0x2020..0x7F7F */
6368 : -1) /* 0x2020..0x7FFF (can't decide) */
6369 : 3) /* 0x20A0..0x7FFF */
6370 : -1) /* 0x20??..0xA0?? (can't decide) */
6371 : (font->min_char_or_byte2 < 0x80
6372 ? (font->max_char_or_byte2 < 0x80
6373 ? 2 /* 0xA020..0xFF7F */
6374 : -1) /* 0xA020..0xFFFF (can't decide) */
6375 : 1))); /* 0xA0A0..0xFFFF */
6376
6377 fontp->baseline_offset
6378 = (XGetFontProperty (font, dpyinfo->Xatom_MULE_BASELINE_OFFSET, &value)
6379 ? (long) value : 0);
6380 fontp->relative_compose
6381 = (XGetFontProperty (font, dpyinfo->Xatom_MULE_RELATIVE_COMPOSE, &value)
6382 ? (long) value : 0);
6383
6384 UNBLOCK_INPUT;
6385 dpyinfo->n_fonts++;
6386
6387 return fontp;
6388 }
6389}
6390
6391/* Return a pointer to struct font_info of a font named FONTNAME for frame F.
6392 If no such font is loaded, return NULL. */
6393struct font_info *
6394x_query_font (f, fontname)
6395 struct frame *f;
6396 register char *fontname;
6397{
6398 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
6399 int i;
6400
6401 for (i = 0; i < dpyinfo->n_fonts; i++)
6402 if (!strcmp (dpyinfo->font_table[i].name, fontname)
6403 || !strcmp (dpyinfo->font_table[i].full_name, fontname))
6404 return (dpyinfo->font_table + i);
6405 return NULL;
6406}
6407
6408
5899/* Initialization. */ 6409/* Initialization. */
5900 6410
5901#ifdef USE_X_TOOLKIT 6411#ifdef USE_X_TOOLKIT
@@ -6139,14 +6649,14 @@ x_term_init (display_name, xrm_option, resource_name)
6139 = XInternAtom (dpyinfo->display, "WM_MOVED", False); 6649 = XInternAtom (dpyinfo->display, "WM_MOVED", False);
6140 dpyinfo->Xatom_editres 6650 dpyinfo->Xatom_editres
6141 = XInternAtom (dpyinfo->display, "Editres", False); 6651 = XInternAtom (dpyinfo->display, "Editres", False);
6142 dpyinfo->Xatom_FONT
6143 = XInternAtom (dpyinfo->display, "FONT", False);
6144 dpyinfo->Xatom_CLIPBOARD 6652 dpyinfo->Xatom_CLIPBOARD
6145 = XInternAtom (dpyinfo->display, "CLIPBOARD", False); 6653 = XInternAtom (dpyinfo->display, "CLIPBOARD", False);
6146 dpyinfo->Xatom_TIMESTAMP 6654 dpyinfo->Xatom_TIMESTAMP
6147 = XInternAtom (dpyinfo->display, "TIMESTAMP", False); 6655 = XInternAtom (dpyinfo->display, "TIMESTAMP", False);
6148 dpyinfo->Xatom_TEXT 6656 dpyinfo->Xatom_TEXT
6149 = XInternAtom (dpyinfo->display, "TEXT", False); 6657 = XInternAtom (dpyinfo->display, "TEXT", False);
6658 dpyinfo->Xatom_COMPOUND_TEXT
6659 = XInternAtom (dpyinfo->display, "COMPOUND_TEXT", False);
6150 dpyinfo->Xatom_DELETE 6660 dpyinfo->Xatom_DELETE
6151 = XInternAtom (dpyinfo->display, "DELETE", False); 6661 = XInternAtom (dpyinfo->display, "DELETE", False);
6152 dpyinfo->Xatom_MULTIPLE 6662 dpyinfo->Xatom_MULTIPLE
@@ -6161,12 +6671,28 @@ x_term_init (display_name, xrm_option, resource_name)
6161 = XInternAtom (dpyinfo->display, "NULL", False); 6671 = XInternAtom (dpyinfo->display, "NULL", False);
6162 dpyinfo->Xatom_ATOM_PAIR 6672 dpyinfo->Xatom_ATOM_PAIR
6163 = XInternAtom (dpyinfo->display, "ATOM_PAIR", False); 6673 = XInternAtom (dpyinfo->display, "ATOM_PAIR", False);
6674 /* For properties of font. */
6675 dpyinfo->Xatom_PIXEL_SIZE
6676 = XInternAtom (dpyinfo->display, "PIXEL_SIZE", False);
6677 dpyinfo->Xatom_MULE_BASELINE_OFFSET
6678 = XInternAtom (dpyinfo->display, "_MULE_BASELINE_OFFSET", False);
6679 dpyinfo->Xatom_MULE_RELATIVE_COMPOSE
6680 = XInternAtom (dpyinfo->display, "_MULE_RELATIVE_COMPOSE", False);
6164 6681
6165 dpyinfo->cut_buffers_initialized = 0; 6682 dpyinfo->cut_buffers_initialized = 0;
6166 6683
6167 connection = ConnectionNumber (dpyinfo->display); 6684 connection = ConnectionNumber (dpyinfo->display);
6168 dpyinfo->connection = connection; 6685 dpyinfo->connection = connection;
6169 6686
6687 {
6688 char null_bits[] = { 0x00 };
6689
6690 dpyinfo->null_pixel
6691 = XCreatePixmapFromBitmapData (dpyinfo->display, dpyinfo->root_window,
6692 null_bits, 1, 1, (long) 0, (long) 0,
6693 1);
6694 }
6695
6170#ifdef subprocesses 6696#ifdef subprocesses
6171 /* This is only needed for distinguishing keyboard and process input. */ 6697 /* This is only needed for distinguishing keyboard and process input. */
6172 if (connection != 0) 6698 if (connection != 0)