diff options
Diffstat (limited to 'src/xfont.c')
-rw-r--r-- | src/xfont.c | 228 |
1 files changed, 144 insertions, 84 deletions
diff --git a/src/xfont.c b/src/xfont.c index 3891c8b7b92..951446b44d2 100644 --- a/src/xfont.c +++ b/src/xfont.c @@ -1,5 +1,5 @@ /* xfont.c -- X core font driver. - Copyright (C) 2006-2017 Free Software Foundation, Inc. + Copyright (C) 2006-2022 Free Software Foundation, Inc. Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 National Institute of Advanced Industrial Science and Technology (AIST) Registration Number H13PRO009 @@ -20,7 +20,6 @@ You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ #include <config.h> -#include <stdio.h> #include <stdlib.h> #include <X11/Xlib.h> @@ -31,6 +30,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ #include "character.h" #include "charset.h" #include "font.h" +#include "pdumper.h" /* X core font driver. */ @@ -45,18 +45,20 @@ struct xfont_info /* Prototypes of support functions. */ -static XCharStruct *xfont_get_pcm (XFontStruct *, XChar2b *); +static XCharStruct *xfont_get_pcm (XFontStruct *, unsigned char2b); /* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B is not contained in the font. */ static XCharStruct * -xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b) +xfont_get_pcm (XFontStruct *xfont, unsigned char2b) { /* The result metric information. */ XCharStruct *pcm = NULL; + const unsigned char byte1 = char2b >> 8; + const unsigned char byte2 = char2b & 0xFF; - eassert (xfont && char2b); + eassert (xfont); if (xfont->per_char != NULL) { @@ -65,13 +67,13 @@ xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b) /* min_char_or_byte2 specifies the linear character index corresponding to the first element of the per_char array, max_char_or_byte2 is the index of the last character. A - character with non-zero CHAR2B->byte1 is not in the font. + character with non-zero byte1 is not in the font. A character with byte2 less than min_char_or_byte2 or greater max_char_or_byte2 is not in the font. */ - if (char2b->byte1 == 0 - && char2b->byte2 >= xfont->min_char_or_byte2 - && char2b->byte2 <= xfont->max_char_or_byte2) - pcm = xfont->per_char + char2b->byte2 - xfont->min_char_or_byte2; + if (byte1 == 0 + && byte2 >= xfont->min_char_or_byte2 + && byte2 <= xfont->max_char_or_byte2) + pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2; } else { @@ -88,14 +90,14 @@ xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b) D = max_char_or_byte2 - min_char_or_byte2 + 1 / = integer division \ = integer modulus */ - if (char2b->byte1 >= xfont->min_byte1 - && char2b->byte1 <= xfont->max_byte1 - && char2b->byte2 >= xfont->min_char_or_byte2 - && char2b->byte2 <= xfont->max_char_or_byte2) + if (byte1 >= xfont->min_byte1 + && byte1 <= xfont->max_byte1 + && byte2 >= xfont->min_char_or_byte2 + && byte2 <= xfont->max_char_or_byte2) pcm = (xfont->per_char + ((xfont->max_char_or_byte2 - xfont->min_char_or_byte2 + 1) - * (char2b->byte1 - xfont->min_byte1)) - + (char2b->byte2 - xfont->min_char_or_byte2)); + * (byte1 - xfont->min_byte1)) + + (byte2 - xfont->min_char_or_byte2)); } } else @@ -103,8 +105,8 @@ xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b) /* If the per_char pointer is null, all glyphs between the first and last character indexes inclusive have the same information, as given by both min_bounds and max_bounds. */ - if (char2b->byte2 >= xfont->min_char_or_byte2 - && char2b->byte2 <= xfont->max_char_or_byte2) + if (byte2 >= xfont->min_char_or_byte2 + && byte2 <= xfont->max_char_or_byte2) pcm = &xfont->max_bounds; } @@ -164,7 +166,7 @@ xfont_encode_coding_xlfd (char *xlfd) while (*p0) { - int c = STRING_CHAR_ADVANCE (p0); + int c = string_char_advance (&p0); if (c >= 0x100) return -1; @@ -190,9 +192,8 @@ xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont, { for (; CONSP (chars); chars = XCDR (chars)) { - int c = XINT (XCAR (chars)); + int c = XFIXNUM (XCAR (chars)); unsigned code = ENCODE_CHAR (charset, c); - XChar2b char2b; if (code == CHARSET_INVALID_CODE (charset)) break; @@ -200,9 +201,7 @@ xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont, continue; if (code >= 0x10000) break; - char2b.byte1 = code >> 8; - char2b.byte2 = code & 0xFF; - if (! xfont_get_pcm (xfont, &char2b)) + if (! xfont_get_pcm (xfont, code)) break; } return (NILP (chars)); @@ -213,9 +212,8 @@ xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont, for (i = ASIZE (chars) - 1; i >= 0; i--) { - int c = XINT (AREF (chars, i)); + int c = XFIXNUM (AREF (chars, i)); unsigned code = ENCODE_CHAR (charset, c); - XChar2b char2b; if (code == CHARSET_INVALID_CODE (charset)) continue; @@ -223,9 +221,7 @@ xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont, break; if (code >= 0x10000) continue; - char2b.byte1 = code >> 8; - char2b.byte2 = code & 0xFF; - if (xfont_get_pcm (xfont, &char2b)) + if (xfont_get_pcm (xfont, code)) break; } return (i >= 0); @@ -257,9 +253,9 @@ xfont_supported_scripts (Display *display, char *fontname, Lisp_Object props, /* Two special cases to avoid opening rather big fonts. */ if (EQ (AREF (props, 2), Qja)) - return list2 (intern ("kana"), intern ("han")); + return list2 (Qkana, Qhan); if (EQ (AREF (props, 2), Qko)) - return list1 (intern ("hangul")); + return list1 (Qhangul); scripts = Fgethash (props, xfont_scripts_cache, Qt); if (EQ (scripts, Qt)) { @@ -299,7 +295,7 @@ xfont_list_pattern (Display *display, const char *pattern, { Lisp_Object list = Qnil; Lisp_Object chars = Qnil; - struct charset *encoding, *repertory = NULL; + struct charset *encoding = NULL, *repertory = NULL; int i, limit, num_fonts; char **names; /* Large enough to decode the longest XLFD (255 bytes). */ @@ -376,18 +372,18 @@ xfont_list_pattern (Display *display, const char *pattern, continue; ASET (entity, FONT_TYPE_INDEX, Qx); /* Avoid auto-scaled fonts. */ - if (INTEGERP (AREF (entity, FONT_DPI_INDEX)) - && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX)) - && XINT (AREF (entity, FONT_DPI_INDEX)) != 0 - && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0) + if (FIXNUMP (AREF (entity, FONT_DPI_INDEX)) + && FIXNUMP (AREF (entity, FONT_AVGWIDTH_INDEX)) + && XFIXNUM (AREF (entity, FONT_DPI_INDEX)) != 0 + && XFIXNUM (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0) continue; /* Avoid not-allowed scalable fonts. */ if (NILP (Vscalable_fonts_allowed)) { int size = 0; - if (INTEGERP (AREF (entity, FONT_SIZE_INDEX))) - size = XINT (AREF (entity, FONT_SIZE_INDEX)); + if (FIXNUMP (AREF (entity, FONT_SIZE_INDEX))) + size = XFIXNUM (AREF (entity, FONT_SIZE_INDEX)); else if (FLOATP (AREF (entity, FONT_SIZE_INDEX))) size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX)); if (size == 0 && i_pass == 0) @@ -600,7 +596,10 @@ xfont_list_family (struct frame *f) char **names; int num_fonts, i; Lisp_Object list; - char *last_family UNINIT; + char const *last_family; +#if defined GCC_LINT || defined lint + last_family = ""; +#endif int last_len; block_input (); @@ -672,8 +671,8 @@ xfont_open (struct frame *f, Lisp_Object entity, int pixel_size) return Qnil; } - if (XINT (AREF (entity, FONT_SIZE_INDEX)) != 0) - pixel_size = XINT (AREF (entity, FONT_SIZE_INDEX)); + if (XFIXNUM (AREF (entity, FONT_SIZE_INDEX)) != 0) + pixel_size = XFIXNUM (AREF (entity, FONT_SIZE_INDEX)); else if (pixel_size == 0) { if (FRAME_FONT (f)) @@ -800,19 +799,17 @@ xfont_open (struct frame *f, Lisp_Object entity, int pixel_size) else { XCharStruct *pcm; - XChar2b char2b; Lisp_Object val; - char2b.byte1 = 0x00, char2b.byte2 = 0x20; - pcm = xfont_get_pcm (xfont, &char2b); + pcm = xfont_get_pcm (xfont, 0x20); if (pcm) font->space_width = pcm->width; else font->space_width = 0; val = Ffont_get (font_object, QCavgwidth); - if (INTEGERP (val)) - font->average_width = XINT (val) / 10; + if (FIXNUMP (val)) + font->average_width = XFIXNUM (val) / 10; if (font->average_width < 0) font->average_width = - font->average_width; else @@ -822,8 +819,8 @@ xfont_open (struct frame *f, Lisp_Object entity, int pixel_size) { int width = font->space_width, n = pcm != NULL; - for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++) - if ((pcm = xfont_get_pcm (xfont, &char2b)) != NULL) + for (unsigned char2b = 33; char2b <= 126; ++char2b) + if ((pcm = xfont_get_pcm (xfont, char2b)) != NULL) width += pcm->width, n++; if (n > 0) font->average_width = width / n; @@ -933,7 +930,6 @@ xfont_encode_char (struct font *font, int c) XFontStruct *xfont = ((struct xfont_info *) font)->xfont; struct charset *charset; unsigned code; - XChar2b char2b; charset = CHARSET_FROM_ID (font->encoding_charset); code = ENCODE_CHAR (charset, c); @@ -945,13 +941,11 @@ xfont_encode_char (struct font *font, int c) return (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset) ? code : FONT_INVALID_CODE); } - char2b.byte1 = code >> 8; - char2b.byte2 = code & 0xFF; - return (xfont_get_pcm (xfont, &char2b) ? code : FONT_INVALID_CODE); + return (xfont_get_pcm (xfont, code) ? code : FONT_INVALID_CODE); } static void -xfont_text_extents (struct font *font, unsigned int *code, +xfont_text_extents (struct font *font, const unsigned int *code, int nglyphs, struct font_metrics *metrics) { XFontStruct *xfont = ((struct xfont_info *) font)->xfont; @@ -960,13 +954,11 @@ xfont_text_extents (struct font *font, unsigned int *code, for (i = 0, first = true; i < nglyphs; i++) { - XChar2b char2b; static XCharStruct *pcm; if (code[i] >= 0x10000) continue; - char2b.byte1 = code[i] >> 8, char2b.byte2 = code[i] & 0xFF; - pcm = xfont_get_pcm (xfont, &char2b); + pcm = xfont_get_pcm (xfont, code[i]); if (! pcm) continue; if (first) @@ -999,6 +991,7 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y, bool with_background) { XFontStruct *xfont = ((struct xfont_info *) s->font)->xfont; + Display *display = FRAME_X_DISPLAY (s->f); int len = to - from; GC gc = s->gc; int i; @@ -1006,35 +999,61 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y, if (s->gc != s->face->gc) { block_input (); - XSetFont (s->display, gc, xfont->fid); + XSetFont (display, gc, xfont->fid); unblock_input (); } +#if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2)) + if (with_background + && FRAME_DISPLAY_INFO (s->f)->alpha_bits + && FRAME_CHECK_XR_VERSION (s->f, 0, 2)) + { + x_xr_ensure_picture (s->f); + + if (FRAME_X_PICTURE (s->f) != None) + { + XRenderColor xc; + int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font); + + x_xr_apply_ext_clip (s->f, gc); + x_xrender_color_from_gc_background (s->f, gc, &xc, + s->hl != DRAW_CURSOR); + XRenderFillRectangle (FRAME_X_DISPLAY (s->f), + PictOpSrc, FRAME_X_PICTURE (s->f), + &xc, x, y - ascent, s->width, height); + x_xr_reset_ext_clip (s->f); + x_mark_frame_dirty (s->f); + + with_background = false; + } + } +#endif + if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0) { USE_SAFE_ALLOCA; char *str = SAFE_ALLOCA (len); for (i = 0; i < len ; i++) - str[i] = XCHAR2B_BYTE2 (s->char2b + from + i); + str[i] = s->char2b[from + i] & 0xFF; block_input (); if (with_background) { if (s->padding_p) for (i = 0; i < len; i++) - XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f), + XDrawImageString (display, FRAME_X_DRAWABLE (s->f), gc, x + i, y, str + i, 1); else - XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f), + XDrawImageString (display, FRAME_X_DRAWABLE (s->f), gc, x, y, str, len); } else { if (s->padding_p) for (i = 0; i < len; i++) - XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f), + XDrawString (display, FRAME_X_DRAWABLE (s->f), gc, x + i, y, str + i, 1); else - XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f), + XDrawString (display, FRAME_X_DRAWABLE (s->f), gc, x, y, str, len); } unblock_input (); @@ -1047,21 +1066,51 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y, { if (s->padding_p) for (i = 0; i < len; i++) - XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f), - gc, x + i, y, s->char2b + from + i, 1); + { + const unsigned code = s->char2b[from + i]; + const XChar2b char2b = { .byte1 = code >> 8, + .byte2 = code & 0xFF }; + XDrawImageString16 (display, FRAME_X_DRAWABLE (s->f), + gc, x + i, y, &char2b, 1); + } else - XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f), - gc, x, y, s->char2b + from, len); + { + USE_SAFE_ALLOCA; + const unsigned *code = s->char2b + from; + XChar2b *char2b; + SAFE_NALLOCA (char2b, 1, len); + for (int i = 0; i < len; ++i) + char2b[i] = (XChar2b) { .byte1 = code[i] >> 8, + .byte2 = code[i] & 0xFF }; + XDrawImageString16 (display, FRAME_X_DRAWABLE (s->f), + gc, x, y, char2b, len); + SAFE_FREE (); + } } else { if (s->padding_p) for (i = 0; i < len; i++) - XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f), - gc, x + i, y, s->char2b + from + i, 1); + { + const unsigned code = s->char2b[from + i]; + const XChar2b char2b = { .byte1 = code >> 8, + .byte2 = code & 0xFF }; + XDrawString16 (display, FRAME_X_DRAWABLE (s->f), + gc, x + i, y, &char2b, 1); + } else - XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f), - gc, x, y, s->char2b + from, len); + { + USE_SAFE_ALLOCA; + const unsigned *code = s->char2b + from; + XChar2b *char2b; + SAFE_NALLOCA (char2b, 1, len); + for (int i = 0; i < len; ++i) + char2b[i] = (XChar2b) { .byte1 = code[i] >> 8, + .byte2 = code[i] & 0xFF }; + XDrawString16 (display, FRAME_X_DRAWABLE (s->f), + gc, x, y, char2b, len); + SAFE_FREE (); + } } unblock_input (); @@ -1077,22 +1126,23 @@ xfont_check (struct frame *f, struct font *font) } +static void syms_of_xfont_for_pdumper (void); struct font_driver const xfont_driver = { - .type = LISPSYM_INITIALLY (Qx), - .get_cache = xfont_get_cache, - .list = xfont_list, - .match = xfont_match, - .list_family = xfont_list_family, - .open = xfont_open, - .close = xfont_close, - .prepare_face = xfont_prepare_face, - .has_char = xfont_has_char, - .encode_char = xfont_encode_char, - .text_extents = xfont_text_extents, - .draw = xfont_draw, - .check = xfont_check, + .type = LISPSYM_INITIALLY (Qx), + .get_cache = xfont_get_cache, + .list = xfont_list, + .match = xfont_match, + .list_family = xfont_list_family, + .open_font = xfont_open, + .close_font = xfont_close, + .prepare_face = xfont_prepare_face, + .has_char = xfont_has_char, + .encode_char = xfont_encode_char, + .text_extents = xfont_text_extents, + .draw = xfont_draw, + .check = xfont_check, }; void @@ -1101,6 +1151,16 @@ syms_of_xfont (void) staticpro (&xfont_scripts_cache); xfont_scripts_cache = CALLN (Fmake_hash_table, QCtest, Qequal); staticpro (&xfont_scratch_props); - xfont_scratch_props = Fmake_vector (make_number (8), Qnil); + xfont_scratch_props = make_nil_vector (8); + pdumper_do_now_and_after_load (syms_of_xfont_for_pdumper); + + DEFSYM (Qkana, "kana"); + DEFSYM (Qhan, "han"); + DEFSYM (Qhangul, "hangul"); +} + +static void +syms_of_xfont_for_pdumper (void) +{ register_font_driver (&xfont_driver, NULL); } |