Merge pull request #877 from fanc999/master.msvc

Fix CMake builds on Windows, MSVC in particular
diff --git a/CMakeLists.txt b/CMakeLists.txt
index defd5d6..53e8974 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -90,6 +90,8 @@
 add_definitions(-DHAVE_OT)
 add_definitions(-DHAVE_FALLBACK)
 
+# We need PYTHON_EXECUTABLE to be set for running the tests...
+include (FindPythonInterp)
 
 ## Functions and headers
 include (CheckFunctionExists)
@@ -103,7 +105,10 @@
     endif ()
   endforeach ()
 endmacro ()
-check_funcs(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l)
+if (UNIX)
+  list(APPEND CMAKE_REQUIRED_LIBRARIES m)
+endif ()
+check_funcs(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l round)
 check_include_file(unistd.h HAVE_UNISTD_H)
 if (${HAVE_UNISTD_H})
   add_definitions(-DHAVE_UNISTD_H)
@@ -116,6 +121,10 @@
 if (${HAVE_XLOCALE_H})
   add_definitions(-DHAVE_XLOCALE_H)
 endif ()
+check_include_file(stdbool.h HAVE_STDBOOL_H)
+if (${HAVE_STDBOOL_H})
+  add_definitions(-DHAVE_STDBOOL_H)
+endif ()
 
 
 if (MSVC)
@@ -385,7 +394,6 @@
 endif ()
 
 if (HB_HAVE_GOBJECT)
-  include (FindPythonInterp)
   include (FindPerl)
 
   # Use the hints from glib-2.0.pc to find glib-mkenums
@@ -638,6 +646,11 @@
     endif ()
   endforeach ()
 
+  file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list)
+  foreach (s ${introspected_sources})
+    file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list "${s}\n")
+  endforeach ()
+
   # Finally, build the introspection files...
   add_custom_command(
     TARGET harfbuzz-gobject
@@ -667,9 +680,9 @@
       --library=harfbuzz
       -L${hb_libpath}
       ${extra_libs}
-      ${introspected_sources}
+      --filelist ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list
       -o ${hb_libpath}/HarfBuzz-0.0.gir
-    DEPENDS harfbuzz-gobject harfbuzz
+    DEPENDS harfbuzz-gobject harfbuzz ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list
   )
 
   add_custom_command(
@@ -749,7 +762,7 @@
     install(TARGETS hb-view
       RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
     )
-    install(TARGETS hb-view
+    install(TARGETS hb-subset
       RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
     )
 
diff --git a/configure.ac b/configure.ac
index 1fb8a10..031be4a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -78,8 +78,15 @@
 ])
 
 # Functions, and headers
+
 AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l setlinebuf)
