diff -pru ../fontconfig-2.4.2/configure.in ./configure.in --- ../fontconfig-2.4.2/configure.in 2006-12-03 01:24:39.000000000 +0200 +++ ./configure.in 2007-03-01 22:59:29.406250000 +0200 @@ -459,7 +459,11 @@ AC_ARG_WITH(cache-dir, [ --with- case $fc_cachedir in no|yes) - fc_cachedir=`eval echo "${localstatedir}/cache/"${PACKAGE}` + if test "$os_win32" = "yes"; then + fc_cachedir="WINDOWSTEMPDIR_FONTCONFIG_CACHE" + else + fc_cachedir=`eval echo "${localstatedir}/cache/"${PACKAGE}` + fi ;; *) ;; diff -pru ../fontconfig-2.4.2/fc-cache/Makefile.am ./fc-cache/Makefile.am --- ../fontconfig-2.4.2/fc-cache/Makefile.am 2006-09-14 04:52:22.000000000 +0300 +++ ./fc-cache/Makefile.am 2007-03-01 22:52:37.890625000 +0200 @@ -27,11 +27,14 @@ FC_CACHE_SRC=${top_srcdir}/fc-cache SGML = ${FC_CACHE_SRC}/fc-cache.sgml +if OS_WIN32 +else install-data-local: -$(mkinstalldirs) "$(DESTDIR)$(fc_cachedir)" uninstall-local: -$(RM) -rf "$(DESTDIR)$(fc_cachedir)" +endif INCLUDES=-I${top_srcdir} -I${top_srcdir}/src $(FREETYPE_CFLAGS) $(WARN_CFLAGS) diff -pru ../fontconfig-2.4.2/src/fccache.c ./src/fccache.c --- ../fontconfig-2.4.2/src/fccache.c 2006-12-02 23:33:41.000000000 +0200 +++ ./src/fccache.c 2007-03-01 22:15:54.406250000 +0200 @@ -33,6 +33,7 @@ # include # include #elif defined(_WIN32) +# define _WIN32_WINNT 0x0500 # include #endif @@ -53,6 +54,90 @@ static void MD5Transform(FcChar32 buf[4] #define CACHEBASE_LEN (1 + 32 + 1 + sizeof (FC_ARCHITECTURE) + sizeof (FC_CACHE_SUFFIX)) +#ifdef _WIN32 + +#include + +#ifdef __GNUC__ +typedef long long INT64; +#define EPOCH_OFFSET 11644473600ll +#else +#define EPOCH_OFFSET 11644473600i64 +typedef __int64 INT64; +#endif + +/* Workaround for problems in the stat() in the Microsoft C library: + * + * 1) stat() uses FindFirstFile() to get the file + * attributes. Unfortunately this API doesn't return correct values + * for modification time of a directory until some time after a file + * or subdirectory has been added to the directory. (This causes + * run-test.sh to fail, for instance.) GetFileAttributesEx() is + * better, it returns the updated timestamp right away. + * + * 2) stat() does some strange things related to backward + * compatibility with the local time timestamps on FAT volumes and + * daylight saving time. This causes problems after the switches + * to/from daylight saving time. See + * http://bugzilla.gnome.org/show_bug.cgi?id=154968 , especially + * comment #30, and http://www.codeproject.com/datetime/dstbugs.asp . + * We don't need any of that, FAT and Win9x are as good as dead. So + * just use the UTC timestamps from NTFS, converted to the Unix epoch. + */ + +static int +FcStat (const char *file, struct stat *statb) +{ + WIN32_FILE_ATTRIBUTE_DATA wfad; + char full_path_name[MAX_PATH]; + char *basename; + DWORD rc; + + if (!GetFileAttributesEx (file, 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 = GetFullPathName (file, sizeof (full_path_name), full_path_name, &basename); + if (rc == 0 || rc > sizeof (full_path_name)) + return -1; + + rc = GetLongPathName (full_path_name, full_path_name, sizeof (full_path_name)); + statb->st_ino = FcStringHash (full_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; +} + +#else + +#define FcStat stat + +#endif + static const char bin2hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', @@ -117,14 +202,20 @@ FcDirCacheOpenFile (const FcChar8 *cache { int fd; +#ifdef _WIN32 + if (FcStat (cache_file, file_stat) < 0) + return -1; +#endif fd = open((char *) cache_file, O_RDONLY | O_BINARY); if (fd < 0) return fd; +#ifndef _WIN32 if (fstat (fd, file_stat) < 0) { close (fd); return -1; } +#endif return fd; } @@ -145,7 +236,7 @@ FcDirCacheProcess (FcConfig *config, con struct stat file_stat, dir_stat; FcBool ret = FcFalse; - if (stat ((char *) dir, &dir_stat) < 0) + if (FcStat ((char *) dir, &dir_stat) < 0) return FcFalse; FcDirCacheBasename (dir, cache_base); diff -pru ../fontconfig-2.4.2/src/fcxml.c ./src/fcxml.c --- ../fontconfig-2.4.2/src/fcxml.c 2006-12-02 23:54:03.000000000 +0200 +++ ./src/fcxml.c 2007-03-02 00:11:50.500000000 +0200 @@ -2072,6 +2072,30 @@ FcEndElement(void *userData, const XML_C FcConfigMessage (parse, FcSevereError, "out of memory"); break; } +#ifdef _WIN32 + if (strcmp (data, "WINDOWSTEMPDIR_FONTCONFIG_CACHE") == 0) + { + int rc; + FcStrFree (data); + data = malloc (1000); + if (!data) + { + FcConfigMessage (parse, FcSevereError, "out of memory"); + break; + } + FcMemAlloc (FC_MEM_STRING, 1000); + rc = GetTempPath (800, data); + if (rc == 0 || rc > 800) + { + FcConfigMessage (parse, FcSevereError, "GetWindowsDirectory failed"); + FcStrFree (data); + break; + } + if (data [strlen (data) - 1] != '\\') + strcat (data, "\\"); + strcat (data, "fontconfig\\cache"); + } +#endif if (!FcStrUsesHome (data) || FcConfigHome ()) { if (!FcConfigAddCacheDir (parse->config, data))