Document ASCII limitations of Fc character conversion macros
Fix off-by-one error in utf-8 case walking code. Add FcStrDowncase (useful
    for testing case conversion functions)
diff --git a/ChangeLog b/ChangeLog
index f84e0c4..70228f0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2004-12-29  Keith Packard  <keithp@keithp.com>
 
+	* fontconfig/fontconfig.h:
+	Document ASCII limitations of Fc character conversion macros
+	* src/fcstr.c: (FcStrCaseWalkerLong), (FcStrDowncase):
+	Fix off-by-one error in utf-8 case walking code.
+	Add FcStrDowncase (useful for testing case conversion functions)
+
+2004-12-29  Keith Packard  <keithp@keithp.com>
+
 	* .cvsignore:
 	* fc-case/.cvsignore:
 	clean up CVS ignore lists
diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
index ab312da..f025259 100644
--- a/fontconfig/fontconfig.h
+++ b/fontconfig/fontconfig.h
@@ -749,9 +749,13 @@
 FcChar8 *
 FcStrCopyFilename (const FcChar8 *s);
     
-#define FcIsUpper(c)	(('A' <= (c) && (c) <= 'Z'))
-#define FcIsLower(c)	(('a' <= (c) && (c) <= 'z'))
-#define FcToLower(c)	(FcIsUpper(c) ? (c) - 'A' + 'a' : (c))
+/* These are ASCII only, suitable only for pattern element names */
+#define FcIsUpper(c)	((0101 <= (c) && (c) <= 0132))
+#define FcIsLower(c)	((0141 <= (c) && (c) <= 0172))
+#define FcToLower(c)	(FcIsUpper(c) ? (c) - 0101 + 0141 : (c))
+
+FcChar8 *
+FcStrDowncase (const FcChar8 *s);
 
 int
 FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2);
diff --git a/src/fcstr.c b/src/fcstr.c
index 61f1897..730e440 100644
--- a/src/fcstr.c
+++ b/src/fcstr.c
@@ -92,7 +92,7 @@
     FcChar32	ucs4;
     int		slen;
 
-    slen = FcUtf8ToUcs4 (w->src - 1, &ucs4, w->len);
+    slen = FcUtf8ToUcs4 (w->src - 1, &ucs4, w->len + 1);
     if (slen <= 0)
 	return r;
     if (FC_MIN_FOLD_CHAR <= ucs4 && ucs4 <= FC_MAX_FOLD_CHAR)
@@ -188,6 +188,25 @@
     return r;
 }
 
+FcChar8 *
+FcStrDowncase (const FcChar8 *s)
+{
+    FcCaseWalker    w;
+    int		    len = 0;
+    FcChar8	    *dst, *d;
+
+    FcStrCaseWalkerInit (s, &w);
+    while (FcStrCaseWalkerNext (&w))
+	len++;
+    d = dst = malloc (len + 1);
+    if (!d)
+	return 0;
+    FcMemAlloc (FC_MEM_STRING, len + 1);
+    FcStrCaseWalkerInit (s, &w);
+    while ((*d++ = FcStrCaseWalkerNext (&w)));
+    return dst;
+}
+
 int
 FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
 {