Commit d84b082d authored by Jason Rumney's avatar Jason Rumney

(w32_load_system_font, w32_to_x_charset): Use strnicmp

in place of stricmp.
(w32_list_synthesized_fonts): Removed.
(w32_to_all_x_charsets, enum_font_maybe_add_to_list): New functions.
(struct enumfont_t): New element; list.
(enum_font_cb2): List all style and charset variations of a font.
(Fw32_select_font): New optional argument; include_proportional.
Exclude vertical fonts.  Exclude proportional fonts unless
include_proportional is non-nil.
(w32_enable_synthesized_fonts): Change to a boolean.
(Fw32_send_sys_command): Doc fix.
parent 73dc743c
...@@ -129,7 +129,7 @@ Lisp_Object Vw32_scroll_lock_modifier; ...@@ -129,7 +129,7 @@ Lisp_Object Vw32_scroll_lock_modifier;
/* Switch to control whether we inhibit requests for synthesized bold /* Switch to control whether we inhibit requests for synthesized bold
and italic versions of fonts. */ and italic versions of fonts. */
Lisp_Object Vw32_enable_synthesized_fonts; int w32_enable_synthesized_fonts;
/* Enable palette management. */ /* Enable palette management. */
Lisp_Object Vw32_enable_palette; Lisp_Object Vw32_enable_palette;
...@@ -5913,7 +5913,7 @@ w32_load_system_font (f,fontname,size) ...@@ -5913,7 +5913,7 @@ w32_load_system_font (f,fontname,size)
/* SJIS fonts need to be set to type 4, all others seem to work as /* SJIS fonts need to be set to type 4, all others seem to work as
type FONT_ENCODING_NOT_DECIDED. */ type FONT_ENCODING_NOT_DECIDED. */
encoding = strrchr (fontp->name, '-'); encoding = strrchr (fontp->name, '-');
if (encoding && stricmp (encoding+1, "sjis") == 0) if (encoding && strnicmp (encoding+1, "sjis", 4) == 0)
fontp->encoding[1] = 4; fontp->encoding[1] = 4;
else else
fontp->encoding[1] = FONT_ENCODING_NOT_DECIDED; fontp->encoding[1] = FONT_ENCODING_NOT_DECIDED;
...@@ -6082,7 +6082,7 @@ x_to_w32_charset (lpcs) ...@@ -6082,7 +6082,7 @@ x_to_w32_charset (lpcs)
w32_charset = Fcar (Fcdr (this_entry)); w32_charset = Fcar (Fcdr (this_entry));
// Translate Lisp symbol to number. /* Translate Lisp symbol to number. */
if (w32_charset == Qw32_charset_ansi) if (w32_charset == Qw32_charset_ansi)
return ANSI_CHARSET; return ANSI_CHARSET;
if (w32_charset == Qw32_charset_symbol) if (w32_charset == Qw32_charset_symbol)
...@@ -6258,13 +6258,13 @@ w32_to_x_charset (fncharset) ...@@ -6258,13 +6258,13 @@ w32_to_x_charset (fncharset)
best_match = x_charset; best_match = x_charset;
/* If this is an ISO codepage, and the best so far isn't, /* If this is an ISO codepage, and the best so far isn't,
then this is better. */ then this is better. */
else if (stricmp (best_match, "iso") != 0 else if (strnicmp (best_match, "iso", 3) != 0
&& stricmp (x_charset, "iso") == 0) && strnicmp (x_charset, "iso", 3) == 0)
best_match = x_charset; best_match = x_charset;
/* If both are ISO8859 codepages, choose the one with the /* If both are ISO8859 codepages, choose the one with the
lowest number in the encoding field. */ lowest number in the encoding field. */
else if (stricmp (best_match, "iso8859-") == 0 else if (strnicmp (best_match, "iso8859-", 8) == 0
&& stricmp (x_charset, "iso8859-") == 0) && strnicmp (x_charset, "iso8859-", 8) == 0)
{ {
int best_enc = atoi (best_match + 8); int best_enc = atoi (best_match + 8);
int this_enc = atoi (x_charset + 8); int this_enc = atoi (x_charset + 8);
...@@ -6288,6 +6288,142 @@ w32_to_x_charset (fncharset) ...@@ -6288,6 +6288,142 @@ w32_to_x_charset (fncharset)
} }
/* Return all the X charsets that map to a font. */
static Lisp_Object
w32_to_all_x_charsets (fncharset)
int fncharset;
{
static char buf[32];
Lisp_Object charset_type;
Lisp_Object retval = Qnil;
switch (fncharset)
{
case ANSI_CHARSET:
/* Handle startup case of w32-charset-info-alist not
being set up yet. */
if (NILP(Vw32_charset_info_alist))
return "iso8859-1";
charset_type = Qw32_charset_ansi;
break;
case DEFAULT_CHARSET:
charset_type = Qw32_charset_default;
break;
case SYMBOL_CHARSET:
charset_type = Qw32_charset_symbol;
break;
case SHIFTJIS_CHARSET:
charset_type = Qw32_charset_shiftjis;
break;
case HANGEUL_CHARSET:
charset_type = Qw32_charset_hangeul;
break;
case GB2312_CHARSET:
charset_type = Qw32_charset_gb2312;
break;
case CHINESEBIG5_CHARSET:
charset_type = Qw32_charset_chinesebig5;
break;
case OEM_CHARSET:
charset_type = Qw32_charset_oem;
break;
/* More recent versions of Windows (95 and NT4.0) define more
character sets. */
#ifdef EASTEUROPE_CHARSET
case EASTEUROPE_CHARSET:
charset_type = Qw32_charset_easteurope;
break;
case TURKISH_CHARSET:
charset_type = Qw32_charset_turkish;
break;
case BALTIC_CHARSET:
charset_type = Qw32_charset_baltic;
break;
case RUSSIAN_CHARSET:
charset_type = Qw32_charset_russian;
break;
case ARABIC_CHARSET:
charset_type = Qw32_charset_arabic;
break;
case GREEK_CHARSET:
charset_type = Qw32_charset_greek;
break;
case HEBREW_CHARSET:
charset_type = Qw32_charset_hebrew;
break;
case VIETNAMESE_CHARSET:
charset_type = Qw32_charset_vietnamese;
break;
case THAI_CHARSET:
charset_type = Qw32_charset_thai;
break;
case MAC_CHARSET:
charset_type = Qw32_charset_mac;
break;
case JOHAB_CHARSET:
charset_type = Qw32_charset_johab;
break;
#endif
#ifdef UNICODE_CHARSET
case UNICODE_CHARSET:
charset_type = Qw32_charset_unicode;
break;
#endif
default:
/* Encode numerical value of unknown charset. */
sprintf (buf, "*-#%u", fncharset);
return Fcons (build_string (buf), Qnil);
}
{
Lisp_Object rest;
/* Look through w32-charset-info-alist for the character set.
Only return charsets for codepages which are installed.
Format of each entry in Vw32_charset_info_alist is
(CHARSET_NAME . (WINDOWS_CHARSET . CODEPAGE)).
*/
for (rest = Vw32_charset_info_alist; CONSP (rest); rest = XCDR (rest))
{
Lisp_Object x_charset;
Lisp_Object w32_charset;
Lisp_Object codepage;
Lisp_Object this_entry = XCAR (rest);
/* Skip invalid entries in alist. */
if (!CONSP (this_entry) || !STRINGP (XCAR (this_entry))
|| !CONSP (XCDR (this_entry))
|| !SYMBOLP (XCAR (XCDR (this_entry))))
continue;
x_charset = XCAR (this_entry);
w32_charset = XCAR (XCDR (this_entry));
codepage = XCDR (XCDR (this_entry));
/* Look for Same charset and a valid codepage (or non-int
which means ignore). */
if (w32_charset == charset_type
&& (!INTEGERP (codepage) || codepage == CP_DEFAULT
|| IsValidCodePage (XINT (codepage))))
{
retval = Fcons (x_charset, retval);
}
}
/* If no match, encode the numeric value. */
if (NILP (retval))
{
sprintf (buf, "*-#%u", fncharset);
return Fcons (build_string (buf), Qnil);
}
return retval;
}
}
/* Get the Windows codepage corresponding to the specified font. The /* Get the Windows codepage corresponding to the specified font. The
charset info in the font name is used to look up charset info in the font name is used to look up
w32-charset-to-codepage-alist. */ w32-charset-to-codepage-alist. */
...@@ -6802,9 +6938,15 @@ typedef struct enumfont_t ...@@ -6802,9 +6938,15 @@ typedef struct enumfont_t
LOGFONT logfont; LOGFONT logfont;
XFontStruct *size_ref; XFontStruct *size_ref;
Lisp_Object *pattern; Lisp_Object *pattern;
Lisp_Object list;
Lisp_Object *tail; Lisp_Object *tail;
} enumfont_t; } enumfont_t;
static void
enum_font_maybe_add_to_list (enumfont_t *, LOGFONT *, char *, Lisp_Object);
static int CALLBACK static int CALLBACK
enum_font_cb2 (lplf, lptm, FontType, lpef) enum_font_cb2 (lplf, lptm, FontType, lpef)
ENUMLOGFONT * lplf; ENUMLOGFONT * lplf;
...@@ -6832,6 +6974,7 @@ enum_font_cb2 (lplf, lptm, FontType, lpef) ...@@ -6832,6 +6974,7 @@ enum_font_cb2 (lplf, lptm, FontType, lpef)
{ {
char buf[100]; char buf[100];
Lisp_Object width = Qnil; Lisp_Object width = Qnil;
Lisp_Object charset_list = Qnil;
char *charset = NULL; char *charset = NULL;
/* Truetype fonts do not report their true metrics until loaded */ /* Truetype fonts do not report their true metrics until loaded */
...@@ -6866,28 +7009,83 @@ enum_font_cb2 (lplf, lptm, FontType, lpef) ...@@ -6866,28 +7009,83 @@ enum_font_cb2 (lplf, lptm, FontType, lpef)
{ {
charset = xlfd_charset_of_font (XSTRING(*(lpef->pattern))->data); charset = xlfd_charset_of_font (XSTRING(*(lpef->pattern))->data);
/* Ensure that charset is valid for this font. */ /* Ensure that charset is valid for this font.
Continue if invalid in case charset contains a wildcard. */
if (charset if (charset
&& (x_to_w32_charset (charset) != lplf->elfLogFont.lfCharSet)) && (x_to_w32_charset (charset) != lplf->elfLogFont.lfCharSet))
charset = NULL; charset = NULL;
} }
/* TODO: List all relevant charsets if charset not specified. */ if (charset)
if (!w32_to_x_font (&(lplf->elfLogFont), buf, 100, charset)) charset_list = Fcons (build_string (charset), Qnil);
else
charset_list = w32_to_all_x_charsets (lplf->elfLogFont.lfCharSet);
/* Loop through the charsets. */
for ( ; CONSP (charset_list); charset_list = Fcdr (charset_list))
{
Lisp_Object this_charset = Fcar (charset_list);
charset = XSTRING (this_charset)->data;
/* List bold and italic variations if w32-enable-synthesized-fonts
is non-nil and this is a plain font. */
if (w32_enable_synthesized_fonts
&& lplf->elfLogFont.lfWeight == FW_NORMAL
&& lplf->elfLogFont.lfItalic == FALSE)
{
enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
charset, width);
/* bold. */
lplf->elfLogFont.lfWeight = FW_BOLD;
enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
charset, width);
/* bold italic. */
lplf->elfLogFont.lfItalic = TRUE;
enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
charset, width);
/* italic. */
lplf->elfLogFont.lfWeight = FW_NORMAL;
enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
charset, width);
}
else
enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
charset, width);
}
}
return 1; return 1;
}
static void
enum_font_maybe_add_to_list (lpef, logfont, match_charset, width)
enumfont_t * lpef;
LOGFONT * logfont;
char * match_charset;
Lisp_Object width;
{
char buf[100];
if (!w32_to_x_font (logfont, buf, 100, match_charset))
return;
if (NILP (*(lpef->pattern)) if (NILP (*(lpef->pattern))
|| w32_font_match (buf, XSTRING (*(lpef->pattern))->data)) || w32_font_match (buf, XSTRING (*(lpef->pattern))->data))
{
/* Check if we already listed this font. This may happen if
w32_enable_synthesized_fonts is non-nil, and there are real
bold and italic versions of the font. */
Lisp_Object font_name = build_string (buf);
if (NILP (Fmember (font_name, lpef->list)))
{ {
*lpef->tail = Fcons (Fcons (build_string (buf), width), Qnil); *lpef->tail = Fcons (Fcons (build_string (buf), width), Qnil);
lpef->tail = &(XCDR (*lpef->tail)); lpef->tail = &(XCDR (*lpef->tail));
lpef->numFonts++; lpef->numFonts++;
} }
} }
return 1;
} }
static int CALLBACK static int CALLBACK
enum_font_cb1 (lplf, lptm, FontType, lpef) enum_font_cb1 (lplf, lptm, FontType, lpef)
ENUMLOGFONT * lplf; ENUMLOGFONT * lplf;
...@@ -6970,9 +7168,6 @@ static Lisp_Object w32_list_bdf_fonts (Lisp_Object pattern, int max_names) ...@@ -6970,9 +7168,6 @@ static Lisp_Object w32_list_bdf_fonts (Lisp_Object pattern, int max_names)
return newlist; return newlist;
} }
static Lisp_Object w32_list_synthesized_fonts (FRAME_PTR f,
Lisp_Object pattern,
int size, int max_names);
/* Return a list of names of available fonts matching PATTERN on frame /* Return a list of names of available fonts matching PATTERN on frame
F. If SIZE is not 0, it is the size (maximum bound width) of fonts F. If SIZE is not 0, it is the size (maximum bound width) of fonts
...@@ -7031,6 +7226,7 @@ w32_list_fonts (f, pattern, size, maxnames) ...@@ -7031,6 +7226,7 @@ w32_list_fonts (f, pattern, size, maxnames)
/* At first, put PATTERN in the cache. */ /* At first, put PATTERN in the cache. */
list = Qnil; list = Qnil;
ef.pattern = &tpat; ef.pattern = &tpat;
ef.list = list;
ef.tail = &list; ef.tail = &list;
ef.numFonts = 0; ef.numFonts = 0;
...@@ -7175,68 +7371,9 @@ w32_list_fonts (f, pattern, size, maxnames) ...@@ -7175,68 +7371,9 @@ w32_list_fonts (f, pattern, size, maxnames)
newlist = Fnconc(2, combined); newlist = Fnconc(2, combined);
} }
/* If we can't find a font that matches, check if Windows would be
able to synthesize it from a different style. */
if (NILP (newlist) && !NILP (Vw32_enable_synthesized_fonts))
newlist = w32_list_synthesized_fonts (f, pattern, size, maxnames);
return newlist; return newlist;
} }
static Lisp_Object
w32_list_synthesized_fonts (f, pattern, size, max_names)
FRAME_PTR f;
Lisp_Object pattern;
int size;
int max_names;
{
int fields;
char *full_pattn, *new_pattn, foundary[50], family[50], *pattn_part2;
char style[20], slant;
Lisp_Object matches, tem, synthed_matches = Qnil;
full_pattn = XSTRING (pattern)->data;
pattn_part2 = alloca (XSTRING (pattern)->size + 1);
/* Allow some space for wildcard expansion. */
new_pattn = alloca (XSTRING (pattern)->size + 100);
fields = sscanf (full_pattn, "-%49[^-]-%49[^-]-%19[^-]-%c-%s",
foundary, family, style, &slant, pattn_part2);
if (fields == EOF || fields < 5)
return Qnil;
/* If the style and slant are wildcards already there is no point
checking again (and we don't want to keep recursing). */
if (*style == '*' && slant == '*')
return Qnil;
sprintf (new_pattn, "-%s-%s-*-*-%s", foundary, family, pattn_part2);
matches = w32_list_fonts (f, build_string (new_pattn), size, max_names);
for ( ; CONSP (matches); matches = XCDR (matches))
{
tem = XCAR (matches);
if (!STRINGP (tem))
continue;
full_pattn = XSTRING (tem)->data;
fields = sscanf (full_pattn, "-%49[^-]-%49[^-]-%*[^-]-%*c-%s",
foundary, family, pattn_part2);
if (fields == EOF || fields < 3)
continue;
sprintf (new_pattn, "-%s-%s-%s-%c-%s", foundary, family, style,
slant, pattn_part2);
synthed_matches = Fcons (build_string (new_pattn),
synthed_matches);
}
return synthed_matches;
}
/* Return a pointer to struct font_info of font FONT_IDX of frame F. */ /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
struct font_info * struct font_info *
...@@ -13843,11 +13980,11 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */) ...@@ -13843,11 +13980,11 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */)
w32 specialized functions w32 specialized functions
***********************************************************************/ ***********************************************************************/
DEFUN ("w32-select-font", Fw32_select_font, Sw32_select_font, 0, 1, 0, DEFUN ("w32-select-font", Fw32_select_font, Sw32_select_font, 0, 2, 0,
doc: /* Select a font using the W32 font dialog. doc: /* Select a font using the W32 font dialog.
Returns an X font string corresponding to the selection. */) Returns an X font string corresponding to the selection. */)
(frame) (frame, include_proportional)
Lisp_Object frame; Lisp_Object frame, include_proportional;
{ {
FRAME_PTR f = check_x_frame (frame); FRAME_PTR f = check_x_frame (frame);
CHOOSEFONT cf; CHOOSEFONT cf;
...@@ -13862,7 +13999,13 @@ Returns an X font string corresponding to the selection. */) ...@@ -13862,7 +13999,13 @@ Returns an X font string corresponding to the selection. */)
cf.lStructSize = sizeof (cf); cf.lStructSize = sizeof (cf);
cf.hwndOwner = FRAME_W32_WINDOW (f); cf.hwndOwner = FRAME_W32_WINDOW (f);
cf.Flags = CF_FORCEFONTEXIST | CF_SCREENFONTS; cf.Flags = CF_FORCEFONTEXIST | CF_SCREENFONTS | CF_NOVERTFONTS;
/* Unless include_proportional is non-nil, limit the selection to
monospaced fonts. */
if (NILP (include_proportional))
cf.Flags |= CF_FIXEDPITCHONLY;
cf.lpLogFont = &lf; cf.lpLogFont = &lf;
/* Initialize as much of the font details as we can from the current /* Initialize as much of the font details as we can from the current
...@@ -13892,9 +14035,9 @@ Returns an X font string corresponding to the selection. */) ...@@ -13892,9 +14035,9 @@ Returns an X font string corresponding to the selection. */)
DEFUN ("w32-send-sys-command", Fw32_send_sys_command, DEFUN ("w32-send-sys-command", Fw32_send_sys_command,
Sw32_send_sys_command, 1, 2, 0, Sw32_send_sys_command, 1, 2, 0,
doc: /* Send frame a Windows WM_SYSCOMMAND message of type COMMAND. doc: /* Send frame a Windows WM_SYSCOMMAND message of type COMMAND.
Some useful values for command are 0xf030 to maximise frame (0xf020 Some useful values for command are #xf030 to maximise frame (#xf020
to minimize), 0xf120 to restore frame to original size, and 0xf100 to minimize), #xf120 to restore frame to original size, and #xf100
to activate the menubar for keyboard access. 0xf140 activates the to activate the menubar for keyboard access. #xf140 activates the
screen saver if defined. screen saver if defined.
If optional parameter FRAME is not specified, use selected frame. */) If optional parameter FRAME is not specified, use selected frame. */)
...@@ -14497,9 +14640,9 @@ respective modifier, or nil to appear as the key `apps'. ...@@ -14497,9 +14640,9 @@ respective modifier, or nil to appear as the key `apps'.
Any other value will cause the key to be ignored. */); Any other value will cause the key to be ignored. */);
Vw32_apps_modifier = Qnil; Vw32_apps_modifier = Qnil;
DEFVAR_LISP ("w32-enable-synthesized-fonts", &Vw32_enable_synthesized_fonts, DEFVAR_BOOL ("w32-enable-synthesized-fonts", &w32_enable_synthesized_fonts,
doc: /* Non-nil enables selection of artificially italicized and bold fonts. */); doc: /* Non-nil enables selection of artificially italicized and bold fonts. */);
Vw32_enable_synthesized_fonts = Qnil; w32_enable_synthesized_fonts = 0;
DEFVAR_LISP ("w32-enable-palette", &Vw32_enable_palette, DEFVAR_LISP ("w32-enable-palette", &Vw32_enable_palette,
doc: /* Non-nil enables Windows palette management to map colors exactly. */); doc: /* Non-nil enables Windows palette management to map colors exactly. */);
......
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