+static int
+compare_font_names (const void *name1, const void *name2)
+{
+ return xstrcasecmp (*(const unsigned char **) name1,
+ *(const unsigned char **) name2);
+}
+
+/* Decode XLFD as iso-8859-1 into OUTPUT, and return the byte length
+ of the decoding result. LEN is the byte length of XLFD, or -1 if
+ XLFD is NULL terminated. The caller must assure that OUTPUT is at
+ least twice (plus 1) as large as XLFD. */
+
+static int
+xfont_decode_coding_xlfd (char *xlfd, int len, char *output)
+{
+ char *p0 = xlfd, *p1 = output;
+ int c;
+
+ while (*p0)
+ {
+ c = *(unsigned char *) p0++;
+ p1 += CHAR_STRING (c, p1);
+ if (--len == 0)
+ break;
+ }
+ *p1 = 0;
+ return (p1 - output);
+}
+
+/* Encode XLFD from UTF-8 to iso-8859-1 destructively, and return the
+ resulting byte length. If XLFD contains unencodable character,
+ return -1. */
+
+static int
+xfont_encode_coding_xlfd (char *xlfd)
+{
+ const unsigned char *p0 = (unsigned char *) xlfd;
+ unsigned char *p1 = (unsigned char *) xlfd;
+ int len = 0;
+
+ while (*p0)
+ {
+ int c = STRING_CHAR_ADVANCE (p0);
+
+ if (c >= 0x100)
+ return -1;
+ *p1++ = c;
+ len++;
+ }
+ *p1 = 0;
+ return len;
+}
+
+/* Check if CHARS (cons or vector) is supported by XFONT whose
+ encoding charset is ENCODING (XFONT is NULL) or by a font whose
+ registry corresponds to ENCODING and REPERTORY.
+ Return 1 if supported, return 0 otherwise. */
+
+static int
+xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont,
+ struct charset *encoding, struct charset *repertory)
+{
+ struct charset *charset = repertory ? repertory : encoding;
+
+ if (CONSP (chars))
+ {
+ for (; CONSP (chars); chars = XCDR (chars))
+ {
+ int c = XINT (XCAR (chars));
+ unsigned code = ENCODE_CHAR (charset, c);
+ XChar2b char2b;
+
+ if (code == CHARSET_INVALID_CODE (charset))
+ break;
+ if (! xfont)
+ continue;
+ if (code >= 0x10000)
+ break;
+ char2b.byte1 = code >> 8;
+ char2b.byte2 = code & 0xFF;
+ if (! xfont_get_pcm (xfont, &char2b))
+ break;
+ }
+ return (NILP (chars));
+ }
+ else if (VECTORP (chars))
+ {
+ int i;
+
+ for (i = ASIZE (chars) - 1; i >= 0; i--)
+ {
+ int c = XINT (AREF (chars, i));
+ unsigned code = ENCODE_CHAR (charset, c);
+ XChar2b char2b;
+
+ if (code == CHARSET_INVALID_CODE (charset))
+ continue;
+ if (! xfont)
+ break;
+ if (code >= 0x10000)
+ continue;
+ char2b.byte1 = code >> 8;
+ char2b.byte2 = code & 0xFF;
+ if (xfont_get_pcm (xfont, &char2b))
+ break;
+ }
+ return (i >= 0);
+ }
+ return 0;
+}
+
+/* A hash table recoding which font supports which scritps. Each key
+ is a vector of characteristic font propertis FOUNDRY to WIDTH and
+ ADDSTYLE, and each value is a list of script symbols.
+
+ We assume that fonts that have the same value in the above
+ properties supports the same set of characters on all displays. */
+
+static Lisp_Object xfont_scripts_cache;
+
+/* Re-usable vector to store characteristic font properites. */
+static Lisp_Object xfont_scratch_props;
+
+extern Lisp_Object Qlatin;
+
+/* Return a list of scripts supported by the font of FONTNAME whose
+ characteristic properties are in PROPS and whose encoding charset
+ is ENCODING. A caller must call BLOCK_INPUT in advance. */
+