Compare commits

...

4 Commits

Author SHA1 Message Date
Chun-wei Fan
22543210ba demos/font_features.c: Support PangoWin32 Font as well
Also support PangoWin32 fonts for the font features demo, which will
enable running on Windows even if PangoFT support is not enabled or is
unused.

Check for PangoWin32 as well in configure to see whether the font
features demo will be built.  If either PangoFT2 or PangoWin32 is found
along with HarfBuzz, build the font features demo.
2019-04-17 17:09:31 +08:00
Chun-wei Fan
17a60d5752 gtk/gtkfontchooserwidget.c: Use Native Windows API for language/scripts
This eliminates the need to install iso-codes on Windows, which is
largely unneeded because we can just use the Windows APIs to do that for
us.
2019-04-17 17:09:31 +08:00
Chun-wei Fan
12da6b4712 gtk/gtkfontchooserwidget.c: Support PangoWin32 fonts as well
The current font tweaking support here actually assumes that
PangoFCFonts are used, which is not the case on Windows unless one
specifically uses the FontConfig backend (set PANGOCAIRO_BACKEND=fc).
This means that if GTK+ is build with HarfBuzz and PangoFT support
enabled, the attempting to run the font tweaking support code on Windows
will crash unless the FontConfig Pango backend is used.

Use the utility code that we just added to support turning the
PangoWin32Font into a FT_Face, so that we can load it using HarfBuzz,
which is necessary before Pango is updated to use HarfBuzz for shaping
on all supported backends at least.  This will also allow the font
tweaking page to at least display properly even if GTK+ is not built
with PangoFT support.

Note that for the font tweaking updates to be applied, PangoWin32 needs
to be updated as well, but at least for the GTK+ front this will pave
the foundation for this.
2019-04-17 17:09:31 +08:00
Chun-wei Fan
43adfea5f0 gtk: Add utility source to convert from PangoFont to FT_Face
...when we are not using PangoFT2, so that we can continue using
HarfBuzz to query the OpenType tags for use with font tweaking, at least
before Pango uses HarfBuzz to shape on all platforms.
2019-04-17 17:09:25 +08:00
7 changed files with 556 additions and 45 deletions

View File

