Add hb_gdi_face_create API

Based on Konstantin Ritt work posted on mailing list
This commit is contained in:
Ebrahim Byagowi 2019-07-16 22:27:01 +04:30 committed by Behdad Esfahbod
parent 3d03bb84d4
commit eb8bd2f7ec
12 changed files with 168 additions and 15 deletions

View File

@ -43,6 +43,7 @@ if (APPLE)
endif () endif ()
if (WIN32) if (WIN32)
option(HB_HAVE_UNISCRIBE "Enable Uniscribe shaper backend on Windows" OFF) 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) option(HB_HAVE_DIRECTWRITE "Enable DirectWrite shaper backend on Windows" OFF)
endif () endif ()
option(HB_BUILD_UTILS "Build harfbuzz utils, needs cairo, freetype, and glib properly be installed" OFF) 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) set (HB_HAVE_GRAPHITE2 ON)
if (WIN32) if (WIN32)
set (HB_HAVE_UNISCRIBE ON) set (HB_HAVE_UNISCRIBE ON)
set (HB_HAVE_GDI ON)
set (HB_HAVE_DIRECTWRITE ON) set (HB_HAVE_DIRECTWRITE ON)
elseif (APPLE) elseif (APPLE)
set (HB_HAVE_CORETEXT ON) set (HB_HAVE_CORETEXT ON)
@ -305,6 +307,12 @@ if (APPLE AND HB_HAVE_CORETEXT)
endif () endif ()
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) if (WIN32 AND HB_HAVE_UNISCRIBE)
add_definitions(-DHAVE_UNISCRIBE) add_definitions(-DHAVE_UNISCRIBE)
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.h) list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.h)

View File

@ -73,7 +73,7 @@ build_script:
- 'if "%compiler%"=="msvc2" cmake --build build --config %configuration%' - '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 "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: cache:
- c:\tools\vcpkg\installed\ - c:\tools\vcpkg\installed\

View File

@ -361,6 +361,28 @@ AM_CONDITIONAL(HAVE_UNISCRIBE, $have_uniscribe)
dnl =========================================================================== 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, AC_ARG_WITH(directwrite,
[AS_HELP_STRING([--with-directwrite=@<:@yes/no/auto@:>@], [AS_HELP_STRING([--with-directwrite=@<:@yes/no/auto@:>@],
[Use the DirectWrite library (experimental) @<:@default=no@:>@])],, [Use the DirectWrite library (experimental) @<:@default=no@:>@])],,
@ -510,6 +532,7 @@ Additional shapers (the more the merrier):
Platform shapers (not normally needed): Platform shapers (not normally needed):
CoreText: ${have_coretext} CoreText: ${have_coretext}
DirectWrite: ${have_directwrite} DirectWrite: ${have_directwrite}
GDI: ${have_gdi}
Uniscribe: ${have_uniscribe} Uniscribe: ${have_uniscribe}
Other features: Other features:

View File

@ -369,6 +369,11 @@ hb_ft_font_get_load_flags
hb_ft_font_set_funcs hb_ft_font_set_funcs
</SECTION> </SECTION>
<SECTION>
<FILE>hb-gdi</FILE>
hb_gdi_face_create
</SECTION>
<SECTION> <SECTION>
<FILE>hb-glib</FILE> <FILE>hb-glib</FILE>
hb_glib_get_unicode_funcs hb_glib_get_unicode_funcs

View File

@ -82,6 +82,13 @@ HBSOURCES += $(HB_DIRECTWRITE_sources)
HBHEADERS += $(HB_DIRECTWRITE_headers) HBHEADERS += $(HB_DIRECTWRITE_headers)
endif endif
if HAVE_GDI
HBCFLAGS += $(GDI_CXXFLAGS)
HBNONPCLIBS += $(GDI_LIBS)
HBSOURCES += $(HB_GDI_sources)
HBHEADERS += $(HB_GDI_headers)
endif
if HAVE_CORETEXT if HAVE_CORETEXT
HBCFLAGS += $(CORETEXT_CFLAGS) HBCFLAGS += $(CORETEXT_CFLAGS)
HBNONPCLIBS += $(CORETEXT_LIBS) HBNONPCLIBS += $(CORETEXT_LIBS)
@ -313,6 +320,7 @@ harfbuzz.cc: Makefile.sources
$(HB_FT_sources) \ $(HB_FT_sources) \
$(HB_GRAPHITE2_sources) \ $(HB_GRAPHITE2_sources) \
$(HB_UNISCRIBE_sources) \ $(HB_UNISCRIBE_sources) \
$(HB_GDI_sources) \
$(HB_DIRECTWRITE_sources) \ $(HB_DIRECTWRITE_sources) \
$(HB_CORETEXT_sources) \ $(HB_CORETEXT_sources) \
; do echo '#include "'$$f'"'; done | \ ; do echo '#include "'$$f'"'; done | \

View File

@ -225,6 +225,9 @@ HB_CORETEXT_headers = hb-coretext.h
HB_DIRECTWRITE_sources = hb-directwrite.cc HB_DIRECTWRITE_sources = hb-directwrite.cc
HB_DIRECTWRITE_headers = hb-directwrite.h 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_sources = hb-uniscribe.cc
HB_UNISCRIBE_headers = hb-uniscribe.h HB_UNISCRIBE_headers = hb-uniscribe.h

View File

@ -47,5 +47,6 @@
#include "hb-ft.cc" #include "hb-ft.cc"
#include "hb-graphite2.cc" #include "hb-graphite2.cc"
#include "hb-uniscribe.cc" #include "hb-uniscribe.cc"
#include "hb-gdi.cc"
#include "hb-directwrite.cc" #include "hb-directwrite.cc"
#include "hb-coretext.cc" #include "hb-coretext.cc"

View File

@ -539,11 +539,6 @@ protected:
Run mRunHead; 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 * shaper
*/ */
@ -653,7 +648,7 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan,
for (unsigned int i = 0; i < num_features; ++i) for (unsigned int i = 0; i < num_features; ++i)
{ {
typographic_features.features[i].nameTag = (DWRITE_FONT_FEATURE_TAG) 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; 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; uint32_t length;
void *table_context; void *table_context;
BOOL exists; 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))) &length, &table_context, &exists)))
return nullptr; return nullptr;

73
src/hb-gdi.cc Normal file
View File

@ -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

39
src/hb-gdi.h Normal file
View File

@ -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 <windows.h>
HB_BEGIN_DECLS
HB_EXTERN hb_face_t *
hb_gdi_face_create (HFONT hfont);
HB_END_DECLS
#endif /* HB_GDI_H */

View File

@ -58,13 +58,6 @@
* Functions for using HarfBuzz with the Windows fonts. * 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*/( typedef HRESULT (WINAPI *SIOT) /*ScriptItemizeOpenType*/(
const WCHAR *pwcInChars, const WCHAR *pwcInChars,
int cInChars, int cInChars,

View File

@ -476,6 +476,11 @@ static_assert ((sizeof (hb_var_int_t) == 4), "");
/* Size signifying variable-sized array */ /* Size signifying variable-sized array */
#define VAR 1 #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. * Big-endian integers. Here because fundamental.