# HG changeset patch # User Kenichi Handa # Date 1027656385 0 # Node ID d32a3736c4fe8523b0808282aa5656e0e36b3985 # Parent 8975795eb087d5bb93907453d6c2ef560524a6c6 (Qprepend, Qappend): New variables. (FONTSET_CHARSET_ALIST, FONTSET_FACE_ALIST): These macros deleted. (FONTSET_NOFONT_FACE, FONTSET_REPERTORY): New macros. (FONTSET_REF): Optimize if FONTSET is Vdefault_fontset. (FONTSET_REF_AND_RANGE, FONTSET_ADD): New macros. (fontset_ref_and_range, fontset_add, reorder_font_vector) (load_font_get_repertory): New functions. (fontset_set): This function deleted. (fontset_face): New arg FACE. Return face ID, not face. Completely re-written to handle new fontset structure. Caller changed. (free_face_fontset): Use ASET istead of AREF (X) = Y. (face_for_char): Don't call lookup_face. (make_fontset_for_ascii_face): New arg FACE. (fs_load_font): New arg CHARSET_ID. Don't check Vfont_encoding_alist here. (find_font_encoding): New function. (list_fontsets): Use STRINGP, not ! NILP. (accumulate_script_ranges): New function. (Fset_fontset_font, Fnew_fontset, Ffontset_info): Completely re-written to handle new fontset structure. (Ffontset_font): Return a copy of element. (syms_of_fontset): Define symbols Qprepend and Qappend. Fix docstring of font-encoding-alist. diff -r 8975795eb087 -r d32a3736c4fe src/fontset.c --- a/src/fontset.c Fri Jul 26 04:06:05 2002 +0000 +++ b/src/fontset.c Fri Jul 26 04:06:25 2002 +0000 @@ -54,61 +54,105 @@ /* FONTSET A fontset is a collection of font related information to give - similar appearance (style, etc) of characters. There are two kinds - of fontsets; base and realized. A base fontset is created by - `new-fontset' from Emacs Lisp explicitly. A realized fontset is - created implicitly when a face is realized for ASCII characters. A - face is also realized for non-ASCII characters based on an ASCII - face. All of non-ASCII faces based on the same ASCII face share - the same realized fontset. + similar appearance (style, etc) of characters. A fontset has two + roles. One is to use for the frame parameter `font' as if it is an + ASCII font. In that case, Emacs uses the font specified for + `ascii' script for the frame's default font. + + Another role, the more important one, is to provide information + about which font to use for each non-ASCII character. + + There are two kinds of fontsets; base and realized. A base fontset + is created by `new-fontset' from Emacs Lisp explicitly. A realized + fontset is created implicitly when a face is realized for ASCII + characters. A face is also realized for non-ASCII characters based + on an ASCII face. All of non-ASCII faces based on the same ASCII + face share the same realized fontset. A fontset object is implemented by a char-table whose default value and parent are always nil. - An element of a base fontset is a font specification of the form: - [ FAMILY WEIGHT SLANT SWIDTH REGISTRY ] (vector of size 5) + An element of a base fontset is a vector of FONT-DEFs which itself + is a vector [ FONT-SPEC ENCODING REPERTORY ]. + + FONT-SPEC is: + [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ] or - FONT-NAME (strig) + FONT-NAME + where FAMILY, WEIGHT, SLANT, SWIDTH, ADSTYLE, REGISTRY, and + FONT-NAME are strings. - FAMILY and REGISTRY are strings. + ENCODING is a charset ID or a char-table that can convert + characters to glyph codes of the corresponding font. - WEIGHT, SLANT, and SWIDTH must be symbols that set-face-attribute - accepts as attribute values for :weight, :slant, :swidth - respectively. + REPERTORY is a charset ID or nil. If REPERTORY is a charset ID, + the repertory of the charset exactly matches with that of the font. + If REPERTORY is nil, we consult with the font itself to get the + repertory. + + ENCODING and REPERTORY are extracted from the variable + Vfont_encoding_alist by using a font name generated form FONT-SPEC + (if it is a vector) or FONT-NAME as a key. - A fontset has 7 extra slots. + An element of a realized fontset is nil or t, or has this form: + + ( CHARSET-PRIORITY-LIST-TICK . FONT-VECTOR ) - The 1st slot is an ID number of the fontset. + FONT-VECTOR is a vector whose elements have this form: + + [ FACE-ID FONT-INDEX FONT-DEF ] + + FONT-VECTOR is automatically reordered by the current charset + priority list. - The 2nd slot is a name of the fontset in a base fontset, and nil in - a realized fontset. + The value nil means that we have not yet generated FONT-VECTOR from + the base of the fontset. - The 3rd slot is nil in a base fontset, and a base fontset in a - realized fontset. + The value t means that no font is available for the corresponding + range of characters. + + + A fontset has 5 extra slots. + + The 1st slot: the ID number of the fontset - The 4th slot is a frame that the fontset belongs to. This is nil - in a base fontset. + The 2nd slot: + base: the name of the fontset + realized: nil - The 5th slot is a cons of 0 and fontname for ASCII characters in a - base fontset, and nil in a realized face. + The 3rd slot: + base: nli + realized: the base fontset + + The 4th slot: + base: nil + realized: the frame that the fontset belongs to - The 6th slot is an alist of a charset vs. the corresponding font - specification. + The 5th slot: + base: the font name for ASCII characters + realized: nil - The 7th slot is an alist of a font specification vs. the - corresponding face ID. In a base fontset, the face IDs are all - nil. + The 6th slot: + base: nil + realized: the ID number of a face to use for characters that + has no font in a realized fontset. - All fontsets are recorded in Vfontset_table. + The 7th slot: + base: nil + realized: Alist of font index vs the corresponding repertory + char-table. + + + All fontsets are recorded in the vector Vfontset_table. DEFAULT FONTSET - There's a special fontset named `default fontset' which defines the - default font specifications. When a base fontset doesn't specify a - font for a specific character, the corresponding value in the - default fontset is used. The format is the same as a base fontset. + There's a special base fontset named `default fontset' which + defines the default font specifications. When a base fontset + doesn't specify a font for a specific character, the corresponding + value in the default fontset is used. The parent of a realized fontset created for such a face that has no fontset is the default fontset. @@ -118,7 +162,7 @@ The other codes handle fontsets only by their ID numbers. They usually use the variable name `fontset' for IDs. But, in this file, we always use varialbe name `id' for IDs, and name `fontset' - for the actual fontset objects (i.e. char-table objects). + for an actual fontset object, i.e., char-table. */ @@ -126,6 +170,7 @@ extern Lisp_Object Qfont; Lisp_Object Qfontset; +static Lisp_Object Qprepend, Qappend; /* Vector containing all fontsets. */ static Lisp_Object Vfontset_table; @@ -176,6 +221,9 @@ This function set the member `encoder' of the structure. */ void (*find_ccl_program_func) P_ ((struct font_info *)); +Lisp_Object (*get_font_repertory_func) P_ ((struct frame *, + struct font_info *)); + /* Check if any window system is used now. */ void (*check_window_system_func) P_ ((void)); @@ -184,6 +232,9 @@ static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); static int fontset_id_valid_p P_ ((int)); static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object)); +static void accumulate_script_ranges P_ ((Lisp_Object, Lisp_Object, + Lisp_Object)); + /********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/ @@ -203,13 +254,19 @@ /* Macros to access special values of (realized) FONTSET. */ #define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->extras[2] #define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[3] -#define FONTSET_CHARSET_ALIST(fontset) XCHAR_TABLE (fontset)->extras[5] -#define FONTSET_FACE_ALIST(fontset) XCHAR_TABLE (fontset)->extras[6] +#define FONTSET_NOFONT_FACE(fontset) XCHAR_TABLE (fontset)->extras[5] +#define FONTSET_REPERTORY(fontset) XCHAR_TABLE (fontset)->extras[6] -/* Return the element of FONTSET (char-table) at index C (character). */ +/* Return the element of FONTSET for the character C. If FONTSET is a + base fontset other then the default fontset and FONTSET doesn't + contain information for C, return the information in the default + fontset. */ -#define FONTSET_REF(fontset, c, etl) ((elt) = fontset_ref ((fontset), (c))) +#define FONTSET_REF(fontset, c) \ + (EQ (fontset, Vdefault_fontset) \ + ? CHAR_TABLE_REF (fontset, c) \ + : fontset_ref ((fontset), (c))) static Lisp_Object fontset_ref (fontset, c) @@ -218,105 +275,336 @@ { Lisp_Object elt; - while (1) - { - elt = CHAR_TABLE_REF (fontset, c); - if (NILP (elt) && ASCII_CHAR_P (c)) - elt = FONTSET_ASCII (fontset); - if (NILP (elt)) - { - Lisp_Object tail; - struct charset *charset; + elt = CHAR_TABLE_REF (fontset, c); + if (NILP (elt) && ! EQ (fontset, Vdefault_fontset) + /* Don't check Vdefault_fontset for a realized fontset. */ + && NILP (FONTSET_BASE (fontset))) + elt = CHAR_TABLE_REF (Vdefault_fontset, c); + return elt; +} + + +/* Return the element of FONTSET for the character C, set FROM and TO + to the range of characters around C that have the same value as C. + If FONTSET is a base fontset other then the default fontset and + FONTSET doesn't contain information for C, return the information + in the default fontset. */ + +#define FONTSET_REF_AND_RANGE(fontset, c, form, to) \ + (EQ (fontset, Vdefault_fontset) \ + ? char_table_ref_and_range (fontset, c, &from, &to) \ + : fontset_ref_and_range (fontset, c, &from, &to)) - for (tail = FONTSET_CHARSET_ALIST (fontset); - CONSP (tail); tail = XCDR (tail)) - { - charset = CHARSET_FROM_ID (XINT (XCAR (XCAR (tail)))); - if (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset)) - { - elt = XCDR (XCAR (tail)); - break; - } - } - } - if (! NILP (elt) || EQ (fontset, Vdefault_fontset)) - break; - fontset = Vdefault_fontset; +static Lisp_Object +fontset_ref_and_range (fontset, c, from, to) + Lisp_Object fontset; + int c; + int *from, *to; +{ + Lisp_Object elt; + + elt = char_table_ref_and_range (fontset, c, from, to); + if (NILP (elt) && ! EQ (fontset, Vdefault_fontset) + /* Don't check Vdefault_fontset for a realized fontset. */ + && NILP (FONTSET_BASE (fontset))) + { + int from1, to1; + + elt = char_table_ref_and_range (Vdefault_fontset, c, &from1, &to1); + if (*from < from1) + *from = from1; + if (*to > to1) + *to = to1; } return elt; } -/* Set the element of FONTSET at index IDX to the value ELT. IDX may - be a character or a charset. */ +/* Set elements of FONTSET for characters in RANGE to the value ELT. + RANGE is a cons (FROM . TO), where FROM and TO are character codes + specifying a range. */ + +#define FONTSET_SET(fontset, range, elt) \ + Fset_char_table_range ((fontset), (range), (elt)) + + +/* Modify the elements of FONTSET for characters in RANGE by replacing + with ELT or adding ETL. RANGE is a cons (FROM . TO), where FROM + and TO are character codes specifying a range. If ADD is nil, + replace with ELT, if ADD is `prepend', prepend ELT, otherwise, + append ELT. */ + +#define FONTSET_ADD(fontset, range, elt, add) \ + (NILP (add) \ + ? Fset_char_table_range ((fontset), (range), \ + Fmake_vector (make_number (1), (elt))) \ + : fontset_add ((fontset), (range), (elt), (add))) -#define FONTSET_SET(fontset, c, newelt) fontset_set(fontset, c, newelt) +static void +fontset_add (fontset, range, elt, add) +{ + int from, to, from1, to1; + Lisp_Object elt1; + + from = XINT (XCAR (range)); + to = XINT (XCDR (range)); + do { + elt1 = char_table_ref_and_range (fontset, from, &from1, &to1); + if (NILP (elt1)) + elt1 = Fmake_vector (make_number (1), elt); + else + { + int i, i0 = 1, i1 = ASIZE (elt1) + 1; + Lisp_Object new; + + new = Fmake_vector (i1, elt); + if (EQ (add, Qappend)) + i0--, i1--; + for (i = 0; i0 < i1; i++, i0++) + ASET (new, i0, AREF (elt1, i)); + elt1 = new; + } + char_table_set_range (fontset, from, to1, elt1); + from = to1 + 1; + } while (from < to); +} + + +/* Update FONTSET_ELEMENT which has this form: + ( CHARSET-PRIORITY-LIST-TICK . FONT-VECTOR). + Reorder FONT-VECTOR according to the current order of charset + (Vcharset_ordered_list), and update CHARSET-PRIORITY-LIST-TICK to + the latest value. */ static void -fontset_set (fontset, idx, elt) - Lisp_Object fontset, idx, elt; +reorder_font_vector (fontset_element) + Lisp_Object fontset_element; { - if (SYMBOLP (idx)) + Lisp_Object vec, list, *new_vec; + int size; + int *charset_id_table; + int i, idx; + + XSETCAR (fontset_element, make_number (charset_ordered_list_tick)); + vec = XCDR (fontset_element); + size = ASIZE (vec); + if (size < 2) + /* No need of reordering VEC. */ + return; + charset_id_table = (int *) alloca (sizeof (int) * size); + new_vec = (Lisp_Object *) alloca (sizeof (Lisp_Object) * size); + /* At first, extract ENCODING (a chaset ID) from VEC. VEC has this + form: + [[FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ]] ...] */ + for (i = 0; i < size; i++) + charset_id_table[i] = XINT (AREF (AREF (AREF (vec, i), 2), 1)); + + /* Then, store the elements of VEC in NEW_VEC in the correct + order. */ + idx = 0; + for (list = Vcharset_ordered_list; CONSP (list); list = XCDR (list)) { - Lisp_Object id, slot, tail; - - id = CHARSET_SYMBOL_ID (idx); - if (XFASTINT (id) == charset_ascii) - Fset_char_table_range (fontset, - Fcons (make_number (0), make_number (127)), - elt); - else - { - slot = Fassq (id, FONTSET_CHARSET_ALIST (fontset)); - if (CONSP (slot)) - XCDR (slot) = elt; - else if (CONSP (FONTSET_CHARSET_ALIST (fontset))) - { - for (tail = FONTSET_CHARSET_ALIST (fontset); - CONSP (XCDR (tail)); tail = XCDR (tail)); - XCDR (tail) = Fcons (Fcons (id, elt), Qnil); - } - else - FONTSET_CHARSET_ALIST (fontset) = Fcons (Fcons (id, elt), Qnil); - } + for (i = 0; i < size; i++) + if (charset_id_table[i] == XINT (XCAR (list))) + new_vec[idx++] = AREF (vec, i); + if (idx == size) + break; } - else - { - int from = XINT (XCAR (idx)); - int to = XINT (XCDR (idx)); + + /* At last, update VEC. */ + for (i = 0; i < size; i++) + ASET (vec, i, new_vec[i]); +} + + +/* Load a font matching the font related attributes in FACE->lface and + font pattern in FONT_DEF of FONTSET, and return an index of the + font. FONT_DEF has this form: + [ FONT-SPEC ENCODING REPERTORY ] + If REPERTORY is nil, generate a char-table representing the font + repertory by looking into the font itself. */ - if (from == to) - CHAR_TABLE_SET (fontset, from, elt); - else - Fset_char_table_range (fontset, idx, elt); +static int +load_font_get_repertory (f, face, font_def, fontset) + FRAME_PTR f; + struct face *face; + Lisp_Object font_def; + Lisp_Object fontset; +{ + char *font_name; + struct font_info *font_info; + + font_name = choose_face_font (f, face->lface, AREF (font_def, 0)); + if (! (font_info = fs_load_font (f, font_name, XINT (AREF (font_def, 1))))) + return -1; + + if (NILP (AREF (font_def, 2)) + && NILP (Fassq (make_number (font_info->font_idx), + FONTSET_REPERTORY (fontset)))) + { + /* We must look into the font to get the correct repertory as a + char-table. */ + Lisp_Object repertory; + + repertory = (*get_font_repertory_func) (f, font_info); + FONTSET_REPERTORY (fontset) + = Fcons (Fcons (make_number (font_info->font_idx), repertory), + FONTSET_REPERTORY (fontset)); } + + return font_info->font_idx; } -/* Return a face registerd in the realized fontset FONTSET for the - character C. Return -1 if a face ID is not yet set. */ +/* Return a face ID registerd in the realized fontset FONTSET for the + character C. If FACE is NULL, return -1 if a face is not yet + set. Otherwise, realize a proper face from FACE and return it. */ -static struct face * -fontset_face (fontset, c) +static int +fontset_face (fontset, c, face) Lisp_Object fontset; int c; + struct face *face; { - Lisp_Object base, elt; - int id; - struct face *face; + Lisp_Object elt, vec; + int i, from, to; + int font_idx; + FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset)); - base = FONTSET_BASE (fontset); - FONTSET_REF (base, c, elt); + elt = CHAR_TABLE_REF (fontset, c); + if (EQ (elt, Qt)) + goto font_not_found; if (NILP (elt)) - return NULL; + { + /* We have not yet decided a face for C. */ + Lisp_Object base_fontset, range; + + if (! face) + return -1; + base_fontset = FONTSET_BASE (fontset); + elt = FONTSET_REF_AND_RANGE (base_fontset, c, from, to); + range = Fcons (make_number (from), make_number (to)); + if (NILP (elt)) + { + /* Record that we have no font for characters of this + range. */ + FONTSET_SET (fontset, range, Qt); + goto font_not_found; + } + elt = Fcopy_sequence (elt); + /* Now ELT is a vector of FONT-DEFs. We at first change it to + FONT-VECTOR, a vector of [ nil nil FONT-DEF ]. */ + for (i = 0; i < ASIZE (elt); i++) + { + Lisp_Object tmp; + + tmp = Fmake_vector (make_number (3), Qnil); + ASET (tmp, 2, AREF (elt, i)); + ASET (elt, i, tmp); + } + /* Then store (-1 . FONT-VECTOR) in the fontset. -1 is to force + reordering of FONT-VECTOR. */ + elt = Fcons (make_number (-1), elt); + FONTSET_SET (fontset, range, elt); + } + + if (XINT (XCAR (elt)) != charset_ordered_list_tick) + /* The priority of charsets is changed after we selected a face + for C last time. */ + reorder_font_vector (elt); + + vec = XCDR (elt); + /* Find the first available font in the font vector VEC. */ + for (i = 0; i < ASIZE (vec); i++) + { + Lisp_Object font_def; + + elt = AREF (vec, i); + /* ELT == [ FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ] ] */ + font_def = AREF (elt, 2); + if (INTEGERP (AREF (elt, 1)) && XINT (AREF (elt, 1)) < 0) + /* We couldn't open this font last time. */ + continue; + + if (!face && (NILP (AREF (elt, 1)) || NILP (AREF (elt, 0)))) + /* We have not yet opened the font, or we have not yet made a + realized face for the font. */ + return -1; + + if (INTEGERP (AREF (font_def, 2))) + { + /* The repertory is specified by charset ID. */ + struct charset *charset + = CHARSET_FROM_ID (XINT (AREF (font_def, 2))); - elt = Fassoc (elt, FONTSET_FACE_ALIST (fontset)); - if (! CONSP (elt)) - return NULL; - id = XINT (XCDR (elt)); - face = FACE_FROM_ID (XFRAME (FONTSET_FRAME (fontset)), id); - return face; + if (! CHAR_CHARSET_P (c, charset)) + /* This fond can't display C. */ + continue; + } + else + { + Lisp_Object slot; + + if (! INTEGERP (AREF (elt, 1))) + { + /* We have not yet opened a font matching this spec. + Open the best matching font now and register the + repertory. */ + font_idx = load_font_get_repertory (f, face, font_def, fontset); + ASET (elt, 1, make_number (font_idx)); + if (font_idx < 0) + /* This means that we couldn't find a font matching + FONT_DEF. */ + continue; + } + + slot = Fassq (AREF (elt, 1), FONTSET_REPERTORY (fontset)); + if (! CONSP (slot)) + abort (); + if (NILP (CHAR_TABLE_REF (XCDR (slot), c))) + /* This fond can't display C. */ + continue; + } + + /* Now we have decided to use this font spec to display C. */ + if (INTEGERP (AREF (elt, 1))) + font_idx = XINT (AREF (elt, 1)); + else + { + /* But not yet opened the best matching font. */ + font_idx = load_font_get_repertory (f, face, font_def, fontset); + ASET (elt, 1, make_number (font_idx)); + if (font_idx < 0) + continue; + } + + /* Now we have the opened font. */ + if (NILP (AREF (elt, 0))) + { + /* But not yet made a realized face that uses this font. */ + int face_id = lookup_non_ascii_face (f, font_idx, face); + + ASET (elt, 0, make_number (face_id)); + } + + /* Ok, this face can display C. */ + return XINT (AREF (elt, 0)); + } + + font_not_found: + /* We have tried all the fonts for C, but none of them can be opened + nor can display C. */ + if (NILP (FONTSET_NOFONT_FACE (fontset))) + { + int face_id; + + if (! face) + return -1; + face_id = lookup_non_ascii_face (f, -1, face); + FONTSET_NOFONT_FACE (fontset) = make_number (face_id); + } + return XINT (FONTSET_NOFONT_FACE (fontset)); } @@ -341,6 +629,7 @@ if (id + 1 == size) { + /* We must grow Vfontset_table. */ Lisp_Object tem; int i; @@ -371,9 +660,9 @@ -/********** INTERFACES TO xfaces.c and dispextern.h **********/ +/********** INTERFACES TO xfaces.c, xfns.c, and dispextern.h **********/ -/* Return name of the fontset with ID. */ +/* Return the name of the fontset who has ID. */ Lisp_Object fontset_name (id) @@ -386,16 +675,19 @@ } -/* Return ASCII font name of the fontset with ID. */ +/* Return the ASCII font name of the fontset who has ID. */ Lisp_Object fontset_ascii (id) int id; { - Lisp_Object fontset; + Lisp_Object fontset, elt; fontset= FONTSET_FROM_ID (id); - return FONTSET_ASCII (fontset); + elt = FONTSET_ASCII (fontset); + /* It is assured that ELT is always a string (i.e. fontname + pattern). */ + return elt; } @@ -407,7 +699,7 @@ FRAME_PTR f; struct face *face; { - AREF (Vfontset_table, face->fontset) = Qnil; + ASET (Vfontset_table, face->fontset, Qnil); if (face->fontset < next_fontset_id) next_fontset_id = face->fontset; } @@ -425,14 +717,13 @@ Lisp_Object fontset; fontset = FONTSET_FROM_ID (face->fontset); - return (face == fontset_face (fontset, c)); + return (face->id == fontset_face (fontset, c, NULL)); } /* Return ID of face suitable for displaying character C on frame F. - The selection of face is done based on the fontset of FACE. FACE - must be reazlied for ASCII characters in advance. Called from the - macro FACE_FOR_CHAR when C is not an ASCII character. */ + FACE must be reazlied for ASCII characters in advance. Called from + the macro FACE_FOR_CHAR. */ int face_for_char (f, face, c) @@ -441,19 +732,17 @@ int c; { Lisp_Object fontset; - struct face *new_face; + Lisp_Object elt, vec; + int font_idx; + int i; + + if (ASCII_CHAR_P (c)) + return face->ascii_face->id; xassert (fontset_id_valid_p (face->fontset)); fontset = FONTSET_FROM_ID (face->fontset); xassert (!BASE_FONTSET_P (fontset)); - - new_face = fontset_face (fontset, c); - if (new_face) - return new_face->id; - - /* No face is recorded for C in the fontset of FACE. Make a new - realized face for C that has the same fontset. */ - return lookup_face (f, face->lface, c, face); + return fontset_face (fontset, c, face); } @@ -463,9 +752,10 @@ Called from realize_x_face. */ int -make_fontset_for_ascii_face (f, base_fontset_id) +make_fontset_for_ascii_face (f, base_fontset_id, face) FRAME_PTR f; int base_fontset_id; + struct face *face; { Lisp_Object base_fontset, fontset, frame; @@ -476,53 +766,25 @@ if (!BASE_FONTSET_P (base_fontset)) base_fontset = FONTSET_BASE (base_fontset); xassert (BASE_FONTSET_P (base_fontset)); + if (! BASE_FONTSET_P (base_fontset)) + abort (); } else base_fontset = Vdefault_fontset; fontset = make_fontset (frame, Qnil, base_fontset); - return XINT (FONTSET_ID (fontset)); -} - - -/* Return FONT-SPEC recorded in the fontset of FACE for character C. - If FACE is null, or the fontset doesn't contain information about - C, get the font name pattern from the default fontset. Called from - choose_face_font. */ - -Lisp_Object -fontset_font_pattern (f, face, c) - FRAME_PTR f; - struct face *face; - int c; -{ - Lisp_Object fontset, base, elt; - int id = face ? face->fontset : -1; + { + Lisp_Object elt; - if (id >= 0) - { - fontset = FONTSET_FROM_ID (id); - xassert (!BASE_FONTSET_P (fontset)); - base = FONTSET_BASE (fontset); - } - else - { - base = Vdefault_fontset; - } - - FONTSET_REF (base, c, elt); - if (face && ! NILP (elt)) - { - Lisp_Object slot; - - slot = Fassoc (elt, FONTSET_FACE_ALIST (fontset)); - if (CONSP (slot)) - XSETCDR (slot, make_number (face->id)); - FONTSET_FACE_ALIST (fontset) - = Fcons (Fcons (elt, make_number (face->id)), - FONTSET_FACE_ALIST (fontset)); - } - return elt; + elt = FONTSET_REF (base_fontset, 0); + elt = Fmake_vector (make_number (3), AREF (elt, 0)); + ASET (elt, 0, make_number (face->id)); + ASET (elt, 1, make_number (face->font_info_id)); + elt = Fcons (make_number (charset_ordered_list_tick), + Fmake_vector (make_number (1), elt)); + char_table_set_range (fontset, 0, 127, elt); + } + return XINT (FONTSET_ID (fontset)); } @@ -532,49 +794,41 @@ /* Load a font named FONTNAME on frame F. Return a pointer to the struct font_info of the loaded font. If loading fails, return - NULL. */ + NULL. CHARSET_ID is an ID of charset to encode characters for this + font. */ struct font_info * -fs_load_font (f, fontname) +fs_load_font (f, fontname, charset_id) FRAME_PTR f; char *fontname; + int charset_id; { - Lisp_Object tail, elt; struct font_info *fontp; if (!fontname) /* No way to get fontname. */ - return 0; + return NULL; fontp = (*load_font_func) (f, fontname, 0); if (!fontp) return NULL; fontname = fontp->full_name; - /* Fill in members (charset, vertical_centering, encoding, etc) of - font_info structure that are not set by (*load_font_func). */ - for (tail = Vfont_encoding_alist; CONSP (tail); tail = XCDR (tail)) - { - elt = XCAR (tail); - if (STRINGP (XCAR (elt)) && CHARSETP (XCDR (elt)) - && fast_c_string_match_ignore_case (XCAR (elt), fontname) >= 0) - { - fontp->charset = XFASTINT (CHARSET_SYMBOL_ID (XCDR (elt))); - break; - } - } - if (! CONSP (tail)) - return NULL; - fontp->vertical_centering - = (STRINGP (Vvertical_centering_font_regexp) - && (fast_c_string_match_ignore_case - (Vvertical_centering_font_regexp, fontname) >= 0)); - + fontp->charset = charset_id; + fontp->vertical_centering = 0; fontp->font_encoder = NULL; - if (find_ccl_program_func) - (*find_ccl_program_func) (fontp); + if (charset_id != charset_ascii) + { + fontp->vertical_centering + = (STRINGP (Vvertical_centering_font_regexp) + && (fast_c_string_match_ignore_case + (Vvertical_centering_font_regexp, fontname) >= 0)); + + if (find_ccl_program_func) + (*find_ccl_program_func) (fontp); + } return fontp; } @@ -584,6 +838,34 @@ #endif +/* Return ENCODING or a cons(ENCODING REPERTORY) of the font FONTNAME. + ENCODING is a charset symbol that specifies the encoding of the + font. REPERTORY is a charset symbol or nil. */ + + +static Lisp_Object +find_font_encoding (fontname) + char *fontname; +{ + Lisp_Object tail, elt; + + for (tail = Vfont_encoding_alist; CONSP (tail); tail = XCDR (tail)) + { + elt = XCAR (tail); + if (CONSP (elt) + && STRINGP (XCAR (elt)) + && fast_c_string_match_ignore_case (XCAR (elt), fontname) >= 0 + && (SYMBOLP (XCDR (elt)) + ? CHARSETP (XCDR (elt)) + : CONSP (XCDR (elt)) && CHARSETP (XCAR (XCDR (elt))))) + return (XCDR (elt)); + } + /* We don't know the encoding of this font. Let's assume Unicode + encoding. */ + return Qunicode; +} + + /* Cache data used by fontset_pattern_regexp. The car part is a pattern string containing at least one wild card, the cdr part is the corresponding regular expression. */ @@ -738,7 +1020,7 @@ continue; name = XSTRING (FONTSET_NAME (fontset))->data; - if (!NILP (regexp) + if (STRINGP (regexp) ? (fast_c_string_match_ignore_case (regexp, name) < 0) : strcmp (XSTRING (pattern)->data, name)) continue; @@ -811,84 +1093,183 @@ return FONTSET_FROM_ID (id); } -DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0, - doc: /* Modify fontset NAME to use FONT-SPEC for characters of CHARSETS. +static void +accumulate_script_ranges (arg, range, val) + Lisp_Object arg, range, val; +{ + if (EQ (XCAR (arg), val)) + { + if (CONSP (range)) + XSETCDR (arg, Fcons (Fcons (XCAR (range), XCDR (range)), XCDR (arg))); + else + XSETCDR (arg, Fcons (Fcons (range, range), XCDR (arg))); + } +} -CHARSET may be a cons; (FROM . TO), where FROM and TO are characters. -In that case, use FONT-SPEC for all characters in the range FROM and -TO (inclusive). + +DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 5, 0, + doc: /* +Modify fontset NAME to use FONT-SPEC for CHARACTER. + +CHARACTER may be a cons; (FROM . TO), where FROM and TO are +characters. In that case, use FONT-SPEC for all characters in the +range FROM and TO (inclusive). -FONT-SPEC is be a vector; [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ] +CHARACTER may be a script name symbol. In that case, use FONT-SPEC +for all characters that belong to the script. + +CHARACTER may be a charset who has :code-offset attribute and the +attribute value is greater than the maximum Unicode character +\(#x10FFFF). In that case, use FONT-SPEC for all characters in the +charset. + +FONT-SPEC is a vector; [ FAMILY WEIGHT SLANT ADSTYLE REGISTRY ]. +See the documentation of `set-face-attribute' for the detail of +these vector elements. -FONT-SPEC may be a cons; (FAMILY . REGISTRY), where FAMILY is a family -name of a font, REGSITRY is a registry name of a font. +FONT-SPEC may be a cons; (FAMILY . REGISTRY). + +FONT-SPEC may be a font name string. + +Optional 4th argument FRAME, if non-nil, is a frame. This argument is +kept for backward compatibility and has no meaning. -FONT-SPEC may be a font name string. */) - (name, charset, font_spec, frame) - Lisp_Object name, charset, font_spec, frame; +Optional 5th argument ADD, if non-nil, specifies how to add FONT-SPEC +to the font specifications for RANGE previously set. If it is +`prepend', FONT-SPEC is prepended. If it is `append', FONT-SPEC is +appended. By default, FONT-SPEC overrides the previous settings. */) + (name, character, font_spec, frame, add) + Lisp_Object name, character, font_spec, frame, add; { Lisp_Object fontset; - Lisp_Object family, registry; + int i; + Lisp_Object font_def, registry; + Lisp_Object val, encoding, repertory; + Lisp_Object range_list; fontset = check_fontset_name (name); - if (VECTORP (font_spec)) - { - int i; - Lisp_Object val; - - font_spec = Fcopy_sequence (font_spec); - for (i = 0; i < 5; i++) - { - val = Faref (font_spec, make_number (i)); - if (! NILP (val)) - { - CHECK_STRING (val); - ASET (font_spec, i, Fdowncase (val)); - } - } - val = Faref (font_spec, make_number (5)); - CHECK_STRING (val); - ASET (font_spec, 5, Fdowncase (val)); - } - else if (STRINGP (font_spec)) - font_spec = Fdowncase (font_spec); - else if (CONSP (font_spec)) - { - CHECK_CONS (font_spec); - family = XCAR (font_spec); - registry = XCDR (font_spec); - font_spec = Fmake_vector (make_number (6), Qnil); - if (!NILP (family)) - { - CHECK_STRING (family); - ASET (font_spec, 0, Fdowncase (family)); - } - CHECK_STRING (registry); - ASET (font_spec, 5, Fdowncase (registry)); - } - - if (SYMBOLP (charset)) - { - CHECK_CHARSET (charset); - } - else - { - Lisp_Object from, to; - - /* CHARSET should be (FROM . TO). */ - from = Fcar (charset); - to = Fcdr (charset); - CHECK_CHARACTER (from); - CHECK_CHARACTER (to); - } - /* The arg FRAME is kept for backward compatibility. We only check the validity. */ if (!NILP (frame)) CHECK_LIVE_FRAME (frame); - FONTSET_SET (fontset, charset, font_spec); + if (VECTORP (font_spec)) + { + int j; + + if (ASIZE (font_spec) != 6) + args_out_of_range (make_number (6), + make_number (ASIZE (font_spec))); + + font_spec = Fcopy_sequence (font_spec); + for (j = 0; j < 5; j++) + if (! NILP (AREF (font_spec, j))) + { + CHECK_STRING (AREF (font_spec, j)); + ASET (font_spec, j, Fdowncase (AREF (font_spec, j))); + } + /* REGISTRY should not be omitted. */ + CHECK_STRING (AREF (font_spec, 5)); + registry = Fdowncase (AREF (font_spec, 5)); + ASET (font_spec, 5, registry); + + } + else if (CONSP (font_spec)) + { + Lisp_Object family; + + family = XCAR (font_spec); + registry = XCDR (font_spec); + + if (! NILP (family)) + { + CHECK_STRING (family); + family = Fdowncase (family); + } + CHECK_STRING (registry); + registry = Fdowncase (registry); + font_spec = Fmake_vector (make_number (6), Qnil); + ASET (font_spec, 0, family); + ASET (font_spec, 5, registry); + } + else + { + CHECK_STRING (font_spec); + font_spec = Fdowncase (font_spec); + registry = font_name_registry (font_spec); + if (NILP (registry)) + error ("No XLFD: %s", XSTRING (font_spec)->data); + } + + if (STRINGP (font_spec)) + encoding = find_font_encoding ((char *) XSTRING (font_spec)->data); + else + encoding = find_font_encoding ((char *) XSTRING (registry)->data); + if (SYMBOLP (encoding)) + encoding = repertory = CHARSET_SYMBOL_ID (encoding); + else + { + repertory = XCDR (encoding); + encoding = CHARSET_SYMBOL_ID (XCAR (encoding)); + } + font_def = Fmake_vector (make_number (3), font_spec); + ASET (font_def, 1, encoding); + ASET (font_def, 2, repertory); + + if (CHARACTERP (character)) + range_list = Fcons (Fcons (character, character), Qnil); + else if (CONSP (character)) + { + Lisp_Object from, to; + + from = Fcar (character); + to = Fcdr (character); + CHECK_CHARACTER (from); + CHECK_CHARACTER (to); + range_list = Fcons (character, Qnil); + } + else + { + Lisp_Object script_list; + Lisp_Object val; + + CHECK_SYMBOL (character); + range_list = Qnil; + script_list = XCHAR_TABLE (Vchar_script_table)->extras[0]; + if (! NILP (Fmemq (character, script_list))) + { + val = Fcons (character, Qnil); + map_char_table (accumulate_script_ranges, Qnil, Vchar_script_table, + val, 0, NULL); + range_list = XCDR (val); + if (EQ (character, Qascii)) + { + if (! STRINGP (font_spec)) + font_spec = generate_ascii_font_name (FONTSET_NAME (fontset), + font_spec); + FONTSET_ASCII (fontset) = font_spec; + } + } + else if (CHARSETP (character)) + { + struct charset *charset; + + CHECK_CHARSET_GET_CHARSET (character, charset); + if (CHARSET_METHOD (charset) == CHARSET_METHOD_OFFSET) + range_list + = Fcons (Fcons (make_number (CHARSET_MIN_CHAR (charset)), + make_number (CHARSET_MAX_CHAR (charset))), + range_list); + } + + if (NILP (range_list)) + error ("Invalid script or charset name: %s", + XSYMBOL (character)->name->data); + } + + for (; CONSP (range_list); range_list = XCDR (range_list)) + FONTSET_ADD (fontset, XCAR (range_list), font_def, add); /* Free all realized fontsets whose base is FONTSET. This way, the specified character(s) are surely redisplayed by a correct @@ -902,51 +1283,50 @@ DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0, doc: /* Create a new fontset NAME from font information in FONTLIST. -FONTLIST is an alist of charsets vs corresponding font specifications. -Each element of FONTLIST has the form (CHARSET . FONT-SPEC), where -a character of CHARSET is displayed by a font that matches FONT-SPEC. +FONTLIST is an alist of scripts vs the corresponding font specification list. +Each element of FONTLIST has the form (SCRIPT FONT-SPEC ...), where +a character of SCRIPT is displayed by a font that matches FONT-SPEC. -FONT-SPEC is a vector [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ], where -FAMILY is a string specifying the font family, -WEIGHT is a string specifying the weight of the font, -SLANT is a string specifying the slant of the font, -WIDTH is a string specifying the width of the font, -ADSTYLE is a string specifying the adstyle of the font, -REGISTRY is a string specifying the charset-registry of the font. +SCRIPT is a symbol that appears in the variable `script-alist'. -See also the documentation of `set-face-attribute' for the detail of -these vector elements. - -FONT-SPEC may be a font name (string). */) +FONT-SPEC is a vector, a cons, or a string. See the documentation of +`set-fontset-font' for the meaning. */) (name, fontlist) Lisp_Object name, fontlist; { - Lisp_Object fontset, ascii_font; - Lisp_Object tem, tail; + Lisp_Object fontset; + Lisp_Object val; + int id; CHECK_STRING (name); CHECK_LIST (fontlist); - name = Fdowncase (name); - tem = Fquery_fontset (name, Qnil); - if (! NILP (tem)) - free_realized_fontsets (tem); - - fontset = make_fontset (Qnil, name, Qnil); + /* Check if an ASCII font is specified in FONTLIST. */ + val = Fcar (Fcdr (Fassq (Qascii, fontlist))); + if (NILP (val)) + error ("No ascii font specified"); - /* Check the validity of FONTLIST. */ - ascii_font = Fcdr (Fassq (Qascii, fontlist)); - if (NILP (ascii_font)) - error ("No ascii font specified"); - if (! STRINGP (ascii_font)) - ascii_font = generate_ascii_font (name, ascii_font); + id = fs_query_fontset (name, 0); + if (id < 0) + fontset = make_fontset (Qnil, Fdowncase (name), Qnil); + else + { + fontset = FONTSET_FROM_ID (id);; + free_realized_fontsets (fontset); + Fset_char_table_range (fontset, Qt, Qnil); + } - fontlist = Fcopy_sequence (fontlist); - for (tail = fontlist; ! NILP (tail); tail = Fcdr (tail)) - Fset_fontset_font (name, Fcar (Fcar (tail)), Fcdr (Fcar (tail)), Qnil); + for (; ! NILP (fontlist); fontlist = Fcdr (fontlist)) + { + Lisp_Object elt, script; - FONTSET_ASCII (fontset) = ascii_font; - + elt = Fcar (fontlist); + script = Fcar (elt); + elt = Fcdr (elt); + Fset_fontset_font (name, script, Fcar (elt), Qnil, Qnil); + for (elt = Fcdr (elt); ! NILP (elt); elt = Fcdr (elt)) + Fset_fontset_font (name, script, XCAR (elt), Qnil, Qappend); + } return name; } @@ -1051,170 +1431,108 @@ } -#if 0 /* unused */ -/* 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.. */ +DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0, + doc: /* Return information about a fontset FONTSET on frame FRAME. +The value is a char-table of which elements has this form. -static void -accumulate_font_info (arg, character, elt) - Lisp_Object arg, character, elt; -{ - Lisp_Object last, last_char, last_elt; + ((FONT-PATTERN OPENED-FONT ...) ...) - if (!CONSP (elt) && !SINGLE_BYTE_CHAR_P (XINT (character))) - FONTSET_REF (Vdefault_fontset, XINT (character), elt); - 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))) - { - struct charset *this_charset = CHAR_CHARSET (XINT (character)); +FONT-PATTERN is a vector: - if (CONSP (last_char)) /* LAST_CHAR == (FROM . TO) */ - { - if (this_charset == CHAR_CHARSET (XINT (XCAR (last_char)))) - { - XSETCDR (last_char, character); - return; - } - } - else if (XINT (last_char) == XINT (character)) - return; - else if (this_charset == CHAR_CHARSET (XINT (last_char))) - { - XSETCAR (XCAR (last), Fcons (last_char, character)); - return; - } - } - XSETCDR (last, Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil)); - XSETCAR (arg, XCDR (last)); -} -#endif /* 0 */ + [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ] + +or a string of font name pattern. -DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0, - doc: /* Return information about a fontset named NAME on frame FRAME. -The value is a vector: - [ SIZE HEIGHT ((CHARSET-OR-RANGE FONT-SPEC OPENED ...) ...) ], -where, - SIZE is the maximum bound width of ASCII font in the fontset, - HEIGHT is the maximum bound height of ASCII font in the fontset, - CHARSET-OR-RANGE is a charset or a cons of two characters specifying - the range of characters. - FONT-SPEC is a fontname pattern string or a vector - [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ]. - See the documentation of `new-fontset' for the meanings those elements. - OPENEDs are names of fonts actually opened. -If the ASCII font is not yet opened, SIZE and HEIGHT are 0. -If FRAME is omitted, it defaults to the currently selected frame. */) - (name, frame) - Lisp_Object name, frame; +OPENED-FONT is a name of a font actually opened. */) + (fontset, frame) + Lisp_Object fontset, frame; { - Lisp_Object fontset; FRAME_PTR f; - Lisp_Object val, tail, elt; + Lisp_Object table, val, elt; Lisp_Object *realized; struct font_info *fontp = NULL; int n_realized = 0; - int i; + int c, i, j; (*check_window_system_func) (); - fontset = check_fontset_name (name); + fontset = check_fontset_name (fontset); if (NILP (frame)) frame = selected_frame; CHECK_LIVE_FRAME (frame); f = XFRAME (frame); - /* Recode realized fontsets whose base is FONTSET in the table - `realized'. */ + /* Recode fontsets realized on FRAME from the base fontset FONTSET + in the table `realized'. */ realized = (Lisp_Object *) alloca (sizeof (Lisp_Object) * ASIZE (Vfontset_table)); for (i = 0; i < ASIZE (Vfontset_table); i++) { elt = FONTSET_FROM_ID (i); if (!NILP (elt) - && EQ (FONTSET_BASE (elt), fontset)) + && EQ (FONTSET_BASE (elt), fontset) + && EQ (FONTSET_FRAME (elt), frame)) realized[n_realized++] = elt; } - /* 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 (Qascii, Fcons (FONTSET_ASCII (fontset), Qnil)), Qnil); - val = Fcons (val, val); - for (i = 128; i <= MAX_CHAR; ) + + table = Fmake_char_table (Qnil, Qnil); + /* Accumulate information of the fontset in TABLE. The format of + each element is ((FONT-SPEC OPENED-FONT ...) ...). */ + for (c = 0; c <= MAX_CHAR; ) { - Lisp_Object elt; int from, to; - elt = char_table_ref_and_range (fontset, i, &from, &to); - if (! NILP (elt)) + val = FONTSET_REF_AND_RANGE (fontset, c, from, to); + if (VECTORP (val)) { - elt = Fcons (Fcons (make_number (from), make_number (to)), - Fcons (elt, Qnil)); - XSETCDR (XCAR (val), Fcons (elt, Qnil)); - XSETCAR (val, XCDR (XCAR (val))); - } - i = to + 1; - } + Lisp_Object alist; + + /* At first, set ALIST to ((FONT-SPEC) ...). */ + for (alist = Qnil, i = 0; i < ASIZE (val); i++) + alist = Fcons (Fcons (AREF (AREF (val, i), 0), Qnil), alist); + alist = Fnreverse (alist); - for (tail = FONTSET_CHARSET_ALIST (fontset); - CONSP (tail); tail = XCDR (tail)) - { - elt = XCAR (tail); - elt = Fcons ((INTEGERP (XCAR (elt)) - ? CHARSET_NAME (CHARSET_FROM_ID (XFASTINT (XCAR (elt)))) - : XCAR (elt)), - Fcons (XCDR (elt), Qnil)); - XSETCDR (XCAR (val), Fcons (elt, Qnil)); - XSETCAR (val, XCDR (XCAR (val))); + /* Then store opend font names to cdr of each elements. */ + for (i = 0; i < n_realized; i++) + { + val = FONTSET_REF (realized[i], c); + if (NILP (val)) + continue; + val = XCDR (val); + /* Now VAL is [[FACE-ID FONT-INDEX FONT-DEF] ...]. + If a font of an element is already opened, + FONT-INDEX of the element is integer. */ + for (j = 0; j < ASIZE (val); j++) + if (INTEGERP (AREF (AREF (val, j), 0))) + { + Lisp_Object font_idx; + + font_idx = AREF (AREF (val, j), 1); + elt = Fassq (AREF (AREF (AREF (val, j), 2), 0), alist); + if (CONSP (elt) + && NILP (Fmemq (font_idx, XCDR(elt)))) + nconc2 (elt, Fcons (font_idx, Qnil)); + } + } + for (val = alist; CONSP (val); val = XCDR (val)) + for (elt = XCDR (XCAR (val)); CONSP (elt); elt = XCDR (elt)) + { + struct font_info *font_info + = (*get_font_info_func) (f, XINT (XCAR (elt))); + XSETCAR (elt, build_string (font_info->full_name)); + } + + /* Store ALIST in TABLE for characters C..TO. */ + char_table_set_range (table, c, to, alist); + } + c = to + 1; } - val = XCDR (val); - - /* If fonts are opened for FONT-SPEC, append the names of the fonts to - FONT-SPEC. */ - for (tail = val; CONSP (tail); tail = XCDR (tail)) - { - elt = XCAR (tail); - for (i = 0; i < n_realized; i++) - { - Lisp_Object face_list, fontname; - - for (face_list = FONTSET_FACE_ALIST (realized[i]); - CONSP (face_list); face_list = XCDR (face_list)) - { - int face_id = XINT (XCDR (XCAR (face_list))); - struct face *face = FACE_FROM_ID (f, face_id); + return table; +} - if (face->font && face->font_name) - { - fontname = build_string (face->font_name); - if (NILP (Fmember (fontname, XCDR (XCDR (elt))))) - XSETCDR (XCDR (elt), Fcons (fontname, XCDR (XCDR (elt)))); - } - } - } - } - - elt = XCDR (XCDR (XCAR (val))); - if (CONSP (elt)) - fontp = (*query_font_func) (f, XSTRING (XCAR (elt))->data); - val = Fmake_vector (make_number (3), val); - AREF (val, 0) = fontp ? make_number (fontp->size) : make_number (0); - AREF (val, 1) = fontp ? make_number (fontp->height) : make_number (0); - return val; -} DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0, doc: /* Return a font name pattern for character CH in fontset NAME. @@ -1229,8 +1547,8 @@ CHECK_CHARACTER (ch); c = XINT (ch); - FONTSET_REF (fontset, c, elt); - return elt; + elt = FONTSET_REF (fontset, c); + return Fcopy_sequence (elt); } DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0, @@ -1259,10 +1577,12 @@ /* Window system initializer should have set proper functions. */ abort (); - Qfontset = intern ("fontset"); - staticpro (&Qfontset); + DEFSYM (Qfontset, "fontset"); Fput (Qfontset, Qchar_table_extra_slots, make_number (7)); + DEFSYM (Qprepend, "prepend"); + DEFSYM (Qappend, "append"); + Vcached_fontset_data = Qnil; staticpro (&Vcached_fontset_data); @@ -1293,13 +1613,27 @@ next_fontset_id = 1; DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist, - doc: /* Alist of fontname patterns vs corresponding encoding info. -Each element looks like (REGEXP . CHARSET), where CHARSET is an -Emacs charset symbol. */); + doc: /* +Alist of fontname patterns vs the corresponding encoding and repertory info. +Each element looks like (REGEXP . (ENCODING . REPERTORY)), +where ENCODING is a charset or a char-table, +and REPERTORY is a charset, a char-table, or nil. + +ENCODING is for converting a character to a glyph code of the font. +If ENCODING is a charset, encoding a character by the charset gives +the corresponding glyph code. If ENCODING is a char-table, looking up +the table by a character gives the corresponding glyph code. + +REPERTORY specifies a repertory of characters supported by the font. +If REPERTORY is a charset, all characters beloging to the charset are +supported. If REPERTORY is a char-table, all characters who have a +non-nil value in the table are supported. It REPERTORY is nil, Emacs +gets the repertory information by an opened font and ENCODING. */); Vfont_encoding_alist = Qnil; DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent, - doc: /* Char table of characters whose ascent values should be ignored. + doc: /* +Char table of characters whose ascent values should be ignored. If an entry for a character is non-nil, the ascent value of the glyph is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font. @@ -1308,7 +1642,8 @@ Vuse_default_ascent = Qnil; DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition, - doc: /* Char table of characters which is not composed relatively. + doc: /* +Char table of characters which is not composed relatively. If an entry for a character is non-nil, a composition sequence which contains that character is displayed so that the glyph of that character is put without considering