@@ -11,8 +11,9 @@
* axes are also offered for customization.
*/
#include "config.h"
#include <gtk/gtk.h>
#include <pango/pangofc-font.h>
#include <hb.h>
#include <hb-ot.h>
#include <hb-ft.h>
@@ -23,8 +24,15 @@
#include "open-type-layout.h"
#include "fontplane.h"
#include "script-names.h"
#include "language-names.h"
#ifdef G_OS_WIN32
extern GHashTable *
gtk_font_chooser_widget_get_win32_locales (void);
#else
# include "script-names.h"
# include "language-names.h"
#endif
#include "gtkpangofontutilsprivate.h"
#define MAKE_TAG(a,b,c,d) (unsigned int)(((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
@@ -422,7 +430,17 @@ update_display (void)
pango_attr_list_unref (attrs);
}
static PangoFont *
typedef struct
{
PangoContext *context;
PangoFontMap *map;
PangoFont *font;
gpointer *ft_extra_items;
} demo_pango_items;
static demo_pango_items items;
static void
get_pango_font (void)
{
PangoFontDescription *desc;
@@ -430,6 +448,9 @@ get_pango_font (void)
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (font));
context = gtk_widget_get_pango_context (font);
items.map = pango_context_get_font_map (context);
items.font = pango_font_map_load_font (items.map, context, desc);
items.ft_extra_items = _gtk_pango_font_init_extra_ft_items (items.font);
return pango_context_load_font (context, desc);
}
@@ -485,7 +506,6 @@ update_script_combo (void)
hb_font_t *hb_font;
gint i, j, k;
FT_Face ft_face;
PangoFont *pango_font;
GHashTable *tags;
GHashTableIter iter;
TagPair *pair;
@@ -504,8 +524,10 @@ update_script_combo (void)
store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
pango_font = get_pango_font ();
ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)),
get_pango_font ();
ft_face = _gtk_pango_font_get_ft_face (items.font,
items.map,
items.ft_extra_items);
hb_font = hb_ft_font_create (ft_face, NULL);
tags = g_hash_table_new_full (tag_pair_hash, tag_pair_equal, g_free, NULL);
@@ -549,8 +571,12 @@ update_script_combo (void)
hb_face_destroy (hb_face);
}
pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
g_object_unref (pango_font);
_gtk_pango_font_release_ft_face (items.font, items.ft_extra_items);
if (_gtk_pango_font_release_ft_items (items.ft_extra_items))
g_free (items.ft_extra_items);
g_object_unref (items.font);
g_hash_table_iter_init (&iter, tags);
while (g_hash_table_iter_next (&iter, (gpointer *)&pair, NULL))
@@ -563,7 +589,16 @@ update_script_combo (void)
langname = NC_("Language", "Default");
else
{
#ifdef G_OS_WIN32
GHashTable *ht_win32_languages = NULL;
hb_language_t lang;
ht_win32_languages = _gtk_font_chooser_widget_get_win32_locales ();
lang = hb_ot_tag_to_language (pair->lang_tag);
langname = g_hash_table_lookup (ht_win32_languages, lang);
#else
langname = get_language_name_for_tag (pair->lang_tag);
#endif
if (!langname)
{
hb_tag_to_string (pair->lang_tag, langbuf);
@@ -606,7 +641,6 @@ update_features (void)
GtkTreeModel *model;
GtkTreeIter iter;
guint script_index, lang_index;
PangoFont *pango_font;
FT_Face ft_face;
hb_font_t *hb_font;
GList *l;
@@ -631,8 +665,8 @@ update_features (void)
2, &lang_index,
-1);
pango_font = get_pango_font ();
ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)),
get_pango_font ();
ft_face = _gtk_pango_font_get_ft_face (items.font, items.map, items.ft_extra_items);
hb_font = hb_ft_font_create (ft_face, NULL);
if (hb_font)
@@ -719,8 +753,12 @@ update_features (void)
hb_face_destroy (hb_face);
}
pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
g_object_unref (pango_font);
_gtk_pango_font_release_ft_face (items.font, items.ft_extra_items);
if (_gtk_pango_font_release_ft_items (items.ft_extra_items))
g_free (items.ft_extra_items);
g_object_unref (items.font);
}
#define FixedToFloat(f) (((float)(f))/65536.0)
@@ -1519,7 +1557,6 @@ static void
update_font_variations (void)
{
GtkWidget *child, *next;
PangoFont *pango_font;
FT_Face ft_face;
FT_MM_Var *ft_mm_var;
FT_Error ret;
@@ -1537,8 +1574,10 @@ update_font_variations (void)
g_hash_table_remove_all (axes);
g_hash_table_remove_all (instances);
pango_font = get_pango_font ();
ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)),
get_pango_font ();
ft_face = _gtk_pango_font_get_ft_face (items.font,
items.map,
items.ft_extra_items);
ret = FT_Get_MM_Var (ft_face, &ft_mm_var);
if (ret == 0)
@@ -1592,8 +1631,13 @@ update_font_variations (void)
free (ft_mm_var);
}
pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
g_object_unref (pango_font);
_gtk_pango_font_release_ft_face (items.font, items.ft_extra_items);
if (_gtk_pango_font_release_ft_items (items.ft_extra_items))
g_free (items.ft_extra_items);
g_object_unref (items.font);
}
static void

View File

@@ -86,10 +86,18 @@ extra_demo_sources = files(['main.c',
'bluroverlay.c',
'demotaggedentry.c'])
if harfbuzz_dep.found() and pangoft_dep.found()
if build_with_harfbuzz
demos += files('font_features.c')
extra_demo_sources += files(['script-names.c', 'language-names.c'])
gtkdemo_deps += [ harfbuzz_dep, ]
extra_demo_sources += files('../../gtk/gtkpangofontutils.c')
gtkdemo_deps += [ harfbuzz_dep ]
if pangoft_dep.found()
gtkdemo_deps += [ pangoft_dep ]
endif
if os_win32
gtkdemo_deps += [ ft2_dep ]
else
extra_demo_sources += files(['script-names.c', 'language-names.c'])
endif
endif
if os_unix

