/* 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.
+
+ ENCODING is a charset ID or a char-table that can convert
+ characters to glyph codes of the corresponding font.
+
+ 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.
+
+
+ An element of a realized fontset is nil or t, or has this form:
+
+ ( CHARSET-PRIORITY-LIST-TICK . FONT-VECTOR )
+
+ FONT-VECTOR is a vector whose elements have this form:
+
+ [ FACE-ID FONT-INDEX FONT-DEF ]
- FAMILY and REGISTRY are strings.
+ FONT-VECTOR is automatically reordered by the current charset
+ priority list.
- WEIGHT, SLANT, and SWIDTH must be symbols that set-face-attribute
- accepts as attribute values for :weight, :slant, :swidth
- respectively.
+ The value nil means that we have not yet generated FONT-VECTOR from
+ the base of the fontset.
+ The value t means that no font is available for the corresponding
+ range of characters.
- A fontset has 7 extra slots.
- The 1st slot is an ID number of the fontset.
+ A fontset has 5 extra slots.
- The 2nd slot is a name of the fontset in a base fontset, and nil in
- a realized fontset.
+ The 1st slot: the ID number of the fontset
- The 3rd slot is nil in a base fontset, and a base fontset in a
- realized fontset.
+ The 2nd slot:
+ base: the name of the fontset
+ realized: nil
- The 4th slot is a frame that the fontset belongs to. This is nil
- in a base fontset.
+ The 3rd slot:
+ base: nli
+ realized: the base fontset
- The 5th slot is a cons of 0 and fontname for ASCII characters in a
- base fontset, and nil in a realized face.
+ 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.
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.
*/
extern Lisp_Object Qfont;
Lisp_Object Qfontset;
+static Lisp_Object Qprepend, Qappend;
/* Vector containing all fontsets. */
static Lisp_Object Vfontset_table;
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));
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));
+
\f
/********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/
/* 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)
{
Lisp_Object elt;
- while (1)
+ 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))
+
+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)))
{
- 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;
+ int from1, to1;
- 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;
+ 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))
+
-#define FONTSET_SET(fontset, c, newelt) fontset_set(fontset, c, newelt)
+/* 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)))
static void
-fontset_set (fontset, idx, elt)
- Lisp_Object fontset, idx, elt;
+fontset_add (fontset, range, elt, add)
{
- if (SYMBOLP (idx))
+ 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
+reorder_font_vector (fontset_element)
+ Lisp_Object fontset_element;
+{
+ 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));
- if (from == to)
- CHAR_TABLE_SET (fontset, from, elt);
- else
- Fset_char_table_range (fontset, idx, elt);
+ /* 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. */
+
+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;
- 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;
+ 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)));
+
+ 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));
}
if (id + 1 == size)
{
+ /* We must grow Vfontset_table. */
Lisp_Object tem;
int i;
\f
-/********** 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)
}
-/* 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;
}
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;
}
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)
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);
}
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;
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);
+ {
+ Lisp_Object 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));
}
-/* 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;
-
- 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;
-}
-
-
#if defined(WINDOWSNT) && defined (_MSC_VER)
#pragma optimize("", off)
#endif
/* 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;
}
#endif
\f
+/* 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. */
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;
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)));
+ }
+}
+
+
+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).
-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).
+CHARACTER may be a script name symbol. In that case, use FONT-SPEC
+for all characters that belong to the script.
-FONT-SPEC is be a vector; [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ]
+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. */)
- (name, charset, font_spec, frame)
- Lisp_Object name, charset, font_spec, frame;
+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.
+
+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);
+ /* The arg FRAME is kept for backward compatibility. We only check
+ the validity. */
+ if (!NILP (frame))
+ CHECK_LIVE_FRAME (frame);
+
if (VECTORP (font_spec))
{
- int i;
- Lisp_Object val;
+ 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 (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));
+ 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 (STRINGP (font_spec))
- font_spec = Fdowncase (font_spec);
else if (CONSP (font_spec))
{
- CHECK_CONS (font_spec);
+ Lisp_Object family;
+
family = XCAR (font_spec);
registry = XCDR (font_spec);
- font_spec = Fmake_vector (make_number (6), Qnil);
- if (!NILP (family))
+
+ if (! NILP (family))
{
CHECK_STRING (family);
- ASET (font_spec, 0, Fdowncase (family));
+ family = Fdowncase (family);
}
CHECK_STRING (registry);
- ASET (font_spec, 5, Fdowncase (registry));
+ registry = Fdowncase (registry);
+ font_spec = Fmake_vector (make_number (6), Qnil);
+ ASET (font_spec, 0, family);
+ ASET (font_spec, 5, registry);
}
-
- if (SYMBOLP (charset))
+ else
{
- CHECK_CHARSET (charset);
+ 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;
- /* CHARSET should be (FROM . TO). */
- from = Fcar (charset);
- to = Fcdr (charset);
+ 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;
- /* The arg FRAME is kept for backward compatibility. We only check
- the validity. */
- if (!NILP (frame))
- CHECK_LIVE_FRAME (frame);
+ 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);
+ }
- FONTSET_SET (fontset, charset, font_spec);
+ 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
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.
-
-See also the documentation of `set-face-attribute' for the detail of
-these vector elements.
+SCRIPT is a symbol that appears in the variable `script-alist'.
-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 the validity of FONTLIST. */
- ascii_font = Fcdr (Fassq (Qascii, fontlist));
- if (NILP (ascii_font))
+ /* Check if an ASCII font is specified in FONTLIST. */
+ val = Fcar (Fcdr (Fassq (Qascii, fontlist)));
+ if (NILP (val))
error ("No ascii font specified");
- if (! STRINGP (ascii_font))
- ascii_font = generate_ascii_font (name, ascii_font);
- fontlist = Fcopy_sequence (fontlist);
- for (tail = fontlist; ! NILP (tail); tail = Fcdr (tail))
- Fset_fontset_font (name, Fcar (Fcar (tail)), Fcdr (Fcar (tail)), Qnil);
-
- FONTSET_ASCII (fontset) = 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);
+ }
+ for (; ! NILP (fontlist); fontlist = Fcdr (fontlist))
+ {
+ Lisp_Object elt, script;
+
+ 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;
}
}
-#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 ]
-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;
+or a string of font name pattern.
+
+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;
- }
-
- 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)));
- }
+ Lisp_Object alist;
- 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;
+ /* 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 (face_list = FONTSET_FACE_ALIST (realized[i]);
- CONSP (face_list); face_list = XCDR (face_list))
+ /* Then store opend font names to cdr of each elements. */
+ for (i = 0; i < n_realized; i++)
{
- int face_id = XINT (XCDR (XCAR (face_list)));
- struct face *face = FACE_FROM_ID (f, face_id);
-
- 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))));
- }
+ 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;
}
- 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;
+ return table;
}
+
DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0,
doc: /* Return a font name pattern for character CH in fontset NAME.
If NAME is t, find a font name pattern in the default fontset. */)
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,
/* 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);
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.
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