📄 pangoatsui-fontmap.c
字号:
/* Pango * pangoatsui-fontmap.c * * Copyright (C) 2000-2003 Red Hat, Inc. * Copyright (C) 2005-2007 Imendio AB * * 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 "pango-fontmap.h"#include "pangoatsui-private.h"#include "pango-impl-utils.h"#include "modules.h"#import <Cocoa/Cocoa.h>typedef struct _FontHashKey FontHashKey;struct _PangoATSUIFamily{ PangoFontFamily parent_instance; char *family_name; PangoFontFace **faces; gint n_faces;};#define PANGO_TYPE_ATSUI_FAMILY (pango_atsui_family_get_type ())#define PANGO_ATSUI_FAMILY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_ATSUI_FAMILY, PangoATSUIFamily))#define PANGO_IS_ATSUI_FAMILY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_ATSUI_FAMILY))#define PANGO_TYPE_ATSUI_FACE (pango_atsui_face_get_type ())#define PANGO_ATSUI_FACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_ATSUI_FACE, PangoATSUIFace))#define PANGO_IS_ATSUI_FACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_ATSUI_FACE))struct _PangoATSUIFace{ PangoFontFace parent_instance; PangoATSUIFamily *family; PangoCoverage *coverage; char *postscript_name; char *style_name; int weight; int traits; guint synthetic_italic : 1;};static GType pango_atsui_family_get_type (void);static GType pango_atsui_face_get_type (void);static gpointer pango_atsui_family_parent_class;static gpointer pango_atsui_face_parent_class;static const char *get_real_family (const char *family_name){ switch (family_name[0]) { case 'm': case 'M': if (g_ascii_strcasecmp (family_name, "monospace") == 0) return "Courier"; break; case 's': case 'S': if (g_ascii_strcasecmp (family_name, "sans") == 0) return "Helvetica"; else if (g_ascii_strcasecmp (family_name, "serif") == 0) return "Times"; break; } return family_name;}static voidpango_atsui_family_list_faces (PangoFontFamily *family, PangoFontFace ***faces, int *n_faces){ PangoATSUIFamily *atsuifamily = PANGO_ATSUI_FAMILY (family); if (atsuifamily->n_faces < 0) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; const char *real_family = get_real_family (atsuifamily->family_name); NSFontManager *manager = [NSFontManager sharedFontManager]; NSArray *members = [manager availableMembersOfFontFamily:[NSString stringWithUTF8String:real_family]]; int i, count; GHashTable *hash_table; GList *faces = NULL, *l; GList *synthetic_faces = NULL; /* The NSFontManager API returns italic faces for some families * even if they don't exist. When using Cocoa to create * instances of those fonts, Cocoa synthesizes italic versions * by applying a shear transformation. We do that manually for * those fonts in pangocairo-atsuifont.c. For many other fonts, * there is no italic face at all, so we create synthesized * versions of those like in the win32 and fontconfig backends. */ hash_table = g_hash_table_new (g_direct_hash, g_direct_equal); count = [members count]; for (i = 0; i < count; i++) { PangoATSUIFace *face = g_object_new (PANGO_TYPE_ATSUI_FACE, NULL); NSArray *font_array = [members objectAtIndex:i]; face->family = atsuifamily; face->postscript_name = g_strdup ([[font_array objectAtIndex:0] UTF8String]); face->style_name = g_strdup ([[font_array objectAtIndex:1] UTF8String]); face->weight = [[font_array objectAtIndex:2] intValue]; face->traits = [[font_array objectAtIndex:3] intValue]; faces = g_list_prepend (faces, face); if (face->traits & NSItalicFontMask) g_hash_table_insert (hash_table, GINT_TO_POINTER (face->weight), face); } for (l = faces; l; l = l->next) { PangoATSUIFace *face = l->data; if (!g_hash_table_lookup (hash_table, GINT_TO_POINTER (face->weight))) { PangoATSUIFace *italic_face = g_object_new (PANGO_TYPE_ATSUI_FACE, NULL); italic_face->family = atsuifamily; italic_face->postscript_name = g_strdup (face->postscript_name); italic_face->weight = face->weight; italic_face->traits = face->traits | NSItalicFontMask; italic_face->synthetic_italic = TRUE; /* Try to create a sensible face name. */ if (strcasecmp (face->style_name, "regular") == 0) italic_face->style_name = g_strdup ("Oblique"); else italic_face->style_name = g_strdup_printf ("%s Oblique", face->style_name); synthetic_faces = g_list_prepend (synthetic_faces, italic_face); } } faces = g_list_concat (faces, synthetic_faces); atsuifamily->n_faces = g_list_length (faces); atsuifamily->faces = g_new (PangoFontFace *, atsuifamily->n_faces); for (l = faces, i = 0; l; l = l->next, i++) atsuifamily->faces[i] = l->data; g_list_free (faces); g_hash_table_destroy (hash_table); [pool release]; } if (n_faces) *n_faces = atsuifamily->n_faces; if (faces) *faces = g_memdup (atsuifamily->faces, atsuifamily->n_faces * sizeof (PangoFontFace *));}static const char *pango_atsui_family_get_name (PangoFontFamily *family){ PangoATSUIFamily *atsuifamily = PANGO_ATSUI_FAMILY (family); return atsuifamily->family_name;}static gbooleanpango_atsui_family_is_monospace (PangoFontFamily *family){ /* Fixme: Implement */ return FALSE;}static voidpango_atsui_family_finalize (GObject *object){ PangoATSUIFamily *family = PANGO_ATSUI_FAMILY (object); int i; g_free (family->family_name); if (family->n_faces != -1) { for (i = 0; i < family->n_faces; i++) g_object_unref (family->faces[i]); g_free (family->faces); } G_OBJECT_CLASS (pango_atsui_family_parent_class)->finalize (object);}static voidpango_atsui_family_class_init (PangoFontFamilyClass *class){ GObjectClass *object_class = (GObjectClass *)class; int i; pango_atsui_family_parent_class = g_type_class_peek_parent (class); object_class->finalize = pango_atsui_family_finalize; class->list_faces = pango_atsui_family_list_faces; class->get_name = pango_atsui_family_get_name; class->is_monospace = pango_atsui_family_is_monospace; for (i = 0; _pango_included_atsui_modules[i].list; i++) pango_module_register (&_pango_included_atsui_modules[i]);}static voidpango_atsui_family_init (PangoATSUIFamily *family){ family->n_faces = -1;}static GTypepango_atsui_family_get_type (void){ static GType object_type = 0; if (G_UNLIKELY (!object_type)) { const GTypeInfo object_info = { sizeof (PangoFontFamilyClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) pango_atsui_family_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (PangoATSUIFamily), 0, /* n_preallocs */ (GInstanceInitFunc) pango_atsui_family_init, }; object_type = g_type_register_static (PANGO_TYPE_FONT_FAMILY, I_("PangoATSUIFamily"), &object_info, 0); } return object_type;}static PangoFontDescription *pango_atsui_face_describe (PangoFontFace *face){ PangoATSUIFace *atsuiface = PANGO_ATSUI_FACE (face); PangoFontDescription *description; PangoWeight pango_weight; PangoStyle pango_style; PangoVariant pango_variant; int weight; description = pango_font_description_new (); pango_font_description_set_family (description, atsuiface->family->family_name); weight = atsuiface->weight; if (weight == 1 || weight == 2) pango_weight = PANGO_WEIGHT_ULTRALIGHT; else if (weight == 3 || weight == 4) pango_weight = PANGO_WEIGHT_LIGHT; else if (weight == 5 || weight == 6) pango_weight = PANGO_WEIGHT_NORMAL; else if (weight == 7 || weight == 8) pango_weight = PANGO_WEIGHT_SEMIBOLD; else if (weight == 9 || weight == 10) pango_weight = PANGO_WEIGHT_BOLD; else if (weight == 11 || weight == 12) pango_weight = PANGO_WEIGHT_ULTRABOLD; else if (weight == 13 || weight == 14) pango_weight = PANGO_WEIGHT_HEAVY; else g_assert_not_reached (); if (atsuiface->traits & NSItalicFontMask) pango_style = PANGO_STYLE_ITALIC; else pango_style = PANGO_STYLE_NORMAL; if (atsuiface->traits & NSSmallCapsFontMask) pango_variant = PANGO_VARIANT_SMALL_CAPS; else pango_variant = PANGO_VARIANT_NORMAL; pango_font_description_set_weight (description, pango_weight); pango_font_description_set_style (description, pango_style); pango_font_description_set_variant (description, pango_variant); return description;}static const char *pango_atsui_face_get_face_name (PangoFontFace *face){ PangoATSUIFace *atsuiface = PANGO_ATSUI_FACE (face); return atsuiface->style_name;}static voidpango_atsui_face_list_sizes (PangoFontFace *face, int **sizes, int *n_sizes){ *n_sizes = 0; *sizes = NULL;}static voidpango_atsui_face_finalize (GObject *object){ PangoATSUIFace *atsuiface = PANGO_ATSUI_FACE (object); if (atsuiface->coverage) pango_coverage_unref (atsuiface->coverage); g_free (atsuiface->postscript_name); g_free (atsuiface->style_name); G_OBJECT_CLASS (pango_atsui_face_parent_class)->finalize (object);}static gbooleanpango_atsui_face_is_synthesized (PangoFontFace *face){ PangoATSUIFace *atsuiface = PANGO_ATSUI_FACE (face); return atsuiface->synthetic_italic;}static voidpango_atsui_face_class_init (PangoFontFaceClass *class){ GObjectClass *object_class = (GObjectClass *)class; pango_atsui_face_parent_class = g_type_class_peek_parent (class); object_class->finalize = pango_atsui_face_finalize; class->describe = pango_atsui_face_describe; class->get_face_name = pango_atsui_face_get_face_name; class->list_sizes = pango_atsui_face_list_sizes; class->is_synthesized = pango_atsui_face_is_synthesized;}GTypepango_atsui_face_get_type (void){ static GType object_type = 0; if (G_UNLIKELY (!object_type)) { const GTypeInfo object_info = { sizeof (PangoFontFaceClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) pango_atsui_face_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (PangoATSUIFace), 0, /* n_preallocs */ (GInstanceInitFunc) NULL, }; object_type = g_type_register_static (PANGO_TYPE_FONT_FACE, I_("PangoATSUIFace"), &object_info, 0); } return object_type;}const char *_pango_atsui_face_get_postscript_name (PangoATSUIFace *face){ return face->postscript_name;}gboolean_pango_atsui_face_get_synthetic_italic (PangoATSUIFace *face){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -