/* Fontset handler.
- Ver.1.0
+ Copyright (C) 1995, 1997 Electrotechnical Laboratory, JAPAN.
+ Licensed to the Free Software Foundation.
- Copyright (C) 1995 Free Software Foundation, Inc.
- Copyright (C) 1995 Electrotechnical Laboratory, JAPAN.
+This file is part of GNU Emacs.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include <config.h>
#if HAVE_ALLOCA_H
#include "frame.h"
Lisp_Object Vglobal_fontset_alist;
-
Lisp_Object Vfont_encoding_alist;
+Lisp_Object Vuse_default_ascent;
+Lisp_Object Vignore_relative_composition;
+Lisp_Object Valternate_fontname_alist;
+Lisp_Object Vfontset_alias_alist;
+Lisp_Object Vhighlight_wrong_size_font;
+Lisp_Object Vclip_large_size_font;
+
+/* Used as a temporary in macro FS_LOAD_FONT. */
+int font_idx_temp;
/* We had better have our own strcasecmp function because some system
doesn't have it. */
the comments in src/fontset.h for more detail. */
/* Return a pointer to struct font_info of font FONT_IDX of frame F. */
-struct font_info *(*get_font_info_func) (/* FRAME_PTR f; int font_idx */);
+struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx));
/* Return a list of font names which matches PATTERN. See the document of
`x-list-fonts' for more detail. */
-Lisp_Object (*list_fonts_func) (/* Lisp_Object pattern, face, frame, width */);
+Lisp_Object (*list_fonts_func) P_ ((Lisp_Object pattern, Lisp_Object face,
+ Lisp_Object frame, Lisp_Object width));
/* Load a font named NAME for frame F and return a pointer to the
information of the loaded font. If loading is failed, return 0. */
-struct font_info *(*load_font_func) (/* FRAME_PTR f; char *name */);
+struct font_info *(*load_font_func) P_ ((FRAME_PTR f, char *name, int));
/* Return a pointer to struct font_info of a font named NAME for frame F. */
-struct font_info *(*query_font_func) (/* FRAME_PTR f; char *name */);
+struct font_info *(*query_font_func) P_ ((FRAME_PTR f, char *name));
/* Additional function for setting fontset or changing fontset
contents of frame F. */
-void (*set_frame_fontset_func) (/* FRAME_PTR f; Lisp_Object arg, oldval */);
+void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg,
+ Lisp_Object oldval));
/* Check if any window system is used now. */
-void (*check_window_system_func) ();
+void (*check_window_system_func) P_ ((void));
struct fontset_data *
alloc_fontset_data ()
free_fontset_data (fontset_data)
struct fontset_data *fontset_data;
{
- int i;
-
- for (i = 0; i < fontset_data->n_fontsets; i++)
+ if (fontset_data->fontset_table)
{
- int j;
+ int i;
- xfree (fontset_data->fontset_table[i]->name);
- for (j = 0; j < MAX_CHARSET; j++)
- if (fontset_data->fontset_table[i]->fontname[j])
- xfree (fontset_data->fontset_table[i]->fontname[j]);
- xfree (fontset_data->fontset_table[i]);
+ for (i = 0; i < fontset_data->n_fontsets; i++)
+ {
+ int j;
+
+ xfree (fontset_data->fontset_table[i]->name);
+ for (j = 0; j <= MAX_CHARSET; j++)
+ if (fontset_data->fontset_table[i]->fontname[j])
+ xfree (fontset_data->fontset_table[i]->fontname[j]);
+ xfree (fontset_data->fontset_table[i]);
+ }
+ xfree (fontset_data->fontset_table);
}
- xfree (fontset_data->fontset_table);
xfree (fontset_data);
}
If loading fails, return 0;
If FONTNAME is NULL, the name is taken from the information of FONTSET.
If FONTSET is given, try to load a font whose size matches that of
- FONTSET, and, the font index is stored in the table for FONTSET. */
+ FONTSET, and, the font index is stored in the table for FONTSET.
+
+ If you give FONTSET argument, don't call this function directry,
+ instead call macro FS_LOAD_FONT with the same argument. */
struct font_info *
fs_load_font (f, font_table, charset, fontname, fontset)
/* No way to get fontname. */
return 0;
- /* If a fontset is specified and we have already loaded some fonts
- in the fontset, we need a font of appropriate size to be used
- with the fonts. */
- if (fontsetp && fontsetp->size)
- size = fontsetp->size * CHARSET_WIDTH (charset);
+ /* If CHARSET is not ASCII and FONTSET is specified, we must load a
+ font of appropriate size to be used with other fonts in this
+ fontset. */
+ if (charset != CHARSET_ASCII && fontsetp)
+ {
+ /* If we have not yet loaded ASCII font of FONTSET, we must load
+ it now to decided the size and height of this fontset. */
+ if (fontsetp->size == 0)
+ {
+ fontp = fs_load_font (f, font_table, CHARSET_ASCII, 0, fontset);
+ if (!fontp)
+ /* Any fontset should contain avairable ASCII. */
+ return 0;
+ }
+ /* Now we have surely decided the size of this fontset. */
+ size = fontsetp->size * CHARSET_WIDTH (charset);
+ }
fontp = (*load_font_func) (f, fontname, size);
not set by (*load_font_func). */
fontp->charset = charset;
- if (fontp->encoding[1] >= 0)
+ if (fontp->encoding[1] != FONT_ENCODING_NOT_DECIDED)
{
/* The font itself tells which code points to be used. Use this
encoding for all other charsets. */
int i;
fontp->encoding[0] = fontp->encoding[1];
- for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i < MAX_CHARSET; i++)
+ for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
fontp->encoding[i] = fontp->encoding[1];
}
else
/* At first, set 1 (means 0xA0..0xFF) as the default. */
fontp->encoding[0] = 1;
- for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i < MAX_CHARSET; i++)
+ for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
fontp->encoding[i] = 1;
/* Then override them by a specification in Vfont_encoding_alist. */
for (list = Vfont_encoding_alist; CONSP (list); list = XCONS (list)->cdr)
elt = XCONS (list)->car;
if (CONSP (elt)
&& STRINGP (XCONS (elt)->car) && CONSP (XCONS (elt)->cdr)
- && (fast_string_match_ignore_case (XCONS (elt)->car, fontname)
+ && (fast_c_string_match_ignore_case (XCONS (elt)->car, fontname)
>= 0))
{
Lisp_Object tmp;
for (tmp = XCONS (elt)->cdr; CONSP (tmp); tmp = XCONS (tmp)->cdr)
if (CONSP (XCONS (tmp)->car)
- && INTEGERP (XCONS (XCONS (tmp)->car)->car)
&& ((i = get_charset_id (XCONS (XCONS (tmp)->car)->car))
>= 0)
&& INTEGERP (XCONS (XCONS (tmp)->car)->cdr)
elt = XCONS (list)->car;
if (CONSP (elt)
&& STRINGP (XCONS (elt)->car) && VECTORP (XCONS (elt)->cdr)
- && fast_string_match_ignore_case (XCONS (elt)->car, fontname) >= 0)
+ && fast_c_string_match_ignore_case (XCONS (elt)->car, fontname) >= 0)
{
fontp->font_encoder
= (struct ccl_program *) xmalloc (sizeof (struct ccl_program));
}
}
+ /* If FONTSET is specified, setup various fields of it. */
if (fontsetp)
{
fontsetp->font_indexes[charset] = fontp->font_idx;
- if (fontsetp->size == 0)
- fontsetp->size = fontp->size / CHARSET_WIDTH (charset);
-
- if (charset == CHARSET_ASCII
- && fontsetp->size != fontp->size)
+ if (charset == CHARSET_ASCII)
{
- /* When loading ASCII font of the different size from the
- size of FONTSET, we have to update the size of FONTSET.
- Since changing the size of FONTSET may make some fonts
- already loaded inappropriate to be used in FONTSET, we
- must delete the record of such fonts. In that case, we
- also have to calculate the height of FONTSET from the
- remaining fonts. */
- int i;
-
- fontsetp->size = fontp->size;
- fontsetp->height = fontp->height;
- for (i = CHARSET_ASCII + 1; i < MAX_CHARSET; i++)
+ /* Decide or change the size and height of this fontset. */
+ if (fontsetp->size == 0)
{
- font_idx = fontsetp->font_indexes[i];
- if (font_idx >= 0)
+ fontsetp->size = fontp->size;
+ fontsetp->height = fontp->height;
+ }
+ else if (fontsetp->size != fontp->size
+ || fontsetp->height != fontp->height)
+ {
+ /* When loading ASCII font of the different size from
+ the size of FONTSET, we have to update the size of
+ FONTSET. Since changing the size of FONTSET may make
+ some fonts already loaded inappropriate to be used in
+ FONTSET, we must delete the record of such fonts. In
+ that case, we also have to calculate the height of
+ FONTSET from the remaining fonts. */
+ int i;
+
+ fontsetp->size = fontp->size;
+ fontsetp->height = fontp->height;
+ for (i = CHARSET_ASCII + 1; i <= MAX_CHARSET; i++)
{
- struct font_info *fontp2 = font_table + font_idx;
-
- if (fontp2->size != fontp->size * CHARSET_WIDTH (i))
- fontsetp->font_indexes[i] = FONT_NOT_OPENED;
- else if (fontsetp->height < fontp->height)
- fontsetp->height = fontp->height;
+ font_idx = fontsetp->font_indexes[i];
+ if (font_idx >= 0)
+ {
+ struct font_info *fontp2 = font_table + font_idx;
+
+ if (fontp2->size != fontp->size * CHARSET_WIDTH (i))
+ fontsetp->font_indexes[i] = FONT_NOT_OPENED;
+ /* The following code should be disabled until
+ Emacs supports variable height lines. */
+#if 0
+ else if (fontsetp->height < fontp->height)
+ fontsetp->height = fontp->height;
+#endif
+ }
}
}
}
- else if (fontsetp->height < fontp->height)
- fontsetp->height = fontp->height;
}
return fontp;
fontsetp->size = fontsetp->height = 0;
- for (i = 0; i < MAX_CHARSET; i++)
+ for (i = 0; i <= MAX_CHARSET; i++)
{
fontsetp->fontname[i] = (char *) 0;
fontsetp->font_indexes[i] = FONT_NOT_OPENED;
fontset_pattern_regexp (pattern)
Lisp_Object pattern;
{
- int nickname = 0;
-
if (!index (XSTRING (pattern)->data, '*')
&& !index (XSTRING (pattern)->data, '?'))
/* PATTERN does not contain any wild cards. */
- {
- if (XSTRING (pattern)->size > 8
- && ! bcmp (XSTRING (pattern)->data, "fontset-", 8))
- /* Just a nickname of a fontset is specified. */
- nickname = 1;
- else
- return Qnil;
- }
+ return Qnil;
if (!CONSP (Vcached_fontset_data)
|| strcmp (XSTRING (pattern)->data, CACHED_FONTSET_NAME))
{
/* We must at first update the cached data. */
- char *regex = (char *) alloca (XSTRING (pattern)->size * 2 + 3);
+ char *regex = (char *) alloca (XSTRING (pattern)->size * 2);
char *p0, *p1 = regex;
- if (nickname)
+ /* Convert "*" to ".*", "?" to ".". */
+ *p1++ = '^';
+ for (p0 = (char *) XSTRING (pattern)->data; *p0; p0++)
{
- /* Just prepend ".*-" to PATTERN. */
- *p1++= '.'; *p1++= '*', *p1++= '-';
- bcopy (XSTRING (pattern)->data, p1, XSTRING (pattern)->size);
- p1 += XSTRING (pattern)->size;
- }
- else
- {
- /* Convert "*" to ".*", "?" to ".". */
- *p1++ = '^';
- for (p0 = XSTRING (pattern)->data; *p0; p0++)
+ if (*p0 == '*')
{
- if (*p0 == '*')
- {
- *p1++ = '.';
- *p1++ = '*';
- }
- else if (*p0 == '?')
- *p1++ == '.';
- else
- *p1++ = *p0;
+ *p1++ = '.';
+ *p1++ = '*';
}
+ else if (*p0 == '?')
+ *p1++ == '.';
+ else
+ *p1++ = *p0;
}
*p1++ = '$';
*p1++ = 0;
if (XSTRING (pattern)->size == 0)
return Qnil;
+ tem = Frassoc (pattern, Vfontset_alias_alist);
+ if (!NILP (tem))
+ return Fcar (tem);
+
regexp = fontset_pattern_regexp (pattern);
for (tem = Vglobal_fontset_alist; CONSP (tem); tem = XCONS (tem)->cdr)
Lisp_Object fontset_name = XCONS (XCONS (tem)->car)->car;
if (!NILP (regexp))
{
- if (fast_string_match_ignore_case (regexp,
- XSTRING (fontset_name)->data)
+ if (fast_c_string_match_ignore_case (regexp,
+ XSTRING (fontset_name)->data)
>= 0)
return fontset_name;
}
if (!NILP (regexp))
{
- if (fast_string_match_ignore_case (regexp, fontsetp->name) >= 0)
+ if (fast_c_string_match_ignore_case (regexp, fontsetp->name) >= 0)
name_matched = 1;
}
else
one with SIZE. */
int j;
- for (j = 0; j < MAX_CHARSET; j++)
+ for (j = 0; j <= MAX_CHARSET; j++)
if (fontsetp->fontname[j])
{
if ((*load_font_func) (f, fontsetp->fontname[j], size))
if (NILP (frame))
{
Lisp_Object fontset_info = Fassoc (fullname, Vglobal_fontset_alist);
- Lisp_Object tem = Fassq (charset, XCONS (fontset_info)->cdr);
+ Lisp_Object tem = Fassq (charset_symbol, XCONS (fontset_info)->cdr);
if (NILP (tem))
XCONS (fontset_info)->cdr
- = Fcons (Fcons (charset, fontname), XCONS (fontset_info)->cdr);
+ = Fcons (Fcons (charset_symbol, fontname),
+ XCONS (fontset_info)->cdr);
else
XCONS (tem)->cdr = fontname;
}
struct fontset_info *fontsetp
= FRAME_FONTSET_DATA (f)->fontset_table[fontset];
- if (fontsetp->fontname[XINT (charset)])
- xfree (fontsetp->fontname[XINT (charset)]);
- fontsetp->fontname[XINT (charset)]
+ if (fontsetp->fontname[charset])
+ xfree (fontsetp->fontname[charset]);
+ fontsetp->fontname[charset]
= (char *) xmalloc (XSTRING (fontname)->size + 1);
- bcopy (XSTRING (fontname)->data, fontsetp->fontname[XINT (charset)],
+ bcopy (XSTRING (fontname)->data, fontsetp->fontname[charset],
XSTRING (fontname)->size + 1);
- fontsetp->font_indexes[XINT (charset)] = FONT_NOT_OPENED;
+ fontsetp->font_indexes[charset] = FONT_NOT_OPENED;
if (charset == CHARSET_ASCII)
{
"Return information about a font named NAME on frame FRAME.\n\
If FRAME is omitted or nil, use the selected frame.\n\
The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,\n\
- HEIGHT, BASELINE-OFFSET, and RELATIVE-COMPOSE,\n\
+ HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,\n\
where\n\
OPENED-NAME is the name used for opening the font,\n\
FULL-NAME is the full name of the font,\n\
SIZE is the minimum bound width of the font,\n\
HEIGHT is the height of the font,\n\
BASELINE-OFFSET is the upward offset pixels from ASCII baseline,\n\
- RELATIVE-COMPOSE is the number controlling how to compose characters.\n\
+ RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling\n\
+ how to compose characters.\n\
If the named font is not yet loaded, return nil.")
(name, frame)
Lisp_Object name, frame;
if (!fontp)
return Qnil;
- info = Fmake_vector (make_number (6), Qnil);
+ info = Fmake_vector (make_number (8), Qnil);
XVECTOR (info)->contents[0] = build_string (fontp->name);
XVECTOR (info)->contents[1] = build_string (fontp->full_name);
XVECTOR (info)->contents[4] = make_number (fontp->height);
XVECTOR (info)->contents[5] = make_number (fontp->baseline_offset);
XVECTOR (info)->contents[6] = make_number (fontp->relative_compose);
+ XVECTOR (info)->contents[7] = make_number (fontp->default_ascent);
return info;
}
XVECTOR (info)->contents[0] = make_number (fontsetp->size);
XVECTOR (info)->contents[1] = make_number (fontsetp->height);
val = Qnil;
- for (i = 0; i < MAX_CHARSET; i++)
+ for (i = 0; i <= MAX_CHARSET; i++)
if (fontsetp->fontname[i])
{
int font_idx = fontsetp->font_indexes[i];
/* Window system initializer should have set proper functions. */
abort ();
+ Qfontset = intern ("fontset");
staticpro (&Qfontset);
Vcached_fontset_data = Qnil;
3: code points 0xA020..0xFF7F are used.");
Vfont_encoding_alist = Qnil;
+ DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
+ "Char table of characters whose ascent values should be ignored.\n\
+If an entry for a character is non-nil, the ascent value of the glyph\n\
+is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.\n\
+\n\
+This affects how a composite character which contains\n\
+such a character is displayed on screen.");
+ Vuse_default_ascent = Qnil;
+
+ DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
+ "Char table of characters which is not composed relatively.\n\
+If an entry for a character is non-nil, a composite character\n\
+which contains that character is displayed so that\n\
+the glyph of that character is put without considering\n\
+an ascent and descent value of a previous character.");
+ Vuse_default_ascent = Qnil;
+
+ DEFVAR_LISP ("alternate-fontname-alist", &Valternate_fontname_alist,
+ "Alist of fontname vs list of the alternate fontnames.\n\
+When a specified font name is not found, the corresponding\n\
+alternate fontnames (if any) are tried instead.");
+ Valternate_fontname_alist = Qnil;
+
+ DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist,
+ "Alist of fontset names vs the aliases.");
+ Vfontset_alias_alist = Qnil;
+
+ DEFVAR_LISP ("highlight-wrong-size-font", &Vhighlight_wrong_size_font,
+ "*Non-nil means highlight characters shown in wrong size fonts somehow.\n\
+The way to highlight them depends on window system on which Emacs runs.\n\
+On X11, a rectangle is shown around each such character.");
+ Vhighlight_wrong_size_font = Qnil;
+
+ DEFVAR_LISP ("clip-large-size-font", &Vclip_large_size_font,
+ "*Non-nil means characters shown in overlarge fonts are clipped.\n\
+The height of clipping area is the same as that of an ASCII character.\n\
+The width of the area is the same as that of an ASCII character,\n\
+or twice as wide, depending on the character set's column-width.\n\
+\n\
+If the only font you have for a specific character set is too large,\n\
+and clipping these characters makes them hard to read,\n\
+you can set this variable to nil to display the characters without clipping.\n\
+The drawback is that you will get some garbage left on your screen.");
+ Vclip_large_size_font = Qt;
+
defsubr (&Squery_fontset);
defsubr (&Snew_fontset);
defsubr (&Sset_fontset_font);