diff options
author | Owen Taylor <otaylor@redhat.com> | 2003-08-03 21:57:35 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2003-08-03 21:57:35 +0000 |
commit | 2584212cd0976f5f95d9381e829917e7d2a10d28 (patch) | |
tree | 5773e9f6802f8316c5c7463aa55677babe67343c /pango | |
parent | 95a8d1788e884b7d8d29d4171a1adc51c61e880e (diff) | |
download | pango-2584212cd0976f5f95d9381e829917e7d2a10d28.tar.gz |
Make PangoEngine{,Lang,Shape} GObjects, and use a GTypeModule-based
Sat Aug 2 23:19:16 2003 Owen Taylor <otaylor@redhat.com>
* pango/pango-engine.[ch] modules/*/*-{fc,win32,x}.c
pango/modules.c pango/break.c pango/pango-context.c
pango/pango-layout.c pango/pango-modules.h
pango/querymodules.c pango/shape.c: Make
PangoEngine{,Lang,Shape} GObjects, and use a
GTypeModule-based module-loading system closely based
on the one used for GtkIMContext and GtkThemeEngine.
* pango/pango-impl-utils.h: OK, I'm tired of typing
in get_type() functions.
* pango/pango-script.[ch] pango/pango-script-table.h
tests/testscript.c tools/gen-script-table.pl: Add port
of script-range code from ICU in preparation for future
use. (#91542)
* tools/gen-script-for-lang.c: Utility program to determine
the script for each fontconfig .orth file.
* docs/tmpl/{scripts.sgml,pango-engine-lang.sgml,
pango-engine-shape.sgml} docs/pango-sections.txt docs/pango-docs.sgml:
Redo to go along with the above changes.
* configure.in: chmod +x tests/runtests.sh
Diffstat (limited to 'pango')
-rw-r--r-- | pango/Makefile.am | 45 | ||||
-rw-r--r-- | pango/break.c | 4 | ||||
-rw-r--r-- | pango/modules.c | 243 | ||||
-rw-r--r-- | pango/pango-context.c | 63 | ||||
-rw-r--r-- | pango/pango-engine.c | 162 | ||||
-rw-r--r-- | pango/pango-engine.h | 314 | ||||
-rw-r--r-- | pango/pango-impl-utils.h | 77 | ||||
-rw-r--r-- | pango/pango-layout.c | 5 | ||||
-rw-r--r-- | pango/pango-modules.h | 8 | ||||
-rw-r--r-- | pango/pango-script-table.h | 404 | ||||
-rw-r--r-- | pango/pango-script.c | 343 | ||||
-rw-r--r-- | pango/pango-script.h | 111 | ||||
-rw-r--r-- | pango/pango.h | 1 | ||||
-rw-r--r-- | pango/pangox-fontmap.c | 3 | ||||
-rw-r--r-- | pango/querymodules.c | 10 | ||||
-rw-r--r-- | pango/shape.c | 5 |
16 files changed, 1605 insertions, 193 deletions
diff --git a/pango/Makefile.am b/pango/Makefile.am index 8d6aa7de..1048b1ab 100644 --- a/pango/Makefile.am +++ b/pango/Makefile.am @@ -49,26 +49,30 @@ endif pango-win32res.lo: pango.rc $(top_srcdir)/../glib/build/win32/lt-compile-resource $< $@ -libpango_1_0_la_SOURCES = \ - break.c \ - fonts.c \ - glyphstring.c \ - mapping.c \ - modules.c \ - pango-attributes.c \ - pango-color.c \ - pango-context.c \ - pango-coverage.c \ - pango-fontmap.c \ - pango-fontset.c \ - pango-glyph-item.c \ - pango-item.c \ - pango-layout.c \ - pango-markup.c \ - pango-tabs.c \ - pango-utils.c \ - reorder-items.c \ - shape.c \ +libpango_1_0_la_SOURCES = \ + break.c \ + fonts.c \ + glyphstring.c \ + mapping.c \ + modules.c \ + pango-attributes.c \ + pango-color.c \ + pango-context.c \ + pango-coverage.c \ + pango-engine.c \ + pango-engine-private.h \ + pango-fontmap.c \ + pango-fontset.c \ + pango-glyph-item.c \ + pango-item.c \ + pango-layout.c \ + pango-markup.c \ + pango-script.c \ + pango-script-table.h \ + pango-tabs.c \ + pango-utils.c \ + reorder-items.c \ + shape.c \ pango-enum-types.c pango_headers = \ @@ -86,6 +90,7 @@ pango_headers = \ pango-item.h \ pango-layout.h \ pango-modules.h \ + pango-script.h \ pango-tabs.h \ pango-types.h \ pango-utils.h \ diff --git a/pango/break.c b/pango/break.c index d49c242e..491e936f 100644 --- a/pango/break.c +++ b/pango/break.c @@ -1306,8 +1306,8 @@ pango_break (const gchar *text, length = strlen (text); if (analysis->lang_engine && - analysis->lang_engine->script_break) - (* analysis->lang_engine->script_break) (text, length, analysis, attrs, attrs_len); + PANGO_ENGINE_LANG_CLASS (analysis->lang_engine)->script_break) + PANGO_ENGINE_LANG_CLASS (analysis->lang_engine)->script_break (analysis->lang_engine, text, length, analysis, attrs, attrs_len); else pango_default_break (text, length, analysis, attrs, attrs_len); } diff --git a/pango/modules.c b/pango/modules.c index d01a8cf8..afbe1169 100644 --- a/pango/modules.c +++ b/pango/modules.c @@ -29,6 +29,14 @@ #include "pango-modules.h" #include "pango-utils.h" +#include "pango-impl-utils.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; @@ -60,16 +68,34 @@ struct _PangoMapInfo struct _PangoEnginePair { PangoEngineInfo info; - gboolean included; - void *load_info; + PangoModule *module; PangoEngine *engine; }; -static GList *maps = NULL; +struct _PangoModule +{ + GTypeModule parent_instance; + + char *path; + GModule *library; -static GSList *builtin_engines = NULL; + 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; + +GObjectClass *parent_class; static void build_map (PangoMapInfo *info); static void init_modules (void); @@ -136,56 +162,126 @@ pango_find_map (PangoLanguage *language, return map_info->map; } -static PangoEngine * -pango_engine_pair_get_engine (PangoEnginePair *pair) +static gboolean +pango_module_load (GTypeModule *module) { - if (!pair->engine) + PangoModule *pango_module = PANGO_MODULE (module); + + if (pango_module->path) { - if (pair->included) + pango_module->library = g_module_open (pango_module->path, 0); + if (!pango_module->library) { - PangoIncludedModule *included_module = pair->load_info; - - pair->engine = included_module->load (pair->info.id); + g_warning (g_module_error()); + return FALSE; } - else + + /* 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)) { - GModule *module; - char *module_name = pair->load_info; - PangoEngine *(*load) (const gchar *id); - - module = g_module_open (module_name, 0); - if (!module) - { - g_printerr ("Cannot load module %s: %s\n", - module_name, g_module_error()); - return NULL; - } + g_warning (g_module_error()); + g_module_close (pango_module->library); - g_module_symbol (module, "script_engine_load", (gpointer *) &load); - if (!load) - { - g_printerr ("cannot retrieve script_engine_load from %s: %s\n", - module_name, g_module_error()); - g_module_close (module); - return NULL; - } - - pair->engine = (*load) (pair->info.id); + 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 void +pango_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 void +pango_module_finalize (GObject *object) +{ + PangoModule *module = PANGO_MODULE (object); + + g_free (module->path); + + parent_class->finalize (object); +} + +static void +pango_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) + g_printerr ("Failed to load Pango module for id: '%s'", pair->info.id); } return pair->engine; } static void -handle_included_module (PangoIncludedModule *module, - GSList **engine_list) +handle_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++) @@ -193,14 +289,56 @@ handle_included_module (PangoIncludedModule *module, PangoEnginePair *pair = g_new (PangoEnginePair, 1); pair->info = engine_info[i]; - pair->included = TRUE; - pair->load_info = module; + 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 gboolean /* Returns true if succeeded, false if failed */ process_module_file (FILE *module_file) { @@ -219,8 +357,6 @@ process_module_file (FILE *module_file) int i; int start, end; - pair->included = FALSE; - p = line_buf->str; if (!pango_skip_space (&p)) @@ -241,29 +377,7 @@ process_module_file (FILE *module_file) switch (i) { case 0: - pair->load_info = g_strdup (tmp_buf->str); -#if defined(G_OS_WIN32) && defined(LIBDIR) - if (strncmp (pair->load_info, - 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. */ - gchar *tem = pair->load_info; - pair->load_info = - g_strconcat (pango_get_lib_subdirectory (), - "\\" MODULE_VERSION "\\modules\\", - tem + strlen (LIBDIR "/pango/" MODULE_VERSION "/modules/"), - NULL); - g_free (tem); - } - -#endif + pair->module = find_or_create_module (tmp_buf->str); break; case 1: pair->info.id = g_strdup (tmp_buf->str); @@ -351,6 +465,8 @@ read_modules (void) 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", @@ -520,7 +636,7 @@ build_map (PangoMapInfo *info) init_modules(); - if (!dlloaded_engines && !registered_engines && !builtin_engines) + if (!dlloaded_engines && !registered_engines) { static gboolean no_module_warning = FALSE; if (!no_module_warning) @@ -546,7 +662,6 @@ build_map (PangoMapInfo *info) map_add_engine_list (info, dlloaded_engines, engine_type, render_type); map_add_engine_list (info, registered_engines, engine_type, render_type); - map_add_engine_list (info, builtin_engines, engine_type, render_type); } /** diff --git a/pango/pango-context.c b/pango/pango-context.c index 99407d85..8f9de155 100644 --- a/pango/pango-context.c +++ b/pango/pango-context.c @@ -25,6 +25,7 @@ #include "pango/pango-context.h" #include "pango/pango-utils.h" +#include "pango-engine.h" #include "pango-modules.h" struct _PangoContext @@ -495,66 +496,6 @@ pango_itemize (PangoContext *context, return g_list_reverse (result); } -static void -fallback_engine_shape (PangoFont *font, - const char *text, - gint length, - PangoAnalysis *analysis, - PangoGlyphString *glyphs) -{ - int n_chars; - int i; - const char *p; - - g_return_if_fail (font != NULL); - g_return_if_fail (text != NULL); - g_return_if_fail (length >= 0); - g_return_if_fail (analysis != NULL); - - n_chars = g_utf8_strlen (text, length); - pango_glyph_string_set_size (glyphs, n_chars); - - p = text; - i = 0; - while (i < n_chars) - { - glyphs->glyphs[i].glyph = 0; - - glyphs->glyphs[i].geometry.x_offset = 0; - glyphs->glyphs[i].geometry.y_offset = 0; - glyphs->glyphs[i].geometry.width = 0; - - glyphs->log_clusters[i] = p - text; - - ++i; - p = g_utf8_next_char (p); - } -} - -static PangoCoverage* -fallback_engine_get_coverage (PangoFont *font, - PangoLanguage *lang) -{ - PangoCoverage *result = pango_coverage_new (); - - /* We return an empty coverage (this function won't get - * called, but if it is, empty coverage will keep - * it from being used). - */ - - return result; -} - -static PangoEngineShape fallback_shaper = { - { - "FallbackScriptEngine", - PANGO_ENGINE_TYPE_SHAPE, - sizeof (PangoEngineShape) - }, - fallback_engine_shape, - fallback_engine_get_coverage -}; - static gboolean advance_iterator_to (PangoAttrIterator *iterator, int start_index) @@ -683,7 +624,7 @@ add_engines (PangoContext *context, analysis->shape_engine = NULL; if (analysis->shape_engine == NULL) - analysis->shape_engine = &fallback_shaper; + analysis->shape_engine = pango_get_fallback_shaper (); analysis->extra_attrs = extra_attrs; } diff --git a/pango/pango-engine.c b/pango/pango-engine.c new file mode 100644 index 00000000..034f5eb6 --- /dev/null +++ b/pango/pango-engine.c @@ -0,0 +1,162 @@ +/* Pango + * pango-engine.c: Engines for script and language specific processing + * + * Copyright (C) 2003 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 "pango-engine.h" +#include "pango-engine-private.h" +#include "pango-impl-utils.h" + +PANGO_DEFINE_TYPE_ABSTRACT (PangoEngine, pango_engine, + NULL, NULL, + G_TYPE_OBJECT); + +PANGO_DEFINE_TYPE_ABSTRACT (PangoEngineLang, pango_engine_lang, + NULL, NULL, + PANGO_TYPE_ENGINE); + +static PangoCoverage * +pango_engine_shape_real_get_coverage (PangoEngineShape *engine, + PangoFont *font, + PangoLanguage *language) +{ + return pango_font_get_coverage (font, language); +} + +void +pango_engine_shape_class_init (PangoEngineShapeClass *class) +{ + class->get_coverage = pango_engine_shape_real_get_coverage; +} + +PANGO_DEFINE_TYPE_ABSTRACT (PangoEngineShape, pango_engine_shape, + pango_engine_shape_class_init, NULL, + PANGO_TYPE_ENGINE); + +void +_pango_engine_shape_shape (PangoEngineShape *engine, + PangoFont *font, + const char *text, + int length, + PangoAnalysis *analysis, + PangoGlyphString *glyphs) +{ + g_return_if_fail (PANGO_IS_ENGINE_SHAPE (engine)); + g_return_if_fail (PANGO_IS_FONT (font)); + g_return_if_fail (text != NULL); + g_return_if_fail (analysis != NULL); + g_return_if_fail (glyphs != NULL); + + PANGO_ENGINE_SHAPE_GET_CLASS (engine)->script_shape (engine, + font, + text, length, + analysis, + glyphs); +} + +PangoCoverage * +_pango_engine_shape_get_coverage (PangoEngineShape *engine, + PangoFont *font, + PangoLanguage *language) +{ + g_return_val_if_fail (PANGO_IS_ENGINE_SHAPE (engine), NULL); + g_return_val_if_fail (PANGO_IS_FONT (font), NULL); + + return PANGO_ENGINE_SHAPE_GET_CLASS (engine)->get_coverage (engine, + font, + language); +} + +/* No extra fields needed */ +typedef PangoEngineShape PangoFallbackEngine; +typedef PangoEngineShapeClass PangoFallbackEngineClass; + +static void +fallback_engine_shape (PangoEngineShape *engine, + PangoFont *font, + const char *text, + gint length, + PangoAnalysis *analysis, + PangoGlyphString *glyphs) +{ + int n_chars; + int i; + const char *p; + + g_return_if_fail (font != NULL); + g_return_if_fail (text != NULL); + g_return_if_fail (length >= 0); + g_return_if_fail (analysis != NULL); + + n_chars = g_utf8_strlen (text, length); + pango_glyph_string_set_size (glyphs, n_chars); + + p = text; + i = 0; + while (i < n_chars) + { + glyphs->glyphs[i].glyph = 0; + + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + glyphs->glyphs[i].geometry.width = 0; + + glyphs->log_clusters[i] = p - text; + + ++i; + p = g_utf8_next_char (p); + } +} + +static PangoCoverage* +fallback_engine_get_coverage (PangoEngineShape *engine, + PangoFont *font, + PangoLanguage *lang) +{ + PangoCoverage *result = pango_coverage_new (); + + /* We return an empty coverage (this function won't get + * called, but if it is, empty coverage will keep + * it from being used). + */ + + return result; +} + +static void +fallback_engine_class_init (PangoEngineShapeClass *class) +{ + class->get_coverage = fallback_engine_get_coverage; + class->script_shape = fallback_engine_shape; +} + +static PANGO_DEFINE_TYPE (PangoFallbackEngine, pango_fallback_engine, + fallback_engine_class_init, NULL, + PANGO_TYPE_ENGINE_SHAPE); + +PangoEngineShape * +pango_get_fallback_shaper (void) +{ + static PangoEngineShape *fallback_shaper = NULL; + if (!fallback_shaper) + fallback_shaper = g_object_new (pango_fallback_engine_get_type (), NULL); + + return fallback_shaper; +} + diff --git a/pango/pango-engine.h b/pango/pango-engine.h index 0a7ada25..1aa429de 100644 --- a/pango/pango-engine.h +++ b/pango/pango-engine.h @@ -1,7 +1,7 @@ /* Pango - * pango-engine.h: Module handling + * pango-engine.h: Engines for script and language specific processing * - * Copyright (C) 2000 Red Hat Software + * Copyright (C) 2000,2003 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 @@ -33,66 +33,316 @@ G_BEGIN_DECLS /* Module API */ -#define PANGO_ENGINE_TYPE_LANG "PangoEngineLang" -#define PANGO_ENGINE_TYPE_SHAPE "PangoEngineShape" - #define PANGO_RENDER_TYPE_NONE "PangoRenderNone" -typedef struct _PangoEngineInfo PangoEngineInfo; -typedef struct _PangoEngineRange PangoEngineRange; +#define PANGO_TYPE_ENGINE (pango_engine_get_type ()) +#define PANGO_ENGINE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_ENGINE, PangoEngine)) +#define PANGO_IS_ENGINE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_ENGINE)) +#define PANGO_ENGINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_ENGINE, PangoEngineClass)) +#define PANGO_IS_ENGINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_ENGINE)) +#define PANGO_ENGINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_ENGINE, PangoEngineClass)) + typedef struct _PangoEngine PangoEngine; +typedef struct _PangoEngineClass PangoEngineClass; -struct _PangoEngineRange +/** + * PangoEngine: + * + * #PangoEngine is the base class for all types of language and + * script specific engines. It has no functionality by itself. + **/ +struct _PangoEngine { - guint32 start; - guint32 end; - gchar *langs; + /*< private >*/ + GObject parent_instance; }; -struct _PangoEngineInfo +/** + * PangoEngineClass: + * + * Class structure for #PangoEngine + **/ +struct _PangoEngineClass { - gchar *id; - gchar *engine_type; - gchar *render_type; - PangoEngineRange *ranges; - gint n_ranges; + /*< private >*/ + GObjectClass parent_class; }; -struct _PangoEngine +GType pango_engine_get_type (void) G_GNUC_CONST; + +#define PANGO_ENGINE_TYPE_LANG "PangoEngineLang" + +#define PANGO_TYPE_ENGINE_LANG (pango_engine_lang_get_type ()) +#define PANGO_ENGINE_LANG(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_ENGINE_LANG, PangoEngineLang)) +#define PANGO_IS_ENGINE_LANG(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_ENGINE_LANG)) +#define PANGO_ENGINE_LANG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_ENGINE_LANG, PangoEngineLangClass)) +#define PANGO_IS_ENGINE_LANG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_ENGINE_LANG)) +#define PANGO_ENGINE_LANG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_ENGINE_LANG, PangoEngineLangClass)) + +typedef struct _PangoEngineLangClass PangoEngineLangClass; + +/** + * PangoEngineLang: + * + * The #PangoEngineLang class is implemented by engines that + * customize the rendering-system independent part of the + * Pango pipeline for a particular script or language. For + * instance, a custom #PangoEngineLang could be provided for + * Thai to implement the dictionary-based word boundary + * lookups needed for that language. + **/ +struct _PangoEngineLang { - gchar *id; - gchar *type; - gint length; + /*< private >*/ + PangoEngine parent_instance; }; -struct _PangoEngineLang +/** + * PangoEngineLangClass: + * @script_break: Provides a custom implementation of pango_break(). + * if this is %NULL, pango_default_break() will be used. + * + * Class structure for #PangoEngineLang + **/ +struct _PangoEngineLangClass { - PangoEngine engine; - void (*script_break) (const char *text, + /*< private >*/ + PangoEngineClass parent_class; + + /*< public >*/ + void (*script_break) (PangoEngineLang *engine, + const char *text, int len, PangoAnalysis *analysis, PangoLogAttr *attrs, int attrs_len); }; +GType pango_engine_lang_get_type (void) G_GNUC_CONST; + +#define PANGO_ENGINE_TYPE_SHAPE "PangoEngineShape" + +#define PANGO_TYPE_ENGINE_SHAPE (pango_engine_shape_get_type ()) +#define PANGO_ENGINE_SHAPE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_ENGINE_SHAPE, PangoEngineShape)) +#define PANGO_IS_ENGINE_SHAPE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_ENGINE_SHAPE)) +#define PANGO_ENGINE_SHAPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_ENGINE_SHAPE, PangoEngine_ShapeClass)) +#define PANGO_IS_ENGINE_SHAPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_ENGINE_SHAPE)) +#define PANGO_ENGINE_SHAPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_ENGINE_SHAPE, PangoEngineShapeClass)) + +typedef struct _PangoEngineShapeClass PangoEngineShapeClass; + +/** + * PangoEngineShape + * + * The #PangoEngineShape class is implemented by engines that + * customize the rendering-system dependent part of the + * Pango pipeline for a particular script or language. + * A #PangoEngineShape implementation is then specific to both + * a particular rendering system or group of rendering systems + * and to a particular script. For instance, there is one + * #PangoEngineShape implementation to handling shaping Arabic + * for Fontconfig-based backends. + **/ struct _PangoEngineShape { - PangoEngine engine; - void (*script_shape) (PangoFont *font, + PangoEngine parent_instance; +}; + +/** + * PangoEngineShapeClass: + * @script_shape: Given a font, a piece of text, and a #PangoAnalysis + * structure, converts characters to glyphs and positions the + * resulting glyphs. The results are stored in the #PangoGlyphString + * that is passed in. (The implementation should resize it + * appropriately using pango_glyph_string_set_size()). All fields + * of the @log_clusters and @glyphs array must be filled in, with + * the exception that Pango will automatically generate + * <literal>glyphs->glyphs[i].attr.is_cluster_start</literal> + * using the @log_clusters array. Each input character must occur in one + * of the output logical clusters; + * if no rendering is desired for a character, this may involve + * inserting glyphs with the #PangoGlyph ID 0, which is guaranteed never + * to render. + * @get_coverage: Returns the characters that this engine can cover + * with a given font for a given language. If not overridden, the default + * implementation simply returns the coverage information for the + * font itself unmodified. + * + * Class structure for #PangoEngineShape + **/ +struct _PangoEngineShapeClass +{ + /*< private >*/ + PangoEngineClass parent_class; + + /*< public >*/ + void (*script_shape) (PangoEngineShape *engine, + PangoFont *font, const char *text, int length, PangoAnalysis *analysis, PangoGlyphString *glyphs); - PangoCoverage *(*get_coverage) (PangoFont *font, + PangoCoverage *(*get_coverage) (PangoEngineShape *engine, + PangoFont *font, PangoLanguage *language); }; -/* A module should export the following functions */ +GType pango_engine_shape_get_type (void) G_GNUC_CONST; + +typedef struct _PangoEngineInfo PangoEngineInfo; +typedef struct _PangoEngineRange PangoEngineRange; + +struct _PangoEngineRange +{ + guint32 start; + guint32 end; + gchar *langs; +}; + +struct _PangoEngineInfo +{ + gchar *id; + gchar *engine_type; + gchar *render_type; + PangoEngineRange *ranges; + gint n_ranges; +}; + +/** + * script_engine_list: + * @engines: location to store a pointer to an array of engines. + * @n_engines: location to store the number of elements in @engines. + * + * Function to be provided by a module to list the engines that the + * module supplies. The function stores a pointer to an array + * of #PangoEngineInfo structures and the length of that array in + * the given location. + * + * Note that script_engine_init() will not be called before this + * function. + **/ +void script_engine_list (PangoEngineInfo **engines, + int *n_engines); + +/** + * script_engine_init: + * @module: a #GTypeModule structure used to associate any + * GObject types created in this module with the module. + * + * Function to be provided by a module to register any + * GObject types in the module. + **/ +void script_engine_init (GTypeModule *module); + + +/** + * script_engine_exit: + * + * Function to be provided by the module that is called + * when the module is unloading. Frequently does nothing. + **/ +void script_engine_exit (void); + +/** + * script_engine_create: + * @id: the ID of an engine as reported by script_engine_list. + * + * Function to be provided by the module to create an instance + * of one of the engines implemented by the module. + * + * Return value: a newly created #PangoEngine of the specified + * type, or %NULL if an error occurred. (In normal operation, + * a module should not return %NULL. A %NULL return is only + * acceptable in the case where system misconfiguration or + * bugs in the driver routine are encountered.) + **/ +PangoEngine *script_engine_create (const char *id); + +/* Utility macro used by PANGO_ENGINE_LANG_DEFINE_TYPE and + * PANGO_ENGINE_LANG_DEFINE_TYPE + */ +#define PANGO_ENGINE_DEFINE_TYPE(name, prefix, class_init, instance_init, parent_type) \ +static GType prefix ## _type; \ +static void \ +prefix ## _register_type (GTypeModule *module) \ +{ \ + static const GTypeInfo object_info = \ + { \ + sizeof (name ## Class), \ + (GBaseInitFunc) NULL, \ + (GBaseFinalizeFunc) NULL, \ + (GClassInitFunc) class_init, \ + (GClassFinalizeFunc) NULL, \ + NULL, /* class_data */ \ + sizeof (name), \ + 0, /* n_prelocs */ \ + (GInstanceInitFunc) instance_init, \ + }; \ + \ + prefix ## _type = g_type_module_register_type (module, parent_type, \ + # name, \ + &object_info, 0); \ +} -void script_engine_list (PangoEngineInfo **engines, - int *n_engines); -PangoEngine *script_engine_load (const char *id); -void script_engine_unload (PangoEngine *engine); +/** + * PANGO_ENGINE_LANG_DEFINE_TYPE: + * @name: Name of the the type to register (for example:, <literal>ArabicEngineFc</literal> + * @prefix: Prefix for symbols that will be defined (for example:, <literal>arabic_engine_fc</literal> + * @class_init: Class initialization function for the new type, or %NULL + * @instance_init: Instance initialization function for the new type, or %NULL + * + * Outputs the necessary code for GObject type registration for a + * #PangoEngineLang class defined in a module. Two static symbols + * are defined. + * + * <programlisting> + * static GType <replaceable>prefix</replaceable>_type; + * static void <replaceable>prefix</replaceable>_register_type (GTypeModule module); + * </programlisting> + * + * The <function><replaceable>prefix</replaceable>_register_type()</function> + * function should be called in your script_engine_init() function for + * each type that your module implements, and then your script_engine_create() + * function can create instances of the object as follows: + * + * <informalexample><programlisting> + * PangoEngine *engine = g_object_new (<replaceable>prefix</replaceable>_type, NULL); + * </programlisting></informalexample> + **/ +#define PANGO_ENGINE_LANG_DEFINE_TYPE(name, prefix, class_init, instance_init) \ + PANGO_ENGINE_DEFINE_TYPE (name, prefix, \ + class_init, instance_init, \ + PANGO_TYPE_ENGINE_LANG) + +/** + * PANGO_ENGINE_SHAPE_DEFINE_TYPE: + * @name: Name of the the type to register (for example:, <literal>ArabicEngineFc</literal> + * @prefix: Prefix for symbols that will be defined (for example:, <literal>arabic_engine_fc</literal> + * @class_init: Class initialization function for the new type, or %NULL + * @instance_init: Instance initialization function for the new type, or %NULL + * + * Outputs the necessary code for GObject type registration for a + * #PangoEngineShape class defined in a module. Two static symbols + * are defined. + * + * <programlisting> + * static GType <replaceable>prefix</replaceable>_type; + * static void <replaceable>prefix</replaceable>_register_type (GTypeModule module); + * </programlisting> + * + * The <function><replaceable>prefix</replaceable>_register_type()</function> + * function should be called in your script_engine_init() function for + * each type that your module implements, and then your script_engine_create() + * function can create instances of the object as follows: + * + * <informalexample><programlisting> + * PangoEngine *engine = g_object_new (<replaceable>prefix</replaceable>_type, NULL); + * </programlisting></informalexample> + **/ +#define PANGO_ENGINE_SHAPE_DEFINE_TYPE(name, prefix, class_init, instance_init) \ + PANGO_ENGINE_DEFINE_TYPE (name, prefix, \ + class_init, instance_init, \ + PANGO_TYPE_ENGINE_SHAPE) /* Macro used for possibly builtin Pango modules. Not useful * for externally build modules. If we are compiling a module standaline, diff --git a/pango/pango-impl-utils.h b/pango/pango-impl-utils.h new file mode 100644 index 00000000..fc2e7cf7 --- /dev/null +++ b/pango/pango-impl-utils.h @@ -0,0 +1,77 @@ +/* Pango + * pango-impl-utils.h: Macros for get_type() functions + * Inspired by Jody Goldberg's gsf-impl-utils.h + * + * Copyright (C) 2003 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. + */ + +#ifndef __PANGO_IMPL_UTILS_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define PANGO_DEFINE_TYPE_FULL(name, prefix, \ + class_init, instance_init, \ + parent_type, abstract) \ +GType \ +prefix ## _get_type (void) \ +{ \ + static GType object_type = 0; \ + \ + if (!object_type) \ + { \ + static const GTypeInfo object_info = \ + { \ + sizeof (name ## Class), \ + (GBaseInitFunc) NULL, \ + (GBaseFinalizeFunc) NULL, \ + (GClassInitFunc) class_init, \ + (GClassFinalizeFunc) NULL, \ + NULL, /* class_data */ \ + sizeof (name), \ + 0, /* n_prelocs */ \ + (GInstanceInitFunc) instance_init \ + }; \ + \ + object_type = g_type_register_static (parent_type, \ + # name, \ + &object_info, abstract); \ + } \ + \ + return object_type; \ +} + +#define PANGO_DEFINE_TYPE(name, prefix, \ + class_init, instance_init, \ + parent_type) \ + PANGO_DEFINE_TYPE_FULL (name, prefix, \ + class_init, instance_init, \ + parent_type, 0) + +#define PANGO_DEFINE_TYPE_ABSTRACT(name, prefix, \ + class_init, instance_init, \ + parent_type) \ + PANGO_DEFINE_TYPE_FULL (name, prefix, \ + class_init, instance_init, \ + parent_type, G_TYPE_FLAG_ABSTRACT) + +G_END_DECLS + +#endif /* __PANGO_IMPL_UTILS_H__ */ + diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 63e96c49..e620967c 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -2811,10 +2811,7 @@ get_items_log_attrs (const char *text, PangoItem *next_item = items->next->data; /* FIXME: Handle language tags */ - if (next_item->analysis.lang_engine != tmp_item.analysis.lang_engine && - (!next_item->analysis.lang_engine || !tmp_item.analysis.lang_engine || - strcmp (next_item->analysis.lang_engine->engine.id, - tmp_item.analysis.lang_engine->engine.id) != 0)) + if (next_item->analysis.lang_engine != tmp_item.analysis.lang_engine) break; else { diff --git a/pango/pango-modules.h b/pango/pango-modules.h index c0c65301..c0bb5c9a 100644 --- a/pango/pango-modules.h +++ b/pango/pango-modules.h @@ -41,9 +41,11 @@ typedef struct _PangoIncludedModule PangoIncludedModule; struct _PangoIncludedModule { - void (*list) (PangoEngineInfo **engines, int *n_engines); - PangoEngine *(*load) (const char *id); - void (*unload) (PangoEngine *engine); + void (*list) (PangoEngineInfo **engines, + int *n_engines); + void (*init) (GTypeModule *module); + void (*exit) (void); + PangoEngine *(*create) (const char *id); }; PangoMap * pango_find_map (PangoLanguage *language, diff --git a/pango/pango-script-table.h b/pango/pango-script-table.h new file mode 100644 index 00000000..ae9753bc --- /dev/null +++ b/pango/pango-script-table.h @@ -0,0 +1,404 @@ +/* pango-script-table.h: Generated by gen-script-table.pl + * + * Date: Sun Aug 3 03:11:30 2003 + * Source: Scripts-4.0.0.txt + * + * Do not edit. + */ +static const struct { + gunichar start; + guint16 chars; + guint16 script; /* PangoScript */ +} pango_script_table[] = { + { 0x0041, 26, PANGO_SCRIPT_LATIN }, + { 0x0061, 26, PANGO_SCRIPT_LATIN }, + { 0x00aa, 1, PANGO_SCRIPT_LATIN }, + { 0x00b5, 1, PANGO_SCRIPT_GREEK }, + { 0x00ba, 1, PANGO_SCRIPT_LATIN }, + { 0x00c0, 23, PANGO_SCRIPT_LATIN }, + { 0x00d8, 31, PANGO_SCRIPT_LATIN }, + { 0x00f8, 319, PANGO_SCRIPT_LATIN }, + { 0x0250, 105, PANGO_SCRIPT_LATIN }, + { 0x02e0, 5, PANGO_SCRIPT_LATIN }, + { 0x0300, 80, PANGO_SCRIPT_INHERITED }, + { 0x0360, 16, PANGO_SCRIPT_INHERITED }, + { 0x037a, 1, PANGO_SCRIPT_GREEK }, + { 0x0386, 1, PANGO_SCRIPT_GREEK }, + { 0x0388, 3, PANGO_SCRIPT_GREEK }, + { 0x038c, 1, PANGO_SCRIPT_GREEK }, + { 0x038e, 20, PANGO_SCRIPT_GREEK }, + { 0x03a3, 44, PANGO_SCRIPT_GREEK }, + { 0x03d0, 38, PANGO_SCRIPT_GREEK }, + { 0x03f7, 5, PANGO_SCRIPT_GREEK }, + { 0x0400, 130, PANGO_SCRIPT_CYRILLIC }, + { 0x0483, 4, PANGO_SCRIPT_CYRILLIC }, + { 0x0488, 2, PANGO_SCRIPT_INHERITED }, + { 0x048a, 69, PANGO_SCRIPT_CYRILLIC }, + { 0x04d0, 38, PANGO_SCRIPT_CYRILLIC }, + { 0x04f8, 2, PANGO_SCRIPT_CYRILLIC }, + { 0x0500, 16, PANGO_SCRIPT_CYRILLIC }, + { 0x0531, 38, PANGO_SCRIPT_ARMENIAN }, + { 0x0559, 1, PANGO_SCRIPT_ARMENIAN }, + { 0x0561, 39, PANGO_SCRIPT_ARMENIAN }, + { 0x0591, 17, PANGO_SCRIPT_INHERITED }, + { 0x05a3, 23, PANGO_SCRIPT_INHERITED }, + { 0x05bb, 3, PANGO_SCRIPT_INHERITED }, + { 0x05bf, 1, PANGO_SCRIPT_INHERITED }, + { 0x05c1, 2, PANGO_SCRIPT_INHERITED }, + { 0x05c4, 1, PANGO_SCRIPT_INHERITED }, + { 0x05d0, 27, PANGO_SCRIPT_HEBREW }, + { 0x05f0, 3, PANGO_SCRIPT_HEBREW }, + { 0x0621, 26, PANGO_SCRIPT_ARABIC }, + { 0x0641, 10, PANGO_SCRIPT_ARABIC }, + { 0x064b, 11, PANGO_SCRIPT_INHERITED }, + { 0x066e, 2, PANGO_SCRIPT_ARABIC }, + { 0x0670, 1, PANGO_SCRIPT_INHERITED }, + { 0x0671, 99, PANGO_SCRIPT_ARABIC }, + { 0x06d5, 1, PANGO_SCRIPT_ARABIC }, + { 0x06d6, 15, PANGO_SCRIPT_INHERITED }, + { 0x06e5, 2, PANGO_SCRIPT_ARABIC }, + { 0x06e7, 2, PANGO_SCRIPT_INHERITED }, + { 0x06ea, 4, PANGO_SCRIPT_INHERITED }, + { 0x06ee, 2, PANGO_SCRIPT_ARABIC }, + { 0x06fa, 3, PANGO_SCRIPT_ARABIC }, + { 0x06ff, 1, PANGO_SCRIPT_ARABIC }, + { 0x0710, 59, PANGO_SCRIPT_SYRIAC }, + { 0x074d, 3, PANGO_SCRIPT_SYRIAC }, + { 0x0780, 50, PANGO_SCRIPT_THAANA }, + { 0x0901, 57, PANGO_SCRIPT_DEVANAGARI }, + { 0x093c, 18, PANGO_SCRIPT_DEVANAGARI }, + { 0x0950, 5, PANGO_SCRIPT_DEVANAGARI }, + { 0x0958, 12, PANGO_SCRIPT_DEVANAGARI }, + { 0x0966, 10, PANGO_SCRIPT_DEVANAGARI }, + { 0x0981, 3, PANGO_SCRIPT_BENGALI }, + { 0x0985, 8, PANGO_SCRIPT_BENGALI }, + { 0x098f, 2, PANGO_SCRIPT_BENGALI }, + { 0x0993, 22, PANGO_SCRIPT_BENGALI }, + { 0x09aa, 7, PANGO_SCRIPT_BENGALI }, + { 0x09b2, 1, PANGO_SCRIPT_BENGALI }, + { 0x09b6, 4, PANGO_SCRIPT_BENGALI }, + { 0x09bc, 9, PANGO_SCRIPT_BENGALI }, + { 0x09c7, 2, PANGO_SCRIPT_BENGALI }, + { 0x09cb, 3, PANGO_SCRIPT_BENGALI }, + { 0x09d7, 1, PANGO_SCRIPT_BENGALI }, + { 0x09dc, 2, PANGO_SCRIPT_BENGALI }, + { 0x09df, 5, PANGO_SCRIPT_BENGALI }, + { 0x09e6, 12, PANGO_SCRIPT_BENGALI }, + { 0x0a02, 2, PANGO_SCRIPT_GURMUKHI }, + { 0x0a05, 6, PANGO_SCRIPT_GURMUKHI }, + { 0x0a0f, 2, PANGO_SCRIPT_GURMUKHI }, + { 0x0a13, 22, PANGO_SCRIPT_GURMUKHI }, + { 0x0a2a, 7, PANGO_SCRIPT_GURMUKHI }, + { 0x0a32, 2, PANGO_SCRIPT_GURMUKHI }, + { 0x0a35, 2, PANGO_SCRIPT_GURMUKHI }, + { 0x0a38, 2, PANGO_SCRIPT_GURMUKHI }, + { 0x0a3c, 1, PANGO_SCRIPT_GURMUKHI }, + { 0x0a3e, 5, PANGO_SCRIPT_GURMUKHI }, + { 0x0a47, 2, PANGO_SCRIPT_GURMUKHI }, + { 0x0a4b, 3, PANGO_SCRIPT_GURMUKHI }, + { 0x0a59, 4, PANGO_SCRIPT_GURMUKHI }, + { 0x0a5e, 1, PANGO_SCRIPT_GURMUKHI }, + { 0x0a66, 15, PANGO_SCRIPT_GURMUKHI }, + { 0x0a81, 3, PANGO_SCRIPT_GUJARATI }, + { 0x0a85, 9, PANGO_SCRIPT_GUJARATI }, + { 0x0a8f, 3, PANGO_SCRIPT_GUJARATI }, + { 0x0a93, 22, PANGO_SCRIPT_GUJARATI }, + { 0x0aaa, 7, PANGO_SCRIPT_GUJARATI }, + { 0x0ab2, 2, PANGO_SCRIPT_GUJARATI }, + { 0x0ab5, 5, PANGO_SCRIPT_GUJARATI }, + { 0x0abc, 10, PANGO_SCRIPT_GUJARATI }, + { 0x0ac7, 3, PANGO_SCRIPT_GUJARATI }, + { 0x0acb, 3, PANGO_SCRIPT_GUJARATI }, + { 0x0ad0, 1, PANGO_SCRIPT_GUJARATI }, + { 0x0ae0, 4, PANGO_SCRIPT_GUJARATI }, + { 0x0ae6, 10, PANGO_SCRIPT_GUJARATI }, + { 0x0b01, 3, PANGO_SCRIPT_ORIYA }, + { 0x0b05, 8, PANGO_SCRIPT_ORIYA }, + { 0x0b0f, 2, PANGO_SCRIPT_ORIYA }, + { 0x0b13, 22, PANGO_SCRIPT_ORIYA }, + { 0x0b2a, 7, PANGO_SCRIPT_ORIYA }, + { 0x0b32, 2, PANGO_SCRIPT_ORIYA }, + { 0x0b35, 5, PANGO_SCRIPT_ORIYA }, + { 0x0b3c, 8, PANGO_SCRIPT_ORIYA }, + { 0x0b47, 2, PANGO_SCRIPT_ORIYA }, + { 0x0b4b, 3, PANGO_SCRIPT_ORIYA }, + { 0x0b56, 2, PANGO_SCRIPT_ORIYA }, + { 0x0b5c, 2, PANGO_SCRIPT_ORIYA }, + { 0x0b5f, 3, PANGO_SCRIPT_ORIYA }, + { 0x0b66, 10, PANGO_SCRIPT_ORIYA }, + { 0x0b71, 1, PANGO_SCRIPT_ORIYA }, + { 0x0b82, 2, PANGO_SCRIPT_TAMIL }, + { 0x0b85, 6, PANGO_SCRIPT_TAMIL }, + { 0x0b8e, 3, PANGO_SCRIPT_TAMIL }, + { 0x0b92, 4, PANGO_SCRIPT_TAMIL }, + { 0x0b99, 2, PANGO_SCRIPT_TAMIL }, + { 0x0b9c, 1, PANGO_SCRIPT_TAMIL }, + { 0x0b9e, 2, PANGO_SCRIPT_TAMIL }, + { 0x0ba3, 2, PANGO_SCRIPT_TAMIL }, + { 0x0ba8, 3, PANGO_SCRIPT_TAMIL }, + { 0x0bae, 8, PANGO_SCRIPT_TAMIL }, + { 0x0bb7, 3, PANGO_SCRIPT_TAMIL }, + { 0x0bbe, 5, PANGO_SCRIPT_TAMIL }, + { 0x0bc6, 3, PANGO_SCRIPT_TAMIL }, + { 0x0bca, 4, PANGO_SCRIPT_TAMIL }, + { 0x0bd7, 1, PANGO_SCRIPT_TAMIL }, + { 0x0be7, 12, PANGO_SCRIPT_TAMIL }, + { 0x0c01, 3, PANGO_SCRIPT_TELUGU }, + { 0x0c05, 8, PANGO_SCRIPT_TELUGU }, + { 0x0c0e, 3, PANGO_SCRIPT_TELUGU }, + { 0x0c12, 23, PANGO_SCRIPT_TELUGU }, + { 0x0c2a, 10, PANGO_SCRIPT_TELUGU }, + { 0x0c35, 5, PANGO_SCRIPT_TELUGU }, + { 0x0c3e, 7, PANGO_SCRIPT_TELUGU }, + { 0x0c46, 3, PANGO_SCRIPT_TELUGU }, + { 0x0c4a, 4, PANGO_SCRIPT_TELUGU }, + { 0x0c55, 2, PANGO_SCRIPT_TELUGU }, + { 0x0c60, 2, PANGO_SCRIPT_TELUGU }, + { 0x0c66, 10, PANGO_SCRIPT_TELUGU }, + { 0x0c82, 2, PANGO_SCRIPT_KANNADA }, + { 0x0c85, 8, PANGO_SCRIPT_KANNADA }, + { 0x0c8e, 3, PANGO_SCRIPT_KANNADA }, + { 0x0c92, 23, PANGO_SCRIPT_KANNADA }, + { 0x0caa, 10, PANGO_SCRIPT_KANNADA }, + { 0x0cb5, 5, PANGO_SCRIPT_KANNADA }, + { 0x0cbd, 8, PANGO_SCRIPT_KANNADA }, + { 0x0cc6, 3, PANGO_SCRIPT_KANNADA }, + { 0x0cca, 4, PANGO_SCRIPT_KANNADA }, + { 0x0cd5, 2, PANGO_SCRIPT_KANNADA }, + { 0x0cde, 1, PANGO_SCRIPT_KANNADA }, + { 0x0ce0, 2, PANGO_SCRIPT_KANNADA }, + { 0x0ce6, 10, PANGO_SCRIPT_KANNADA }, + { 0x0d02, 2, PANGO_SCRIPT_MALAYALAM }, + { 0x0d05, 8, PANGO_SCRIPT_MALAYALAM }, + { 0x0d0e, 3, PANGO_SCRIPT_MALAYALAM }, + { 0x0d12, 23, PANGO_SCRIPT_MALAYALAM }, + { 0x0d2a, 16, PANGO_SCRIPT_MALAYALAM }, + { 0x0d3e, 6, PANGO_SCRIPT_MALAYALAM }, + { 0x0d46, 3, PANGO_SCRIPT_MALAYALAM }, + { 0x0d4a, 4, PANGO_SCRIPT_MALAYALAM }, + { 0x0d57, 1, PANGO_SCRIPT_MALAYALAM }, + { 0x0d60, 2, PANGO_SCRIPT_MALAYALAM }, + { 0x0d66, 10, PANGO_SCRIPT_MALAYALAM }, + { 0x0d82, 2, PANGO_SCRIPT_SINHALA }, + { 0x0d85, 18, PANGO_SCRIPT_SINHALA }, + { 0x0d9a, 24, PANGO_SCRIPT_SINHALA }, + { 0x0db3, 9, PANGO_SCRIPT_SINHALA }, + { 0x0dbd, 1, PANGO_SCRIPT_SINHALA }, + { 0x0dc0, 7, PANGO_SCRIPT_SINHALA }, + { 0x0dca, 1, PANGO_SCRIPT_SINHALA }, + { 0x0dcf, 6, PANGO_SCRIPT_SINHALA }, + { 0x0dd6, 1, PANGO_SCRIPT_SINHALA }, + { 0x0dd8, 8, PANGO_SCRIPT_SINHALA }, + { 0x0df2, 2, PANGO_SCRIPT_SINHALA }, + { 0x0e01, 58, PANGO_SCRIPT_THAI }, + { 0x0e40, 15, PANGO_SCRIPT_THAI }, + { 0x0e50, 10, PANGO_SCRIPT_THAI }, + { 0x0e81, 2, PANGO_SCRIPT_LAO }, + { 0x0e84, 1, PANGO_SCRIPT_LAO }, + { 0x0e87, 2, PANGO_SCRIPT_LAO }, + { 0x0e8a, 1, PANGO_SCRIPT_LAO }, + { 0x0e8d, 1, PANGO_SCRIPT_LAO }, + { 0x0e94, 4, PANGO_SCRIPT_LAO }, + { 0x0e99, 7, PANGO_SCRIPT_LAO }, + { 0x0ea1, 3, PANGO_SCRIPT_LAO }, + { 0x0ea5, 1, PANGO_SCRIPT_LAO }, + { 0x0ea7, 1, PANGO_SCRIPT_LAO }, + { 0x0eaa, 2, PANGO_SCRIPT_LAO }, + { 0x0ead, 13, PANGO_SCRIPT_LAO }, + { 0x0ebb, 3, PANGO_SCRIPT_LAO }, + { 0x0ec0, 5, PANGO_SCRIPT_LAO }, + { 0x0ec6, 1, PANGO_SCRIPT_LAO }, + { 0x0ec8, 6, PANGO_SCRIPT_LAO }, + { 0x0ed0, 10, PANGO_SCRIPT_LAO }, + { 0x0edc, 2, PANGO_SCRIPT_LAO }, + { 0x0f00, 1, PANGO_SCRIPT_TIBETAN }, + { 0x0f18, 2, PANGO_SCRIPT_TIBETAN }, + { 0x0f20, 20, PANGO_SCRIPT_TIBETAN }, + { 0x0f35, 1, PANGO_SCRIPT_TIBETAN }, + { 0x0f37, 1, PANGO_SCRIPT_TIBETAN }, + { 0x0f39, 1, PANGO_SCRIPT_TIBETAN }, + { 0x0f40, 8, PANGO_SCRIPT_TIBETAN }, + { 0x0f49, 34, PANGO_SCRIPT_TIBETAN }, + { 0x0f71, 20, PANGO_SCRIPT_TIBETAN }, + { 0x0f86, 6, PANGO_SCRIPT_TIBETAN }, + { 0x0f90, 8, PANGO_SCRIPT_TIBETAN }, + { 0x0f99, 36, PANGO_SCRIPT_TIBETAN }, + { 0x0fc6, 1, PANGO_SCRIPT_TIBETAN }, + { 0x1000, 34, PANGO_SCRIPT_MYANMAR }, + { 0x1023, 5, PANGO_SCRIPT_MYANMAR }, + { 0x1029, 2, PANGO_SCRIPT_MYANMAR }, + { 0x102c, 7, PANGO_SCRIPT_MYANMAR }, + { 0x1036, 4, PANGO_SCRIPT_MYANMAR }, + { 0x1040, 10, PANGO_SCRIPT_MYANMAR }, + { 0x1050, 10, PANGO_SCRIPT_MYANMAR }, + { 0x10a0, 38, PANGO_SCRIPT_GEORGIAN }, + { 0x10d0, 41, PANGO_SCRIPT_GEORGIAN }, + { 0x1100, 90, PANGO_SCRIPT_HANGUL }, + { 0x115f, 68, PANGO_SCRIPT_HANGUL }, + { 0x11a8, 82, PANGO_SCRIPT_HANGUL }, + { 0x1200, 7, PANGO_SCRIPT_ETHIOPIC }, + { 0x1208, 63, PANGO_SCRIPT_ETHIOPIC }, + { 0x1248, 1, PANGO_SCRIPT_ETHIOPIC }, + { 0x124a, 4, PANGO_SCRIPT_ETHIOPIC }, + { 0x1250, 7, PANGO_SCRIPT_ETHIOPIC }, + { 0x1258, 1, PANGO_SCRIPT_ETHIOPIC }, + { 0x125a, 4, PANGO_SCRIPT_ETHIOPIC }, + { 0x1260, 39, PANGO_SCRIPT_ETHIOPIC }, + { 0x1288, 1, PANGO_SCRIPT_ETHIOPIC }, + { 0x128a, 4, PANGO_SCRIPT_ETHIOPIC }, + { 0x1290, 31, PANGO_SCRIPT_ETHIOPIC }, + { 0x12b0, 1, PANGO_SCRIPT_ETHIOPIC }, + { 0x12b2, 4, PANGO_SCRIPT_ETHIOPIC }, + { 0x12b8, 7, PANGO_SCRIPT_ETHIOPIC }, + { 0x12c0, 1, PANGO_SCRIPT_ETHIOPIC }, + { 0x12c2, 4, PANGO_SCRIPT_ETHIOPIC }, + { 0x12c8, 7, PANGO_SCRIPT_ETHIOPIC }, + { 0x12d0, 7, PANGO_SCRIPT_ETHIOPIC }, + { 0x12d8, 23, PANGO_SCRIPT_ETHIOPIC }, + { 0x12f0, 31, PANGO_SCRIPT_ETHIOPIC }, + { 0x1310, 1, PANGO_SCRIPT_ETHIOPIC }, + { 0x1312, 4, PANGO_SCRIPT_ETHIOPIC }, + { 0x1318, 7, PANGO_SCRIPT_ETHIOPIC }, + { 0x1320, 39, PANGO_SCRIPT_ETHIOPIC }, + { 0x1348, 19, PANGO_SCRIPT_ETHIOPIC }, + { 0x1369, 20, PANGO_SCRIPT_ETHIOPIC }, + { 0x13a0, 85, PANGO_SCRIPT_CHEROKEE }, + { 0x1401, 620, PANGO_SCRIPT_CANADIAN_ABORIGINAL }, + { 0x166f, 8, PANGO_SCRIPT_CANADIAN_ABORIGINAL }, + { 0x1681, 26, PANGO_SCRIPT_OGHAM }, + { 0x16a0, 75, PANGO_SCRIPT_RUNIC }, + { 0x16ee, 3, PANGO_SCRIPT_RUNIC }, + { 0x1700, 13, PANGO_SCRIPT_TAGALOG }, + { 0x170e, 7, PANGO_SCRIPT_TAGALOG }, + { 0x1720, 21, PANGO_SCRIPT_HANUNOO }, + { 0x1740, 20, PANGO_SCRIPT_BUHID }, + { 0x1760, 13, PANGO_SCRIPT_TAGBANWA }, + { 0x176e, 3, PANGO_SCRIPT_TAGBANWA }, + { 0x1772, 2, PANGO_SCRIPT_TAGBANWA }, + { 0x1780, 84, PANGO_SCRIPT_KHMER }, + { 0x17e0, 10, PANGO_SCRIPT_KHMER }, + { 0x180b, 3, PANGO_SCRIPT_INHERITED }, + { 0x1810, 10, PANGO_SCRIPT_MONGOLIAN }, + { 0x1820, 88, PANGO_SCRIPT_MONGOLIAN }, + { 0x1880, 42, PANGO_SCRIPT_MONGOLIAN }, + { 0x1900, 29, PANGO_SCRIPT_LIMBU }, + { 0x1920, 12, PANGO_SCRIPT_LIMBU }, + { 0x1930, 12, PANGO_SCRIPT_LIMBU }, + { 0x1946, 10, PANGO_SCRIPT_LIMBU }, + { 0x1950, 30, PANGO_SCRIPT_TAI_LE }, + { 0x1970, 5, PANGO_SCRIPT_TAI_LE }, + { 0x1d00, 38, PANGO_SCRIPT_LATIN }, + { 0x1d26, 5, PANGO_SCRIPT_GREEK }, + { 0x1d2b, 1, PANGO_SCRIPT_CYRILLIC }, + { 0x1d2c, 49, PANGO_SCRIPT_LATIN }, + { 0x1d5d, 5, PANGO_SCRIPT_GREEK }, + { 0x1d62, 4, PANGO_SCRIPT_LATIN }, + { 0x1d66, 5, PANGO_SCRIPT_GREEK }, + { 0x1d6b, 1, PANGO_SCRIPT_LATIN }, + { 0x1e00, 156, PANGO_SCRIPT_LATIN }, + { 0x1ea0, 90, PANGO_SCRIPT_LATIN }, + { 0x1f00, 22, PANGO_SCRIPT_GREEK }, + { 0x1f18, 6, PANGO_SCRIPT_GREEK }, + { 0x1f20, 38, PANGO_SCRIPT_GREEK }, + { 0x1f48, 6, PANGO_SCRIPT_GREEK }, + { 0x1f50, 8, PANGO_SCRIPT_GREEK }, + { 0x1f59, 1, PANGO_SCRIPT_GREEK }, + { 0x1f5b, 1, PANGO_SCRIPT_GREEK }, + { 0x1f5d, 1, PANGO_SCRIPT_GREEK }, + { 0x1f5f, 31, PANGO_SCRIPT_GREEK }, + { 0x1f80, 53, PANGO_SCRIPT_GREEK }, + { 0x1fb6, 7, PANGO_SCRIPT_GREEK }, + { 0x1fbe, 1, PANGO_SCRIPT_GREEK }, + { 0x1fc2, 3, PANGO_SCRIPT_GREEK }, + { 0x1fc6, 7, PANGO_SCRIPT_GREEK }, + { 0x1fd0, 4, PANGO_SCRIPT_GREEK }, + { 0x1fd6, 6, PANGO_SCRIPT_GREEK }, + { 0x1fe0, 13, PANGO_SCRIPT_GREEK }, + { 0x1ff2, 3, PANGO_SCRIPT_GREEK }, + { 0x1ff6, 7, PANGO_SCRIPT_GREEK }, + { 0x2071, 1, PANGO_SCRIPT_LATIN }, + { 0x207f, 1, PANGO_SCRIPT_LATIN }, + { 0x20d0, 27, PANGO_SCRIPT_INHERITED }, + { 0x2126, 1, PANGO_SCRIPT_GREEK }, + { 0x212a, 2, PANGO_SCRIPT_LATIN }, + { 0x2800, 256, PANGO_SCRIPT_BRAILLE }, + { 0x2e80, 26, PANGO_SCRIPT_HAN }, + { 0x2e9b, 89, PANGO_SCRIPT_HAN }, + { 0x2f00, 214, PANGO_SCRIPT_HAN }, + { 0x3005, 1, PANGO_SCRIPT_HAN }, + { 0x3007, 1, PANGO_SCRIPT_HAN }, + { 0x3021, 9, PANGO_SCRIPT_HAN }, + { 0x302a, 6, PANGO_SCRIPT_INHERITED }, + { 0x3038, 4, PANGO_SCRIPT_HAN }, + { 0x3041, 86, PANGO_SCRIPT_HIRAGANA }, + { 0x3099, 2, PANGO_SCRIPT_INHERITED }, + { 0x309d, 3, PANGO_SCRIPT_HIRAGANA }, + { 0x30a1, 90, PANGO_SCRIPT_KATAKANA }, + { 0x30fd, 3, PANGO_SCRIPT_KATAKANA }, + { 0x3105, 40, PANGO_SCRIPT_BOPOMOFO }, + { 0x3131, 94, PANGO_SCRIPT_HANGUL }, + { 0x31a0, 24, PANGO_SCRIPT_BOPOMOFO }, + { 0x31f0, 16, PANGO_SCRIPT_KATAKANA }, + { 0x3400, 6582, PANGO_SCRIPT_HAN }, + { 0x4e00, 20902, PANGO_SCRIPT_HAN }, + { 0xa000, 1165, PANGO_SCRIPT_YI }, + { 0xa490, 55, PANGO_SCRIPT_YI }, + { 0xac00, 11172, PANGO_SCRIPT_HANGUL }, + { 0xf900, 302, PANGO_SCRIPT_HAN }, + { 0xfa30, 59, PANGO_SCRIPT_HAN }, + { 0xfb00, 7, PANGO_SCRIPT_LATIN }, + { 0xfb13, 5, PANGO_SCRIPT_ARMENIAN }, + { 0xfb1d, 1, PANGO_SCRIPT_HEBREW }, + { 0xfb1e, 1, PANGO_SCRIPT_INHERITED }, + { 0xfb1f, 10, PANGO_SCRIPT_HEBREW }, + { 0xfb2a, 13, PANGO_SCRIPT_HEBREW }, + { 0xfb38, 5, PANGO_SCRIPT_HEBREW }, + { 0xfb3e, 1, PANGO_SCRIPT_HEBREW }, + { 0xfb40, 2, PANGO_SCRIPT_HEBREW }, + { 0xfb43, 2, PANGO_SCRIPT_HEBREW }, + { 0xfb46, 10, PANGO_SCRIPT_HEBREW }, + { 0xfb50, 98, PANGO_SCRIPT_ARABIC }, + { 0xfbd3, 363, PANGO_SCRIPT_ARABIC }, + { 0xfd50, 64, PANGO_SCRIPT_ARABIC }, + { 0xfd92, 54, PANGO_SCRIPT_ARABIC }, + { 0xfdf0, 12, PANGO_SCRIPT_ARABIC }, + { 0xfe00, 16, PANGO_SCRIPT_INHERITED }, + { 0xfe20, 4, PANGO_SCRIPT_INHERITED }, + { 0xfe70, 5, PANGO_SCRIPT_ARABIC }, + { 0xfe76, 135, PANGO_SCRIPT_ARABIC }, + { 0xff21, 26, PANGO_SCRIPT_LATIN }, + { 0xff41, 26, PANGO_SCRIPT_LATIN }, + { 0xff66, 10, PANGO_SCRIPT_KATAKANA }, + { 0xff71, 45, PANGO_SCRIPT_KATAKANA }, + { 0xffa0, 31, PANGO_SCRIPT_HANGUL }, + { 0xffc2, 6, PANGO_SCRIPT_HANGUL }, + { 0xffca, 6, PANGO_SCRIPT_HANGUL }, + { 0xffd2, 6, PANGO_SCRIPT_HANGUL }, + { 0xffda, 3, PANGO_SCRIPT_HANGUL }, + { 0x10000, 12, PANGO_SCRIPT_LINEAR_B }, + { 0x1000d, 26, PANGO_SCRIPT_LINEAR_B }, + { 0x10028, 19, PANGO_SCRIPT_LINEAR_B }, + { 0x1003c, 2, PANGO_SCRIPT_LINEAR_B }, + { 0x1003f, 15, PANGO_SCRIPT_LINEAR_B }, + { 0x10050, 14, PANGO_SCRIPT_LINEAR_B }, + { 0x10080, 123, PANGO_SCRIPT_LINEAR_B }, + { 0x10300, 31, PANGO_SCRIPT_OLD_ITALIC }, + { 0x10330, 27, PANGO_SCRIPT_GOTHIC }, + { 0x10380, 30, PANGO_SCRIPT_UGARITIC }, + { 0x10400, 80, PANGO_SCRIPT_DESERET }, + { 0x10450, 48, PANGO_SCRIPT_SHAVIAN }, + { 0x10480, 30, PANGO_SCRIPT_OSMANYA }, + { 0x104a0, 10, PANGO_SCRIPT_OSMANYA }, + { 0x10800, 6, PANGO_SCRIPT_CYPRIOT }, + { 0x10808, 1, PANGO_SCRIPT_CYPRIOT }, + { 0x1080a, 44, PANGO_SCRIPT_CYPRIOT }, + { 0x10837, 2, PANGO_SCRIPT_CYPRIOT }, + { 0x1083c, 1, PANGO_SCRIPT_CYPRIOT }, + { 0x1083f, 1, PANGO_SCRIPT_CYPRIOT }, + { 0x1d167, 3, PANGO_SCRIPT_INHERITED }, + { 0x1d17b, 8, PANGO_SCRIPT_INHERITED }, + { 0x1d185, 7, PANGO_SCRIPT_INHERITED }, + { 0x1d1aa, 4, PANGO_SCRIPT_INHERITED }, + { 0x20000, 42711, PANGO_SCRIPT_HAN }, + { 0x2f800, 542, PANGO_SCRIPT_HAN }, +}; diff --git a/pango/pango-script.c b/pango/pango-script.c new file mode 100644 index 00000000..39a95641 --- /dev/null +++ b/pango/pango-script.c @@ -0,0 +1,343 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* Pango + * pango-script.c: Script tag handling + * + * Copyright (C) 2002 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. + * + * Implementation of pango_script_iter is derived from ICU: + * + * icu/sources/common/usc_impl.c + * + ********************************************************************** + * Copyright (C) 1999-2002, International Business Machines + * Corporation and others. All Rights Reserved. + ********************************************************************** + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ +#include <string.h> + +#include "pango-script.h" +#include "pango-script-table.h" + +#define PAREN_STACK_DEPTH 128 + +typedef struct _ParenStackEntry ParenStackEntry; + +struct _ParenStackEntry +{ + int pair_index; + PangoScript script_code; +}; + +struct _PangoScriptIter +{ + const gchar *text_start; + const gchar *text_end; + + const gchar *script_start; + const gchar *script_end; + PangoScript script_code; + + ParenStackEntry paren_stack[PAREN_STACK_DEPTH]; + int paren_sp; +}; + +/** + * pango_script_for_unichar: + * @ch: a unicode characters + * + * Looks up the #PangoScript for a particular character (as defined by + * Unicode Technical report #24). No check is made for @ch being + * valid unicode character; if you pass in invalid character, the + * result is undefined. + * + * Return value: the #PangoScript for the character. + **/ +PangoScript +pango_script_for_unichar (gunichar ch) +{ + int lower = 0; + int upper = G_N_ELEMENTS (pango_script_table) - 1; + + while (lower <= upper) + { + int mid = (lower + upper) / 2; + if (ch < pango_script_table[mid].start) + upper = mid - 1; + else if (ch >= pango_script_table[mid].start + pango_script_table[mid].chars) + lower = mid + 1; + else + return pango_script_table[mid].script; + } + + return PANGO_SCRIPT_COMMON; +} + +/**********************************************************************/ + +/** + * pango_script_iter_new: + * @text: a UTF-8 string + * @length: length of @text, or -1 if @text is NUL-terminated. + * + * Create a new #PangoScriptIter, used to break a string of + * Unicode into runs by text. No copy is made of @text, so + * the caller needs to make sure it remains valid until + * the iterator is freed with pango_script_iter_free ().x + * + * Return value: the newly created script iterator, initialized + * to point at the first range in the text. If the string is + * empty, it will point at an empty range. + **/ +PangoScriptIter * +pango_script_iter_new (const char *text, + int length) +{ + PangoScriptIter *iter = g_new (PangoScriptIter, 1); + + iter->text_start = text; + if (length >= 0) + iter->text_end = text + length; + else + iter->text_end = text + strlen (text); + + iter->script_start = text; + iter->script_end = text; + iter->script_code = PANGO_SCRIPT_COMMON; + + iter->paren_sp = -1; + + pango_script_iter_next (iter); + + return iter; +} + +/** + * pango_script_iter_free: + * @iter: a #PangoScriptIter + * + * Frees a #PangoScriptIter created with pango_script_iter_new(). + **/ +void +pango_script_iter_free (PangoScriptIter *iter) +{ + g_free (iter); +} + +/** + * pango_script_iter_get_range: + * @iter: a #PangoScriptIter + * @start: location to store start position of the range, or %NULL + * @end: location to store end position of the range, or %NULL + * @script: location to store script for range, or %NULL + * + * Gets information about the range to which @iter currently points. + * The range is the is the set of locations p where *start <= p < *end. + * (That is, it doesn't include the character stored at *end) + **/ +void +pango_script_iter_get_range (PangoScriptIter *iter, + G_CONST_RETURN char **start, + G_CONST_RETURN char **end, + PangoScript *script) +{ + if (start) + *start = iter->script_start; + if (end) + *end = iter->script_end; + if (script) + *script = iter->script_code; +} + +static const gunichar paired_chars[] = { + 0x0028, 0x0029, /* ascii paired punctuation */ + 0x003c, 0x003e, + 0x005b, 0x005d, + 0x007b, 0x007d, + 0x00ab, 0x00bb, /* guillemets */ + 0x2018, 0x2019, /* general punctuation */ + 0x201c, 0x201d, + 0x2039, 0x203a, + 0x3008, 0x3009, /* chinese paired punctuation */ + 0x300a, 0x300b, + 0x300c, 0x300d, + 0x300e, 0x300f, + 0x3010, 0x3011, + 0x3014, 0x3015, + 0x3016, 0x3017, + 0x3018, 0x3019, + 0x301a, 0x301b +}; + +int +get_pair_index (gunichar ch) +{ + int lower = 0; + int upper = G_N_ELEMENTS (paired_chars) - 1; + + while (lower <= upper) + { + int mid = (lower + upper) / 2; + + if (ch < paired_chars[mid]) + upper = mid - 1; + else if (ch > paired_chars[mid]) + lower = mid + 1; + else + return mid; + } + + return -1; +} + +#define REAL_SCRIPT(script) \ + ((script) > PANGO_SCRIPT_INHERITED) + +#define SAME_SCRIPT(script1, script2) \ + (!REAL_SCRIPT (script1) || !REAL_SCRIPT (script2) || (script1) == (script2)) + +#define IS_OPEN(pair_index) (((pair_index) & 1) == 0) + +/** + * pango_script_iter_next: + * @iter: a #PangoScriptIter + * + * Advances a #PangoScriptIter to the next range. If the iter + * is already at the end, it is left unchanged and %FALSE + * is returned. + * + * Return value: %TRUE if the iter was succesfully advanced. + **/ +gboolean +pango_script_iter_next (PangoScriptIter *iter) +{ + int start_sp; + + if (iter->script_end == iter->text_end) + return FALSE; + + start_sp = iter->paren_sp; + iter->script_code = PANGO_SCRIPT_COMMON; + iter->script_start = iter->script_end; + + for (; iter->script_end < iter->text_end; iter->script_end = g_utf8_next_char (iter->script_end)) + { + gunichar ch = g_utf8_get_char (iter->script_end); + PangoScript sc; + int pair_index; + + sc = pango_script_for_unichar (ch); + pair_index = get_pair_index (ch); + + /* + * Paired character handling: + * + * if it's an open character, push it onto the stack. + * if it's a close character, find the matching open on the + * stack, and use that script code. Any non-matching open + * characters above it on the stack will be poped. + */ + if (pair_index >= 0) + { + if (IS_OPEN (pair_index)) + { + /* + * If the paren stack is full, empty it. This + * means that deeply nested paired punctuation + * characters will be ignored, but that's an unusual + * case, and it's better to ignore them than to + * write off the end of the stack... + */ + if (++iter->paren_sp >= PAREN_STACK_DEPTH) + iter->paren_sp = 0; + + iter->paren_stack[iter->paren_sp].pair_index = pair_index; + iter->paren_stack[iter->paren_sp].script_code = iter->script_code; + } + else if (iter->paren_sp >= 0) + { + int pi = pair_index & ~1; + + while (iter->paren_sp >= 0 && iter->paren_stack[iter->paren_sp].pair_index != pi) + iter->paren_sp--; + + if (iter->paren_sp < start_sp) + start_sp = iter->paren_sp; + + if (iter->paren_sp >= 0) + sc = iter->paren_stack[iter->paren_sp].script_code; + } + } + + if (SAME_SCRIPT (iter->script_code, sc)) + { + if (!REAL_SCRIPT (iter->script_code) && REAL_SCRIPT (sc)) + { + iter->script_code = sc; + + /* + * now that we have a final script code, fix any open + * characters we pushed before we knew the script code. + */ + while (start_sp < iter->paren_sp) + iter->paren_stack[++start_sp].script_code = iter->script_code; + } + + /* + * if this character is a close paired character, + * pop it from the stack + */ + if (pair_index >= 0 && !IS_OPEN (pair_index) != 0 && iter->paren_sp >= 0) + { + iter->paren_sp--; + start_sp--; + } + } + else + { + /* Different script, we're done */ + break; + } + } + + return TRUE; +} diff --git a/pango/pango-script.h b/pango/pango-script.h new file mode 100644 index 00000000..6c03c89b --- /dev/null +++ b/pango/pango-script.h @@ -0,0 +1,111 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* Pango + * pango-script.h: Script tag handling + * + * Copyright (C) 2002 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. + */ + +#ifndef __PANGO_SCRIPT_H__ +#define __PANGO_SCRIPT_H__ + +#include <glib.h> + +G_BEGIN_DECLS + +/** + * PangoScriptIter: + + * A #PangoScriptIter is used to iterate through a string + * and identify ranges in different scripts. + **/ +typedef struct _PangoScriptIter PangoScriptIter; + +typedef enum { /* ISO 15924 code */ + PANGO_SCRIPT_INVALID_CODE = -1, + PANGO_SCRIPT_COMMON = 0, /* Zyyy */ + PANGO_SCRIPT_INHERITED, /* Qaai */ + PANGO_SCRIPT_ARABIC, /* Arab */ + PANGO_SCRIPT_ARMENIAN, /* Armn */ + PANGO_SCRIPT_BENGALI, /* Beng */ + PANGO_SCRIPT_BOPOMOFO, /* Bopo */ + PANGO_SCRIPT_CHEROKEE, /* Cher */ + PANGO_SCRIPT_COPTIC, /* Qaac */ + PANGO_SCRIPT_CYRILLIC, /* Cyrl (Cyrs) */ + PANGO_SCRIPT_DESERET, /* Dsrt */ + PANGO_SCRIPT_DEVANAGARI, /* Deva */ + PANGO_SCRIPT_ETHIOPIC, /* Ethi */ + PANGO_SCRIPT_GEORGIAN, /* Geor (Geon, Geoa) */ + PANGO_SCRIPT_GOTHIC, /* Goth */ + PANGO_SCRIPT_GREEK, /* Grek */ + PANGO_SCRIPT_GUJARATI, /* Gujr */ + PANGO_SCRIPT_GURMUKHI, /* Guru */ + PANGO_SCRIPT_HAN, /* Hani */ + PANGO_SCRIPT_HANGUL, /* Hang */ + PANGO_SCRIPT_HEBREW, /* Hebr */ + PANGO_SCRIPT_HIRAGANA, /* Hira */ + PANGO_SCRIPT_KANNADA, /* Knda */ + PANGO_SCRIPT_KATAKANA, /* Kana */ + PANGO_SCRIPT_KHMER, /* Khmr */ + PANGO_SCRIPT_LAO, /* Laoo */ + PANGO_SCRIPT_LATIN, /* Latn (Latf, Latg) */ + PANGO_SCRIPT_MALAYALAM, /* Mlym */ + PANGO_SCRIPT_MONGOLIAN, /* Mong */ + PANGO_SCRIPT_MYANMAR, /* Mymr */ + PANGO_SCRIPT_OGHAM, /* Ogam */ + PANGO_SCRIPT_OLD_ITALIC, /* Ital */ + PANGO_SCRIPT_ORIYA, /* Orya */ + PANGO_SCRIPT_RUNIC, /* Runr */ + PANGO_SCRIPT_SINHALA, /* Sinh */ + PANGO_SCRIPT_SYRIAC, /* Syrc (Syrj, Syrn, Syre) */ + PANGO_SCRIPT_TAMIL, /* Taml */ + PANGO_SCRIPT_TELUGU, /* Telu */ + PANGO_SCRIPT_THAANA, /* Thaa */ + PANGO_SCRIPT_THAI, /* Thai */ + PANGO_SCRIPT_TIBETAN, /* Tibt */ + PANGO_SCRIPT_CANADIAN_ABORIGINAL, /* Cans */ + PANGO_SCRIPT_YI, /* Yiii */ + PANGO_SCRIPT_TAGALOG, /* Tglg */ + PANGO_SCRIPT_HANUNOO, /* Hano */ + PANGO_SCRIPT_BUHID, /* Buhd */ + PANGO_SCRIPT_TAGBANWA, /* Tagb */ + + /* Unicode-4.0 additions */ + PANGO_SCRIPT_BRAILLE, /* Brai */ + PANGO_SCRIPT_CYPRIOT, /* Cprt */ + PANGO_SCRIPT_LIMBU, /* Limb */ + PANGO_SCRIPT_OSMANYA, /* Osma */ + PANGO_SCRIPT_SHAVIAN, /* Shaw */ + PANGO_SCRIPT_LINEAR_B, /* Linb */ + PANGO_SCRIPT_TAI_LE, /* Tale */ + PANGO_SCRIPT_UGARITIC /* Ugar */ +} PangoScript; + +PangoScript pango_script_for_unichar (gunichar ch); + +PangoScriptIter *pango_script_iter_new (const char *text, + int length); +void pango_script_iter_get_range (PangoScriptIter *iter, + G_CONST_RETURN char **start, + G_CONST_RETURN char **end, + PangoScript *script); +gboolean pango_script_iter_next (PangoScriptIter *iter); +void pango_script_iter_free (PangoScriptIter *iter); + +G_END_DECLS + +#endif /* __PANGO_SCRIPT_H__ */ diff --git a/pango/pango.h b/pango/pango.h index ae440e03..592da837 100644 --- a/pango/pango.h +++ b/pango/pango.h @@ -33,6 +33,7 @@ #include <pango/pango-glyph.h> #include <pango/pango-item.h> #include <pango/pango-layout.h> +#include <pango/pango-script.h> #include <pango/pango-types.h> #endif /* __PANGO_H__ */ diff --git a/pango/pangox-fontmap.c b/pango/pangox-fontmap.c index 0d83fe79..af669c67 100644 --- a/pango/pangox-fontmap.c +++ b/pango/pangox-fontmap.c @@ -30,6 +30,7 @@ /* For XExtSetCloseDisplay */ #include <X11/Xlibint.h> +#include "pango-engine-private.h" #include "pango-fontmap.h" #include "pango-utils.h" @@ -1573,7 +1574,7 @@ pango_x_face_get_coverage (PangoXFace *xface, if (!coverage) { PangoEngineShape *engine = (PangoEngineShape *)pango_map_get_engine (shape_map, ch); - coverage = engine->get_coverage (font, language); + coverage = _pango_engine_shape_get_coverage (engine, font, language); g_hash_table_insert (coverage_hash, map_entry->info->id, coverage); } diff --git a/pango/querymodules.c b/pango/querymodules.c index 6b126409..2c6542dc 100644 --- a/pango/querymodules.c +++ b/pango/querymodules.c @@ -88,8 +88,9 @@ void query_module (const char *dir, const char *name) { void (*list) (PangoEngineInfo **engines, gint *n_engines); - PangoEngine *(*load) (const gchar *id); - void (*unload) (PangoEngine *engine); + void (*init) (GTypeModule *module); + void (*exit) (void); + PangoEngine *(*create) (const gchar *id); GModule *module; gchar *path; @@ -106,8 +107,9 @@ query_module (const char *dir, const char *name) if (module && g_module_symbol (module, "script_engine_list", (gpointer *) &list) && - g_module_symbol (module, "script_engine_load", (gpointer *) &load) && - g_module_symbol (module, "script_engine_unload", (gpointer *) &unload)) + g_module_symbol (module, "script_engine_init", (gpointer *) &init) && + g_module_symbol (module, "script_engine_exit", (gpointer *) &exit) && + g_module_symbol (module, "script_engine_create", (gpointer *) &create)) { gint i,j; PangoEngineInfo *engines; diff --git a/pango/shape.c b/pango/shape.c index 5cfdf13b..05188860 100644 --- a/pango/shape.c +++ b/pango/shape.c @@ -20,7 +20,7 @@ */ #include <pango/pango-glyph.h> -#include <pango/pango-engine.h> +#include <pango/pango-engine-private.h> /** * pango_shape: @@ -44,7 +44,8 @@ pango_shape (const gchar *text, int last_cluster = -1; if (analysis->shape_engine) - analysis->shape_engine->script_shape (analysis->font, text, length, analysis, glyphs); + _pango_engine_shape_shape (analysis->shape_engine, analysis->font, + text, length, analysis, glyphs); else { pango_glyph_string_set_size (glyphs, 1); |