⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pangofc-fontmap.c

📁 GTK+-2.0源码之pango-1.15.6.tar.gz
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Pango * pangofc-fontmap.c: Base fontmap type for fontconfig-based backends * * Copyright (C) 2000-2003 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* Size of fontset cache */#define FONTSET_CACHE_SIZE 64#include <config.h>#include <math.h>#include "pango-context.h"#include "pangofc-fontmap.h"#include "pangofc-private.h"#include "pango-impl-utils.h"#include "modules.h"#include "pango-enum-types.h"typedef struct _PangoFcCoverageKey  PangoFcCoverageKey;typedef struct _PangoFcFace         PangoFcFace;typedef struct _PangoFcFamily       PangoFcFamily;typedef struct _PangoFcPatternSet   PangoFcPatternSet;typedef struct _PangoFcFindFuncInfo PangoFcFindFuncInfo;typedef struct _FontsetHashKey      FontsetHashKey;typedef struct _FontHashKey         FontHashKey;#define PANGO_FC_TYPE_FAMILY              (pango_fc_family_get_type ())#define PANGO_FC_FAMILY(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_FC_TYPE_FAMILY, PangoFcFamily))#define PANGO_FC_IS_FAMILY(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_FC_TYPE_FAMILY))#define PANGO_FC_TYPE_FACE              (pango_fc_face_get_type ())#define PANGO_FC_FACE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_FC_TYPE_FACE, PangoFcFace))#define PANGO_FC_IS_FACE(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_FC_TYPE_FACE))struct _PangoFcFontMapPrivate{  GHashTable *fontset_hash;	/* Maps PangoFontDescription -> PangoFcPatternSet  */  /* pattern_hash is used to make sure we only store one copy of   * each identical pattern. (Speeds up lookup).   */  GHashTable *pattern_hash;  GHashTable *coverage_hash; /* Maps font file name/id -> PangoCoverage */  GHashTable *font_hash; /* Maps FcPattern -> PangoFcFont */  GQueue *fontset_cache;	/* Recently used fontsets */  /* List of all families availible */  PangoFcFamily **families;  int n_families;		/* -1 == uninitialized */  double dpi;  /* Decoders */  GSList *findfuncs;  guint closed : 1;};struct _PangoFcCoverageKey{  char *filename;  int id;            /* needed to handle TTC files with multiple faces */};struct _PangoFcFace{  PangoFontFace parent_instance;  PangoFcFamily *family;  char *style;  guint fake : 1;};struct _PangoFcFamily{  PangoFontFamily parent_instance;  PangoFcFontMap *fontmap;  char *family_name;  PangoFcFace **faces;  int n_faces;		/* -1 == uninitialized */  int spacing;  /* FC_SPACING */};struct _PangoFcPatternSet{  int n_patterns;  FcPattern **patterns;  PangoFontset *fontset;  GList *cache_link;  FontsetHashKey *key;};struct _PangoFcFindFuncInfo{  PangoFcDecoderFindFunc findfunc;  gpointer               user_data;  GDestroyNotify         dnotify;  gpointer               ddata;};static GType    pango_fc_family_get_type     (void);static GType    pango_fc_face_get_type       (void);static void          pango_fc_font_map_finalize      (GObject                      *object);static PangoFont *   pango_fc_font_map_load_font     (PangoFontMap                 *fontmap,						       PangoContext                 *context,						       const PangoFontDescription   *description);static PangoFontset *pango_fc_font_map_load_fontset  (PangoFontMap                 *fontmap,						       PangoContext                 *context,						       const PangoFontDescription   *desc,						       PangoLanguage                *language);static void          pango_fc_font_map_list_families (PangoFontMap                 *fontmap,						       PangoFontFamily            ***families,						       int                          *n_families);static void pango_fc_font_map_cache_fontset (PangoFcFontMap    *fcfontmap,					     PangoFcPatternSet *patterns);static void pango_fc_pattern_set_free      (PangoFcPatternSet *patterns);static guint    pango_fc_pattern_hash       (FcPattern           *pattern);static gboolean pango_fc_pattern_equal      (FcPattern           *pattern1,					      FcPattern           *pattern2);static guint    pango_fc_coverage_key_hash  (PangoFcCoverageKey *key);static gboolean pango_fc_coverage_key_equal (PangoFcCoverageKey *key1,					      PangoFcCoverageKey *key2);static guint    font_hash_key_hash  (const FontHashKey *key);static gboolean font_hash_key_equal (const FontHashKey *key_a,				     const FontHashKey *key_b);static void     font_hash_key_free  (FontHashKey       *key);static guint    fontset_hash_key_hash  (const FontsetHashKey *key);static gboolean fontset_hash_key_equal (const FontsetHashKey *key_a,					const FontsetHashKey *key_b);static void     fontset_hash_key_free  (FontsetHashKey       *key);G_DEFINE_TYPE (PangoFcFontMap, pango_fc_font_map, PANGO_TYPE_FONT_MAP)static voidpango_fc_font_map_init (PangoFcFontMap *fcfontmap){  static gboolean registered_modules = FALSE;  PangoFcFontMapPrivate *priv;  priv = fcfontmap->priv = G_TYPE_INSTANCE_GET_PRIVATE (fcfontmap,							PANGO_TYPE_FC_FONT_MAP,							PangoFcFontMapPrivate);  if (!registered_modules)    {      int i;      registered_modules = TRUE;      for (i = 0; _pango_included_fc_modules[i].list; i++)	pango_module_register (&_pango_included_fc_modules[i]);    }  priv->n_families = -1;  priv->font_hash = g_hash_table_new_full ((GHashFunc)font_hash_key_hash,					   (GEqualFunc)font_hash_key_equal,					   (GDestroyNotify)font_hash_key_free,					   NULL);  priv->fontset_hash = g_hash_table_new_full ((GHashFunc)fontset_hash_key_hash,					      (GEqualFunc)fontset_hash_key_equal,					      (GDestroyNotify)fontset_hash_key_free,					      (GDestroyNotify)pango_fc_pattern_set_free);  priv->coverage_hash = g_hash_table_new_full ((GHashFunc)pango_fc_coverage_key_hash,					       (GEqualFunc)pango_fc_coverage_key_equal,					       (GDestroyNotify)g_free,					       (GDestroyNotify)pango_coverage_unref);  priv->fontset_cache = g_queue_new ();  priv->dpi = -1;}static voidpango_fc_font_map_class_init (PangoFcFontMapClass *class){  GObjectClass *object_class = G_OBJECT_CLASS (class);  PangoFontMapClass *fontmap_class = PANGO_FONT_MAP_CLASS (class);  object_class->finalize = pango_fc_font_map_finalize;  fontmap_class->load_font = pango_fc_font_map_load_font;  fontmap_class->load_fontset = pango_fc_font_map_load_fontset;  fontmap_class->list_families = pango_fc_font_map_list_families;  fontmap_class->shape_engine_type = PANGO_RENDER_TYPE_FC;  g_type_class_add_private (object_class, sizeof (PangoFcFontMapPrivate));}static gpointerget_gravity_class (void){  static GEnumClass *class = NULL;  if (G_UNLIKELY (!class))    class = g_type_class_ref (PANGO_TYPE_GRAVITY);  return class;}static guintpango_fc_pattern_hash (FcPattern *pattern){#if 1  return FcPatternHash (pattern);#else  /* Hashing only part of the pattern can improve speed a bit.   */  char *str;  int i;  double d;  guint hash = 0;  FcPatternGetString (pattern, FC_FILE, 0, (FcChar8 **) &str);  if (str)    hash = g_str_hash (str);  if (FcPatternGetInteger (pattern, FC_INDEX, 0, &i) == FcResultMatch)    hash ^= i;  if (FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &d) == FcResultMatch)    hash ^= (guint) (d*1000.0);  return hash;#endif}static gbooleanpango_fc_pattern_equal (FcPattern *pattern1,			 FcPattern *pattern2){  if (pattern1 == pattern2)    return TRUE;  else    return FcPatternEqual (pattern1, pattern2);}static guintpango_fc_coverage_key_hash (PangoFcCoverageKey *key){  return g_str_hash (key->filename) ^ key->id;}static gbooleanpango_fc_coverage_key_equal (PangoFcCoverageKey *key1,			       PangoFcCoverageKey *key2){  return key1->id == key2->id && strcmp (key1->filename, key2->filename) == 0;}struct _FontsetHashKey {  PangoFcFontMap *fontmap;  PangoMatrix matrix;  PangoLanguage *language;  PangoFontDescription *desc;  int size;			/* scaled via the current DPI */  gpointer context_key;};struct _FontHashKey {  PangoFcFontMap *fontmap;  PangoMatrix matrix;  FcPattern *pattern;  gpointer context_key;};/* Fowler / Noll / Vo (FNV) Hash (http://www.isthe.com/chongo/tech/comp/fnv/) * * Not necessarily better than a lot of other hashes, but should be OK, and * well tested with binary data. */#define FNV_32_PRIME ((guint32)0x01000193)#define FNV1_32_INIT ((guint32)0x811c9dc5)static guint32hash_bytes_fnv (unsigned char *buffer,		int            len,		guint32        hval){  while (len--)    {      hval *= FNV_32_PRIME;      hval ^= *buffer++;    }  return hval;}static gbooleanfontset_hash_key_equal (const FontsetHashKey *key_a,			const FontsetHashKey *key_b){  if (key_a->size == key_b->size &&      pango_font_description_equal (key_a->desc, key_b->desc) &&      key_a->language == key_b->language &&      key_a->matrix.xx == key_b->matrix.xx &&      key_a->matrix.xy == key_b->matrix.xy &&      key_a->matrix.yx == key_b->matrix.yx &&      key_a->matrix.yy == key_b->matrix.yy)    {      if (key_a->context_key)	return PANGO_FC_FONT_MAP_GET_CLASS (key_a->fontmap)->context_key_equal (key_a->fontmap,										key_a->context_key,										key_b->context_key);      else	return TRUE;    }  else    return FALSE;}static guintfontset_hash_key_hash (const FontsetHashKey *key){    guint32 hash = FNV1_32_INIT;    /* We do a bytewise hash on the context matrix */    hash = hash_bytes_fnv ((unsigned char *)(&key->matrix),			   sizeof(double) * 4,			   hash);    if (key->context_key)      hash ^= PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_hash (key->fontmap,									    key->context_key);    /* 1237 is just an abitrary prime */    return (hash ^	    GPOINTER_TO_UINT (key->language) ^	    (key->size * 1237) ^	    pango_font_description_hash (key->desc));}static voidfontset_hash_key_free (FontsetHashKey *key){  pango_font_description_free (key->desc);  if (key->context_key)    PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_free (key->fontmap,								  key->context_key);  g_slice_free (FontsetHashKey, key);}static FontsetHashKey *fontset_hash_key_copy (FontsetHashKey *old){  FontsetHashKey *key = g_slice_new (FontsetHashKey);  key->fontmap = old->fontmap;  key->matrix = old->matrix;  key->language = old->language;  key->desc = pango_font_description_copy (old->desc);  key->size = old->size;  if (old->context_key)    key->context_key = PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_copy (key->fontmap,										     old->context_key);  else    key->context_key = NULL;  return key;}static gbooleanfont_hash_key_equal (const FontHashKey *key_a,		     const FontHashKey *key_b){  if (key_a->matrix.xx == key_b->matrix.xx &&      key_a->matrix.xy == key_b->matrix.xy &&      key_a->matrix.yx == key_b->matrix.yx &&      key_a->matrix.yy == key_b->matrix.yy &&      key_a->pattern == key_b->pattern)    {      if (key_a->context_key)	return PANGO_FC_FONT_MAP_GET_CLASS (key_a->fontmap)->context_key_equal (key_a->fontmap,										key_a->context_key,										key_b->context_key);      else	return TRUE;    }  else    return FALSE;}static guintfont_hash_key_hash (const FontHashKey *key){    guint32 hash = FNV1_32_INIT;    /* We do a bytewise hash on the context matrix */    hash = hash_bytes_fnv ((unsigned char *)(&key->matrix),			   sizeof(double) * 4,			   hash);    if (key->context_key)      hash ^= PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_hash (key->fontmap,									    key->context_key);    return (hash ^ GPOINTER_TO_UINT (key->pattern));}static voidfont_hash_key_free (FontHashKey *key){  if (key->context_key)    PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_free (key->fontmap,								  key->context_key);  g_slice_free (FontHashKey, key);}static FontHashKey *font_hash_key_copy (FontHashKey *old){  FontHashKey *key = g_slice_new (FontHashKey);  key->fontmap = old->fontmap;  key->matrix = old->matrix;  key->pattern = old->pattern;  if (old->context_key)    key->context_key = PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_copy (key->fontmap,										     old->context_key);  else    key->context_key = NULL;  return key;}/** * pango_fc_font_map_add_decoder_find_func: * @fcfontmap: The #PangoFcFontMap to add this method to. * @findfunc: The #PangoFcDecoderFindFunc callback function * @user_data: User data. * @dnotify: A #GDestroyNotify callback that will be called when the *  fontmap is finalized and the decoder is released. * * This function saves a callback method in the #PangoFcFontMap that * will be called whenever new fonts are created.  If the * function returns a #PangoFcDecoder, that decoder will be used to * determine both coverage via a #FcCharSet and a one-to-one mapping of * characters to glyphs.  This will allow applications to have * application-specific encodings for various fonts. * * Since: 1.6. **/voidpango_fc_font_map_add_decoder_find_func (PangoFcFontMap        *fcfontmap,					 PangoFcDecoderFindFunc findfunc,					 gpointer               user_data,					 GDestroyNotify         dnotify){  PangoFcFontMapPrivate *priv = fcfontmap->priv;  PangoFcFindFuncInfo *info;  info = g_slice_new (PangoFcFindFuncInfo);  info->findfunc = findfunc;  info->user_data = user_data;  info->dnotify = dnotify;  priv->findfuncs = g_slist_append (priv->findfuncs, info);}static voidpango_fc_font_map_finalize (GObject *object){  PangoFcFontMap *fcfontmap = PANGO_FC_FONT_MAP (object);  PangoFcFontMapPrivate *priv = fcfontmap->priv;  pango_fc_font_map_cache_clear (fcfontmap);  g_queue_free (priv->fontset_cache);  g_hash_table_destroy (priv->coverage_hash);  if (priv->fontset_hash)    g_hash_table_destroy (priv->fontset_hash);  if (priv->font_hash)    g_hash_table_destroy (priv->font_hash);  if (priv->pattern_hash)    g_hash_table_destroy (priv->pattern_hash);  while (priv->findfuncs)    {      PangoFcFindFuncInfo *info;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -