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

📄 pangox-fontmap.c

📁 GTK+-2.0源码之pango-1.15.6.tar.gz
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Pango * pangox-fontmap.c: X font handling * * Copyright (C) 2000 Red Hat Software * * 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. */#include <config.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <glib.h>#include <X11/Xatom.h>/* For XExtSetCloseDisplay */#include <X11/Xlibint.h>#include "pango-engine-private.h"#include "pango-fontmap.h"#include "pango-impl-utils.h"#undef PANGO_DISABLE_DEPRECATED#include "pangox-private.h"typedef struct _PangoXFamily       PangoXFamily;typedef struct _PangoXSizeInfo     PangoXSizeInfo;/* Number of freed fonts */#define MAX_FREED_FONTS 16/* This is the largest field length we will accept. If a fontname has a field   larger than this we will skip it. */#define XLFD_MAX_FIELD_LEN 64#define MAX_FONTS 32767/* These are the field numbers in the X Logical Font Description fontnames,   e.g. -adobe-courier-bold-o-normal--25-180-100-100-m-150-iso8859-1 */typedef enum{  XLFD_FOUNDRY		= 0,  XLFD_FAMILY		= 1,  XLFD_WEIGHT		= 2,  XLFD_SLANT		= 3,  XLFD_SET_WIDTH	= 4,  XLFD_ADD_STYLE	= 5,  XLFD_PIXELS		= 6,  XLFD_POINTS		= 7,  XLFD_RESOLUTION_X	= 8,  XLFD_RESOLUTION_Y	= 9,  XLFD_SPACING		= 10,  XLFD_AVERAGE_WIDTH	= 11,  XLFD_CHARSET		= 12,  XLFD_NUM_FIELDS} FontField;struct _PangoXFamily{  PangoFontFamily parent_instance;  char *family_name;  GSList *font_entries;};struct _PangoXFace{  PangoFontFace parent_instance;  char *xlfd;  PangoFontDescription *description;  PangoCoverage *coverage;  char *face_name;  GSList *cached_fonts;};struct _PangoXSizeInfo{  char *identifier;  GSList *xlfds;};static const struct {  const gchar text[12];  PangoWeight value;} weights_map[] = {  { "light",     300 },  { "regular",   400 },  { "book",      400 },  { "medium",    500 },  { "semibold",  600 },  { "demibold",  600 },  { "bold",      700 },  { "extrabold", 800 },  { "ultrabold", 800 },  { "heavy",     900 },  { "black",     900 }};static const struct {  const gchar text[4];  PangoStyle value;} styles_map[] = {  { "r", PANGO_STYLE_NORMAL },  { "i", PANGO_STYLE_ITALIC },  { "o", PANGO_STYLE_OBLIQUE }};static const struct {  const gchar text[16];  PangoStretch value;} stretches_map[] = {  { "normal",        PANGO_STRETCH_NORMAL },  { "semicondensed", PANGO_STRETCH_SEMI_CONDENSED },  { "condensed",     PANGO_STRETCH_CONDENSED },};static void     pango_x_font_map_init       (PangoXFontMap      *fontmap);static void     pango_x_font_map_class_init (PangoFontMapClass *class);static void       pango_x_font_map_finalize      (GObject                      *object);static PangoFont *pango_x_font_map_load_font     (PangoFontMap                 *fontmap,						  PangoContext                 *context,						  const PangoFontDescription   *description);static void       pango_x_font_map_list_families (PangoFontMap                 *fontmap,						  PangoFontFamily            ***families,						  int                          *n_families);static void     pango_x_fontmap_cache_clear (PangoXFontMap   *xfontmap);static void     pango_x_font_map_read_aliases (PangoXFontMap *xfontmap);static gint     pango_x_get_size            (PangoXFontMap      *fontmap,					     const char         *fontname);static void     pango_x_insert_font         (PangoXFontMap      *fontmap,					     const char         *fontname);static gboolean pango_x_is_xlfd_font_name   (const char         *fontname);static char *   pango_x_get_xlfd_field      (const char         *fontname,					     FontField           field_num,					     char               *buffer);static char *   pango_x_get_identifier      (const char         *fontname);#define PANGO_X_TYPE_FAMILY              (pango_x_family_get_type ())#define PANGO_X_FAMILY(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_X_TYPE_FAMILY, PangoXFamily))#define PANGO_X_IS_FAMILY(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_X_TYPE_FAMILY))GType           pango_x_family_get_type (void);#define PANGO_X_TYPE_FACE              (pango_x_face_get_type ())#define PANGO_X_FACE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_X_TYPE_FACE, PangoXFace))#define PANGO_X_IS_FACE(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_X_TYPE_FACE))GType           pango_x_face_get_type (void);static PangoFontClass *font_map_parent_class;	/* Parent class structure for PangoXFontMap */GTypepango_x_font_map_get_type (void){  static GType object_type = 0;  if (!object_type)    {      const GTypeInfo object_info =      {	sizeof (PangoFontMapClass),	(GBaseInitFunc) NULL,	(GBaseFinalizeFunc) NULL,	(GClassInitFunc) pango_x_font_map_class_init,	NULL,           /* class_finalize */	NULL,           /* class_data */	sizeof (PangoXFontMap),	0,              /* n_preallocs */	(GInstanceInitFunc) pango_x_font_map_init,	NULL            /* value_table */      };      object_type = g_type_register_static (PANGO_TYPE_FONT_MAP,					    I_("PangoXFontMap"),					    &object_info, 0);    }  return object_type;}static voidpango_x_font_map_init (PangoXFontMap *xfontmap){  xfontmap->families = g_hash_table_new (g_str_hash, g_str_equal);  xfontmap->size_infos = g_hash_table_new (g_str_hash, g_str_equal);  xfontmap->to_atom_cache = g_hash_table_new (g_str_hash, g_str_equal);  xfontmap->from_atom_cache = g_hash_table_new (g_direct_hash, g_direct_equal);  xfontmap->n_fonts = 0;}static voidpango_x_font_map_class_init (PangoFontMapClass *class){  GObjectClass *object_class = G_OBJECT_CLASS (class);  font_map_parent_class = g_type_class_peek_parent (class);  object_class->finalize = pango_x_font_map_finalize;  class->load_font = pango_x_font_map_load_font;  class->list_families = pango_x_font_map_list_families;  class->shape_engine_type = PANGO_RENDER_TYPE_X;}/* * Hackery to set up notification when a Display is closed */static GSList *registered_displays;static intclose_display_cb (Display   *display,		  XExtCodes *extcodes){  pango_x_shutdown_display (display);  registered_displays = g_slist_remove (registered_displays, display);  return 0;}static voidregister_display (Display *display){  XExtCodes *extcodes;  GSList *tmp_list;  for (tmp_list = registered_displays; tmp_list; tmp_list = tmp_list->next)    {      if (tmp_list->data == display)	return;    }  registered_displays = g_slist_prepend (registered_displays, display);  extcodes = XAddExtension (display);  XESetCloseDisplay (display, extcodes->extension, close_display_cb);}static GList *fontmaps = NULL;/** * pango_x_font_map_for_display: * @display: an X #Display. * * Returns a #PangoXFontMap for @display. Font maps are cached and should * not be freed. If the font map for a display is no longer needed, it can * be released with pango_x_shutdown_display(). * * Return value: a #PangoXFontMap for @display. **/PangoFontMap *pango_x_font_map_for_display (Display *display){  PangoXFontMap *xfontmap;  GList *tmp_list = fontmaps;  char **xfontnames;  int num_fonts, i;  int screen;  g_return_val_if_fail (display != NULL, NULL);  /* Make sure that the type system is initialized */  g_type_init ();  while (tmp_list)    {      xfontmap = tmp_list->data;      if (xfontmap->display == display)	return PANGO_FONT_MAP (xfontmap);      tmp_list = tmp_list->next;    }  xfontmap = g_object_new (PANGO_TYPE_X_FONT_MAP, NULL);  xfontmap->display = display;  xfontmap->font_cache = pango_x_font_cache_new (display);  xfontmap->freed_fonts = g_queue_new ();  /* Get a maximum of MAX_FONTS fontnames from the X server.     Use "-*" as the pattern rather than "-*-*-*-*-*-*-*-*-*-*-*-*-*-*" since     the latter may result in fonts being returned which don't actually exist.     xlsfonts also uses "*" so I think it's OK. "-*" gets rid of aliases. */  xfontnames = XListFonts (xfontmap->display, "-*", MAX_FONTS, &num_fonts);  if (num_fonts == MAX_FONTS)    g_warning("MAX_FONTS exceeded. Some fonts may be missing.");  /* Insert the font families into the main table */  for (i = 0; i < num_fonts; i++)    {      if (pango_x_is_xlfd_font_name (xfontnames[i]))	pango_x_insert_font (xfontmap, xfontnames[i]);    }  XFreeFontNames (xfontnames);  pango_x_font_map_read_aliases (xfontmap);  fontmaps = g_list_prepend (fontmaps, xfontmap);  /* This is a little screwed up, since different screens on the same display   * might have different resolutions   */  screen = DefaultScreen (xfontmap->display);  xfontmap->resolution = (PANGO_SCALE * 72.27 / 25.4) * ((double) DisplayWidthMM (xfontmap->display, screen) /							 DisplayWidth (xfontmap->display, screen));  register_display (xfontmap->display);  return PANGO_FONT_MAP (xfontmap);}/** * pango_x_shutdown_display: * @display: an X #Display * * Free cached resources for the given X display structure. **/voidpango_x_shutdown_display (Display *display){  GList *tmp_list;  g_return_if_fail (display != NULL);  tmp_list = fontmaps;  while (tmp_list)    {      PangoXFontMap *xfontmap = tmp_list->data;      if (xfontmap->display == display)	{	  fontmaps = g_list_delete_link (fontmaps, tmp_list);	  pango_x_fontmap_cache_clear (xfontmap);	  g_object_unref (xfontmap);	  return;	}      tmp_list = tmp_list->next;    }}static voidpango_x_font_map_finalize (GObject *object){  PangoXFontMap *xfontmap = PANGO_X_FONT_MAP (object);  g_list_foreach (xfontmap->freed_fonts->head, (GFunc)g_object_unref, NULL);  g_queue_free (xfontmap->freed_fonts);  pango_x_font_cache_free (xfontmap->font_cache);  /* FIXME: Lots more here */  fontmaps = g_list_remove (fontmaps, xfontmap);  G_OBJECT_CLASS (font_map_parent_class)->finalize (object);}static voidlist_families_foreach (gpointer key,		       gpointer value,		       gpointer user_data){  GSList **list = user_data;  *list = g_slist_prepend (*list, value);}static voidpango_x_font_map_list_families (PangoFontMap           *fontmap,				PangoFontFamily      ***families,				int                    *n_families){  GSList *family_list = NULL;  GSList *tmp_list;  PangoXFontMap *xfontmap = (PangoXFontMap *)fontmap;  if (!n_families)    return;  g_hash_table_foreach (xfontmap->families, list_families_foreach, &family_list);  *n_families = g_slist_length (family_list);  if (families)    {      int i = 0;      *families = g_new (PangoFontFamily *, *n_families);      tmp_list = family_list;      while (tmp_list)	{	  (*families)[i] = tmp_list->data;	  i++;	  tmp_list = tmp_list->next;	}    }  g_slist_free (family_list);}static PangoXFamily *pango_x_get_font_family (PangoXFontMap *xfontmap,			 const char    *family_name){  PangoXFamily *font_family = g_hash_table_lookup (xfontmap->families, family_name);  if (!font_family)    {      font_family = g_object_new (PANGO_X_TYPE_FAMILY, NULL);      font_family->family_name = g_strdup (family_name);      font_family->font_entries = NULL;      g_hash_table_insert (xfontmap->families, font_family->family_name, font_family);    }  return font_family;}static PangoFont *pango_x_font_map_load_font (PangoFontMap               *fontmap,			    PangoContext               *context,			    const PangoFontDescription *description){  PangoXFontMap *xfontmap = (PangoXFontMap *)fontmap;  PangoXFamily *font_family;  PangoFont *result = NULL;  GSList *tmp_list;  gchar *name;  gint size;  g_return_val_if_fail (description != NULL, NULL);  name = g_ascii_strdown (pango_font_description_get_family (description), -1);  size = pango_font_description_get_size (description);  if (size < 0)    return NULL;  font_family = g_hash_table_lookup (xfontmap->families, name);  if (font_family)    {      PangoXFace *best_match = NULL;      tmp_list = font_family->font_entries;      while (tmp_list)	{	  PangoXFace *font_entry = tmp_list->data;	  if (pango_font_description_better_match (description,						   best_match ? best_match->description : NULL,						   font_entry->description))	    best_match = font_entry;	  tmp_list = tmp_list->next;	}      if (best_match)	{	  GSList *tmp_list = best_match->cached_fonts;	  while (tmp_list)	    {	      PangoXFont *xfont = tmp_list->data;	      if (xfont->size == size)		{		  result = (PangoFont *)xfont;		  g_object_ref (result);		  if (xfont->in_cache)		    pango_x_fontmap_cache_remove (fontmap, xfont);		  break;		}	      tmp_list = tmp_list->next;	    }	  if (!result)	    {	      PangoXFont *xfont = pango_x_font_new (fontmap, best_match->xlfd, size);	      xfont->fontmap = fontmap;	      xfont->xface = best_match;	      best_match->cached_fonts = g_slist_prepend (best_match->cached_fonts, xfont);	      result = (PangoFont *)xfont;	    }	}    }  g_free (name);  return result;}/************************ * Coverage Map Caching * ************************//* We need to be robust against errors accessing the coverage * cache window, since it is not our window. So we temporarily * set this error handler while accessing it. The error_occurred * global allows us to tell whether an error occurred for * XChangeProperty */static gboolean error_occurred;static intignore_error (Display     *d,	      XErrorEvent *e){  return 0;}/* Retrieve the coverage window for the given display. * We look for a property on the root window, and then * check that the window that property points to also * has the same property pointing to itself. The second * check allows us to make sure that a stale property * isn't just pointing to some other apps window */static Windowpango_x_real_get_coverage_win (Display *display){  Atom type;  int format;  gulong n_items;  gulong bytes_after;  guchar *data;  Window retval = None;  int (*old_handler) (Display *, XErrorEvent *);  Atom coverage_win_atom = XInternAtom (display,					"PANGO_COVERAGE_WIN",

⌨️ 快捷键说明

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