📄 modules.c
字号:
{ GString *line_buf = g_string_new (NULL); GString *tmp_buf = g_string_new (NULL); gboolean have_error = FALSE; while (pango_read_line (module_file, line_buf)) { PangoEnginePair *pair = g_slice_new (PangoEnginePair); PangoEngineScriptInfo *script_info; PangoScript script; GList *scripts = NULL; GList *tmp_list; const char *p; char *q; int i; p = line_buf->str; if (!pango_skip_space (&p)) { g_slice_free (PangoEnginePair, pair); continue; } i = 0; while (1) { if (!pango_scan_string (&p, tmp_buf)) { have_error = TRUE; goto error; } switch (i) { case 0: pair->module = find_or_create_module (tmp_buf->str); break; case 1: pair->info.id = g_strdup (tmp_buf->str); break; case 2: pair->info.engine_type = g_strdup (tmp_buf->str); break; case 3: pair->info.render_type = g_strdup (tmp_buf->str); break; default: q = strchr (tmp_buf->str, ':'); if (!q) { have_error = TRUE; goto error; } *q = '\0'; script = script_from_string (tmp_buf->str); if (script == PANGO_SCRIPT_INVALID_CODE) { have_error = TRUE; goto error; } script_info = g_slice_new (PangoEngineScriptInfo); script_info->script = script; script_info->langs = g_strdup (q + 1); scripts = g_list_prepend (scripts, script_info); } if (!pango_skip_space (&p)) break; i++; } if (i<3) { have_error = TRUE; goto error; } scripts = g_list_reverse (scripts); pair->info.n_scripts = g_list_length (scripts); pair->info.scripts = g_new (PangoEngineScriptInfo, pair->info.n_scripts); tmp_list = scripts; for (i=0; i<pair->info.n_scripts; i++) { pair->info.scripts[i] = *(PangoEngineScriptInfo *)tmp_list->data; tmp_list = tmp_list->next; } pair->engine = NULL; dlloaded_engines = g_slist_prepend (dlloaded_engines, pair); error: g_list_foreach (scripts, (GFunc)script_info_free, NULL); g_list_free (scripts); if (have_error) { g_printerr ("Error reading Pango modules file\n"); g_slice_free(PangoEnginePair, pair); break; } } g_string_free (line_buf, TRUE); g_string_free (tmp_buf, TRUE); return !have_error;}static voidread_modules (void){ FILE *module_file; char *file_str = pango_config_key_get ("Pango/ModuleFiles"); char **files; int n; dlloaded_modules = g_hash_table_new (g_str_hash, g_str_equal); if (!file_str) file_str = g_build_filename (pango_get_sysconf_subdirectory (), "pango.modules", NULL); files = pango_split_file_list (file_str); n = 0; while (files[n]) n++; while (n-- > 0) { module_file = g_fopen (files[n], "r"); if (module_file) { process_module_file(module_file); fclose(module_file); } } g_strfreev (files); g_free (file_str); dlloaded_engines = g_slist_reverse (dlloaded_engines);}static voidinit_modules (void){ static gboolean init = FALSE; int i; if (init) return; else init = TRUE; /* Make sure that the type system is initialized */ g_type_init (); for (i = 0; _pango_included_lang_modules[i].list; i++) pango_module_register (&_pango_included_lang_modules[i]); read_modules ();}static voidmap_add_engine (PangoMapInfo *info, PangoEnginePair *pair){ PangoMap *map = info->map; int i; for (i=0; i<pair->info.n_scripts; i++) { PangoScript script; PangoMapEntry *entry; gboolean is_exact = FALSE; if (pair->info.scripts[i].langs) { if (pango_language_matches (info->language, pair->info.scripts[i].langs)) is_exact = TRUE; } script = pair->info.scripts[i].script; if ((guint)script >= map->entries->len) g_array_set_size (map->entries, script + 1); entry = &g_array_index (map->entries, PangoMapEntry, script); if (is_exact) entry->exact = g_slist_prepend (entry->exact, pair); else entry->exact = g_slist_prepend (entry->fallback, pair); }}static voidmap_add_engine_list (PangoMapInfo *info, GSList *engines, const char *engine_type, const char *render_type){ GSList *tmp_list = engines; while (tmp_list) { PangoEnginePair *pair = tmp_list->data; tmp_list = tmp_list->next; if (strcmp (pair->info.engine_type, engine_type) == 0 && strcmp (pair->info.render_type, render_type) == 0) { map_add_engine (info, pair); } }}static voidbuild_map (PangoMapInfo *info){ const char *engine_type = g_quark_to_string (info->engine_type_id); const char *render_type = g_quark_to_string (info->render_type_id); init_modules(); if (!dlloaded_engines && !registered_engines) { static gboolean no_module_warning = FALSE; if (!no_module_warning) { gchar *filename = g_build_filename (pango_get_sysconf_subdirectory (), "pango.modules", NULL); g_warning ("No builtin or dynamically\n" "loaded modules were found. Pango will not work correctly.\n" "This probably means there was an error in the creation of:\n" " '%s'\n" "You should create this file by running pango-querymodules.", filename); g_free (filename); no_module_warning = TRUE; } } info->map = g_slice_new (PangoMap); info->map->entries = g_array_new (FALSE, TRUE, sizeof (PangoMapEntry)); map_add_engine_list (info, dlloaded_engines, engine_type, render_type); map_add_engine_list (info, registered_engines, engine_type, render_type);}/** * pango_map_get_engine: * @map: a #PangoMap * @script: a #PangoScript * * Returns the best engine listed in the map for a given script * * Return value: the best engine, if one is listed for the script, * or %NULL. The lookup may cause the engine to be loaded; * once an engine is loaded, it won't be unloaded. If multiple * engines are exact for the script, the choice of which is * returned is arbitrary. **/PangoEngine *pango_map_get_engine (PangoMap *map, PangoScript script){ PangoMapEntry *entry = NULL; PangoMapEntry *common_entry = NULL; if ((guint)script < map->entries->len) entry = &g_array_index (map->entries, PangoMapEntry, script); if (PANGO_SCRIPT_COMMON < map->entries->len) common_entry = &g_array_index (map->entries, PangoMapEntry, PANGO_SCRIPT_COMMON); if (entry && entry->exact) return pango_engine_pair_get_engine (entry->exact->data); else if (common_entry && common_entry->exact) return pango_engine_pair_get_engine (common_entry->exact->data); else if (entry && entry->fallback) return pango_engine_pair_get_engine (entry->fallback->data); else if (common_entry && common_entry->fallback) return pango_engine_pair_get_engine (common_entry->fallback->data); else return NULL;}static voidappend_engines (GSList **engine_list, GSList *pair_list){ GSList *l; for (l = pair_list; l; l = l->next) { PangoEngine *engine = pango_engine_pair_get_engine (l->data); if (engine) *engine_list = g_slist_append (*engine_list, engine); }}/** * pango_map_get_engines: * @map: a #PangoMap * @script: a #PangoScript * @exact_engines: location to store list of engines that exactly * handle this script. * @fallback_engines: location to store list of engines that approximately * handle this script. * * Finds engines in the map that handle the given script. The returned * lists should be freed with g_slist_free, but the engines in the * lists are owned by GLib and will be kept around permanently, so * they should not be unref'ed. * * Since: 1.4 **/voidpango_map_get_engines (PangoMap *map, PangoScript script, GSList **exact_engines, GSList **fallback_engines){ PangoMapEntry *entry = NULL; PangoMapEntry *common_entry = NULL; if ((guint)script < map->entries->len) entry = &g_array_index (map->entries, PangoMapEntry, script); if (PANGO_SCRIPT_COMMON < map->entries->len) common_entry = &g_array_index (map->entries, PangoMapEntry, PANGO_SCRIPT_COMMON); if (exact_engines) { *exact_engines = NULL; if (entry && entry->exact) append_engines (exact_engines, entry->exact); else if (common_entry && common_entry->exact) append_engines (exact_engines, common_entry->exact); } if (fallback_engines) { *fallback_engines = NULL; if (entry && entry->fallback) append_engines (fallback_engines, entry->fallback); else if (common_entry && common_entry->fallback) append_engines (fallback_engines, common_entry->fallback); }}/** * pango_module_register: * @module: a #PangoIncludedModule * * Registers a statically linked module with Pango. The * #PangoIncludedModule structure that is passed in contains the * functions that would otherwise be loaded from a dynamically loaded * module. **/voidpango_module_register (PangoIncludedModule *module){ GSList *tmp_list = NULL; handle_included_module (module, &tmp_list); registered_engines = g_slist_concat (registered_engines, g_slist_reverse (tmp_list));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -