#include "keyboard.h"
#include "frame.h"
#include "dispextern.h"
+#include "intervals.h"
#include "fontset.h"
#include "window.h"
+#ifdef HAVE_X_WINDOWS
+#include "xterm.h"
+#endif
+#ifdef WINDOWSNT
+#include "w32term.h"
+#endif
+#ifdef MAC_OS
+#include "macterm.h"
+#endif
#undef xassert
#ifdef FONTSET_DEBUG
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.
+ Note: Currently WEIGHT through ADSTYLE are ignored.
- 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 is a charset ID that can convert characters to glyph codes
+ of the corresponding font.
+
+ REPERTORY is a charset ID, a char-table, or nil. If REPERTORY is a
+ charset ID, the repertory of the charset exactly matches with that
+ of the font. If REPERTORY is a char-table, all characters who have
+ a non-nil value in the table are supported. 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.
+ Vfont_encoding_alist by using a font name generated from FONT-SPEC
+ (if it is a vector) or FONT-NAME as a matching target.
An element of a realized fontset is nil or t, or has this form:
- [CHARSET-PRIORITY-LIST-TICK PREFERRED-CHARSET-ID PREFERRED-FONT-DEF
- FONT-DEF0 FONT-DEF1 ...].
+ [CHARSET-ORDERED-LIST-TICK PREFERRED-CHARSET-ID
+ PREFERRED-RFONT-DEF RFONT-DEF0 RFONT-DEF1 ...].
- FONT-DEFn has this form:
+ RFONT-DEFn (i.e. Realized FONT-DEF) has this form:
- [ FACE-ID FONT-INDEX FONT-DEF ]
+ [ FACE-ID FONT-INDEX FONT-DEF OPENED-FONT-NAME ]
- FONT-DEFn is automatically reordered by the current charset
+ RFONT-DEFn is automatically reordered by the current charset
priority list.
- The value nil means that we have not yet generated FONT-VECTOR from
- the base of the fontset.
+ The value nil means that we have not yet generated the above vector
+ from the base of the fontset.
The value t means that no font is available for the corresponding
range of characters.
/* Prototype declarations for static functions. */
static Lisp_Object fontset_add P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object));
+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));
static void accumulate_script_ranges P_ ((Lisp_Object, Lisp_Object,
/* Update FONTSET_ELEMENT which has this form:
- [CHARSET-PRIORITY-LIST-TICK PREFERRED-CHARSET-ID INDEX
- FONT-DEF0 FONT-DEF1 ...].
- Reorder FONT-DEFs according to the current order of charset
- (Vcharset_ordered_list), and update CHARSET-PRIORITY-LIST-TICK to
+ [CHARSET-ORDERED-LIST-TICK PREFERRED-CHARSET-ID PREFERRED-RFONT-DEF
+ RFONT-DEF0 RFONT-DEF1 ...].
+ Reorder RFONT-DEFs according to the current order of charset
+ (Vcharset_ordered_list), and update CHARSET-ORDERED-LIST-TICK to
the latest value. */
static void
ASET (fontset_element, 0, make_number (charset_ordered_list_tick));
size = ASIZE (fontset_element) - 3;
if (size <= 1)
- /* No need of reordering VEC. */
+ /* No need to reorder VEC. */
return;
charset_id_table = (int *) alloca (sizeof (int) * size);
new_vec = (Lisp_Object *) alloca (sizeof (Lisp_Object) * size);
int charset;
font_name = choose_face_font (f, face->lface, AREF (font_def, 0), NULL);
- if (NATNUMP (AREF (font_def, 1)))
- charset = XINT (AREF (font_def, 1));
- else
- charset = -1;
+ charset = XINT (AREF (font_def, 1));
if (! (font_info = fs_load_font (f, font_name, charset)))
return -1;
}
-/* Return a face ID registerd in the realized fontset FONTSET for the
- character C. If a face is not yet set, return -1 (if FACE is NULL)
- or realize a proper face from FACE and return it. */
+/* Return RFONT-DEF (vector) in the realized fontset FONTSET for the
+ character C. If the corresponding font is not yet opened, open it
+ (if FACE is not NULL) or return Qnil (if FACE is NULL).
+ If no proper font is found for C, return Qnil. */
-static int
-fontset_face (fontset, c, face, id)
+static Lisp_Object
+fontset_font (fontset, c, face, id)
Lisp_Object fontset;
int c;
struct face *face;
Lisp_Object range;
if (! face)
- return -1;
+ return Qnil;
elt = FONTSET_REF_AND_RANGE (base_fontset, c, from, to);
range = Fcons (make_number (from), make_number (to));
if (NILP (elt))
}
/* Build a vector [ -1 -1 nil NEW-ELT0 NEW-ELT1 NEW-ELT2 ... ],
where the first -1 is to force reordering of NEW-ELTn,
- NEW-ETLn is [nil nil AREF (elt, n)]. */
+ NEW-ETLn is [nil nil AREF (elt, n) nil]. */
vec = Fmake_vector (make_number (ASIZE (elt) + 3), make_number (-1));
ASET (vec, 2, Qnil);
for (i = 0; i < ASIZE (elt); i++)
{
Lisp_Object tmp;
- tmp = Fmake_vector (make_number (3), Qnil);
+ tmp = Fmake_vector (make_number (4), Qnil);
ASET (tmp, 2, AREF (elt, i));
ASET (vec, 3 + i, tmp);
}
}
}
- /* Find the first available font in the font vector VEC. */
+ /* Find the first available font in the vector of RFONT-DEF. */
for (; i < ASIZE (vec); i++)
{
Lisp_Object font_def;
elt = AREF (vec, i);
if (NILP (elt))
continue;
- /* ELT == [ FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ] ] */
- font_def = AREF (elt, 2);
+ /* ELT == [ FACE-ID FONT-INDEX FONT-DEF OPENED-FONT-NAME ] */
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 (!face && NILP (AREF (elt, 1)))
+ /* We have not yet opened the font. */
+ return Qnil;
+ font_def = AREF (elt, 2);
+ /* FONT_DEF == [ FONT-SPEC ENCODING REPERTORY ] */
if (INTEGERP (AREF (font_def, 2)))
{
/* The repertory is specified by charset ID. */
/* This font can't display C. */
continue;
}
+ else if (CHAR_TABLE_P (AREF (font_def, 2)))
+ {
+ /* The repertory is specified by a char table. */
+ if (NILP (CHAR_TABLE_REF (AREF (font_def, 2), c)))
+ /* This font can't display C. */
+ continue;
+ }
else
{
Lisp_Object slot;
/* We have not yet opened a font matching this spec.
Open the best matching font now and register the
repertory. */
+ struct font_info *font_info;
+
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;
+ font_info = (*get_font_info_func) (f, font_idx);
+ ASET (elt, 3, build_string (font_info->full_name));
}
slot = Fassq (AREF (elt, 1), FONTSET_REPERTORY (fontset));
- if (! CONSP (slot))
- abort ();
+ xassert (CONSP (slot));
if (NILP (CHAR_TABLE_REF (XCDR (slot), c)))
- /* This fond can't display C. */
+ /* This font 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
+ if (! INTEGERP (AREF (elt, 1)))
{
/* But not yet opened the best matching font. */
+ struct font_info *font_info;
+
font_idx = load_font_get_repertory (f, face, font_def, fontset);
ASET (elt, 1, make_number (font_idx));
if (font_idx < 0)
+ /* Can't open it. Try the other one. */
continue;
+ font_info = (*get_font_info_func) (f, font_idx);
+ ASET (elt, 3, build_string (font_info->full_name));
}
/* 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));
+ return elt;
}
try_fallback:
- if (vec != FONTSET_FALLBACK (fontset))
+ if (! EQ (vec, FONTSET_FALLBACK (fontset)))
{
vec = FONTSET_FALLBACK (fontset);
if (VECTORP (vec))
{
Lisp_Object tmp;
- tmp = Fmake_vector (make_number (3), Qnil);
+ tmp = Fmake_vector (make_number (4), Qnil);
ASET (tmp, 2, AREF (elt, i));
ASET (vec, 3 + i, tmp);
}
if (NILP (FONTSET_DEFAULT (fontset)))
FONTSET_DEFAULT (fontset)
= make_fontset (FONTSET_FRAME (fontset), Qnil, Vdefault_fontset);
- return fontset_face (FONTSET_DEFAULT (fontset), c, face, id);
+ return fontset_font (FONTSET_DEFAULT (fontset), c, face, id);
}
-
- /* 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));
+ return Qnil;
}
next_fontset_id = face->fontset;
if (! NILP (FONTSET_DEFAULT (fontset)))
{
- int id = FONTSET_ID (FONTSET_DEFAULT (fontset));
+ int id = XINT (FONTSET_ID (FONTSET_DEFAULT (fontset)));
fontset = AREF (Vfontset_table, id);
xassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
struct face *face;
int c;
{
- Lisp_Object fontset;
+ Lisp_Object fontset, rfont_def;
fontset = FONTSET_FROM_ID (face->fontset);
- return (face->id == fontset_face (fontset, c, NULL, -1));
+ rfont_def = fontset_font (fontset, c, NULL, -1);
+ return (VECTORP (rfont_def)
+ && INTEGERP (AREF (rfont_def, 0))
+ && face->id == XINT (AREF (rfont_def, 0)));
}
int c, pos;
Lisp_Object object;
{
- Lisp_Object fontset, charset;
+ Lisp_Object fontset, charset, rfont_def;
+ int face_id;
int id;
if (ASCII_CHAR_P (c))
else if (CHARSETP (charset))
id = XINT (CHARSET_SYMBOL_ID (charset));
}
- return fontset_face (fontset, c, face, id);
+ rfont_def = fontset_font (fontset, c, face, id);
+ if (VECTORP (rfont_def))
+ {
+ if (NILP (AREF (rfont_def, 0)))
+ {
+ /* We have not yet made a realized face that uses this font. */
+ int font_idx = XINT (AREF (rfont_def, 1));
+
+ face_id = lookup_non_ascii_face (f, font_idx, face);
+ ASET (rfont_def, 0, make_number (face_id));
+ }
+ return XINT (AREF (rfont_def, 0));
+ }
+
+ if (NILP (FONTSET_NOFONT_FACE (fontset)))
+ {
+ face_id = lookup_non_ascii_face (f, -1, face);
+ FONTSET_NOFONT_FACE (fontset) = make_number (face_id);
+ }
+ return XINT (FONTSET_NOFONT_FACE (fontset));
}
fontset = make_fontset (frame, Qnil, base_fontset);
{
- Lisp_Object elt;
+ Lisp_Object elt, rfont_def;
elt = FONTSET_REF (base_fontset, 0);
- elt = Fmake_vector (make_number (4), AREF (elt, 0));
+ xassert (VECTORP (elt) && ASIZE (elt) > 0);
+ rfont_def = Fmake_vector (make_number (4), Qnil);
+ ASET (rfont_def, 0, make_number (face->id));
+ ASET (rfont_def, 1, make_number (face->font_info_id));
+ ASET (rfont_def, 2, AREF (elt, 0));
+ ASET (rfont_def, 3, build_string (face->font_name));
+ elt = Fmake_vector (make_number (4), Qnil);
ASET (elt, 0, make_number (charset_ordered_list_tick));
- ASET (elt, 1, make_number (face->id));
- ASET (elt, 2, make_number (face->font_info_id));
+ ASET (elt, 1, make_number (charset_ascii));
+ ASET (elt, 2, rfont_def);
+ ASET (elt, 3, rfont_def);
char_table_set_range (fontset, 0, 127, elt);
}
return XINT (FONTSET_ID (fontset));
: 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;
+ /* We don't know the encoding of this font. Let's assume `ascii'. */
+ return Qascii;
}
return build_font_name_from_vector (vec);
}
+/* Variables referred in set_fontset_font. They are set before
+ map_charset_chars is called in Fset_fontset_font. */
+static Lisp_Object font_def_arg, add_arg;
+static int from_arg, to_arg;
+
+/* Callback function for map_charset_chars in Fset_fontset_font. In
+ FONTSET, set font_def_arg in a fashion specified by add_arg for
+ characters in RANGE while ignoring the range between from_arg and
+ to_arg. */
+
static void
-set_fontset_font (arg, range)
- Lisp_Object arg, range;
+set_fontset_font (fontset, range)
+ Lisp_Object fontset, range;
{
- Lisp_Object fontset, font_def, add;
+ if (from_arg < to_arg)
+ {
+ int from = XINT (XCAR (range)), to = XINT (XCDR (range));
- fontset = XCAR (arg);
- font_def = XCAR (XCDR (arg));
- add = XCAR (XCDR (XCDR (arg)));
- FONTSET_ADD (fontset, range, font_def, add);
- free_realized_fontsets (fontset);
+ if (from < from_arg)
+ {
+ if (to > to_arg)
+ {
+ Lisp_Object range2;
+
+ range2 = Fcons (make_number (to_arg), XCDR (range));
+ FONTSET_ADD (fontset, range, font_def_arg, add_arg);
+ to = to_arg;
+ }
+ if (to > from_arg)
+ range = Fcons (XCAR (range), make_number (from_arg));
+ }
+ else if (to <= to_arg)
+ return;
+ else
+ {
+ if (from < to_arg)
+ range = Fcons (make_number (to_arg), XCDR (range));
+ }
+ }
+ FONTSET_ADD (fontset, range, font_def_arg, add_arg);
}
Lisp_Object font_def, registry;
Lisp_Object encoding, repertory;
Lisp_Object range_list;
+ struct charset *charset = NULL;
fontset = check_fontset_name (name);
else
encoding = find_font_encoding ((char *) SDATA (registry));
if (SYMBOLP (encoding))
- encoding = repertory = CHARSET_SYMBOL_ID (encoding);
+ {
+ CHECK_CHARSET (encoding);
+ encoding = repertory = CHARSET_SYMBOL_ID (encoding);
+ }
else
{
repertory = XCDR (encoding);
- encoding = CHARSET_SYMBOL_ID (XCAR (encoding));
+ encoding = XCAR (encoding);
+ CHECK_CHARSET (encoding);
+ encoding = CHARSET_SYMBOL_ID (encoding);
+ if (! NILP (repertory) && SYMBOLP (repertory))
+ {
+ CHECK_CHARSET (repertory);
+ repertory = CHARSET_SYMBOL_ID (repertory);
+ }
}
font_def = Fmake_vector (make_number (3), font_spec);
ASET (font_def, 1, encoding);
val);
range_list = XCDR (val);
}
- else if (CHARSETP (target))
+ if (CHARSETP (target))
{
- struct charset *charset;
-
- CHECK_CHARSET_GET_CHARSET (target, charset);
if (EQ (target, Qascii))
{
if (VECTORP (font_spec))
}
else
{
- map_charset_chars (set_fontset_font, Qnil,
- list3 (fontset, font_def, add), charset,
- CHARSET_MIN_CODE (charset),
- CHARSET_MAX_CODE (charset));
- return Qnil;
+ CHECK_CHARSET_GET_CHARSET (target, charset);
}
}
-
- if (NILP (range_list))
+ else if (NILP (range_list))
error ("Invalid script or charset name: %s",
SDATA (SYMBOL_NAME (target)));
}
else
error ("Invalid target for setting a font");
+
+ if (charset)
+ {
+ font_def_arg = font_def;
+ add_arg = add;
+ if (NILP (range_list))
+ from_arg = to_arg = 0;
+ else
+ from_arg = XINT (XCAR (XCAR (range_list))),
+ to_arg = XINT (XCDR (XCAR (range_list)));
+
+ map_charset_chars (set_fontset_font, Qnil, fontset, charset,
+ CHARSET_MIN_CODE (charset),
+ CHARSET_MAX_CODE (charset));
+ }
for (; CONSP (range_list); range_list = XCDR (range_list))
FONTSET_ADD (fontset, XCAR (range_list), font_def, add);
else
{
char temp[20];
- int len = Flength (auto_fontset_alist);
+ int len = XINT (Flength (auto_fontset_alist));
sprintf (temp, "auto%d", len);
ASET (vec, 13, build_string (temp));
name = build_font_name_from_vector (vec);
}
- name = Fnew_fontset (name, Fcons (Fcons (Fcons (make_number (0),
+ name = Fnew_fontset (name, list2 (list2 (Qascii, fontname),
+ list2 (Fcons (make_number (0),
make_number (MAX_CHAR)),
- Fcons (fontname, Qnil)),
- Qnil));
+ fontname)));
id = fs_query_fontset (name, 0);
auto_fontset_alist
= Fcons (Fcons (fontname, make_number (id)), auto_fontset_alist);
}
-/* Return the font name for the character at POSITION in the current
+/* Return a cons (FONT-NAME . GLYPH-CODE).
+ FONT-NAME is the font name for the character at POSITION in the current
buffer. This is computed from all the text properties and overlays
- that apply to POSITION. It returns nil in the following cases:
+ that apply to POSITION.
+ GLYPH-CODE is the glyph code in the font to use for the character.
+
+ If the 2nd optional arg CH is non-nil, it is a character to check
+ the font instead of the character at POSITION.
+
+ It returns nil in the following cases:
(1) The window system doesn't have a font for the character (thus
it is displayed by an empty box).
POSITION is currently not visible. */
-DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 1, 0,
+DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
doc: /* For internal use only. */)
- (position)
- Lisp_Object position;
+ (position, ch)
+ Lisp_Object position, ch;
{
int pos, pos_byte, dummy;
int face_id;
struct window *w;
struct frame *f;
struct face *face;
+ Lisp_Object charset, rfont_def;
+ int charset_id;
CHECK_NUMBER_COERCE_MARKER (position);
pos = XINT (position);
if (pos < BEGV || pos >= ZV)
args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
pos_byte = CHAR_TO_BYTE (pos);
- c = FETCH_CHAR (pos_byte);
+ if (NILP (ch))
+ c = FETCH_CHAR (pos_byte);
+ else
+ {
+ CHECK_CHARACTER (ch);
+ c = XINT (ch);
+ }
window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
if (NILP (window))
return Qnil;
w = XWINDOW (window);
f = XFRAME (w->frame);
face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0);
- face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c, pos, Qnil);
face = FACE_FROM_ID (f, face_id);
- return (face->font && face->font_name
- ? build_string (face->font_name)
- : Qnil);
+ charset = Fget_char_property (position, Qcharset, Qnil);
+ if (CHARSETP (charset))
+ charset_id = XINT (CHARSET_SYMBOL_ID (charset));
+ else
+ charset_id = -1;
+ rfont_def = fontset_font (FONTSET_FROM_ID (face->fontset),
+ c, face, charset_id);
+ if (VECTORP (rfont_def) && STRINGP (AREF (rfont_def, 3)))
+ {
+ Lisp_Object font_def;
+ struct font_info *fontp;
+ struct charset *charset;
+ XChar2b char2b;
+ int code;
+
+ font_def = AREF (rfont_def, 2);
+ charset = CHARSET_FROM_ID (XINT (AREF (font_def, 1)));
+ code = ENCODE_CHAR (charset, c);
+ if (code == CHARSET_INVALID_CODE (charset))
+ return (Fcons (AREF (rfont_def, 3), Qnil));
+ STORE_XCHAR2B (&char2b, ((code >> 8) & 0xFF), (code & 0xFF));
+ fontp = (*get_font_info_func) (f, XINT (AREF (rfont_def, 1)));
+ rif->encode_char (c, &char2b, fontp, charset, NULL);
+ code = (XCHAR2B_BYTE1 (&char2b) << 8) | XCHAR2B_BYTE2 (&char2b);
+ return (Fcons (AREF (rfont_def, 3), make_number (code)));
+ }
+ return Qnil;
}
val = FONTSET_FALLBACK (realized[k][i]);
if (! VECTORP (val))
continue;
- /* VAL is [int int int [FACE-ID FONT-INDEX FONT-DEF] ...].
+ /* VAL is [int int ?
+ [FACE-ID FONT-INDEX FONT-DEF FONT-NAME] ...].
If a font of an element is already opened,
- FONT-INDEX of the element is integer. */
+ FONT-NAME is the name of a opened font. */
for (j = 3; j < ASIZE (val); j++)
- if (INTEGERP (AREF (AREF (val, j), 0)))
+ if (STRINGP (AREF (AREF (val, j), 3)))
{
Lisp_Object font_idx;
defsubr (&Sfontset_list_all);
#endif
}
+
+/* arch-tag: ea861585-2f5f-4e5b-9849-d04a9c3a3537
+ (do not change this comment) */