pangowin32-fontmap.c

来自「GTK+-2.0源码之pango-1.15.6.tar.gz」· C语言 代码 · 共 1,154 行 · 第 1/3 页

C
1,154
字号
/* Pango * pangowin32-fontmap.c: Win32 font handling * * Copyright (C) 2000 Red Hat Software * Copyright (C) 2000 Tor Lillqvist * Copyright (C) 2001 Alexander Larsson * * 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 <ctype.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include "pango-fontmap.h"#include "pango-impl-utils.h"#include "pangowin32-private.h"#include "modules.h"typedef struct _PangoWin32Family       PangoWin32Family;typedef struct _PangoWin32SizeInfo     PangoWin32SizeInfo;/* Number of freed fonts */#define MAX_FREED_FONTS 16struct _PangoWin32Family{  PangoFontFamily parent_instance;  char *family_name;  GSList *font_entries;  gboolean is_monospace;};struct _PangoWin32SizeInfo{  GSList *logfonts;};#define PANGO_WIN32_TYPE_FAMILY              (pango_win32_family_get_type ())#define PANGO_WIN32_FAMILY(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_WIN32_TYPE_FAMILY, PangoWin32Family))#define PANGO_WIN32_IS_FAMILY(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_WIN32_TYPE_FAMILY))#define PANGO_WIN32_TYPE_FACE              (pango_win32_face_get_type ())#define PANGO_WIN32_FACE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_WIN32_TYPE_FACE, PangoWin32Face))#define PANGO_WIN32_IS_FACE(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_WIN32_TYPE_FACE))GType             pango_win32_family_get_type        (void);GType             pango_win32_face_get_type          (void);static void       pango_win32_face_list_sizes        (PangoFontFace  *face,						      int           **sizes,						      int            *n_sizes);static void       pango_win32_font_map_finalize      (GObject                      *object);static PangoFont *pango_win32_font_map_load_font     (PangoFontMap                 *fontmap,						      PangoContext                 *context,						      const PangoFontDescription   *description);static void       pango_win32_font_map_list_families (PangoFontMap                 *fontmap,						       PangoFontFamily            ***families,						       int                          *n_families);static PangoFont *pango_win32_font_map_real_find_font (PangoWin32FontMap          *win32fontmap,						       PangoContext               *context,						       PangoWin32Face             *face,						       const PangoFontDescription *description);static void       pango_win32_fontmap_cache_clear    (PangoWin32FontMap            *win32fontmap);static void       pango_win32_insert_font            (PangoWin32FontMap            *fontmap,						      LOGFONT                      *lfp);static PangoWin32FontMap *default_fontmap = NULL;G_DEFINE_TYPE (PangoWin32FontMap, pango_win32_font_map, PANGO_TYPE_FONT_MAP)#define TOLOWER(c) \  (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' + 'a' : (c))static guintcase_insensitive_hash (const char *key){  const char *p = key;  guint h = TOLOWER (*p);  if (h)    {      for (p += 1; *p != '\0'; p++)	h = (h << 5) - h + TOLOWER (*p);    }  return h;}static gbooleancase_insensitive_equal (const char *key1,			const char *key2){  return (g_ascii_strcasecmp (key1, key2) == 0);}/* A hash function for LOGFONTs that takes into consideration only * those fields that indicate a specific .ttf file is in use: * lfFaceName, lfItalic and lfWeight. Dunno how correct this is. */static guintlogfont_nosize_hash (const LOGFONT *lfp){  return case_insensitive_hash (lfp->lfFaceName) + lfp->lfItalic + lfp->lfWeight;}/* Ditto comparison function */static gbooleanlogfont_nosize_equal (const LOGFONT *lfp1,		      const LOGFONT *lfp2){  return (case_insensitive_equal (lfp1->lfFaceName, lfp2->lfFaceName)	  && lfp1->lfItalic == lfp2->lfItalic	  && lfp1->lfWeight == lfp2->lfWeight);}static int CALLBACKpango_win32_inner_enum_proc (LOGFONT    *lfp,			     TEXTMETRIC *metrics,			     DWORD       fontType,			     LPARAM      lParam){  PangoWin32FontMap *win32fontmap = (PangoWin32FontMap *)lParam;  /* Windows generates synthetic vertical writing versions of East   * Asian fonts with @ prepended to their name, ignore them.   */  if (lfp->lfFaceName[0] != '@')    pango_win32_insert_font (win32fontmap, lfp);  return 1;}static int CALLBACKpango_win32_enum_proc (LOGFONT    *lfp,		       TEXTMETRIC *metrics,		       DWORD       fontType,		       LPARAM      lParam){  LOGFONT lf;  PING(("%s", lfp->lfFaceName));  if (fontType != TRUETYPE_FONTTYPE)    return 1;  lf = *lfp;  EnumFontFamiliesExA (pango_win32_hdc, &lf,		       (FONTENUMPROC) pango_win32_inner_enum_proc,		       lParam, 0);  return 1;}static gbooleanfirst_match (gpointer key,	    gpointer value,	    gpointer user_data){  LOGFONT *lfp = (LOGFONT *)key;  LOGFONT *lfp2 = (LOGFONT *)((PangoWin32SizeInfo *)value)->logfonts->data;  gchar *name = (gchar *)user_data;  if (strcmp (lfp->lfFaceName, name) == 0 && lfp->lfWeight == lfp2->lfWeight)    return TRUE;  return FALSE;}typedef struct _ItalicHelper{  PangoWin32FontMap *fontmap;  GSList            *list;} ItalicHelper;static voidensure_italic (gpointer key,	       gpointer value,	       gpointer user_data){  ItalicHelper *helper = (ItalicHelper *)user_data;  /* PangoWin32Family *win32family = (PangoWin32Family *)value; */  PangoWin32SizeInfo *sip = (PangoWin32SizeInfo *)g_hash_table_find (helper->fontmap->size_infos, first_match, key);  if (sip)    {      GSList *list = sip->logfonts;      while (list)	{	  LOGFONT *lfp = (LOGFONT *)list->data;	  if (!lfp->lfItalic)	    {	      /* we have a non italic variant, look if there is an italic */	      LOGFONT logfont = *lfp;	      logfont.lfItalic = 1;	      sip = (PangoWin32SizeInfo *)g_hash_table_find (helper->fontmap->size_infos, first_match, &logfont);	      if (!sip)		{		  /* remember the non italic variant to be added later as italic */		  helper->list = g_slist_append (helper->list, lfp);		}	    }	  list = list->next;	}    }}static voidpango_win32_font_map_init (PangoWin32FontMap *win32fontmap){  LOGFONT logfont;  win32fontmap->families = g_hash_table_new ((GHashFunc) case_insensitive_hash,					     (GEqualFunc) case_insensitive_equal);  win32fontmap->size_infos =    g_hash_table_new ((GHashFunc) logfont_nosize_hash, (GEqualFunc) logfont_nosize_equal);  win32fontmap->n_fonts = 0;  win32fontmap->font_cache = pango_win32_font_cache_new ();  win32fontmap->freed_fonts = g_queue_new ();  memset (&logfont, 0, sizeof (logfont));  logfont.lfCharSet = DEFAULT_CHARSET;  EnumFontFamiliesExA (pango_win32_hdc, &logfont, (FONTENUMPROC) pango_win32_enum_proc,		       (LPARAM)win32fontmap, 0);  /* create synthetic italic entries */  {    ItalicHelper helper = { win32fontmap, NULL };    GSList *list;    g_hash_table_foreach (win32fontmap->families, ensure_italic, &helper);    /* cant modify while iterating */    list = helper.list;    while (list)      {	LOGFONT logfont = *((LOGFONT *)list->data);	logfont.lfItalic = 1;	pango_win32_insert_font (win32fontmap, &logfont);	list = list->next;      }    g_slist_free (helper.list);  }  win32fontmap->resolution = (PANGO_SCALE / (double) GetDeviceCaps (pango_win32_hdc, LOGPIXELSY)) * 72.0;}static voidpango_win32_font_map_class_init (PangoWin32FontMapClass *class){  GObjectClass *object_class = G_OBJECT_CLASS (class);  PangoFontMapClass *fontmap_class = PANGO_FONT_MAP_CLASS (class);  int i;  class->find_font = pango_win32_font_map_real_find_font;  object_class->finalize = pango_win32_font_map_finalize;  fontmap_class->load_font = pango_win32_font_map_load_font;  fontmap_class->list_families = pango_win32_font_map_list_families;  fontmap_class->shape_engine_type = PANGO_RENDER_TYPE_WIN32;  pango_win32_get_dc ();  for (i = 0; _pango_included_win32_modules[i].list; i++)    pango_module_register (&_pango_included_win32_modules[i]);}/** * pango_win32_font_map_for_display: * * Returns a #PangoWin32FontMap. Font maps are cached and should * not be freed. If the font map is no longer needed, it can * be released with pango_win32_shutdown_display(). * * Return value: a #PangoFontMap. **/PangoFontMap *pango_win32_font_map_for_display (void){  /* Make sure that the type system is initialized */  g_type_init ();  if (default_fontmap != NULL)    return PANGO_FONT_MAP (default_fontmap);  default_fontmap = g_object_new (PANGO_TYPE_WIN32_FONT_MAP, NULL);  return PANGO_FONT_MAP (default_fontmap);}/** * pango_win32_shutdown_display: * * Free cached resources. **/voidpango_win32_shutdown_display (void){  if (default_fontmap)    {      pango_win32_fontmap_cache_clear (default_fontmap);      g_object_unref (default_fontmap);      default_fontmap = NULL;    }}static voidpango_win32_font_map_finalize (GObject *object){  PangoWin32FontMap *win32fontmap = PANGO_WIN32_FONT_MAP (object);  g_list_foreach (win32fontmap->freed_fonts->head, (GFunc)g_object_unref, NULL);  g_queue_free (win32fontmap->freed_fonts);  pango_win32_font_cache_free (win32fontmap->font_cache);  G_OBJECT_CLASS (pango_win32_font_map_parent_class)->finalize (object);}/* * PangoWin32Family */static voidpango_win32_family_list_faces (PangoFontFamily  *family,			       PangoFontFace  ***faces,			       int              *n_faces){  PangoWin32Family *win32family = PANGO_WIN32_FAMILY (family);  *n_faces = g_slist_length (win32family->font_entries);  if (faces)    {      GSList *tmp_list;      int i = 0;      *faces = g_new (PangoFontFace *, *n_faces);      tmp_list = win32family->font_entries;      while (tmp_list)	{	  (*faces)[i++] = tmp_list->data;	  tmp_list = tmp_list->next;	}    }}static const char *pango_win32_family_get_name (PangoFontFamily  *family){  PangoWin32Family *win32family = PANGO_WIN32_FAMILY (family);  return win32family->family_name;}static gbooleanpango_win32_family_is_monospace (PangoFontFamily *family){  PangoWin32Family *win32family = PANGO_WIN32_FAMILY (family);  return win32family->is_monospace;}

⌨️ 快捷键说明

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