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 | |
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
48 files changed, 2886 insertions, 540 deletions
@@ -1,3 +1,30 @@ +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 + 2003-08-03 Noah Levitt <nlevitt@columbia.edu> * pango/Makefile.am (libpangoxft_1_0_la_DEPENDENCIES): Really make diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10 index d9e4dd41..3460b941 100644 --- a/ChangeLog.pre-1-10 +++ b/ChangeLog.pre-1-10 @@ -1,3 +1,30 @@ +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 + 2003-08-03 Noah Levitt <nlevitt@columbia.edu> * pango/Makefile.am (libpangoxft_1_0_la_DEPENDENCIES): Really make diff --git a/ChangeLog.pre-1-4 b/ChangeLog.pre-1-4 index d9e4dd41..3460b941 100644 --- a/ChangeLog.pre-1-4 +++ b/ChangeLog.pre-1-4 @@ -1,3 +1,30 @@ +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 + 2003-08-03 Noah Levitt <nlevitt@columbia.edu> * pango/Makefile.am (libpangoxft_1_0_la_DEPENDENCIES): Really make diff --git a/ChangeLog.pre-1-6 b/ChangeLog.pre-1-6 index d9e4dd41..3460b941 100644 --- a/ChangeLog.pre-1-6 +++ b/ChangeLog.pre-1-6 @@ -1,3 +1,30 @@ +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 + 2003-08-03 Noah Levitt <nlevitt@columbia.edu> * pango/Makefile.am (libpangoxft_1_0_la_DEPENDENCIES): Really make diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8 index d9e4dd41..3460b941 100644 --- a/ChangeLog.pre-1-8 +++ b/ChangeLog.pre-1-8 @@ -1,3 +1,30 @@ +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 + 2003-08-03 Noah Levitt <nlevitt@columbia.edu> * pango/Makefile.am (libpangoxft_1_0_la_DEPENDENCIES): Really make diff --git a/configure.in b/configure.in index 9bab8977..db52dd08 100644 --- a/configure.in +++ b/configure.in @@ -504,8 +504,9 @@ for module in $included_modules; do module_c=`echo $module | sed s/-/_/` cat >> pango/module-defs.h <<EOTEXT extern void _pango_${module_c}_script_engine_list (PangoEngineInfo **engines, int *n_engines); -extern PangoEngine *_pango_${module_c}_script_engine_load (const char *id); -extern void _pango_${module_c}_script_engine_unload (PangoEngine *engine); +extern PangoEngine *_pango_${module_c}_script_engine_init (GTypeModule *module); +extern void _pango_${module_c}_script_engine_exit (void); +extern void _pango_${module_c}_script_engine_create (const char *id); EOTEXT done @@ -531,7 +532,7 @@ for module in $included_modules; do if echo $module | egrep -- "-x($|,)" > /dev/null; then module_c=`echo $module | sed s/-/_/` cat >> pango/module-defs-x.c <<EOTEXT - { _pango_${module_c}_script_engine_list, _pango_${module_c}_script_engine_load,_pango_${module_c}_script_engine_unload }, + { _pango_${module_c}_script_engine_list, _pango_${module_c}_script_engine_init, _pango_${module_c}_script_engine_exit, _pango_${module_c}_script_engine_create }, EOTEXT fi done @@ -560,7 +561,7 @@ for module in $included_modules; do if echo $module | egrep -- "-fc($|,)" > /dev/null; then module_c=`echo $module | sed s/-/_/` cat >> pango/module-defs-fc.c <<EOTEXT - { _pango_${module_c}_script_engine_list, _pango_${module_c}_script_engine_load,_pango_${module_c}_script_engine_unload }, + { _pango_${module_c}_script_engine_list, _pango_${module_c}_script_engine_init, _pango_${module_c}_script_engine_exit, _pango_${module_c}_script_engine_create }, EOTEXT fi done @@ -589,7 +590,7 @@ for module in $included_modules; do if echo $module | egrep -- "-win32($|,)" > /dev/null; then module_c=`echo $module | sed s/-/_/` cat >> pango/module-defs-win32.c <<EOTEXT - { _pango_${module_c}_script_engine_list, _pango_${module_c}_script_engine_load,_pango_${module_c}_script_engine_unload }, + { _pango_${module_c}_script_engine_list, _pango_${module_c}_script_engine_init, _pango_${module_c}_script_engine_exit, _pango_${module_c}_script_engine_create }, EOTEXT fi done @@ -629,7 +630,6 @@ docs/Makefile docs/version.xml tools/Makefile tests/Makefile -tests/runtests.sh pango.pc pangox.pc pangowin32.pc @@ -643,6 +643,9 @@ pangoxft-uninstalled.pc pango-zip.sh ]) +AC_CONFIG_FILES([tests/runtests.sh], + [chmod +x tests/runtests.sh]) + AC_OUTPUT backends="" diff --git a/docs/Makefile.am b/docs/Makefile.am index e7948401..63814d94 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -22,9 +22,12 @@ CFILE_GLOB=$(top_srcdir)/pango/*.c IGNORE_HFILES= \ mini-fribidi \ mini-xft \ + module-defs.h \ opentype \ modules.h \ - pango-intset.h \ + pango-engine-private.h \ + pango-impl-utils.h \ + pango-script-table.h \ pango-utils.h \ pangofc-private.h \ pangoft2-private.h \ @@ -36,6 +39,7 @@ IGNORE_HFILES= \ # if $(DOC_MODULE).types is non-empty. INCLUDES = \ -DPANGO_ENABLE_BACKEND \ + -DPANGO_ENABLE_ENGINE \ -I$(top_srcdir) \ $(GLIB_CFLAGS) \ $(XFT_CFLAGS) \ diff --git a/docs/pango-docs.sgml b/docs/pango-docs.sgml index 79cdf112..a923b96c 100644 --- a/docs/pango-docs.sgml +++ b/docs/pango-docs.sgml @@ -8,7 +8,10 @@ <!ENTITY pango-Text-Attributes SYSTEM "xml/text-attributes.xml"> <!ENTITY pango-Tab-Stops SYSTEM "xml/tab-stops.xml"> <!ENTITY pango-Layout-Objects SYSTEM "xml/layout.xml"> +<!ENTITY pango-Scripts SYSTEM "xml/scripts.xml"> <!ENTITY pango-Engines SYSTEM "xml/engines.xml"> +<!ENTITY PangoEngineLang SYSTEM "xml/pango-engine-lang.xml"> +<!ENTITY PangoEngineShape SYSTEM "xml/pango-engine-shape.xml"> <!ENTITY pango-Modules SYSTEM "xml/modules.xml"> <!ENTITY pango-X-Fonts-and-Rendering SYSTEM "xml/x-fonts.xml"> <!ENTITY pango-Win32-Fonts-and-Rendering SYSTEM "xml/win32-fonts.xml"> @@ -36,6 +39,7 @@ &pango-Tab-Stops; &markup-format; &pango-Layout-Objects; + &pango-Scripts; </chapter> <chapter id="rendering"> @@ -53,6 +57,8 @@ &pango-OpenType-Font-Handling; &pango-Coverage-Maps; &pango-Engines; + &PangoEngineLang; + &PangoEngineShape; &pango-Modules; </chapter> diff --git a/docs/pango-sections.txt b/docs/pango-sections.txt index 27c9bb9c..d1306e0b 100644 --- a/docs/pango-sections.txt +++ b/docs/pango-sections.txt @@ -450,21 +450,79 @@ pango_wrap_mode_get_type </SECTION> <SECTION> +<TITLE>Scripts</TITLE> +<FILE>scripts</FILE> +PangoScriptIter +PangoScript +PANGO_TYPE_SCRIPT +pango_script_for_unichar +pango_script_iter_new +pango_script_iter_get_range +pango_script_iter_next +pango_script_iter_free +<SUBSECTION Private> +pango_script_get_type +</SECTION> + +<SECTION> <TITLE>Engines</TITLE> <FILE>engines</FILE> PangoEngineInfo PangoEngineRange PangoEngine -PangoEngineLang -PangoEngineShape -PANGO_ENGINE_TYPE_LANG -PANGO_ENGINE_TYPE_SHAPE +PangoEngineClass PANGO_RENDER_TYPE_NONE script_engine_list -script_engine_load -script_engine_unload +script_engine_init +script_engine_exit +script_engine_create +<SUBSECTION Standard> +PANGO_ENGINE +PANGO_IS_ENGINE +PANGO_TYPE_ENGINE +PANGO_ENGINE_CLASS +PANGO_IS_ENGINE_CLASS +PANGO_ENGINE_GET_CLASS <SUBSECTION Private> +pango_engine_get_type PANGO_MODULE_ENTRY +PANGO_ENGINE_DEFINE_TYPE +</SECTION> + +<SECTION> +<TITLE>PangoEngineLang</TITLE> +<FILE>pango-engine-lang</FILE> +PangoEngineLang +PangoEngineLangClass +PANGO_ENGINE_TYPE_LANG +PANGO_ENGINE_LANG_DEFINE_TYPE +<SUBSECTION Standard> +PANGO_ENGINE_LANG +PANGO_IS_ENGINE_LANG +PANGO_TYPE_ENGINE_LANG +PANGO_ENGINE_LANG_CLASS +PANGO_IS_ENGINE_LANG_CLASS +PANGO_ENGINE_LANG_GET_CLASS +<SUBSECTION Private> +pango_engine_lang_get_type +</SECTION> + +<SECTION> +<TITLE>PangoEngineShape</TITLE> +<FILE>pango-engine-shape</FILE> +PangoEngineShape +PangoEngineShapeClass +PANGO_ENGINE_TYPE_SHAPE +PANGO_ENGINE_SHAPE_DEFINE_TYPE +<SUBSECTION Standard> +PANGO_ENGINE_SHAPE +PANGO_IS_ENGINE_SHAPE +PANGO_TYPE_ENGINE_SHAPE +PANGO_ENGINE_SHAPE_CLASS +PANGO_IS_ENGINE_SHAPE_CLASS +PANGO_ENGINE_SHAPE_GET_CLASS +<SUBSECTION Private> +pango_engine_shape_get_type </SECTION> <SECTION> diff --git a/docs/pango.types b/docs/pango.types index ae3d2947..4e54d55f 100644 --- a/docs/pango.types +++ b/docs/pango.types @@ -4,6 +4,9 @@ #include <pango/pangoft2.h> #include <pango/pangoxft.h> +pango_engine_get_type +pango_engine_lang_get_type +pango_engine_shape_get_type pango_font_get_type pango_font_family_get_type pango_font_face_get_type diff --git a/docs/tmpl/engines.sgml b/docs/tmpl/engines.sgml index 4b88affd..754540ce 100644 --- a/docs/tmpl/engines.sgml +++ b/docs/tmpl/engines.sgml @@ -17,8 +17,9 @@ strings. <para> Each dynamically-loaded module exports several functions which provide the public API. These functions are script_engine_list(), -script_engine_load() and script_engine_unload(). The latter two -functions are used for loading and unloading modules, while the first +script_engine_init() and script_engine_exit, and +script_engine_create(). The latter three functions are used when +creating engines from the module at run time, while the first function is used when building a catalog of all available modules. </para> @@ -63,61 +64,15 @@ points. It contains the following fields: <!-- ##### STRUCT PangoEngine ##### --> <para> -The #PangoEngine structure contains basic -information common to all script engines. It -contains the following fields: </para> -@id: a unique string ID for this language engine. -@type: the "type" of the engine. (Is this engine type or render type??). -@length: the length of the entire structure in bytes. This is - provided so that new functions can be added at the - end of subtypes of #PangoEngine without breaking - older modules. -<!-- ##### STRUCT PangoEngineLang ##### --> +<!-- ##### STRUCT PangoEngineClass ##### --> <para> -The #PangoEngineLang structure extends the -basic #PangoEngine structure to engines that -deal with the rendering-system independent part -of of the rendering pipeline. It contains the following fields: -</para> - -@engine: a nested structure containing basic engine data. -@script_break: a function that provides an implementation for pango_break(). - -<!-- ##### STRUCT PangoEngineShape ##### --> -<para> -The #PangoEngineShape structure extends the -basic #PangoEngine structure to engines that -deal with the rendering-system dependent part -of of the rendering pipeline. It contains the following fields: -</para> -@engine: a nested structure containing basic engine data. -@script_shape: a function that provides an implementation for pango_shape. -@get_coverage: - -<!-- ##### MACRO PANGO_ENGINE_TYPE_LANG ##### --> -<para> -A string constant defining the engine type -for <firstterm>language engines</firstterm>. -These engines have a engine structure of -type #PangoEngineLang. </para> - -<!-- ##### MACRO PANGO_ENGINE_TYPE_SHAPE ##### --> -<para> -A string constant defining the engine type -for <firstterm>shaping engines</firstterm>. -These engines have a engine structure of -type #PangoEngineShape. -</para> - - - <!-- ##### MACRO PANGO_RENDER_TYPE_NONE ##### --> <para> A string constant defining the render type @@ -129,37 +84,33 @@ specific. <!-- ##### FUNCTION script_engine_list ##### --> <para> -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. </para> @engines: location to store a pointer to an array of engines. @n_engines: location to store the number of elements in @engines. -<!-- ##### FUNCTION script_engine_load ##### --> +<!-- ##### FUNCTION script_engine_init ##### --> <para> -Function to be provided by a module to load a particular engine. + </para> -@id: the ID from the #PangoEngineInfo structure of the - module to load. -@Returns: the newly created script engine. +@module: -<!-- ##### FUNCTION script_engine_unload ##### --> +<!-- ##### FUNCTION script_engine_exit ##### --> <para> -Function to be provided by a module to unload an engine loaded -with script_engine_load(). + </para> -@engine: the engine to unload. -<!-- Local Variables: --> -<!-- sgml-parent-document: ("../pango-docs.sgml" "book" "refsect2") --> -<!-- End: --> +<!-- ##### FUNCTION script_engine_create ##### --> +<para> + +</para> + +@id: +@Returns: diff --git a/docs/tmpl/modules.sgml b/docs/tmpl/modules.sgml index 032248a3..32172efd 100644 --- a/docs/tmpl/modules.sgml +++ b/docs/tmpl/modules.sgml @@ -22,8 +22,9 @@ loaded module. </para> @list: -@load: -@unload: +@init: +@exit: +@create: <!-- ##### STRUCT PangoMap ##### --> <para> diff --git a/docs/tmpl/pango-engine-lang.sgml b/docs/tmpl/pango-engine-lang.sgml new file mode 100644 index 00000000..79b08f21 --- /dev/null +++ b/docs/tmpl/pango-engine-lang.sgml @@ -0,0 +1,56 @@ +<!-- ##### SECTION Title ##### --> +PangoEngineLang + +<!-- ##### SECTION Short_Description ##### --> +Rendering-system independent script engines + +<!-- ##### SECTION Long_Description ##### --> +<para> + +</para> + +<!-- ##### SECTION See_Also ##### --> +<para> + +</para> + +<!-- ##### STRUCT PangoEngineLang ##### --> +<para> +</para> + + +<!-- ##### STRUCT PangoEngineLangClass ##### --> +<para> + +</para> + +@script_break: + +<!-- ##### MACRO PANGO_ENGINE_TYPE_LANG ##### --> +<para> +A string constant defining the engine type +for <firstterm>language engines</firstterm>. +These engines derive from #PangoEngineLang. +</para> + + + +<!-- ##### MACRO PANGO_ENGINE_LANG_DEFINE_TYPE ##### --> +<para> + +</para> + +@name: +@prefix: +@\ + class_init: +@\ + class_init: +@\ + class_init: +@\ + class_init: +@class_init: +@instance_init: + + diff --git a/docs/tmpl/pango-engine-shape.sgml b/docs/tmpl/pango-engine-shape.sgml new file mode 100644 index 00000000..2e0f91ce --- /dev/null +++ b/docs/tmpl/pango-engine-shape.sgml @@ -0,0 +1,57 @@ +<!-- ##### SECTION Title ##### --> +PangoEngineShape + +<!-- ##### SECTION Short_Description ##### --> +Rendering-system dependent script engines + +<!-- ##### SECTION Long_Description ##### --> +<para> + +</para> + +<!-- ##### SECTION See_Also ##### --> +<para> + +</para> + +<!-- ##### STRUCT PangoEngineShape ##### --> +<para> +</para> + + +<!-- ##### STRUCT PangoEngineShapeClass ##### --> +<para> + +</para> + +@script_shape: +@get_coverage: + +<!-- ##### MACRO PANGO_ENGINE_TYPE_SHAPE ##### --> +<para> +A string constant defining the engine type +for <firstterm>shaping engines</firstterm>. +These engines derive from #PangoEngineShape. +</para> + + + +<!-- ##### MACRO PANGO_ENGINE_SHAPE_DEFINE_TYPE ##### --> +<para> + +</para> + +@name: +@prefix: +@\ + class_init: +@\ + class_init: +@\ + class_init: +@\ + class_init: +@class_init: +@instance_init: + + diff --git a/docs/tmpl/scripts.sgml b/docs/tmpl/scripts.sgml new file mode 100644 index 00000000..be1db3a3 --- /dev/null +++ b/docs/tmpl/scripts.sgml @@ -0,0 +1,146 @@ +<!-- ##### SECTION Title ##### --> +Scripts + +<!-- ##### SECTION Short_Description ##### --> +Identifying writing systems + +<!-- ##### SECTION Long_Description ##### --> +<para> +The functions in this section are used to identify the writing +system, or <firstterm>script</firstterm> of individual characters +and of ranges within a larger text string. +</para> + + +<!-- ##### SECTION See_Also ##### --> +<para> + +</para> + + +<!-- ##### STRUCT PangoScriptIter ##### --> +<para> + +</para> + + +<!-- ##### ENUM PangoScript ##### --> +<para> +The #PangoScript enumeration identifies different writing +systems. The values correspond to the names defined in the +Unicode standard. (See <ulink +url="http://www.unicode.org/reports/tr24/">Unicode Standard Annex +#24: Script names</ulink>). +</para> + +@PANGO_SCRIPT_INVALID_CODE: a value never used for any unicode character +@PANGO_SCRIPT_COMMON: a character used by multiple different scripts +@PANGO_SCRIPT_INHERITED: a mark glyph that takes its script from the + base glyph to which it is attached. +@PANGO_SCRIPT_ARABIC: +@PANGO_SCRIPT_ARMENIAN: +@PANGO_SCRIPT_BENGALI: +@PANGO_SCRIPT_BOPOMOFO: +@PANGO_SCRIPT_CHEROKEE: +@PANGO_SCRIPT_COPTIC: +@PANGO_SCRIPT_CYRILLIC: +@PANGO_SCRIPT_DESERET: +@PANGO_SCRIPT_DEVANAGARI: +@PANGO_SCRIPT_ETHIOPIC: +@PANGO_SCRIPT_GEORGIAN: +@PANGO_SCRIPT_GOTHIC: +@PANGO_SCRIPT_GREEK: +@PANGO_SCRIPT_GUJARATI: +@PANGO_SCRIPT_GURMUKHI: +@PANGO_SCRIPT_HAN: +@PANGO_SCRIPT_HANGUL: +@PANGO_SCRIPT_HEBREW: +@PANGO_SCRIPT_HIRAGANA: +@PANGO_SCRIPT_KANNADA: +@PANGO_SCRIPT_KATAKANA: +@PANGO_SCRIPT_KHMER: +@PANGO_SCRIPT_LAO: +@PANGO_SCRIPT_LATIN: +@PANGO_SCRIPT_MALAYALAM: +@PANGO_SCRIPT_MONGOLIAN: +@PANGO_SCRIPT_MYANMAR: +@PANGO_SCRIPT_OGHAM: +@PANGO_SCRIPT_OLD_ITALIC: +@PANGO_SCRIPT_ORIYA: +@PANGO_SCRIPT_RUNIC: +@PANGO_SCRIPT_SINHALA: +@PANGO_SCRIPT_SYRIAC: +@PANGO_SCRIPT_TAMIL: +@PANGO_SCRIPT_TELUGU: +@PANGO_SCRIPT_THAANA: +@PANGO_SCRIPT_THAI: +@PANGO_SCRIPT_TIBETAN: +@PANGO_SCRIPT_CANADIAN_ABORIGINAL: +@PANGO_SCRIPT_YI: +@PANGO_SCRIPT_TAGALOG: +@PANGO_SCRIPT_HANUNOO: +@PANGO_SCRIPT_BUHID: +@PANGO_SCRIPT_TAGBANWA: +@PANGO_SCRIPT_BRAILLE: +@PANGO_SCRIPT_CYPRIOT: +@PANGO_SCRIPT_LIMBU: +@PANGO_SCRIPT_OSMANYA: +@PANGO_SCRIPT_SHAVIAN: +@PANGO_SCRIPT_LINEAR_B: +@PANGO_SCRIPT_TAI_LE: +@PANGO_SCRIPT_UGARITIC: + +<!-- ##### MACRO PANGO_TYPE_SCRIPT ##### --> +<para> +The GObject type for #PangoScript +</para> + + + +<!-- ##### FUNCTION pango_script_for_unichar ##### --> +<para> + +</para> + +@ch: +@Returns: + + +<!-- ##### FUNCTION pango_script_iter_new ##### --> +<para> + +</para> + +@text: +@length: +@Returns: + + +<!-- ##### FUNCTION pango_script_iter_get_range ##### --> +<para> + +</para> + +@iter: +@start: +@end: +@script: + + +<!-- ##### FUNCTION pango_script_iter_next ##### --> +<para> + +</para> + +@iter: +@Returns: + + +<!-- ##### FUNCTION pango_script_iter_free ##### --> +<para> + +</para> + +@iter: + + diff --git a/modules/arabic/arabic-fc.c b/modules/arabic/arabic-fc.c index 80c9ae81..fd425d2e 100644 --- a/modules/arabic/arabic-fc.c +++ b/modules/arabic/arabic-fc.c @@ -26,8 +26,12 @@ #include "pango-engine.h" #include "pango-utils.h" - #include "pangofc-font.h" + +/* No extra fields needed */ +typedef PangoEngineShape ArabicEngineFc; +typedef PangoEngineShapeClass ArabicEngineFcClass ; + #define SCRIPT_ENGINE_NAME "ArabicScriptEngineFc" #define RENDER_TYPE PANGO_RENDER_TYPE_FC @@ -129,7 +133,8 @@ set_glyph (PangoFont *font, PangoGlyphString *glyphs, int i, int offset, PangoGl } static void -arabic_engine_shape (PangoFont *font, +arabic_engine_shape (PangoEngineShape *engine, + PangoFont *font, const char *text, gint length, PangoAnalysis *analysis, @@ -294,31 +299,26 @@ arabic_engine_shape (PangoFont *font, pango_fc_font_unlock_face (fc_font); } -static PangoCoverage * -arabic_engine_get_coverage (PangoFont *font, - PangoLanguage *lang) +static void +arabic_engine_fc_class_init (PangoEngineShapeClass *class) { - return pango_font_get_coverage (font, lang); + class->script_shape = arabic_engine_shape; } -static PangoEngine * -arabic_engine_fc_new () -{ - PangoEngineShape *result; - - result = g_new (PangoEngineShape, 1); +PANGO_ENGINE_SHAPE_DEFINE_TYPE (ArabicEngineFc, arabic_engine_fc, + arabic_engine_fc_class_init, NULL); - result->engine.id = SCRIPT_ENGINE_NAME; - result->engine.type = PANGO_ENGINE_TYPE_SHAPE; - result->engine.length = sizeof (result); - result->script_shape = arabic_engine_shape; - result->get_coverage = arabic_engine_get_coverage; +void +PANGO_MODULE_ENTRY(init) (GTypeModule *module) +{ + arabic_engine_fc_register_type (module); +} - return (PangoEngine *)result; +void +PANGO_MODULE_ENTRY(exit) (void) +{ } -/* List the engines contained within this module - */ void PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, int *n_engines) @@ -327,18 +327,11 @@ PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, *n_engines = G_N_ELEMENTS (script_engines); } -/* Load a particular engine given the ID for the engine - */ PangoEngine * -PANGO_MODULE_ENTRY(load) (const char *id) +PANGO_MODULE_ENTRY(create) (const char *id) { if (!strcmp (id, SCRIPT_ENGINE_NAME)) - return arabic_engine_fc_new (); + return g_object_new (arabic_engine_fc_type, NULL); else return NULL; } - -void -PANGO_MODULE_ENTRY(unload) (PangoEngine *engine) -{ -} diff --git a/modules/basic/basic-fc.c b/modules/basic/basic-fc.c index 7af2d3af..6de50e8c 100644 --- a/modules/basic/basic-fc.c +++ b/modules/basic/basic-fc.c @@ -25,10 +25,14 @@ #include <glib/gprintf.h> #include "pango-engine.h" #include "pango-utils.h" +#include "pangofc-font.h" #include "basic-common.h" -#include "pangofc-font.h" +/* No extra fields needed */ +typedef PangoEngineShape BasicEngineFc; +typedef PangoEngineShapeClass BasicEngineFcClass; + #define SCRIPT_ENGINE_NAME "BasicScriptEngineFc" #define RENDER_TYPE PANGO_RENDER_TYPE_FC @@ -115,7 +119,8 @@ set_glyph (PangoFont *font, } static void -basic_engine_shape (PangoFont *font, +basic_engine_shape (PangoEngineShape *engine, + PangoFont *font, const char *text, gint length, PangoAnalysis *analysis, @@ -222,31 +227,26 @@ basic_engine_shape (PangoFont *font, pango_fc_font_unlock_face (fc_font); } -static PangoCoverage * -basic_engine_get_coverage (PangoFont *font, - PangoLanguage *lang) +static void +basic_engine_fc_class_init (PangoEngineShapeClass *class) { - return pango_font_get_coverage (font, lang); + class->script_shape = basic_engine_shape; } -static PangoEngine * -basic_engine_fc_new () -{ - PangoEngineShape *result; - - result = g_new (PangoEngineShape, 1); +PANGO_ENGINE_SHAPE_DEFINE_TYPE (BasicEngineFc, basic_engine_fc, + basic_engine_fc_class_init, NULL); - result->engine.id = SCRIPT_ENGINE_NAME; - result->engine.type = PANGO_ENGINE_TYPE_SHAPE; - result->engine.length = sizeof (result); - result->script_shape = basic_engine_shape; - result->get_coverage = basic_engine_get_coverage; +void +PANGO_MODULE_ENTRY(init) (GTypeModule *module) +{ + basic_engine_fc_register_type (module); +} - return (PangoEngine *)result; +void +PANGO_MODULE_ENTRY(exit) (void) +{ } -/* List the engines contained within this module - */ void PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, int *n_engines) @@ -255,18 +255,11 @@ PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, *n_engines = G_N_ELEMENTS (script_engines); } -/* Load a particular engine given the ID for the engine - */ PangoEngine * -PANGO_MODULE_ENTRY(load) (const char *id) +PANGO_MODULE_ENTRY(create) (const char *id) { if (!strcmp (id, SCRIPT_ENGINE_NAME)) - return basic_engine_fc_new (); + return g_object_new (basic_engine_fc_type, NULL); else return NULL; } - -void -PANGO_MODULE_ENTRY(unload) (PangoEngine *engine) -{ -} diff --git a/modules/basic/basic-win32.c b/modules/basic/basic-win32.c index c63a016a..9e00139c 100644 --- a/modules/basic/basic-win32.c +++ b/modules/basic/basic-win32.c @@ -34,6 +34,10 @@ #include "basic-common.h" +/* No extra fields needed */ +typedef PangoEngineShape BasicEngineWin32; +typedef PangoEngineShapeClass BasicEngineWin32Class ; + #define SCRIPT_ENGINE_NAME "BasicScriptEngineWin32" static gboolean pango_win32_debug = FALSE; @@ -971,7 +975,8 @@ uniscribe_shape (PangoFont *font, #endif /* HAVE_USP10_H */ static void -basic_engine_shape (PangoFont *font, +basic_engine_shape (PangoEngineShape *engine, + PangoFont *font, const char *text, gint length, PangoAnalysis *analysis, @@ -1075,29 +1080,6 @@ basic_engine_shape (PangoFont *font, } } -static PangoCoverage * -basic_engine_get_coverage (PangoFont *font, - PangoLanguage *lang) -{ - return pango_font_get_coverage (font, lang); -} - -static PangoEngine * -basic_engine_win32_new (void) -{ - PangoEngineShape *result; - - result = g_new (PangoEngineShape, 1); - - result->engine.id = SCRIPT_ENGINE_NAME; - result->engine.type = PANGO_ENGINE_TYPE_SHAPE; - result->engine.length = sizeof (result); - result->script_shape = basic_engine_shape; - result->get_coverage = basic_engine_get_coverage; - - return (PangoEngine *)result; -} - static void init_uniscribe (void) { @@ -1133,13 +1115,34 @@ init_uniscribe (void) #endif } -/* The following three functions provide the public module API for - * Pango - */ +static void +basic_engine_win32_class_init (PangoEngineShapeClass *class) +{ + class->script_shape = basic_engine_shape; +} + +PANGO_ENGINE_SHAPE_DEFINE_TYPE (BasicEngineWin32, basic_engine_win32, + basic_engine_win32_class_init, NULL); + +void +PANGO_MODULE_ENTRY(init) (GTypeModule *module) +{ + init_uniscribe (); -void + if (pango_win32_get_debug_flag ()) + pango_win32_debug = TRUE; + + basic_engine_register_type (module); +} + +void +PANGO_MODULE_ENTRY(exit) (void) +{ +} + +void PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, - gint *n_engines) + int *n_engines) { init_uniscribe (); @@ -1176,20 +1179,10 @@ PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, } PangoEngine * -PANGO_MODULE_ENTRY(load) (const char *id) +PANGO_MODULE_ENTRY(create) (const char *id) { - init_uniscribe (); - - if (pango_win32_get_debug_flag ()) - pango_win32_debug = TRUE; - if (!strcmp (id, SCRIPT_ENGINE_NAME)) - return basic_engine_win32_new (); + return g_object_new (basic_engine_win32_type, NULL); else return NULL; } - -void -PANGO_MODULE_ENTRY(unload) (PangoEngine *engine) -{ -} diff --git a/modules/basic/basic-x.c b/modules/basic/basic-x.c index 2003da18..9b9431a2 100644 --- a/modules/basic/basic-x.c +++ b/modules/basic/basic-x.c @@ -29,6 +29,10 @@ #include "basic-common.h" +/* No extra fields needed */ +typedef PangoEngineShape BasicEngineX; +typedef PangoEngineShapeClass BasicEngineXClass ; + typedef struct _CharRange CharRange; typedef struct _Charset Charset; typedef struct _CharsetOrdering CharsetOrdering; @@ -141,8 +145,6 @@ static PangoEngineInfo script_engines[] = { } }; -static gint n_script_engines = G_N_ELEMENTS (script_engines); - /* * X window system script engine portion */ @@ -569,7 +571,8 @@ get_char_cache (PangoFont *font, } static void -basic_engine_shape (PangoFont *font, +basic_engine_shape (PangoEngineShape *engine, + PangoFont *font, const char *text, gint length, PangoAnalysis *analysis, @@ -682,8 +685,9 @@ basic_engine_shape (PangoFont *font, } static PangoCoverage * -basic_engine_get_coverage (PangoFont *font, - PangoLanguage *lang) +basic_engine_get_coverage (PangoEngineShape *engine, + PangoFont *font, + PangoLanguage *lang) { CharCache *cache = get_char_cache (font, lang); PangoCoverage *result = pango_coverage_new (); @@ -701,20 +705,25 @@ basic_engine_get_coverage (PangoFont *font, return result; } -static PangoEngine * -basic_engine_x_new () +static void +basic_engine_x_class_init (PangoEngineShapeClass *class) { - PangoEngineShape *result; - - result = g_new (PangoEngineShape, 1); + class->get_coverage = basic_engine_get_coverage; + class->script_shape = basic_engine_shape; +} + +PANGO_ENGINE_SHAPE_DEFINE_TYPE (BasicEngineX, basic_engine_x, + basic_engine_x_class_init, NULL); - result->engine.id = SCRIPT_ENGINE_NAME; - result->engine.type = PANGO_ENGINE_TYPE_SHAPE; - result->engine.length = sizeof (result); - result->script_shape = basic_engine_shape; - result->get_coverage = basic_engine_get_coverage; +void +PANGO_MODULE_ENTRY(init) (GTypeModule *module) +{ + basic_engine_x_register_type (module); +} - return (PangoEngine *)result; +void +PANGO_MODULE_ENTRY(exit) (void) +{ } void @@ -722,20 +731,14 @@ PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, int *n_engines) { *engines = script_engines; - *n_engines = n_script_engines; + *n_engines = G_N_ELEMENTS (script_engines); } PangoEngine * -PANGO_MODULE_ENTRY(load) (const char *id) +PANGO_MODULE_ENTRY(create) (const char *id) { if (!strcmp (id, SCRIPT_ENGINE_NAME)) - return basic_engine_x_new (); + return g_object_new (basic_engine_x_type, NULL); else return NULL; } - -void -PANGO_MODULE_ENTRY(unload) (PangoEngine *engine) -{ -} - diff --git a/modules/hangul/hangul-fc.c b/modules/hangul/hangul-fc.c index 3ba6a479..94216695 100644 --- a/modules/hangul/hangul-fc.c +++ b/modules/hangul/hangul-fc.c @@ -24,11 +24,15 @@ #include "pango-engine.h" #include "pango-utils.h" +#include "pangofc-font.h" #include "hangul-defs.h" #include "tables-jamos.i" -#include "pangofc-font.h" +/* No extra fields needed */ +typedef PangoEngineShape HangulEngineFc; +typedef PangoEngineShapeClass HangulEngineFcClass ; + #define SCRIPT_ENGINE_NAME "HangulScriptEngineFc" #define RENDER_TYPE PANGO_RENDER_TYPE_FC @@ -275,7 +279,8 @@ render_syllable (PangoFont *font, gunichar *text, int length, } static void -hangul_engine_shape (PangoFont *font, +hangul_engine_shape (PangoEngineShape *engine, + PangoFont *font, const char *text, gint length, PangoAnalysis *analysis, @@ -357,42 +362,26 @@ hangul_engine_shape (PangoFont *font, g_free(jamos); } -static PangoCoverage * -hangul_engine_get_coverage (PangoFont *font, - PangoLanguage *lang) +static void +hangul_engine_fc_class_init (PangoEngineShapeClass *class) { - PangoCoverage *result = pango_coverage_new (); - int i; - - /* Well, no unicode rendering engine could render Hangul Jamo area - _exactly_, I sure. */ - for (i = 0x1100; i <= 0x11ff; i++) - pango_coverage_set (result, i, PANGO_COVERAGE_FALLBACK); - pango_coverage_set (result, 0x302e, PANGO_COVERAGE_FALLBACK); - pango_coverage_set (result, 0x302f, PANGO_COVERAGE_FALLBACK); - for (i = 0xac00; i <= 0xd7a3; i++) - pango_coverage_set (result, i, PANGO_COVERAGE_EXACT); - return result; + class->script_shape = hangul_engine_shape; } -static PangoEngine * -hangul_engine_xft_new () -{ - PangoEngineShape *result; - - result = g_new (PangoEngineShape, 1); +PANGO_ENGINE_SHAPE_DEFINE_TYPE (HangulEngineFc, hangul_engine_fc, + hangul_engine_fc_class_init, NULL); - result->engine.id = SCRIPT_ENGINE_NAME; - result->engine.type = PANGO_ENGINE_TYPE_SHAPE; - result->engine.length = sizeof (result); - result->script_shape = hangul_engine_shape; - result->get_coverage = hangul_engine_get_coverage; +void +PANGO_MODULE_ENTRY(init) (GTypeModule *module) +{ + hangul_engine_fc_register_type (module); +} - return (PangoEngine *)result; +void +PANGO_MODULE_ENTRY(exit) (void) +{ } -/* List the engines contained within this module - */ void PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, int *n_engines) @@ -401,18 +390,11 @@ PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, *n_engines = G_N_ELEMENTS (script_engines); } -/* Load a particular engine given the ID for the engine - */ PangoEngine * -PANGO_MODULE_ENTRY(load) (const char *id) +PANGO_MODULE_ENTRY(create) (const char *id) { if (!strcmp (id, SCRIPT_ENGINE_NAME)) - return hangul_engine_xft_new (); + return g_object_new (hangul_engine_fc_type, NULL); else return NULL; } - -void -PANGO_MODULE_ENTRY(unload) (PangoEngine *engine) -{ -} diff --git a/modules/hebrew/hebrew-fc.c b/modules/hebrew/hebrew-fc.c index 273755e4..01a7f2e3 100644 --- a/modules/hebrew/hebrew-fc.c +++ b/modules/hebrew/hebrew-fc.c @@ -24,8 +24,13 @@ #include "pango-engine.h" #include "pango-utils.h" +#include "pangofc-font.h" #include "hebrew-shaper.h" +/* No extra fields needed */ +typedef PangoEngineShape HebrewEngineFc; +typedef PangoEngineShapeClass HebrewEngineFcClass ; + #define MAX_CLUSTER_CHRS 20 static PangoEngineRange hebrew_ranges[] = { @@ -34,7 +39,6 @@ static PangoEngineRange hebrew_ranges[] = { { 0xfb1d, 0xfb4f, "*" } /* Hebrew presentation forms */ }; -#include "pangofc-font.h" #define SCRIPT_ENGINE_NAME "HebrewScriptEngineFc" #define RENDER_TYPE PANGO_RENDER_TYPE_FC @@ -124,11 +128,12 @@ add_cluster(PangoFont *font, static void -hebrew_engine_shape (PangoFont *font, - const char *text, - gint length, - PangoAnalysis *analysis, - PangoGlyphString *glyphs) +hebrew_engine_shape (PangoEngineShape *engine, + PangoFont *font, + const char *text, + gint length, + PangoAnalysis *analysis, + PangoGlyphString *glyphs) { const char *p; const char *log_cluster; @@ -189,31 +194,26 @@ hebrew_engine_shape (PangoFont *font, hebrew_shaper_bidi_reorder(glyphs); } -static PangoCoverage * -hebrew_engine_get_coverage (PangoFont *font, - PangoLanguage *lang) +static void +hebrew_engine_fc_class_init (PangoEngineShapeClass *class) { - return pango_font_get_coverage (font, lang); + class->script_shape = hebrew_engine_shape; } -static PangoEngine * -hebrew_engine_fc_new () -{ - PangoEngineShape *result; - - result = g_new (PangoEngineShape, 1); +PANGO_ENGINE_SHAPE_DEFINE_TYPE (HebrewEngineFc, hebrew_engine_fc, + hebrew_engine_fc_class_init, NULL); - result->engine.id = SCRIPT_ENGINE_NAME; - result->engine.type = PANGO_ENGINE_TYPE_SHAPE; - result->engine.length = sizeof (result); - result->script_shape = hebrew_engine_shape; - result->get_coverage = hebrew_engine_get_coverage; +void +PANGO_MODULE_ENTRY(init) (GTypeModule *module) +{ + hebrew_engine_fc_register_type (module); +} - return (PangoEngine *)result; +void +PANGO_MODULE_ENTRY(exit) (void) +{ } -/* List the engines contained within this module - */ void PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, int *n_engines) @@ -222,18 +222,11 @@ PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, *n_engines = G_N_ELEMENTS (script_engines); } -/* Load a particular engine given the ID for the engine - */ PangoEngine * -PANGO_MODULE_ENTRY(load) (const char *id) +PANGO_MODULE_ENTRY(create) (const char *id) { if (!strcmp (id, SCRIPT_ENGINE_NAME)) - return hebrew_engine_fc_new (); + return g_object_new (hebrew_engine_fc_type, NULL); else return NULL; } - -void -PANGO_MODULE_ENTRY(unload) (PangoEngine *engine) -{ -} diff --git a/modules/indic/indic-fc.c b/modules/indic/indic-fc.c index bd4c8f4b..f70fadfb 100644 --- a/modules/indic/indic-fc.c +++ b/modules/indic/indic-fc.c @@ -28,11 +28,14 @@ #include "pango-engine.h" #include "pango-ot.h" #include "pango-utils.h" +#include "pangofc-font.h" -typedef struct _PangoEngineShapeIndic PangoEngineShapeIndic; typedef struct _PangoIndicInfo PangoIndicInfo; -struct _PangoEngineShapeIndic +typedef struct _IndicEngineFc IndicEngineFc; +typedef PangoEngineShapeClass IndicEngineFcClass ; /* No extra fields needed */ + +struct _IndicEngineFc { PangoEngineShape shapeEngine; PangoIndicInfo *indicInfo; @@ -46,7 +49,6 @@ struct _PangoIndicInfo gchar *gposQuarkName; }; -#include "pangofc-font.h" #define ENGINE_SUFFIX "ScriptEngineFc" #define RENDER_TYPE PANGO_RENDER_TYPE_FC @@ -291,7 +293,8 @@ expand_text(const gchar *text, glong length, glong **offsets, glong *n_chars) /* analysis->shape_engine has the PangoEngine... */ static void -indic_engine_shape (PangoFont *font, +indic_engine_shape (PangoEngineShape *engine, + PangoFont *font, const char *text, gint length, PangoAnalysis *analysis, @@ -304,7 +307,7 @@ indic_engine_shape (PangoFont *font, glong *indices = NULL; FT_Face face; PangoOTRuleset *gsub_ruleset = NULL, *gpos_ruleset = NULL; - PangoEngineShapeIndic *indic_shape_engine = NULL; + IndicEngineFc *indic_shape_engine = NULL; PangoIndicInfo *indic_info = NULL; PangoFcFont *fc_font; MPreFixups *mprefixups; @@ -318,11 +321,7 @@ indic_engine_shape (PangoFont *font, face = pango_fc_font_lock_face (fc_font); g_assert (face != NULL); - indic_shape_engine = (PangoEngineShapeIndic *) analysis->shape_engine; - -#if 1 - g_assert (indic_shape_engine->shapeEngine.engine.length == sizeof (PangoEngineShapeIndic)); -#endif + indic_shape_engine = (IndicEngineFc *) engine; indic_info = indic_shape_engine->indicInfo; @@ -400,33 +399,26 @@ indic_engine_shape (PangoFont *font, g_free (utf8_offsets); } -static PangoCoverage * -indic_engine_get_coverage (PangoFont *font, - PangoLanguage *lang) +static void +indic_engine_fc_class_init (PangoEngineShapeClass *class) { - return pango_font_get_coverage (font, lang); + class->script_shape = indic_engine_shape; } -static PangoEngine * -indic_engine_fc_new (gint index) -{ - PangoEngineShapeIndic *result; - - result = g_new (PangoEngineShapeIndic, 1); - - result->shapeEngine.engine.id = script_engines[index].id; - result->shapeEngine.engine.type = PANGO_ENGINE_TYPE_SHAPE; - result->shapeEngine.engine.length = sizeof (*result); - result->shapeEngine.script_shape = indic_engine_shape; - result->shapeEngine.get_coverage = indic_engine_get_coverage; +PANGO_ENGINE_SHAPE_DEFINE_TYPE (IndicEngineFc, indic_engine_fc, + indic_engine_fc_class_init, NULL); - result->indicInfo = &indic_info[index]; +void +PANGO_MODULE_ENTRY(init) (GTypeModule *module) +{ + indic_engine_fc_register_type (module); +} - return (PangoEngine *)result; +void +PANGO_MODULE_ENTRY(exit) (void) +{ } -/* List the engines contained within this module - */ void PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, int *n_engines) @@ -435,10 +427,8 @@ PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, *n_engines = G_N_ELEMENTS (script_engines); } -/* Load a particular engine given the ID for the engine - */ PangoEngine * -PANGO_MODULE_ENTRY(load) (const char *id) +PANGO_MODULE_ENTRY(create) (const char *id) { gint i; @@ -446,14 +436,12 @@ PANGO_MODULE_ENTRY(load) (const char *id) { if (!strcmp(id, script_engines[i].id)) { - return indic_engine_fc_new(i); + IndicEngineFc *engine = g_object_new (indic_engine_fc_type, NULL); + engine->indicInfo = &indic_info[i]; + + return (PangoEngine *)engine; } } return NULL; } - -void -PANGO_MODULE_ENTRY(unload) (PangoEngine *engine) -{ -} diff --git a/modules/thai/thai-fc.c b/modules/thai/thai-fc.c index 6c537639..9a9839a9 100644 --- a/modules/thai/thai-fc.c +++ b/modules/thai/thai-fc.c @@ -31,9 +31,14 @@ #include <glib.h> #include "pango-engine.h" +#include "pangofc-font.h" + #include "thai-shaper.h" -#include "pangofc-font.h" +/* No extra fields needed */ +typedef PangoEngineShape ThaiEngineFc; +typedef PangoEngineShapeClass ThaiEngineFcClass ; + #define SCRIPT_ENGINE_NAME "ThaiScriptEngineFc" #define RENDER_TYPE PANGO_RENDER_TYPE_FC @@ -199,31 +204,26 @@ thai_has_glyph (ThaiFontInfo *font_info, PangoGlyph glyph) return TRUE; } -static PangoCoverage * -thai_engine_get_coverage (PangoFont *font, - PangoLanguage *lang) +static void +thai_engine_fc_class_init (PangoEngineShapeClass *class) { - return pango_font_get_coverage (font, lang); + class->script_shape = thai_engine_shape; } -static PangoEngine * -thai_engine_fc_new () -{ - PangoEngineShape *result; - - result = g_new (PangoEngineShape, 1); +PANGO_ENGINE_SHAPE_DEFINE_TYPE (ThaiEngineFc, thai_engine_fc, + thai_engine_fc_class_init, NULL); - result->engine.id = SCRIPT_ENGINE_NAME; - result->engine.type = PANGO_ENGINE_TYPE_SHAPE; - result->engine.length = sizeof (result); - result->script_shape = thai_engine_shape; - result->get_coverage = thai_engine_get_coverage; +void +PANGO_MODULE_ENTRY(init) (GTypeModule *module) +{ + thai_engine_fc_register_type (module); +} - return (PangoEngine *)result; +void +PANGO_MODULE_ENTRY(exit) (void) +{ } -/* List the engines contained within this module - */ void PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, int *n_engines) @@ -232,18 +232,11 @@ PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, *n_engines = G_N_ELEMENTS (script_engines); } -/* Load a particular engine given the ID for the engine - */ PangoEngine * -PANGO_MODULE_ENTRY(load) (const char *id) +PANGO_MODULE_ENTRY(create) (const char *id) { if (!strcmp (id, SCRIPT_ENGINE_NAME)) - return thai_engine_fc_new (); + return g_object_new (thai_engine_fc_type, NULL); else return NULL; } - -void -PANGO_MODULE_ENTRY(unload) (PangoEngine *engine) -{ -} diff --git a/modules/thai/thai-shaper.c b/modules/thai/thai-shaper.c index fd052dd3..4cd98283 100644 --- a/modules/thai/thai-shaper.c +++ b/modules/thai/thai-shaper.c @@ -692,7 +692,8 @@ get_next_cluster(const char *text, } void -thai_engine_shape (PangoFont *font, +thai_engine_shape (PangoEngineShape *engine, + PangoFont *font, const char *text, gint length, PangoAnalysis *analysis, diff --git a/modules/thai/thai-shaper.h b/modules/thai/thai-shaper.h index 7a9bb31e..b745da86 100644 --- a/modules/thai/thai-shaper.h +++ b/modules/thai/thai-shaper.h @@ -54,7 +54,8 @@ thai_has_glyph (ThaiFontInfo *font_info, PangoGlyph glyph); * Public functions */ void -thai_engine_shape (PangoFont *font, +thai_engine_shape (PangoEngineShape *engine, + PangoFont *font, const char *text, gint length, PangoAnalysis *analysis, 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); diff --git a/tests/.cvsignore b/tests/.cvsignore index 29920694..d6cd9e30 100644 --- a/tests/.cvsignore +++ b/tests/.cvsignore @@ -3,6 +3,7 @@ runtests.sh runtests.log testboundaries +testscript dump-boundaries gen-all-unicode all-unicode.txt diff --git a/tests/Makefile.am b/tests/Makefile.am index 8c0982f5..ef1ea433 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -27,7 +27,7 @@ TESTS=runtests.sh noinst_PROGRAMS = gen-all-unicode dump-boundaries -check_PROGRAMS = testboundaries testcolor +check_PROGRAMS = testboundaries testcolor testscript gen_all_unicode_SOURCES = gen-all-unicode.c @@ -35,6 +35,8 @@ testboundaries_SOURCES = testboundaries.c testcolor_SOURCES = testcolor.c +testscript_SOURCES = testscript.c + dump_boundaries_SOURCES = dump-boundaries.c gen_all_unicode_LDADD = $(GLIB_LIBS) @@ -43,6 +45,8 @@ testboundaries_LDADD = ../pango/libpango-$(PANGO_API_VERSION).la testcolor_LDADD = ../pango/libpango-$(PANGO_API_VERSION).la +testscript_LDADD = ../pango/libpango-$(PANGO_API_VERSION).la + dump_boundaries_LDADD = ../pango/libpango-$(PANGO_API_VERSION).la if HAVE_CXX diff --git a/tests/testscript.c b/tests/testscript.c new file mode 100644 index 00000000..5ef39384 --- /dev/null +++ b/tests/testscript.c @@ -0,0 +1,254 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* Pango + * testscript.c: Test cases for PangoScriptIter + * + * 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. + * + * The test strings here come from ICU: + * + * icu/sources/test/cintltst/cucdtst.c + * + ******************************************************************** + * COPYRIGHT: + * Copyright (c) 1997-2001, 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 <stdlib.h> +#include <string.h> + +#include "pango/pango-script.h" +#include "pango/pango-script-table.h" + +#undef VERBOSE + +#define ASSERT(stmt) G_STMT_START { \ + if (stmt) { } \ + else \ + { \ + g_warning ("%s:%d (%s): assertion '%s' failed", \ + __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, #stmt); \ + exit (1); \ + } \ +} G_STMT_END + +typedef struct +{ + const char *run_text_escaped; + char *run_text; + PangoScript run_code; +} RunTestData; + +static gchar * +unescape (const char *text) +{ + gboolean escaped = FALSE; + GString *result = g_string_new (NULL); + const gchar *p; + + for (p = text; *p; p = g_utf8_next_char (p)) + { + gunichar ch = g_utf8_get_char (p); + + if (escaped) + { + if (ch == 'u' || ch == 'U') + { + int n_chars = ch == 'u' ? 4 : 8; + int i; + + ch = 0; + for (i = 0; i < n_chars; i++) + { + p++; + ch <<= 4; + if (*p <= '9' && *p >= '0') + ch += *p - '0'; + else if (*p <= 'F' && *p >= 'A') + ch += 10 + *p - 'A'; + else if (*p <= 'f' && *p >= 'a') + ch += 10 + *p - 'a'; + else + g_assert_not_reached (); + } + } + else if (ch == '\\') + { + ch = '\\'; + } + else + { + g_assert_not_reached (); + } + + escaped = FALSE; + } + else + { + if (ch == '\\') + { + escaped = TRUE; + continue; + } + } + + g_string_append_unichar (result, ch); + } + + return g_string_free (result, FALSE); +} + +static void +test_script_lookup () +{ + gunichar ch = 0; + int i, j; + + for (i = 0; i < G_N_ELEMENTS (pango_script_table); i++) + { + while (ch < pango_script_table[i].start) + { + ASSERT (pango_script_for_unichar (ch) == PANGO_SCRIPT_COMMON); + ch++; + } + + for (j = 0; j < pango_script_table[i].chars; j++) + { + ASSERT (pango_script_for_unichar (ch) == pango_script_table[i].script); + ch++; + } + } + + ASSERT (pango_script_for_unichar (ch) == PANGO_SCRIPT_COMMON); +} + +static void +test_script_iter (void) +{ + static RunTestData test_data[] = { + { "\\u0020\\u0946\\u0939\\u093F\\u0928\\u094D\\u0926\\u0940\\u0020", NULL, PANGO_SCRIPT_DEVANAGARI }, + { "\\u0627\\u0644\\u0639\\u0631\\u0628\\u064A\\u0629\\u0020", NULL, PANGO_SCRIPT_ARABIC }, + { "\\u0420\\u0443\\u0441\\u0441\\u043A\\u0438\\u0439\\u0020", NULL, PANGO_SCRIPT_CYRILLIC }, + { "English (", NULL, PANGO_SCRIPT_LATIN }, + { "\\u0E44\\u0E17\\u0E22", NULL, PANGO_SCRIPT_THAI }, + { ") ", NULL, PANGO_SCRIPT_LATIN }, + { "\\u6F22\\u5B75", NULL, PANGO_SCRIPT_HAN }, + { "\\u3068\\u3072\\u3089\\u304C\\u306A\\u3068", NULL, PANGO_SCRIPT_HIRAGANA }, + { "\\u30AB\\u30BF\\u30AB\\u30CA", NULL, PANGO_SCRIPT_KATAKANA }, + { "\\U00010400\\U00010401\\U00010402\\U00010403", NULL, PANGO_SCRIPT_DESERET } + }; + + PangoScriptIter *iter; + GString *all = g_string_new (FALSE); + char *pos; + const char *start; + const char *end; + PangoScript script; + int i; + + for (i = 0; i < G_N_ELEMENTS(test_data); i++) + { + test_data[i].run_text = unescape (test_data[i].run_text_escaped); + g_string_append (all, test_data[i].run_text); + } + + iter = pango_script_iter_new (all->str, -1); + +#ifdef VERBOSE + g_print ("Total length: %d\n", all->len); +#endif + + pos = all->str; + for (i = 0; i < G_N_ELEMENTS(test_data); i++) + { + char *next_pos = pos + strlen (test_data[i].run_text); + gboolean result; + + pango_script_iter_get_range (iter, &start, &end, &script); +#ifdef VERBOSE + g_print ("Range: %d-%d: %d\n", start - all->str, end - all->str, script); +#endif + + ASSERT (start == pos); + ASSERT (end == next_pos); + ASSERT (script == test_data[i].run_code); + + result = pango_script_iter_next (iter); + ASSERT (result == (i != G_N_ELEMENTS (test_data) - 1)); + + pos = next_pos; + } + + pango_script_iter_free (iter); + + /* + * Test an empty string. + */ + iter = pango_script_iter_new (all->str, 0); + + pango_script_iter_get_range (iter, &start, &end, &script); + + ASSERT (start == all->str); + ASSERT (end == all->str); + ASSERT (script == PANGO_SCRIPT_COMMON); + ASSERT (!pango_script_iter_next (iter)); + + pango_script_iter_free (iter); + + /* Cleanup */ + + for (i = 0; i < G_N_ELEMENTS (test_data); i++) + g_free (test_data[i].run_text); + + g_string_free (all, TRUE); +} + +int +main (int argc, char **argv) +{ + test_script_lookup (); + test_script_iter (); + + return 0; +} diff --git a/tools/.cvsignore b/tools/.cvsignore index c038ed78..24f67f13 100644 --- a/tools/.cvsignore +++ b/tools/.cvsignore @@ -1,2 +1,3 @@ +gen-script-for-lang Makefile Makefile.in
\ No newline at end of file diff --git a/tools/Makefile.am b/tools/Makefile.am index d43cf4a6..2206e601 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,8 +1,20 @@ ## Process this file with automake to create Makefile.in. +INCLUDES = \ + -I$(top_srcdir) \ + $(GLIB_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DPANGO_DISABLE_DEPRECATED \ + $(PANGO_DEBUG_FLAGS) + +noinst_PROGRAMS = gen-script-for-lang + EXTRA_DIST= \ add-copyright \ compress-table.pl \ make-table.sh \ maps/README \ maps/tis-620 + +gen_script_for_lang_SOURCES = gen-script-for-lang.c +gen_script_for_lang_LDADD = ../pango/libpango-$(PANGO_API_VERSION).la diff --git a/tools/gen-script-for-lang.c b/tools/gen-script-for-lang.c new file mode 100644 index 00000000..ee1580e2 --- /dev/null +++ b/tools/gen-script-for-lang.c @@ -0,0 +1,232 @@ +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <pango/pango-enum-types.h> +#include <pango/pango-script.h> +#include <pango/pango-types.h> +#include <pango/pango-utils.h> + +PangoScript script_for_file (const char *base_dir, + const char *file_part); + +const char *get_script_name (PangoScript script) +{ + static GEnumClass *class = NULL; + if (!class) + class = g_type_class_ref (PANGO_TYPE_SCRIPT); + + GEnumValue *value = g_enum_get_value (class, script); + g_assert (value); + + return value->value_name; +} + +int fail (char *format, ...) +{ + va_list vap; + + va_start (vap, format); + vfprintf (stderr, format, vap); + va_end (vap); + + exit (1); +} + +gboolean scan_hex (const char **str, gunichar *result) +{ + const char *end; + + *result = strtol (*str, (char **)&end, 16); + if (end == *str) + return FALSE; + + *str = end; + return TRUE; +} + +void warn_mismatch (const char *file_part, + PangoScript script1, + PangoScript script2) +{ + g_printerr ("%s has characters for both %s and %s\n", + file_part, get_script_name (script1), get_script_name (script2)); +} + +PangoScript script_for_line (const char *base_dir, + const char *file_part, + const char *str) +{ + gunichar start_char; + gunichar end_char; + gunichar ch; + PangoScript result = PANGO_SCRIPT_COMMON; + const char *p = str; + + if (g_str_has_prefix (str, "include")) + { + GString *file_part = g_string_new (NULL); + + str += strlen ("include"); + if (!pango_skip_space (&str)) + goto err; + + if (!pango_scan_string (&str, file_part) || + pango_skip_space (&str)) + goto err; + + result = script_for_file (base_dir, file_part->str); + g_string_free (file_part, TRUE); + + return result; + } + + /* Format is HEX_DIGITS or HEX_DIGITS-HEX_DIGITS */ + if (!scan_hex (&p, &start_char)) + goto err; + + end_char = start_char; + + pango_skip_space (&p); + if (*p == '-') + { + p++; + if (!scan_hex (&p, &end_char)) + goto err; + + pango_skip_space (&p); + } + if (*p != '\0') + goto err; + + for (ch = start_char; ch <= end_char; ch++) + { + PangoScript script = pango_script_for_unichar (ch); + if (script != PANGO_SCRIPT_COMMON && + script != PANGO_SCRIPT_INHERITED) + { + if (result != PANGO_SCRIPT_COMMON && script != result) + { + warn_mismatch (file_part, script, result); + return PANGO_SCRIPT_INVALID_CODE; + } + result = script; + } + } + + return result; + + err: + fail ("While processing '%s', cannot parse line: '%s'\n", file_part, str); + return PANGO_SCRIPT_INVALID_CODE; /* Not reached */ +} + +PangoScript script_for_file (const char *base_dir, + const char *file_part) +{ + GError *error = NULL; + char *filename = g_build_filename (base_dir, file_part, NULL); + GIOChannel *channel = g_io_channel_new_file (filename, "r", &error); + GIOStatus status = G_IO_STATUS_NORMAL; + PangoScript result = PANGO_SCRIPT_COMMON; + + if (!channel) + fail ("Error opening '%s': %s\n", filename, error); + + /* The files have ISO-8859-1 copyright signs in them */ + if (!g_io_channel_set_encoding (channel, "ISO-8859-1", &error)) + fail ("Cannot set encoding when reading '%s': %s\n", filename, error); + + while (status == G_IO_STATUS_NORMAL) + { + char *str; + size_t term; + char *comment; + + status = g_io_channel_read_line (channel, &str, NULL, &term, &error); + switch (status) + { + case G_IO_STATUS_NORMAL: + str[term] = '\0'; + comment = strchr (str, '#'); + if (comment) + *comment = '\0'; + g_strstrip (str); + if (str[0] != '\0') /* Empty */ + { + PangoScript script = script_for_line (base_dir, file_part, str); + if (script != PANGO_SCRIPT_COMMON && + script != PANGO_SCRIPT_INHERITED) + { + if (result != PANGO_SCRIPT_COMMON && script != result) + { + warn_mismatch (file_part, script, result); + result = PANGO_SCRIPT_INVALID_CODE; + status = G_IO_STATUS_EOF; + } + else + result = script; + } + } + g_free (str); + break; + case G_IO_STATUS_EOF: + break; + case G_IO_STATUS_ERROR: + fail ("Error reading '%s': %s\n", filename, error->message); + break; + case G_IO_STATUS_AGAIN: + g_assert_not_reached (); + break; + } + } + + if (!g_io_channel_shutdown (channel, FALSE, &error)) + fail ("Error closing '%s': %s\n", channel, error); + + g_free (filename); + + return result; +} + +int main (int argc, char **argv) +{ + GDir *dir; + GError *error = NULL; + + g_type_init (); + + if (argc != 2) + fail ("Usage: gen-script-for-lang DIR > script-for-lang.h\n"); + + dir = g_dir_open (argv[1], 0, &error); + if (!dir) + fail ("%s\n", error->message); + + while (TRUE) + { + const char *name = g_dir_read_name (dir); + if (!name) + break; + + if (g_str_has_suffix (name, ".orth")) + { + char *langpart = g_strndup (name, + strlen (name) - strlen (".orth")); + PangoLanguage *lang = pango_language_from_string (langpart); + PangoScript script; + + script = script_for_file (argv[1], name); + g_print ("%s - %s\n", + pango_language_to_string (lang), + get_script_name (script)); + g_free (langpart); + } + } + + g_dir_close (dir); + + return 0; +} + diff --git a/tools/gen-script-table.pl b/tools/gen-script-table.pl new file mode 100755 index 00000000..6b524ef7 --- /dev/null +++ b/tools/gen-script-table.pl @@ -0,0 +1,70 @@ +#!/usr/bin/perl -w +# +# Script to convert http://www.unicode.org/Public/UNIDATA/Scripts.txt +# into a machine-readable table. +# +###################################################################### + +if (@ARGV != 1) { + die "Usage: gen-script-table.pl Scripts.txt > pango-script-table.h\n"; +} + +open IN, $ARGV[0] || die "Cannot open $ARGV[0]: $!\n"; + +my @ranges; +my $file; + +while (<IN>) { + if (/^\#\s+(Scripts-.*.txt)/) { + $file = $1; + } + + s/#.*//; + next if /^\s*$/; + if (!/^([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s+;\s+([A-Z_]+)\s+$/) { + die "Cannot parse line: $_\n"; + } + + if (defined $2) { + push @ranges, [ hex $1, hex $2, $3 ]; + } else { + push @ranges, [ hex $1, hex $1, $3 ]; + } +} + +$date = gmtime; + +print <<"EOT"; +/* pango-script-table.h: Generated by gen-script-table.pl + * + * Date: $date + * Source: $file + * + * Do not edit. + */ +static const struct { + gunichar start; + guint16 chars; + guint16 script; /* PangoScript */ +} pango_script_table[] = { +EOT + +@ranges = sort { $a->[0] <=> $b->[0] } @ranges; + +for (my $i = 0; $i <= $#ranges; $i++) { + my $start = $ranges[$i]->[0]; + my $end = $ranges[$i]->[1]; + my $script = $ranges[$i]->[2]; + + while ($i <= $#ranges - 1 && + $ranges[$i + 1]->[0] == $end + 1 && + $ranges[$i + 1]->[2] eq $script) { + $i++; + $end = $ranges[$i]->[1]; + } + + printf " { %#06x, %5d, PANGO_SCRIPT_%s },\n", $start, $end - $start + 1, $script; +} + +printf "};\n"; + |