User: aidan
Date: 05/04/01 02:27:26
Branch: xemacs/src sjt-xft
Modified: xemacs/src ChangeLog objects-x.c
Log:
Make the debug messages mule clean, treat FC font names as UTF-8.
Revision Changes Path
1.758.2.22 +14 -0 XEmacs/xemacs/src/ChangeLog
Index: ChangeLog
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/ChangeLog,v
retrieving revision 1.758.2.21
retrieving revision 1.758.2.22
diff -u -p -r1.758.2.21 -r1.758.2.22
--- ChangeLog 2005/03/15 05:23:36 1.758.2.21
+++ ChangeLog 2005/04/01 00:27:18 1.758.2.22
@@ -1,3 +1,17 @@
+2005-04-01 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * objects-x.c:
+ * objects-x.c (x_initialize_font_instance):
+ * objects-x.c (CHECKING_LANG):
+ General mule-sanity cleanup for the debug messages, to eliminate
+ the issue Giacomo Boffi saw in
+ 16970.44359.621213.994821(a)boffi95.stru.polimi.it.
+
+ * objects-x.c (x_find_charset_font):
+ Font names are also treated as UTF-8; relatedly, when passing back
+ the font's full name, the character coverage bitmap isn't included
+ any more, because that would make it an invalid UTF-8 string.
+
2005-03-11 Stephen J. Turnbull <stephen(a)xemacs.org>
* XEmacs 21.5.20 "cilantro" is released.
1.26.2.16 +94 -27 XEmacs/xemacs/src/objects-x.c
Index: objects-x.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/objects-x.c,v
retrieving revision 1.26.2.15
retrieving revision 1.26.2.16
diff -u -p -r1.26.2.15 -r1.26.2.16
--- objects-x.c 2005/03/15 05:24:35 1.26.2.15
+++ objects-x.c 2005/04/01 00:27:22 1.26.2.16
@@ -221,7 +221,8 @@ x_initialize_font_instance (Lisp_Font_In
#ifdef USE_XFT
if (debug_xft > 2)
- stderr_out ("attempting to initialize font spec %s\n", extname);
+ stderr_out ("attempting to initialize font spec %s\n",
+ XSTRING_DATA(f->name));
/* #### serialize (optimize) these later... */
/* #### This function really needs to go away.
The problem is that the fontconfig/Xft functions work much too hard
@@ -288,13 +289,15 @@ x_initialize_font_instance (Lisp_Font_In
stderr_out ("initialized metrics ascent %d descent %d width %d height %d\n",
f->ascent, f->descent, f->width, f->height);
if (debug_xft > 2) /* we also output on initialization of any font below */
- stderr_out ("initialized Xft font %s\n", extname);
+ stderr_out ("initialized Xft font %s\n",
+ XSTRING_DATA(f->name));
fs = NULL; /* we don' need no steenkin' X font */
}
else
{
if (debug_xft > 0)
- stderr_out ("couldn't initialize Xft font %s\n", extname);
+ stderr_out ("couldn't initialize Xft font %s\n",
+ XSTRING_DATA(f->name));
}
#endif
@@ -369,11 +372,11 @@ x_initialize_font_instance (Lisp_Font_In
/* #### check for weirdness */
if (n * f->height < d * f->width)
stderr_out ("font %s: width:height is %d:%d, larger than %d:%d\n",
- extname, f->width, f->height, n, d);
+ XSTRING_DATA(f->name), f->width, f->height, n, d);
if (f->height <= 0 || f->width <= 0)
stderr_out ("bogus dimensions of font %s: width = %d, height = %d\n",
- extname, f->width, f->height);
- stderr_out ("initialized font %s\n", extname);
+ XSTRING_DATA(f->name), f->width, f->height);
+ stderr_out ("initialized font %s\n", XSTRING_DATA(f->name));
}
#else
#undef rf
@@ -1114,12 +1117,19 @@ mule_to_fc_charset (Lisp_Object cs)
/* print an Xft pattern to stderr
LEVEL is the debug level (to compare to debug_xft)
FORMAT is a newline-terminated printf format with one %s for the pattern
- PATTERN is an FcPattern *. */
-#define PRINT_XFT_PATTERN(level,format,pattern) \
- do { \
- FcChar8 *name = FcNameUnparse (pattern); \
- DEBUG_XFT1 (level, format, name); \
- free (name); \
+ PATTERN is an FcPattern *.
+
+ Qbinary is the only coding system that's appropriate; while the font
+ names themselves are UTF-8, the coverage information is a pure bitmap
+ that won't be in any valid multibyte encoding. */
+#define PRINT_XFT_PATTERN(level,format,pattern) \
+ do { \
+ DECLARE_EISTRING (eistrpxft_name); \
+ FcChar8 *name = FcNameUnparse (pattern); \
+ \
+ eicpy_ext(eistrpxft_name, name, Qbinary); \
+ DEBUG_XFT1 (level, format, eidata(eistrpxft_name)); \
+ free (name); \
} while (0)
/* print a progress message
@@ -1127,8 +1137,13 @@ mule_to_fc_charset (Lisp_Object cs)
FORMAT is a newline-terminated printf format with two %s for font and lang
FONT is the Xft font
LANG is the language being checked for support. */
-#define CHECKING_LANG(level,font,lang) \
- DEBUG_XFT2 (level, "checking if %s handles %s\n", font, lang)
+#define CHECKING_LANG(level,font,lang) \
+ do { \
+ DECLARE_EISTRING (eistrcl_name); \
+ eicpy_ext(eistrcl_name, font, Qbinary); \
+ DEBUG_XFT2 (level, "checking if %s handles %s\n", \
+ eidata(eistrcl_name), lang); \
+ } while (0)
struct charset_reporter {
Lisp_Object *charset;
@@ -1195,10 +1210,14 @@ x_find_charset_font (Lisp_Object device,
return Qnil;
#ifdef USE_XFT
- /* #### does Xft permit/require a different encoding? */
- LISP_STRING_TO_EXTERNAL (font, patternext, Qx_font_name_encoding);
+ /* Fontconfig converts all strings to UTF-8 before passing them back to
+ callers--see FcFreeTypeQuery, in fcfreetype.c, for where it does
+ this. I don't believe this is documented. */
+
+ LISP_STRING_TO_EXTERNAL (font, patternext, Qutf_8);
- DEBUG_XFT1 (1, "confirming charset for font instance %s\n", patternext);
+ DEBUG_XFT1 (1, "confirming charset for font instance %s\n",
+ XSTRING_DATA(font));
/* #### this looks like a fair amount of work, but the basic design
has never been rethought, and it should be
@@ -1216,9 +1235,11 @@ x_find_charset_font (Lisp_Object device,
FcChar8 *lang = "en";
FcCharSet *fccs = NULL;
FcChar8 *shortname;
+ DECLARE_EISTRING (eistr_shortname);
fcc = FcConfigGetCurrent ();
patternxft = FcNameParse (patternext); /* #### needs freeing */
+
PRINT_XFT_PATTERN (1,"FcNameParse'ed name is %s\n",patternxft);
/* #### Next two return FcBool, but what does the return mean? */
/* The order is correct according the fontconfig docs. */
@@ -1236,6 +1257,8 @@ x_find_charset_font (Lisp_Object device,
FcPatternDel (p, FC_LANG);
shortname = FcNameUnparse (p); /* #### needs freeing */
FcPatternDestroy (p);
+ eicpy_ext(eistr_shortname, shortname, Qutf_8);
+ free(shortname);
}
/* The language approach may better in the long run, but we can't use
@@ -1254,7 +1277,7 @@ x_find_charset_font (Lisp_Object device,
if (cr->rfc3066)
{
- CHECKING_LANG (0, shortname, cr->language);
+ CHECKING_LANG (0, eidata(eistr_shortname), cr->language);
lang = cr->rfc3066;
}
else if (cr->charset)
@@ -1275,6 +1298,8 @@ x_find_charset_font (Lisp_Object device,
/* default to "en" */
}
+ ASSERT_ASCTEXT_ASCII(lang);
+
if (fccs)
{
/* check for character set coverage */
@@ -1285,6 +1310,7 @@ x_find_charset_font (Lisp_Object device,
if (r == FcResultTypeMismatch)
{
+ free(patternxft);
/* Urk! Fall back and punt to core font. */
DEBUG_XFT0 (0, "Unexpected type return in charset value\n");
/* uncomment this to not try core font */
@@ -1292,14 +1318,43 @@ x_find_charset_font (Lisp_Object device,
}
else if (r == FcResultMatch && FcCharSetIsSubset (fccs, v))
{
- DEBUG_XFT2 (0, "Xft font %s supports %s\n", shortname, lang);
- /* #### would it be better to return shortname? */
- retval = (build_string (FcNameUnparse (patternxft)));
+ FcChar8 *unparsed = FcNameUnparse(patternxft);
+ DECLARE_EISTRING (eistr_longname);
+
+#ifdef __GNUC__
+#warning "Perhaps the shortname won't identify the font uniquely--see comment."
+#endif
+ /* If we're going to use the full font name above, we can't
+ treat it as any other encoding than Qbinary, because the
+ bitmap of character coverage which forms part of it gives
+ no guarantees that it'll encode as anything else.
+
+ However, fontconfig returns foundry and name information in
+ UTF-8. So the shortname above will better correspond to the
+ font's name, because we can treat it as valid UTF-8, and
+ non-ASCII characters will show up properly as Mule
+ characters.
+
+ So, in the interest of getting XEmacs' font selection
+ almost coherent, I'm passing back the short name, as a Lisp
+ String, decoded from UTF-8. */
+
+ eicpy_ext(eistr_longname, unparsed, Qbinary);
+ free(unparsed);
+ free(patternxft);
+
+ DEBUG_XFT2 (0, "Xft font, full specification, %s supports %s\n",
+ eidata(eistr_longname), lang);
+ DEBUG_XFT1 (0, "We're returning the short specification %s, in the interest of preserving the encoding of the font's name. ",
+ eidata(eistr_shortname));
+
+ retval = eimake_string(eistr_shortname);
}
else
{
+ free(patternxft);
DEBUG_XFT2 (0, "Xft font %s doesn't support %s\n",
- shortname, lang);
+ eidata(eistr_shortname), lang);
/* comment this to try the core font */
retval = Qnil;
}
@@ -1316,10 +1371,13 @@ x_find_charset_font (Lisp_Object device,
FcValue v;
/* the main event */
FcResult r = FcPatternGet (patternxft, FC_LANG, i, &v);
+ /* Not using patternxft beyond here. */
+
if (r == FcResultMatch)
{
if (v.type != FcTypeLangSet) /* excessive paranoia */
{
+ ASSERT_ASCTEXT_ASCII(FcTypeOfValueToString(v));
/* Urk! Fall back and punt to core font. */
DEBUG_XFT1 (0, "Unexpected type of lang value (%s)\n",
FcTypeOfValueToString (v));
@@ -1328,23 +1386,32 @@ x_find_charset_font (Lisp_Object device,
}
else if (FcLangSetHasLang (v.u.l, lang) != FcLangDifferentLang)
{
- DEBUG_XFT2 (0, "Xft font %s supports %s\n", shortname, lang);
- /* #### would it be better to return shortname? */
- return (build_string (FcNameUnparse (patternxft)));
+ DEBUG_XFT2 (0, "Xft font %s supports %s\n",
+ eidata(eistr_shortname), lang);
+ free(patternxft);
+ /* #### would it be better to return shortname?
+
+ Aidan says yes. The full pattern with the bitmap
+ coverage is massively unwieldy. */
+
+ return eimake_string(eistr_shortname);
}
else
{
DEBUG_XFT2 (0, "Xft font %s doesn't support %s\n",
- shortname, lang);
+ eidata(eistr_shortname), lang);
return Qnil;
}
}
+ ASSERT_ASCTEXT_ASCII(FcResultToString(r));
DEBUG_XFT1 (0, "Unexpected result getting lang=%s\n",
FcResultToString (r));
+ free(patternxft);
}
}
- DEBUG_XFT1 (0, "shit happens, try X11 charset match for %s\n", patternext);
+ DEBUG_XFT1 (0, "shit happens, try X11 charset match for %s\n",
+ XSTRING_DATA(font));
#endif /* USE_XFT */
names = XListFonts (DEVICE_X_DISPLAY (XDEVICE (device)),