-AC_CHECK_HEADERS(unistd.h sys/mman.h xlocale.h)
+
+save_libs="$LIBS"
+LIBS="$LIBS -lm"
+AC_CHECK_FUNCS([round], ,[AC_CHECK_DECLS([round], , ,[#include <math.h>])])
+LIBS="$save_libs"
+
+AC_CHECK_HEADERS(unistd.h sys/mman.h xlocale.h stdbool.h)
 
 # Compiler flags
 AC_CANONICAL_HOST
diff --git a/src/hb-private.hh b/src/hb-private.hh
index daa496e..62a103c 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -1070,4 +1070,17 @@
 };
 
 
+/* fallback for round() */
+#if !defined (HAVE_ROUND) && !defined (HAVE_DECL_ROUND)
+static inline double
+round (double x)
+{
+  if (x >= 0)
+    return floor (x + 0.5);
+  else
+    return ceil (x - 0.5);
+}
+#endif
+
+
 #endif /* HB_PRIVATE_HH */
diff --git a/test/api/CMakeLists.txt b/test/api/CMakeLists.txt
index f1a2300..b540eb5 100644
--- a/test/api/CMakeLists.txt
+++ b/test/api/CMakeLists.txt
@@ -21,7 +21,12 @@
       message (FATAL_ERROR "No source file found for test ${test_name}")
     endif ()
     target_link_libraries (${test_name} harfbuzz harfbuzz-subset)
-    add_test (${test_name} ${test_name})
+    if (WIN32)
+      set_property (TARGET ${test_name} PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+      add_test (NAME ${test_name} COMMAND ${test_name})
+    else (WIN32)
+      add_test (${test_name} ${test_name})
+    endif (WIN32)
   endforeach ()
   set_tests_properties (${TEST_PROGS} PROPERTIES ENVIRONMENT
     "G_TEST_SRCDIR=${CMAKE_CURRENT_SOURCE_DIR};G_TEST_BUILDDIR=${CMAKE_CURRENT_BINARY_DIR}"
diff --git a/test/api/hb-subset-test.h b/test/api/hb-subset-test.h
index f8386b1..49c3fdd 100644
--- a/test/api/hb-subset-test.h
+++ b/test/api/hb-subset-test.h
@@ -32,6 +32,18 @@
 #include "hb-test.h"
 #include "hb-subset.h"
 
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+typedef short bool;
+# ifndef true
+#  define true 1
+# endif
+# ifndef false
+#  define false 0
+# endif
+#endif
+
 
 HB_BEGIN_DECLS
 
@@ -122,9 +134,10 @@
                       hb_face_t *actual,
                       hb_tag_t   table)
 {
+  hb_blob_t *expected_blob, *actual_blob;
   fprintf(stderr, "compare %c%c%c%c\n", HB_UNTAG(table));
-  hb_blob_t *expected_blob = hb_face_reference_table (expected, table);
-  hb_blob_t *actual_blob = hb_face_reference_table (actual, table);
+  expected_blob = hb_face_reference_table (expected, table);
+  actual_blob = hb_face_reference_table (actual, table);
   hb_test_assert_blobs_equal (expected_blob, actual_blob);
   hb_blob_destroy (expected_blob);
   hb_blob_destroy (actual_blob);
diff --git a/test/api/test-subset-cmap.c b/test/api/test-subset-cmap.c
index 0771579..618b725 100644
--- a/test/api/test-subset-cmap.c
+++ b/test/api/test-subset-cmap.c
@@ -24,8 +24,6 @@
  * Google Author(s): Roderick Sheeter
  */
 
-#include <stdbool.h>
-
 #include "hb-test.h"
 #include "hb-subset-test.h"
 
@@ -38,9 +36,10 @@
   hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.cmap-format12-only.ttf");
 
   hb_set_t *codepoints = hb_set_create ();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 97);
   hb_set_add (codepoints, 99);
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('c','m','a','p'));
@@ -56,10 +55,11 @@
   hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.cmap-format12-only.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 97);
   hb_set_add (codepoints, 98);
   hb_set_add (codepoints, 99);
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('c','m','a','p'));
diff --git a/test/api/test-subset-glyf.c b/test/api/test-subset-glyf.c
index 8e17e8d..e72086a 100644
--- a/test/api/test-subset-glyf.c
+++ b/test/api/test-subset-glyf.c
@@ -24,8 +24,6 @@
  * Google Author(s): Garret Rieger
  */
 
-#include <stdbool.h>
-
 #include "hb-test.h"
 #include "hb-subset-test.h"
 
@@ -66,9 +64,10 @@
   hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 97);
   hb_set_add (codepoints, 99);
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f'));
@@ -87,8 +86,9 @@
   hb_face_t *face_subset = hb_subset_test_open_font ("fonts/Roboto-Regular.components.subset.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_face_t *face_generated_subset;
   hb_set_add (codepoints, 0x1fc);
-  hb_face_t *face_generated_subset = hb_subset_test_create_subset (face_components, hb_subset_test_create_input (codepoints));
+  face_generated_subset = hb_subset_test_create_subset (face_components, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_subset, face_generated_subset, HB_TAG ('g','l','y','f'));
@@ -106,10 +106,11 @@
   hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 97);
   hb_set_add (codepoints, 98);
   hb_set_add (codepoints, 99);
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('g','l','y','f'));
@@ -127,11 +128,13 @@
   hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.nohints.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_subset_input_t *input;
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
-  hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
+  input = hb_subset_test_create_input (codepoints);
   *hb_subset_input_drop_hints(input) = true;
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, input);
+  face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('l','o','c', 'a'));
@@ -150,11 +153,13 @@
   hb_face_t *face_subset = hb_subset_test_open_font ("fonts/Roboto-Regular.components.1fc.nohints.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_subset_input_t *input;
+  hb_face_t *face_generated_subset;
   hb_set_add (codepoints, 0x1fc);
-  hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
+  input = hb_subset_test_create_input (codepoints);
   *hb_subset_input_drop_hints(input) = true;
 
-  hb_face_t *face_generated_subset = hb_subset_test_create_subset (face_components, input);
+  face_generated_subset = hb_subset_test_create_subset (face_components, input);
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_subset, face_generated_subset, HB_TAG ('g','l','y','f'));
diff --git a/test/api/test-subset-hdmx.c b/test/api/test-subset-hdmx.c
index 5211dbc..609ee06 100644
--- a/test/api/test-subset-hdmx.c
+++ b/test/api/test-subset-hdmx.c
@@ -24,8 +24,6 @@
  * Google Author(s): Garret Rieger
  */
 
-#include <stdbool.h>
-
 #include "hb-test.h"
 #include "hb-subset-test.h"
 
@@ -39,9 +37,10 @@
   hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.ttf");
 
   hb_set_t *codepoints = hb_set_create ();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('h','d','m','x'));
@@ -57,10 +56,11 @@
   hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'b');
   hb_set_add (codepoints, 'c');
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('h','d','m','x'));
diff --git a/test/api/test-subset-hmtx.c b/test/api/test-subset-hmtx.c
index 2b76452..fc57718 100644
--- a/test/api/test-subset-hmtx.c
+++ b/test/api/test-subset-hmtx.c
@@ -24,8 +24,6 @@
  * Google Author(s): Roderick Sheeter
  */
 
