|
Packit |
0ec9dd |
/* Pango
|
|
Packit |
0ec9dd |
* pango-fontmap.c: Font handling
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Copyright (C) 2000 Red Hat Software
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* This library is free software; you can redistribute it and/or
|
|
Packit |
0ec9dd |
* modify it under the terms of the GNU Library General Public
|
|
Packit |
0ec9dd |
* License as published by the Free Software Foundation; either
|
|
Packit |
0ec9dd |
* version 2 of the License, or (at your option) any later version.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
0ec9dd |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
0ec9dd |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
0ec9dd |
* Library General Public License for more details.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* You should have received a copy of the GNU Library General Public
|
|
Packit |
0ec9dd |
* License along with this library; if not, write to the
|
|
Packit |
0ec9dd |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Packit |
0ec9dd |
* Boston, MA 02111-1307, USA.
|
|
Packit |
0ec9dd |
*/
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
#include "config.h"
|
|
Packit |
0ec9dd |
#include "pango-fontmap.h"
|
|
Packit |
0ec9dd |
#include "pango-impl-utils.h"
|
|
Packit |
0ec9dd |
#include <stdlib.h>
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static PangoFontset *pango_font_map_real_load_fontset (PangoFontMap *fontmap,
|
|
Packit |
0ec9dd |
PangoContext *context,
|
|
Packit |
0ec9dd |
const PangoFontDescription *desc,
|
|
Packit |
0ec9dd |
PangoLanguage *language);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
G_DEFINE_ABSTRACT_TYPE (PangoFontMap, pango_font_map, G_TYPE_OBJECT)
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static void
|
|
Packit |
0ec9dd |
pango_font_map_class_init (PangoFontMapClass *class)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
class->load_fontset = pango_font_map_real_load_fontset;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static void
|
|
Packit |
0ec9dd |
pango_font_map_init (PangoFontMap *fontmap G_GNUC_UNUSED)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/**
|
|
Packit |
0ec9dd |
* pango_font_map_create_context:
|
|
Packit |
0ec9dd |
* @fontmap: a #PangoFontMap
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Creates a #PangoContext connected to @fontmap. This is equivalent
|
|
Packit |
0ec9dd |
* to pango_context_new() followed by pango_context_set_font_map().
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* If you are using Pango as part of a higher-level system,
|
|
Packit |
0ec9dd |
* that system may have it's own way of create a #PangoContext.
|
|
Packit |
0ec9dd |
* For instance, the GTK+ toolkit has, among others,
|
|
Packit |
0ec9dd |
* gdk_pango_context_get_for_screen(), and
|
|
Packit |
0ec9dd |
* gtk_widget_get_pango_context(). Use those instead.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Return value: (transfer full): the newly allocated #PangoContext,
|
|
Packit |
0ec9dd |
* which should be freed with g_object_unref().
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Since: 1.22
|
|
Packit |
0ec9dd |
**/
|
|
Packit |
0ec9dd |
PangoContext *
|
|
Packit |
0ec9dd |
pango_font_map_create_context (PangoFontMap *fontmap)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
PangoContext *context;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_return_val_if_fail (fontmap != NULL, NULL);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
context = pango_context_new ();
|
|
Packit |
0ec9dd |
pango_context_set_font_map (context, fontmap);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return context;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/**
|
|
Packit |
0ec9dd |
* pango_font_map_load_font:
|
|
Packit |
0ec9dd |
* @fontmap: a #PangoFontMap
|
|
Packit |
0ec9dd |
* @context: the #PangoContext the font will be used with
|
|
Packit |
0ec9dd |
* @desc: a #PangoFontDescription describing the font to load
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Load the font in the fontmap that is the closest match for @desc.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Returns: (transfer full) (nullable): the newly allocated #PangoFont
|
|
Packit |
0ec9dd |
* loaded, or %NULL if no font matched.
|
|
Packit |
0ec9dd |
**/
|
|
Packit |
0ec9dd |
PangoFont *
|
|
Packit |
0ec9dd |
pango_font_map_load_font (PangoFontMap *fontmap,
|
|
Packit |
0ec9dd |
PangoContext *context,
|
|
Packit |
0ec9dd |
const PangoFontDescription *desc)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
g_return_val_if_fail (fontmap != NULL, NULL);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return PANGO_FONT_MAP_GET_CLASS (fontmap)->load_font (fontmap, context, desc);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/**
|
|
Packit |
0ec9dd |
* pango_font_map_list_families:
|
|
Packit |
0ec9dd |
* @fontmap: a #PangoFontMap
|
|
Packit |
0ec9dd |
* @families: (out) (array length=n_families) (transfer container): location to store a pointer to an array of #PangoFontFamily *.
|
|
Packit |
0ec9dd |
* This array should be freed with g_free().
|
|
Packit |
0ec9dd |
* @n_families: (out): location to store the number of elements in @families
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* List all families for a fontmap.
|
|
Packit |
0ec9dd |
**/
|
|
Packit |
0ec9dd |
void
|
|
Packit |
0ec9dd |
pango_font_map_list_families (PangoFontMap *fontmap,
|
|
Packit |
0ec9dd |
PangoFontFamily ***families,
|
|
Packit |
0ec9dd |
int *n_families)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
g_return_if_fail (fontmap != NULL);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
PANGO_FONT_MAP_GET_CLASS (fontmap)->list_families (fontmap, families, n_families);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/**
|
|
Packit |
0ec9dd |
* pango_font_map_load_fontset:
|
|
Packit |
0ec9dd |
* @fontmap: a #PangoFontMap
|
|
Packit |
0ec9dd |
* @context: the #PangoContext the font will be used with
|
|
Packit |
0ec9dd |
* @desc: a #PangoFontDescription describing the font to load
|
|
Packit |
0ec9dd |
* @language: a #PangoLanguage the fonts will be used for
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Load a set of fonts in the fontmap that can be used to render
|
|
Packit |
0ec9dd |
* a font matching @desc.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Returns: (transfer full) (nullable): the newly allocated
|
|
Packit |
0ec9dd |
* #PangoFontset loaded, or %NULL if no font matched.
|
|
Packit |
0ec9dd |
**/
|
|
Packit |
0ec9dd |
PangoFontset *
|
|
Packit |
0ec9dd |
pango_font_map_load_fontset (PangoFontMap *fontmap,
|
|
Packit |
0ec9dd |
PangoContext *context,
|
|
Packit |
0ec9dd |
const PangoFontDescription *desc,
|
|
Packit |
0ec9dd |
PangoLanguage *language)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
g_return_val_if_fail (fontmap != NULL, NULL);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return PANGO_FONT_MAP_GET_CLASS (fontmap)->load_fontset (fontmap, context, desc, language);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static void
|
|
Packit |
0ec9dd |
pango_font_map_fontset_add_fonts (PangoFontMap *fontmap,
|
|
Packit |
0ec9dd |
PangoContext *context,
|
|
Packit |
0ec9dd |
PangoFontsetSimple *fonts,
|
|
Packit |
0ec9dd |
PangoFontDescription *desc,
|
|
Packit |
0ec9dd |
const char *family)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
PangoFont *font;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
pango_font_description_set_family_static (desc, family);
|
|
Packit |
0ec9dd |
font = pango_font_map_load_font (fontmap, context, desc);
|
|
Packit |
0ec9dd |
if (font)
|
|
Packit |
0ec9dd |
pango_fontset_simple_append (fonts, font);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static PangoFontset *
|
|
Packit |
0ec9dd |
pango_font_map_real_load_fontset (PangoFontMap *fontmap,
|
|
Packit |
0ec9dd |
PangoContext *context,
|
|
Packit |
0ec9dd |
const PangoFontDescription *desc,
|
|
Packit |
0ec9dd |
PangoLanguage *language)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
PangoFontDescription *tmp_desc = pango_font_description_copy_static (desc);
|
|
Packit |
0ec9dd |
const char *family;
|
|
Packit |
0ec9dd |
char **families;
|
|
Packit |
0ec9dd |
int i;
|
|
Packit |
0ec9dd |
PangoFontsetSimple *fonts;
|
|
Packit |
0ec9dd |
static GHashTable *warned_fonts = NULL; /* MT-safe */
|
|
Packit |
0ec9dd |
G_LOCK_DEFINE_STATIC (warned_fonts);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
family = pango_font_description_get_family (desc);
|
|
Packit |
0ec9dd |
families = g_strsplit (family ? family : "", ",", -1);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
fonts = pango_fontset_simple_new (language);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
for (i = 0; families[i]; i++)
|
|
Packit |
0ec9dd |
pango_font_map_fontset_add_fonts (fontmap,
|
|
Packit |
0ec9dd |
context,
|
|
Packit |
0ec9dd |
fonts,
|
|
Packit |
0ec9dd |
tmp_desc,
|
|
Packit |
0ec9dd |
families[i]);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_strfreev (families);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/* The font description was completely unloadable, try with
|
|
Packit |
0ec9dd |
* family == "Sans"
|
|
Packit |
0ec9dd |
*/
|
|
Packit |
0ec9dd |
if (pango_fontset_simple_size (fonts) == 0)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
char *ctmp1, *ctmp2;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
pango_font_description_set_family_static (tmp_desc,
|
|
Packit |
0ec9dd |
pango_font_description_get_family (desc));
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
ctmp1 = pango_font_description_to_string (desc);
|
|
Packit |
0ec9dd |
pango_font_description_set_family_static (tmp_desc, "Sans");
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
G_LOCK (warned_fonts);
|
|
Packit |
0ec9dd |
if (!warned_fonts || !g_hash_table_lookup (warned_fonts, ctmp1))
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
if (!warned_fonts)
|
|
Packit |
0ec9dd |
warned_fonts = g_hash_table_new (g_str_hash, g_str_equal);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_hash_table_insert (warned_fonts, g_strdup (ctmp1), GINT_TO_POINTER (1));
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
ctmp2 = pango_font_description_to_string (tmp_desc);
|
|
Packit |
0ec9dd |
g_warning ("couldn't load font \"%s\", falling back to \"%s\", "
|
|
Packit |
0ec9dd |
"expect ugly output.", ctmp1, ctmp2);
|
|
Packit |
0ec9dd |
g_free (ctmp2);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
G_UNLOCK (warned_fonts);
|
|
Packit |
0ec9dd |
g_free (ctmp1);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
pango_font_map_fontset_add_fonts (fontmap,
|
|
Packit |
0ec9dd |
context,
|
|
Packit |
0ec9dd |
fonts,
|
|
Packit |
0ec9dd |
tmp_desc,
|
|
Packit |
0ec9dd |
"Sans");
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/* We couldn't try with Sans and the specified style. Try Sans Normal
|
|
Packit |
0ec9dd |
*/
|
|
Packit |
0ec9dd |
if (pango_fontset_simple_size (fonts) == 0)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
char *ctmp1, *ctmp2;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
pango_font_description_set_family_static (tmp_desc, "Sans");
|
|
Packit |
0ec9dd |
ctmp1 = pango_font_description_to_string (tmp_desc);
|
|
Packit |
0ec9dd |
pango_font_description_set_style (tmp_desc, PANGO_STYLE_NORMAL);
|
|
Packit |
0ec9dd |
pango_font_description_set_weight (tmp_desc, PANGO_WEIGHT_NORMAL);
|
|
Packit |
0ec9dd |
pango_font_description_set_variant (tmp_desc, PANGO_VARIANT_NORMAL);
|
|
Packit |
0ec9dd |
pango_font_description_set_stretch (tmp_desc, PANGO_STRETCH_NORMAL);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
G_LOCK (warned_fonts);
|
|
Packit |
0ec9dd |
if (!warned_fonts || !g_hash_table_lookup (warned_fonts, ctmp1))
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
g_hash_table_insert (warned_fonts, g_strdup (ctmp1), GINT_TO_POINTER (1));
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
ctmp2 = pango_font_description_to_string (tmp_desc);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_warning ("couldn't load font \"%s\", falling back to \"%s\", "
|
|
Packit |
0ec9dd |
"expect ugly output.", ctmp1, ctmp2);
|
|
Packit |
0ec9dd |
g_free (ctmp2);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
G_UNLOCK (warned_fonts);
|
|
Packit |
0ec9dd |
g_free (ctmp1);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
pango_font_map_fontset_add_fonts (fontmap,
|
|
Packit |
0ec9dd |
context,
|
|
Packit |
0ec9dd |
fonts,
|
|
Packit |
0ec9dd |
tmp_desc,
|
|
Packit |
0ec9dd |
"Sans");
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
pango_font_description_free (tmp_desc);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/* Everything failed, we are screwed, there is no way to continue,
|
|
Packit |
0ec9dd |
* but lets just not crash here.
|
|
Packit |
0ec9dd |
*/
|
|
Packit |
0ec9dd |
if (pango_fontset_simple_size (fonts) == 0)
|
|
Packit |
0ec9dd |
g_warning ("All font fallbacks failed!!!!");
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return PANGO_FONTSET (fonts);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/**
|
|
Packit |
0ec9dd |
* pango_font_map_get_shape_engine_type:
|
|
Packit |
0ec9dd |
* @fontmap: a #PangoFontMap
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Returns the render ID for shape engines for this fontmap.
|
|
Packit |
0ec9dd |
* See the <structfield>render_type</structfield> field of
|
|
Packit |
0ec9dd |
* #PangoEngineInfo.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Return value: the ID string for shape engines for
|
|
Packit |
0ec9dd |
* this fontmap. Owned by Pango, should not be modified
|
|
Packit |
0ec9dd |
* or freed.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Since: 1.4
|
|
Packit |
0ec9dd |
* Deprecated: 1.38
|
|
Packit |
0ec9dd |
**/
|
|
Packit |
0ec9dd |
const char *
|
|
Packit |
0ec9dd |
pango_font_map_get_shape_engine_type (PangoFontMap *fontmap)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
g_return_val_if_fail (PANGO_IS_FONT_MAP (fontmap), NULL);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return PANGO_FONT_MAP_GET_CLASS (fontmap)->shape_engine_type;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/**
|
|
Packit |
0ec9dd |
* pango_font_map_get_serial:
|
|
Packit |
0ec9dd |
* @fontmap: a #PangoFontMap
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Returns the current serial number of @fontmap. The serial number is
|
|
Packit |
0ec9dd |
* initialized to an small number larger than zero when a new fontmap
|
|
Packit |
0ec9dd |
* is created and is increased whenever the fontmap is changed. It may
|
|
Packit |
0ec9dd |
* wrap, but will never have the value 0. Since it can wrap, never compare
|
|
Packit |
0ec9dd |
* it with "less than", always use "not equals".
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* The fontmap can only be changed using backend-specific API, like changing
|
|
Packit |
0ec9dd |
* fontmap resolution.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* This can be used to automatically detect changes to a #PangoFontMap, like
|
|
Packit |
0ec9dd |
* in #PangoContext.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Return value: The current serial number of @fontmap.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Since: 1.32.4
|
|
Packit |
0ec9dd |
**/
|
|
Packit |
0ec9dd |
guint
|
|
Packit |
0ec9dd |
pango_font_map_get_serial (PangoFontMap *fontmap)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
g_return_val_if_fail (PANGO_IS_FONT_MAP (fontmap), 0);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (PANGO_FONT_MAP_GET_CLASS (fontmap)->get_serial)
|
|
Packit |
0ec9dd |
return PANGO_FONT_MAP_GET_CLASS (fontmap)->get_serial (fontmap);
|
|
Packit |
0ec9dd |
else
|
|
Packit |
0ec9dd |
return 1;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/**
|
|
Packit |
0ec9dd |
* pango_font_map_changed:
|
|
Packit |
0ec9dd |
* @fontmap: a #PangoFontMap
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Forces a change in the context, which will cause any #PangoContext
|
|
Packit |
0ec9dd |
* using this fontmap to change.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* This function is only useful when implementing a new backend
|
|
Packit |
0ec9dd |
* for Pango, something applications won't do. Backends should
|
|
Packit |
0ec9dd |
* call this function if they have attached extra data to the context
|
|
Packit |
0ec9dd |
* and such data is changed.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Since: 1.34
|
|
Packit |
0ec9dd |
**/
|
|
Packit |
0ec9dd |
void
|
|
Packit |
0ec9dd |
pango_font_map_changed (PangoFontMap *fontmap)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
g_return_if_fail (PANGO_IS_FONT_MAP (fontmap));
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (PANGO_FONT_MAP_GET_CLASS (fontmap)->changed)
|
|
Packit |
0ec9dd |
PANGO_FONT_MAP_GET_CLASS (fontmap)->changed (fontmap);
|
|
Packit |
0ec9dd |
}
|