View File

@@ -25,6 +25,7 @@
#include "gtkfontchooserwidget.h"
#include "gtkfontchooserwidgetprivate.h"
#include "gtkpangofontutilsprivate.h"
#include "gtkadjustment.h"
#include "gtkbuildable.h"
@@ -56,16 +57,19 @@
#include "gtkgesturemultipress.h"
#include "gtkeventcontrollerscroll.h"
#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT)
#include <pango/pangofc-font.h>
#include <hb.h>
#include <hb-ot.h>
#include <hb-ft.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_MULTIPLE_MASTERS_H
#include "language-names.h"
#include "script-names.h"
#if defined(HAVE_HARFBUZZ)
# include <hb.h>
# include <hb-ot.h>
# include <hb-ft.h>
# include <ft2build.h>
# include FT_FREETYPE_H
# include FT_MULTIPLE_MASTERS_H
# ifdef HAVE_PANGOFT
# include "language-names.h"
# include "script-names.h"
# endif
#endif
#include "open-type-layout.h"
@@ -143,6 +147,8 @@ struct _GtkFontChooserWidgetPrivate
GList *feature_items;
GAction *tweak_action;
gpointer ft_extra_items;
};
enum {
@@ -870,7 +876,7 @@ gtk_font_chooser_widget_init (GtkFontChooserWidget *fontchooser)
/* Load data and set initial style-dependent parameters */
gtk_font_chooser_widget_load_fonts (fontchooser, TRUE);
#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT)
#if defined(HAVE_HARFBUZZ)
gtk_font_chooser_widget_populate_features (fontchooser);
#endif
@@ -1188,6 +1194,11 @@ gtk_font_chooser_widget_finalize (GObject *object)
g_free (priv->font_features);
#ifdef HAVE_HARFBUZZ
if (_gtk_pango_font_release_ft_items (priv->ft_extra_items))
g_free (priv->ft_extra_items);
#endif
G_OBJECT_CLASS (gtk_font_chooser_widget_parent_class)->finalize (object);
}
@@ -1459,7 +1470,7 @@ gtk_font_chooser_widget_ensure_selection (GtkFontChooserWidget *fontchooser)
}
}
#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT)
#if defined(HAVE_HARFBUZZ)
/* OpenType variations */
@@ -1610,10 +1621,14 @@ gtk_font_chooser_widget_update_font_variations (GtkFontChooserWidget *fontchoose
{
GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
PangoFont *pango_font;
FT_Face ft_face;
FT_MM_Var *ft_mm_var;
FT_Error ret;
FT_Byte *font_file_data = NULL;
gboolean has_axis = FALSE;
PangoFontMap *font_map = NULL;
gpointer ft_extra_items = NULL;
if (priv->updating_variations)
return FALSE;
@@ -1626,7 +1641,21 @@ gtk_font_chooser_widget_update_font_variations (GtkFontChooserWidget *fontchoose
pango_font = pango_context_load_font (gtk_widget_get_pango_context (GTK_WIDGET (fontchooser)),
priv->font_desc);
ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font));
font_map = priv->font_map;
ft_extra_items = priv->ft_extra_items;
if (!font_map)
font_map = pango_cairo_font_map_get_default ();
if (!ft_extra_items)
{
ft_extra_items = _gtk_pango_font_init_extra_ft_items (pango_font);
if (ft_extra_items != NULL)
priv->ft_extra_items = ft_extra_items;
}
ft_face = _gtk_pango_font_get_ft_face (pango_font, font_map, ft_extra_items);
ret = FT_Get_MM_Var (ft_face, &ft_mm_var);
if (ret == 0)
@@ -1658,7 +1687,8 @@ gtk_font_chooser_widget_update_font_variations (GtkFontChooserWidget *fontchoose
free (ft_mm_var);
}
pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
_gtk_pango_font_release_ft_face (pango_font, ft_extra_items);
g_object_unref (pango_font);
return has_axis;
@@ -2130,6 +2160,8 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser)
GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
PangoFont *pango_font;
FT_Face ft_face;
FT_Byte *font_file_data = NULL;
hb_font_t *hb_font;
hb_tag_t script_tag;
hb_tag_t lang_tag;
@@ -2138,6 +2170,8 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser)
int i, j;
GList *l;
gboolean has_feature = FALSE;
PangoFontMap *font_map = NULL;
gpointer ft_extra_items = NULL;
for (l = priv->feature_items; l; l = l->next)
{
@@ -2151,7 +2185,22 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser)
pango_font = pango_context_load_font (gtk_widget_get_pango_context (GTK_WIDGET (fontchooser)),
priv->font_desc);
ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)),
font_map = priv->font_map;
ft_extra_items = priv->ft_extra_items;
if (!font_map)
font_map = pango_cairo_font_map_get_default ();
if (!ft_extra_items)
{
ft_extra_items = _gtk_pango_font_init_extra_ft_items (pango_font);
if (ft_extra_items != NULL)
priv->ft_extra_items = ft_extra_items;
}
ft_face = _gtk_pango_font_get_ft_face (pango_font, font_map, ft_extra_items);
hb_font = hb_ft_font_create (ft_face, NULL);
if (hb_font)
@@ -2215,7 +2264,8 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser)
hb_font_destroy (hb_font);
}
pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
_gtk_pango_font_release_ft_face (pango_font, ft_extra_items);
g_object_unref (pango_font);
return has_feature;
@@ -2315,7 +2365,7 @@ gtk_font_chooser_widget_merge_font_desc (GtkFontChooserWidget *fontchooser
gtk_font_chooser_widget_update_marks (fontchooser);
#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT)
#if defined(HAVE_HARFBUZZ)
if (gtk_font_chooser_widget_update_font_features (fontchooser))
has_tweak = TRUE;
if (gtk_font_chooser_widget_update_font_variations (fontchooser))

341
gtk/gtkpangofontutils.c Normal file
View File

@@ -0,0 +1,341 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2019 Chun-wei Fan <fanc999@yahoo.com.tw>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#ifdef HAVE_HARFBUZZ
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_MODULE_H
#include "gtkpangofontutilsprivate.h"
#ifdef G_OS_WIN32
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <hb.h>
#endif
#ifdef HAVE_PANGOFT
# include <pango/pangofc-font.h>
/* On Windows, we need to check whether the PangoFont is a FontConfig Font or a Win32/GDI font,
* and acquire/release the FT_Face accordingly.
*/
# ifdef G_OS_WIN32
# define FT_EXT_ITEM_INIT(f) \
PANGO_IS_FC_FONT(f) ? \
NULL : \
g_new0 (gtk_win32_ft_items, 1)
# define PANGO_FONT_GET_FT_FACE(f,m,i) \
PANGO_IS_FC_FONT(f) ? \
pango_fc_font_lock_face (PANGO_FC_FONT (f)) : \
pangowin32_font_get_ftface (f, m, i)
# define PANGO_FONT_RELEASE_FT_FACE(f,i) \
PANGO_IS_FC_FONT(f) ? \
pango_fc_font_unlock_face (PANGO_FC_FONT (f)) : \
pangowin32_font_release_ftface (i);
# define RELEASE_EXTRA_FT_ITEMS(i) pangowin32_font_release_extra_ft_items(i)
# else /* On non-Windows, acquire/release the FT_Face as we did before */
# define FT_EXT_ITEM_INIT(f) NULL
# define PANGO_FONT_GET_FT_FACE(f,m,i) pango_fc_font_lock_face (PANGO_FC_FONT (f))
# define PANGO_FONT_RELEASE_FT_FACE(f,i) pango_fc_font_unlock_face (PANGO_FC_FONT (f))
# define RELEASE_EXTRA_FT_ITEMS(i) FALSE
# endif
#elif defined (G_OS_WIN32) /* HAVE_PANGOFT */
/* Until Pango uses HarfBuzz for shaping on all platforms, we need to go through FreeType */
# define FT_EXT_ITEM_INIT(f) g_new0 (gtk_win32_ft_items, 1)
# define PANGO_FONT_GET_FT_FACE(f,m,i) pangowin32_font_get_ftface (f, m, i)
# define PANGO_FONT_RELEASE_FT_FACE(f,i) pangowin32_font_release_ftface (i)
# define RELEASE_EXTRA_FT_ITEMS(i) pangowin32_font_release_extra_ft_items(i)
#endif /* G_OS_WIN32 */
/* Note: The following is for both builds with and without PangoFT support on Windows */
#ifdef G_OS_WIN32
#include <pango/pangowin32.h>
/* Check for TTC fonts and get their font data */
# define FONT_TABLE_TTCF (('t' << 0) + ('t' << 8) + ('c' << 16) + ('f' << 24))
typedef struct _gtk_win32_ft_items
{
FT_Library ft_lib;
FT_Byte *font_data_stream;
FT_Face face;
HDC hdc;
LOGFONTW *logfont;
HFONT hfont;
PangoWin32FontCache *cache;
} gtk_win32_ft_items;
#define WIN32_FT_FACE_FAIL(msg) \
{ \
g_warning(msg); \
goto ft_face_fail; \
}
static FT_Face
pangowin32_font_get_ftface (PangoFont *font,
PangoFontMap *font_map,
gtk_win32_ft_items *item)
{
PangoWin32FontCache *cache = NULL;
LOGFONTW *logfont = NULL;
HFONT hfont = NULL;
HFONT hfont_orig = NULL;
HDC hdc = NULL;
DWORD is_ttc_font;
FT_Face face;
FT_Byte *font_stream = NULL;
unsigned char buf[4];
gsize font_size;
if (item == NULL)
item = g_new0 (gtk_win32_ft_items, 1);
cache = pango_win32_font_map_get_font_cache (font_map);
if (!cache)
WIN32_FT_FACE_FAIL ("Failed to acquire PangoWin32FontCache");
logfont = pango_win32_font_logfontw (font);
if (logfont == NULL)
WIN32_FT_FACE_FAIL ("Unable to acquire LOGFONT from PangoFont");
hfont = pango_win32_font_cache_loadw (cache, logfont);
if (hfont == NULL)
WIN32_FT_FACE_FAIL ("Unable to acquire HFONT from PangoWin32FontCache with LOGFONT (LOGFONT invalid?)");
hdc = GetDC (NULL);
if (hdc == NULL)
WIN32_FT_FACE_FAIL ("Failed to acquire DC");
if (item->ft_lib == NULL)
{
if (FT_Init_FreeType (&item->ft_lib) != FT_Err_Ok)
WIN32_FT_FACE_FAIL ("Failed to initialize FreeType for PangoWin32Font->FT_Face transformation");
}
hfont_orig = SelectObject (hdc, hfont);
if (hfont_orig == HGDI_ERROR)
WIN32_FT_FACE_FAIL ("SelectObject() for the PangoFont failed");
/* is_ttc_font is GDI_ERROR if the HFONT does not refer to a font in a TTC when,
* specifying FONT_TABLE_TTCF for the Font Table type, otherwise it is 1,
* so try again without specifying FONT_TABLE_TTCF if is_ttc_font is not 1
*/
is_ttc_font = GetFontData (hdc, FONT_TABLE_TTCF, 0, &buf, 1);
if (is_ttc_font == 1)
font_size = GetFontData (hdc, FONT_TABLE_TTCF, 0, NULL, 0);
else
font_size = GetFontData (hdc, 0, 0, NULL, 0);
if (font_size == GDI_ERROR)
WIN32_FT_FACE_FAIL ("Could not acquire font size from GetFontData()");
/* Now, get the font data stream that we need for creating the FT_Face */
font_stream = g_malloc (font_size);
if (GetFontData (hdc,
is_ttc_font == 1 ? FONT_TABLE_TTCF : 0,
0,
font_stream,
font_size) == GDI_ERROR)
{
WIN32_FT_FACE_FAIL ("Unable to get data stream of font!");
}
/* Finally, create the FT_Face we need */
if (FT_New_Memory_Face (item->ft_lib,
font_stream,
font_size,
0,
&face) == FT_Err_Ok)
{
/* We need to track these because we can only release/free those items *after* we
* are done with them in FreeType
*/
item->cache = cache;
item->logfont = logfont;
item->hdc = hdc;
item->hfont = hfont;
item->font_data_stream = font_stream;
item->face = face;
return item->face;
}
else
WIN32_FT_FACE_FAIL ("Unable to create FT_Face from font data stream!");
ft_face_fail:
if (font_stream != NULL)
g_free (font_stream);
if (hdc != NULL)
ReleaseDC (NULL, hdc);
if (cache != NULL && hfont != NULL)
pango_win32_font_cache_unload (cache, hfont);
if (logfont != NULL)
g_free (logfont);
return NULL;
}
#undef WIN32_FT_FACE_FAIL
static void
pangowin32_font_release_ftface (gtk_win32_ft_items *item)
{
FT_Done_Face (item->face);
g_free (item->font_data_stream);
ReleaseDC (NULL, item->hdc);
item->hdc = NULL;
pango_win32_font_cache_unload (item->cache, item->hfont);
g_free (item->logfont);
}
static gboolean
pangowin32_font_release_extra_ft_items (gpointer ft_item)
{
gtk_win32_ft_items *item = NULL;
if (ft_item == NULL)
return FALSE;
item = (gtk_win32_ft_items *)ft_item;
if (item->ft_lib != NULL)
{
FT_Done_Library (item->ft_lib);
item->ft_lib = NULL;
}
return TRUE;
}
/* if we are using native Windows (PangoWin32),
* use native Windows API for language/script names
*/
static BOOL CALLBACK
get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
{
wchar_t *langname_w = NULL;
wchar_t *locale_abbrev_w = NULL;
gchar *langname, *locale_abbrev, *locale, *p;
gint i;
hb_language_t lang;
GHashTable *ht_scripts_langs = (GHashTable *)param;
gint langname_size, locale_abbrev_size;
langname_size = GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, 0);
if (langname_size == 0)
return FALSE;
langname_w = g_new0 (wchar_t, langname_size);
if (langname_size == 0)
return FALSE;
GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, langname_size);
langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL);
locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL);
p = strchr (locale, '-');
lang = hb_language_from_string (locale, p ? p - locale : -1);
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
g_hash_table_insert (ht_scripts_langs, lang, langname);
/* track 3-letter ISO639-2/3 language codes as well */
locale_abbrev_size = GetLocaleInfoEx (locale_w, LOCALE_SABBREVLANGNAME, locale_abbrev_w, 0);
if (locale_abbrev_size > 0)
{
locale_abbrev_w = g_new0 (wchar_t, locale_abbrev_size);
GetLocaleInfoEx (locale_w, LOCALE_SABBREVLANGNAME, locale_abbrev_w, locale_abbrev_size);
locale_abbrev = g_utf16_to_utf8 (locale_abbrev_w, -1, NULL, NULL, NULL);
lang = hb_language_from_string (locale_abbrev, -1);
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
g_hash_table_insert (ht_scripts_langs, lang, langname);
g_free (locale_abbrev);
g_free (locale_abbrev_w);
}
g_free (locale);
g_free (langname_w);
return TRUE;
}
GHashTable *
_gtk_font_chooser_widget_get_win32_locales (void)
{
static GHashTable *ht_langtag_locales = NULL;
static volatile gsize inited = 0;
if (g_once_init_enter (&inited))
{
gchar *locales, *script;
ht_langtag_locales = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
EnumSystemLocalesEx (&get_win32_all_locales_scripts, LOCALE_ALL, (LPARAM)ht_langtag_locales, NULL);
g_once_init_leave (&inited, 1);
}
return ht_langtag_locales;
}
#endif /* G_OS_WIN32 */
gpointer
_gtk_pango_font_init_extra_ft_items (PangoFont *font)
{
return FT_EXT_ITEM_INIT (font);
}
FT_Face
_gtk_pango_font_get_ft_face (PangoFont *font,
PangoFontMap *font_map,
gpointer ft_items)
{
return PANGO_FONT_GET_FT_FACE (font, font_map, ft_items);
}
void
_gtk_pango_font_release_ft_face (PangoFont *font,
gpointer ft_items)
{
PANGO_FONT_RELEASE_FT_FACE (font, ft_items);
}
gboolean
_gtk_pango_font_release_ft_items (gpointer ft_items)
{
return RELEASE_EXTRA_FT_ITEMS (ft_items);
}
#endif /* HAVE_HARFBUZZ */

