Hi,
I've attached a patch that adds a CMakeLists.txt and msvcport to enable
native compilation on windows via cmake. The patch is against a recent
git version of fontconfig. I am not sure what procedures to follow for
contributing a patch. Please comment so I can improve it or drop it if
there is no interest.
Thank you,
Pavel.
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..23bc25b
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,503 @@
+cmake_minimum_required(VERSION 2.8.0)
+
+project(fontconfig)
+
+include_directories(AFTER
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ src
+ )
+
+
+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
+ )
+
+
+set(FCLANG_ORTH
+ aa.orth
+ ab.orth
+ af.orth
+ ak.orth
+ am.orth
+ an.orth
+ ar.orth
+ as.orth
+ ast.orth
+ av.orth
+ ay.orth
+ az_az.orth
+ az_ir.orth
+ ba.orth
+ be.orth
+ ber_dz.orth
+ ber_ma.orth
+ bg.orth
+ bh.orth
+ bho.orth
+ bi.orth
+ bin.orth
+ bm.orth
+ bn.orth
+ bo.orth
+ br.orth
+ brx.orth
+ bs.orth
+ bua.orth
+ byn.orth
+ ca.orth
+ ce.orth
+ ch.orth
+ chm.orth
+ chr.orth
+ co.orth
+ crh.orth
+ cs.orth
+ csb.orth
+ cu.orth
+ cv.orth
+ cy.orth
+ da.orth
+ de.orth
+ doi.orth
+ dv.orth
+ dz.orth
+ ee.orth
+ el.orth
+ en.orth
+ eo.orth
+ es.orth
+ et.orth
+ eu.orth
+ fa.orth
+ fat.orth
+ ff.orth
+ fi.orth
+ fil.orth
+ fj.orth
+ fo.orth
+ fr.orth
+ fur.orth
+ fy.orth
+ ga.orth
+ gd.orth
+ gez.orth
+ gl.orth
+ gn.orth
+ gu.orth
+ gv.orth
+ ha.orth
+ haw.orth
+ he.orth
+ hi.orth
+ hne.orth
+ ho.orth
+ hr.orth
+ hsb.orth
+ ht.orth
+ hu.orth
+ hy.orth
+ hz.orth
+ ia.orth
+ id.orth
+ ie.orth
+ ig.orth
+ ii.orth
+ ik.orth
+ io.orth
+ is.orth
+ it.orth
+ iu.orth
+ ja.orth
+ jv.orth
+ ka.orth
+ kaa.orth
+ kab.orth
+ ki.orth
+ kj.orth
+ kk.orth
+ kl.orth
+ km.orth
+ kn.orth
+ ko.orth
+ kok.orth
+ kr.orth
+ ks.orth
+ ku_am.orth
+ ku_iq.orth
+ ku_ir.orth
+ ku_tr.orth
+ kum.orth
+ kv.orth
+ kw.orth
+ kwm.orth
+ ky.orth
+ la.orth
+ lah.orth
+ lb.orth
+ lez.orth
+ lg.orth
+ li.orth
+ ln.orth
+ lo.orth
+ lt.orth
+ lv.orth
+ mai.orth
+ mg.orth
+ mh.orth
+ mi.orth
+ mk.orth
+ ml.orth
+ mn_cn.orth
+ mn_mn.orth
+ mni.orth
+ mo.orth
+ mr.orth
+ ms.orth
+ mt.orth
+ my.orth
+ na.orth
+ nb.orth
+ nds.orth
+ ne.orth
+ ng.orth
+ nl.orth
+ nn.orth
+ no.orth
+ nqo.orth
+ nr.orth
+ nso.orth
+ nv.orth
+ ny.orth
+ oc.orth
+ om.orth
+ or.orth
+ os.orth
+ ota.orth
+ pa.orth
+ pa_pk.orth
+ pap_an.orth
+ pap_aw.orth
+ pes.orth
+ pl.orth
+ prs.orth
+ ps_af.orth
+ ps_pk.orth
+ pt.orth
+ qu.orth
+ rm.orth
+ rn.orth
+ ro.orth
+ ru.orth
+ rw.orth
+ sa.orth
+ sah.orth
+ sat.orth
+ sc.orth
+ sco.orth
+ sd.orth
+ se.orth
+ sel.orth
+ sg.orth
+ sh.orth
+ shs.orth
+ si.orth
+ sid.orth
+ sk.orth
+ sl.orth
+ sm.orth
+ sma.orth
+ smj.orth
+ smn.orth
+ sms.orth
+ sn.orth
+ so.orth
+ sq.orth
+ sr.orth
+ ss.orth
+ st.orth
+ su.orth
+ sv.orth
+ sw.orth
+ syr.orth
+ ta.orth
+ te.orth
+ tg.orth
+ th.orth
+ ti_er.orth
+ ti_et.orth
+ tig.orth
+ tk.orth
+ tl.orth
+ tn.orth
+ to.orth
+ tr.orth
+ ts.orth
+ tt.orth
+ tw.orth
+ ty.orth
+ tyv.orth
+ ug.orth
+ uk.orth
+ ur.orth
+ uz.orth
+ ve.orth
+ vi.orth
+ vo.orth
+ vot.orth
+ wa.orth
+ wal.orth
+ wen.orth
+ wo.orth
+ xh.orth
+ yap.orth
+ yi.orth
+ yo.orth
+ za.orth
+ zh_cn.orth
+ zh_hk.orth
+ zh_mo.orth
+ zh_sg.orth
+ zh_tw.orth
+ zu.orth
+)
+
+
+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(fontconfig_static STATIC
+ ${project_sources}
+ )
+add_dependencies(fontconfig_static "autogenerate")
+
+add_library(fontconfig_shared SHARED
+ ${project_sources}
+ )
+add_dependencies(fontconfig_shared "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_shared ${THIRD_PARTY_LIBS})
+
+
+install(TARGETS fontconfig_static fontconfig_shared DESTINATION lib)
+install(FILES
+ fontconfig/fontconfig.h
+ fontconfig/fcfreetype.h
+ fontconfig/fcprivate.h
+
+ DESTINATION
+ include/fontconfig)
diff --git a/config-fixups.h b/config-fixups.h
index 93ebf5b..e613711 100644
--- a/config-fixups.h
+++ b/config-fixups.h
@@ -38,3 +38,21 @@
# define ALIGNOF_DOUBLE 4
# endif
#endif
+
+/* a very thin portability layer */
+#if defined(_WIN32) && !defined(__MINGW32__)
+#include "msvcport.h"
+#else
+#define fc_opendir(x) opendir(x)
+#define fc_readdir(x) readdir(x)
+#define fc_closedir(x) closedir(x)
+
+#define fc_mkdir(x, y) mkdir(x, y)
+#define fc_rmdir(x) rmdir(x)
+
+#define fc_access(x, y) access(x, y)
+#define fc_chmod(x, y) chmod(x, y)
+#define fc_unlink(x) unlink(x)
+#define fc_open(x, y, ...) open(x, y, __VA_ARGS__)
+
+#endif
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/fcftalias.h b/msvcport/fcftalias.h
new file mode 100644
index 0000000..e69de29
diff --git a/msvcport/fcftaliastail.h b/msvcport/fcftaliastail.h
new file mode 100644
index 0000000..e69de29
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..c548e02
--- /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 fc_opendir(x) fc_msvcport_opendir(x)
+#define fc_readdir(x) fc_msvcport_readdir(x)
+#define fc_closedir(x) fc_msvcport_closedir(x)
+
+#define fc_mkdir(x, y) fc_msvcport_mkdir(x, y)
+#define fc_rmdir(x) fc_msvcport_rmdir(x)
+
+#define fc_access(x, y) fc_msvcport_access(x, y)
+#define fc_chmod(x, y) chmod(x, y)
+#define fc_unlink(x) fc_msvcport_unlink(x)
+#define fc_open(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..af339d8
--- /dev/null
+++ b/msvcport/msvcport_private.c
@@ -0,0 +1,343 @@
+/* -*- 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;
+}
+
+int64_t
+fc_msvcport_file_seek64(int fd, int64_t offset, int whence)
+{
+ __int64 pos = _lseeki64(fd, offset, whence);
+ return pos;
+}
+
+int64_t
+fc_msvcport_file_size64(int fd)
+{
+ struct _stati64 st;
+ __int64 ret = _fstati64(fd, &st);
+
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ return st.st_size;
+}
+
+void *
+fc_msvcport_fopen(const char * filenameUtf8, const char * mode)
+{
+ FILE * file = NULL;
+
+ wchar_t * wname = fc_utf8_to_utf16(filenameUtf8);
+ wchar_t * wmode = fc_utf8_to_utf16(mode);
+
+ _wfopen_s(&file, wname, wmode);
+
+ free(wname);
+ free(wmode);
+
+ return file;
+}
+
+
+#endif /* _WIN32 */
diff --git a/msvcport/msvcport_private.h b/msvcport/msvcport_private.h
new file mode 100644
index 0000000..18cfe3a
--- /dev/null
+++ b/msvcport/msvcport_private.h
@@ -0,0 +1,65 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+
+#ifndef FONTCONFIG_MSVCPORT_PRIVATE_H_
+#define FONTCONFIG_MSVCPORT_PRIVATE_H_
+
+#include <stdint.h>
+#include <wchar.h>
+
+#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, ...);
+
+ extern int64_t fc_msvcport_file_seek64(int fd, int64_t offset, int whence);
+ extern int64_t fc_msvcport_file_size64(int fd);
+
+ extern void * fc_msvcport_fopen(const char * path, const char * mode);
+
+#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/fcatomic.c b/src/fcatomic.c
index 350744a..d7a5eb2 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);
+ fc_unlink ((char *) atomic->tmp);
return FcFalse;
}
ret = fprintf (f, "%ld\n", (long)getpid());
if (ret <= 0)
{
fclose (f);
- unlink ((char *) atomic->tmp);
+ fc_unlink ((char *) atomic->tmp);
return FcFalse;
}
if (fclose (f) == EOF)
{
- unlink ((char *) atomic->tmp);
+ fc_unlink ((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 = fc_mkdir ((char *) atomic->lck, 0600);
no_link = FcTrue;
}
- (void) unlink ((char *) atomic->tmp);
+ (void) fc_unlink ((char *) atomic->tmp);
#else
- ret = mkdir ((char *) atomic->lck, 0600);
+ ret = fc_mkdir ((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 (fc_rmdir ((char *) atomic->lck) == 0)
return FcAtomicLock (atomic);
}
else
{
- if (unlink ((char *) atomic->lck) == 0)
+ if (fc_unlink ((char *) atomic->lck) == 0)
return FcAtomicLock (atomic);
}
#else
- if (rmdir ((char *) atomic->lck) == 0)
+ if (fc_rmdir ((char *) atomic->lck) == 0)
return FcAtomicLock (atomic);
#endif
}
}
return FcFalse;
}
- (void) unlink ((char *) atomic->new);
+ (void) fc_unlink ((char *) atomic->new);
return FcTrue;
}
@@ -196,7 +194,7 @@ FcBool
FcAtomicReplaceOrig (FcAtomic *atomic)
{
#ifdef _WIN32
- unlink ((const char *) atomic->file);
+ fc_unlink ((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);
+ fc_unlink ((char *) atomic->new);
}
void
FcAtomicUnlock (FcAtomic *atomic)
{
#ifdef HAVE_LINK
- if (unlink ((char *) atomic->lck) == -1)
- rmdir ((char *) atomic->lck);
+ if (fc_unlink ((char *) atomic->lck) == -1)
+ fc_rmdir ((char *) atomic->lck);
#else
- rmdir ((char *) atomic->lck);
+ fc_rmdir ((char *) atomic->lck);
#endif
}
diff --git a/src/fccache.c b/src/fccache.c
index 81985df..b307cb3 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) fc_unlink ((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 = fc_open((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 (fc_access ((char *) parent, F_OK) == 0)
+ ret = fc_mkdir ((char *) dir, 0755) == 0 && fc_chmod ((char *) dir, 0755) == 0;
+ else if (fc_access ((char *) parent, F_OK) == -1)
+ ret = FcMakeDirectory (parent) && (fc_mkdir ((char *) dir, 0755) == 0) && fc_chmod ((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 (fc_access ((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 (fc_access ((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 (fc_chmod ((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 = fc_open((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 (fc_access ((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");
+ fc_access ((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 = fc_opendir ((char *) cache_dir);
if (!d)
{
perror ((char *) cache_dir);
ret = FcFalse;
goto bail0;
}
- while ((ent = readdir (d)))
+ while ((ent = fc_readdir (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 ((char *) 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 (fc_unlink ((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);
+ fc_closedir (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 (fc_access ((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 = fc_open((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..c21d678 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 (fc_access ((char *) path, R_OK) == 0)
return path;
FcStrFree (path);
diff --git a/src/fcdir.c b/src/fcdir.c
index 2b476e8..fa00b25 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 = fc_opendir ((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 = fc_readdir (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);
+ fc_closedir (d);
bail:
if (file)
free (file);
diff --git a/src/fcformat.c b/src/fcformat.c
index 8eef7bb..d4287db 100644
--- a/src/fcformat.c
+++ b/src/fcformat.c
@@ -566,7 +566,11 @@ interpret_count (FcFormatContext *c,
count++;
}
+#ifdef _WIN32
+ _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;
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..de92d6f 100644
--- a/src/fcstat.c
+++ b/src/fcstat.c
@@ -1,3 +1,4 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t -*- */
/*
* Copyright © 2000 Keith Packard
* Copyright © 2005 Patrick Lam
@@ -55,6 +56,15 @@ typedef long long INT64;
typedef __int64 INT64;
#endif
+static FcChar32
+FcStringHashW (const wchar_t * wstr)
+{
+ char * str = fc_utf16_to_utf8(wstr);
+ FcChar32 ret = FcStringHash(str);
+ free(str);
+ return ret;
+}
+
/* Workaround for problems in the stat() in the Microsoft C library:
*
* 1) stat() uses FindFirstFile() to get the file
@@ -75,14 +85,14 @@ typedef __int64 INT64;
*/
int
-FcStat (const FcChar8 *file, struct stat *statb)
+FcStatW (const wchar_t *wfile, struct stat *statb)
{
WIN32_FILE_ATTRIBUTE_DATA wfad;
- char full_path_name[MAX_PATH];
- char *basename;
+ wchar_t wfull_path_name[MAX_PATH];
+ wchar_t *wbasename;
DWORD rc;
- if (!GetFileAttributesEx ((LPCSTR) file, GetFileExInfoStandard, &wfad))
+ if (!GetFileAttributesExW (wfile, GetFileExInfoStandard, &wfad))
return -1;
statb->st_dev = 0;
@@ -91,12 +101,12 @@ FcStat (const FcChar8 *file, struct stat *statb)
* Call GetLongPathName() to get the spelling of the path name as it
* is on disk.
*/
- rc = GetFullPathName ((LPCSTR) file, sizeof (full_path_name), full_path_name, &basename);
- if (rc == 0 || rc > sizeof (full_path_name))
+ rc = GetFullPathNameW (wfile, MAX_PATH, wfull_path_name, &wbasename);
+ if (rc == 0 || rc > MAX_PATH)
return -1;
- rc = GetLongPathName (full_path_name, full_path_name, sizeof (full_path_name));
- statb->st_ino = FcStringHash ((const FcChar8 *) full_path_name);
+ 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);
@@ -121,6 +131,21 @@ FcStat (const FcChar8 *file, struct stat *statb)
return 0;
}
+int
+FcStat (const FcChar8 *file_utf8, struct stat *statb)
+{
+ wchar_t * wfile = fc_utf8_to_utf16(file_utf8, CP_UTF8);
+ int ret = FcStatW(wfile, statb);
+ free(wfile);
+ return ret;
+}
+
+#if !defined(__MINGW32__)
+int S_ISDIR(int statb_st_mode)
+{
+ return statb_st_mode & _S_IFDIR;
+}
+#endif
#else
int
@@ -334,7 +359,7 @@ FcIsFsMmapSafe (int fd)
FcBool
FcIsFsMtimeBroken (const FcChar8 *dir)
{
- int fd = open ((const char *) dir, O_RDONLY);
+ int fd = fc_open ((const char *) dir, O_RDONLY);
if (fd != -1)
{
diff --git a/src/fcxml.c b/src/fcxml.c
index 5edc867..08a1115 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 = fc_opendir ((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 = fc_readdir (d)))
{
int d_len;
#define TAIL ".conf"
@@ -2836,9 +2838,12 @@ bail3:
bail2:
free (file);
bail1:
- closedir (d);
+ fc_closedir (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 = fc_open ((char *) filename, O_RDONLY);
if (fd == -1) {
FcStrFree (filename);
goto bail0;
_______________________________________________
Fontconfig mailing list
Fontconfig@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/fontconfig