Commit 41ad6003 authored by Kenichi Handa's avatar Kenichi Handa
Browse files

(fontset_compare_rfontdef): Fix plus/minus.

(reorder_font_vector): Change the arg preferred_family to font.
Prefer the spec matching with font.
(fontset_get_font_group): New function.
(fontset_find_font): Change the format of an element of a realized
fontset.  Use fontset_get_font_group.
(fontset_font): Try the current fontset, the default fontset, the
fallbacks of the current fonset, and the fallbacks of the default
fontset in this order.
(face_for_char): Delete the shortcut to use the current font.
(fontset_from_font): Don't set fonts for Latin in the fontset.
parent 45cebfd9
......@@ -208,7 +208,7 @@ static Lisp_Object fontset_add P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object));
static Lisp_Object fontset_find_font P_ ((Lisp_Object, int, struct face *,
int, int));
static void reorder_font_vector P_ ((Lisp_Object, Lisp_Object));
static void reorder_font_vector P_ ((Lisp_Object, struct font *));
static Lisp_Object fontset_font P_ ((Lisp_Object, int, struct face *, int));
static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
......@@ -377,8 +377,8 @@ static int
fontset_compare_rfontdef (val1, val2)
const void *val1, *val2;
{
return (RFONT_DEF_SCORE (*(Lisp_Object *) val2)
- RFONT_DEF_SCORE (*(Lisp_Object *) val1));
return (RFONT_DEF_SCORE (*(Lisp_Object *) val1)
- RFONT_DEF_SCORE (*(Lisp_Object *) val2));
}
/* Update FONT-GROUP which has this form:
......@@ -393,54 +393,57 @@ fontset_compare_rfontdef (val1, val2)
extern Lisp_Object Fassoc_string ();
static void
reorder_font_vector (font_group, preferred_family)
reorder_font_vector (font_group, font)
Lisp_Object font_group;
Lisp_Object preferred_family;
struct font *font;
{
Lisp_Object vec, font_object;
int size;
int i;
int score_changed = 0;
size = ASIZE (font_group);
/* Exclude the tailing nil elements from the reordering. */
while (NILP (AREF (font_group, size - 1))) size--;
size -= 2;
if (font)
XSETFONT (font_object, font);
else
font_object = Qnil;
vec = XCDR (font_group);
size = ASIZE (vec);
/* Exclude the tailing nil element from the reordering. */
if (NILP (AREF (vec, size - 1)))
size--;
for (i = 0; i < size; i++)
{
Lisp_Object rfont_def = AREF (font_group, i + 2);
Lisp_Object rfont_def = AREF (vec, i);
Lisp_Object font_def = RFONT_DEF_FONT_DEF (rfont_def);
Lisp_Object font_spec = FONT_DEF_SPEC (font_def);
Lisp_Object lang = Ffont_get (font_spec, QClang);
Lisp_Object family = AREF (font_spec, FONT_FAMILY_INDEX);
Lisp_Object repertory = FONT_DEF_REPERTORY (font_def);
int score = 0;
int score = RFONT_DEF_SCORE (rfont_def) & 0xFF;
if (! NILP (repertory))
if (! font_match_p (font_spec, font_object))
{
Lisp_Object tail;
Lisp_Object repertory = FONT_DEF_REPERTORY (font_def);
for (score = 0xFFFF, tail = Vcharset_ordered_list;
! EQ (tail, Vcharset_non_preferred_head) && CONSP (tail);
score--, tail = XCDR (tail))
if (EQ (repertory, XCAR (tail)))
break;
if (EQ (tail, Vcharset_non_preferred_head))
score = 0;
}
else if (! NILP (lang))
{
if (EQ (lang, Vcurrent_iso639_language))
score = 0xFFFF;
else if (CONSP (Vcurrent_iso639_language))
score = ! NILP (Fmemq (lang, Vcurrent_iso639_language));
}
if (! NILP (repertory))
{
Lisp_Object tail;
if (! NILP (preferred_family) && ! NILP (family))
{
if (fast_string_match_ignore_case (preferred_family,
SYMBOL_NAME (family)) < 0)
score |= 0x10000;
for (tail = Vcharset_ordered_list;
! EQ (tail, Vcharset_non_preferred_head) && CONSP (tail);
score += 0x100, tail = XCDR (tail))
if (EQ (repertory, XCAR (tail)))
break;
}
else
{
Lisp_Object lang = Ffont_get (font_spec, QClang);
if (! NILP (lang)
&& ! EQ (lang, Vcurrent_iso639_language)
&& (! CONSP (Vcurrent_iso639_language)
|| NILP (Fmemq (lang, Vcurrent_iso639_language))))
score |= 0x100;
}
}
if (RFONT_DEF_SCORE (rfont_def) != score)
{
......@@ -450,10 +453,49 @@ reorder_font_vector (font_group, preferred_family)
}
if (score_changed)
qsort (XVECTOR (font_group)->contents + 2, size, sizeof (Lisp_Object),
qsort (XVECTOR (vec)->contents, size, sizeof (Lisp_Object),
fontset_compare_rfontdef);
XSETCAR (font_group, make_number (charset_ordered_list_tick));
}
static Lisp_Object
fontset_get_font_group (fontset, c)
{
Lisp_Object font_group;
Lisp_Object base_fontset;
int from, to, i;
ASET (font_group, 0, make_number (charset_ordered_list_tick));
xassert (! BASE_FONTSET_P (fontset));
if (c >= 0)
font_group = CHAR_TABLE_REF (fontset, c);
else
font_group = FONTSET_FALLBACK (fontset);
if (! NILP (font_group))
return font_group;
base_fontset = FONTSET_BASE (fontset);
if (c >= 0)
font_group = char_table_ref_and_range (base_fontset, c, &from, &to);
else
font_group = FONTSET_FALLBACK (base_fontset);
if (NILP (font_group))
return Qnil;
font_group = Fcopy_sequence (font_group);
for (i = 0; i < ASIZE (font_group); i++)
if (! NILP (AREF (font_group, i)))
{
Lisp_Object rfont_def;
RFONT_DEF_NEW (rfont_def, AREF (font_group, i));
/* Remember the original order. */
RFONT_DEF_SET_SCORE (rfont_def, i);
ASET (font_group, i, rfont_def);
}
font_group = Fcons (make_number (-1), font_group);
if (c >= 0)
char_table_set_range (fontset, from, to, font_group);
else
FONTSET_FALLBACK (fontset) = font_group;
return font_group;
}
/* Return RFONT-DEF (vector) in the realized fontset FONTSET for the
......@@ -476,117 +518,61 @@ fontset_find_font (fontset, c, face, id, fallback)
struct face *face;
int id, fallback;
{
Lisp_Object base_fontset, elt, vec;
int i, from, to;
Lisp_Object elt, vec, font_group;
int i;
FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset));
int charset_matched = -1;
base_fontset = FONTSET_BASE (fontset);
if (! fallback)
vec = CHAR_TABLE_REF (fontset, c);
else
vec = FONTSET_FALLBACK (fontset);
font_group = fontset_get_font_group (fontset, fallback ? -1 : c);
if (! CONSP (font_group))
return Qnil;
vec = XCDR (font_group);
if (ASIZE (vec) == 0)
return Qnil;
if (NILP (vec))
if (ASIZE (vec) > 1)
{
Lisp_Object range;
/* We have not yet decided a font for C. */
if (! face)
return Qnil;
if (! fallback)
{
elt = char_table_ref_and_range (base_fontset, c, &from, &to);
range = Fcons (make_number (from), make_number (to));
}
else
{
elt = FONTSET_FALLBACK (base_fontset);
}
if (NILP (elt))
{
/* This fontset doesn't specify any font for C. */
vec = make_number (0);
}
else if (ASIZE (elt) == 1 && NILP (AREF (elt, 0)))
{
/* Explicitly specified no font. */
vec = Qt;
}
else
{
/* Build a font-group vector [ -1 nil RFONT-DEF0 RFONT-DEF1 ... ],
where the first -1 is to force reordering of RFONT-DEFs. */
int size = ASIZE (elt);
int j;
vec = Fmake_vector (make_number (size + 2), Qnil);
ASET (vec, 0, make_number (-1));
for (i = j = 0; i < size; i++)
if (! NILP (AREF (elt, i)))
if (XINT (XCAR (font_group)) != charset_ordered_list_tick)
/* We have just created the font-group,
or the charset priorities were changed. */
reorder_font_vector (font_group, face->ascii_face->font);
if (id >= 0)
/* Find a spec matching with the charset ID to try at
first. */
for (i = 0; i < ASIZE (vec); i++)
{
Lisp_Object rfont_def = AREF (vec, i);
Lisp_Object repertory
= FONT_DEF_REPERTORY (RFONT_DEF_FONT_DEF (rfont_def));
if (XINT (repertory) == id)
{
Lisp_Object rfont_def;
RFONT_DEF_NEW (rfont_def, AREF (elt, i));
ASET (vec, j + 2, rfont_def);
j++;
}
}
/* Then store it in the fontset. */
if (! fallback)
FONTSET_SET (fontset, range, vec);
else
FONTSET_FALLBACK (fontset) = vec;
}
if (! VECTORP (vec))
return (EQ (vec, Qt) ? Qt : Qnil);
if (ASIZE (vec) > 4 /* multiple RFONT-DEFs */
&& XINT (AREF (vec, 0)) != charset_ordered_list_tick)
/* We have just created VEC,
or the charset priorities were changed. */
reorder_font_vector (vec, face->lface[LFACE_FAMILY_INDEX]);
i = 2;
if (id >= 0)
{
elt = AREF (vec, 1);
if (! NILP (elt)
&& EQ (make_number (id), RFONT_DEF_REPERTORY (elt)))
i = 1;
else
{
for (; i < ASIZE (vec); i++)
{
elt = AREF (vec, i);
if (! NILP (elt)
&& EQ (make_number (id), RFONT_DEF_REPERTORY (elt)))
charset_matched = i;
break;
}
if (i < ASIZE (vec))
{
ASET (vec, 1, elt);
i = 1;
}
else
{
ASET (vec, 1, Qnil);
i = 2;
}
}
}
}
}
/* Find the first available font in the vector of RFONT-DEF. */
for (; i < ASIZE (vec); i++)
for (i = 0; i < ASIZE (vec); i++)
{
Lisp_Object font_entity, font_object;
elt = AREF (vec, i);
if (i == 0 && charset_matched >= 0)
{
/* Try the element matching with the charset ID at first. */
elt = AREF (vec, charset_matched);
charset_matched = -1;
i--;
}
else if (i != charset_matched)
elt = AREF (vec, i);
else
continue;
if (NILP (elt))
/* This is the sign of not to try fallback fonts. */
/* This is a sign of not to try the other fonts. */
return Qt;
if (id >= 0 && i > 1 && EQ (AREF (vec, 1), elt))
/* This is already checked. */
continue;
if (INTEGERP (RFONT_DEF_FACE (elt))
&& XINT (AREF (elt, 1)) < 0)
/* We couldn't open this font last time. */
......@@ -678,37 +664,46 @@ fontset_font (fontset, c, face, id)
Lisp_Object rfont_def;
Lisp_Object base_fontset;
/* Try a font-group for C. */
/* Try a font-group of FONTSET. */
rfont_def = fontset_find_font (fontset, c, face, id, 0);
if (VECTORP (rfont_def))
return rfont_def;
if (EQ (rfont_def, Qt))
return Qnil;
/* Try a fallback font-group. */
/* Try a font-group of the default fontset. */
base_fontset = FONTSET_BASE (fontset);
if (! EQ (base_fontset, Vdefault_fontset))
{
if (NILP (FONTSET_DEFAULT (fontset)))
FONTSET_DEFAULT (fontset)
= make_fontset (FONTSET_FRAME (fontset), Qnil, Vdefault_fontset);
rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 0);
if (VECTORP (rfont_def))
return rfont_def;
if (EQ (rfont_def, Qt))
return Qnil;
}
/* Try a fallback font-group of FONTSET. */
rfont_def = fontset_find_font (fontset, c, face, id, 1);
if (VECTORP (rfont_def))
return rfont_def;
if (EQ (rfont_def, Qt))
return Qnil;
base_fontset = FONTSET_BASE (fontset);
if (EQ (base_fontset, Vdefault_fontset))
return Qnil;
/* Try a font-group for C of the default fontset. */
if (NILP (FONTSET_DEFAULT (fontset)))
FONTSET_DEFAULT (fontset)
= make_fontset (FONTSET_FRAME (fontset), Qnil, Vdefault_fontset);
rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 0);
if (VECTORP (rfont_def))
return rfont_def;
/* Try a fallback font-group of the default fontset . */
rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 1);
if (! VECTORP (rfont_def))
/* Remeber that we have no font for C. */
FONTSET_SET (fontset, make_number (c), Qt);
if (! EQ (base_fontset, Vdefault_fontset))
{
rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 1);
if (VECTORP (rfont_def))
return rfont_def;
}
/* Remeber that we have no font for C. */
FONTSET_SET (fontset, make_number (c), Qt);
return rfont_def;
return Qnil;
}
/* Return a newly created fontset with NAME. If BASE is nil, make a
......@@ -890,6 +885,7 @@ face_for_char (f, face, c, pos, object)
xassert (fontset_id_valid_p (face->fontset));
fontset = FONTSET_FROM_ID (face->fontset);
xassert (!BASE_FONTSET_P (fontset));
if (pos < 0)
id = -1;
else
......@@ -909,16 +905,6 @@ face_for_char (f, face, c, pos, object)
id = XINT (CHARSET_SYMBOL_ID (charset));
}
}
if (id < 0)
{
struct font *font = face->ascii_face->font;
if (font && font->driver->encode_char (font, c) != FONT_INVALID_CODE)
return face->ascii_face->id;
font = face->font;
if (font && font->driver->encode_char (font, c) != FONT_INVALID_CODE)
return face->id;
}
rfont_def = fontset_font (fontset, c, face, id);
if (VECTORP (rfont_def))
......@@ -1634,13 +1620,9 @@ fontset_from_font (font_object)
auto_fontset_alist = Fcons (Fcons (font_spec, fontset), auto_fontset_alist);
FONTSET_ASCII (fontset) = font_name;
font_spec = Fcopy_font_spec (font_spec);
ASET (font_spec, FONT_FOUNDRY_INDEX, Qnil);
ASET (font_spec, FONT_ADSTYLE_INDEX, Qnil);
ASET (font_spec, FONT_REGISTRY_INDEX, Qiso10646_1);
for (i = FONT_WEIGHT_INDEX; i < FONT_EXTRA_INDEX; i++)
ASET (font_spec, i, Qnil);
Fset_fontset_font (name, Qlatin, font_spec, Qnil, Qnil);
font_spec = Fcopy_font_spec (font_spec);
ASET (font_spec, FONT_REGISTRY_INDEX, Qiso10646_1);
Fset_fontset_font (name, Qnil, font_spec, Qnil, Qnil);
return XINT (FONTSET_ID (fontset));
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment