comparison src/xterm.c @ 17194:ae76b2a59dcc

(dumpglyphs): Set a clipping region when we draw glyphs with a font of inappropriate size. (x_list_fonts): Try alternate fonts if we can't find a font of an appropriate size.
author Kenichi Handa <handa@m17n.org>
date Wed, 19 Mar 1997 16:33:48 +0000
parents 4173a7215c5b
children d11d6c9a48e8
comparison
equal deleted inserted replaced
17193:dc4562b0152a 17194:ae76b2a59dcc
548 register int tlen = GLYPH_TABLE_LENGTH; 548 register int tlen = GLYPH_TABLE_LENGTH;
549 register Lisp_Object *tbase = GLYPH_TABLE_BASE; 549 register Lisp_Object *tbase = GLYPH_TABLE_BASE;
550 Window window = FRAME_X_WINDOW (f); 550 Window window = FRAME_X_WINDOW (f);
551 int orig_left = left; 551 int orig_left = left;
552 int gidx = 0; 552 int gidx = 0;
553 int pixel_width; 553 int i;
554 554
555 while (n > 0) 555 while (n > 0)
556 { 556 {
557 /* Get the face-code of the next GLYPH. */ 557 /* Get the face-code of the next GLYPH. */
558 int cf, len; 558 int cf, len;
617 ++gp, --n; 617 ++gp, --n;
618 } 618 }
619 619
620 /* LEN gets the length of the run. */ 620 /* LEN gets the length of the run. */
621 len = cp - buf; 621 len = cp - buf;
622 /* PIXEL_WIDTH get the pixcel width of the run. */
623 pixel_width
624 = (FONT_WIDTH (f->output_data.x->font)
625 * (cmpcharp ? cmpcharp->width : len * CHARSET_WIDTH (charset)));
626
627 /* Now output this run of chars, with the font and pixel values 622 /* Now output this run of chars, with the font and pixel values
628 determined by the face code CF. */ 623 determined by the face code CF. */
629 { 624 {
630 struct face *face = FRAME_DEFAULT_FACE (f); 625 struct face *face = FRAME_DEFAULT_FACE (f);
631 XFontStruct *font = NULL; 626 XFontStruct *font = NULL;
632 GC gc; 627 GC gc;
633 int stippled = 0; 628 int stippled = 0;
629 int line_height = f->output_data.x->line_height;
630 /* Pixel width of each glyph in this run. */
631 int glyph_width
632 = FONT_WIDTH (f->output_data.x->font) * CHARSET_WIDTH (charset);
633 /* Overall pixel width of this run. */
634 int run_width
635 = (FONT_WIDTH (f->output_data.x->font)
636 * (cmpcharp ? cmpcharp->width : len * CHARSET_WIDTH (charset)));
634 /* A flag to tell if we have already filled background. We 637 /* A flag to tell if we have already filled background. We
635 fill background in advance in the following cases: 638 fill background in advance in the following cases:
636 1) A face has stipple. 639 1) A face has stipple.
637 2) A height of font is different from that of the current line. 640 2) A height of font is shorter than LINE_HEIGHT.
638 3) Drawing a composite character. 641 3) Drawing a composite character.
639 4) Font has non-zero _MULE_BASELINE_OFFSET property. 642 4) Font has non-zero _MULE_BASELINE_OFFSET property.
640 After filling background, we draw glyphs by XDrawString16. */ 643 After filling background, we draw glyphs by XDrawString16. */
641 int background_filled; 644 int background_filled;
642 /* Baseline position of a character, offset from TOP. */ 645 /* Baseline position of a character, offset from TOP. */
643 int baseline; 646 int baseline;
644 /* The property value of `_MULE_RELATIVE_COMPOSE' and 647 /* The property value of `_MULE_RELATIVE_COMPOSE' and
645 `_MULE_DEFAULT_ASCENT'. */ 648 `_MULE_DEFAULT_ASCENT'. */
646 int relative_compose = 0, default_ascent = 0; 649 int relative_compose = 0, default_ascent = 0;
650 /* 1 if we find no font or a font of inappropriate size. */
651 int require_clipping;
647 652
648 /* HL = 3 means use a mouse face previously chosen. */ 653 /* HL = 3 means use a mouse face previously chosen. */
649 if (hl == 3) 654 if (hl == 3)
650 cf = FRAME_X_DISPLAY_INFO (f)->mouse_face_face_id; 655 cf = FRAME_X_DISPLAY_INFO (f)->mouse_face_face_id;
651 656
689 goto font_not_found; 694 goto font_not_found;
690 695
691 font = (XFontStruct *) (fontp->font); 696 font = (XFontStruct *) (fontp->font);
692 gc = FACE_NON_ASCII_GC (face); 697 gc = FACE_NON_ASCII_GC (face);
693 XSetFont (FRAME_X_DISPLAY (f), gc, font->fid); 698 XSetFont (FRAME_X_DISPLAY (f), gc, font->fid);
694 if (font->max_byte1 != 0) 699 baseline
695 baseline = (f->output_data.x->line_height 700 = (font->max_byte1 != 0
696 + font->ascent - font->descent) / 2; 701 ? (line_height + font->ascent - font->descent) / 2
697 else 702 : f->output_data.x->font_baseline - fontp->baseline_offset);
698 baseline = (f->output_data.x->font_baseline
699 - fontp->baseline_offset);
700 if (cmpcharp && cmpcharp->cmp_rule == NULL) 703 if (cmpcharp && cmpcharp->cmp_rule == NULL)
701 { 704 {
702 relative_compose = fontp->relative_compose; 705 relative_compose = fontp->relative_compose;
703 default_ascent = fontp->default_ascent; 706 default_ascent = fontp->default_ascent;
704 } 707 }
753 if (hl == 2) 756 if (hl == 2)
754 { 757 {
755 /* The cursor overrides stippling. */ 758 /* The cursor overrides stippling. */
756 stippled = 0; 759 stippled = 0;
757 760
758 if (!cmpcharp 761 if ((font == (XFontStruct *) FACE_DEFAULT
759 && (!font 762 || font == f->output_data.x->font)
760 || font == (XFontStruct *) FACE_DEFAULT
761 || font == f->output_data.x->font)
762 && face->background == f->output_data.x->background_pixel 763 && face->background == f->output_data.x->background_pixel
763 && face->foreground == f->output_data.x->foreground_pixel) 764 && face->foreground == f->output_data.x->foreground_pixel)
764 { 765 {
765 gc = f->output_data.x->cursor_gc; 766 gc = f->output_data.x->cursor_gc;
766 } 767 }
811 } 812 }
812 813
813 if (font == (XFontStruct *) FACE_DEFAULT) 814 if (font == (XFontStruct *) FACE_DEFAULT)
814 font = f->output_data.x->font; 815 font = f->output_data.x->font;
815 816
817 if (font)
818 require_clipping = (FONT_HEIGHT (font) > line_height
819 || FONT_WIDTH (font) > glyph_width
820 || baseline != f->output_data.x->font_baseline);
821
816 if (font && (just_foreground || (cmpcharp && gidx > 0))) 822 if (font && (just_foreground || (cmpcharp && gidx > 0)))
817 background_filled = 1; 823 background_filled = 1;
818 else if (!font 824 else if (stippled)
819 || stippled
820 || f->output_data.x->line_height != FONT_HEIGHT (font)
821 || cmpcharp
822 || baseline != f->output_data.x->font_baseline)
823 { 825 {
824 if (!stippled)
825 /* This is to fill a rectangle with background color. */
826 XSetStipple (FRAME_X_DISPLAY (f), gc,
827 FRAME_X_DISPLAY_INFO (f)->null_pixel);
828 /* Turn stipple on. */ 826 /* Turn stipple on. */
829 XSetFillStyle (FRAME_X_DISPLAY (f), gc, FillOpaqueStippled); 827 XSetFillStyle (FRAME_X_DISPLAY (f), gc, FillOpaqueStippled);
830 828
831 /* Draw stipple or background color on background. */ 829 /* Draw stipple or background color on background. */
832 XFillRectangle (FRAME_X_DISPLAY (f), window, gc, 830 XFillRectangle (FRAME_X_DISPLAY (f), window, gc,
833 left, top, pixel_width, 831 left, top, run_width, line_height);
834 f->output_data.x->line_height);
835 832
836 /* Turn stipple off. */ 833 /* Turn stipple off. */
837 XSetFillStyle (FRAME_X_DISPLAY (f), gc, FillSolid); 834 XSetFillStyle (FRAME_X_DISPLAY (f), gc, FillSolid);
835
836 background_filled = 1;
837 }
838 else if (!font
839 || FONT_HEIGHT (font) < line_height
840 || FONT_WIDTH (font) < glyph_width
841 || baseline != f->output_data.x->font_baseline
842 || cmpcharp)
843 {
844 /* Fill a area for the current run in background pixle of GC. */
845 XGCValues xgcv;
846 unsigned long mask = GCForeground | GCBackground;
847 unsigned long fore, back;
848
849 /* The current code at first exchange foreground and
850 background of GC, fill the area, then recover the
851 original foreground and background of GC.
852 Aren't there more smart ways? */
853
854 XGetGCValues (FRAME_X_DISPLAY (f), gc, mask, &xgcv);
855 fore = xgcv.foreground, back = xgcv.background;
856 xgcv.foreground = back, xgcv.background = fore;
857 XChangeGC (FRAME_X_DISPLAY (f), gc, mask, &xgcv);
858 XFillRectangle (FRAME_X_DISPLAY (f), window, gc,
859 left, top, run_width, line_height);
860 xgcv.foreground = fore, xgcv.background = back;
861 XChangeGC (FRAME_X_DISPLAY (f), gc, mask, &xgcv);
838 862
839 background_filled = 1; 863 background_filled = 1;
840 if (cmpcharp) 864 if (cmpcharp)
841 /* To assure not to fill background while drawing 865 /* To assure not to fill background while drawing
842 remaining components. */ 866 remaining components. */
845 else 869 else
846 background_filled = 0; 870 background_filled = 0;
847 871
848 if (font) 872 if (font)
849 { 873 {
850 if (cmpcharp) 874 if (require_clipping)
875 {
876 Region region; /* Region used for setting clip mask to GC. */
877 XPoint x[4]; /* Data used for creating REGION. */
878
879 x[0].x = x[3].x = left, x[1].x = x[2].x = left + glyph_width;
880 x[0].y = x[1].y = top, x[2].y = x[3].y = top + line_height;
881 region = XPolygonRegion (x, 4, EvenOddRule);
882 XSetRegion (FRAME_X_DISPLAY (f), gc, region);
883 XDestroyRegion (region);
884 }
885
886 if (!cmpcharp)
887 {
888 if (require_clipping)
889 for (i = 0; i < len; i++)
890 {
891 if (i > 0)
892 XSetClipOrigin (FRAME_X_DISPLAY (f), gc,
893 glyph_width * i, 0);
894 if (background_filled)
895 XDrawString16 (FRAME_X_DISPLAY (f), window, gc,
896 left + glyph_width * i,
897 top + baseline, buf + i, 1);
898 else
899 XDrawImageString16 (FRAME_X_DISPLAY (f), window, gc,
900 left + glyph_width * i,
901 top + baseline, buf + i, 1);
902 }
903 else
904 {
905 if (background_filled)
906 XDrawString16 (FRAME_X_DISPLAY (f), window, gc,
907 left, top + baseline, buf, len);
908 else
909 XDrawImageString16 (FRAME_X_DISPLAY (f), window, gc,
910 left, top + baseline, buf, len);
911 }
912 }
913 else
851 { 914 {
852 XCharStruct *pcm; /* Pointer to per char metric info. */ 915 XCharStruct *pcm; /* Pointer to per char metric info. */
853 int i;
854 916
855 if ((cmpcharp->cmp_rule || relative_compose) 917 if ((cmpcharp->cmp_rule || relative_compose)
856 && gidx == 0) 918 && gidx == 0)
857 { 919 {
858 /* This is the first character. Initialize variables. 920 /* This is the first character. Initialize variables.
937 XDrawString16 (FRAME_X_DISPLAY (f), window, gc, 999 XDrawString16 (FRAME_X_DISPLAY (f), window, gc,
938 left + x_offset, top + baseline - y_offset, 1000 left + x_offset, top + baseline - y_offset,
939 buf + i, 1); 1001 buf + i, 1);
940 } 1002 }
941 } 1003 }
942 else if (background_filled) 1004 if (require_clipping)
943 XDrawString16 (FRAME_X_DISPLAY (f), window, gc, 1005 XSetClipMask (FRAME_X_DISPLAY (f), gc, None);
944 left, top + baseline, buf, len);
945 else
946 XDrawImageString16 (FRAME_X_DISPLAY (f), window, gc,
947 left, top + baseline, buf, len);
948
949 /* Clear the rest of the line's height. */
950 if (f->output_data.x->line_height > FONT_HEIGHT (font))
951 XClearArea (FRAME_X_DISPLAY (f), window, left,
952 top + FONT_HEIGHT (font),
953 FONT_WIDTH (font) * len,
954 /* This is how many pixels of height
955 we have to clear. */
956 f->output_data.x->line_height - FONT_HEIGHT (font),
957 False);
958 1006
959 #if 0 /* Doesn't work, because it uses FRAME_CURRENT_GLYPHS, 1007 #if 0 /* Doesn't work, because it uses FRAME_CURRENT_GLYPHS,
960 which often is not up to date yet. */ 1008 which often is not up to date yet. */
961 if (!just_foreground) 1009 if (!just_foreground)
962 { 1010 {
967 redraw_following_char (f, PIXEL_TO_CHAR_COL (f, left + len * FONT_WIDTH (font)), 1015 redraw_following_char (f, PIXEL_TO_CHAR_COL (f, left + len * FONT_WIDTH (font)),
968 PIXEL_TO_CHAR_ROW (f, top), hl == 1); 1016 PIXEL_TO_CHAR_ROW (f, top), hl == 1);
969 } 1017 }
970 #endif 1018 #endif
971 } 1019 }
972 else 1020 if (!font || require_clipping)
973 { 1021 {
974 /* There's no appropriate font for this glyph. Just show 1022 /* Show rectangles to show that we found no font or a font
975 rectangles. */ 1023 of inappropriate size. */
976 1024
977 if (cmpcharp) 1025 if (cmpcharp)
978 XDrawRectangle 1026 XDrawRectangle
979 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc, 1027 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
980 left, top + 1, 1028 left, top, run_width - 1, line_height - 1);
981 pixel_width - 2, f->output_data.x->line_height - 3);
982 else 1029 else
983 { 1030 for (i = 0; i < len; i++)
984 int left_offset; 1031 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
985 int left_skip_step = (FONT_WIDTH (f->output_data.x->font) 1032 left + glyph_width * i, top,
986 * CHARSET_WIDTH (charset)); 1033 glyph_width -1, line_height - 1);
987
988 for (left_offset = 0; left_offset < pixel_width;
989 left_offset += left_skip_step)
990 XDrawRectangle
991 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
992 left + left_offset, top + 1,
993 left_skip_step - 2, f->output_data.x->line_height - 3);
994 }
995 } 1034 }
996 1035
997 /* We should probably check for XA_UNDERLINE_POSITION and 1036 /* We should probably check for XA_UNDERLINE_POSITION and
998 XA_UNDERLINE_THICKNESS properties on the font, but let's 1037 XA_UNDERLINE_THICKNESS properties on the font, but let's
999 just get the thing working, and come back to that. */ 1038 just get the thing working, and come back to that. */
1002 current font results in shaky underline if it strides 1041 current font results in shaky underline if it strides
1003 over different fonts. So, we set the position based only 1042 over different fonts. So, we set the position based only
1004 on the default font of this frame. */ 1043 on the default font of this frame. */
1005 int underline_position = f->output_data.x->font_baseline + 1; 1044 int underline_position = f->output_data.x->font_baseline + 1;
1006 1045
1007 if (underline_position >= f->output_data.x->line_height) 1046 if (underline_position >= line_height)
1008 underline_position = f->output_data.x->line_height - 1; 1047 underline_position = line_height - 1;
1009 1048
1010 if (face->underline) 1049 if (face->underline)
1011 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 1050 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1012 FACE_GC (face), 1051 FACE_GC (face),
1013 left, top + underline_position, pixel_width, 1); 1052 left, top + underline_position, run_width, 1);
1014 } 1053 }
1015 1054
1016 if (!cmpcharp) 1055 if (!cmpcharp)
1017 left += pixel_width; 1056 left += run_width;
1018 } 1057 }
1019 } 1058 }
1020 1059
1021 return (left - orig_left); 1060 return (left - orig_left);
1022 } 1061 }
5169 return build_string (fontp->full_name); 5208 return build_string (fontp->full_name);
5170 } 5209 }
5171 5210
5172 /* Give frame F the fontset named FONTSETNAME as its default font, and 5211 /* Give frame F the fontset named FONTSETNAME as its default font, and
5173 return the full name of that fontset. FONTSETNAME may be a wildcard 5212 return the full name of that fontset. FONTSETNAME may be a wildcard
5174 pattern; in that case, we choose some font that fits the pattern. 5213 pattern; in that case, we choose some fontset that fits the pattern.
5175 The return value shows which font we chose. */ 5214 The return value shows which fontset we chose. */
5176 5215
5177 Lisp_Object 5216 Lisp_Object
5178 x_new_fontset (f, fontsetname) 5217 x_new_fontset (f, fontsetname)
5179 struct frame *f; 5218 struct frame *f;
5180 char *fontsetname; 5219 char *fontsetname;
6126 FRAME_PTR f; 6165 FRAME_PTR f;
6127 Lisp_Object pattern; 6166 Lisp_Object pattern;
6128 int size; 6167 int size;
6129 int maxnames; 6168 int maxnames;
6130 { 6169 {
6131 Lisp_Object list, newlist, key; 6170 Lisp_Object list, patterns = Qnil, newlist = Qnil, key, tem, second_best;
6132 Display *dpy = f != NULL ? FRAME_X_DISPLAY (f) : x_display_list->display; 6171 Display *dpy = f != NULL ? FRAME_X_DISPLAY (f) : x_display_list->display;
6133 6172
6134 key = Fcons (pattern, make_number (maxnames)); 6173 for (list = Valternative_fontname_alist; CONSP (list);
6135 6174 list = XCONS (list)->cdr)
6136 if (f == NULL) 6175 {
6137 list = Qnil; 6176 tem = XCONS (list)->car;
6138 else 6177 if (CONSP (tem)
6139 /* See if we cached the result for this particular query. */ 6178 && STRINGP (XCONS (tem)->car)
6140 list = Fassoc (key, 6179 && !NILP (Fstring_equal (XCONS (tem)->car, pattern)))
6141 XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr); 6180 {
6142 6181 patterns = XCONS (tem)->cdr;
6143 /* Now LIST has the form (KEY . FONT-DATA-LIST), where KEY is a 6182 break;
6144 pattern which matches font names in FONT-DATA-LIST, FONT-DATA-LIST 6183 }
6145 is a list of cons cells for the form (FONTNAME . FONTWIDTH). */ 6184 }
6146 6185
6147 if (!NILP (list)) 6186 for (patterns = Fcons (pattern, patterns); CONSP (patterns);
6148 list = XCONS (list)->cdr; 6187 patterns = XCONS (patterns)->cdr, pattern = XCONS (patterns)->car)
6149 else 6188 {
6150 {
6151 /* At first, put PATTERN in the cache. */
6152 int num_fonts; 6189 int num_fonts;
6153 char **names; 6190 char **names;
6154 6191
6192 /* See if we cached the result for this particular query. */
6193 if (f && (tem = XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr,
6194 key = Fcons (pattern, make_number (maxnames)),
6195 !NILP (list = Fassoc (key, tem))))
6196 {
6197 list = Fcdr_safe (list);
6198 /* We have a cashed list. Don't have to get the list again. */
6199 goto label_cached;
6200 }
6201
6202 /* At first, put PATTERN in the cache. */
6155 BLOCK_INPUT; 6203 BLOCK_INPUT;
6156 names = XListFonts (dpy, XSTRING (pattern)->data, maxnames, &num_fonts); 6204 names = XListFonts (dpy, XSTRING (pattern)->data, maxnames, &num_fonts);
6157 UNBLOCK_INPUT; 6205 UNBLOCK_INPUT;
6158 6206
6159 if (names) 6207 if (names)
6160 { 6208 {
6161 int i; 6209 int i;
6162 Lisp_Object tem;
6163 6210
6164 /* Make a list of all the fonts we got back. 6211 /* Make a list of all the fonts we got back.
6165 Store that in the font cache for the display. */ 6212 Store that in the font cache for the display. */
6166 for (i = 0; i < num_fonts; i++) 6213 for (i = 0; i < num_fonts; i++)
6167 { 6214 {
6168 char *p = names[i]; 6215 char *p = names[i];
6169 int average_width = -1, dashes = 0, width = 0; 6216 int average_width = -1, dashes = 0, width = 0;
6170 6217
6171 /* Count the number of dashes in NAMES[I]. If there are 6218 /* Count the number of dashes in NAMES[I]. If there are
6172 14 dashes, and the field value following 12th dash 6219 14 dashes, and the field value following 12th dash
6173 (AVERAGE_WIDTH) is 0, this is a auto-scaled font 6220 (AVERAGE_WIDTH) is 0, this is a auto-scaled font which
6174 which is usually too ugly to be used for editing. 6221 is usually too ugly to be used for editing. Let's
6175 Let's ignore it. */ 6222 ignore it. */
6176 while (*p) 6223 while (*p)
6177 if (*p++ == '-') 6224 if (*p++ == '-')
6178 { 6225 {
6179 dashes++; 6226 dashes++;
6180 if (dashes == 7) /* PIXEL_SIZE field */ 6227 if (dashes == 7) /* PIXEL_SIZE field */
6190 if (STRINGP (Vx_pixel_size_width_font_regexp) 6237 if (STRINGP (Vx_pixel_size_width_font_regexp)
6191 && (fast_string_match_ignore_case 6238 && (fast_string_match_ignore_case
6192 (Vx_pixel_size_width_font_regexp, names[i]) 6239 (Vx_pixel_size_width_font_regexp, names[i])
6193 >= 0)) 6240 >= 0))
6194 /* We can set the value of PIXEL_SIZE to the 6241 /* We can set the value of PIXEL_SIZE to the
6195 width of this font. */ 6242 width of this font. */
6196 list = Fcons (Fcons (tem, make_number (width)), list); 6243 list = Fcons (Fcons (tem, make_number (width)), list);
6197 else 6244 else
6198 /* For the moment, width is not known. */ 6245 /* For the moment, width is not known. */
6199 list = Fcons (Fcons (tem, Qnil), list); 6246 list = Fcons (Fcons (tem, Qnil), list);
6200 } 6247 }
6201 } 6248 }
6202 } 6249 }
6203 XFreeFontNames (names); 6250 XFreeFontNames (names);
6204 } 6251 }
6205 6252
6253 /* Now store the result in the cache. */
6206 if (f != NULL) 6254 if (f != NULL)
6207 XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr 6255 XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr
6208 = Fcons (Fcons (key, list), 6256 = Fcons (Fcons (key, list),
6209 XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr); 6257 XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr);
6210 } 6258
6211 6259 label_cached:
6212 if (NILP (list)) 6260 if (NILP (list)) continue; /* Try the remaining alternatives. */
6213 return Qnil; 6261
6214 6262 newlist = second_best = Qnil;
6215 newlist = Qnil; 6263 /* Make a list of the fonts that have the right width. */
6216 6264 for (; CONSP (list); list = XCONS (list)->cdr)
6217 /* Make a list of the fonts that have the right width. */
6218 for (; CONSP (list); list = XCONS (list)->cdr)
6219 {
6220 Lisp_Object tem = XCONS (list)->car;
6221 int keeper;
6222
6223 if (!CONSP (tem) || NILP (XCONS (tem)->car))
6224 continue;
6225 if (!size)
6226 keeper = 1;
6227 else
6228 { 6265 {
6266 tem = XCONS (list)->car;
6267
6268 if (!CONSP (tem) || NILP (XCONS (tem)->car))
6269 continue;
6270 if (!size)
6271 {
6272 newlist = Fcons (XCONS (tem)->car, newlist);
6273 continue;
6274 }
6275
6229 if (!INTEGERP (XCONS (tem)->cdr)) 6276 if (!INTEGERP (XCONS (tem)->cdr))
6230 { 6277 {
6278 /* Since we have not yet known the size of this font, we
6279 must try slow function call XLoadQueryFont. */
6231 XFontStruct *thisinfo; 6280 XFontStruct *thisinfo;
6232 6281
6233 BLOCK_INPUT; 6282 BLOCK_INPUT;
6234 thisinfo = XLoadQueryFont (dpy, 6283 thisinfo = XLoadQueryFont (dpy,
6235 XSTRING (XCONS (tem)->car)->data); 6284 XSTRING (XCONS (tem)->car)->data);
6239 { 6288 {
6240 XCONS (tem)->cdr = make_number (thisinfo->max_bounds.width); 6289 XCONS (tem)->cdr = make_number (thisinfo->max_bounds.width);
6241 XFreeFont (dpy, thisinfo); 6290 XFreeFont (dpy, thisinfo);
6242 } 6291 }
6243 else 6292 else
6293 /* For unknown reason, the previous call of XListFont had
6294 retruned a font which can't be opened. Record the size
6295 as 0 not to try to open it again. */
6244 XCONS (tem)->cdr = make_number (0); 6296 XCONS (tem)->cdr = make_number (0);
6245 } 6297 }
6246 keeper = XINT (XCONS (tem)->cdr) == size; 6298 if (XINT (XCONS (tem)->cdr) == size)
6299 newlist = Fcons (XCONS (tem)->car, newlist);
6300 else if (NILP (second_best))
6301 second_best = tem;
6302 else if (XINT (XCONS (tem)->cdr) < size)
6303 {
6304 if (XINT (XCONS (second_best)->cdr) > size
6305 || XINT (XCONS (second_best)->cdr) < XINT (XCONS (tem)->cdr))
6306 second_best = tem;
6307 }
6308 else
6309 {
6310 if (XINT (XCONS (second_best)->cdr) > size
6311 && XINT (XCONS (second_best)->cdr) > XINT (XCONS (tem)->cdr))
6312 second_best = tem;
6313 }
6247 } 6314 }
6248 if (keeper) 6315 if (!NILP (newlist))
6249 newlist = Fcons (XCONS (tem)->car, newlist); 6316 break;
6317 else if (!NILP (second_best))
6318 {
6319 newlist = Fcons (XCONS (second_best)->car, Qnil);
6320 break;
6321 }
6250 } 6322 }
6251 6323
6252 return newlist; 6324 return newlist;
6253 } 6325 }
6254 6326
6296 fontname = XSTRING (XCONS (font_names)->car)->data; 6368 fontname = XSTRING (XCONS (font_names)->car)->data;
6297 6369
6298 BLOCK_INPUT; 6370 BLOCK_INPUT;
6299 font = (XFontStruct *) XLoadQueryFont (FRAME_X_DISPLAY (f), fontname); 6371 font = (XFontStruct *) XLoadQueryFont (FRAME_X_DISPLAY (f), fontname);
6300 UNBLOCK_INPUT; 6372 UNBLOCK_INPUT;
6301 if (!font || (size && font->max_bounds.width != size)) 6373 if (!font)
6302 return NULL; 6374 return NULL;
6303 6375
6304 /* Do we need to create the table? */ 6376 /* Do we need to create the table? */
6305 if (dpyinfo->font_table_size == 0) 6377 if (dpyinfo->font_table_size == 0)
6306 { 6378 {