[Fontconfig] msvcport cmake project, patch attached for review

Pavel Koshevoy pkoshevoy at gmail.com
Wed Oct 10 23:22:34 PDT 2012


On 10/10/12 7:58 PM, Pavel Koshevoy wrote:
> On 10/10/2012 07:16 PM, Akira TAGOH wrote:
>> On Thu, Oct 11, 2012 at 3:17 AM, Behdad Esfahbod <behdad at behdad.org> 
>> wrote:
>>> It's not my call anymore, but if it was, I would have straight 
>>> rejected this
>>> patchset.  First, it mixes code and buildsystem changes. Second, it 
>>> adds a
>>> second parallel build system, that is doomed to be outdated most of 
>>> the time...
>> Yes, that's valid point and what I was concerned earlier. that said
>> improving something for the native build on MSVC would be nice. though
>> I still prefer to improve this with autotools as far as possible or
>> just put minimal Makefile as other projects do.
>>
>> I should pointed out more specifically, but this patch could be
>> separate to 1) cmake for MSVC 2) direct.h emulation at least.
>>
>> Aside from how the review is going on, we have to work out on some
>> updates on autotools too since it's our build system and at least it
>> won't be shipped into the archive otherwise.
>>
>> Anyway I can't promise anything so far when it will be merged because
>> it's the sort of big patch, I'll do my best.
>>
>
>
> I could break up this patch into 3 separate patches.
>
> 1st patch to add FcOpen, FcAccess, FcReaddir... etc macros in 
> config-fixups.h and replace system calls with these wrappers
> 2nd patch to add msvcport implementations of FcOpen, FcAccess, 
> FcReaddir...
> 3rd patch to add msvcport/CMakeLists.txt
>
>     Pavel.
>

I've attached 4 patches.  If you think the 0001 patch placing the thin 
wrapper macros in config-fixups.h is inappropriate please suggest where 
I should place those instead (so that the macros would still be visible 
to all source files).

I've made sure that fontconfig compiles without warning after each patch 
is applied.  I've tested on Windows (autotools build on cygwin for 
i686-w64-mingw32 host) and Linux (openSUSE 12.2).

After 0004 patch is applied CMake may be used to generate a native win32 
build.  I've tested with VS2005.

Thank you,
     Pavel.

-------------- next part --------------
From 81bdab35f7fd2cb8b12f6858c98321daa4830533 Mon Sep 17 00:00:00 2001
From: Pavel Koshevoy <pkoshevoy at gmail.com>
Date: Thu, 11 Oct 2012 00:02:25 -0600
Subject: [PATCH 1/4] Add FcOpen, FcReaddir, etc... thin portability layer

Introduce wrapper macros for FcOpen, FcAccess, FcReaddir... in
config-fixups.h and replace system calls with these.  This creates
a thin portability layer and makes it easier to provide platform
specific implementations.
---
 config-fixups.h |   17 +++++++++++++++++
 src/fcatomic.c  |   36 +++++++++++++++++-------------------
 src/fccache.c   |   42 +++++++++++++++++++-----------------------
 src/fccfg.c     |    2 +-
 src/fcdir.c     |    6 +++---
 src/fcint.h     |    2 ++
 src/fcstat.c    |    2 +-
 src/fcxml.c     |   17 +++++++++++------
 8 files changed, 71 insertions(+), 53 deletions(-)

diff --git a/config-fixups.h b/config-fixups.h
index 93ebf5b..fff7754 100644
--- a/config-fixups.h
+++ b/config-fixups.h
@@ -38,3 +38,20 @@
 #  define ALIGNOF_DOUBLE 4
 # endif
 #endif
+
+/* a very thin portability layer */
+#define FcOpendir(x) opendir(x)
+#define FcReaddir(x) readdir(x)
+#define FcClosedir(x) closedir(x)
+
+#ifdef _WIN32
+#define FcMkdir(path, mode) _mkdir(path)
+#else
+#define FcMkdir(x, y) mkdir(x, y)
+#endif
+#define FcRmdir(x) rmdir(x)
+
+#define FcAccess(x, y) access(x, y)
+#define FcChmod(x, y) chmod(x, y)
+#define FcUnlink(x) unlink(x)
+#define FcOpen(x, ...) open(x, __VA_ARGS__)
diff --git a/src/fcatomic.c b/src/fcatomic.c
index 350744a..43c5c70 100644
--- a/src/fcatomic.c
+++ b/src/fcatomic.c
@@ -51,14 +51,12 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif
 #include <stdlib.h>
 #include <time.h>
 
-#ifdef _WIN32
-#define mkdir(path,mode) _mkdir(path)
-#endif
-
 #define NEW_NAME	".NEW"
 #define LCK_NAME	".LCK"
 #define TMP_NAME	".TMP-XXXXXX"
@@ -116,19 +114,19 @@ FcAtomicLock (FcAtomic *atomic)
     if (!f)
     {
     	close (fd);
-	unlink ((char *) atomic->tmp);
+	FcUnlink ((char *) atomic->tmp);
 	return FcFalse;
     }
     ret = fprintf (f, "%ld\n", (long)getpid());
     if (ret <= 0)
     {
 	fclose (f);
-	unlink ((char *) atomic->tmp);
+	FcUnlink ((char *) atomic->tmp);
 	return FcFalse;
     }
     if (fclose (f) == EOF)
     {
-	unlink ((char *) atomic->tmp);
+	FcUnlink ((char *) atomic->tmp);
 	return FcFalse;
     }
     ret = link ((char *) atomic->tmp, (char *) atomic->lck);
@@ -137,12 +135,12 @@ FcAtomicLock (FcAtomic *atomic)
 	/* the filesystem where atomic->lck points to may not supports
 	 * the hard link. so better try to fallback
 	 */
-	ret = mkdir ((char *) atomic->lck, 0600);
+	ret = FcMkdir ((char *) atomic->lck, 0600);
 	no_link = FcTrue;
     }
-    (void) unlink ((char *) atomic->tmp);
+    (void) FcUnlink ((char *) atomic->tmp);
 #else
-    ret = mkdir ((char *) atomic->lck, 0600);
+    ret = FcMkdir ((char *) atomic->lck, 0600);
 #endif
     if (ret < 0)
     {
@@ -160,23 +158,23 @@ FcAtomicLock (FcAtomic *atomic)
 #ifdef HAVE_LINK
 		if (no_link)
 		{
-		    if (rmdir ((char *) atomic->lck) == 0)
+		    if (FcRmdir ((char *) atomic->lck) == 0)
 			return FcAtomicLock (atomic);
 		}
 		else
 		{
-		    if (unlink ((char *) atomic->lck) == 0)
+		    if (FcUnlink ((char *) atomic->lck) == 0)
 			return FcAtomicLock (atomic);
 		}
 #else
-		if (rmdir ((char *) atomic->lck) == 0)
+		if (FcRmdir ((char *) atomic->lck) == 0)
 		    return FcAtomicLock (atomic);
 #endif
 	    }
 	}
 	return FcFalse;
     }
-    (void) unlink ((char *) atomic->new);
+    (void) FcUnlink ((char *) atomic->new);
     return FcTrue;
 }
 
@@ -196,7 +194,7 @@ FcBool
 FcAtomicReplaceOrig (FcAtomic *atomic)
 {
 #ifdef _WIN32
-    unlink ((const char *) atomic->file);
+    FcUnlink ((const char *) atomic->file);
 #endif
     if (rename ((char *) atomic->new, (char *) atomic->file) < 0)
 	return FcFalse;
@@ -206,17 +204,17 @@ FcAtomicReplaceOrig (FcAtomic *atomic)
 void
 FcAtomicDeleteNew (FcAtomic *atomic)
 {
-    unlink ((char *) atomic->new);
+    FcUnlink ((char *) atomic->new);
 }
 
 void
 FcAtomicUnlock (FcAtomic *atomic)
 {
 #ifdef HAVE_LINK
-    if (unlink ((char *) atomic->lck) == -1)
-	rmdir ((char *) atomic->lck);
+    if (FcUnlink ((char *) atomic->lck) == -1)
+	FcRmdir ((char *) atomic->lck);
 #else
-    rmdir ((char *) atomic->lck);
+    FcRmdir ((char *) atomic->lck);
 #endif
 }
 
diff --git a/src/fccache.c b/src/fccache.c
index 81985df..7dd1474 100644
--- a/src/fccache.c
+++ b/src/fccache.c
@@ -131,7 +131,7 @@ FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config)
         cache_hashed = FcStrPlus (cache_dir, cache_base);
         if (!cache_hashed)
 	    break;
-	(void) unlink ((char *) cache_hashed);
+	(void) FcUnlink ((char *) cache_hashed);
 	FcStrFree (cache_hashed);
     }
     FcStrListDone (list);
@@ -150,7 +150,7 @@ FcDirCacheOpenFile (const FcChar8 *cache_file, struct stat *file_stat)
     if (FcStat (cache_file, file_stat) < 0)
         return -1;
 #endif
-    fd = open((char *) cache_file, O_RDONLY | O_BINARY);
+    fd = FcOpen ((char *) cache_file, O_RDONLY | O_BINARY);
     if (fd < 0)
 	return fd;
 #ifndef _WIN32
@@ -802,10 +802,6 @@ bail1:
 }
 
 
-#ifdef _WIN32
-#define mkdir(path,mode) _mkdir(path)
-#endif
-
 static FcBool
 FcMakeDirectory (const FcChar8 *dir)
 {
@@ -818,10 +814,10 @@ FcMakeDirectory (const FcChar8 *dir)
     parent = FcStrDirname (dir);
     if (!parent)
 	return FcFalse;
-    if (access ((char *) parent, F_OK) == 0)
-	ret = mkdir ((char *) dir, 0755) == 0 && chmod ((char *) dir, 0755) == 0;
-    else if (access ((char *) parent, F_OK) == -1)
-	ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0755) == 0) && chmod ((char *) dir, 0755) == 0;
+    if (FcAccess ((char *) parent, F_OK) == 0)
+	ret = FcMkdir ((char *) dir, 0755) == 0 && FcChmod ((char *) dir, 0755) == 0;
+    else if (FcAccess ((char *) parent, F_OK) == -1)
+	ret = FcMakeDirectory (parent) && (FcMkdir ((char *) dir, 0755) == 0) && FcChmod ((char *) dir, 0755) == 0;
     else
 	ret = FcFalse;
     FcStrFree (parent);
