Mercurial > emacs
changeset 28963:24af4ff8f7b6
Include "buffer.h".
(fs_load_font): If the face has fontset, record the face ID in
that fontset.
(Finternal_char_font): New function.
(accumulate_font_info): New function.
(Ffontset_info): Rewritten for the new fontset implementation.
(syms_of_fontset): Register Vdefault_fontset in the first element
of Vfontset_table. Include Vdefault_fontset in
Vfontset_alias_alist. Declare `internal-char-font' as a Lisp
function.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Wed, 17 May 2000 23:30:30 +0000 |
parents | 3f62d70df67c |
children | 7ba5753774e5 |
files | src/fontset.c |
diffstat | 1 files changed, 182 insertions(+), 74 deletions(-) [+] |
line wrap: on
line diff
--- a/src/fontset.c Wed May 17 23:30:06 2000 +0000 +++ b/src/fontset.c Wed May 17 23:30:30 2000 +0000 @@ -28,6 +28,7 @@ #endif #include "lisp.h" +#include "buffer.h" #include "charset.h" #include "ccl.h" #include "frame.h" @@ -75,8 +76,8 @@ element in a fontset. The element is stored in `defalt' slot of the fontset. And this slot is never used as a default value of multibyte characters. That means that the first 256 elements of a - fontset set is always nil (as this is not efficient, we may - implement a fontset in a different way in the future). + fontset are always nil (as this is not efficient, we may implement + a fontset in a different way in the future). To access or set each element, use macros FONTSET_REF and FONTSET_SET respectively for efficiency. @@ -251,7 +252,6 @@ { int charset, c1, c2; Lisp_Object elt; - int i; if (SINGLE_BYTE_CHAR_P (*c)) return FONTSET_ASCII (fontset); @@ -689,6 +689,12 @@ if (find_ccl_program_func) (*find_ccl_program_func) (fontp); + /* If we loaded a font for a face that has fontset, record the face + ID in the fontset for C. */ + if (face + && !NILP (fontset) + && !BASE_FONTSET_P (fontset)) + FONTSET_SET (fontset, c, make_number (face->id)); return fontp; } @@ -1123,23 +1129,128 @@ return info; } + +/* Return the font name for the character at POSITION in the current + buffer. This is computed from all the text properties and overlays + that apply to POSITION. It returns nil in the following cases: + + (1) The window system doesn't have a font for the character (thus + it is displayed by an empty box). + + (2) The character code is invalid. + + (3) The current buffer is not displayed in any window. + + In addition, the returned font name may not take into account of + such redisplay engine hooks as what used in jit-lock-mode if + POSITION is currently not visible. */ + + +DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 1, 0, + "For internal use only.") + (position) + Lisp_Object position; +{ + int pos, pos_byte, dummy; + int face_id; + int c; + Lisp_Object window; + struct window *w; + struct frame *f; + struct face *face; + + CHECK_NUMBER_COERCE_MARKER (position, 0); + pos = XINT (position); + if (pos < BEGV || pos >= ZV) + args_out_of_range_3 (position, make_number (BEGV), make_number (ZV)); + pos_byte = CHAR_TO_BYTE (pos); + c = FETCH_CHAR (pos_byte); + if (! CHAR_VALID_P (c, 0)) + return Qnil; + window = Fget_buffer_window (Fcurrent_buffer (), Qt); + if (NILP (window)) + return Qnil; + w = XWINDOW (window); + f = XFRAME (w->frame); + face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0); + face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c); + face = FACE_FROM_ID (f, face_id); + return (face->font && face->font_name + ? build_string (face->font_name) + : Qnil); +} + + +/* Called from Ffontset_info via map_char_table on each leaf of + fontset. ARG is a list (LAST FONT-INFO ...), where LAST is `(last + ARG)' and FONT-INFOs have this form: + (CHAR FONT-SPEC) or ((FROM . TO) FONT-SPEC) + The current leaf is indexed by CHARACTER and has value ELT. This + function add the information of the current leaf to ARG by + appending a new element or modifying the last element.. */ + +static void +accumulate_font_info (arg, character, elt) + Lisp_Object arg, character, elt; +{ + Lisp_Object last, last_char, last_elt, tmp; + + if (!CONSP (elt)) + return; + last = XCAR (arg); + last_char = XCAR (XCAR (last)); + last_elt = XCAR (XCDR (XCAR (last))); + elt = XCDR (elt); + if (!NILP (Fequal (elt, last_elt))) + { + int this_charset = CHAR_CHARSET (XINT (character)); + + if (CONSP (last_char)) /* LAST_CHAR == (FROM . TO) */ + { + if (this_charset == CHAR_CHARSET (XINT (XCAR (last_char)))) + { + XCDR (last_char) = character; + return; + } + } + else + { + if (this_charset == CHAR_CHARSET (XINT (last_char))) + { + XCAR (XCAR (last)) = Fcons (last_char, character); + return; + } + } + } + XCDR (last) = Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil); + XCAR (arg) = XCDR (last); +} + + DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0, "Return information about a fontset named NAME on frame FRAME.\n\ -If FRAME is omitted or nil, use the selected frame.\n\ -The returned value is a vector of SIZE, HEIGHT, and FONT-LIST,\n\ -where\n\ - SIZE is the maximum bound width of ASCII font of the fontset,\n\ - HEIGHT is the height of the ASCII font in the fontset, and\n\ - FONT-LIST is an alist of the format:\n\ - (CHARSET REQUESTED-FONT-NAME LOADED-FONT-NAME).\n\ -LOADED-FONT-NAME t means the font is not yet loaded, nil means the\n\ -loading failed.") +The value is a list:\n\ + \(FONTSET-NAME (CHARSET-OR-RANGE FONT-SPEC OPENED ...) ...),\n\ +where,\n\ + FONTSET-NAME is a full name of the fontset.\n\ + CHARSET-OR-RANGE is a charset, a character (may be a generic character)\n\ + or a cons of two characters specifying the range of characters.\n\ + FONT-SPEC is a fontname pattern string or a cons (FAMILY . REGISTRY),\n\ + where FAMILY is a `FAMILY' field of a XLFD font name,\n\ + REGISTRY is a `CHARSET_REGISTRY' field of a XLDF font name.\n\ + FAMILY may contain a `FOUNDARY' field at the head.\n\ + REGISTRY may contain a `CHARSET_ENCODING' field at the tail.\n\ + OPENEDs are names of fonts actually opened.\n\ +If FRAME is omitted, it defaults to the currently selected frame.") (name, frame) Lisp_Object name, frame; { + Lisp_Object fontset; FRAME_PTR f; - Lisp_Object fontset, realized; - Lisp_Object info, val, loaded, requested; + Lisp_Object indices[3]; + Lisp_Object val, tail, elt; + Lisp_Object *realized; + int n_realized = 0; int i; (*check_window_system_func) (); @@ -1151,77 +1262,66 @@ CHECK_LIVE_FRAME (frame, 1); f = XFRAME (frame); - info = Fmake_vector (make_number (3), Qnil); - + /* Recodeq realized fontsets whose base is FONTSET in the table + `realized'. */ + realized = (Lisp_Object *) alloca (sizeof (Lisp_Object) + * ASIZE (Vfontset_table)); for (i = 0; i < ASIZE (Vfontset_table); i++) { - realized = FONTSET_FROM_ID (i); - if (!NILP (realized) - && EQ (FONTSET_FRAME (realized), frame) - && EQ (FONTSET_BASE (realized), fontset) - && INTEGERP (FONTSET_ASCII (realized))) - break; + elt = FONTSET_FROM_ID (i); + if (!NILP (elt) + && EQ (FONTSET_BASE (elt), fontset)) + realized[n_realized++] = elt; } - if (NILP (realized)) - return Qnil; - - XVECTOR (info)->contents[0] = Qnil; - XVECTOR (info)->contents[1] = Qnil; - loaded = Qnil; + /* Accumulate information of the fontset in VAL. The format is + (LAST FONT-INFO FONT-INFO ...), where FONT-INFO is (CHAR-OR-RANGE + FONT-SPEC). See the comment for accumulate_font_info for the + detail. */ + val = Fcons (Fcons (make_number (0), + Fcons (XCDR (FONTSET_ASCII (fontset)), Qnil)), + Qnil); + val = Fcons (val, val); + map_char_table (accumulate_font_info, Qnil, fontset, val, 0, indices); + val = XCDR (val); - val = Fcons (Fcons (CHARSET_SYMBOL (CHARSET_ASCII), - Fcons (FONTSET_ASCII (fontset), - Fcons (loaded, Qnil))), - Qnil); - for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++) + /* For each FONT-INFO, if CHAR_OR_RANGE (car part) is a generic + character for a charset, replace it wiht the charset symbol. If + fonts are opened for FONT-SPEC, append the names of the fonts to + FONT-SPEC. */ + for (tail = val; CONSP (tail); tail = XCDR (tail)) { - Lisp_Object elt; - elt = XCHAR_TABLE (fontset)->contents[i + 128]; - - if (VECTORP (elt)) + int c; + elt = XCAR (tail); + if (INTEGERP (XCAR (elt))) { - int face_id; + int charset, c1, c2; + c = XINT (XCAR (elt)); + SPLIT_CHAR (c, charset, c1, c2); + if (c1 == 0) + XCAR (elt) = CHARSET_SYMBOL (charset); + } + else + c = XINT (XCAR (XCAR (elt))); + for (i = 0; i < n_realized; i++) + { + Lisp_Object face_id, font; struct face *face; - if (INTEGERP (AREF (elt, 2)) - && (face_id = XINT (AREF (elt, 2)), - face = FACE_FROM_ID (f, face_id))) - { - struct font_info *fontp; - fontp = (*get_font_info_func) (f, face->font_info_id); - requested = build_string (fontp->name); - loaded = (fontp->full_name - ? build_string (fontp->full_name) - : Qnil); - } - else + face_id = FONTSET_REF_VIA_BASE (realized[i], c); + if (INTEGERP (face_id)) { - char *str; - int family_len = 0, registry_len = 0; - - if (STRINGP (AREF (elt, 0))) - family_len = STRING_BYTES (XSTRING (AREF (elt, 0))); - if (STRINGP (AREF (elt, 1))) - registry_len = STRING_BYTES (XSTRING (AREF (elt, 1))); - str = (char *) alloca (1 + family_len + 3 + registry_len + 1); - str[0] = '-'; - str[1] = 0; - if (family_len) - strcat (str, XSTRING (AREF (elt, 0))->data); - strcat (str, "-*-"); - if (registry_len) - strcat (str, XSTRING (AREF (elt, 1))->data); - requested = build_string (str); - loaded = Qnil; + face = FACE_FROM_ID (f, XINT (face_id)); + if (face->font && face->font_name) + { + font = build_string (face->font_name); + if (NILP (Fmember (font, XCDR (XCDR (elt))))) + XCDR (XCDR (elt)) = Fcons (font, XCDR (XCDR (elt))); + } } - val = Fcons (Fcons (CHARSET_SYMBOL (i), - Fcons (requested, Fcons (loaded, Qnil))), - val); } } - XVECTOR (info)->contents[2] = val; - return info; + return Fcons (FONTSET_NAME (fontset), val); } DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0, @@ -1263,6 +1363,7 @@ && BASE_FONTSET_P (fontset)) list = Fcons (FONTSET_NAME (fontset), list); } + return list; } @@ -1284,12 +1385,16 @@ Vfontset_table = Fmake_vector (make_number (32), Qnil); staticpro (&Vfontset_table); - next_fontset_id = 0; Vdefault_fontset = Fmake_char_table (Qfontset, Qnil); staticpro (&Vdefault_fontset); + FONTSET_ID (Vdefault_fontset) = make_number (0); + FONTSET_NAME (Vdefault_fontset) + = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default"); FONTSET_ASCII (Vdefault_fontset) = Fcons (make_number (0), Fcons (Qnil, build_string ("iso8859-1"))); + AREF (Vfontset_table, 0) = Vdefault_fontset; + next_fontset_id = 1; DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist, "Alist of fontname patterns vs corresponding encoding info.\n\ @@ -1327,7 +1432,9 @@ DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist, "Alist of fontset names vs the aliases."); - Vfontset_alias_alist = Qnil; + Vfontset_alias_alist = Fcons (Fcons (FONTSET_NAME (Vdefault_fontset), + build_string ("fontset-default")), + Qnil); DEFVAR_LISP ("highlight-wrong-size-font", &Vhighlight_wrong_size_font, "*Non-nil means highlight characters shown in wrong size fonts somehow.\n\ @@ -1358,6 +1465,7 @@ defsubr (&Snew_fontset); defsubr (&Sset_fontset_font); defsubr (&Sfont_info); + defsubr (&Sinternal_char_font); defsubr (&Sfontset_info); defsubr (&Sfontset_font); defsubr (&Sfontset_list);