View File

@@ -0,0 +1,44 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2019 Chun-wei Fan <fanc999@yahoo.com.tw>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_PANGO_FONT_UTILS_PRIVATE_H__
#define __GTK_PANGO_FONT_UTILS_PRIVATE_H__
#include <pango/pango.h>
#if defined(HAVE_HARFBUZZ)
#include <ft2build.h>
#include FT_FREETYPE_H
gpointer _gtk_pango_font_init_extra_ft_items (PangoFont *font);
FT_Face _gtk_pango_font_get_ft_face (PangoFont *font,
PangoFontMap *font_map,
gpointer ft_items);
void _gtk_pango_font_release_ft_face (PangoFont *font,
gpointer ft_items);
gboolean _gtk_pango_font_release_ft_items (gpointer ft_items);
GHashTable *
_gtk_font_chooser_widget_get_win32_locales (void);
#endif /* HAVE_HARFBUZZ */
#endif /* __GTK_PANGO_FONT_UTILS_PRIVATE_H__ */

View File

@@ -901,12 +901,20 @@ gtk_deps = [
graphene_dep,
]
if harfbuzz_dep.found() and pangoft_dep.found()
gtk_deps += [ harfbuzz_dep, pangoft_dep ]
if build_with_harfbuzz
gtk_sources += files([
'language-names.c',
'script-names.c',
'gtkpangofontutils.c',
])
gtk_deps += [ harfbuzz_dep ]
if pangoft_dep.found()
gtk_deps += [ pangoft_dep ]
gtk_sources += files([
'language-names.c',
'script-names.c',
])
elif add_freetype_lib
gtk_deps += [ ft2_dep ]
endif
endif
if x11_enabled

