📄 modules.c
字号:
/* Pango * modules.c: * * Copyright (C) 1999 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 <string.h>#include <limits.h>#include <errno.h>#include <gmodule.h>#include <glib/gstdio.h>#include "pango-enum-types.h"#include "pango-modules.h"#include "pango-impl-utils.h"#include "modules.h"typedef struct _PangoModule PangoModule;typedef struct _PangoModuleClass PangoModuleClass;#define PANGO_TYPE_MODULE (pango_module_get_type ())#define PANGO_MODULE(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), PANGO_TYPE_MODULE, PangoModule))#define PANGO_IS_MODULE(module) (G_TYPE_CHECK_INSTANCE_TYPE ((module), PANGO_TYPE_MODULE))typedef struct _PangoMapInfo PangoMapInfo;typedef struct _PangoEnginePair PangoEnginePair;typedef struct _PangoSubmap PangoSubmap;struct _PangoMap{ GArray *entries;};struct _PangoMapEntry{ GSList *exact; GSList *fallback;};struct _PangoMapInfo{ PangoLanguage *language; guint engine_type_id; guint render_type_id; PangoMap *map;};struct _PangoEnginePair{ PangoEngineInfo info; PangoModule *module; PangoEngine *engine;};struct _PangoModule{ GTypeModule parent_instance; char *path; GModule *library; void (*list) (PangoEngineInfo **engines, gint *n_engines); void (*init) (GTypeModule *module); void (*exit) (void); PangoEngine *(*create) (const gchar *id);};struct _PangoModuleClass{ GTypeModuleClass parent_class;};static GList *maps = NULL;static GSList *registered_engines = NULL;static GSList *dlloaded_engines = NULL;static GHashTable *dlloaded_modules;static GObjectClass *parent_class;static void build_map (PangoMapInfo *info);static void init_modules (void);static GType pango_module_get_type (void);/** * pango_find_map: * @language: the language tag for which to find the map * @engine_type_id: the engine type for the map to find * @render_type_id: the render type for the map to find * * Locate a #PangoMap for a particular engine type and render * type. The resulting map can be used to determine the engine * for each character. * * Return value: the suitable #PangoMap. **/PangoMap *pango_find_map (PangoLanguage *language, guint engine_type_id, guint render_type_id){ GList *tmp_list = maps; PangoMapInfo *map_info = NULL; gboolean found_earlier = FALSE; while (tmp_list) { map_info = tmp_list->data; if (map_info->engine_type_id == engine_type_id && map_info->render_type_id == render_type_id) { if (map_info->language == language) break; else found_earlier = TRUE; } tmp_list = tmp_list->next; } if (!tmp_list) { map_info = g_slice_new (PangoMapInfo); map_info->language = language; map_info->engine_type_id = engine_type_id; map_info->render_type_id = render_type_id; build_map (map_info); maps = g_list_prepend (maps, map_info); } else if (found_earlier) { /* Move the found map to the beginning of the list * for speed next time around if we had to do * any failing comparison. (No longer so important, * since we don't strcmp.) */ maps = g_list_remove_link(maps, tmp_list); maps = g_list_prepend(maps, tmp_list->data); g_list_free_1(tmp_list); } return map_info->map;}static gbooleanpango_module_load (GTypeModule *module){ PangoModule *pango_module = PANGO_MODULE (module); if (pango_module->path) { pango_module->library = g_module_open (pango_module->path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); if (!pango_module->library) { g_warning ("%s", g_module_error()); return FALSE; } /* extract symbols from the lib */ if (!g_module_symbol (pango_module->library, "script_engine_init", (gpointer *)&pango_module->init) || !g_module_symbol (pango_module->library, "script_engine_exit", (gpointer *)&pango_module->exit) || !g_module_symbol (pango_module->library, "script_engine_list", (gpointer *)&pango_module->list) || !g_module_symbol (pango_module->library, "script_engine_create", (gpointer *)&pango_module->create)) { g_warning ("%s", g_module_error()); g_module_close (pango_module->library); return FALSE; } } /* call the module's init function to let it */ /* setup anything it needs to set up. */ pango_module->init (module); return TRUE;}static voidpango_module_unload (GTypeModule *module){ PangoModule *pango_module = PANGO_MODULE (module); pango_module->exit(); if (pango_module->path) { g_module_close (pango_module->library); pango_module->library = NULL; pango_module->init = NULL; pango_module->exit = NULL; pango_module->list = NULL; pango_module->create = NULL; }}/* This only will ever be called if an error occurs during * initialization */static voidpango_module_finalize (GObject *object){ PangoModule *module = PANGO_MODULE (object); g_free (module->path); parent_class->finalize (object);}static voidpango_module_class_init (PangoModuleClass *class){ GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class); GObjectClass *gobject_class = G_OBJECT_CLASS (class); parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (class)); module_class->load = pango_module_load; module_class->unload = pango_module_unload; gobject_class->finalize = pango_module_finalize;}static PANGO_DEFINE_TYPE (PangoModule, pango_module, pango_module_class_init, NULL, G_TYPE_TYPE_MODULE)static PangoEngine *pango_engine_pair_get_engine (PangoEnginePair *pair){ if (!pair->engine) { if (g_type_module_use (G_TYPE_MODULE (pair->module))) { pair->engine = pair->module->create (pair->info.id); g_type_module_unuse (G_TYPE_MODULE (pair->module)); } if (!pair->engine) { /* If a module cannot be used, or doesn't not create an engine * correctly, we print out an error containing module name and id, * but to not flood the terminal with zillions of the message, we * set a flag on the module to only err once per module. */ static GQuark warned_quark = 0; if (!warned_quark) warned_quark = g_quark_from_static_string ("pango-module-warned"); if (!g_object_get_qdata (G_OBJECT (pair->module), warned_quark)) { g_warning ("Failed to load Pango module '%s' for id '%s'", pair->module->path, pair->info.id); g_object_set_qdata_full (G_OBJECT (pair->module), warned_quark, GINT_TO_POINTER (1), NULL); } } } return pair->engine;}static voidhandle_included_module (PangoIncludedModule *included_module, GSList **engine_list){ PangoModule *module = g_object_new (PANGO_TYPE_MODULE, NULL); PangoEngineInfo *engine_info; int n_engines; int i; module->list = included_module->list; module->init = included_module->init; module->exit = included_module->exit; module->create = included_module->create; module->list (&engine_info, &n_engines); for (i = 0; i < n_engines; i++) { PangoEnginePair *pair = g_slice_new (PangoEnginePair); pair->info = engine_info[i]; pair->module = module; pair->engine = NULL; *engine_list = g_slist_prepend (*engine_list, pair); }}static PangoModule *find_or_create_module (const char *raw_path){ PangoModule *module; char *path;#if defined(G_OS_WIN32) && defined(LIBDIR) if (strncmp (raw_path, LIBDIR "/pango/" MODULE_VERSION "/modules/", strlen (LIBDIR "/pango/" MODULE_VERSION "/modules/")) == 0) { /* This is an entry put there by make install on the * packager's system. On Windows a prebuilt Pango * package can be installed in a random * location. The pango.modules file distributed in * such a package contains paths from the package * builder's machine. Replace the path with the real * one on this machine. */ path = g_strconcat (pango_get_lib_subdirectory (), "\\" MODULE_VERSION "\\modules\\", raw_path + strlen (LIBDIR "/pango/" MODULE_VERSION "/modules/"), NULL); } else#endif { path = g_strdup (raw_path); } module = g_hash_table_lookup (dlloaded_modules, path); if (module) g_free (path); else { module = g_object_new (PANGO_TYPE_MODULE, NULL); module->path = path; g_hash_table_insert (dlloaded_modules, path, module); } return module;}static PangoScriptscript_from_string (const char *str){ static GEnumClass *class = NULL; GEnumValue *value; if (!class) class = g_type_class_ref (PANGO_TYPE_SCRIPT); value = g_enum_get_value_by_nick (class, str); if (!value) return PANGO_SCRIPT_INVALID_CODE; return value->value;}static voidscript_info_free (PangoEngineScriptInfo *script_info, gpointer data){ g_slice_free (PangoEngineScriptInfo, script_info);}static gboolean /* Returns true if succeeded, false if failed */process_module_file (FILE *module_file)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -