Compare commits
4 Commits
wip/matthi
...
wip/fanc99
Author | SHA1 | Date | |
---|---|---|---|
|
22543210ba | ||
|
17a60d5752 | ||
|
12da6b4712 | ||
|
43adfea5f0 |
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
341
gtk/gtkpangofontutils.c
Normal 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 */
|
44
gtk/gtkpangofontutilsprivate.h
Normal file
44
gtk/gtkpangofontutilsprivate.h
Normal 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__ */
|
@@ -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
|
||||
|
20
meson.build
20
meson.build
@@ -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']
|
||||
|
Reference in New Issue
Block a user