-#include <stdbool.h>
-
 #include "hb-test.h"
 #include "hb-subset-test.h"
 
@@ -53,9 +51,10 @@
   hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.ttf");
 
   hb_set_t *codepoints = hb_set_create ();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   check_num_hmetrics(face_abc_subset, 3); /* nothing has same width */
@@ -74,9 +73,10 @@
   hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Inconsolata-Regular.ac.ttf");
 
   hb_set_t *codepoints = hb_set_create ();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   check_num_hmetrics(face_abc_subset, 1); /* everything has same width */
@@ -95,9 +95,10 @@
   hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Inconsolata-Regular.ac.widerc.ttf");
 
   hb_set_t *codepoints = hb_set_create ();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   check_num_hmetrics(face_abc_subset, 3); /* c is wider */
@@ -115,9 +116,10 @@
   hb_face_t *face_ab = hb_subset_test_open_font ("fonts/Inconsolata-Regular.ab.ttf");
 
   hb_set_t *codepoints = hb_set_create ();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'b');
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   check_num_hmetrics(face_abc_subset, 1); /* everything left has same width */
@@ -134,10 +136,11 @@
   hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'b');
   hb_set_add (codepoints, 'c');
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   check_num_hmetrics(face_abc_subset, 4); /* nothing has same width */
diff --git a/test/api/test-subset-os2.c b/test/api/test-subset-os2.c
index e9db9be..de63a3f 100644
--- a/test/api/test-subset-os2.c
+++ b/test/api/test-subset-os2.c
@@ -24,7 +24,6 @@
  * Google Author(s): Garret Rieger
  */
 
-#include <stdbool.h>
 
 #include "hb-test.h"
 #include "hb-subset-test.h"
@@ -36,8 +35,9 @@
   hb_face_t *face_b = hb_subset_test_open_font("fonts/Roboto-Regular.b.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 98);
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_b, face_abc_subset, HB_TAG ('O','S','/','2'));
diff --git a/test/fuzzing/CMakeLists.txt b/test/fuzzing/CMakeLists.txt
index e31c744..fe4cf79 100644
--- a/test/fuzzing/CMakeLists.txt
+++ b/test/fuzzing/CMakeLists.txt
@@ -13,6 +13,6 @@
 
   target_compile_definitions(hb-fuzzer PUBLIC ${FUZZING_CPPFLAGS})
   add_test (NAME hb-fuzzer
-    COMMAND python run-fuzzer-tests.py $<TARGET_FILE:hb-fuzzer>
+    COMMAND "${PYTHON_EXECUTABLE}" run-fuzzer-tests.py $<TARGET_FILE:hb-fuzzer>
     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
 endif ()
diff --git a/test/shaping/CMakeLists.txt b/test/shaping/CMakeLists.txt
index 4bdc5c9..7c2c999 100644
--- a/test/shaping/CMakeLists.txt
+++ b/test/shaping/CMakeLists.txt
@@ -3,7 +3,7 @@
   extract_make_variable (TESTS ${INHOUSE})
   foreach (test IN ITEMS ${TESTS})
     add_test (NAME ${test}
-      COMMAND python run-tests.py $<TARGET_FILE:hb-shape> "data/in-house/${test}"
+      COMMAND "${PYTHON_EXECUTABLE}" run-tests.py $<TARGET_FILE:hb-shape> "data/in-house/${test}"
       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
   endforeach ()
 
@@ -11,7 +11,7 @@
   extract_make_variable (TESTS ${TEXTRENDERING})
   foreach (test IN ITEMS ${TESTS})
     add_test (NAME ${test}
-      COMMAND python run-tests.py $<TARGET_FILE:hb-shape> "data/text-rendering-tests/${test}"
+      COMMAND "${PYTHON_EXECUTABLE}" run-tests.py $<TARGET_FILE:hb-shape> "data/text-rendering-tests/${test}"
       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
   endforeach ()
 endif ()
diff --git a/test/subset/CMakeLists.txt b/test/subset/CMakeLists.txt
index ea04105..af2b41a 100644
--- a/test/subset/CMakeLists.txt
+++ b/test/subset/CMakeLists.txt
@@ -3,7 +3,7 @@
   extract_make_variable (TESTS ${SOURCES})
   foreach (test IN ITEMS ${TESTS})
     add_test (NAME ${test}
-      COMMAND python run-tests.py $<TARGET_FILE:hb-subset> "data/${test}"
+      COMMAND "${PYTHON_EXECUTABLE}" run-tests.py $<TARGET_FILE:hb-subset> "data/${test}"
       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
     set_property(TEST ${test} PROPERTY SKIP_RETURN_CODE 77)
   endforeach ()