mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-15 11:21:19 -07:00
Give 8 extra slots to fontset objects.
(Qfontset_info): New variable. (syms_of_fontset): Defsym it. (FONTSET_FALLBACK): New macro. (fontset_face): Try also the default fontset. (make_fontset): Realize a fallback fontset from the default fontset. (generate_ascii_font_name): Moved from xfaces.c. Rewritten by using split_font_name_into_vector and build_font_name_from_vector. (Fset_fontset_font): Access the elements of font_spec by enum FONT_SPEC_INDEX. If font_spec is a string, extract the registry name by using split_font_name_into_vector. (Fnew_fontset): If no ASCII font is specified in FONTLIST, generate a proper font name from the fontset name. Update Vfontset_alias_alist. (n_auto_fontsets): New variable. (new_fontset_from_font_name): New function. (Ffont_info): Store the information about fonts generated from the default fontset in the first extra slot of the returned char-table.
This commit is contained in:
parent
154c2d3959
commit
d6aaac9ead
1 changed files with 195 additions and 80 deletions
275
src/fontset.c
275
src/fontset.c
|
|
@ -113,7 +113,7 @@ EXFUN (Fclear_face_cache, 1);
|
|||
range of characters.
|
||||
|
||||
|
||||
A fontset has 5 extra slots.
|
||||
A fontset has 8 extra slots.
|
||||
|
||||
The 1st slot: the ID number of the fontset
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ EXFUN (Fclear_face_cache, 1);
|
|||
realized: nil
|
||||
|
||||
The 3rd slot:
|
||||
base: nli
|
||||
base: nil
|
||||
realized: the base fontset
|
||||
|
||||
The 4th slot:
|
||||
|
|
@ -143,6 +143,10 @@ EXFUN (Fclear_face_cache, 1);
|
|||
realized: Alist of font index vs the corresponding repertory
|
||||
char-table.
|
||||
|
||||
The 8th slot:
|
||||
base: nil
|
||||
realized: If the base is not the default fontset, a fontset
|
||||
realized from the default fontset, else nil.
|
||||
|
||||
All fontsets are recorded in the vector Vfontset_table.
|
||||
|
||||
|
|
@ -169,7 +173,8 @@ EXFUN (Fclear_face_cache, 1);
|
|||
/********** VARIABLES and FUNCTION PROTOTYPES **********/
|
||||
|
||||
extern Lisp_Object Qfont;
|
||||
Lisp_Object Qfontset;
|
||||
static Lisp_Object Qfontset;
|
||||
static Lisp_Object Qfontset_info;
|
||||
static Lisp_Object Qprepend, Qappend;
|
||||
|
||||
/* Vector containing all fontsets. */
|
||||
|
|
@ -271,6 +276,7 @@ fontset_id_valid_p (id)
|
|||
#define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[3]
|
||||
#define FONTSET_NOFONT_FACE(fontset) XCHAR_TABLE (fontset)->extras[5]
|
||||
#define FONTSET_REPERTORY(fontset) XCHAR_TABLE (fontset)->extras[6]
|
||||
#define FONTSET_FALLBACK(fontset) XCHAR_TABLE (fontset)->extras[7]
|
||||
|
||||
|
||||
/* Return the element of FONTSET for the character C. If FONTSET is a
|
||||
|
|
@ -483,23 +489,24 @@ fontset_face (fontset, c, face)
|
|||
int c;
|
||||
struct face *face;
|
||||
{
|
||||
Lisp_Object elt, vec;
|
||||
Lisp_Object base_fontset, elt, vec;
|
||||
int i, from, to;
|
||||
int font_idx;
|
||||
FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset));
|
||||
|
||||
base_fontset = FONTSET_BASE (fontset);
|
||||
elt = CHAR_TABLE_REF (fontset, c);
|
||||
|
||||
if (EQ (elt, Qt))
|
||||
goto font_not_found;
|
||||
goto try_default;
|
||||
|
||||
if (NILP (elt))
|
||||
{
|
||||
/* We have not yet decided a face for C. */
|
||||
Lisp_Object base_fontset, range;
|
||||
Lisp_Object 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))
|
||||
|
|
@ -507,7 +514,7 @@ fontset_face (fontset, c, face)
|
|||
/* Record that we have no font for characters of this
|
||||
range. */
|
||||
FONTSET_SET (fontset, range, Qt);
|
||||
goto font_not_found;
|
||||
goto try_default;
|
||||
}
|
||||
elt = Fcopy_sequence (elt);
|
||||
/* Now ELT is a vector of FONT-DEFs. We at first change it to
|
||||
|
|
@ -556,7 +563,7 @@ fontset_face (fontset, c, face)
|
|||
= CHARSET_FROM_ID (XINT (AREF (font_def, 2)));
|
||||
|
||||
if (! CHAR_CHARSET_P (c, charset))
|
||||
/* This fond can't display C. */
|
||||
/* This font can't display C. */
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
|
@ -609,6 +616,10 @@ fontset_face (fontset, c, face)
|
|||
return XINT (AREF (elt, 0));
|
||||
}
|
||||
|
||||
try_default:
|
||||
if (! EQ (base_fontset, Vdefault_fontset))
|
||||
return fontset_face (FONTSET_FALLBACK (fontset), c, face);
|
||||
|
||||
font_not_found:
|
||||
/* We have tried all the fonts for C, but none of them can be opened
|
||||
nor can display C. */
|
||||
|
|
@ -672,6 +683,8 @@ make_fontset (frame, name, base)
|
|||
|
||||
ASET (Vfontset_table, id, fontset);
|
||||
next_fontset_id = id + 1;
|
||||
if (! NILP (base) && ! EQ (base, Vdefault_fontset))
|
||||
FONTSET_FALLBACK (fontset) = make_fontset (frame, Qnil, Vdefault_fontset);
|
||||
return fontset;
|
||||
}
|
||||
|
||||
|
|
@ -1130,6 +1143,28 @@ accumulate_script_ranges (arg, range, val)
|
|||
}
|
||||
|
||||
|
||||
/* Return an ASCII font name generated from fontset name NAME and
|
||||
ASCII font specification ASCII_SPEC. NAME is a string conforming
|
||||
to XLFD. ASCII_SPEC is a vector:
|
||||
[FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY]. */
|
||||
|
||||
static INLINE Lisp_Object
|
||||
generate_ascii_font_name (name, ascii_spec)
|
||||
Lisp_Object name, ascii_spec;
|
||||
{
|
||||
Lisp_Object vec;
|
||||
int i;
|
||||
|
||||
vec = split_font_name_into_vector (name);
|
||||
for (i = FONT_SPEC_FAMILY_INDEX; i <= FONT_SPEC_ADSTYLE_INDEX; i++)
|
||||
if (! NILP (AREF (ascii_spec, i)))
|
||||
ASET (vec, 1 + i, AREF (ascii_spec, i));
|
||||
if (! NILP (AREF (ascii_spec, FONT_SPEC_REGISTRY_INDEX)))
|
||||
ASET (vec, 12, AREF (ascii_spec, FONT_SPEC_REGISTRY_INDEX));
|
||||
return build_font_name_from_vector (vec);
|
||||
}
|
||||
|
||||
|
||||
DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 5, 0,
|
||||
doc: /*
|
||||
Modify fontset NAME to use FONT-SPEC for CHARACTER.
|
||||
|
|
@ -1180,21 +1215,21 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
|
|||
{
|
||||
int j;
|
||||
|
||||
if (ASIZE (font_spec) != 6)
|
||||
args_out_of_range (make_number (6),
|
||||
if (ASIZE (font_spec) != FONT_SPEC_MAX_INDEX)
|
||||
args_out_of_range (make_number (FONT_SPEC_MAX_INDEX),
|
||||
make_number (ASIZE (font_spec)));
|
||||
|
||||
font_spec = Fcopy_sequence (font_spec);
|
||||
for (j = 0; j < 5; j++)
|
||||
for (j = 0; j < FONT_SPEC_MAX_INDEX - 1; 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);
|
||||
CHECK_STRING (AREF (font_spec, FONT_SPEC_REGISTRY_INDEX));
|
||||
registry = Fdowncase (AREF (font_spec, FONT_SPEC_REGISTRY_INDEX));
|
||||
ASET (font_spec, FONT_SPEC_REGISTRY_INDEX, registry);
|
||||
|
||||
}
|
||||
else if (CONSP (font_spec))
|
||||
|
|
@ -1211,17 +1246,22 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
|
|||
}
|
||||
CHECK_STRING (registry);
|
||||
registry = Fdowncase (registry);
|
||||
font_spec = Fmake_vector (make_number (6), Qnil);
|
||||
ASET (font_spec, 0, family);
|
||||
ASET (font_spec, 5, registry);
|
||||
font_spec = Fmake_vector (make_number (FONT_SPEC_MAX_INDEX), Qnil);
|
||||
ASET (font_spec, FONT_SPEC_FAMILY_INDEX, family);
|
||||
ASET (font_spec, FONT_SPEC_REGISTRY_INDEX, registry);
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_STRING (font_spec);
|
||||
font_spec = Fdowncase (font_spec);
|
||||
registry = font_name_registry (font_spec);
|
||||
registry = split_font_name_into_vector (font_spec);
|
||||
if (NILP (registry))
|
||||
error ("No XLFD: %s", XSTRING (font_spec)->data);
|
||||
if (NILP (AREF (registry, 12))
|
||||
|| NILP (AREF (registry, 13)))
|
||||
error ("Registry must be specified");
|
||||
registry = concat2 (concat2 (AREF (registry, 12), build_string ("-")),
|
||||
AREF (registry, 13));
|
||||
}
|
||||
|
||||
if (STRINGP (font_spec))
|
||||
|
|
@ -1278,7 +1318,7 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
|
|||
range_list);
|
||||
if (EQ (character, Qascii))
|
||||
{
|
||||
if (! STRINGP (font_spec))
|
||||
if (VECTORP (font_spec))
|
||||
font_spec = generate_ascii_font_name (FONTSET_NAME (fontset),
|
||||
font_spec);
|
||||
FONTSET_ASCII (fontset) = font_spec;
|
||||
|
|
@ -1306,10 +1346,12 @@ 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 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.
|
||||
Each element of FONTLIST has the form (SCRIPT FONT-SPEC ...), where a
|
||||
character of SCRIPT is displayed by a font that matches one of
|
||||
FONT-SPEC.
|
||||
|
||||
SCRIPT is a symbol that appears in the variable `script-alist'.
|
||||
SCRIPT is a symbol that appears in the first extra slot of the
|
||||
char-table `char-script-table'.
|
||||
|
||||
FONT-SPEC is a vector, a cons, or a string. See the documentation of
|
||||
`set-fontset-font' for the meaning. */)
|
||||
|
|
@ -1323,14 +1365,24 @@ FONT-SPEC is a vector, a cons, or a string. See the documentation of
|
|||
CHECK_STRING (name);
|
||||
CHECK_LIST (fontlist);
|
||||
|
||||
/* Check if an ASCII font is specified in FONTLIST. */
|
||||
val = Fcar (Fcdr (Fassq (Qascii, fontlist)));
|
||||
if (NILP (val))
|
||||
error ("No ascii font specified");
|
||||
|
||||
id = fs_query_fontset (name, 0);
|
||||
if (id < 0)
|
||||
fontset = make_fontset (Qnil, Fdowncase (name), Qnil);
|
||||
{
|
||||
name = Fdowncase (name);
|
||||
val = split_font_name_into_vector (name);
|
||||
if (NILP (val))
|
||||
error ("Fontset name must be in XLFD format");
|
||||
if (strcmp (XSTRING (AREF (val, 12))->data, "fontset"))
|
||||
error ("Registry field of fontset name must be \"fontset\"");
|
||||
Vfontset_alias_alist
|
||||
= Fcons (Fcons (name,
|
||||
concat2 (concat2 (AREF (val, 12), build_string ("-")),
|
||||
AREF (val, 13))),
|
||||
Vfontset_alias_alist);
|
||||
ASET (val, 12, build_string ("iso8859-1"));
|
||||
fontset = make_fontset (Qnil, name, Qnil);
|
||||
FONTSET_ASCII (fontset) = build_font_name_from_vector (val);
|
||||
}
|
||||
else
|
||||
{
|
||||
fontset = FONTSET_FROM_ID (id);;
|
||||
|
|
@ -1344,15 +1396,51 @@ FONT-SPEC is a vector, a cons, or a string. See the documentation of
|
|||
|
||||
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);
|
||||
Fset_fontset_font (name, script, Fcar (elt), Qnil, Qappend);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
/* Number of fontsets created from a fontname automatically. */
|
||||
static int n_auto_fontsets;
|
||||
|
||||
int
|
||||
new_fontset_from_font_name (Lisp_Object fontname)
|
||||
{
|
||||
Lisp_Object name;
|
||||
Lisp_Object vec;
|
||||
|
||||
fontname = Fdowncase (fontname);
|
||||
vec = split_font_name_into_vector (fontname);
|
||||
if ( NILP (vec))
|
||||
vec = Fmake_vector (make_number (14), build_string (""));
|
||||
ASET (vec, 12, build_string ("fontset"));
|
||||
if (n_auto_fontsets == 0)
|
||||
{
|
||||
ASET (vec, 13, build_string ("startup"));
|
||||
name = build_font_name_from_vector (vec);
|
||||
n_auto_fontsets++;
|
||||
}
|
||||
else
|
||||
{
|
||||
char temp[20];
|
||||
|
||||
do {
|
||||
sprintf (temp, "auto%d", n_auto_fontsets);
|
||||
ASET (vec, 13, build_string (temp));
|
||||
name = build_font_name_from_vector (vec);
|
||||
n_auto_fontsets++;
|
||||
} while (fs_query_fontset (name, 0) >= 0);
|
||||
}
|
||||
name = Fnew_fontset (name,
|
||||
Fcons (Fcons (Qascii, Fcons (fontname, Qnil)), Qnil));
|
||||
Vfontset_alias_alist = Fcons (Fcons (name, fontname), Vfontset_alias_alist);
|
||||
return fs_query_fontset (name, 0);
|
||||
}
|
||||
|
||||
|
||||
DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
|
||||
doc: /* Return information about a font named NAME on frame FRAME.
|
||||
If FRAME is omitted or nil, use the selected frame.
|
||||
|
|
@ -1465,7 +1553,11 @@ FONT-PATTERN is a vector:
|
|||
|
||||
or a string of font name pattern.
|
||||
|
||||
OPENED-FONT is a name of a font actually opened. */)
|
||||
OPENED-FONT is a name of a font actually opened.
|
||||
|
||||
The char-table has one extra slot. The value is a char-table
|
||||
containing the information about the derived fonts from the default
|
||||
fontset. The format is the same as abobe. */)
|
||||
(fontset, frame)
|
||||
Lisp_Object fontset, frame;
|
||||
{
|
||||
|
|
@ -1473,6 +1565,7 @@ OPENED-FONT is a name of a font actually opened. */)
|
|||
Lisp_Object table, val, elt;
|
||||
Lisp_Object *realized;
|
||||
int n_realized = 0;
|
||||
int fallback;
|
||||
int c, i, j;
|
||||
|
||||
(*check_window_system_func) ();
|
||||
|
|
@ -1498,57 +1591,77 @@ OPENED-FONT is a name of a font actually opened. */)
|
|||
}
|
||||
|
||||
|
||||
table = Fmake_char_table (Qnil, Qnil);
|
||||
table = Fmake_char_table (Qfontset_info, Qnil);
|
||||
XCHAR_TABLE (table)->extras[0] = 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; )
|
||||
for (fallback = 0; fallback <= 1; fallback++)
|
||||
{
|
||||
int from, to;
|
||||
|
||||
val = FONTSET_REF_AND_RANGE (fontset, c, from, to);
|
||||
if (VECTORP (val))
|
||||
Lisp_Object this_fontset, this_table;
|
||||
|
||||
if (! fallback)
|
||||
{
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
this_fontset = fontset;
|
||||
this_table = table;
|
||||
}
|
||||
else
|
||||
{
|
||||
this_fontset = Vdefault_fontset;
|
||||
this_table = XCHAR_TABLE (table)->extras[0];
|
||||
for (i = 0; i < n_realized; i++)
|
||||
realized[i] = FONTSET_FALLBACK (realized[i]);
|
||||
}
|
||||
for (c = 0; c <= MAX_5_BYTE_CHAR; )
|
||||
{
|
||||
int from, to;
|
||||
|
||||
val = char_table_ref_and_range (this_fontset, c, &from, &to);
|
||||
if (VECTORP (val))
|
||||
{
|
||||
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);
|
||||
|
||||
/* Then store opend font names to cdr of each elements. */
|
||||
for (i = 0; i < n_realized; i++)
|
||||
{
|
||||
if (NILP (realized[i]))
|
||||
continue;
|
||||
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 TBL for characters C..TO. */
|
||||
char_table_set_range (this_table, c, to, alist);
|
||||
}
|
||||
c = to + 1;
|
||||
}
|
||||
c = to + 1;
|
||||
}
|
||||
|
||||
return table;
|
||||
|
|
@ -1599,7 +1712,9 @@ syms_of_fontset ()
|
|||
abort ();
|
||||
|
||||
DEFSYM (Qfontset, "fontset");
|
||||
Fput (Qfontset, Qchar_table_extra_slots, make_number (7));
|
||||
Fput (Qfontset, Qchar_table_extra_slots, make_number (8));
|
||||
DEFSYM (Qfontset_info, "fontset-info");
|
||||
Fput (Qfontset_info, Qchar_table_extra_slots, make_number (1));
|
||||
|
||||
DEFSYM (Qprepend, "prepend");
|
||||
DEFSYM (Qappend, "append");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue