diff --git a/CMakeLists.txt b/CMakeLists.txt
index c41579c1c..ac857ef8f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -43,6 +43,7 @@ if (APPLE)
endif ()
if (WIN32)
option(HB_HAVE_UNISCRIBE "Enable Uniscribe shaper backend on Windows" OFF)
+ option(HB_HAVE_GDI "Enable GDI integration helpers on Windows" OFF)
option(HB_HAVE_DIRECTWRITE "Enable DirectWrite shaper backend on Windows" OFF)
endif ()
option(HB_BUILD_UTILS "Build harfbuzz utils, needs cairo, freetype, and glib properly be installed" OFF)
@@ -77,6 +78,7 @@ if (HB_CHECK)
set (HB_HAVE_GRAPHITE2 ON)
if (WIN32)
set (HB_HAVE_UNISCRIBE ON)
+ set (HB_HAVE_GDI ON)
set (HB_HAVE_DIRECTWRITE ON)
elseif (APPLE)
set (HB_HAVE_CORETEXT ON)
@@ -305,6 +307,12 @@ if (APPLE AND HB_HAVE_CORETEXT)
endif ()
endif ()
+if (WIN32 AND HB_HAVE_GDI)
+ add_definitions(-DHAVE_GDI)
+ list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-gdi.h)
+ list(APPEND THIRD_PARTY_LIBS gdi32)
+endif ()
+
if (WIN32 AND HB_HAVE_UNISCRIBE)
add_definitions(-DHAVE_UNISCRIBE)
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.h)
diff --git a/appveyor.yml b/appveyor.yml
index 236bb1b12..6daf8d225 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -73,7 +73,7 @@ build_script:
- 'if "%compiler%"=="msvc2" cmake --build build --config %configuration%'
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "curl https://raw.githubusercontent.com/mirror/mingw-w64/023eb04c396d4e8d8fcf604cfababc53dae13398/mingw-w64-headers/include/dwrite_1.h > %MINGW_PREFIX%/%MINGW_CHOST%/include/dwrite_1.h"'
- - 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "cd $APPVEYOR_BUILD_FOLDER; PATH=$PATH:/mingw64/bin:/mingw32/bin; ./autogen.sh --with-uniscribe --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 --with-directwrite --build=%MINGW_CHOST% --host=%MINGW_CHOST% --prefix=%MINGW_PREFIX%; make -j3 check || .ci/fail.sh"'
+ - 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "cd $APPVEYOR_BUILD_FOLDER; PATH=$PATH:/mingw64/bin:/mingw32/bin; ./autogen.sh --with-uniscribe --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 --with-directwrite --with-gdi --build=%MINGW_CHOST% --host=%MINGW_CHOST% --prefix=%MINGW_PREFIX%; make -j3 check || .ci/fail.sh"'
cache:
- c:\tools\vcpkg\installed\
diff --git a/configure.ac b/configure.ac
index 09ce4e6ec..cebb10adf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -361,6 +361,28 @@ AM_CONDITIONAL(HAVE_UNISCRIBE, $have_uniscribe)
dnl ===========================================================================
+AC_ARG_WITH(gdi,
+ [AS_HELP_STRING([--with-gdi=@<:@yes/no/auto@:>@],
+ [Provide GDI integration helpers @<:@default=no@:>@])],,
+ [with_gdi=no])
+have_gdi=false
+if test "x$with_gdi" = "xyes" -o "x$with_gdi" = "xauto"; then
+ AC_CHECK_HEADERS(windows.h, have_gdi=true)
+fi
+if test "x$with_gdi" = "xyes" -a "x$have_gdi" != "xtrue"; then
+ AC_MSG_ERROR([gdi support requested but not found])
+fi
+if $have_gdi; then
+ GDI_CFLAGS=
+ GDI_LIBS="-lgdi32"
+ AC_SUBST(GDI_CFLAGS)
+ AC_SUBST(GDI_LIBS)
+ AC_DEFINE(HAVE_GDI, 1, [Have GDI library])
+fi
+AM_CONDITIONAL(HAVE_GDI, $have_gdi)
+
+dnl ===========================================================================
+
AC_ARG_WITH(directwrite,
[AS_HELP_STRING([--with-directwrite=@<:@yes/no/auto@:>@],
[Use the DirectWrite library (experimental) @<:@default=no@:>@])],,
@@ -510,6 +532,7 @@ Additional shapers (the more the merrier):
Platform shapers (not normally needed):
CoreText: ${have_coretext}
DirectWrite: ${have_directwrite}
+ GDI: ${have_gdi}
Uniscribe: ${have_uniscribe}
Other features:
diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index f23dcd19b..43fd76115 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -369,6 +369,11 @@ hb_ft_font_get_load_flags
hb_ft_font_set_funcs
+
+hb-gdi
+hb_gdi_face_create
+
+
hb-glib
hb_glib_get_unicode_funcs
diff --git a/src/Makefile.am b/src/Makefile.am
index 1e79483c9..54e4a02cf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -82,6 +82,13 @@ HBSOURCES += $(HB_DIRECTWRITE_sources)
HBHEADERS += $(HB_DIRECTWRITE_headers)
endif
+if HAVE_GDI
+HBCFLAGS += $(GDI_CXXFLAGS)
+HBNONPCLIBS += $(GDI_LIBS)
+HBSOURCES += $(HB_GDI_sources)
+HBHEADERS += $(HB_GDI_headers)
+endif
+
if HAVE_CORETEXT
HBCFLAGS += $(CORETEXT_CFLAGS)
HBNONPCLIBS += $(CORETEXT_LIBS)
@@ -313,6 +320,7 @@ harfbuzz.cc: Makefile.sources
$(HB_FT_sources) \
$(HB_GRAPHITE2_sources) \
$(HB_UNISCRIBE_sources) \
+ $(HB_GDI_sources) \
$(HB_DIRECTWRITE_sources) \
$(HB_CORETEXT_sources) \
; do echo '#include "'$$f'"'; done | \
diff --git a/src/Makefile.sources b/src/Makefile.sources
index e8d5bc593..4e84d869e 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -225,6 +225,9 @@ HB_CORETEXT_headers = hb-coretext.h
HB_DIRECTWRITE_sources = hb-directwrite.cc
HB_DIRECTWRITE_headers = hb-directwrite.h
+HB_GDI_sources = hb-gdi.cc
+HB_GDI_headers = hb-gdi.h
+
HB_UNISCRIBE_sources = hb-uniscribe.cc
HB_UNISCRIBE_headers = hb-uniscribe.h
diff --git a/src/harfbuzz.cc b/src/harfbuzz.cc
index 26cfac1b4..e39913761 100644
--- a/src/harfbuzz.cc
+++ b/src/harfbuzz.cc
@@ -47,5 +47,6 @@
#include "hb-ft.cc"
#include "hb-graphite2.cc"
#include "hb-uniscribe.cc"
+#include "hb-gdi.cc"
#include "hb-directwrite.cc"
#include "hb-coretext.cc"
diff --git a/src/hb-directwrite.cc b/src/hb-directwrite.cc
index 810c5e553..c14e9d2be 100644
--- a/src/hb-directwrite.cc
+++ b/src/hb-directwrite.cc
@@ -539,11 +539,6 @@ protected:
Run mRunHead;
};
-static inline uint16_t hb_dw_uint16_swap (const uint16_t v)
-{ return (v >> 8) | (v << 8); }
-static inline uint32_t hb_dw_uint32_swap (const uint32_t v)
-{ return (hb_dw_uint16_swap (v) << 16) | hb_dw_uint16_swap (v >> 16); }
-
/*
* shaper
*/
@@ -653,7 +648,7 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan,
for (unsigned int i = 0; i < num_features; ++i)
{
typographic_features.features[i].nameTag = (DWRITE_FONT_FEATURE_TAG)
- hb_dw_uint32_swap (features[i].tag);
+ hb_uint32_swap (features[i].tag);
typographic_features.features[i].parameter = features[i].value;
}
}
@@ -941,7 +936,7 @@ _hb_directwrite_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *
uint32_t length;
void *table_context;
BOOL exists;
- if (!dw_face || FAILED (dw_face->TryGetFontTable (hb_dw_uint32_swap (tag), &data,
+ if (!dw_face || FAILED (dw_face->TryGetFontTable (hb_uint32_swap (tag), &data,
&length, &table_context, &exists)))
return nullptr;
diff --git a/src/hb-gdi.cc b/src/hb-gdi.cc
new file mode 100644
index 000000000..526f1cd9e
--- /dev/null
+++ b/src/hb-gdi.cc
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2019 Ebrahim Byagowi
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include "hb.hh"
+
+#ifdef HAVE_GDI
+
+#include "hb-gdi.h"
+
+static hb_blob_t *
+_hb_gdi_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
+{
+ char *buffer = nullptr;
+ DWORD length = 0;
+
+ HDC hdc = GetDC (nullptr);
+ if (unlikely (!SelectObject (hdc, (HFONT) user_data))) goto fail;
+
+ length = GetFontData (hdc, hb_uint32_swap (tag), 0, buffer, length);
+ if (unlikely (length == GDI_ERROR)) goto fail_with_releasedc;
+
+ buffer = (char *) malloc (length);
+ if (unlikely (!buffer)) goto fail_with_releasedc;
+ length = GetFontData (hdc, hb_uint32_swap (tag), 0, buffer, length);
+ if (unlikely (length == GDI_ERROR)) goto fail_with_releasedc_and_free;
+ ReleaseDC (nullptr, hdc);
+
+ return hb_blob_create ((const char *) buffer, length, HB_MEMORY_MODE_WRITABLE, buffer, free);
+
+fail_with_releasedc_and_free:
+ free (buffer);
+fail_with_releasedc:
+ ReleaseDC (nullptr, hdc);
+fail:
+ return hb_blob_get_empty ();
+}
+
+/**
+ * hb_gdi_face_create:
+ * @hdc: a HFONT object.
+ *
+ * Return value: #hb_face_t object corresponding to the given input
+ *
+ * Since: REPLACEME
+ **/
+hb_face_t *
+hb_gdi_face_create (HFONT hfont)
+{
+ return hb_face_create_for_tables (_hb_gdi_reference_table, (void *) hfont, nullptr);
+}
+
+#endif
diff --git a/src/hb-gdi.h b/src/hb-gdi.h
new file mode 100644
index 000000000..68cc43917
--- /dev/null
+++ b/src/hb-gdi.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2019 Ebrahim Byagowi
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_GDI_H
+#define HB_GDI_H
+
+#include "hb.h"
+
+#include
+
+HB_BEGIN_DECLS
+
+HB_EXTERN hb_face_t *
+hb_gdi_face_create (HFONT hfont);
+
+HB_END_DECLS
+
+#endif /* HB_GDI_H */
diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc
index b113ed4cf..289a3477f 100644
--- a/src/hb-uniscribe.cc
+++ b/src/hb-uniscribe.cc
@@ -58,13 +58,6 @@
* Functions for using HarfBuzz with the Windows fonts.
**/
-
-static inline uint16_t hb_uint16_swap (const uint16_t v)
-{ return (v >> 8) | (v << 8); }
-static inline uint32_t hb_uint32_swap (const uint32_t v)
-{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); }
-
-
typedef HRESULT (WINAPI *SIOT) /*ScriptItemizeOpenType*/(
const WCHAR *pwcInChars,
int cInChars,
diff --git a/src/hb.hh b/src/hb.hh
index f8b5e70a8..0790de2fd 100644
--- a/src/hb.hh
+++ b/src/hb.hh
@@ -476,6 +476,11 @@ static_assert ((sizeof (hb_var_int_t) == 4), "");
/* Size signifying variable-sized array */
#define VAR 1
+/* Endian swap, used in Windows related backends */
+static inline uint16_t hb_uint16_swap (const uint16_t v)
+{ return (v >> 8) | (v << 8); }
+static inline uint32_t hb_uint32_swap (const uint32_t v)
+{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); }
/*
* Big-endian integers. Here because fundamental.