diff options
| author | Kenichi Handa | 1997-03-19 16:33:48 +0000 |
|---|---|---|
| committer | Kenichi Handa | 1997-03-19 16:33:48 +0000 |
| commit | b5210ea72e8c1cc6b69ba5fd1a43289559cfa980 (patch) | |
| tree | 13f1b17b4539f684f0c78aca8614bbac6b721ca5 /src | |
| parent | 8c83e4f9fb79230ce3ec0d9cd49d3edc489c1647 (diff) | |
| download | emacs-b5210ea72e8c1cc6b69ba5fd1a43289559cfa980.tar.gz emacs-b5210ea72e8c1cc6b69ba5fd1a43289559cfa980.zip | |
(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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 294 |
1 files changed, 183 insertions, 111 deletions
diff --git a/src/xterm.c b/src/xterm.c index 47161855862..386aa54599a 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -550,7 +550,7 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | |||
| 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 | { |
| @@ -619,11 +619,6 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | |||
| 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 | { |
| @@ -631,10 +626,18 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | |||
| 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. */ |
| @@ -644,6 +647,8 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | |||
| 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) |
| @@ -691,12 +696,10 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | |||
| 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; |
| @@ -755,10 +758,8 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | |||
| 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 | { |
| @@ -813,30 +814,53 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | |||
| 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); |
| 838 | 835 | ||
| 839 | background_filled = 1; | 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); | ||
| 862 | |||
| 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. */ |
| @@ -847,10 +871,48 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | |||
| 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) |
| @@ -939,22 +1001,8 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | |||
| 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. */ |
| @@ -969,29 +1017,20 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | |||
| 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 |
| @@ -1004,17 +1043,17 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | |||
| 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 | ||
| @@ -5171,8 +5210,8 @@ x_new_font (f, fontname) | |||
| 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) |
| @@ -6128,30 +6167,39 @@ x_list_fonts (f, pattern, size, maxnames) | |||
| 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 | ||
| 6150 | { | 6188 | { |
| 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; |
| @@ -6159,7 +6207,6 @@ x_list_fonts (f, pattern, size, maxnames) | |||
| 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. */ |
| @@ -6169,10 +6216,10 @@ x_list_fonts (f, pattern, size, maxnames) | |||
| 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 | { |
| @@ -6192,7 +6239,7 @@ x_list_fonts (f, pattern, size, maxnames) | |||
| 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. */ |
| @@ -6203,31 +6250,33 @@ x_list_fonts (f, pattern, size, maxnames) | |||
| 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 | } | ||
| 6211 | 6258 | ||
| 6212 | if (NILP (list)) | 6259 | label_cached: |
| 6213 | return Qnil; | 6260 | if (NILP (list)) continue; /* Try the remaining alternatives. */ |
| 6214 | 6261 | ||
| 6215 | newlist = Qnil; | 6262 | newlist = second_best = Qnil; |
| 6263 | /* Make a list of the fonts that have the right width. */ | ||
| 6264 | for (; CONSP (list); list = XCONS (list)->cdr) | ||
| 6265 | { | ||
| 6266 | tem = XCONS (list)->car; | ||
| 6216 | 6267 | ||
| 6217 | /* Make a list of the fonts that have the right width. */ | 6268 | if (!CONSP (tem) || NILP (XCONS (tem)->car)) |
| 6218 | for (; CONSP (list); list = XCONS (list)->cdr) | 6269 | continue; |
| 6219 | { | 6270 | if (!size) |
| 6220 | Lisp_Object tem = XCONS (list)->car; | 6271 | { |
| 6221 | int keeper; | 6272 | newlist = Fcons (XCONS (tem)->car, newlist); |
| 6273 | continue; | ||
| 6274 | } | ||
| 6222 | 6275 | ||
| 6223 | if (!CONSP (tem) || NILP (XCONS (tem)->car)) | ||
| 6224 | continue; | ||
| 6225 | if (!size) | ||
| 6226 | keeper = 1; | ||
| 6227 | else | ||
| 6228 | { | ||
| 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; |
| @@ -6241,12 +6290,35 @@ x_list_fonts (f, pattern, size, maxnames) | |||
| 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 | } | ||
| 6314 | } | ||
| 6315 | if (!NILP (newlist)) | ||
| 6316 | break; | ||
| 6317 | else if (!NILP (second_best)) | ||
| 6318 | { | ||
| 6319 | newlist = Fcons (XCONS (second_best)->car, Qnil); | ||
| 6320 | break; | ||
| 6247 | } | 6321 | } |
| 6248 | if (keeper) | ||
| 6249 | newlist = Fcons (XCONS (tem)->car, newlist); | ||
| 6250 | } | 6322 | } |
| 6251 | 6323 | ||
| 6252 | return newlist; | 6324 | return newlist; |
| @@ -6298,7 +6370,7 @@ x_load_font (f, fontname, size) | |||
| 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? */ |