summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2003-08-03 21:57:35 +0000
committerOwen Taylor <otaylor@src.gnome.org>2003-08-03 21:57:35 +0000
commit2584212cd0976f5f95d9381e829917e7d2a10d28 (patch)
tree5773e9f6802f8316c5c7463aa55677babe67343c /pango
parent95a8d1788e884b7d8d29d4171a1adc51c61e880e (diff)
downloadpango-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.am45
-rw-r--r--pango/break.c4
-rw-r--r--pango/modules.c243
-rw-r--r--pango/pango-context.c63
-rw-r--r--pango/pango-engine.c162
-rw-r--r--pango/pango-engine.h314
-rw-r--r--pango/pango-impl-utils.h77
-rw-r--r--pango/pango-layout.c5
-rw-r--r--pango/pango-modules.h8
-rw-r--r--pango/pango-script-table.h404
-rw-r--r--pango/pango-script.c343
-rw-r--r--pango/pango-script.h111
-rw-r--r--pango/pango.h1
-rw-r--r--pango/pangox-fontmap.c3
-rw-r--r--pango/querymodules.c10
-rw-r--r--pango/shape.c5
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);