View File

@@ -333,7 +333,9 @@ fribidi_dep = dependency('fribidi', version: fribidi_req,
require_pangoft2 = wayland_enabled or x11_enabled
pangoft_dep = dependency('pangoft2', required: false)
if pangoft_dep.found()
ft2_dep = []
if pangoft_dep.found() or os_win32
# Need at least 2.7.1 for FT_Get_Var_Design_Coordinates()
# We get the dependency itself from pango, but pango doesn't care
# about ft2 version, so an extra check is needed.
@@ -428,6 +430,9 @@ if cairogobj_dep.found()
endif
cairo_libs = []
add_freetype_lib = false
if cc.get_id() == 'msvc'
# Fallback depedency discovery for those on Visual Studio that do not generate
# pkg-config files in their build systems for MSVC
@@ -455,6 +460,9 @@ if cc.get_id() == 'msvc'
if not harfbuzz_dep.found()
if cc.has_header('hb.h')
harfbuzz_dep = cc.find_library('harfbuzz', required : false)
if harfbuzz_dep.found()
add_freetype_lib = true
endif
endif
endif
endif
@@ -464,7 +472,15 @@ if not harfbuzz_dep.found()
fallback: ['harfbuzz', 'libharfbuzz_dep'])
endif
cdata.set('HAVE_HARFBUZZ', harfbuzz_dep.found())
build_with_harfbuzz = false
if pangoft_dep.found()
build_with_harfbuzz = true
elif os_win32 and harfbuzz_dep.found() and ft2_dep.found()
build_with_harfbuzz = cc.has_header_symbol('hb-ft.h', 'hb_ft_face_create', dependencies : harfbuzz_dep)
endif
cdata.set('HAVE_HARFBUZZ', build_with_harfbuzz)
cdata.set('HAVE_PANGOFT', pangoft_dep.found())
atk_pkgs = ['atk']