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 + -
显示快捷键?