@@ -853,7 +849,7 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
     if (!list)
 	return FcFalse;
     while ((test_dir = FcStrListNext (list))) {
-	if (access ((char *) test_dir, W_OK) == 0)
+	if (FcAccess ((char *) test_dir, W_OK) == 0)
 	{
 	    cache_dir = test_dir;
 	    break;
@@ -863,7 +859,7 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
 	    /*
 	     * If the directory doesn't exist, try to create it
 	     */
-	    if (access ((char *) test_dir, F_OK) == -1) {
+	    if (FcAccess ((char *) test_dir, F_OK) == -1) {
 		if (FcMakeDirectory (test_dir))
 		{
 		    cache_dir = test_dir;
@@ -875,7 +871,7 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
 	    /*
 	     * Otherwise, try making it writable
 	     */
-	    else if (chmod ((char *) test_dir, 0755) == 0)
+	    else if (FcChmod ((char *) test_dir, 0755) == 0)
 	    {
 		cache_dir = test_dir;
 		/* Try to create CACHEDIR.TAG too */
@@ -904,7 +900,7 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
     if (!FcAtomicLock (atomic))
 	goto bail3;
 
-    fd = open((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT | O_BINARY, 0666);
+    fd = FcOpen((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT | O_BINARY, 0666);
     if (fd == -1)
 	goto bail4;
 
@@ -978,23 +974,23 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose)
 	fprintf (stderr, "Fontconfig error: %s: out of memory\n", cache_dir);
 	return FcFalse;
     }
-    if (access ((char *) cache_dir, W_OK) != 0)
+    if (FcAccess ((char *) cache_dir, W_OK) != 0)
     {
 	if (verbose || FcDebug () & FC_DBG_CACHE)
 	    printf ("%s: not cleaning %s cache directory\n", cache_dir,
-		    access ((char *) cache_dir, F_OK) == 0 ? "unwritable" : "non-existent");
+		    FcAccess ((char *) cache_dir, F_OK) == 0 ? "unwritable" : "non-existent");
 	goto bail0;
     }
     if (verbose || FcDebug () & FC_DBG_CACHE)
 	printf ("%s: cleaning cache directory\n", cache_dir);
-    d = opendir ((char *) cache_dir);
+    d = FcOpendir ((char *) cache_dir);
     if (!d)
     {
 	perror ((char *) cache_dir);
 	ret = FcFalse;
 	goto bail0;
     }
-    while ((ent = readdir (d)))
+    while ((ent = FcReaddir (d)))
     {
 	FcChar8	*file_name;
 	const FcChar8	*target_dir;
@@ -1025,7 +1021,7 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose)
 	else
 	{
 	    target_dir = FcCacheDir (cache);
-	    if (stat ((char *) target_dir, &target_stat) < 0)
+	    if (FcStat (target_dir, &target_stat) < 0)
 	    {
 		if (verbose || FcDebug () & FC_DBG_CACHE)
 		    printf ("%s: %s: missing directory: %s \n",
@@ -1035,7 +1031,7 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose)
 	}
 	if (remove)
 	{
-	    if (unlink ((char *) file_name) < 0)
+	    if (FcUnlink ((char *) file_name) < 0)
 	    {
 		perror ((char *) file_name);
 		ret = FcFalse;
@@ -1045,7 +1041,7 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose)
         FcStrFree (file_name);
     }
 
-    closedir (d);
+    FcClosedir (d);
   bail0:
     FcStrFree (dir_base);
 
@@ -1368,7 +1364,7 @@ FcDirCacheCreateTagFile (const FcChar8 *cache_dir)
     if (!cache_dir)
 	return FcFalse;
 
-    if (access ((char *) cache_dir, W_OK) == 0)
+    if (FcAccess ((char *) cache_dir, W_OK) == 0)
     {
 	/* Create CACHEDIR.TAG */
 	cache_tag = FcStrPlus (cache_dir, (const FcChar8 *) FC_DIR_SEPARATOR_S "CACHEDIR.TAG");
@@ -1379,7 +1375,7 @@ FcDirCacheCreateTagFile (const FcChar8 *cache_dir)
 	    goto bail1;
 	if (!FcAtomicLock (atomic))
 	    goto bail2;
-	fd = open((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT, 0644);
+	fd = FcOpen((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT, 0644);
 	if (fd == -1)
 	    goto bail3;
 	fp = fdopen(fd, "wb");
diff --git a/src/fccfg.c b/src/fccfg.c
index d3752e5..bc40f2c 100644
--- a/src/fccfg.c
+++ b/src/fccfg.c
@@ -1747,7 +1747,7 @@ FcConfigFileExists (const FcChar8 *dir, const FcChar8 *file)
     strcat ((char *) path, (char *) file);
 
     FcMemAlloc (FC_MEM_STRING, osize);
-    if (access ((char *) path, R_OK) == 0)
+    if (FcAccess ((char *) path, R_OK) == 0)
 	return path;
 
     FcStrFree (path);
diff --git a/src/fcdir.c b/src/fcdir.c
index 2b476e8..a030db4 100644
--- a/src/fcdir.c
+++ b/src/fcdir.c
@@ -168,7 +168,7 @@ FcDirScanConfig (FcFontSet	*set,
     if (FcDebug () & FC_DBG_SCAN)
 	printf ("\tScanning dir %s\n", dir);
 	
-    d = opendir ((char *) dir);
+    d = FcOpendir ((char *) dir);
     if (!d)
     {
 	/* Don't complain about missing directories */
@@ -183,7 +183,7 @@ FcDirScanConfig (FcFontSet	*set,
 	ret = FcFalse;
 	goto bail1;
     }
-    while ((e = readdir (d)))
+    while ((e = FcReaddir (d)))
     {
 	if (e->d_name[0] != '.' && strlen (e->d_name) < FC_MAX_FILE_LEN)
 	{
@@ -209,7 +209,7 @@ FcDirScanConfig (FcFontSet	*set,
 bail2:
     FcStrSetDestroy (files);
 bail1:
-    closedir (d);
+    FcClosedir (d);
 bail:
     if (file)
 	free (file);
diff --git a/src/fcint.h b/src/fcint.h
index c078575..de72cb9 100644
--- a/src/fcint.h
+++ b/src/fcint.h
@@ -41,7 +41,9 @@
 #include <string.h>
 #include <ctype.h>
 #include <errno.h>
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif
 #include <stddef.h>
 #include <sys/types.h>
 #include <sys/stat.h>
diff --git a/src/fcstat.c b/src/fcstat.c
index d8663d0..617abf6 100644
--- a/src/fcstat.c
+++ b/src/fcstat.c
@@ -334,7 +334,7 @@ FcIsFsMmapSafe (int fd)
 FcBool
 FcIsFsMtimeBroken (const FcChar8 *dir)
 {
-    int fd = open ((const char *) dir, O_RDONLY);
+    int fd = FcOpen ((const char *) dir, O_RDONLY);
 
     if (fd != -1)
     {
diff --git a/src/fcxml.c b/src/fcxml.c
index 5edc867..13f0c41 100644
--- a/src/fcxml.c
+++ b/src/fcxml.c
@@ -25,8 +25,9 @@
 #include "fcint.h"
 #include <fcntl.h>
 #include <stdarg.h>
+#ifdef HAVE_DIRENT_H
 #include <dirent.h>
-
+#endif
 #ifdef ENABLE_LIBXML2
 
 #include <libxml/parser.h>
@@ -2764,6 +2765,7 @@ FcConfigParseAndLoadDir (FcConfig	*config,
 			 const FcChar8	*dir,
 			 FcBool		complain)
 {
+#ifdef HAVE_DIRENT_H
     DIR		    *d;
     struct dirent   *e;
     FcBool	    ret = FcTrue;
@@ -2771,7 +2773,7 @@ FcConfigParseAndLoadDir (FcConfig	*config,
     FcChar8	    *base;
     FcStrSet	    *files;
 
-    d = opendir ((char *) dir);
+    d = FcOpendir ((char *) dir);
     if (!d)
     {
 	if (complain)
@@ -2801,8 +2803,8 @@ FcConfigParseAndLoadDir (FcConfig	*config,
 
     if (FcDebug () & FC_DBG_CONFIG)
 	printf ("\tScanning config dir %s\n", dir);
-	
-    while (ret && (e = readdir (d)))
+
+    while (ret && (e = FcReaddir (d)))
     {
 	int d_len;
 #define TAIL	    ".conf"
@@ -2836,9 +2838,12 @@ bail3:
 bail2:
     free (file);
 bail1:
-    closedir (d);
+    FcClosedir (d);
 bail0:
     return ret || !complain;
+#else
+#error missing dirent.h
+#endif
 }
 
 #ifdef _WIN32
@@ -2908,7 +2913,7 @@ FcConfigParseAndLoad (FcConfig	    *config,
     if (FcDebug () & FC_DBG_CONFIG)
 	printf ("\tLoading config file %s\n", filename);
 
-    fd = open ((char *) filename, O_RDONLY);
+    fd = FcOpen ((char *) filename, O_RDONLY);
     if (fd == -1) {
 	FcStrFree (filename);
 	goto bail0;
-- 
1.7.9
-------------- next part --------------
From e3236410cfbcc4e9c88a2a5c7ff6dd078c4bfb31 Mon Sep 17 00:00:00 2001
From: Pavel Koshevoy <pkoshevoy at gmail.com>
Date: Thu, 11 Oct 2012 00:04:43 -0600
Subject: [PATCH 2/4] Add msvcport folder for native compilation with MSVC

Add platform specific implementation of FcOpen, FcAccess, etc.. to
enable native Win32 compilation using Visual Studio or Windows SDK.

Also, Win32 lacks snprintf, so use _snprintf_s instead.
---
 config-fixups.h             |   28 ++--
 msvcport/config.h           |  294 +++++++++++++++++++++++++++++++++++++++++
 msvcport/dirent.h           |    8 +
 msvcport/fcalias.h          |    1 +
 msvcport/fcaliastail.h      |    1 +
 msvcport/fcftalias.h        |    1 +
 msvcport/fcftaliastail.h    |    1 +
 msvcport/fontconfig.pc.in   |   16 +++
 msvcport/inttypes.h         |  305 ++++++++++++++++++++++++++++++++++++++++++
 msvcport/msvcport.h         |   21 +++
 msvcport/msvcport_private.c |  306 +++++++++++++++++++++++++++++++++++++++++++
 msvcport/msvcport_private.h |   63 +++++++++
 msvcport/stdint.h           |  247 ++++++++++++++++++++++++++++++++++
 src/fcformat.c              |    4 +
 14 files changed, 1283 insertions(+), 13 deletions(-)
 create mode 100644 msvcport/config.h
 create mode 100644 msvcport/dirent.h
 create mode 100644 msvcport/fcalias.h
 create mode 100644 msvcport/fcaliastail.h
 create mode 100644 msvcport/fcftalias.h
 create mode 100644 msvcport/fcftaliastail.h
 create mode 100644 msvcport/fontconfig.pc.in
 create mode 100644 msvcport/inttypes.h
 create mode 100644 msvcport/msvcport.h
 create mode 100644 msvcport/msvcport_private.c
 create mode 100644 msvcport/msvcport_private.h
 create mode 100644 msvcport/stdint.h

diff --git a/config-fixups.h b/config-fixups.h
index fff7754..76a4723 100644
--- a/config-fixups.h
+++ b/config-fixups.h
@@ -40,18 +40,20 @@
 #endif
 
 /* a very thin portability layer */
-#define FcOpendir(x) opendir(x)
-#define FcReaddir(x) readdir(x)
-#define FcClosedir(x) closedir(x)
-
-#ifdef _WIN32
-#define FcMkdir(path, mode) _mkdir(path)
+#if defined(_WIN32) && defined(_MSC_VER)
+# include "msvcport.h"
 #else
-#define FcMkdir(x, y) mkdir(x, y)
+# define FcOpendir(x) opendir(x)
+# define FcReaddir(x) readdir(x)
+# define FcClosedir(x) closedir(x)
+# ifdef _WIN32
+#  define FcMkdir(path, mode) _mkdir(path)
+# else
+#  define FcMkdir(x, y) mkdir(x, y)
+# endif
+# define FcRmdir(x) rmdir(x)
+# define FcAccess(x, y) access(x, y)
+# define FcChmod(x, y) chmod(x, y)
+# define FcUnlink(x) unlink(x)
+# define FcOpen(x, ...) open(x, __VA_ARGS__)
 #endif
-#define FcRmdir(x) rmdir(x)
-
-#define FcAccess(x, y) access(x, y)
-#define FcChmod(x, y) chmod(x, y)
-#define FcUnlink(x) unlink(x)
-#define FcOpen(x, ...) open(x, __VA_ARGS__)
diff --git a/msvcport/config.h b/msvcport/config.h
new file mode 100644
index 0000000..514127f
--- /dev/null
+++ b/msvcport/config.h
@@ -0,0 +1,294 @@
+/* config.h.  Generated from config.h.in by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* The normal alignment of `double', in bytes. */
+#define ALIGNOF_DOUBLE 8
+
+/* Use libxml2 instead of Expat */
+/* #undef ENABLE_LIBXML2 */
+
+/* Additional font directories */
+#define FC_ADD_FONTS "yes"
+
+/* Architecture prefix to use for cache file names */
+/* #undef FC_ARCHITECTURE */
+
+/* System font directory */
+#define FC_DEFAULT_FONTS "WINDOWSFONTDIR"
+
+/* Define to nothing if C supports flexible array members, and to 1 if it does
+   not. That way, with a declaration like `struct s { int n; double
+   d[FLEXIBLE_ARRAY_MEMBER]; };', the struct hack can be used with pre-C99
+   compilers. When computing the size of such an object, don't use 'sizeof
+   (struct s)' as it overestimates the size. Use 'offsetof (struct s, d)'
+   instead. Don't use 'offsetof (struct s, d[0])', as this doesn't work with
+   MSVC and with C++ compilers. */
+#define FLEXIBLE_ARRAY_MEMBER 1
+
+/* Define to 1 if you have the `chsize' function. */
+#define HAVE_CHSIZE 1
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+   */
+#define HAVE_DIRENT_H 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+/* #undef HAVE_DLFCN_H */
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+/* #undef HAVE_DOPRNT */
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `fstatfs' function. */
+/* #undef HAVE_FSTATFS */
+
+/* Define to 1 if you have the `fstatvfs' function. */
+/* #undef HAVE_FSTATVFS */
+
+/* Define to 1 if you have the `ftruncate' function. */
+#define HAVE_FTRUNCATE 1
+
+/* FT_Bitmap_Size structure includes y_ppem field */
+#define HAVE_FT_BITMAP_SIZE_Y_PPEM 1
+
+/* Define to 1 if you have the `FT_Get_BDF_Property' function. */
+#define HAVE_FT_GET_BDF_PROPERTY 1
+
+/* Define to 1 if you have the `FT_Get_Next_Char' function. */
+#define HAVE_FT_GET_NEXT_CHAR 1
+
+/* Define to 1 if you have the `FT_Get_PS_Font_Info' function. */
+#define HAVE_FT_GET_PS_FONT_INFO 1
+
+/* Define to 1 if you have the `FT_Get_X11_Font_Format' function. */
+#define HAVE_FT_GET_X11_FONT_FORMAT 1
+
+/* Define to 1 if you have the `FT_Has_PS_Glyph_Names' function. */
+#define HAVE_FT_HAS_PS_GLYPH_NAMES 1
+
+/* Define to 1 if you have the `FT_Select_Size' function. */
+#define HAVE_FT_SELECT_SIZE 1
+
+/* Define to 1 if you have the `geteuid' function. */
+/* #undef HAVE_GETEUID */
+
+/* Define to 1 if you have the `getopt' function. */
+#define HAVE_GETOPT 1
+
+/* Define to 1 if you have the `getopt_long' function. */
+#define HAVE_GETOPT_LONG 1
+
+/* Define to 1 if you have the `getpagesize' function. */
+#define HAVE_GETPAGESIZE 1
+
+/* Define to 1 if you have the `getuid' function. */
+/* #undef HAVE_GETUID */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `link' function. */
+/* #undef HAVE_LINK */
+
+/* Define to 1 if you have the `lrand48' function. */
+/* #undef HAVE_LRAND48 */
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `memset' function. */
+#define HAVE_MEMSET 1
+
+/* Define to 1 if you have the `mkstemp' function. */
+/* #undef HAVE_MKSTEMP */
+
+/* Define to 1 if you have a working `mmap' system call. */
+/* #undef HAVE_MMAP */
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+/* #undef HAVE_NDIR_H */
+
+/* Define to 1 if you have the `posix_fadvise' function. */
+/* #undef HAVE_POSIX_FADVISE */
+
+/* Define to 1 if you have the `rand' function. */
+#define HAVE_RAND 1
+
+/* Define to 1 if you have the `random' function. */
+/* #undef HAVE_RANDOM */
+
+/* Define to 1 if you have the `random_r' function. */
+/* #undef HAVE_RANDOM_R */
+
+/* Define to 1 if you have the `rand_r' function. */
+/* #undef HAVE_RAND_R */
+
+/* Define to 1 if you have the `regcomp' function. */
+/* #undef HAVE_REGCOMP */
+
+/* Define to 1 if you have the `regerror' function. */
+/* #undef HAVE_REGERROR */
+
+/* Define to 1 if you have the `regexec' function. */
+/* #undef HAVE_REGEXEC */
+
+/* Define to 1 if you have the <regex.h> header file. */
+/* #undef HAVE_REGEX_H */
+
+/* Define to 1 if you have the `regfree' function. */
+/* #undef HAVE_REGFREE */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strchr' function. */
+#define HAVE_STRCHR 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strrchr' function. */
+#define HAVE_STRRCHR 1
+
+/* Define to 1 if you have the `strtol' function. */
+#define HAVE_STRTOL 1
+
+/* Define to 1 if `d_type' is a member of `struct dirent'. */
+/* #undef HAVE_STRUCT_DIRENT_D_TYPE */
+
+/* Define to 1 if `f_flags' is a member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_FLAGS */
+
+/* Define to 1 if `f_fstypename' is a member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_FSTYPENAME */
+
+/* Define to 1 if `f_basetype' is a member of `struct statvfs'. */
+/* #undef HAVE_STRUCT_STATVFS_F_BASETYPE */
+
+/* Define to 1 if `f_fstypename' is a member of `struct statvfs'. */
+/* #undef HAVE_STRUCT_STATVFS_F_FSTYPENAME */
+
+/* Define to 1 if you have the `sysconf' function. */
+/* #undef HAVE_SYSCONF */
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+   */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define to 1 if you have the <sys/mount.h> header file. */
+/* #undef HAVE_SYS_MOUNT_H */
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+   */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+/* #define HAVE_SYS_PARAM_H 1 */
+
+/* Define to 1 if you have the <sys/statfs.h> header file. */
+/* #undef HAVE_SYS_STATFS_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/vfs.h> header file. */
+/* #undef HAVE_SYS_VFS_H */
+
+/* Define to 1 if you have the <unistd.h> header file. */
+/* #define HAVE_UNISTD_H 1 */
+
+/* Define to 1 if you have the `vprintf' function. */
+#define HAVE_VPRINTF 1
+
+/* Can use #warning in C files */
+#define HAVE_WARNING_CPP_DIRECTIVE 1
+
+/* Use xmlparse.h instead of expat.h */
+/* #undef HAVE_XMLPARSE_H */
+
+/* Define to 1 if you have the `XML_SetDoctypeDeclHandler' function. */
+#define HAVE_XML_SETDOCTYPEDECLHANDLER 1
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "fontconfig"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME ""
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING ""
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME ""
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION ""
+
+/* The size of `void *', as computed by sizeof. */
+#define SIZEOF_VOID_P 4
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Use iconv. */
+#define USE_ICONV 1
+
+/* Use regex */
+/* #undef USE_REGEX */
+
+/* Version number of package */
+#define VERSION "2.10.1"
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* #  undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef pid_t */
+
+#include "config-fixups.h"
+#include "msvcport.h"
diff --git a/msvcport/dirent.h b/msvcport/dirent.h
new file mode 100644
index 0000000..b045938
--- /dev/null
+++ b/msvcport/dirent.h
@@ -0,0 +1,8 @@
+/* -*- Mode: c++; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+
+#ifndef FONTCONFIG_DIRENT_H_
+#define FONTCONFIG_DIRENT_H_
+
+#include "msvcport.h"
+
+#endif /* FONTCONFIG_DIRENT_H_ */
diff --git a/msvcport/fcalias.h b/msvcport/fcalias.h
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/msvcport/fcalias.h
@@ -0,0 +1 @@
+
diff --git a/msvcport/fcaliastail.h b/msvcport/fcaliastail.h
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/msvcport/fcaliastail.h
@@ -0,0 +1 @@
+
diff --git a/msvcport/fcftalias.h b/msvcport/fcftalias.h
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/msvcport/fcftalias.h
@@ -0,0 +1 @@
+
diff --git a/msvcport/fcftaliastail.h b/msvcport/fcftaliastail.h
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/msvcport/fcftaliastail.h
@@ -0,0 +1 @@
+
diff --git a/msvcport/fontconfig.pc.in b/msvcport/fontconfig.pc.in
new file mode 100644
index 0000000..9d5470f
--- /dev/null
+++ b/msvcport/fontconfig.pc.in
@@ -0,0 +1,16 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+sysconfdir=${prefix}/etc
+localstatedir=${prefix}/var
+PACKAGE=fontconfig
+confdir=${sysconfdir}/fonts
+cachedir=WINDOWSTEMPDIR_FONTCONFIG_CACHE
+
+Name: Fontconfig
+Description: Font configuration and customization library
+Version: @FONTCONFIG_VERSION@
+Libs: -L${libdir} -lfontconfig
+Libs.private:  -L${libdir} -lexpat -L${libdir} -lfreetype -L${libdir} -liconv
+Cflags: -I${includedir}
diff --git a/msvcport/inttypes.h b/msvcport/inttypes.h
new file mode 100644
index 0000000..4b3828a
--- /dev/null
+++ b/msvcport/inttypes.h
@@ -0,0 +1,305 @@
+// ISO C9x  compliant inttypes.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
+// 
+//  Copyright (c) 2006 Alexander Chemeris
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+//   1. Redistributions of source code must retain the above copyright notice,
+//      this list of conditions and the following disclaimer.
+// 
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+// 
+//   3. The name of the author may be used to endorse or promote products
+//      derived from this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// 
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_INTTYPES_H_ // [
+#define _MSC_INTTYPES_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include "stdint.h"
+
+// 7.8 Format conversion of integer types
+
+typedef struct {
+   intmax_t quot;
+   intmax_t rem;
+} imaxdiv_t;
+
+// 7.8.1 Macros for format specifiers
+
+#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [   See footnote 185 at page 198
+
+// The fprintf macros for signed integers are:
+#define PRId8       "d"
+#define PRIi8       "i"
+#define PRIdLEAST8  "d"
+#define PRIiLEAST8  "i"
+#define PRIdFAST8   "d"
+#define PRIiFAST8   "i"
+
+#define PRId16       "hd"
+#define PRIi16       "hi"
+#define PRIdLEAST16  "hd"
+#define PRIiLEAST16  "hi"
+#define PRIdFAST16   "hd"
+#define PRIiFAST16   "hi"
+
+#define PRId32       "I32d"
+#define PRIi32       "I32i"
+#define PRIdLEAST32  "I32d"
+#define PRIiLEAST32  "I32i"
+#define PRIdFAST32   "I32d"
+#define PRIiFAST32   "I32i"
+
+#define PRId64       "I64d"
+#define PRIi64       "I64i"
+#define PRIdLEAST64  "I64d"
+#define PRIiLEAST64  "I64i"
+#define PRIdFAST64   "I64d"
+#define PRIiFAST64   "I64i"
+
+#define PRIdMAX     "I64d"
+#define PRIiMAX     "I64i"
+
+#define PRIdPTR     "Id"
+#define PRIiPTR     "Ii"
+
+// The fprintf macros for unsigned integers are:
+#define PRIo8       "o"
+#define PRIu8       "u"
+#define PRIx8       "x"
+#define PRIX8       "X"
+#define PRIoLEAST8  "o"
+#define PRIuLEAST8  "u"
+#define PRIxLEAST8  "x"
+#define PRIXLEAST8  "X"
+#define PRIoFAST8   "o"
+#define PRIuFAST8   "u"
+#define PRIxFAST8   "x"
+#define PRIXFAST8   "X"
+
+#define PRIo16       "ho"
+#define PRIu16       "hu"
+#define PRIx16       "hx"
+#define PRIX16       "hX"
+#define PRIoLEAST16  "ho"
+#define PRIuLEAST16  "hu"
+#define PRIxLEAST16  "hx"
+#define PRIXLEAST16  "hX"
+#define PRIoFAST16   "ho"
+#define PRIuFAST16   "hu"
+#define PRIxFAST16   "hx"
+#define PRIXFAST16   "hX"
+
+#define PRIo32       "I32o"
+#define PRIu32       "I32u"
+#define PRIx32       "I32x"
+#define PRIX32       "I32X"
+#define PRIoLEAST32  "I32o"
+#define PRIuLEAST32  "I32u"
+#define PRIxLEAST32  "I32x"
+#define PRIXLEAST32  "I32X"
+#define PRIoFAST32   "I32o"
+#define PRIuFAST32   "I32u"
+#define PRIxFAST32   "I32x"
+#define PRIXFAST32   "I32X"
+
+#define PRIo64       "I64o"
+#define PRIu64       "I64u"
+#define PRIx64       "I64x"
+#define PRIX64       "I64X"
+#define PRIoLEAST64  "I64o"
+#define PRIuLEAST64  "I64u"
+#define PRIxLEAST64  "I64x"
+#define PRIXLEAST64  "I64X"
+#define PRIoFAST64   "I64o"
+#define PRIuFAST64   "I64u"
+#define PRIxFAST64   "I64x"
+#define PRIXFAST64   "I64X"
+
+#define PRIoMAX     "I64o"
+#define PRIuMAX     "I64u"
+#define PRIxMAX     "I64x"
+#define PRIXMAX     "I64X"
+
+#define PRIoPTR     "Io"
+#define PRIuPTR     "Iu"
+#define PRIxPTR     "Ix"
+#define PRIXPTR     "IX"
+
+// The fscanf macros for signed integers are:
+#define SCNd8       "d"
+#define SCNi8       "i"
+#define SCNdLEAST8  "d"
+#define SCNiLEAST8  "i"
+#define SCNdFAST8   "d"
+#define SCNiFAST8   "i"
+
+#define SCNd16       "hd"
+#define SCNi16       "hi"
+#define SCNdLEAST16  "hd"
+#define SCNiLEAST16  "hi"
+#define SCNdFAST16   "hd"
+#define SCNiFAST16   "hi"
+
+#define SCNd32       "ld"
+#define SCNi32       "li"
+#define SCNdLEAST32  "ld"
+#define SCNiLEAST32  "li"
+#define SCNdFAST32   "ld"
+#define SCNiFAST32   "li"
+
+#define SCNd64       "I64d"
+#define SCNi64       "I64i"
+#define SCNdLEAST64  "I64d"
+#define SCNiLEAST64  "I64i"
+#define SCNdFAST64   "I64d"
+#define SCNiFAST64   "I64i"
+
+#define SCNdMAX     "I64d"
+#define SCNiMAX     "I64i"
+
+#ifdef _WIN64 // [
+#  define SCNdPTR     "I64d"
+#  define SCNiPTR     "I64i"
+#else  // _WIN64 ][
+#  define SCNdPTR     "ld"
+#  define SCNiPTR     "li"
+#endif  // _WIN64 ]
+
+// The fscanf macros for unsigned integers are:
+#define SCNo8       "o"
+#define SCNu8       "u"
+#define SCNx8       "x"
+#define SCNX8       "X"
+#define SCNoLEAST8  "o"
+#define SCNuLEAST8  "u"
+#define SCNxLEAST8  "x"
+#define SCNXLEAST8  "X"
+#define SCNoFAST8   "o"
+#define SCNuFAST8   "u"
+#define SCNxFAST8   "x"
+#define SCNXFAST8   "X"
+
+#define SCNo16       "ho"
+#define SCNu16       "hu"
+#define SCNx16       "hx"
+#define SCNX16       "hX"
+#define SCNoLEAST16  "ho"
+#define SCNuLEAST16  "hu"
+#define SCNxLEAST16  "hx"
+#define SCNXLEAST16  "hX"
+#define SCNoFAST16   "ho"
+#define SCNuFAST16   "hu"
+#define SCNxFAST16   "hx"
+#define SCNXFAST16   "hX"
+
+#define SCNo32       "lo"
+#define SCNu32       "lu"
+#define SCNx32       "lx"
+#define SCNX32       "lX"
+#define SCNoLEAST32  "lo"
+#define SCNuLEAST32  "lu"
+#define SCNxLEAST32  "lx"
+#define SCNXLEAST32  "lX"
+#define SCNoFAST32   "lo"
+#define SCNuFAST32   "lu"
+#define SCNxFAST32   "lx"
+#define SCNXFAST32   "lX"
+
+#define SCNo64       "I64o"
+#define SCNu64       "I64u"
+#define SCNx64       "I64x"
+#define SCNX64       "I64X"
+#define SCNoLEAST64  "I64o"
+#define SCNuLEAST64  "I64u"
+#define SCNxLEAST64  "I64x"
+#define SCNXLEAST64  "I64X"
+#define SCNoFAST64   "I64o"
+#define SCNuFAST64   "I64u"
+#define SCNxFAST64   "I64x"
+#define SCNXFAST64   "I64X"
+
+#define SCNoMAX     "I64o"
+#define SCNuMAX     "I64u"
+#define SCNxMAX     "I64x"
+#define SCNXMAX     "I64X"
+
+#ifdef _WIN64 // [
+#  define SCNoPTR     "I64o"
+#  define SCNuPTR     "I64u"
+#  define SCNxPTR     "I64x"
+#  define SCNXPTR     "I64X"
+#else  // _WIN64 ][
+#  define SCNoPTR     "lo"
+#  define SCNuPTR     "lu"
+#  define SCNxPTR     "lx"
+#  define SCNXPTR     "lX"
+#endif  // _WIN64 ]
+
+#endif // __STDC_FORMAT_MACROS ]
+
+// 7.8.2 Functions for greatest-width integer types
+
+// 7.8.2.1 The imaxabs function
+#define imaxabs _abs64
+
+// 7.8.2.2 The imaxdiv function
+
+// This is modified version of div() function from Microsoft's div.c found
+// in %MSVC.NET%\crt\src\div.c
+#ifdef STATIC_IMAXDIV // [
+static
+#else // STATIC_IMAXDIV ][
+_inline
+#endif // STATIC_IMAXDIV ]
+imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
+{
+   imaxdiv_t result;
+
+   result.quot = numer / denom;
+   result.rem = numer % denom;
+
+   if (numer < 0 && result.rem > 0) {
+      // did division wrong; must fix up
+      ++result.quot;
+      result.rem -= denom;
+   }
+
+   return result;
+}
+
+// 7.8.2.3 The strtoimax and strtoumax functions
+#define strtoimax _strtoi64
+#define strtoumax _strtoui64
+
+// 7.8.2.4 The wcstoimax and wcstoumax functions
+#define wcstoimax _wcstoi64
+#define wcstoumax _wcstoui64
+
+
+#endif // _MSC_INTTYPES_H_ ]
diff --git a/msvcport/msvcport.h b/msvcport/msvcport.h
new file mode 100644
index 0000000..0ff6bf8
--- /dev/null
+++ b/msvcport/msvcport.h
@@ -0,0 +1,21 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+
+#ifndef FONTCONFIG_MSVCPORT_H_
+#define FONTCONFIG_MSVCPORT_H_
+
+#include "msvcport_private.h"
+
+#define FcOpendir(x) fc_msvcport_opendir(x)
+#define FcReaddir(x) fc_msvcport_readdir(x)
+#define FcClosedir(x) fc_msvcport_closedir(x)
+
+#define FcMkdir(x, y) fc_msvcport_mkdir(x, y)
+#define FcRmdir(x) fc_msvcport_rmdir(x)
+
+#define FcAccess(x, y) fc_msvcport_access(x, y)
+#define FcChmod(x, y) fc_msvcport_chmod(x, y)
+#define FcUnlink(x) fc_msvcport_unlink(x)
+#define FcOpen(x, y, ...) fc_msvcport_open(x, y, __VA_ARGS__)
+
+
+#endif /* FONTCONFIG_MSVCPORT_H_ */
diff --git a/msvcport/msvcport_private.c b/msvcport/msvcport_private.c
new file mode 100644
index 0000000..0b314aa
--- /dev/null
+++ b/msvcport/msvcport_private.c
@@ -0,0 +1,306 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+#if defined(_WIN32)
+
+#ifndef __STDC_CONSTANT_MACROS
+#define __STDC_CONSTANT_MACROS
+#endif
+
+#ifndef _FILE_OFFSET_BITS
+#define _FILE_OFFSET_BITS 64
+#endif
+
+#include <windows.h>
+#include <io.h>
+#include <winnls.h>
+#include <wchar.h>
+#include <share.h>
+
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "msvcport_private.h"
+
+wchar_t *
+fc_utf8_to_utf16(const char * cstr)
+{
+    int sz = MultiByteToWideChar(CP_UTF8, 0, cstr, -1, NULL, 0);
+    wchar_t * wstr = (wchar_t *)malloc(sz * sizeof(wchar_t));
+    MultiByteToWideChar(CP_UTF8, 0, cstr, -1, wstr, sz);
+    return wstr;
+}
+
+char *
+fc_utf16_to_utf8(const wchar_t * wstr)
+{
+    int sz = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
+    char * cstr = (char *)malloc(sz);
+    WideCharToMultiByte(CP_UTF8, 0, wstr, -1, cstr, sz, NULL, NULL);
+    return cstr;
+}
+
+
+struct TDir
+{
+    struct dirent         dirent_;
+    intptr_t              handle_;
+    struct _wfinddata64_t dfound_;
+    int                   nfound_;
+    wchar_t *             wquery_;
+};
+
+static void
+TDirInit(struct TDir * d)
+{
+    memset(d, 0, sizeof(struct TDir));
+}
+
+static int
+TDirClose(struct TDir * d)
+{
+    if (d->handle_)
+    {
+        int err = _findclose(d->handle_);
+        memset(&d->dirent_, 0, sizeof(d->dirent_));
+        d->nfound_ = 0;
+        free(d->wquery_);
+        d->wquery_ = NULL;
+        return err;
+    }
+
+    return 0;
+}
+
+static int
+TDirOpen(struct TDir * d, const char * path)
+{
+    size_t pathLen = strlen(path);
+    size_t queryLen = pathLen;
+
+    char * query = (char *)malloc(pathLen + 3);
+    memcpy(query, path, queryLen);
+
+    if (!pathLen || !strchr("\\/", path[pathLen - 1]))
+    {
+        query[queryLen++] = '/';
+    }
+
+    query[queryLen++] = '*';
+    query[queryLen] = 0;
+
+    TDirClose(d);
+    d->wquery_ = fc_utf8_to_utf16(query);
+    free(query);
+    query = NULL;
+
+    if (!d->wquery_)
+    {
+        return 0;
+    }
+
+    d->handle_ = _wfindfirst64(d->wquery_, &d->dfound_);
+    if (d->handle_)
+    {
+        return 1;
+    }
+
+    return 0;
+}
+
+static void
+TDirLoad(struct TDir * d)
+{
+    static const size_t nameMax = sizeof(d->dirent_.d_name);
+    char * name = fc_utf16_to_utf8(d->dfound_.name);
+    size_t nameLen = strlen(name);
+    size_t copyLen = nameLen < nameMax ? nameLen : nameMax;
+    strncpy_s(d->dirent_.d_name, nameMax, name, copyLen);
+    free(name);
+}
+
+static int
+TDirNext(struct TDir * d)
+{
+    if (!d->handle_ || d->nfound_ < 0)
+    {
+        return 0;
+    }
+
+    TDirLoad(d);
+
+    if (_wfindnext64(d->handle_, &d->dfound_) == -1)
+    {
+        d->nfound_ = -1;
+    }
+    else
+    {
+        d->nfound_ ++;
+    }
+
+    return 1;
+}
+
+
+void *
+fc_msvcport_opendir(const char * path)
+{
+    struct TDir * dir = (struct TDir *)malloc(sizeof(struct TDir));
+    TDirInit(dir);
+
+    if (TDirOpen(dir, path))
+    {
+        return dir;
+    }
+
+    TDirClose(dir);
+    free(dir);
+    return NULL;
+}
+
+int
+fc_msvcport_closedir(void * priv)
+{
+    struct TDir * dir = (struct TDir *)priv;
+    if (!dir)
+    {
+        return -1;
+    }
+
+    TDirClose(dir);
+    free(dir);
+    return 0;
+}
+
+struct dirent *
+fc_msvcport_readdir(void * priv)
+{
+    struct TDir * dir = (struct TDir *)priv;
+    if (dir && TDirNext(dir))
+    {
+        return &(dir->dirent_);
+    }
+
+    return NULL;
+}
+
+int
+fc_msvcport_mkdir(const char * path, int mode)
+{
+    wchar_t * tmp = fc_utf8_to_utf16(path);
+    int r = _wmkdir(tmp);
+    free(tmp);
+    return r;
+}
+
+int
+fc_msvcport_rmdir(const char * path)
+{
+    wchar_t * tmp = fc_utf8_to_utf16(path);
+    int r = _wrmdir(tmp);
+    free(tmp);
+    return r;
+}
+
+int
+fc_msvcport_access(const char * path, int perms)
+{
+    /* X_OK (01) permission causes fatal error in win32 _access(..),
+       therefore it must be excluded from the permission bitmask: */
+    int wperms = perms & ~1;
+
+    wchar_t * tmp = fc_utf8_to_utf16(path);
+    int r = _waccess(tmp, wperms);
+    free(tmp);
+    return r;
+}
+
+int
+fc_msvcport_chmod(const char * path, int unixPerms)
+{
+    wchar_t * tmp = fc_utf8_to_utf16(path);
+    int permissions = 0;
+    int ret = 0;
+
+    if (unixPerms & 0444)
+    {
+        permissions |= _S_IREAD;
+    }
+
+    if (unixPerms & 0222)
+    {
+        permissions |= _S_IWRITE;
+    }
+
+    ret = _wchmod(tmp, permissions);
+    free(tmp);
+    return ret;
+}
+
+int
+fc_msvcport_rename(const char * fnOld, const char * fnNew)
+{
+    wchar_t * wold = fc_utf8_to_utf16(fnOld);
+    wchar_t * wnew = fc_utf8_to_utf16(fnNew);
+
+    int ret = _wrename(wold, wnew);
+
+    free(wold);
+    free(wnew);
+    return ret;
+}
+
+int
+fc_msvcport_unlink(const char * path)
+{
+    wchar_t * tmp = fc_utf8_to_utf16(path);
+    int r = _wunlink(tmp);
+    free(tmp);
+    return r;
+}
+
+int
+fc_msvcport_open(const char * filenameUtf8, int accessMode, ...)
+{
+    int waccessMode = accessMode | O_BINARY;
+
+    wchar_t * wname = fc_utf8_to_utf16(filenameUtf8);
+    int fd = -1;
+    int sh = accessMode & (_O_RDWR | _O_WRONLY) ? _SH_DENYWR : _SH_DENYNO;
+    int permissions = _S_IREAD;
+    errno_t err = 0;
+
+    if ((accessMode & _O_CREAT) != 0)
+    {
+        int unixPerms = 0644;
+        va_list ap;
+        va_start(ap, accessMode);
+        unixPerms = va_arg(ap, int);
+
+        permissions = 0;
+        if (unixPerms & 0444)
+        {
+            permissions |= _S_IREAD;
+        }
+
+        if (unixPerms & 0222)
+        {
+            permissions |= _S_IWRITE;
+        }
+
+        if (unixPerms & 0111)
+        {
+            permissions |= _S_IEXEC;
+        }
+
+        va_end(ap);
+    }
+
+    err = _wsopen_s(&fd, wname, waccessMode, sh, permissions);
+    free(wname);
+
+    return fd;
+}
+
+
+#endif /* _WIN32 */
diff --git a/msvcport/msvcport_private.h b/msvcport/msvcport_private.h
new file mode 100644
index 0000000..f156cb3
--- /dev/null
+++ b/msvcport/msvcport_private.h
@@ -0,0 +1,63 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+
+#ifndef FONTCONFIG_MSVCPORT_PRIVATE_H_
+#define FONTCONFIG_MSVCPORT_PRIVATE_H_
+
+#include <wchar.h>
+
+#if defined(_MSC_VER) && !defined(S_ISDIR)
+#define S_ISDIR(mode) (((mode) & _S_IFDIR) != 0)
+#endif
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+    wchar_t * fc_utf8_to_utf16(const char * cstr);
+    char * fc_utf16_to_utf8(const wchar_t * wstr);
+
+    /* NOTE:
+       all char * strings passed to or returned from these
+       fc_msvcport_... functions are UTF-8 encoded
+    */
+
+    typedef void * DIR;
+
+    /*
+      this structure is layed out same as in mingw/include/dirent.h
+      for binary compatibility with code built with mingw compiler
+    */
+    struct dirent
+    {
+        long int           d_ino;       /* always zero */
+        unsigned short int d_reclen;    /* always zero */
+        unsigned short int d_namlen;    /* name length */
+        char               d_name[260]; /* name[FILENAME_MAX] */
+    };
+
+    extern void * fc_msvcport_opendir(const char * path);
+    extern struct dirent * fc_msvcport_readdir(void * priv);
+    extern int fc_msvcport_closedir(void * priv);
+
+    extern int fc_msvcport_mkdir(const char * path, int mode);
+    extern int fc_msvcport_rmdir(const char * path);
+
+    enum
+    {
+        F_OK = 0, /* Existence only */
+        W_OK = 2, /* Write permission */
+        R_OK = 4  /* Read permission */
+    };
+
+    extern int fc_msvcport_access(const char * path, int perms);
+    extern int fc_msvcport_chmod(const char * path, int mode);
+    extern int fc_msvcport_rename(const char * fnOld, const char * fnNew);
+    extern int fc_msvcport_unlink(const char * path);
+    extern int fc_msvcport_open(const char * fn, int oflag, ...);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+
+#endif /* FONTCONFIG_MSVCPORT_PRIVATE_H_ */
diff --git a/msvcport/stdint.h b/msvcport/stdint.h
new file mode 100644
index 0000000..d02608a
--- /dev/null
+++ b/msvcport/stdint.h
@@ -0,0 +1,247 @@
+// ISO C9x  compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
+// 
+//  Copyright (c) 2006-2008 Alexander Chemeris
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+//   1. Redistributions of source code must retain the above copyright notice,
+//      this list of conditions and the following disclaimer.
+// 
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+// 
+//   3. The name of the author may be used to endorse or promote products
+//      derived from this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// 
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+#  include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+#     define _W64 __w64
+#  else
+#     define _W64
+#  endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+   typedef signed char       int8_t;
+   typedef signed short      int16_t;
+   typedef signed int        int32_t;
+   typedef unsigned char     uint8_t;
+   typedef unsigned short    uint16_t;
+   typedef unsigned int      uint32_t;
+#else
+   typedef signed __int8     int8_t;
+   typedef signed __int16    int16_t;
+   typedef signed __int32    int32_t;
+   typedef unsigned __int8   uint8_t;
+   typedef unsigned __int16  uint16_t;
+   typedef unsigned __int32  uint32_t;
+#endif
+typedef signed __int64       int64_t;
+typedef unsigned __int64     uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t    int_least8_t;
+typedef int16_t   int_least16_t;
+typedef int32_t   int_least32_t;
+typedef int64_t   int_least64_t;
+typedef uint8_t   uint_least8_t;
+typedef uint16_t  uint_least16_t;
+typedef uint32_t  uint_least32_t;
+typedef uint64_t  uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t    int_fast8_t;
+typedef int16_t   int_fast16_t;
+typedef int32_t   int_fast32_t;
+typedef int64_t   int_fast64_t;
+typedef uint8_t   uint_fast8_t;
+typedef uint16_t  uint_fast16_t;
+typedef uint32_t  uint_fast32_t;
+typedef uint64_t  uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+   typedef signed __int64    intptr_t;
+   typedef unsigned __int64  uintptr_t;
+#else // _WIN64 ][
+   typedef _W64 signed int   intptr_t;
+   typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t   intmax_t;
+typedef uint64_t  uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN     ((int8_t)_I8_MIN)
+#define INT8_MAX     _I8_MAX
+#define INT16_MIN    ((int16_t)_I16_MIN)
+#define INT16_MAX    _I16_MAX
+#define INT32_MIN    ((int32_t)_I32_MIN)
+#define INT32_MAX    _I32_MAX
+#define INT64_MIN    ((int64_t)_I64_MIN)
+#define INT64_MAX    _I64_MAX
+#define UINT8_MAX    _UI8_MAX
+#define UINT16_MAX   _UI16_MAX
+#define UINT32_MAX   _UI32_MAX
+#define UINT64_MAX   _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN    INT8_MIN
+#define INT_LEAST8_MAX    INT8_MAX
+#define INT_LEAST16_MIN   INT16_MIN
+#define INT_LEAST16_MAX   INT16_MAX
+#define INT_LEAST32_MIN   INT32_MIN
+#define INT_LEAST32_MAX   INT32_MAX
+#define INT_LEAST64_MIN   INT64_MIN
+#define INT_LEAST64_MAX   INT64_MAX
+#define UINT_LEAST8_MAX   UINT8_MAX
+#define UINT_LEAST16_MAX  UINT16_MAX
+#define UINT_LEAST32_MAX  UINT32_MAX
+#define UINT_LEAST64_MAX  UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN    INT8_MIN
+#define INT_FAST8_MAX    INT8_MAX
+#define INT_FAST16_MIN   INT16_MIN
+#define INT_FAST16_MAX   INT16_MAX
+#define INT_FAST32_MIN   INT32_MIN
+#define INT_FAST32_MAX   INT32_MAX
+#define INT_FAST64_MIN   INT64_MIN
+#define INT_FAST64_MAX   INT64_MAX
+#define UINT_FAST8_MAX   UINT8_MAX
+#define UINT_FAST16_MAX  UINT16_MAX
+#define UINT_FAST32_MAX  UINT32_MAX
+#define UINT_FAST64_MAX  UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+#  define INTPTR_MIN   INT64_MIN
+#  define INTPTR_MAX   INT64_MAX
+#  define UINTPTR_MAX  UINT64_MAX
+#else // _WIN64 ][
+#  define INTPTR_MIN   INT32_MIN
+#  define INTPTR_MAX   INT32_MAX
+#  define UINTPTR_MAX  UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN   INT64_MIN
+#define INTMAX_MAX   INT64_MAX
+#define UINTMAX_MAX  UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+#  define PTRDIFF_MIN  _I64_MIN
+#  define PTRDIFF_MAX  _I64_MAX
+#else  // _WIN64 ][
+#  define PTRDIFF_MIN  _I32_MIN
+#  define PTRDIFF_MAX  _I32_MAX
+#endif  // _WIN64 ]
+
+#define SIG_ATOMIC_MIN  INT_MIN
+#define SIG_ATOMIC_MAX  INT_MAX
+
+#ifndef SIZE_MAX // [
+#  ifdef _WIN64 // [
+#     define SIZE_MAX  _UI64_MAX
+#  else // _WIN64 ][
+#     define SIZE_MAX  _UI32_MAX
+#  endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+#  define WCHAR_MIN  0
+#endif  // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+#  define WCHAR_MAX  _UI16_MAX
+#endif  // WCHAR_MAX ]
+
+#define WINT_MIN  0
+#define WINT_MAX  _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val)  val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val)  val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C   INT64_C
+#define UINTMAX_C  UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
diff --git a/src/fcformat.c b/src/fcformat.c
index 8eef7bb..b18dc44 100644
--- a/src/fcformat.c
+++ b/src/fcformat.c
@@ -566,7 +566,11 @@ interpret_count (FcFormatContext *c,
 	    count++;
     }
 
+#if defined(_WIN32) && defined(_MSC_VER)
+    _snprintf_s ((char *) buf_static, sizeof (buf_static), sizeof (buf_static), "%d", count);
+#else
     snprintf ((char *) buf_static, sizeof (buf_static), "%d", count);
+#endif
     FcStrBufString (buf, buf_static);
 
     return FcTrue;
-- 
1.7.9
-------------- next part --------------
From a9337d4f2e69e94eb9794c090add9cd4857a9560 Mon Sep 17 00:00:00 2001
From: Pavel Koshevoy <pkoshevoy at gmail.com>
Date: Thu, 11 Oct 2012 00:06:51 -0600
Subject: [PATCH 3/4] Add utf-8 version of FcStat for msvcport.

It is necessary to provide a utf-8 version of FcStat because all
msvcport wrappers require utf-8 encoded filepath parameters, and all
thin portability wrappers should be consistent regarding text
encoding.

It may make sense to get rid of non-utf8 Fc.... wrappers for _WIN32
builds all together, however that would risk breaking existing
applications that link against mingw/cygwin/msys builds of fontconfig
and may use non-unicode (ansi code page) encoded filepaths.

Someone needs to clarify what are the fontconfig API requirements
regarding char * text encoding on windows (and other platforms).
---
 src/fcstat.c |   69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/src/fcstat.c b/src/fcstat.c
index 617abf6..89ac248 100644
--- a/src/fcstat.c
+++ b/src/fcstat.c
@@ -74,6 +74,7 @@ typedef __int64 INT64;
  * just use the UTC timestamps from NTFS, converted to the Unix epoch.
  */
 
+# if !defined(_MSC_VER)
 int
 FcStat (const FcChar8 *file, struct stat *statb)
 {
@@ -121,6 +122,74 @@ FcStat (const FcChar8 *file, struct stat *statb)
     return 0;
 }
 
+# else /* _MSC_VER */
+
+static FcChar32
+FcStringHashW (const wchar_t * wstr)
+{
+    char * str = fc_utf16_to_utf8 (wstr);
+    FcChar32 ret = FcStringHash (str);
+    free (str);
+    return ret;
+}
+
+int
+FcStatW (const wchar_t *wfile, struct stat *statb)
+{
+    WIN32_FILE_ATTRIBUTE_DATA wfad;
+    wchar_t wfull_path_name[MAX_PATH];
+    wchar_t *wbasename;
+    DWORD rc;
+
+    if (!GetFileAttributesExW (wfile, GetFileExInfoStandard, &wfad))
+	return -1;
+
+    statb->st_dev = 0;
+
+    /* Calculate a pseudo inode number as a hash of the full path name.
+     * Call GetLongPathName() to get the spelling of the path name as it
+     * is on disk.
+     */
+    rc = GetFullPathNameW (wfile, MAX_PATH, wfull_path_name, &wbasename);
+    if (rc == 0 || rc > MAX_PATH)
+	return -1;
+
+    rc = GetLongPathNameW (wfull_path_name, wfull_path_name, MAX_PATH);
+    statb->st_ino = FcStringHashW (wfull_path_name);
+
+    statb->st_mode = _S_IREAD | _S_IWRITE;
+    statb->st_mode |= (statb->st_mode >> 3) | (statb->st_mode >> 6);
+
+    if (wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+	statb->st_mode |= _S_IFDIR;
+    else
+	statb->st_mode |= _S_IFREG;
+
+    statb->st_nlink = 1;
+    statb->st_uid = statb->st_gid = 0;
+    statb->st_rdev = 0;
+
+    if (wfad.nFileSizeHigh > 0)
+	return -1;
+    statb->st_size = wfad.nFileSizeLow;
+
+    statb->st_atime = (*(INT64 *)&wfad.ftLastAccessTime)/10000000 - EPOCH_OFFSET;
+    statb->st_mtime = (*(INT64 *)&wfad.ftLastWriteTime)/10000000 - EPOCH_OFFSET;
+    statb->st_ctime = statb->st_mtime;
+
+    return 0;
+}
+
+int
+FcStat (const FcChar8 *file_utf8, struct stat *statb)
+{
+    wchar_t *wfile = fc_utf8_to_utf16 (file_utf8);
+    int ret = FcStatW (wfile, statb);
+    free (wfile);
+    return ret;
+}
+# endif /* _MSC_VER */
+
 #else
 
 int
-- 
1.7.9
-------------- next part --------------
From 227ef25b847851906eae5280c26131289112e597 Mon Sep 17 00:00:00 2001
From: Pavel Koshevoy <pkoshevoy at gmail.com>
Date: Thu, 11 Oct 2012 00:08:33 -0600
Subject: [PATCH 4/4] Add CMake project for msvcport

Visual Studio does not support debugging code compiled with gcc.
With this cmake project one can generate a Visual Studio solution
for fontconfig and compile it in Debug/Release/etc... win32 or x64
configuration.
---
 msvcport/CMakeLists.txt |  313 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 313 insertions(+), 0 deletions(-)
 create mode 100644 msvcport/CMakeLists.txt

diff --git a/msvcport/CMakeLists.txt b/msvcport/CMakeLists.txt
new file mode 100644
index 0000000..341438f
--- /dev/null
+++ b/msvcport/CMakeLists.txt
@@ -0,0 +1,313 @@
+cmake_minimum_required(VERSION 2.8.0)
+
+project(fontconfig)
+
+if (NOT WIN32 OR (MINGW OR MSYS OR CYGWIN))
+  message(FATAL_ERROR
+    "This CMake project is intended only for native WIN32 compilation.  "
+    "For any other platforms please use the autotools ./configure script.")
+endif (NOT WIN32 OR (MINGW OR MSYS OR CYGWIN))
+
+
+include_directories(AFTER
+  ${CMAKE_CURRENT_SOURCE_DIR}/..
+  ${CMAKE_CURRENT_SOURCE_DIR}/../src
+  )
+
+file(STRINGS ../configure.ac READ_CONFIGURE_AC REGEX "^AM_INIT_AUTOMAKE *\\( *fontconfig.*")
+string(REGEX REPLACE
+  ".*AM_INIT_AUTOMAKE *\\( *fontconfig *, *([^ ]+) *\\).*$"
+  "\\1"
+  FONTCONFIG_VERSION
+  "${READ_CONFIGURE_AC}"
+  )
+string(REGEX REPLACE
+  "([0-9]+\\.[0-9]+)\\.[0-9]+"
+  "\\1"
+  FONTCONFIG_MAJOR_MINOR
+  "${FONTCONFIG_VERSION}"
+  )
+
+if (WIN32)
+  set(FONTCONFIG_DEF "${PROJECT_BINARY_DIR}/src/fontconfig.def")
+  set_source_files_properties("${FONTCONFIG_DEF}" PROPERTIES GENERATED true)
+
+  file(STRINGS ../fontconfig/fontconfig.h READ_FONTCONFIG_H  REGEX "^Fc[^ ]* *\\(")
+  file(STRINGS ../src/fcdeprecate.h       READ_FCDEPRECATE_H REGEX "^Fc[^ ]* *\\(")
+  file(STRINGS ../fontconfig/fcprivate.h  READ_FCPRIVATE_H   REGEX "^Fc[^ ]* *\\(")
+  file(STRINGS ../fontconfig/fcfreetype.h READ_FCFREETYPE_H  REGEX "^Fc[^ ]* *\\(")
+
+  file(WRITE "${FONTCONFIG_DEF}" "EXPORTS\n")
+  foreach(line ${READ_FONTCONFIG_H} ${READ_FCDEPRECATE_H} ${READ_FCPRIVATE_H} ${READ_FCFREETYPE_H})
+    string(REGEX REPLACE
+      " *\\(.*$"
+      ""
+      FONTCONFIG_EXPORT
+      "${line}"
+      )
+    file(APPEND "${FONTCONFIG_DEF}" "	${FONTCONFIG_EXPORT}\n")
+  endforeach(line)
+  file(APPEND "${FONTCONFIG_DEF}" "LIBRARY fontconfig.dll\n")
+  file(APPEND "${FONTCONFIG_DEF}" "VERSION ${FONTCONFIG_MAJOR_MINOR}\n")
+endif (WIN32)
+
+set(CASEFOLDING_TXT "${PROJECT_SOURCE_DIR}/../fc-case/CaseFolding.txt")
+set(FCCASE_TMPL_H "${PROJECT_SOURCE_DIR}/../fc-case/fccase.tmpl.h")
+set(FCCASE_H "${PROJECT_SOURCE_DIR}/../fc-case/fccase.h")
+set_source_files_properties("${FCCASE_H}" PROPERTIES GENERATED true)
+
+if (MINGW OR MSYS)
+  string(REPLACE "/" "\\\\" NATIVE_CASEFOLDING_TXT "${CASEFOLDING_TXT}")
+  string(REPLACE "/" "\\\\" NATIVE_FCCASE_TMPL_H "${FCCASE_TMPL_H}")
+  string(REPLACE "/" "\\\\" NATIVE_FCCASE_H "${FCCASE_H}")
+else (MINGW OR MSYS)
+  file(TO_NATIVE_PATH "${CASEFOLDING_TXT}" NATIVE_CASEFOLDING_TXT)
+  file(TO_NATIVE_PATH "${FCCASE_TMPL_H}" NATIVE_FCCASE_TMPL_H)
+  file(TO_NATIVE_PATH "${FCCASE_H}" NATIVE_FCCASE_H)
+endif (MINGW OR MSYS)
+
+add_custom_command(OUTPUT "${FCCASE_H}"
+  COMMAND fc-case
+  ARGS
+  "${NATIVE_CASEFOLDING_TXT}" < "${NATIVE_FCCASE_TMPL_H}" > "${NATIVE_FCCASE_H}"
+  DEPENDS
+  fc-case
+  )
+
+set(ZAPFDINGBATS_TXT "${PROJECT_SOURCE_DIR}/../fc-glyphname/zapfdingbats.txt")
+set(FCGLYPHNAME_TMPL_H "${PROJECT_SOURCE_DIR}/../fc-glyphname/fcglyphname.tmpl.h")
+set(FCGLYPHNAME_H "${PROJECT_SOURCE_DIR}/../fc-glyphname/fcglyphname.h")
+set_source_files_properties("${FCGLYPHNAME_H}" PROPERTIES GENERATED true)
+
+if (MINGW OR MSYS)
+  string(REPLACE "/" "\\\\" NATIVE_ZAPFDINGBATS_TXT "${ZAPFDINGBATS_TXT}")
+  string(REPLACE "/" "\\\\" NATIVE_FCGLYPHNAME_TMPL_H "${FCGLYPHNAME_TMPL_H}")
+  string(REPLACE "/" "\\\\" NATIVE_FCGLYPHNAME_H "${FCGLYPHNAME_H}")
+else (MINGW OR MSYS)
+  file(TO_NATIVE_PATH "${ZAPFDINGBATS_TXT}" NATIVE_ZAPFDINGBATS_TXT)
+  file(TO_NATIVE_PATH "${FCGLYPHNAME_TMPL_H}" NATIVE_FCGLYPHNAME_TMPL_H)
+  file(TO_NATIVE_PATH "${FCGLYPHNAME_H}" NATIVE_FCGLYPHNAME_H)
+endif (MINGW OR MSYS)
+
+add_custom_command(OUTPUT "${FCGLYPHNAME_H}"
+  COMMAND fc-glyphname
+  ARGS
+  "${NATIVE_ZAPFDINGBATS_TXT}" < "${NATIVE_FCGLYPHNAME_TMPL_H}" > "${NATIVE_FCGLYPHNAME_H}"
+  DEPENDS
+  fc-glyphname
+  )
+
+
+file(STRINGS "../fc-lang/Makefile.am" READ_FCLANG_ORTH REGEX "[^ ]+\\.orth")
+string(REGEX REPLACE "([ 	]+)" "" FCLANG_ORTH_LIST "${READ_FCLANG_ORTH}")
+set(FCLANG_ORTH ${FCLANG_ORTH_LIST})
+
+set(FCLANG_DIR "${PROJECT_SOURCE_DIR}/../fc-lang/")
+set(FCLANG_TMPL_H "${PROJECT_SOURCE_DIR}/../fc-lang/fclang.tmpl.h")
+set(FCLANG_H "${PROJECT_SOURCE_DIR}/../fc-lang/fclang.h")
+set_source_files_properties("${FCLANG_H}" PROPERTIES GENERATED true)
+
+if (MINGW OR MSYS)
+  string(REPLACE "/" "\\\\" NATIVE_FCLANG_DIR "${FCLANG_DIR}")
+  string(REPLACE "/" "\\\\" NATIVE_FCLANG_TMPL_H "${FCLANG_TMPL_H}")
+  string(REPLACE "/" "\\\\" NATIVE_FCLANG_H "${FCLANG_H}")
+else (MINGW OR MSYS)
+  file(TO_NATIVE_PATH "${FCLANG_DIR}" NATIVE_FCLANG_DIR)
+  file(TO_NATIVE_PATH "${FCLANG_TMPL_H}" NATIVE_FCLANG_TMPL_H)
+  file(TO_NATIVE_PATH "${FCLANG_H}" NATIVE_FCLANG_H)
+endif (MINGW OR MSYS)
+
+add_custom_command(OUTPUT "${FCLANG_H}"
+  COMMAND fc-lang
+  ARGS
+  -d "${NATIVE_FCLANG_DIR}" ${FCLANG_ORTH} < "${NATIVE_FCLANG_TMPL_H}" > "${NATIVE_FCLANG_H}"
+  DEPENDS
+  fc-lang "${FCCASE_H}"
+  )
+
+
+add_custom_target("autogenerate" ALL
+  DEPENDS
+  "${FCCASE_H}"
+  "${FCGLYPHNAME_H}"
+  "${FCLANG_H}"
+  )
+
+add_executable(fc-case
+  ../fc-case/fc-case.c
+  ../fc-case/fccase.tmpl.h
+  ../fc-case/CaseFolding.txt
+  )
+
+
+add_executable(fc-lang
+  "${FCCASE_H}"
+  ../fc-lang/fc-lang.c
+  ../fc-lang/fclang.tmpl.h
+  ../fc-lang/iso-3166.txt
+  ../fc-lang/iso639-1
+  ../fc-lang/iso639-2
+  )
+
+add_executable(fc-glyphname
+  ../fc-glyphname/fc-glyphname.c
+  ../fc-glyphname/fcglyphname.tmpl.h
+  )
+
+if (WIN32)
+  ADD_DEFINITIONS(-D_USE_MATH_DEFINES)
+  ADD_DEFINITIONS(-DNOMINMAX)
+  ADD_DEFINITIONS(-DFC_CACHEDIR="WINDOWSTEMPDIR_FONTCONFIG_CACHE")
+  ADD_DEFINITIONS(-DHAVE_CONFIG_H)
+
+  OPTION(LINKING_TO_STATIC_EXPAT_LIB "Check this if linking to static expat library" false)
+  if (LINKING_TO_STATIC_EXPAT_LIB)
+    ADD_DEFINITIONS(-DXML_STATIC=1)
+  endif(LINKING_TO_STATIC_EXPAT_LIB)
+
+  include_directories(AFTER
+    ../msvcport
+    )
+endif (WIN32)
+
+
+set(FREETYPE_DIR "$ENV{FREETYPE_DIR}"
+  CACHE PATH "root path for freetype lib/ and include/ folders"
+  )
+find_path(FREETYPE_INCLUDE_DIR
+  ft2build.h freetype2/freetype/freetype.h
+  PATHS ${FREETYPE_DIR}/include
+  )
+find_library(FREETYPE_LIBRARY
+  freetype libfreetype
+  PATHS ${FREETYPE_DIR}/lib
+  DOC "freetype library"
+  )
+if (FREETYPE_INCLUDE_DIR)
+  include_directories(AFTER ${FREETYPE_INCLUDE_DIR} ${FREETYPE_INCLUDE_DIR}/freetype2)
+endif (FREETYPE_INCLUDE_DIR)
+
+
+set(EXPAT_DIR "$ENV{EXPAT_DIR}"
+  CACHE PATH "root path for expat lib/ and include/ folders"
+  )
+find_path(EXPAT_INCLUDE_DIR
+  expat.h
+  PATHS ${EXPAT_DIR}/include
+  )
+find_library(EXPAT_LIBRARY
+  expat libexpat
+  PATHS ${EXPAT_DIR}/lib
+  DOC "expat library"
+  )
+if (EXPAT_INCLUDE_DIR)
+  include_directories(AFTER ${EXPAT_INCLUDE_DIR})
+endif (EXPAT_INCLUDE_DIR)
+
+
+set(ICONV_DIR "$ENV{ICONV_DIR}"
+  CACHE PATH "root path for iconv lib/ and include/ folders"
+  )
+find_path(ICONV_INCLUDE_DIR
+  iconv.h
+  PATHS ${ICONV_DIR}/include
+  )
+find_library(ICONV_LIBRARY
+  iconv libiconv
+  PATHS ${ICONV_DIR}/lib
+  DOC "iconv library"
+  )
+if (ICONV_INCLUDE_DIR)
+  include_directories(AFTER ${ICONV_INCLUDE_DIR})
+endif (ICONV_INCLUDE_DIR)
+
+
+set(project_sources
+  "${FCCASE_H}"
+  "${FCLANG_H}"
+  "${FCGLYPHNAME_H}"
+  ../src/fcarch.h
+  ../src/fcatomic.c
+  ../src/fcblanks.c
+  ../src/fccache.c
+  ../src/fccfg.c
+  ../src/fccharset.c
+  ../src/fcdbg.c
+  ../src/fcdefault.c
+  ../src/fcdir.c
+  ../src/fcformat.c
+  ../src/fcfreetype.c
+  ../src/fcfs.c
+  ../src/fcinit.c
+  ../src/fclang.c
+  ../src/fclist.c
+  ../src/fcmatch.c
+  ../src/fcmatrix.c
+  ../src/fcname.c
+  ../src/fcpat.c
+  ../src/fcserialize.c
+  ../src/fcstat.c
+  ../src/fcstr.c
+  ../src/fcxml.c
+  ../src/ftglue.h
+  ../src/ftglue.c
+  )
+
+if (WIN32)
+  set(project_sources
+    ${project_sources}
+    ../msvcport/config.h
+    ../msvcport/dirent.h
+    ../msvcport/fcalias.h
+    ../msvcport/fcaliastail.h
+    ../msvcport/fcftalias.h
+    ../msvcport/fcftaliastail.h
+    ../msvcport/inttypes.h
+    ../msvcport/stdint.h
+    ../msvcport/msvcport.h
+    ../msvcport/msvcport_private.h
+    ../msvcport/msvcport_private.c
+    )
+  find_library(LIBGCC_LIBRARY libgcc PATHS ${FFMPEG_LIBS_PATH} DOC "mingw libgcc library")
+endif (WIN32)
+
+add_library(libfontconfig STATIC ${project_sources})
+add_dependencies(libfontconfig "autogenerate")
+
+set (sharedlib_sources ${project_sources})
+if (WIN32)
+  set (sharedlib_sources ${sharedlib_sources} ${FONTCONFIG_DEF})
+endif (WIN32)
+add_library(fontconfig SHARED ${sharedlib_sources})
+add_dependencies(fontconfig "autogenerate")
+
+
+set(THIRD_PARTY_LIBS ${FREETYPE_LIBRARY} ${EXPAT_LIBRARY} ${ICONV_LIBRARY})
+if (WIN32)
+  if (LIBGCC_LIBRARY)
+    set(THIRD_PARTY_LIBS ${THIRD_PARTY_LIBS} ${LIBGCC_LIBRARY})
+  endif (LIBGCC_LIBRARY)
+endif (WIN32)
+target_link_libraries(fontconfig ${THIRD_PARTY_LIBS})
+
+
+install(TARGETS libfontconfig fontconfig DESTINATION lib)
+install(FILES
+  ../fontconfig/fontconfig.h
+  ../fontconfig/fcfreetype.h
+  ../fontconfig/fcprivate.h
+
+  DESTINATION
+  include/fontconfig)
+
+if (WIN32)
+  set (FONTCONFIG_PC_IN "${PROJECT_SOURCE_DIR}/../msvcport/fontconfig.pc.in")
+  set (FONTCONFIG_PC "${PROJECT_BINARY_DIR}/fontconfig.pc")
+  set_source_files_properties("${FONTCONFIG_PC}" PROPERTIES GENERATED true)
+  configure_file("${FONTCONFIG_PC_IN}" "${FONTCONFIG_PC}.tmp" @ONLY)
+  execute_process(COMMAND "${CMAKE_COMMAND}" -E copy_if_different
+    "${FONTCONFIG_PC}.tmp"
+    "${FONTCONFIG_PC}")
+  file(REMOVE "${FONTCONFIG_PC}.tmp")
+  install(FILES "${FONTCONFIG_PC}" DESTINATION lib/pkgconfig)
+endif (WIN32)
-- 
1.7.9


More information about the Fontconfig mailing list