diff options
author | Robert Brady <rbrady@src.gnome.org> | 2000-11-08 06:07:47 +0000 |
---|---|---|
committer | Robert Brady <rbrady@src.gnome.org> | 2000-11-08 06:07:47 +0000 |
commit | 452359df74d9ab351b010a58693e597a53aa6362 (patch) | |
tree | 0011ec5c2192c96d27663cdd2a945a784f8920de | |
parent | 28b8f5db1a22d8ccefb4a88bb0f16ea3d84afade (diff) | |
download | pango-452359df74d9ab351b010a58693e597a53aa6362.tar.gz |
Shiny new Indic shapers!
30 files changed, 3795 insertions, 4616 deletions
@@ -1,5 +1,24 @@ 2000-11-08 Robert Brady <rwb197@zepler.org> + * pango/fonts/devnag.README: Updated to point to the new fonts + + * examples/HELLO.utf8: Added a few new entries. + + * modules/Makefile.am, configure.in: s/devanagari/indic/ + + * modules/devangari: Removed. + + * modules/indic: New shapers for Devanagari, + Bengali, Gurmukhi, Gujarati, and Burmese, that make use of + the below facilities. + + * pango/fonts/devnag18.bdf: Removed. + + * pango/docs/TEXT/ligatures: Documentation on the ligatures. + + * examples/pangox.aliases: Added fonts for the new Indic renderers + to sans, serif and monospace. + * pango/pangox-fontmap.c, pango/pangox-private.h: Add a per-PangoXFontMap cache for X Atoms. diff --git a/ChangeLog.pre-1-0 b/ChangeLog.pre-1-0 index ef604304..4bf6a47d 100644 --- a/ChangeLog.pre-1-0 +++ b/ChangeLog.pre-1-0 @@ -1,5 +1,24 @@ 2000-11-08 Robert Brady <rwb197@zepler.org> + * pango/fonts/devnag.README: Updated to point to the new fonts + + * examples/HELLO.utf8: Added a few new entries. + + * modules/Makefile.am, configure.in: s/devanagari/indic/ + + * modules/devangari: Removed. + + * modules/indic: New shapers for Devanagari, + Bengali, Gurmukhi, Gujarati, and Burmese, that make use of + the below facilities. + + * pango/fonts/devnag18.bdf: Removed. + + * pango/docs/TEXT/ligatures: Documentation on the ligatures. + + * examples/pangox.aliases: Added fonts for the new Indic renderers + to sans, serif and monospace. + * pango/pangox-fontmap.c, pango/pangox-private.h: Add a per-PangoXFontMap cache for X Atoms. diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10 index ef604304..4bf6a47d 100644 --- a/ChangeLog.pre-1-10 +++ b/ChangeLog.pre-1-10 @@ -1,5 +1,24 @@ 2000-11-08 Robert Brady <rwb197@zepler.org> + * pango/fonts/devnag.README: Updated to point to the new fonts + + * examples/HELLO.utf8: Added a few new entries. + + * modules/Makefile.am, configure.in: s/devanagari/indic/ + + * modules/devangari: Removed. + + * modules/indic: New shapers for Devanagari, + Bengali, Gurmukhi, Gujarati, and Burmese, that make use of + the below facilities. + + * pango/fonts/devnag18.bdf: Removed. + + * pango/docs/TEXT/ligatures: Documentation on the ligatures. + + * examples/pangox.aliases: Added fonts for the new Indic renderers + to sans, serif and monospace. + * pango/pangox-fontmap.c, pango/pangox-private.h: Add a per-PangoXFontMap cache for X Atoms. diff --git a/ChangeLog.pre-1-2 b/ChangeLog.pre-1-2 index ef604304..4bf6a47d 100644 --- a/ChangeLog.pre-1-2 +++ b/ChangeLog.pre-1-2 @@ -1,5 +1,24 @@ 2000-11-08 Robert Brady <rwb197@zepler.org> + * pango/fonts/devnag.README: Updated to point to the new fonts + + * examples/HELLO.utf8: Added a few new entries. + + * modules/Makefile.am, configure.in: s/devanagari/indic/ + + * modules/devangari: Removed. + + * modules/indic: New shapers for Devanagari, + Bengali, Gurmukhi, Gujarati, and Burmese, that make use of + the below facilities. + + * pango/fonts/devnag18.bdf: Removed. + + * pango/docs/TEXT/ligatures: Documentation on the ligatures. + + * examples/pangox.aliases: Added fonts for the new Indic renderers + to sans, serif and monospace. + * pango/pangox-fontmap.c, pango/pangox-private.h: Add a per-PangoXFontMap cache for X Atoms. diff --git a/ChangeLog.pre-1-4 b/ChangeLog.pre-1-4 index ef604304..4bf6a47d 100644 --- a/ChangeLog.pre-1-4 +++ b/ChangeLog.pre-1-4 @@ -1,5 +1,24 @@ 2000-11-08 Robert Brady <rwb197@zepler.org> + * pango/fonts/devnag.README: Updated to point to the new fonts + + * examples/HELLO.utf8: Added a few new entries. + + * modules/Makefile.am, configure.in: s/devanagari/indic/ + + * modules/devangari: Removed. + + * modules/indic: New shapers for Devanagari, + Bengali, Gurmukhi, Gujarati, and Burmese, that make use of + the below facilities. + + * pango/fonts/devnag18.bdf: Removed. + + * pango/docs/TEXT/ligatures: Documentation on the ligatures. + + * examples/pangox.aliases: Added fonts for the new Indic renderers + to sans, serif and monospace. + * pango/pangox-fontmap.c, pango/pangox-private.h: Add a per-PangoXFontMap cache for X Atoms. diff --git a/ChangeLog.pre-1-6 b/ChangeLog.pre-1-6 index ef604304..4bf6a47d 100644 --- a/ChangeLog.pre-1-6 +++ b/ChangeLog.pre-1-6 @@ -1,5 +1,24 @@ 2000-11-08 Robert Brady <rwb197@zepler.org> + * pango/fonts/devnag.README: Updated to point to the new fonts + + * examples/HELLO.utf8: Added a few new entries. + + * modules/Makefile.am, configure.in: s/devanagari/indic/ + + * modules/devangari: Removed. + + * modules/indic: New shapers for Devanagari, + Bengali, Gurmukhi, Gujarati, and Burmese, that make use of + the below facilities. + + * pango/fonts/devnag18.bdf: Removed. + + * pango/docs/TEXT/ligatures: Documentation on the ligatures. + + * examples/pangox.aliases: Added fonts for the new Indic renderers + to sans, serif and monospace. + * pango/pangox-fontmap.c, pango/pangox-private.h: Add a per-PangoXFontMap cache for X Atoms. diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8 index ef604304..4bf6a47d 100644 --- a/ChangeLog.pre-1-8 +++ b/ChangeLog.pre-1-8 @@ -1,5 +1,24 @@ 2000-11-08 Robert Brady <rwb197@zepler.org> + * pango/fonts/devnag.README: Updated to point to the new fonts + + * examples/HELLO.utf8: Added a few new entries. + + * modules/Makefile.am, configure.in: s/devanagari/indic/ + + * modules/devangari: Removed. + + * modules/indic: New shapers for Devanagari, + Bengali, Gurmukhi, Gujarati, and Burmese, that make use of + the below facilities. + + * pango/fonts/devnag18.bdf: Removed. + + * pango/docs/TEXT/ligatures: Documentation on the ligatures. + + * examples/pangox.aliases: Added fonts for the new Indic renderers + to sans, serif and monospace. + * pango/pangox-fontmap.c, pango/pangox-private.h: Add a per-PangoXFontMap cache for X Atoms. diff --git a/configure.in b/configure.in index d583e383..9494385c 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_SUBST(PANGO_MAJOR_VERSION) AC_SUBST(PANGO_MINOR_VERSION) AC_INIT(ChangeLog) -AM_INIT_AUTOMAKE(pango, $PANGO_MAJOR_VERSION.$PANGO_MINOR_VERSION) +AM_INIT_AUTOMAKE(pango, 0.12) AM_CONFIG_HEADER(config.h) @@ -108,7 +108,7 @@ if test "x$with_included_modules" != xno || test "x$with_included_modules" = x ; # If no modules specified, include all modules if test "x$with_included_modules" = xyes ; then - included_modules="arabic,devanagari,basic,hangul,tamil,thai" + included_modules="arabic,basic,hangul,indic,tamil,thai" else included_modules="$with_included_modules" fi @@ -125,8 +125,8 @@ AC_SUBST(INCLUDED_MODULES) AM_CONDITIONAL(INCLUDE_ARABIC,echo $included_modules | grep '\(^\|,\)arabic\($\|,\)' > /dev/null) AM_CONDITIONAL(INCLUDE_BASIC,echo $included_modules | grep '\(^\|,\)basic\($\|,\)' > /dev/null) -AM_CONDITIONAL(INCLUDE_DEVANAGARI,echo $included_modules | grep '\(^\|,\)devanagari\($\|,\)' > /dev/null) AM_CONDITIONAL(INCLUDE_HANGUL,echo $included_modules | grep '\(^\|,\)hangul\($\|,\)' > /dev/null) +AM_CONDITIONAL(INCLUDE_INDIC,echo $included_modules | grep '\(^\|,\)indic\($\|,\)' > /dev/null) AM_CONDITIONAL(INCLUDE_TAMIL,echo $included_modules | grep '\(^\|,\)tamil\($\|,\)' > /dev/null) AM_CONDITIONAL(INCLUDE_THAI,echo $included_modules | grep '\(^\|,\)thai\($\|,\)' > /dev/null) @@ -265,8 +265,8 @@ modules/Makefile modules/arabic/Makefile modules/basic/Makefile modules/basic/makefile.mingw -modules/devanagari/Makefile modules/hangul/Makefile +modules/indic/Makefile modules/tamil/Makefile modules/thai/Makefile examples/Makefile diff --git a/docs/TEXT/ligatures b/docs/TEXT/ligatures new file mode 100644 index 00000000..6bc7e45f --- /dev/null +++ b/docs/TEXT/ligatures @@ -0,0 +1,33 @@ +PANGO_LIGATURE_HACK is defined as follows + +It comprises a space-seperated list of elements. An +element can either be of the form :xx:zzzz, in which +case the first part is a language code and the second +is a name of another property to look in if the +language is matched. + +or as follows + + $AAAA=0000+007F-0915,0944 + + This defines a set, this will be visible to the entire font. + +or of the form + + xxxx[+xxxx[+xxxx...]]=yyyy[+yyyy] + + xxxx can either be a hex glyph code which is matches directly, + or %AAAA, where it will match anything in the set. + + yyyy is either a hex glyph code, or %n, in which case it refers + to the nth thing to have matched - e.g. + + %FOO+2=2+%1, would swap instances of $FOO and 2. + + + +(The language-specific stuff isn't implemented yet, but is parsed OK + and duly ignored here. This will be implemented soon) + + +Robert Brady <rwb197@zepler.org>, 2000-11-08 diff --git a/examples/HELLO.utf8 b/examples/HELLO.utf8 index 281c1be1..eb759b70 100644 --- a/examples/HELLO.utf8 +++ b/examples/HELLO.utf8 @@ -5,7 +5,10 @@ This is a list of ways to say hello in various languages. Its purpose is to illu (Converted into UTF-8) --------------------------------------------------------- -Arabic السلام عليكم +Arabic السلام عليكم +Bengali (বাঙ্লা) ষাগতোম +Burmese (မ္ရန္မာ) +Cherokee (ᏣᎳᎩ) ᎣᏏᏲ Czech (česky) Dobrý den Danish (Dansk) Hej, Goddag English Hello @@ -16,22 +19,26 @@ Finnish (Suomi) Hei French (Français) Bonjour, Salut German (Deutsch Nord) Guten Tag German (Deutsch Süd) Grüß Gott +Georgian (ქართველი) გამარჯობა +Gujarati (ગુજરાતિ) Greek (Ελληνικά) Γειά σας Hebrew שלום Hindi नमस्ते, नमस्कार। Italiano Ciao, Buon giorno +ɪŋglɪʃ hɛləʊ Maltese Ċaw, Saħħa Nederlands, Vlaams Hallo, Dag Norwegian (Norsk) Hei, God dag +Punjabi (ੁਪੁਂਜਾਬਿ) Polish Dzień dobry, Hej -Russian (Русский) Здравствуйте! +Russian (Русский) Здравствуйте! Slovak Dobrý deň Spanish (Español) ¡Hola! Swedish (Svenska) Hej, Goddag Thai (ภาษาไทย) สวัสดีครับ, สวัสดีค่ะ Turkish (Türkçe) Merhaba Vietnamese (Tiếng Việt) Xin Chào -Yiddish (ײַדישע) דאָס הײַזעלע +Yiddish (ײַדישע) דאָס הײַזעלע Japanese (日本語) こんにちは, コンニチハ Chinese (中文,普通话,汉语) 你好 diff --git a/examples/pangox.aliases b/examples/pangox.aliases index 8d5f65e1..ab9995e7 100644 --- a/examples/pangox.aliases +++ b/examples/pangox.aliases @@ -3,12 +3,19 @@ # family style variant weight stretch XLFD sans normal normal normal normal "-*-helvetica-medium-r-normal--*-*-*-*-*-*-*-*,\ - -*-clearlyu-medium-r-normal--*-*-*-*-*-*-iso10646-1,\ - -*-fixed-medium-r-normal--*-*-*-*-*-*-*-*,\ + -*-clearlyu-medium-r-normal--*-*-*-*-*-*-iso10646-1,\ + -*-fixed-medium-r-normal--*-*-*-*-*-*-*-*,\ -kaist-iyagi-bold-r-normal--*-*-*-*-*-*-johab-1,\ -*-song ti-medium-r-normal--*-*-*-*-*-*-*-*,\ -tamil-tscakaram-medium-r-normal--*-*-*-*-*-*-tscii-0,\ - -*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev" +-*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev,\ +-*-gujarati-medium-r-normal--*-*-*-*-*-*-iso10646-guj,\ +-*-gurmukhi-medium-r-normal--*-*-*-*-*-*-iso10646-gur,\ +-*-bengali-medium-r-normal--*-*-*-*-*-*-iso10646-bng,\ +-*-kannada-medium-r-normal--*-*-*-*-*-*-iso10646-kan,\ +-*-burmese-medium-r-normal--*-*-*-*-*-*-iso10646-brm,\ +-*-buginese-medium-r-normal--*-*-*-*-*-*-iso10646-bgn,\ +-*-oriya-medium-r-normal--*-*-*-*-*-*-iso10646-ori" serif normal normal normal normal "-*-times-medium-r-normal--*-*-*-*-*-*-*-*,\ -*-clearlyu-medium-r-normal--*-*-*-*-*-*-iso10646-1,\ @@ -16,11 +23,25 @@ serif normal normal normal normal "-*-times-medium-r-normal--*-*-*-*-*-*-*-*,\ -kaist-iyagi-bold-r-normal--*-*-*-*-*-*-johab-1,\ -*-song ti-medium-r-normal--*-*-*-*-*-*-*-*,\ -tamil-tscakaram-medium-r-normal--*-*-*-*-*-*-tscii-0,\ - -*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev" +-*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev,\ +-*-gujarati-medium-r-normal--*-*-*-*-*-*-iso10646-guj,\ +-*-gurmukhi-medium-r-normal--*-*-*-*-*-*-iso10646-gur,\ +-*-bengali-medium-r-normal--*-*-*-*-*-*-iso10646-bng,\ +-*-kannada-medium-r-normal--*-*-*-*-*-*-iso10646-kan,\ +-*-burmese-medium-r-normal--*-*-*-*-*-*-iso10646-brm,\ +-*-buginese-medium-r-normal--*-*-*-*-*-*-iso10646-bgn,\ +-*-oriya-medium-r-normal--*-*-*-*-*-*-iso10646-ori" monospace normal normal normal normal "-*-fixed-medium-r-normal--*-*-*-*-*-*-*-*,\ -*-clearlyu-medium-r-normal--*-*-*-*-*-*-iso10646-1,\ -kaist-iyagi-bold-r-normal--*-*-*-*-*-*-johab-1,\ -*-song ti-medium-r-normal--*-*-*-*-*-*-*-*,\ -tamil-tscakaram-medium-r-normal--*-*-*-*-*-*-tscii-0,\ - -*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev" +-*-devanagari-medium-r-normal--*-*-*-*-*-*-iso10646-dev,\ +-*-gujarati-medium-r-normal--*-*-*-*-*-*-iso10646-guj,\ +-*-gurmukhi-medium-r-normal--*-*-*-*-*-*-iso10646-gur,\ +-*-bengali-medium-r-normal--*-*-*-*-*-*-iso10646-bng,\ +-*-kannada-medium-r-normal--*-*-*-*-*-*-iso10646-kan,\ +-*-burmese-medium-r-normal--*-*-*-*-*-*-iso10646-brm,\ +-*-buginese-medium-r-normal--*-*-*-*-*-*-iso10646-bgn,\ +-*-oriya-medium-r-normal--*-*-*-*-*-*-iso10646-ori" diff --git a/fonts/devnag.README b/fonts/devnag.README index 55331fbc..b03664a8 100644 --- a/fonts/devnag.README +++ b/fonts/devnag.README @@ -1,12 +1,4 @@ -This is a font that Mark Leisher put together for using Devanagari -with Unicode. To quote from http://crl.NMSU.Edu/~mleisher/devnag.html: - - This font is freeware. - - This font is a variation of the freely available XDVNG fonts put - together by Sandeep Sibal. Only the 18pt size is available from CRL at - the moment. Glyphs have been added and rearranged to fit our local - Unicode toolkit. - - The font is basically an 18 point, 75dpi font with around 200 glyphs. +This font has gone away, see pango-fonts now. +This is available from http://susu.org.uk/~robert/pango-fonts.tar.gz +(and the pango-fonts module in CVS) diff --git a/fonts/devnag18.bdf b/fonts/devnag18.bdf deleted file mode 100644 index c7245515..00000000 --- a/fonts/devnag18.bdf +++ /dev/null @@ -1,3907 +0,0 @@ -STARTFONT 2.1 -FONT -Sibal-Devanagari-Medium-R-Normal--18-18-75-75-P-100-ISO10646-DEV -SIZE 1 75 75 -FONTBOUNDINGBOX 31 26 -7 -8 -STARTPROPERTIES 17 -POINT_SIZE 18 -PIXEL_SIZE 18 -RESOLUTION_X 75 -RESOLUTION_Y 75 -FONT_ASCENT 20 -FONT_DESCENT 10 -AVERAGE_WIDTH 100 -SPACING "P" -_XMBDFED_INFO "Edited with xmbdfed 4.2." -FOUNDRY "Sibal" -FAMILY_NAME "Devanagari" -WEIGHT_NAME "Medium" -SLANT "R" -SETWIDTH_NAME "Normal" -ADD_STYLE_NAME "" -CHARSET_REGISTRY "ISO10646" -CHARSET_ENCODING "DEV" -ENDPROPERTIES -CHARS 196 -STARTCHAR U+0901 -ENCODING 2305 -SWIDTH 4800 0 -DWIDTH 5 0 -BBX 6 5 0 13 -BITMAP -20 -F4 -A4 -4C -38 -ENDCHAR -STARTCHAR U+0902 -ENCODING 2306 -SWIDTH 2880 0 -DWIDTH 3 0 -BBX 3 3 0 14 -BITMAP -40 -E0 -40 -ENDCHAR -STARTCHAR U+0903 -ENCODING 2307 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 5 11 1 0 -BITMAP -20 -70 -F8 -70 -20 -00 -20 -70 -F8 -70 -20 -ENDCHAR -STARTCHAR U+0905 -ENCODING 2309 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 17 13 1 -1 -BITMAP -7DFF00 -FEFF80 -C33000 -033000 -0F3000 -BE3000 -BFF000 -43F000 -633000 -3F3000 -1E3000 -003000 -001000 -ENDCHAR -STARTCHAR U+0906 -ENCODING 2310 -SWIDTH 21120 0 -DWIDTH 22 0 -BBX 23 13 1 -1 -BITMAP -7DFFFC -FEFFFE -C330C0 -0330C0 -0F30C0 -BE30C0 -BFF0C0 -43F0C0 -6330C0 -3F30C0 -1E30C0 -0030C0 -001040 -ENDCHAR -STARTCHAR U+0907 -ENCODING 2311 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 12 14 -1 -2 -BITMAP -FFE0 -7FF0 -0600 -3E00 -7E00 -6000 -7E00 -3F00 -3B00 -7F00 -3E00 -0200 -0100 -0180 -ENDCHAR -STARTCHAR U+0908 -ENCODING 2312 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 12 19 -1 -2 -BITMAP -0700 -0F00 -0C80 -0C00 -0400 -FFE0 -7FF0 -0600 -3E00 -7E00 -6000 -7E00 -3F00 -3B00 -7F00 -3E00 -0200 -0100 -0180 -ENDCHAR -STARTCHAR U+0909 -ENCODING 2313 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 13 12 -1 0 -BITMAP -FFF0 -7FF8 -00C0 -00C0 -01C0 -5F80 -4F80 -6080 -20C0 -30C0 -1FC0 -0F80 -ENDCHAR -STARTCHAR U+090A -ENCODING 2314 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 18 12 -1 0 -BITMAP -FFFF80 -7FFFC0 -00C000 -00C000 -01C000 -5FF800 -4FFC00 -60C400 -20C600 -30CE00 -1FCC00 -0F8C00 -ENDCHAR -STARTCHAR U+090B -ENCODING 2315 -SWIDTH 17280 0 -DWIDTH 18 0 -BBX 19 13 -1 -1 -BITMAP -FFFFC0 -7FFFE0 -018000 -3D8C00 -7F8E00 -63FE00 -03FE00 -0F8600 -3F8E00 -199E00 -019800 -018E00 -008F00 -ENDCHAR -STARTCHAR U+090C -ENCODING 2316 -SWIDTH 15360 0 -DWIDTH 16 0 -BBX 17 14 -1 -2 -BITMAP -FFFF00 -7FFF80 -003000 -003000 -3CF000 -7FF800 -638800 -630C00 -211C00 -307800 -10F000 -18C000 -0CF800 -007C00 -ENDCHAR -STARTCHAR U+090D -ENCODING 2317 -SWIDTH 12480 0 -DWIDTH 13 0 -BBX 14 24 -1 -6 -BITMAP -0420 -0420 -0260 -01C0 -0000 -0000 -FFF8 -7FFC -6180 -6180 -6180 -6180 -6180 -6180 -6780 -3300 -1C00 -0E00 -0380 -01C0 -0060 -0060 -00E0 -0040 -ENDCHAR -STARTCHAR U+090E -ENCODING 2318 -SWIDTH 12480 0 -DWIDTH 13 0 -BBX 14 24 -1 -6 -BITMAP -4000 -6000 -3E00 -1F00 -0180 -0080 -FFF8 -7FFC -6180 -6180 -6180 -6180 -6180 -6180 -6780 -3300 -1C00 -0E00 -0380 -01C0 -0060 -0060 -00E0 -0040 -ENDCHAR -STARTCHAR U+090F -ENCODING 2319 -SWIDTH 12480 0 -DWIDTH 13 0 -BBX 14 18 -1 -6 -BITMAP -FFF8 -7FFC -6180 -6180 -6180 -6180 -6180 -6180 -6780 -3300 -1C00 -0E00 -0380 -01C0 -0060 -0060 -00E0 -0040 -ENDCHAR -STARTCHAR U+0910 -ENCODING 2320 -SWIDTH 12480 0 -DWIDTH 13 0 -BBX 14 24 -1 -6 -BITMAP -7000 -3C00 -0E00 -0300 -0180 -0080 -FFF8 -7FFC -6180 -6180 -6180 -6180 -6180 -6180 -6780 -3300 -1C00 -0E00 -0380 -01C0 -0060 -0060 -00E0 -0040 -ENDCHAR -STARTCHAR U+0911 -ENCODING 2321 -SWIDTH 21120 0 -DWIDTH 22 0 -BBX 23 19 0 -1 -BITMAP -000210 -000210 -000130 -0000E0 -000000 -000000 -7DFFFC -FEFFFE -C330C0 -0330C0 -0F30C0 -BE30C0 -BFF0C0 -43F0C0 -6330C0 -3F30C0 -1E30C0 -0030C0 -001040 -ENDCHAR -STARTCHAR U+0912 -ENCODING 2322 -SWIDTH 21120 0 -DWIDTH 22 0 -BBX 23 19 0 -1 -BITMAP -002000 -003000 -001F00 -000F80 -0000C0 -000040 -7DFFFC -FEFFFE -C330C0 -0330C0 -0F30C0 -BE30C0 -BFF0C0 -43F0C0 -6330C0 -3F30C0 -1E30C0 -0030C0 -001040 -ENDCHAR -STARTCHAR U+0913 -ENCODING 2323 -SWIDTH 21120 0 -DWIDTH 22 0 -BBX 23 19 0 -1 -BITMAP -003800 -001E00 -000700 -000180 -0000C0 -000040 -7DFFFC -FEFFFE -C330C0 -0330C0 -0F30C0 -BE30C0 -BFF0C0 -43F0C0 -6330C0 -3F30C0 -1E30C0 -0030C0 -001040 -ENDCHAR -STARTCHAR U+0914 -ENCODING 2324 -SWIDTH 21120 0 -DWIDTH 22 0 -BBX 23 19 0 -1 -BITMAP -003C00 -001E00 -007B00 -003F00 -000780 -0001C0 -7DFFFC -FEFFFE -C330C0 -0330C0 -0F30C0 -BE30C0 -BFF0C0 -43F0C0 -6330C0 -3F30C0 -1E30C0 -0030C0 -001040 -ENDCHAR -STARTCHAR U+0915 -ENCODING 2325 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 16 13 -1 -1 -BITMAP -FFFE -7FFF -0300 -3FE0 -7FF0 -6398 -6318 -3F18 -1F18 -0338 -0330 -0310 -0100 -ENDCHAR -STARTCHAR U+0916 -ENCODING 2326 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 18 13 -1 -1 -BITMAP -FFFF80 -7FFFC0 -181800 -1BD800 -5FF800 -7E3800 -7E3800 -323800 -13F800 -19F800 -0C3800 -07F800 -03E800 -ENDCHAR -STARTCHAR U+0917 -ENCODING 2327 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 16 13 -1 -1 -BITMAP -FFFE -7FFF -1860 -1860 -1860 -1860 -7860 -7860 -7860 -3860 -0060 -0060 -0020 -ENDCHAR -STARTCHAR U+0918 -ENCODING 2328 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 16 13 -1 -1 -BITMAP -FFFE -7FFF -6060 -6060 -3E60 -7E60 -61E0 -3FE0 -1F60 -0060 -0060 -0060 -0020 -ENDCHAR -STARTCHAR U+0919 -ENCODING 2329 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 16 11 -1 1 -BITMAP -FFFE -7FFF -0180 -0F80 -1F90 -1838 -5F90 -6FC0 -60C0 -3FC0 -1F80 -ENDCHAR -STARTCHAR U+091A -ENCODING 2330 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 16 13 -1 -1 -BITMAP -FFFE -7FFF -0060 -0060 -7FE0 -7FE0 -1860 -08E0 -0FE0 -0760 -0060 -0060 -0020 -ENDCHAR -STARTCHAR U+091B -ENCODING 2331 -SWIDTH 17280 0 -DWIDTH 18 0 -BBX 19 13 -1 -1 -BITMAP -FFFFC0 -7FFFE0 -1C0C00 -3E1C00 -363E00 -203300 -371300 -1F9B00 -1F0F00 -180E00 -087E00 -0FFA00 -07C300 -ENDCHAR -STARTCHAR U+091C -ENCODING 2332 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 18 13 -1 -1 -BITMAP -FFFF80 -7FFFC0 -001800 -001800 -4FF800 -67F800 -231800 -311800 -199800 -0F9800 -071800 -001800 -000800 -ENDCHAR -STARTCHAR U+091D -ENCODING 2333 -SWIDTH 17280 0 -DWIDTH 18 0 -BBX 19 15 -1 -3 -BITMAP -FFFFC0 -7FFFE0 -030C00 -3F0C00 -7F0C00 -603C00 -7FFC00 -3FEC00 -3D8C00 -7F8C00 -3F0C00 -010C00 -018400 -008000 -008000 -ENDCHAR -STARTCHAR U+091E -ENCODING 2334 -SWIDTH 15360 0 -DWIDTH 16 0 -BBX 17 13 -1 -1 -BITMAP -FFFF00 -7FFF80 -003000 -383000 -3C3000 -063000 -07F000 -47F000 -6E3000 -7C3000 -383000 -003000 -001000 -ENDCHAR -STARTCHAR U+091F -ENCODING 2335 -SWIDTH 12480 0 -DWIDTH 13 0 -BBX 14 12 -1 0 -BITMAP -FFF8 -7FFC -0180 -0180 -1F80 -3F80 -7000 -6000 -6000 -60C0 -3FE0 -1F80 -ENDCHAR -STARTCHAR U+0920 -ENCODING 2336 -SWIDTH 12480 0 -DWIDTH 13 0 -BBX 14 12 -1 0 -BITMAP -FFF8 -7FFC -0180 -0180 -1F80 -3FC0 -7040 -6060 -2060 -30E0 -1FC0 -0F80 -ENDCHAR -STARTCHAR U+0921 -ENCODING 2337 -SWIDTH 12480 0 -DWIDTH 13 0 -BBX 14 11 -1 1 -BITMAP -FFF8 -7FFC -0180 -0F80 -1F80 -1800 -5F80 -6FC0 -60C0 -3FC0 -1F80 -ENDCHAR -STARTCHAR U+0922 -ENCODING 2338 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 13 12 -1 0 -BITMAP -FFF0 -7FF8 -0180 -1F80 -3F80 -7000 -6380 -67C0 -2EC0 -3CC0 -1FC0 -0F80 -ENDCHAR -STARTCHAR U+0923 -ENCODING 2339 -SWIDTH 15360 0 -DWIDTH 16 0 -BBX 17 13 -1 -1 -BITMAP -FFFF00 -7FFF80 -663000 -663000 -663000 -663000 -663000 -263000 -3E3000 -1C3000 -003000 -003000 -001000 -ENDCHAR -STARTCHAR U+0924 -ENCODING 2340 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 15 13 -1 -1 -BITMAP -FFFC -7FFE -00C0 -00C0 -3FC0 -7FC0 -60C0 -60C0 -60C0 -20C0 -30C0 -18C0 -0C40 -ENDCHAR -STARTCHAR U+0925 -ENCODING 2341 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 15 13 0 -1 -BITMAP -67FC -F7FE -D0C0 -F8C0 -78C0 -F1C0 -E1C0 -43C0 -7FC0 -3EC0 -00C0 -00C0 -0040 -ENDCHAR -STARTCHAR U+0926 -ENCODING 2342 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 13 12 -1 0 -BITMAP -FFF0 -7FF8 -0300 -3F00 -7F00 -6000 -6000 -6300 -2780 -3F80 -1F00 -0180 -ENDCHAR -STARTCHAR U+0927 -ENCODING 2343 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 15 13 0 -1 -BITMAP -47FC -E7FE -C0C0 -C0C0 -7CC0 -FCC0 -C3C0 -7FC0 -3EC0 -00C0 -00C0 -00C0 -0040 -ENDCHAR -STARTCHAR U+0928 -ENCODING 2344 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 15 13 -1 -1 -BITMAP -FFFC -7FFE -00C0 -00C0 -00C0 -3FC0 -7FC0 -78C0 -30C0 -00C0 -00C0 -00C0 -0040 -ENDCHAR -STARTCHAR U+0929 -ENCODING 2345 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 15 13 -1 -1 -BITMAP -FFFC -7FFE -00C0 -00C0 -00C0 -3FC0 -7FC0 -78C0 -30C0 -00C0 -08C0 -1CC0 -0840 -ENDCHAR -STARTCHAR U+092A -ENCODING 2346 -SWIDTH 12480 0 -DWIDTH 13 0 -BBX 14 13 -1 -1 -BITMAP -FFF8 -7FFC -6180 -6180 -6180 -2180 -3380 -1F80 -0F80 -0180 -0180 -0180 -0080 -ENDCHAR -STARTCHAR U+092B -ENCODING 2347 -SWIDTH 15360 0 -DWIDTH 16 0 -BBX 17 13 -1 -1 -BITMAP -FFFF00 -7FFF80 -618000 -61F000 -61F800 -21CC00 -338C00 -1F8C00 -0F8C00 -019C00 -019800 -018800 -008000 -ENDCHAR -STARTCHAR U+092C -ENCODING 2348 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 15 13 -1 -1 -BITMAP -FFFC -7FFE -00C0 -1EC0 -3FC0 -79C0 -6DC0 -65C0 -3FC0 -1FC0 -00C0 -00C0 -0040 -ENDCHAR -STARTCHAR U+092D -ENCODING 2349 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 16 13 0 -1 -BITMAP -E3FE -F3FF -5060 -7860 -3860 -1860 -7FE0 -7FE0 -3860 -1060 -0060 -0060 -0020 -ENDCHAR -STARTCHAR U+092E -ENCODING 2350 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 16 13 -1 -1 -BITMAP -FFFE -7FFF -3060 -3060 -3060 -3060 -FFE0 -FFE0 -7060 -0060 -0060 -0060 -0020 -ENDCHAR -STARTCHAR U+092F -ENCODING 2351 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 16 13 -1 -1 -BITMAP -FFFE -7FFF -0860 -0C60 -1C60 -78E0 -70E0 -21E0 -3FE0 -1F60 -0060 -0060 -0020 -ENDCHAR -STARTCHAR U+0930 -ENCODING 2352 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 13 13 -1 -1 -BITMAP -FFF0 -7FF8 -0300 -0300 -2700 -3600 -1E00 -1C00 -0C00 -0600 -0300 -0180 -00C0 -ENDCHAR -STARTCHAR U+0931 -ENCODING 2353 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 13 13 -1 -1 -BITMAP -FFF0 -7FF8 -0300 -0300 -2700 -3600 -1E00 -1C00 -0C00 -0600 -1300 -3980 -10C0 -ENDCHAR -STARTCHAR U+0932 -ENCODING 2354 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 18 13 -1 -1 -BITMAP -FFFF80 -7FFFC0 -001800 -001800 -3CF800 -7FF800 -639800 -631800 -211800 -301800 -101800 -181800 -0C0800 -ENDCHAR -STARTCHAR U+0933 -ENCODING 2355 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 18 12 -1 0 -BITMAP -FFFF80 -7FFFC0 -001800 -001800 -3C7800 -7EFC00 -63C400 -638600 -630600 -278600 -3EFE00 -1C7C00 -ENDCHAR -STARTCHAR U+0934 -ENCODING 2356 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 18 15 -1 -3 -BITMAP -FFFF80 -7FFFC0 -001800 -001800 -3C7800 -7EFC00 -63C400 -638600 -630600 -278600 -3EFE00 -1C7C00 -010000 -038000 -010000 -ENDCHAR -STARTCHAR U+0935 -ENCODING 2357 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 15 13 -1 -1 -BITMAP -FFFC -7FFE -00C0 -1EC0 -3FC0 -71C0 -61C0 -61C0 -3FC0 -1FC0 -00C0 -00C0 -0040 -ENDCHAR -STARTCHAR U+0936 -ENCODING 2358 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 18 13 -1 -1 -BITMAP -FFFF80 -7FFFC0 -391800 -319800 -319800 -1F9800 -0F9800 -7F1800 -7E1800 -3E1800 -031800 -011800 -018800 -ENDCHAR -STARTCHAR U+0937 -ENCODING 2359 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 15 13 -1 -1 -BITMAP -FFFC -7FFE -70C0 -68C0 -64C0 -23C0 -33C0 -1FC0 -0EC0 -00C0 -00C0 -00C0 -0040 -ENDCHAR -STARTCHAR U+0938 -ENCODING 2360 -SWIDTH 15360 0 -DWIDTH 16 0 -BBX 17 13 -1 -1 -BITMAP -FFFF00 -7FFF80 -183000 -183000 -587000 -7FF000 -7FF000 -203000 -303000 -103000 -083000 -0C3000 -041000 -ENDCHAR -STARTCHAR U+0939 -ENCODING 2361 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 13 16 -1 -4 -BITMAP -FFF0 -7FF8 -0300 -3F00 -7F00 -6000 -2F00 -3F80 -78C0 -60C0 -27C0 -3380 -1C00 -0F00 -03C0 -00C0 -ENDCHAR -STARTCHAR U+093C -ENCODING 2364 -SWIDTH 2880 0 -DWIDTH 3 0 -BBX 3 3 0 -3 -BITMAP -40 -E0 -40 -ENDCHAR -STARTCHAR U+093D -ENCODING 2365 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 9 13 0 -1 -BITMAP -3F00 -7F80 -6000 -6000 -2000 -3800 -1C00 -8600 -C200 -C300 -4700 -7E00 -3C00 -ENDCHAR -STARTCHAR U+093E -ENCODING 2366 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 8 13 -1 -1 -BITMAP -FE -7F -60 -60 -60 -60 -60 -60 -60 -60 -60 -60 -20 -ENDCHAR -STARTCHAR U+093F -ENCODING 2367 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 11 19 -1 -1 -BITMAP -3E00 -7F80 -61C0 -6060 -6000 -6000 -FE00 -7F00 -6000 -6000 -6000 -6000 -6000 -6000 -6000 -6000 -6000 -6000 -2000 -ENDCHAR -STARTCHAR U+0940 -ENCODING 2368 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 14 19 -7 -1 -BITMAP -3C00 -7E00 -E200 -C300 -C100 -0180 -03F8 -01FC -0180 -0180 -0180 -0180 -0180 -0180 -0180 -0180 -0180 -0180 -0080 -ENDCHAR -STARTCHAR U+0941 -ENCODING 2369 -SWIDTH 7680 0 -DWIDTH 8 0 -BBX 8 4 0 -4 -BITMAP -8E -49 -31 -0F -ENDCHAR -STARTCHAR U+0942 -ENCODING 2370 -SWIDTH 7680 0 -DWIDTH 8 0 -BBX 8 5 0 -5 -BITMAP -F0 -88 -84 -42 -39 -ENDCHAR -STARTCHAR U+0943 -ENCODING 2371 -SWIDTH 5760 0 -DWIDTH 6 0 -BBX 6 4 0 -4 -BITMAP -78 -C0 -80 -7C -ENDCHAR -STARTCHAR U+0944 -ENCODING 2372 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 7 7 0 -7 -BITMAP -78 -C0 -80 -FC -80 -86 -7C -ENDCHAR -STARTCHAR U+0945 -ENCODING 2373 -SWIDTH 5760 0 -DWIDTH 6 0 -BBX 6 4 0 14 -BITMAP -84 -84 -4C -38 -ENDCHAR -STARTCHAR U+0946 -ENCODING 2374 -SWIDTH 7680 0 -DWIDTH 8 0 -BBX 8 6 0 12 -BITMAP -80 -C0 -7C -3E -03 -01 -ENDCHAR -STARTCHAR U+0947 -ENCODING 2375 -SWIDTH 7680 0 -DWIDTH 8 0 -BBX 8 6 0 12 -BITMAP -E0 -78 -1C -06 -03 -01 -ENDCHAR -STARTCHAR U+0948 -ENCODING 2376 -SWIDTH 8640 0 -DWIDTH 9 0 -BBX 9 6 0 12 -BITMAP -7800 -3C00 -F600 -7E00 -0F00 -0380 -ENDCHAR -STARTCHAR U+0949 -ENCODING 2377 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 9 19 -2 -1 -BITMAP -8400 -8400 -4C00 -3800 -0000 -0000 -7F00 -3F80 -3000 -3000 -3000 -3000 -3000 -3000 -3000 -3000 -3000 -3000 -1000 -ENDCHAR -STARTCHAR U+094A -ENCODING 2378 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 13 19 -6 -1 -BITMAP -8000 -C000 -7C00 -3E00 -0300 -0100 -07F0 -03F8 -0300 -0300 -0300 -0300 -0300 -0300 -0300 -0300 -0300 -0300 -0100 -ENDCHAR -STARTCHAR U+094B -ENCODING 2379 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 13 19 -6 -1 -BITMAP -E000 -7800 -1C00 -0400 -0200 -0300 -07F0 -03F8 -0300 -0300 -0300 -0300 -0300 -0300 -0300 -0300 -0300 -0300 -0100 -ENDCHAR -STARTCHAR U+094C -ENCODING 2380 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 13 19 -6 -1 -BITMAP -7800 -3C00 -E600 -7A00 -1F00 -0700 -07F0 -03F8 -0300 -0300 -0300 -0300 -0300 -0300 -0300 -0300 -0300 -0300 -0100 -ENDCHAR -STARTCHAR U+094D -ENCODING 2381 -SWIDTH 5760 0 -DWIDTH 6 0 -BBX 6 4 0 -4 -BITMAP -E0 -78 -18 -04 -ENDCHAR -STARTCHAR U+0950 -ENCODING 2384 -SWIDTH 17280 0 -DWIDTH 18 0 -BBX 17 15 0 -1 -BITMAP -000800 -001D00 -008980 -00C180 -F86380 -FC3F00 -061E00 -060000 -3E3E00 -3FFF00 -01E180 -C18780 -618F80 -3F8C00 -1F0400 -ENDCHAR -STARTCHAR U+0951 -ENCODING 2385 -SWIDTH 1920 0 -DWIDTH 2 0 -BBX 2 6 0 12 -BITMAP -C0 -C0 -C0 -C0 -C0 -C0 -ENDCHAR -STARTCHAR U+0952 -ENCODING 2386 -SWIDTH 5760 0 -DWIDTH 6 0 -BBX 6 1 0 -1 -BITMAP -FC -ENDCHAR -STARTCHAR U+0953 -ENCODING 2387 -SWIDTH 3840 0 -DWIDTH 4 0 -BBX 4 6 0 12 -BITMAP -C0 -C0 -E0 -60 -30 -10 -ENDCHAR -STARTCHAR U+0954 -ENCODING 2388 -SWIDTH 3840 0 -DWIDTH 4 0 -BBX 4 6 0 12 -BITMAP -30 -30 -70 -60 -C0 -80 -ENDCHAR -STARTCHAR U+0958 -ENCODING 2392 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 16 13 -1 -1 -BITMAP -FFFE -7FFF -0300 -3FE0 -7FF0 -6398 -6318 -3F18 -1F18 -0338 -1330 -3B10 -1100 -ENDCHAR -STARTCHAR U+0959 -ENCODING 2393 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 18 17 -1 -5 -BITMAP -FFFF80 -7FFFC0 -181800 -1BD800 -5FF800 -7E3800 -7E3800 -323800 -13F800 -19F800 -0C3800 -07F800 -03E800 -000000 -010000 -038000 -010000 -ENDCHAR -STARTCHAR U+095A -ENCODING 2394 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 16 14 -1 -2 -BITMAP -FFFE -7FFF -1060 -1860 -1860 -1860 -7860 -7860 -7860 -3860 -0060 -1060 -3820 -1000 -ENDCHAR -STARTCHAR U+095B -ENCODING 2395 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 18 13 -1 -1 -BITMAP -FFFF80 -7FFFC0 -001800 -001800 -4FD800 -67F800 -231800 -311800 -199800 -0F9800 -075800 -00F800 -004800 -ENDCHAR -STARTCHAR U+095C -ENCODING 2396 -SWIDTH 12480 0 -DWIDTH 13 0 -BBX 14 15 -1 -3 -BITMAP -FFF8 -7FFC -0180 -0F80 -1F80 -1800 -5F80 -6FC0 -60C0 -3FC0 -1F80 -0000 -0200 -0700 -0200 -ENDCHAR -STARTCHAR U+095D -ENCODING 2397 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 13 16 -1 -4 -BITMAP -FFF0 -7FF8 -0180 -1F80 -3F80 -7000 -6380 -67C0 -2EC0 -3CC0 -1FC0 -0F80 -0000 -0200 -0700 -0200 -ENDCHAR -STARTCHAR U+095E -ENCODING 2398 -SWIDTH 15360 0 -DWIDTH 16 0 -BBX 17 13 -1 -1 -BITMAP -FFFF00 -7FFF80 -618000 -61F000 -61F800 -21CC00 -338C00 -5F8C00 -EF8C00 -4F9C00 -199800 -318800 -008000 -ENDCHAR -STARTCHAR U+095F -ENCODING 2399 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 16 14 -1 -2 -BITMAP -FFFE -7FFF -0860 -0C60 -1C60 -78E0 -70E0 -21E0 -3FE0 -1F60 -0060 -0460 -0E20 -0400 -ENDCHAR -STARTCHAR U+0960 -ENCODING 2400 -SWIDTH 17280 0 -DWIDTH 18 0 -BBX 19 16 -1 -4 -BITMAP -FFFFC0 -7FFFE0 -00C000 -3ECC00 -7FCE00 -61FE00 -03FE00 -0FC600 -1ECE00 -18DE00 -00DA00 -00CF00 -004E00 -000C00 -000F80 -000780 -ENDCHAR -STARTCHAR U+0961 -ENCODING 2401 -SWIDTH 15360 0 -DWIDTH 16 0 -BBX 17 17 -1 -5 -BITMAP -FFFF00 -7FFF80 -003000 -003000 -3CF000 -7FF800 -638800 -630C00 -211C00 -307800 -10F000 -18C000 -0CF800 -007C00 -006000 -003C00 -001E00 -ENDCHAR -STARTCHAR U+0962 -ENCODING 2402 -SWIDTH 8640 0 -DWIDTH 9 0 -BBX 9 6 0 -6 -BITMAP -7600 -8900 -8900 -4200 -0280 -0180 -ENDCHAR -STARTCHAR U+0963 -ENCODING 2403 -SWIDTH 9600 0 -DWIDTH 10 0 -BBX 10 7 0 -7 -BITMAP -7600 -8900 -8900 -4200 -0180 -0200 -01C0 -ENDCHAR -STARTCHAR U+0964 -ENCODING 2404 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 2 13 6 -1 -BITMAP -80 -C0 -C0 -C0 -C0 -C0 -C0 -C0 -C0 -C0 -C0 -C0 -40 -ENDCHAR -STARTCHAR U+0965 -ENCODING 2405 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 6 13 4 -1 -BITMAP -88 -CC -CC -CC -CC -CC -CC -CC -CC -CC -CC -CC -44 -ENDCHAR -STARTCHAR U+0966 -ENCODING 2406 -SWIDTH 8640 0 -DWIDTH 9 0 -BBX 7 7 0 2 -BITMAP -78 -FC -C4 -C6 -46 -7E -3C -ENDCHAR -STARTCHAR U+0967 -ENCODING 2407 -SWIDTH 7680 0 -DWIDTH 8 0 -BBX 6 16 0 -4 -BITMAP -70 -F8 -C8 -CC -CC -7C -3C -38 -70 -E0 -40 -60 -30 -18 -1C -18 -ENDCHAR -STARTCHAR U+0968 -ENCODING 2408 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 9 14 0 -3 -BITMAP -FE00 -FF00 -0180 -0180 -0380 -EF00 -FE00 -7800 -0C00 -0400 -0200 -0300 -0100 -0180 -ENDCHAR -STARTCHAR U+0969 -ENCODING 2409 -SWIDTH 9600 0 -DWIDTH 10 0 -BBX 8 14 0 -3 -BITMAP -F8 -FC -06 -FE -7E -07 -03 -63 -7F -3E -0C -04 -02 -03 -ENDCHAR -STARTCHAR U+096A -ENCODING 2410 -SWIDTH 12480 0 -DWIDTH 13 0 -BBX 11 11 0 1 -BITMAP -8040 -C0E0 -63C0 -3780 -1E00 -1C00 -3A00 -3300 -3300 -1F00 -0E00 -ENDCHAR -STARTCHAR U+096B -ENCODING 2411 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 10 14 0 -2 -BITMAP -8200 -C700 -C600 -C600 -4600 -7E00 -3C00 -0C00 -1C00 -7800 -FE00 -6700 -0180 -00C0 -ENDCHAR -STARTCHAR U+096C -ENCODING 2412 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 9 15 0 -3 -BITMAP -7C00 -FE00 -C000 -C000 -E400 -7E00 -7C00 -6000 -6600 -2700 -3F00 -1E00 -0300 -0100 -0180 -ENDCHAR -STARTCHAR U+096D -ENCODING 2413 -SWIDTH 12480 0 -DWIDTH 13 0 -BBX 11 12 0 0 -BITMAP -8000 -C780 -CFC0 -CC40 -CC60 -C460 -47E0 -63E0 -20E0 -31C0 -1F80 -0F00 -ENDCHAR -STARTCHAR U+096E -ENCODING 2414 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 10 11 -1 -1 -BITMAP -FF80 -7FC0 -7000 -6000 -6000 -6000 -6780 -7FC0 -3CC0 -01C0 -0080 -ENDCHAR -STARTCHAR U+096F -ENCODING 2415 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 9 15 0 -3 -BITMAP -7000 -F800 -CC00 -CC00 -5C00 -7800 -3000 -1000 -1800 -0C00 -0600 -0300 -0100 -0380 -0300 -ENDCHAR -STARTCHAR U+0970 -ENCODING 2416 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 6 6 3 5 -BITMAP -78 -C4 -84 -84 -8C -78 -ENDCHAR -STARTCHAR U+E900 -ENCODING 59648 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 17 14 0 -2 -BITMAP -79FF00 -FDFF80 -C63000 -C67000 -DEF000 -7FF000 -FFB000 -C03000 -CE3000 -4F3000 -7F3000 -3E3000 -031000 -010000 -ENDCHAR -STARTCHAR U+E901 -ENCODING 59649 -SWIDTH 12480 0 -DWIDTH 13 0 -BBX 15 13 -1 -1 -BITMAP -FFFC -7FFE -00C0 -7FC0 -7FC0 -18C0 -0CC0 -04C0 -76C0 -7EC0 -3CC0 -04C0 -0640 -ENDCHAR -STARTCHAR U+E902 -ENCODING 59650 -SWIDTH 15360 0 -DWIDTH 16 0 -BBX 18 13 -1 -1 -BITMAP -FFFF80 -7FFFC0 -001800 -001800 -7FF800 -7FF800 -181800 -181800 -181800 -081800 -0C1800 -071800 -030800 -ENDCHAR -STARTCHAR U+E903 -ENCODING 59651 -SWIDTH 12480 0 -DWIDTH 13 0 -BBX 15 13 -1 -1 -BITMAP -FFFC -7FFE -00C0 -3CC0 -7EC0 -63C0 -03C0 -0FC0 -3EC0 -18C0 -00C0 -00C0 -0040 -ENDCHAR -STARTCHAR U+00C1 -ENCODING 59652 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 19 13 -1 -1 -BITMAP -FFFFC0 -7FFFE0 -330C00 -130C00 -1F0C00 -7FCC00 -70EC00 -1FBC00 -0FFC00 -063C00 -067C00 -07EC00 -03C400 -ENDCHAR -STARTCHAR U+00C2 -ENCODING 59653 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 19 13 -1 -1 -BITMAP -FFFFC0 -7FFFE0 -330C00 -330C00 -1F0C00 -7FEC00 -70FC00 -01EC00 -03CC00 -070C00 -060C00 -000C00 -000400 -ENDCHAR -STARTCHAR U+00C3 -ENCODING 59654 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 19 13 -1 -1 -BITMAP -FFFFC0 -7FFFE0 -330C00 -330C00 -1F0C00 -7FEC00 -73FC00 -07BC00 -067C00 -07EC00 -03CC00 -000C00 -000400 -ENDCHAR -STARTCHAR U+0915 -ENCODING 59655 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 16 13 -1 -1 -BITMAP -FFFE -7FFF -0300 -3FE0 -7FF0 -6398 -6318 -3F18 -1F18 -0F38 -1B30 -3310 -0100 -ENDCHAR -STARTCHAR U+0024 -ENCODING 59656 -SWIDTH 17280 0 -DWIDTH 18 0 -BBX 20 13 -1 -1 -BITMAP -FFFFE0 -7FFFF0 -000600 -000600 -47FE00 -67FE00 -630600 -218600 -318E00 -1F9E00 -0F3600 -006600 -000200 -ENDCHAR -STARTCHAR U+0025 -ENCODING 59657 -SWIDTH 17280 0 -DWIDTH 18 0 -BBX 20 13 -1 -1 -BITMAP -FFFFE0 -7FFFF0 -000600 -000600 -47FE00 -67FE00 -634600 -21E600 -31CE00 -1F9E00 -0F3600 -006600 -000200 -ENDCHAR -STARTCHAR U+0027 -ENCODING 59658 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 17 13 -1 -1 -BITMAP -FFFF00 -7FFF80 -618000 -61F000 -61F800 -21CC00 -338C00 -1F8C00 -0F8C00 -1D9C00 -319800 -618800 -008000 -ENDCHAR -STARTCHAR U+0028 -ENCODING 59659 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 17 13 -1 -1 -BITMAP -FFFF00 -7FFF80 -618000 -61F000 -61F800 -21CC00 -338C00 -5F8C00 -EF8C00 -4F9C00 -199800 -318800 -008000 -ENDCHAR -STARTCHAR U+0029 -ENCODING 59660 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 13 13 -1 -1 -BITMAP -FFF0 -7FF8 -6300 -6300 -6300 -6300 -2300 -3F00 -1F00 -1B00 -3300 -6300 -0100 -ENDCHAR -STARTCHAR U+002B -ENCODING 59661 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 16 13 -1 -1 -BITMAP -FFFE -7FFF -1860 -1860 -5860 -7FE0 -7FE0 -20E0 -31E0 -13E0 -0F60 -0E60 -0420 -ENDCHAR -STARTCHAR U+002C -ENCODING 59662 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 14 13 -1 -1 -BITMAP -FFF8 -7FFC -0180 -0380 -2380 -3740 -1E40 -1CC0 -0C80 -0600 -0300 -0180 -00C0 -ENDCHAR -STARTCHAR U+002D -ENCODING 59663 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 16 13 -1 -1 -BITMAP -FFFE -7FFF -0300 -0300 -27C0 -3620 -1E10 -1D08 -0CE4 -0600 -0300 -0180 -00C0 -ENDCHAR -STARTCHAR U+E915 -ENCODING 59669 -SWIDTH 9600 0 -DWIDTH 10 0 -BBX 12 13 -1 -1 -BITMAP -FFE0 -7FF0 -0300 -3F00 -7FE0 -63E0 -6310 -3F00 -1F00 -0300 -0300 -0300 -0100 -ENDCHAR -STARTCHAR U+E916 -ENCODING 59670 -SWIDTH 9600 0 -DWIDTH 10 0 -BBX 12 13 -1 -1 -BITMAP -FFE0 -7FF0 -1800 -1BC0 -5FE0 -7E20 -7E30 -3230 -13F0 -19E0 -0C00 -0600 -0300 -ENDCHAR -STARTCHAR U+E917 -ENCODING 59671 -SWIDTH 7680 0 -DWIDTH 8 0 -BBX 10 10 -1 2 -BITMAP -FF80 -7FC0 -1800 -1800 -1800 -1800 -7800 -7800 -7800 -3800 -ENDCHAR -STARTCHAR U+E918 -ENCODING 59672 -SWIDTH 7680 0 -DWIDTH 8 0 -BBX 10 9 -1 3 -BITMAP -FF80 -7FC0 -6000 -6000 -3E00 -7E00 -61C0 -3F80 -1F00 -ENDCHAR -STARTCHAR U+E919 -ENCODING 59673 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 16 11 -1 1 -BITMAP -FFFE -7FFF -0180 -0F80 -1F90 -1838 -5F90 -6FC0 -60C0 -3FC0 -1F80 -ENDCHAR -STARTCHAR U+E91A -ENCODING 59674 -SWIDTH 8640 0 -DWIDTH 9 0 -BBX 11 10 -1 2 -BITMAP -FFC0 -7FE0 -0000 -0000 -7F80 -7FC0 -1800 -08E0 -0FE0 -0780 -ENDCHAR -STARTCHAR U+E91B -ENCODING 59675 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 19 13 -1 -1 -BITMAP -FFFFC0 -7FFFE0 -180C00 -7E1C00 -763E00 -203300 -371300 -1F9B00 -1F0F00 -180E00 -087E00 -0FFA00 -07C300 -ENDCHAR -STARTCHAR U+E91C -ENCODING 59676 -SWIDTH 9600 0 -DWIDTH 10 0 -BBX 12 11 -1 1 -BITMAP -FFE0 -7FF0 -0000 -0000 -4FE0 -67F0 -2300 -3100 -1980 -0F80 -0700 -ENDCHAR -STARTCHAR U+E91D -ENCODING 59677 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 13 15 -1 -3 -BITMAP -FFF0 -7FF8 -0300 -3F00 -7F00 -6030 -7FF8 -3FE0 -3D80 -7F80 -3F00 -0100 -0180 -0080 -0080 -ENDCHAR -STARTCHAR U+E91E -ENCODING 59678 -SWIDTH 8640 0 -DWIDTH 9 0 -BBX 11 11 -1 1 -BITMAP -FFC0 -7FE0 -0000 -3800 -3C00 -0600 -07E0 -47E0 -6E00 -7C00 -3800 -ENDCHAR -STARTCHAR U+E91F -ENCODING 59679 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 14 12 -1 0 -BITMAP -FFF8 -7FFC -0180 -0180 -1F80 -3F80 -7000 -6000 -6000 -60C0 -3FE0 -1F80 -ENDCHAR -STARTCHAR U+E920 -ENCODING 59680 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 14 12 -1 0 -BITMAP -FFF8 -7FFC -0180 -0180 -1F80 -3FC0 -7040 -6060 -2060 -30E0 -1FC0 -0F80 -ENDCHAR -STARTCHAR U+E921 -ENCODING 59681 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 14 11 -1 1 -BITMAP -FFF8 -7FFC -0180 -0F80 -1F80 -1800 -5F80 -6FC0 -60C0 -3FC0 -1F80 -ENDCHAR -STARTCHAR U+E922 -ENCODING 59682 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 13 12 -1 0 -BITMAP -FFF0 -7FF8 -0180 -1F80 -3F80 -7000 -6380 -67C0 -2EC0 -3CC0 -1FC0 -0F80 -ENDCHAR -STARTCHAR U+E923 -ENCODING 59683 -SWIDTH 7680 0 -DWIDTH 8 0 -BBX 10 10 -1 2 -BITMAP -FF80 -7FC0 -6600 -6600 -6600 -6600 -6600 -2600 -3E00 -1C00 -ENDCHAR -STARTCHAR U+E924 -ENCODING 59684 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 9 13 -1 -1 -BITMAP -FF00 -7F80 -0000 -0000 -3F00 -7F80 -6000 -6000 -6000 -2000 -3000 -1800 -0C00 -ENDCHAR -STARTCHAR U+E925 -ENCODING 59685 -SWIDTH 7680 0 -DWIDTH 8 0 -BBX 9 10 0 2 -BITMAP -6700 -F780 -D000 -F800 -7800 -F100 -E180 -4380 -7F00 -3E00 -ENDCHAR -STARTCHAR U+E926 -ENCODING 59686 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 13 12 -1 0 -BITMAP -FFF0 -7FF8 -0300 -3F00 -7F00 -6000 -6000 -6300 -2780 -3F80 -1F00 -0180 -ENDCHAR -STARTCHAR U+E927 -ENCODING 59687 -SWIDTH 7680 0 -DWIDTH 8 0 -BBX 9 9 0 3 -BITMAP -4700 -E780 -C000 -C000 -7C00 -FC00 -C380 -7F00 -3E00 -ENDCHAR -STARTCHAR U+E928 -ENCODING 59688 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 9 9 -1 3 -BITMAP -FF00 -7F80 -0000 -0000 -0000 -3F00 -7F80 -7800 -3000 -ENDCHAR -STARTCHAR U+E929 -ENCODING 59689 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 9 13 -1 -1 -BITMAP -FF00 -7F80 -0000 -0000 -0000 -3F00 -7F80 -7800 -3000 -0000 -0400 -0E00 -0400 -ENDCHAR -STARTCHAR U+E92A -ENCODING 59690 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 9 9 -1 3 -BITMAP -FF00 -7F80 -6000 -6000 -6000 -2100 -3380 -1F00 -0E00 -ENDCHAR -STARTCHAR U+E92B -ENCODING 59691 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 13 13 -1 -1 -BITMAP -FFF0 -7FF8 -6180 -6180 -61E0 -21F0 -3398 -1F80 -0F80 -0180 -0180 -0180 -0080 -ENDCHAR -STARTCHAR U+E92C -ENCODING 59692 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 9 10 -1 2 -BITMAP -FF00 -7F80 -0000 -1E00 -3F00 -7980 -6D80 -6580 -3F80 -1F00 -ENDCHAR -STARTCHAR U+E92D -ENCODING 59693 -SWIDTH 7680 0 -DWIDTH 8 0 -BBX 10 10 -1 2 -BITMAP -E380 -F3C0 -5000 -7800 -3800 -1800 -7F80 -7FC0 -3800 -1000 -ENDCHAR -STARTCHAR U+E92E -ENCODING 59694 -SWIDTH 7680 0 -DWIDTH 8 0 -BBX 10 9 -1 3 -BITMAP -FF80 -7FC0 -3000 -3000 -3000 -3000 -FF80 -FFC0 -7000 -ENDCHAR -STARTCHAR U+E92F -ENCODING 59695 -SWIDTH 7680 0 -DWIDTH 8 0 -BBX 10 10 -1 2 -BITMAP -FF80 -7FC0 -0800 -0C00 -1C00 -7880 -70C0 -21C0 -3F80 -1F00 -ENDCHAR -STARTCHAR U+E930 -ENCODING 59696 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 13 13 -1 -1 -BITMAP -FFF0 -7FF8 -0300 -0300 -2700 -3600 -1E00 -1C00 -0C00 -0600 -0300 -0180 -00C0 -ENDCHAR -STARTCHAR U+E931 -ENCODING 59697 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 13 13 0 -1 -BITMAP -FFF0 -7FF8 -0300 -0300 -2700 -3600 -1E00 -1C00 -0C00 -0600 -1300 -3980 -10C0 -ENDCHAR -STARTCHAR U+E932 -ENCODING 59698 -SWIDTH 9600 0 -DWIDTH 10 0 -BBX 12 13 -1 -1 -BITMAP -FFE0 -7FF0 -0000 -0000 -3CE0 -7FF0 -6380 -6300 -2100 -3000 -1000 -1800 -0C00 -ENDCHAR -STARTCHAR U+E933 -ENCODING 59699 -SWIDTH 12480 0 -DWIDTH 13 0 -BBX 15 12 -1 0 -BITMAP -FFFC -7FFE -0000 -0000 -3C78 -7EFC -63C4 -6386 -6306 -278E -3FFC -1C78 -ENDCHAR -STARTCHAR U+E934 -ENCODING 59700 -SWIDTH 12480 0 -DWIDTH 13 0 -BBX 15 15 -1 -3 -BITMAP -FFFC -7FFE -0000 -0000 -3C78 -7EFC -63C4 -6386 -6306 -278E -3FFC -1C78 -0100 -0380 -0100 -ENDCHAR -STARTCHAR U+E935 -ENCODING 59701 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 9 10 -1 2 -BITMAP -FF00 -7F80 -0000 -1E00 -3F00 -7180 -6180 -6180 -3F80 -1F00 -ENDCHAR -STARTCHAR U+E936 -ENCODING 59702 -SWIDTH 9600 0 -DWIDTH 10 0 -BBX 12 13 -1 -1 -BITMAP -FFE0 -7FF0 -3900 -3180 -3180 -1F80 -0F80 -7F00 -7E00 -3E00 -0300 -0100 -0180 -ENDCHAR -STARTCHAR U+005C -ENCODING 59703 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 9 9 -1 3 -BITMAP -FF00 -7F80 -7000 -6800 -6400 -2300 -3380 -1F00 -0E00 -ENDCHAR -STARTCHAR U+E938 -ENCODING 59704 -SWIDTH 8640 0 -DWIDTH 9 0 -BBX 11 13 -1 -1 -BITMAP -FFC0 -7FE0 -1800 -1800 -5840 -7FE0 -7FC0 -2000 -3000 -1000 -0800 -0C00 -0400 -ENDCHAR -STARTCHAR U+E939 -ENCODING 59705 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 13 16 -1 -4 -BITMAP -FFF0 -7FF8 -0300 -3F00 -7F00 -6000 -2F00 -3F80 -78C0 -60C0 -27C0 -3380 -1C00 -0F00 -03C0 -00C0 -ENDCHAR -STARTCHAR U+0915 -ENCODING 59712 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 16 13 -1 -1 -BITMAP -FFFE -7FFF -0300 -3B60 -7FF0 -6398 -6F18 -3F70 -63F8 -6798 -7F18 -3B30 -0100 -ENDCHAR -STARTCHAR U+0924 -ENCODING 59713 -SWIDTH 15360 0 -DWIDTH 16 0 -BBX 18 13 -1 -1 -BITMAP -FFFF80 -7FFFC0 -00C000 -00C000 -FFF800 -7FFC00 -30C600 -30C600 -30C600 -10C600 -18CE00 -0CCC00 -064000 -ENDCHAR -STARTCHAR U+00A2 -ENCODING 59714 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 16 18 -1 -6 -BITMAP -FFFE -7FFF -00C0 -0FC0 -1FD0 -1838 -5FD0 -6FE0 -6060 -3FE0 -1FC0 -0300 -1B40 -3FE0 -2720 -3F60 -1B40 -0300 -ENDCHAR -STARTCHAR U+00A3 -ENCODING 59715 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 16 19 -1 -7 -BITMAP -FFFE -7FFF -00C0 -0FC0 -1FD0 -1838 -5FD0 -6FE0 -6060 -3FE0 -1FC0 -10C0 -37C0 -6CC0 -6CC0 -27C0 -30C0 -19C0 -0F40 -ENDCHAR -STARTCHAR U+00A4 -ENCODING 59716 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 16 19 -1 -7 -BITMAP -FFFE -7FFF -0180 -0F80 -1F90 -1838 -5F90 -6FC0 -60C0 -3FC0 -1F80 -0D80 -0D80 -0D80 -1D80 -1D80 -0180 -0180 -0080 -ENDCHAR -STARTCHAR U+00A5 -ENCODING 59717 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 16 19 -1 -7 -BITMAP -FFFE -7FFF -0180 -0F80 -1F90 -1838 -5F90 -6FC0 -60C0 -3FC0 -3F80 -3180 -1980 -3D80 -3380 -1F80 -0F80 -0180 -0080 -ENDCHAR -STARTCHAR U+091E -ENCODING 59718 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 17 13 -1 -1 -BITMAP -FFFF00 -7FFF80 -003000 -0E3000 -07F000 -33F000 -1F3000 -0E3000 -01F000 -21B000 -31B000 -1FB000 -0F1000 -ENDCHAR -STARTCHAR U+00B9 -ENCODING 59719 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 16 15 -1 -3 -BITMAP -FFFE -7FFF -0060 -07E0 -0FE0 -0C00 -1C00 -3C60 -2CF0 -27F0 -3FE0 -1C30 -0C78 -07E8 -03CC -ENDCHAR -STARTCHAR U+00B8 -ENCODING 59720 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 13 16 -1 -4 -BITMAP -FFF0 -7FF8 -0300 -3F00 -7F00 -6000 -6000 -3F00 -7F00 -6000 -6380 -3FC0 -1F80 -0180 -00C0 -0060 -ENDCHAR -STARTCHAR U+00B9 -ENCODING 59721 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 16 15 -1 -3 -BITMAP -FFFE -7FFF -0060 -07E0 -0FE0 -0C00 -6C00 -6C60 -64F0 -27F0 -3FE0 -1C30 -0C78 -07E8 -03CC -ENDCHAR -STARTCHAR U+00BA -ENCODING 59722 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 13 15 -1 -3 -BITMAP -FFF0 -7FF8 -0300 -3F00 -7F00 -6000 -6000 -6300 -2780 -3F80 -7F00 -6980 -65C0 -3F40 -1E60 -ENDCHAR -STARTCHAR U+00BB -ENCODING 59723 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 16 13 -1 -1 -BITMAP -FFFE -7FFF -0060 -07E0 -0FE0 -0C00 -67C0 -73E0 -1860 -0860 -3FF0 -3FF0 -1C18 -ENDCHAR -STARTCHAR U+00BC -ENCODING 59724 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 16 13 -1 -1 -BITMAP -FFFE -7FFF -0360 -3F60 -7F60 -6060 -3060 -1860 -3FE0 -3FE0 -1C60 -0060 -0020 -ENDCHAR -STARTCHAR U+00BD -ENCODING 59725 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 17 13 -1 -1 -BITMAP -FFFF00 -7FFF80 -033000 -3F3000 -7F3000 -603000 -603000 -263000 -3F3000 -1E3000 -0C7000 -07F000 -03D000 -ENDCHAR -STARTCHAR U+00BE -ENCODING 59726 -SWIDTH 10560 0 -DWIDTH 11 0 -BBX 13 15 -1 -3 -BITMAP -FFF0 -7FF8 -0300 -3F00 -7F00 -6000 -6000 -6300 -2780 -3F80 -7F00 -6380 -3FC0 -1E40 -0060 -ENDCHAR -STARTCHAR U+00AC -ENCODING 59727 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 14 17 -1 -5 -BITMAP -FFF8 -7FFC -0180 -1F80 -3F80 -7000 -6000 -61C0 -3FC0 -1F80 -0F80 -3F80 -7800 -6000 -60C0 -3FE0 -1F80 -ENDCHAR -STARTCHAR U+00AD -ENCODING 59728 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 14 18 -1 -6 -BITMAP -FFF8 -7FFC -0180 -1F80 -3F80 -7000 -6000 -61C0 -3FC0 -1F80 -0780 -3F80 -7C40 -6060 -6060 -60E0 -3FC0 -1F80 -ENDCHAR -STARTCHAR U+00AD -ENCODING 59729 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 14 18 -1 -6 -BITMAP -FFF8 -7FFC -0180 -1F80 -3FC0 -7060 -6060 -60E0 -3FC0 -1F80 -0180 -1F80 -3FC0 -7060 -6060 -60E0 -3FC0 -1F80 -ENDCHAR -STARTCHAR U+00A4 -ENCODING 59730 -SWIDTH 13440 0 -DWIDTH 14 0 -BBX 16 19 -1 -7 -BITMAP -FFFE -7FFF -0180 -0F80 -1F80 -1800 -5F80 -6FC0 -60C0 -3FC0 -1F80 -0D80 -0D80 -0D80 -1D80 -1D80 -0180 -0180 -0080 -ENDCHAR -STARTCHAR U+00B2 -ENCODING 59731 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 14 20 -1 -8 -BITMAP -FFF8 -7FFC -0180 -0F80 -1F80 -1C00 -4F00 -6380 -6180 -3F80 -1F80 -0180 -0F80 -1F80 -1C00 -4F00 -6380 -6180 -3F80 -1F00 -ENDCHAR -STARTCHAR U+00B2 -ENCODING 59732 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 14 20 -1 -8 -BITMAP -FFF8 -7FFC -0180 -0F80 -1F80 -1C00 -4F00 -6380 -6180 -3F80 -1F80 -0180 -1F80 -3F80 -6000 -6700 -6F80 -3980 -3F80 -1F00 -ENDCHAR -STARTCHAR U+00C0 -ENCODING 59733 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 16 13 -1 -1 -BITMAP -FFFE -7FFF -0060 -7C60 -7F60 -73E0 -31E0 -07E0 -1F60 -1C60 -1C60 -0C60 -0020 -ENDCHAR -STARTCHAR U+00C9 -ENCODING 59734 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 19 16 -1 -4 -BITMAP -FFFFC0 -7FFFE0 -018C00 -3F8C00 -7F8C00 -600C00 -3E0C00 -3F0C00 -718C00 -618C00 -23FC00 -33FC00 -1B8C00 -0F8C00 -070400 -018000 -ENDCHAR -STARTCHAR U+00CA -ENCODING 59735 -SWIDTH 16320 0 -DWIDTH 17 0 -BBX 19 16 -1 -4 -BITMAP -FFFFC0 -7FFFE0 -018C00 -3F8C00 -7F8C00 -600C00 -3E0C00 -3F0C00 -718C00 -618C00 -27BC00 -33FC00 -19EC00 -0E0C00 -070400 -018000 -ENDCHAR -STARTCHAR U+00CC -ENCODING 59736 -SWIDTH 19200 0 -DWIDTH 20 0 -BBX 22 16 -1 -4 -BITMAP -FFFFF8 -7FFFFC -0000C0 -003FC0 -007FC0 -002000 -003F80 -003FC0 -007860 -3FE060 -7FE3E0 -6733C0 -219C00 -38CF00 -1F03E0 -0780E0 -ENDCHAR -STARTCHAR U+00CD -ENCODING 59737 -SWIDTH 14400 0 -DWIDTH 15 0 -BBX 17 16 -1 -4 -BITMAP -FFFF00 -7FFF80 -001800 -07F800 -0FF800 -040000 -07F000 -07F800 -0F0C00 -0C0C00 -047C00 -3E7800 -7F8000 -61E000 -3FFC00 -1F1C00 -ENDCHAR -STARTCHAR U+002B -ENCODING 59738 -SWIDTH 17280 0 -DWIDTH 18 0 -BBX 20 13 -1 -1 -BITMAP -FFFFE0 -7FFFF0 -180600 -187600 -58FE00 -7ECE00 -3E0E00 -303E00 -18FE00 -0C6600 -060600 -030600 -018200 -ENDCHAR -STARTCHAR U+0078 -ENCODING 59760 -SWIDTH 8640 0 -DWIDTH 9 0 -BBX 11 14 0 -2 -BITMAP -79C0 -FDE0 -C600 -C640 -DEE0 -7FC0 -FF80 -C000 -CE00 -4F00 -7F00 -3E00 -0300 -0100 -ENDCHAR -STARTCHAR U+E901 -ENCODING 59761 -SWIDTH 12480 0 -DWIDTH 13 0 -BBX 15 13 -1 -1 -BITMAP -FFFC -7FFE -00C0 -7FC0 -7FC0 -18C0 -0CC0 -04C0 -76C0 -7EC0 -3CC0 -04C0 -0640 -ENDCHAR -STARTCHAR U+00B6 -ENCODING 59762 -SWIDTH 9600 0 -DWIDTH 10 0 -BBX 12 13 -1 -1 -BITMAP -FFE0 -7FF0 -0000 -0000 -7FE0 -7FF0 -1800 -1800 -1800 -0800 -0C00 -0700 -0300 -ENDCHAR -STARTCHAR U+002A -ENCODING 59763 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 9 10 -1 2 -BITMAP -FF00 -7F80 -0000 -3C00 -7E00 -6300 -0380 -0F80 -3E00 -1800 -ENDCHAR -STARTCHAR U+00C1 -ENCODING 59764 -SWIDTH 9600 0 -DWIDTH 10 0 -BBX 12 13 -1 -1 -BITMAP -FFE0 -7FF0 -3300 -1300 -1F00 -7FE0 -70E0 -3FB0 -1FF0 -0630 -0670 -07E0 -03C0 -ENDCHAR -STARTCHAR U+00C2 -ENCODING 59765 -SWIDTH 9600 0 -DWIDTH 10 0 -BBX 12 11 -1 1 -BITMAP -FFE0 -7FF0 -3300 -3300 -1F00 -7FE0 -70F0 -01E0 -03C0 -0700 -0600 -ENDCHAR -STARTCHAR U+00C3 -ENCODING 59766 -SWIDTH 9600 0 -DWIDTH 10 0 -BBX 12 11 -1 1 -BITMAP -FFE0 -7FF0 -3300 -3300 -1F00 -7FE0 -73F0 -07B0 -0670 -07E0 -03C0 -ENDCHAR -STARTCHAR char59728 -ENCODING 59771 -SWIDTH 4800 0 -DWIDTH 5 0 -BBX 5 5 0 12 -BITMAP -F0 -88 -B0 -40 -20 -ENDCHAR -STARTCHAR U+E939 -ENCODING 59772 -SWIDTH 11520 0 -DWIDTH 12 0 -BBX 13 16 -1 -4 -BITMAP -FFF0 -7FF8 -0300 -3F00 -7F00 -6000 -2F00 -3F80 -78C0 -60C0 -27C0 -3380 -1C00 -3F00 -63C0 -C0C0 -ENDCHAR -STARTCHAR U+0022 -ENCODING 59773 -SWIDTH 6720 0 -DWIDTH 7 0 -BBX 9 8 -1 4 -BITMAP -FF00 -7F80 -0000 -0000 -0000 -6100 -7F80 -1F00 -ENDCHAR -STARTCHAR char59728 -ENCODING 59774 -SWIDTH 4800 0 -DWIDTH 5 0 -BBX 5 5 0 12 -BITMAP -F0 -88 -80 -40 -20 -ENDCHAR -STARTCHAR U+00D7 -ENCODING 59775 -SWIDTH 5760 0 -DWIDTH 6 0 -BBX 6 5 0 -5 -BITMAP -20 -38 -64 -C0 -80 -ENDCHAR -ENDFONT diff --git a/modules/Makefile.am b/modules/Makefile.am index 80092322..3647c502 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -2,9 +2,9 @@ SUBDIRS = \ arabic \ - devanagari \ basic \ hangul \ + indic \ tamil \ thai diff --git a/modules/devanagari/Makefile.am b/modules/devanagari/Makefile.am deleted file mode 100644 index b050c95d..00000000 --- a/modules/devanagari/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -## Process this file with automake to create Makefile.in. - -sources = \ - devanagari.c \ - dev-ligatures.h - -if INCLUDE_DEVANAGARI -noinst_LTLIBRARIES = libpango-devanagari.la -moddefine = -DMODULE_PREFIX -else -moduledir = $(libdir)/pango/modules -module_LTLIBRARIES = pango-devanagari.la -endif - -INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/pango/ $(moddefine) - -pango_devanagari_la_LDFLAGS = -rpath $(libdir) -export-dynamic -avoid-version -module -pango_devanagari_la_SOURCES = $(sources) - -libpango_devanagari_la_SOURCES = $(sources) - diff --git a/modules/devanagari/dev-ligatures.h b/modules/devanagari/dev-ligatures.h deleted file mode 100644 index fff44ba7..00000000 --- a/modules/devanagari/dev-ligatures.h +++ /dev/null @@ -1,49 +0,0 @@ -/* ones marked with ! weren't used by CURender.java. The - mappings were worked out by staring at the Unicode code - charts for a long time. - */ - -{ 0xE900, { 0x0915, VIRAMA, 0x0937 } }, -{ 0xE901, { 0x091C, VIRAMA, 0x091E } }, -{ 0xE902, { 0x0924, VIRAMA, 0x0924 } }, -{ 0xE903, { 0x0924, VIRAMA, 0x0930 } }, -{ 0xE904, { 0x0936, VIRAMA, 0x091B } }, -{ 0xE905, { 0x0936, VIRAMA, 0x0930 } }, -{ 0xE906, { 0x0936, VIRAMA, 0x0935 } }, - -{ 0xE907, { 0x0915, VIRAMA, RA } }, -{ 0xE908, { 0x091C, VIRAMA, RA } }, -{ 0xE909, { 0x095B, VIRAMA, RA } }, -{ 0xE90A, { 0x092B, VIRAMA, RA } }, -{ 0xE90B, { 0x095E, VIRAMA, RA } }, -{ 0xE90C, { 0x092A, VIRAMA, RA } }, -{ 0xE90D, { 0x0938, VIRAMA, RA } }, - -{ 0xE940, { 0x0915, VIRAMA, 0x0915 } }, -{ 0xE941, { 0x0915, VIRAMA, 0x0924 } }, -{ 0xE942, { 0x0919, VIRAMA, 0x0915 } }, /* ! */ -{ 0xE943, { 0x0919, VIRAMA, 0x0916 } }, /* ! */ -{ 0xE944, { 0x0919, VIRAMA, 0x0917 } }, /* ! */ -{ 0xE945, { 0x0919, VIRAMA, 0x0918 } }, /* ! */ -{ 0xE946, { 0x091e, VIRAMA, 0x091e } }, /* ! */ -{ 0xE947, { 0x0926, VIRAMA, 0x0918 } }, -{ 0xE948, { 0x0926, VIRAMA, 0x0926 } }, /* ! */ -{ 0xE949, { 0x0926, VIRAMA, 0x0927 } }, -{ 0xE94A, { 0x0926, VIRAMA, 0x0937 } }, /* ! */ -{ 0xE94B, { 0x0926, VIRAMA, 0x092D } }, /* ! */ -{ 0xE94C, { 0x0926, VIRAMA, 0x092E } }, /* ! */ -{ 0xE94D, { 0x0926, VIRAMA, 0x092F } }, -{ 0xE94E, { 0x0926, VIRAMA, 0x0935 } }, -{ 0xE94F, { 0x091F, VIRAMA, 0x091F } }, -{ 0xE950, { 0x091F, VIRAMA, 0x0920 } }, -{ 0xE951, { 0x0920, VIRAMA, 0x0920 } }, /* ! */ -{ 0xE952, { 0x0921, VIRAMA, 0x0917 } }, -{ 0xE953, { 0x0921, VIRAMA, 0x0921 } }, /* ! */ -{ 0xE954, { 0x0921, VIRAMA, 0x0922 } }, /* ! */ -{ 0xE955, { 0x0928, VIRAMA, 0x0928 } }, -{ 0xE956, { 0x0939, VIRAMA, 0x092e } }, /* ! */ -{ 0xE957, { 0x0939, VIRAMA, 0x092f } }, /* ! */ -{ 0xE958, { 0x0939, VIRAMA, 0x0932 } }, /* ! */ -{ 0xE959, { 0x0939, VIRAMA, 0x0935 } }, /* ! */ -/* { 0xE95a, { 0x0939, VIRAMA, 0x0e903 } }, ! */ - diff --git a/modules/devanagari/devanagari.c b/modules/devanagari/devanagari.c deleted file mode 100644 index 7f3c1528..00000000 --- a/modules/devanagari/devanagari.c +++ /dev/null @@ -1,615 +0,0 @@ -/* Pango - Devanagari module - * devanagari.c: - * - * Copyright (C) 2000 Robert Brady <rwb197@zepler.org> - * - * 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 <glib.h> -#include <stdio.h> - -#include "pango.h" -#include "pangox.h" - -#define VIRAMA 0x94d -#define CANDRA 0x901 -#define ANUSWAR 0x902 -#define NUKTA 0x93c -#define RA 0x930 -#define JOINING_RA 0xe97f -#define REPHA 0xe97e -#define EYELASH_RA 0xe97d -#define RRA 0x931 - -#define U_S 0x941 -#define UU_S 0x942 - -typedef struct _LigData LigData; - -struct _LigData - { - int replacement; - int source[3]; - }; - -static LigData ligatures[] = -{ -#include "dev-ligatures.h" -}; - -static gint n_ligatures = G_N_ELEMENTS (ligatures); - -static char *default_charset[] = -{ - "iso10646-dev", - /* devanagari encoded in iso10646 way, with PUA used for - * ligatures and half forms */ -}; - -/* Table about ligatures in the font. This should come from the font - * somehow : this needs to be co-ordinated with fonts@xfree86.org. - * (and for whatever passes for a font working group at X.org) - */ - -static PangoEngineRange devanagari_range[] = -{ - {0x900, 0x97f, "*"} -}; - -static PangoEngineInfo script_engines[] = -{ - { - "DevanagariScriptEngineLang", - PANGO_ENGINE_TYPE_LANG, - PANGO_RENDER_TYPE_NONE, - devanagari_range, G_N_ELEMENTS (devanagari_range)}, - { - "DevanagariScriptEngineX", - PANGO_ENGINE_TYPE_SHAPE, - PANGO_RENDER_TYPE_X, - devanagari_range, G_N_ELEMENTS (devanagari_range)} -}; - -static gint n_script_engines = G_N_ELEMENTS (script_engines); - -static gboolean - find_unic_font (PangoFont * font, char *charsets[], PangoXSubfont * rfont); - -static PangoCoverage * -devanagari_engine_get_coverage (PangoFont * font, const char *lang) -{ - gunichar i; - PangoCoverage *result = pango_coverage_new (); - PangoXSubfont subfont; - - int dev_font = find_unic_font (font, default_charset, &subfont); - - if (dev_font) - { - for (i = 0x900; i < 0x97f; i++) - pango_coverage_set (result, i, PANGO_COVERAGE_EXACT); - } - - return result; -} - -static gboolean -find_unic_font (PangoFont * font, char *charsets[], PangoXSubfont * rfont) -{ - int n_subfonts; - int result = 0; - PangoXSubfont *subfonts; - int *subfont_charsets; - n_subfonts = pango_x_list_subfonts (font, charsets, 1, - &subfonts, &subfont_charsets); - - if (n_subfonts > 0) - { - rfont[0] = subfonts[0]; - result = 1; - } - - g_free (subfonts); - g_free (subfont_charsets); - return result; -} - -static int -is_ligating_consonant (int ch) -{ - /* false for 958 to 961, as these don't ligate in any way */ - return (ch >= 0x915 && ch <= 0x939); -} - -static int -is_comb_vowel (int i) -{ - /* one that combines, whether or not it spaces */ - return (i >= 0x93E && i <= 0x94c) || (i >= 0x962 && i <= 0x963); -} - -static int -vowelsign_to_letter (int i) -{ - if (i >= 0x93e && i <= 0x94c) - return i - 0x93e + 0x906; - return i; -} - -static int -is_half_consonant (int i) -{ - return (i >= 0xe915 && i <= 0xe939) || (i >= 0xe970 && i <= 0xe976); -} - -static int -is_consonant (int i) -{ - return (i >= 0x915 && i <= 0x939) || (i >= 0x958 && i <= 0x95f); -} - -static int -is_ind_vowel (int i) -{ - return (i >= 0x905 && i <= 0x914); -} - -static int -is_nonspacing_vowel (gunichar c) -{ - /* one that doesn't space. ie 93f and 940 don't count */ - return (c >= 0x941 && c <= 0x948) || (c >= 0x962 && c <= 0x963); -} - -static int -get_char (gunichar * chars, gunichar * end) -{ - if (chars >= end) - return 0; - return *chars; -} - -static void -devanagari_shift_vowels (gunichar * chars, gunichar * end) -{ - /* moves 0x93f (I) before consonant clusters where appropriate. */ - gunichar *strt = chars; - while (chars < end) - { - if (*chars == 0x93f && chars > strt) - { - gunichar *bubble = chars; - int i = 1; - - /* move back TO START! */ - - while (bubble > strt) - { - bubble[0] = bubble[-1]; - bubble[-1] = 0x93f; - i = 0; - bubble--; - } - } - chars++; - } -} - -void -devanagari_convert_vowels (int *num, gunichar * chars) -{ - /* goes along and converts matras to vowel letters if needed. - * this is only currently done at the beginning of the string. */ - gunichar *end = chars + *num; - gunichar *start = chars; - while (chars < end) - { - if ((chars == start && is_comb_vowel (chars[0])) || - (chars != start && is_comb_vowel (chars[0]) - && is_comb_vowel (chars[-1]))) - { - chars[0] = vowelsign_to_letter (chars[0]); - } - chars++; - } -} - -static void -devanagari_compact (int *num, gunichar * chars, gint * cluster) -{ - /* shuffle stuff up into the blanked out elements. */ - gunichar *dest = chars; - gunichar *end = chars + *num; - gint *cluster_dest = cluster; - while (chars < end) - { - if (*chars) - { - *dest = *chars; - *cluster_dest = *cluster; - dest++; - chars++; - cluster++; - cluster_dest++; - } - else - { - chars++; - cluster++; - } - } - *num -= (chars - dest); -} - -#if 0 -const char *foo[] = -{ - "k", "kh", "g", "gh", "ng", - "c", "ch", "j", "jh", "ny", - "tt", "tth", "dd", "ddh", "nn", - "t", "th", "d", "dh", "n", "nnn", - "p", "ph", "b", "bh", "m", - - "y", "r", "rr", "l", "ll", "lll", - - "v", "sh", "ss", "s", "h", - - "-", "-", "-", "-", - - "aa", - "i", "ii", - "u", "uu", - "[r]", "[rr]", - "[e]", "{e}", - "e", "ai", - "[o]", "{o}", - "o", "au", -}; - -const char *bar[] = -{ - "A", "AA", - "I", "II", - "U", "UU", - "[R]", "[RR]", - "[E]", "{E}", - "E", "AI", - "[O]", "{O}", - "O", "AU", -}; -#endif - -static void -devanagari_make_ligs (gunichar * start, gunichar * end, int *cluster) -{ - gunichar t0 = get_char (start, end); - gunichar t1 = get_char (start + 1, end); - gunichar t2 = get_char (start + 2, end); - gunichar t3 = get_char (start + 3, end); - - int i, j; - int repha = 0, ligature = 0; - - for (i = 0; i < (end - start); i++) - { - t0 = get_char (start + i, end); - t1 = get_char (start + 1 + i, end); - t2 = get_char (start + 2 + i, end); - t3 = get_char (start + 3 + i, end); - - if (!ligature) - { - for (j = 0; j < n_ligatures; j++) - { - /* handle the conjuncts */ - LigData *l = ligatures + j; - if (t0 == l->source[0] && t1 == l->source[1] - && t2 == l->source[2]) - { - start[i + 0] = 0; - start[i + 1] = 0; - start[i + 2] = l->replacement; - ligature = 1; - break; - } - } - if (j != n_ligatures) - continue; - } - - if ((t0 >= 0xe900 && t0 <= 0xe906) && t1 == VIRAMA - && is_ligating_consonant (t2)) - { - start[i + 1] = start[i] + 0x70; - start[i] = 0; - continue; - } - - if (is_consonant (t0) && t1 == VIRAMA && t2 == RA) - { - start[i + 1] = 0; - start[i + 2] = JOINING_RA; - continue; - } - - if (t0 == RRA && t1 == VIRAMA) - { - start[i] = 0; - start[i + 1] = EYELASH_RA; - continue; - } - - if (t0 == RA && t1 == VIRAMA && is_ligating_consonant (t2)) - { - - start[i + 0] = 0; - start[i + 1] = 0; - start[i + 2] = t2; - repha = 1; - continue; - } - - if (is_ligating_consonant (t0) && - t1 == VIRAMA && is_ligating_consonant (t2)) - { - start[i + 0] = t0 + 0xe000; - start[i + 1] = 0; - start[i + 2] = t2; - continue; - } - - if (t0 == RA && (t1 == U_S || t1 == UU_S)) - { - - if (t1 == U_S) - start[i + 1] = 0xe90e; - - if (t1 == UU_S) - start[i + 1] = 0xe90f; - - start[i] = 0; - - } - } - - for (i = 0; i < (end - start); i++) - { - t0 = get_char (start + i, end); - t1 = get_char (start + 1 + i, end); - t2 = get_char (start + 2 + i, end); - t3 = get_char (start + 3 + i, end); - } - - if (repha) - { - int src = 0, dest = 0; - while (src < (end - start)) - { - start[dest] = start[src]; - src++; - if (start[dest]) - dest++; - } - while (dest < (end - start)) - { - start[dest] = 0; - dest++; - } - end[-1] = REPHA; - } -} - -static void -devanagari_engine_shape (PangoFont * font, - const char *text, - int length, - PangoAnalysis * analysis, PangoGlyphString * glyphs) -{ - PangoXSubfont subfont; - - int n_chars, n_glyph; - int lvl; - const char *p; - int i; - gunichar *wc; - int sb; - int n_syls; - gunichar **syls = g_malloc (sizeof (gunichar **)); - - 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 = n_glyph = g_utf8_strlen (text, length); - lvl = find_unic_font (font, default_charset, &subfont); - if (!lvl) - { - PangoGlyph unknown_glyph = pango_x_get_unknown_glyph (font); - PangoRectangle logical_rect; - pango_font_get_glyph_extents (font, unknown_glyph, NULL, &logical_rect); - pango_glyph_string_set_size (glyphs, n_chars); - p = text; - for (i = 0; i < n_chars; i++) - { - glyphs->glyphs[i].glyph = unknown_glyph; - glyphs->glyphs[i].geometry.x_offset = 0; - glyphs->glyphs[i].geometry.y_offset = 0; - glyphs->glyphs[i].geometry.width = logical_rect.width; - glyphs->log_clusters[i] = 0; - - p = g_utf8_next_char (p); - } - return; - } - p = text; - wc = (gunichar *) g_malloc (sizeof (gunichar) * n_chars); - pango_glyph_string_set_size (glyphs, n_glyph); - for (i = 0; i < n_chars; i++) - { - wc[i] = g_utf8_get_char (p); - glyphs->log_clusters[i] = p - text; - p = g_utf8_next_char (p); - } - - devanagari_convert_vowels (&n_glyph, wc); - - n_syls = 1; - syls[0] = wc; - sb = glyphs->log_clusters[0]; - for (i = 0; i < n_chars; i++) - { - if (i && (is_consonant (wc[i]) | is_ind_vowel (wc[i])) - && wc[i - 1] != 0x94d) - { - syls = g_realloc (syls, ((n_syls + 2) * sizeof (gunichar **))); - syls[n_syls] = wc + i; - n_syls++; - sb = glyphs->log_clusters[i]; - } - glyphs->log_clusters[i] = sb; - } - syls[n_syls] = wc + i; - - for (i = 0; i < n_syls; i++) - { - devanagari_make_ligs (syls[i], syls[i + 1], glyphs->log_clusters + - (syls[i] - wc)); - devanagari_shift_vowels (syls[i], syls[i + 1]); - } - - devanagari_compact (&n_glyph, wc, glyphs->log_clusters); - - pango_glyph_string_set_size (glyphs, n_glyph); - - for (i = 0; i < n_glyph; i++) - { - PangoRectangle logical_rect; - glyphs->glyphs[i].glyph = PANGO_X_MAKE_GLYPH (subfont, wc[i]); - pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, - NULL, &logical_rect); - glyphs->glyphs[i].geometry.x_offset = 0; - glyphs->glyphs[i].geometry.y_offset = 0; - glyphs->glyphs[i].geometry.width = logical_rect.width; - - if (wc[i] == JOINING_RA || wc[i] == ANUSWAR || - wc[i] == REPHA || wc[i] == VIRAMA || wc[i] == CANDRA || - is_nonspacing_vowel (wc[i])) - { - if (wc[i] == VIRAMA) - { - glyphs->glyphs[i].geometry.x_offset = - (-glyphs->glyphs[i - 1].geometry.width / 2); - - if (!glyphs->glyphs[i].geometry.x_offset) - glyphs->glyphs[i].geometry.x_offset = - (-glyphs->glyphs[i - 2].geometry.width / 2); - } - else - glyphs->glyphs[i].geometry.x_offset = -logical_rect.width * 2; - - glyphs->glyphs[i].geometry.width = 0; - glyphs->log_clusters[i] = glyphs->log_clusters[i - 1]; - } - } - g_free (syls); -} - -static PangoEngine * -devanagari_engine_x_new () -{ - PangoEngineShape *result; - result = g_new (PangoEngineShape, 1); - result->engine.id = "DevanagariScriptEngine"; - result->engine.type = PANGO_ENGINE_TYPE_LANG; - result->engine.length = sizeof (result); - result->script_shape = devanagari_engine_shape; - result->get_coverage = devanagari_engine_get_coverage; - return (PangoEngine *) result; -} - -static void -devanagari_engine_break (const char *text, - int len, - PangoAnalysis * analysis, PangoLogAttr * attrs) -{ - const char *cur = text; - gint i = 0; - gunichar wc; - - while (*cur && cur - text < len) - { - wc = g_utf8_get_char (cur); - if (wc == (gunichar)-1) - break; /* FIXME: ERROR */ - - attrs[i].is_white = (wc == ' ' || wc == '\t' || wc == 'n') ? 1 : 0; - attrs[i].is_break = (i > 0 && attrs[i - 1].is_white) || - attrs[i].is_white; - attrs[i].is_char_stop = 1; - attrs[i].is_word_stop = (i == 0) || attrs[i - 1].is_white; - /* actually, is_word_stop in not correct, but simple and good enough. */ - - i++; - cur = g_utf8_next_char (cur); - } -} - - -static PangoEngine * -devanagari_engine_lang_new () -{ - PangoEngineLang *result; - - result = g_new (PangoEngineLang, 1); - - result->engine.id = "DevanagariScriptEngine"; - result->engine.type = PANGO_ENGINE_TYPE_LANG; - result->engine.length = sizeof (result); - result->script_break = devanagari_engine_break; - - return (PangoEngine *) result; -} - -#ifdef MODULE_PREFIX -#define MODULE_ENTRY(func) _pango_devanagari_##func -#else -#define MODULE_ENTRY(func) func -#endif - -void -MODULE_ENTRY(script_engine_list) (PangoEngineInfo ** engines, int *n_engines) -{ - *engines = script_engines; - *n_engines = n_script_engines; -} - -PangoEngine * -MODULE_ENTRY(script_engine_load) (const char *id) -{ - if (!strcmp (id, "DevanagariScriptEngineLang")) - return devanagari_engine_lang_new (); - else if (!strcmp (id, "DevanagariScriptEngineX")) - return devanagari_engine_x_new (); - else - return NULL; -} - -void -MODULE_ENTRY(script_engine_unload) (PangoEngine * engine) -{ -} diff --git a/modules/indic/.cvsignore b/modules/indic/.cvsignore new file mode 100644 index 00000000..6e5ca7ed --- /dev/null +++ b/modules/indic/.cvsignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +.deps +.libs +*.lo +*.la diff --git a/modules/indic/Makefile.am b/modules/indic/Makefile.am new file mode 100644 index 00000000..f593b566 --- /dev/null +++ b/modules/indic/Makefile.am @@ -0,0 +1,61 @@ +## Process this file with automake to create Makefile.in. + +sources = \ + myanmar.c \ + gurmukhi.c \ + bengali.c \ + gujarati.c \ + devanagari.c \ + pango-indic-script.h + +if INCLUDE_INDIC +noinst_LTLIBRARIES = libpango-myanmar.la libpango-gurmukhi.la \ + libpango-bengali.la \ + libpango-devanagari.la \ + libpango-gujarati.la +moddefine = -DMODULE_PREFIX +else +moduledir = $(libdir)/pango/modules +module_LTLIBRARIES = pango-myanmar.la pango-gurmukhi.la \ + pango-bengali.la \ + pango-devanagari.la \ + pango-gujarati.la +endif + +INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/pango/ $(moddefine) + +pango_devanagari_la_LDFLAGS = -rpath $(libdir) -export-dynamic -avoid-version -module +pango_devanagari_la_SOURCES = devanagari.c + +libpango_devanagari_la_SOURCES = devanagari.c + + +pango_myanmar_la_LDFLAGS = -rpath $(libdir) -export-dynamic -avoid-version -module +pango_myanmar_la_SOURCES = myanmar.c + +libpango_myanmar_la_SOURCES = myanmar.c + + +pango_gurmukhi_la_LDFLAGS = -rpath $(libdir) -export-dynamic -avoid-version -module +pango_gurmukhi_la_SOURCES = gurmukhi.c + +libpango_gurmukhi_la_SOURCES = gurmukhi.c + + + + +pango_bengali_la_LDFLAGS = -rpath $(libdir) -export-dynamic -avoid-version -module +pango_bengali_la_SOURCES = bengali.c + +libpango_bengali_la_SOURCES = bengali.c + + + + + + +pango_gujarati_la_LDFLAGS = -rpath $(libdir) -export-dynamic -avoid-version -module +pango_gujarati_la_SOURCES = gujarati.c + +libpango_gujarati_la_SOURCES = gujarati.c + diff --git a/modules/indic/bengali-x.c b/modules/indic/bengali-x.c new file mode 100644 index 00000000..05e430f3 --- /dev/null +++ b/modules/indic/bengali-x.c @@ -0,0 +1,359 @@ +/* Pango - Bengali module + * bengali.c: + * + * Copyright (C) 2000 Robert Brady, + * (C) 2000 SuSE Linux Ltd. + * + * Author: Robert Brady <rwb197@zepler.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * Licence as published by the Free Software Foundation; either + * version 2 of the licence, 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 + * Lesser General Public Licence for more details. + * + * You should have received a copy of the GNU Lesser General Public + * Licence along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * This is the renderer for Bengali script. + * + * This script is used to write many languages including the + * following. + * + * as Assamese + * bn Bengali + * kha Khasi + * mni Manipuri + * mun Munda + * sat Santali + * + */ + + +#include <glib.h> +#include <stdio.h> + +#include "pango.h" +#include "pangox.h" +#include "pango-indic.h" + +#define SCRIPT_STRING "Bengali" +#define ISCII_BASED +#define RANGE_START 0x980 +#define RANGE_SIZE 0x80 + +#include "pango-indic-script.h" + +static gboolean is_prefixing_vowel (gunichar i); +static gboolean is_vowel_sign (gunichar i); +static gboolean is_vowel_half (gunichar i); +static gunichar vowel_sign_to_matra (gunichar i); +static gboolean vowel_split (gunichar i, gunichar *a, gunichar *b); + +static PangoIndicScript script = { + SCRIPT_STRING, + &is_prefixing_vowel, + &is_vowel_sign, + &vowel_sign_to_matra, + &is_vowel_half, + &vowel_split, +}; + +static gunichar +vowel_sign_to_matra (gunichar i) +{ + if (!is_vowel_sign (i)) + return i; + return i + 0x987 - 0x9c8; +} + +gboolean +vowel_split (gunichar i, gunichar *a, gunichar *b) +{ + if (i == 0x9cb || i == 0x9cc) { + if (a) + *a = 0x9c7; + if (b) { + if (i == 0x9cc) + *b = 0xe9d7; + else + *b = 0xe9be; + } + return TRUE; + } + return FALSE; +} + +#define RA_SUPERSCRIPT 0xe9ff +#define RA_SUBSCRIPT 0xe9fe + +static char *default_charset = "iso10646-bng"; + +static PangoEngineRange pango_indic_range[] = +{ + {RANGE_START, RANGE_END, "*"}, +}; + +SCRIPT_ENGINE_DEFINITION + +static PangoCoverage * +pango_indic_engine_get_coverage (PangoFont * font, const char *lang) +{ + gunichar i; + PangoCoverage *result = pango_coverage_new (); + PangoXSubfont subfont; + + int dev_font = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + + if (dev_font) + { + for (i = RANGE_START; i <= RANGE_END; i++) + pango_coverage_set (result, i, PANGO_COVERAGE_EXACT); + + pango_coverage_set (result, 0x10000, PANGO_COVERAGE_EXACT); + } + + return result; +} + +static gboolean +is_vowel_sign (gunichar i) +{ + /* one that combines, whether or not it spaces */ + return (i >= 0x9BE && i <= 0x9Cc) || (i >= 0x9E2 && i <= 0x9E3); +} + +static int +is_consonant (int i) +{ + return (i >= 0x995 && i <= 0x9b9) || (i >= 0x9dc && i <= 0x9df) || (i >= 0x9f0 && i <= 0x09f1); +} + +static int +is_ind_vowel (int i) +{ + return (i >= 0x985 && i <= 0x994); +} + +static gboolean +is_vowel_half (gunichar i) +{ + return (i == 0xe9d7) || (i == 0xe9be) || (i == 0x9d7); +} + +static int +is_prefixing_vowel (gunichar what) +{ + return (what == 0x9bf) || (what == 0x9c7) || (what == 0x9c8); +} + +static void +pango_indic_make_ligs (gunichar * start, gunichar * end) +{ + int num = end - start; + int i; + + for (i = 0; i < (end - start); i++) + { + gunichar t0 = pango_indic_get_char (start + i, end); + gunichar t1 = pango_indic_get_char (start + 1 + i, end); + gunichar t2 = pango_indic_get_char (start + 2 + i, end); + + if ((t0 == VIRAMA) && (t1 == 0x9af)) + { + start[i+0] = 0; + start[i+1] = 0xe9fd; + } + } + + if (start[0] == RA && start[1] == VIRAMA && is_consonant (start[2])) + { + start[0] = 0; + start[1] = start[2]; + start[2] = RA_SUPERSCRIPT; + } + + for (i = 0; i < (end - start - 1); i++) + { + if (start[i] == VIRAMA) + { + if (start[i+1] == RA) + { + start[i] = 0; + start[i+1] = RA_SUBSCRIPT; + break; + } + } + } + +} + +static void +pango_indic_engine_shape (PangoFont * font, + const char *text, + int length, + PangoAnalysis * analysis, PangoGlyphString * glyphs) +{ + PangoXSubfont subfont; + + int n_chars, n_glyph; + int lvl; + const char *p; + int i, k; + gunichar *wc; + int sb; + int n_syls; + gunichar **syls = g_malloc (sizeof (gunichar **)); + 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 = n_glyph = g_utf8_strlen (text, length); + lvl = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + if (!lvl) + { + pango_x_fallback_shape (font, glyphs, text, n_chars); + return; + } + + pango_indic_split_out_characters (&script, text, n_chars, &wc, + &n_glyph, glyphs); + pango_indic_convert_vowels (&script, TRUE, &n_glyph, wc, + pango_x_has_glyph (font, + PANGO_X_MAKE_GLYPH (subfont, 0xc9bd))); + + n_syls = 1; + syls[0] = wc; + sb = glyphs->log_clusters[0]; + for (i = 0; i < n_glyph; i++) + { + if (i && (is_consonant (wc[i]) | is_ind_vowel (wc[i])) + && wc[i - 1] != VIRAMA) + { + syls = g_realloc (syls, ((n_syls + 2) * sizeof (gunichar **))); + syls[n_syls] = wc + i; + n_syls++; + sb = glyphs->log_clusters[i]; + } + glyphs->log_clusters[i] = sb; + } + syls[n_syls] = wc + i; + + for (i = 0; i < n_syls; i++) + { + pango_indic_make_ligs (syls[i], syls[i+1]); + pango_indic_shift_vowels (&script, syls[i], syls[i + 1]); + } + + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_x_apply_ligatures (font, subfont, &wc, &n_glyph, &glyphs->log_clusters); + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_glyph_string_set_size (glyphs, n_glyph); + + for (i = 0; i < n_glyph; i++) + { + PangoRectangle logical_rect; + glyphs->glyphs[i].glyph = PANGO_X_MAKE_GLYPH (subfont, wc[i]); + pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, + NULL, &logical_rect); + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + glyphs->glyphs[i].geometry.width = logical_rect.width; + } + g_free (syls); +} + +static PangoEngine * +pango_indic_engine_x_new () +{ + PangoEngineShape *result; + result = g_new (PangoEngineShape, 1); + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_shape = pango_indic_engine_shape; + result->get_coverage = pango_indic_engine_get_coverage; + return (PangoEngine *) result; +} + +static void +pango_indic_engine_break (const char *text, + int len, + PangoAnalysis * analysis, PangoLogAttr * attrs) +{ + const char *cur = text; + gint i = 0; + gunichar wc; + + while (*cur && cur - text < len) + { + wc = g_utf8_get_char (cur); + if (wc == (gunichar)-1) + break; /* FIXME: ERROR */ + + attrs[i].is_white = (wc == ' ' || wc == '\t' || wc == 'n') ? 1 : 0; + attrs[i].is_break = (i > 0 && attrs[i - 1].is_white) || + attrs[i].is_white; + attrs[i].is_char_stop = 1; + attrs[i].is_word_stop = (i == 0) || attrs[i - 1].is_white; + /* actually, is_word_stop in not correct, but simple and good enough. */ + + i++; + cur = g_utf8_next_char (cur); + } +} + + +static PangoEngine * +pango_indic_engine_lang_new () +{ + PangoEngineLang *result; + + result = g_new (PangoEngineLang, 1); + + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_break = pango_indic_engine_break; + + return (PangoEngine *) result; +} + +#ifdef MODULE_PREFIX +#define MODULE_ENTRY(func) _pango_pango_##func +#else +#define MODULE_ENTRY(func) func +#endif + +void +MODULE_ENTRY(script_engine_list) (PangoEngineInfo ** engines, int *n_engines) +{ + *engines = script_engines; + *n_engines = n_script_engines; +} + +PangoEngine * +MODULE_ENTRY(script_engine_load) (const char *id) +{ + if (!strcmp (id, SCRIPT_STRING "ScriptEngineLang")) + return pango_indic_engine_lang_new (); + else if (!strcmp (id, SCRIPT_STRING "ScriptEngineX")) + return pango_indic_engine_x_new (); + else + return NULL; +} + +void +MODULE_ENTRY(script_engine_unload) (PangoEngine * engine) +{ +} + diff --git a/modules/indic/bengali.c b/modules/indic/bengali.c new file mode 100644 index 00000000..05e430f3 --- /dev/null +++ b/modules/indic/bengali.c @@ -0,0 +1,359 @@ +/* Pango - Bengali module + * bengali.c: + * + * Copyright (C) 2000 Robert Brady, + * (C) 2000 SuSE Linux Ltd. + * + * Author: Robert Brady <rwb197@zepler.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * Licence as published by the Free Software Foundation; either + * version 2 of the licence, 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 + * Lesser General Public Licence for more details. + * + * You should have received a copy of the GNU Lesser General Public + * Licence along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * This is the renderer for Bengali script. + * + * This script is used to write many languages including the + * following. + * + * as Assamese + * bn Bengali + * kha Khasi + * mni Manipuri + * mun Munda + * sat Santali + * + */ + + +#include <glib.h> +#include <stdio.h> + +#include "pango.h" +#include "pangox.h" +#include "pango-indic.h" + +#define SCRIPT_STRING "Bengali" +#define ISCII_BASED +#define RANGE_START 0x980 +#define RANGE_SIZE 0x80 + +#include "pango-indic-script.h" + +static gboolean is_prefixing_vowel (gunichar i); +static gboolean is_vowel_sign (gunichar i); +static gboolean is_vowel_half (gunichar i); +static gunichar vowel_sign_to_matra (gunichar i); +static gboolean vowel_split (gunichar i, gunichar *a, gunichar *b); + +static PangoIndicScript script = { + SCRIPT_STRING, + &is_prefixing_vowel, + &is_vowel_sign, + &vowel_sign_to_matra, + &is_vowel_half, + &vowel_split, +}; + +static gunichar +vowel_sign_to_matra (gunichar i) +{ + if (!is_vowel_sign (i)) + return i; + return i + 0x987 - 0x9c8; +} + +gboolean +vowel_split (gunichar i, gunichar *a, gunichar *b) +{ + if (i == 0x9cb || i == 0x9cc) { + if (a) + *a = 0x9c7; + if (b) { + if (i == 0x9cc) + *b = 0xe9d7; + else + *b = 0xe9be; + } + return TRUE; + } + return FALSE; +} + +#define RA_SUPERSCRIPT 0xe9ff +#define RA_SUBSCRIPT 0xe9fe + +static char *default_charset = "iso10646-bng"; + +static PangoEngineRange pango_indic_range[] = +{ + {RANGE_START, RANGE_END, "*"}, +}; + +SCRIPT_ENGINE_DEFINITION + +static PangoCoverage * +pango_indic_engine_get_coverage (PangoFont * font, const char *lang) +{ + gunichar i; + PangoCoverage *result = pango_coverage_new (); + PangoXSubfont subfont; + + int dev_font = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + + if (dev_font) + { + for (i = RANGE_START; i <= RANGE_END; i++) + pango_coverage_set (result, i, PANGO_COVERAGE_EXACT); + + pango_coverage_set (result, 0x10000, PANGO_COVERAGE_EXACT); + } + + return result; +} + +static gboolean +is_vowel_sign (gunichar i) +{ + /* one that combines, whether or not it spaces */ + return (i >= 0x9BE && i <= 0x9Cc) || (i >= 0x9E2 && i <= 0x9E3); +} + +static int +is_consonant (int i) +{ + return (i >= 0x995 && i <= 0x9b9) || (i >= 0x9dc && i <= 0x9df) || (i >= 0x9f0 && i <= 0x09f1); +} + +static int +is_ind_vowel (int i) +{ + return (i >= 0x985 && i <= 0x994); +} + +static gboolean +is_vowel_half (gunichar i) +{ + return (i == 0xe9d7) || (i == 0xe9be) || (i == 0x9d7); +} + +static int +is_prefixing_vowel (gunichar what) +{ + return (what == 0x9bf) || (what == 0x9c7) || (what == 0x9c8); +} + +static void +pango_indic_make_ligs (gunichar * start, gunichar * end) +{ + int num = end - start; + int i; + + for (i = 0; i < (end - start); i++) + { + gunichar t0 = pango_indic_get_char (start + i, end); + gunichar t1 = pango_indic_get_char (start + 1 + i, end); + gunichar t2 = pango_indic_get_char (start + 2 + i, end); + + if ((t0 == VIRAMA) && (t1 == 0x9af)) + { + start[i+0] = 0; + start[i+1] = 0xe9fd; + } + } + + if (start[0] == RA && start[1] == VIRAMA && is_consonant (start[2])) + { + start[0] = 0; + start[1] = start[2]; + start[2] = RA_SUPERSCRIPT; + } + + for (i = 0; i < (end - start - 1); i++) + { + if (start[i] == VIRAMA) + { + if (start[i+1] == RA) + { + start[i] = 0; + start[i+1] = RA_SUBSCRIPT; + break; + } + } + } + +} + +static void +pango_indic_engine_shape (PangoFont * font, + const char *text, + int length, + PangoAnalysis * analysis, PangoGlyphString * glyphs) +{ + PangoXSubfont subfont; + + int n_chars, n_glyph; + int lvl; + const char *p; + int i, k; + gunichar *wc; + int sb; + int n_syls; + gunichar **syls = g_malloc (sizeof (gunichar **)); + 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 = n_glyph = g_utf8_strlen (text, length); + lvl = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + if (!lvl) + { + pango_x_fallback_shape (font, glyphs, text, n_chars); + return; + } + + pango_indic_split_out_characters (&script, text, n_chars, &wc, + &n_glyph, glyphs); + pango_indic_convert_vowels (&script, TRUE, &n_glyph, wc, + pango_x_has_glyph (font, + PANGO_X_MAKE_GLYPH (subfont, 0xc9bd))); + + n_syls = 1; + syls[0] = wc; + sb = glyphs->log_clusters[0]; + for (i = 0; i < n_glyph; i++) + { + if (i && (is_consonant (wc[i]) | is_ind_vowel (wc[i])) + && wc[i - 1] != VIRAMA) + { + syls = g_realloc (syls, ((n_syls + 2) * sizeof (gunichar **))); + syls[n_syls] = wc + i; + n_syls++; + sb = glyphs->log_clusters[i]; + } + glyphs->log_clusters[i] = sb; + } + syls[n_syls] = wc + i; + + for (i = 0; i < n_syls; i++) + { + pango_indic_make_ligs (syls[i], syls[i+1]); + pango_indic_shift_vowels (&script, syls[i], syls[i + 1]); + } + + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_x_apply_ligatures (font, subfont, &wc, &n_glyph, &glyphs->log_clusters); + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_glyph_string_set_size (glyphs, n_glyph); + + for (i = 0; i < n_glyph; i++) + { + PangoRectangle logical_rect; + glyphs->glyphs[i].glyph = PANGO_X_MAKE_GLYPH (subfont, wc[i]); + pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, + NULL, &logical_rect); + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + glyphs->glyphs[i].geometry.width = logical_rect.width; + } + g_free (syls); +} + +static PangoEngine * +pango_indic_engine_x_new () +{ + PangoEngineShape *result; + result = g_new (PangoEngineShape, 1); + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_shape = pango_indic_engine_shape; + result->get_coverage = pango_indic_engine_get_coverage; + return (PangoEngine *) result; +} + +static void +pango_indic_engine_break (const char *text, + int len, + PangoAnalysis * analysis, PangoLogAttr * attrs) +{ + const char *cur = text; + gint i = 0; + gunichar wc; + + while (*cur && cur - text < len) + { + wc = g_utf8_get_char (cur); + if (wc == (gunichar)-1) + break; /* FIXME: ERROR */ + + attrs[i].is_white = (wc == ' ' || wc == '\t' || wc == 'n') ? 1 : 0; + attrs[i].is_break = (i > 0 && attrs[i - 1].is_white) || + attrs[i].is_white; + attrs[i].is_char_stop = 1; + attrs[i].is_word_stop = (i == 0) || attrs[i - 1].is_white; + /* actually, is_word_stop in not correct, but simple and good enough. */ + + i++; + cur = g_utf8_next_char (cur); + } +} + + +static PangoEngine * +pango_indic_engine_lang_new () +{ + PangoEngineLang *result; + + result = g_new (PangoEngineLang, 1); + + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_break = pango_indic_engine_break; + + return (PangoEngine *) result; +} + +#ifdef MODULE_PREFIX +#define MODULE_ENTRY(func) _pango_pango_##func +#else +#define MODULE_ENTRY(func) func +#endif + +void +MODULE_ENTRY(script_engine_list) (PangoEngineInfo ** engines, int *n_engines) +{ + *engines = script_engines; + *n_engines = n_script_engines; +} + +PangoEngine * +MODULE_ENTRY(script_engine_load) (const char *id) +{ + if (!strcmp (id, SCRIPT_STRING "ScriptEngineLang")) + return pango_indic_engine_lang_new (); + else if (!strcmp (id, SCRIPT_STRING "ScriptEngineX")) + return pango_indic_engine_x_new (); + else + return NULL; +} + +void +MODULE_ENTRY(script_engine_unload) (PangoEngine * engine) +{ +} + diff --git a/modules/indic/devanagari-x.c b/modules/indic/devanagari-x.c new file mode 100644 index 00000000..028c432e --- /dev/null +++ b/modules/indic/devanagari-x.c @@ -0,0 +1,411 @@ +/* Pango - Devanagari module + * + * Copyright (C) 2000 SuSE Linux Ltd + * Author: Robert Brady <robert@suse.co.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * Licence as published by the Free Software Foundation; either + * version 2.1 of the Licence, 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 + * Lesser General Public Licence for more details. + * + * You should have received a copy of the GNU Lesser General Public + * Licence along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * This is the renderer for the Devanagari script. + * + * This script is used to write many languages, including the + * following. + * + * awa Awadhi bh Bihari bra Braj Bhasa + * gon Gondhi hi Hindi kok Konkani + * mr Marathi new Newari ne Nepali + * sa Sanskrit sat Santali + * + * For a description of the rendering algorithm, see section 9.1 of + * /The Unicode Standard Version 3.0/. + */ + + +#include <glib.h> +#include <stdio.h> + +#include "pango.h" +#include "pangox.h" + +#define RANGE_START 0x900 +#define RANGE_SIZE 0x80 + +#define ISCII_BASED +#define SCRIPT_STRING "Devanagari" + +#include "pango-indic.h" +#include "pango-indic-script.h" + +static gboolean is_prefixing_vowel (gunichar i); +static gboolean is_vowel_sign (gunichar i); +static gunichar vowel_sign_to_matra (gunichar i); + +static PangoIndicScript script = +{ + SCRIPT_STRING, + &is_prefixing_vowel, + &is_vowel_sign, + &vowel_sign_to_matra, + NULL, /* no split vowels for Devanagari */ +}; + +#define INTERMEDIATE_HALF_FORM_OFFSET 0xf000 +#define FINAL_HALF_FORM_OFFSET 0xe000 + +#define RA_SUPERSCRIPT 0xc97f +#define RA_SUBSCRIPT 0xc97e + +static char *default_charset = "iso10646-dev"; + +static PangoEngineRange pango_indic_range[] = +{ + {RANGE_START, RANGE_END, "*"}, + {ZERO_WIDTH_JOINER, ZERO_WIDTH_JOINER, "*"}, +}; + +SCRIPT_ENGINE_DEFINITION + +static PangoCoverage * +pango_indic_engine_get_coverage (PangoFont * font, const char *lang) +{ + gunichar i; + PangoCoverage *result = pango_coverage_new (); + PangoXSubfont subfont; + + int dev_font = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + + if (dev_font) + { + for (i = RANGE_START; i <= RANGE_END; i++) + pango_coverage_set (result, i, PANGO_COVERAGE_EXACT); + + pango_coverage_set (result, ZERO_WIDTH_JOINER, PANGO_COVERAGE_EXACT); + } + + return result; +} + +static gboolean +is_vowel_sign (gunichar i) +{ + /* one that combines, whether or not it spaces */ + return (i >= 0x93E && i <= 0x94c) || (i >= 0x962 && i <= 0x963); +} + +static int +is_consonant (int i) +{ + return (i >= 0x915 && i <= 0x939) || (i >= 0x958 && i <= 0x95f); +} + +static int +is_ind_vowel (int i) +{ + return (i >= 0x905 && i <= 0x914); +} + +static gunichar +vowel_sign_to_matra (gunichar i) +{ + if (is_vowel_sign (i)) + return i + 0x905 - 0x93e; + return i; +} + +static gboolean +is_prefixing_vowel (gunichar i) +{ + return i == 0x93f; +} + +static void +dev_mini_shuffle (gunichar *s, gunichar *e) +{ + gunichar *dest = s; + while (s < e) + { + if (*s) + { + *dest = *s; + dest++; + } + s++; + } + while (dest < e) + { + *dest = 0; + dest++; + } +} + +static int +is_intermediate_form (int q) +{ + return (q >= 0xf000 && q <= 0xffff); +} + +static int +is_consonantal_form (int q) +{ + return (q == ZERO_WIDTH_JOINER) || is_consonant (q) || (q >= 0xd000); +} + +static int +nominal_form (int q) +{ + return q - 0xf000; +} + +static int +half_form (int q) +{ + return (q & 0xfff) + 0xe000; +} + +static void +shuffle_one_along (gunichar *start, gunichar *end) +{ + end--; + if (*end != 0) + fprintf (stderr, "pango devanagari error, please report. bad shuffle!\n"); + while (end > start) + { + end[0] = end[-1]; + end--; + } + start[0] = 0; +} + +static void +pango_indic_make_ligs (gunichar * start, gunichar * end) +{ + int num = end - start; + int i; + + for (i = 0; i < (end - start); i++) + { + gunichar t0 = pango_indic_get_char (start + i, end); + gunichar t1 = pango_indic_get_char (start + 1 + i, end); + + if (is_consonant (t0) && t1 == VIRAMA) + { + start[i+0] = t0 + INTERMEDIATE_HALF_FORM_OFFSET; + start[i+1] = 0; + } + } + + if (num > 2 && start[0] == INTERMEDIATE_HALF_FORM_OFFSET + RA) + { + for (i=1;i<num;i++) + start[i-1] = start[i]; + + start[num-1] = RA_SUPERSCRIPT; + } + + dev_mini_shuffle (start, end); + + for (i = 0; i < (end - start - 1); i++) + if (is_intermediate_form (start[i])) + { + if (start[i+1] == RA) + { + start[i] = nominal_form (start[i]); + start[i+1] = RA_SUBSCRIPT; + } + else if (start[i+1] == (RA + INTERMEDIATE_HALF_FORM_OFFSET)) + { + start[i] = nominal_form (start[i]); + start[i+1] = RA_SUBSCRIPT; + shuffle_one_along (start+2, end); + start[i+2] = VIRAMA; + } + } +} + +static void +pango_indic_engine_shape (PangoFont * font, + const char *text, + int length, + PangoAnalysis * analysis, + PangoGlyphString * glyphs) +{ + PangoXSubfont subfont; + + int n_chars, n_glyph; + int lvl; + const char *p; + int i; + gunichar *wc; + int sb; + int n_syls; + gunichar **syls = g_malloc (sizeof (gunichar **)); + + 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 = n_glyph = g_utf8_strlen (text, length); + lvl = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + if (!lvl) + { + pango_x_fallback_shape (font, glyphs, text, n_chars); + return; + } + + pango_indic_split_out_characters (&script, text, n_chars, &wc, &n_glyph, + glyphs); + pango_indic_convert_vowels (&script, TRUE, &n_glyph, wc, + pango_x_has_glyph (font, + PANGO_X_MAKE_GLYPH(subfont, 0xc93e))); + + n_syls = 1; + syls[0] = wc; + sb = glyphs->log_clusters[0]; + for (i = 0; i < n_chars; i++) + { + if (i && (is_consonant (wc[i]) | is_ind_vowel (wc[i])) + && wc[i - 1] != VIRAMA) + { + syls = g_realloc (syls, ((n_syls + 2) * sizeof (gunichar **))); + syls[n_syls] = wc + i; + n_syls++; + sb = glyphs->log_clusters[i]; + } + glyphs->log_clusters[i] = sb; + } + syls[n_syls] = wc + i; + + for (i = 0; i < n_syls; i++) + { + pango_indic_make_ligs (syls[i], syls[i+1]); + pango_indic_shift_vowels (&script, syls[i], syls[i + 1]); + } + + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_x_apply_ligatures (font, subfont, &wc, &n_glyph, &glyphs->log_clusters); + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_glyph_string_set_size (glyphs, n_glyph); + + for (i = 0; i < n_glyph; i++) + { + PangoRectangle logical_rect; +#if 0 + if (i && (wc[i] == VIRAMA) && (wc[i-1] == RA_SUBSCRIPT)) + { + wc[i] = LOWER_VIRAMA_GLYPH; + } +#endif + if ((i != (n_glyph - 1)) && is_intermediate_form (wc[i]) && + is_consonantal_form (wc[i+1])) + { + wc[i] = half_form (wc[i]); + } + glyphs->glyphs[i].glyph = PANGO_X_MAKE_GLYPH (subfont, wc[i]); + pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, + NULL, &logical_rect); + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + glyphs->glyphs[i].geometry.width = logical_rect.width; + } + g_free (syls); +} + +static PangoEngine * +pango_indic_engine_x_new () +{ + PangoEngineShape *result; + result = g_new (PangoEngineShape, 1); + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_shape = pango_indic_engine_shape; + result->get_coverage = pango_indic_engine_get_coverage; + return (PangoEngine *) result; +} + +static void +pango_indic_engine_break (const char *text, + int len, + PangoAnalysis * analysis, PangoLogAttr * attrs) +{ + const char *cur = text; + gint i = 0; + gunichar wc; + + while (*cur && cur - text < len) + { + wc = g_utf8_get_char (cur); + if (wc == (gunichar)-1) + break; /* FIXME: ERROR */ + + attrs[i].is_white = (wc == ' ' || wc == '\t' || wc == 'n') ? 1 : 0; + attrs[i].is_break = (i > 0 && attrs[i - 1].is_white) || + attrs[i].is_white; + attrs[i].is_char_stop = 1; + attrs[i].is_word_stop = (i == 0) || attrs[i - 1].is_white; + /* actually, is_word_stop in not correct, but simple and good enough. */ + + i++; + cur = g_utf8_next_char (cur); + } +} + + +static PangoEngine * +pango_indic_engine_lang_new () +{ + PangoEngineLang *result; + + result = g_new (PangoEngineLang, 1); + + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_break = pango_indic_engine_break; + + return (PangoEngine *) result; +} + +#ifdef MODULE_PREFIX +#define MODULE_ENTRY(func) _pango_pango_indic_##func +#else +#define MODULE_ENTRY(func) func +#endif + +void +MODULE_ENTRY(script_engine_list) (PangoEngineInfo ** engines, int *n_engines) +{ + *engines = script_engines; + *n_engines = n_script_engines; +} + +PangoEngine * +MODULE_ENTRY(script_engine_load) (const char *id) +{ + if (!strcmp (id, SCRIPT_STRING "ScriptEngineLang")) + return pango_indic_engine_lang_new (); + else if (!strcmp (id, SCRIPT_STRING "ScriptEngineX")) + return pango_indic_engine_x_new (); + else + return NULL; +} + +void +MODULE_ENTRY(script_engine_unload) (PangoEngine * engine) +{ +} diff --git a/modules/indic/devanagari.c b/modules/indic/devanagari.c new file mode 100644 index 00000000..028c432e --- /dev/null +++ b/modules/indic/devanagari.c @@ -0,0 +1,411 @@ +/* Pango - Devanagari module + * + * Copyright (C) 2000 SuSE Linux Ltd + * Author: Robert Brady <robert@suse.co.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * Licence as published by the Free Software Foundation; either + * version 2.1 of the Licence, 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 + * Lesser General Public Licence for more details. + * + * You should have received a copy of the GNU Lesser General Public + * Licence along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * This is the renderer for the Devanagari script. + * + * This script is used to write many languages, including the + * following. + * + * awa Awadhi bh Bihari bra Braj Bhasa + * gon Gondhi hi Hindi kok Konkani + * mr Marathi new Newari ne Nepali + * sa Sanskrit sat Santali + * + * For a description of the rendering algorithm, see section 9.1 of + * /The Unicode Standard Version 3.0/. + */ + + +#include <glib.h> +#include <stdio.h> + +#include "pango.h" +#include "pangox.h" + +#define RANGE_START 0x900 +#define RANGE_SIZE 0x80 + +#define ISCII_BASED +#define SCRIPT_STRING "Devanagari" + +#include "pango-indic.h" +#include "pango-indic-script.h" + +static gboolean is_prefixing_vowel (gunichar i); +static gboolean is_vowel_sign (gunichar i); +static gunichar vowel_sign_to_matra (gunichar i); + +static PangoIndicScript script = +{ + SCRIPT_STRING, + &is_prefixing_vowel, + &is_vowel_sign, + &vowel_sign_to_matra, + NULL, /* no split vowels for Devanagari */ +}; + +#define INTERMEDIATE_HALF_FORM_OFFSET 0xf000 +#define FINAL_HALF_FORM_OFFSET 0xe000 + +#define RA_SUPERSCRIPT 0xc97f +#define RA_SUBSCRIPT 0xc97e + +static char *default_charset = "iso10646-dev"; + +static PangoEngineRange pango_indic_range[] = +{ + {RANGE_START, RANGE_END, "*"}, + {ZERO_WIDTH_JOINER, ZERO_WIDTH_JOINER, "*"}, +}; + +SCRIPT_ENGINE_DEFINITION + +static PangoCoverage * +pango_indic_engine_get_coverage (PangoFont * font, const char *lang) +{ + gunichar i; + PangoCoverage *result = pango_coverage_new (); + PangoXSubfont subfont; + + int dev_font = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + + if (dev_font) + { + for (i = RANGE_START; i <= RANGE_END; i++) + pango_coverage_set (result, i, PANGO_COVERAGE_EXACT); + + pango_coverage_set (result, ZERO_WIDTH_JOINER, PANGO_COVERAGE_EXACT); + } + + return result; +} + +static gboolean +is_vowel_sign (gunichar i) +{ + /* one that combines, whether or not it spaces */ + return (i >= 0x93E && i <= 0x94c) || (i >= 0x962 && i <= 0x963); +} + +static int +is_consonant (int i) +{ + return (i >= 0x915 && i <= 0x939) || (i >= 0x958 && i <= 0x95f); +} + +static int +is_ind_vowel (int i) +{ + return (i >= 0x905 && i <= 0x914); +} + +static gunichar +vowel_sign_to_matra (gunichar i) +{ + if (is_vowel_sign (i)) + return i + 0x905 - 0x93e; + return i; +} + +static gboolean +is_prefixing_vowel (gunichar i) +{ + return i == 0x93f; +} + +static void +dev_mini_shuffle (gunichar *s, gunichar *e) +{ + gunichar *dest = s; + while (s < e) + { + if (*s) + { + *dest = *s; + dest++; + } + s++; + } + while (dest < e) + { + *dest = 0; + dest++; + } +} + +static int +is_intermediate_form (int q) +{ + return (q >= 0xf000 && q <= 0xffff); +} + +static int +is_consonantal_form (int q) +{ + return (q == ZERO_WIDTH_JOINER) || is_consonant (q) || (q >= 0xd000); +} + +static int +nominal_form (int q) +{ + return q - 0xf000; +} + +static int +half_form (int q) +{ + return (q & 0xfff) + 0xe000; +} + +static void +shuffle_one_along (gunichar *start, gunichar *end) +{ + end--; + if (*end != 0) + fprintf (stderr, "pango devanagari error, please report. bad shuffle!\n"); + while (end > start) + { + end[0] = end[-1]; + end--; + } + start[0] = 0; +} + +static void +pango_indic_make_ligs (gunichar * start, gunichar * end) +{ + int num = end - start; + int i; + + for (i = 0; i < (end - start); i++) + { + gunichar t0 = pango_indic_get_char (start + i, end); + gunichar t1 = pango_indic_get_char (start + 1 + i, end); + + if (is_consonant (t0) && t1 == VIRAMA) + { + start[i+0] = t0 + INTERMEDIATE_HALF_FORM_OFFSET; + start[i+1] = 0; + } + } + + if (num > 2 && start[0] == INTERMEDIATE_HALF_FORM_OFFSET + RA) + { + for (i=1;i<num;i++) + start[i-1] = start[i]; + + start[num-1] = RA_SUPERSCRIPT; + } + + dev_mini_shuffle (start, end); + + for (i = 0; i < (end - start - 1); i++) + if (is_intermediate_form (start[i])) + { + if (start[i+1] == RA) + { + start[i] = nominal_form (start[i]); + start[i+1] = RA_SUBSCRIPT; + } + else if (start[i+1] == (RA + INTERMEDIATE_HALF_FORM_OFFSET)) + { + start[i] = nominal_form (start[i]); + start[i+1] = RA_SUBSCRIPT; + shuffle_one_along (start+2, end); + start[i+2] = VIRAMA; + } + } +} + +static void +pango_indic_engine_shape (PangoFont * font, + const char *text, + int length, + PangoAnalysis * analysis, + PangoGlyphString * glyphs) +{ + PangoXSubfont subfont; + + int n_chars, n_glyph; + int lvl; + const char *p; + int i; + gunichar *wc; + int sb; + int n_syls; + gunichar **syls = g_malloc (sizeof (gunichar **)); + + 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 = n_glyph = g_utf8_strlen (text, length); + lvl = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + if (!lvl) + { + pango_x_fallback_shape (font, glyphs, text, n_chars); + return; + } + + pango_indic_split_out_characters (&script, text, n_chars, &wc, &n_glyph, + glyphs); + pango_indic_convert_vowels (&script, TRUE, &n_glyph, wc, + pango_x_has_glyph (font, + PANGO_X_MAKE_GLYPH(subfont, 0xc93e))); + + n_syls = 1; + syls[0] = wc; + sb = glyphs->log_clusters[0]; + for (i = 0; i < n_chars; i++) + { + if (i && (is_consonant (wc[i]) | is_ind_vowel (wc[i])) + && wc[i - 1] != VIRAMA) + { + syls = g_realloc (syls, ((n_syls + 2) * sizeof (gunichar **))); + syls[n_syls] = wc + i; + n_syls++; + sb = glyphs->log_clusters[i]; + } + glyphs->log_clusters[i] = sb; + } + syls[n_syls] = wc + i; + + for (i = 0; i < n_syls; i++) + { + pango_indic_make_ligs (syls[i], syls[i+1]); + pango_indic_shift_vowels (&script, syls[i], syls[i + 1]); + } + + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_x_apply_ligatures (font, subfont, &wc, &n_glyph, &glyphs->log_clusters); + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_glyph_string_set_size (glyphs, n_glyph); + + for (i = 0; i < n_glyph; i++) + { + PangoRectangle logical_rect; +#if 0 + if (i && (wc[i] == VIRAMA) && (wc[i-1] == RA_SUBSCRIPT)) + { + wc[i] = LOWER_VIRAMA_GLYPH; + } +#endif + if ((i != (n_glyph - 1)) && is_intermediate_form (wc[i]) && + is_consonantal_form (wc[i+1])) + { + wc[i] = half_form (wc[i]); + } + glyphs->glyphs[i].glyph = PANGO_X_MAKE_GLYPH (subfont, wc[i]); + pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, + NULL, &logical_rect); + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + glyphs->glyphs[i].geometry.width = logical_rect.width; + } + g_free (syls); +} + +static PangoEngine * +pango_indic_engine_x_new () +{ + PangoEngineShape *result; + result = g_new (PangoEngineShape, 1); + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_shape = pango_indic_engine_shape; + result->get_coverage = pango_indic_engine_get_coverage; + return (PangoEngine *) result; +} + +static void +pango_indic_engine_break (const char *text, + int len, + PangoAnalysis * analysis, PangoLogAttr * attrs) +{ + const char *cur = text; + gint i = 0; + gunichar wc; + + while (*cur && cur - text < len) + { + wc = g_utf8_get_char (cur); + if (wc == (gunichar)-1) + break; /* FIXME: ERROR */ + + attrs[i].is_white = (wc == ' ' || wc == '\t' || wc == 'n') ? 1 : 0; + attrs[i].is_break = (i > 0 && attrs[i - 1].is_white) || + attrs[i].is_white; + attrs[i].is_char_stop = 1; + attrs[i].is_word_stop = (i == 0) || attrs[i - 1].is_white; + /* actually, is_word_stop in not correct, but simple and good enough. */ + + i++; + cur = g_utf8_next_char (cur); + } +} + + +static PangoEngine * +pango_indic_engine_lang_new () +{ + PangoEngineLang *result; + + result = g_new (PangoEngineLang, 1); + + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_break = pango_indic_engine_break; + + return (PangoEngine *) result; +} + +#ifdef MODULE_PREFIX +#define MODULE_ENTRY(func) _pango_pango_indic_##func +#else +#define MODULE_ENTRY(func) func +#endif + +void +MODULE_ENTRY(script_engine_list) (PangoEngineInfo ** engines, int *n_engines) +{ + *engines = script_engines; + *n_engines = n_script_engines; +} + +PangoEngine * +MODULE_ENTRY(script_engine_load) (const char *id) +{ + if (!strcmp (id, SCRIPT_STRING "ScriptEngineLang")) + return pango_indic_engine_lang_new (); + else if (!strcmp (id, SCRIPT_STRING "ScriptEngineX")) + return pango_indic_engine_x_new (); + else + return NULL; +} + +void +MODULE_ENTRY(script_engine_unload) (PangoEngine * engine) +{ +} diff --git a/modules/indic/gujarati-x.c b/modules/indic/gujarati-x.c new file mode 100644 index 00000000..0b72babd --- /dev/null +++ b/modules/indic/gujarati-x.c @@ -0,0 +1,387 @@ +/* Pango - Gujarati module + * + * Copyright (C) 2000 SuSE Linux Ltd + * Author: Robert Brady <robert@suse.co.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * Licence as published by the Free Software Foundation; either + * version 2.1 of the Licence, 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 + * Lesser General Public Licence for more details. + * + * You should have received a copy of the GNU Lesser General Public + * Licence along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + */ + + +#include <glib.h> +#include <stdio.h> + +#include "pango.h" +#include "pangox.h" + +#define RANGE_START 0xA80 +#define RANGE_SIZE 0x80 + +#define ISCII_BASED +#define SCRIPT_STRING "Gujarati" + +#include "pango-indic.h" +#include "pango-indic-script.h" + +static gboolean is_prefixing_vowel (gunichar i); +static gboolean is_vowel_sign (gunichar i); +static gunichar vowel_sign_to_matra (gunichar i); + +static PangoIndicScript script = { + SCRIPT_STRING, + &is_prefixing_vowel, + &is_vowel_sign, + NULL, /* vowel sign to matra must die! */ + NULL, /* no split vowels for Devanagari */ +}; + +#define INTERMEDIATE_HALF_FORM_OFFSET 0xf000 +#define FINAL_HALF_FORM_OFFSET 0xe000 +#define RA_SUPERSCRIPT 0xeaff +#define RA_SUBSCRIPT 0xeafe + +static char *default_charset = "iso10646-guj"; + +static PangoEngineRange pango_indic_range[] = +{ + {RANGE_START, RANGE_END, "*"}, + {ZERO_WIDTH_JOINER, ZERO_WIDTH_JOINER, "*"}, +}; + +SCRIPT_ENGINE_DEFINITION + +static PangoCoverage * +pango_indic_engine_get_coverage (PangoFont * font, const char *lang) +{ + gunichar i; + PangoCoverage *result = pango_coverage_new (); + PangoXSubfont subfont; + + int dev_font = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + + if (dev_font) + { + for (i = RANGE_START; i <= RANGE_END; i++) + pango_coverage_set (result, i, PANGO_COVERAGE_EXACT); + + pango_coverage_set (result, ZERO_WIDTH_JOINER, PANGO_COVERAGE_EXACT); + } + + return result; +} + +static gboolean +is_vowel_sign (gunichar i) +{ + /* one that combines, whether or not it spaces */ + return (i >= 0xABE && i <= 0xACC); +} + +static int +is_consonant (int i) +{ + return (i >= 0xA95 && i <= 0xAB9) || (i == 0xAE0); +} + +static int +is_ind_vowel (int i) +{ + return (i >= 0xA85 && i <= 0xA94); +} + +static gboolean +is_prefixing_vowel (gunichar i) +{ + return i == 0xABF; +} + +static void +dev_mini_shuffle (gunichar *s, gunichar *e) +{ + gunichar *dest = s; + while (s < e) + { + if (*s) + { + *dest = *s; + dest++; + } + s++; + } + while (dest < e) + { + *dest = 0; + dest++; + } +} + +static int +is_intermediate_form (int q) +{ + return (q >= 0xf000 && q <= 0xffff); +} + +static int +is_consonantal_form (int q) +{ + return (q == ZERO_WIDTH_JOINER) || is_consonant (q) || (q >= 0xc000); +} + +static int +nominal_form (int q) +{ + return q - 0xf000; +} + +static int +half_form (int q) +{ + return (q & 0xfff) + 0xe000; +} + +static void +shuffle_one_along (gunichar *start, gunichar *end) +{ + end--; + if (*end != 0) + { + return; + } + while (end > start) + { + end[0] = end[-1]; + end--; + } + start[0] = 0; +} + +static void +pango_indic_make_ligs (gunichar * start, gunichar * end) +{ + int num = end - start; + int i; + + for (i = 0; i < (end - start); i++) + { + gunichar t0 = pango_indic_get_char (start + i, end); + gunichar t1 = pango_indic_get_char (start + 1 + i, end); + + if (is_consonant (t0) && t1 == VIRAMA) + { + start[i+0] = t0 + INTERMEDIATE_HALF_FORM_OFFSET; + start[i+1] = 0; + } + } + + while (num && !is_consonant (start[num-1])) + { + num--; + } + if (num > 2 && start[0] == INTERMEDIATE_HALF_FORM_OFFSET + RA) + { + for (i=1;i<num;i++) + { + start[i-1] = start[i]; + } + start[num-1] = RA_SUPERSCRIPT; + } + + dev_mini_shuffle (start, end); + + for (i = 0; i < (end - start - 1); i++) + if (is_intermediate_form (start[i])) + { + if (start[i+1] == RA) + { + start[i] = nominal_form (start[i]); + start[i+1] = RA_SUBSCRIPT; + } + else if (start[i+1] == (RA + INTERMEDIATE_HALF_FORM_OFFSET)) + { + start[i] = nominal_form (start[i]); + start[i+1] = RA_SUBSCRIPT; + shuffle_one_along (start+2, end); + start[i+2] = VIRAMA; + } + } +} + +static void +pango_indic_engine_shape (PangoFont * font, + const char *text, + int length, + PangoAnalysis * analysis, PangoGlyphString * glyphs) +{ + PangoXSubfont subfont; + + int n_chars, n_glyph; + int lvl; + const char *p; + int i; + gunichar *wc; + int sb; + int n_syls; + gunichar **syls = g_malloc (sizeof (gunichar **)); + + 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 = n_glyph = g_utf8_strlen (text, length); + lvl = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + if (!lvl) + { + pango_x_fallback_shape (font, glyphs, text, n_chars); + return; + } + + pango_indic_split_out_characters (&script, text, n_chars, &wc, + &n_glyph, glyphs); + pango_indic_convert_vowels (&script, TRUE, &n_glyph, wc, FALSE); + + n_syls = 1; + syls[0] = wc; + sb = glyphs->log_clusters[0]; + for (i = 0; i < n_chars; i++) + { + if (i && (is_consonant (wc[i]) | is_ind_vowel (wc[i])) + && wc[i - 1] != VIRAMA) + { + syls = g_realloc (syls, ((n_syls + 2) * sizeof (gunichar **))); + syls[n_syls] = wc + i; + n_syls++; + sb = glyphs->log_clusters[i]; + } + glyphs->log_clusters[i] = sb; + } + syls[n_syls] = wc + i; + + for (i = 0; i < n_syls; i++) + { + pango_indic_make_ligs (syls[i], syls[i+1]); + pango_indic_shift_vowels (&script, syls[i], syls[i + 1]); + } + + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_x_apply_ligatures (font, subfont, &wc, &n_glyph, &glyphs->log_clusters); + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_glyph_string_set_size (glyphs, n_glyph); + + for (i = 0; i < n_glyph; i++) + { + PangoRectangle logical_rect; + if ((i != (n_glyph - 1)) && is_intermediate_form (wc[i]) && + is_consonantal_form (wc[i+1])) + { + wc[i] = half_form (wc[i]); + } + glyphs->glyphs[i].glyph = PANGO_X_MAKE_GLYPH (subfont, wc[i]); + pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, + NULL, &logical_rect); + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + glyphs->glyphs[i].geometry.width = logical_rect.width; + } + g_free (syls); +} + +static PangoEngine * +pango_indic_engine_x_new () +{ + PangoEngineShape *result; + result = g_new (PangoEngineShape, 1); + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_shape = pango_indic_engine_shape; + result->get_coverage = pango_indic_engine_get_coverage; + return (PangoEngine *) result; +} + +static void +pango_indic_engine_break (const char *text, + int len, + PangoAnalysis * analysis, PangoLogAttr * attrs) +{ + const char *cur = text; + gint i = 0; + gunichar wc; + + while (*cur && cur - text < len) + { + wc = g_utf8_get_char (cur); + if (wc == (gunichar)-1) + break; /* FIXME: ERROR */ + + attrs[i].is_white = (wc == ' ' || wc == '\t' || wc == 'n') ? 1 : 0; + attrs[i].is_break = (i > 0 && attrs[i - 1].is_white) || + attrs[i].is_white; + attrs[i].is_char_stop = 1; + attrs[i].is_word_stop = (i == 0) || attrs[i - 1].is_white; + /* actually, is_word_stop in not correct, but simple and good enough. */ + + i++; + cur = g_utf8_next_char (cur); + } +} + + +static PangoEngine * +pango_indic_engine_lang_new () +{ + PangoEngineLang *result; + + result = g_new (PangoEngineLang, 1); + + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_break = pango_indic_engine_break; + + return (PangoEngine *) result; +} + +#ifdef MODULE_PREFIX +#define MODULE_ENTRY(func) _pango_pango_indic_##func +#else +#define MODULE_ENTRY(func) func +#endif + +void +MODULE_ENTRY(script_engine_list) (PangoEngineInfo ** engines, int *n_engines) +{ + *engines = script_engines; + *n_engines = n_script_engines; +} + +PangoEngine * +MODULE_ENTRY(script_engine_load) (const char *id) +{ + if (!strcmp (id, SCRIPT_STRING "ScriptEngineLang")) + return pango_indic_engine_lang_new (); + else if (!strcmp (id, SCRIPT_STRING "ScriptEngineX")) + return pango_indic_engine_x_new (); + else + return NULL; +} + +void +MODULE_ENTRY(script_engine_unload) (PangoEngine * engine) +{ +} diff --git a/modules/indic/gujarati.c b/modules/indic/gujarati.c new file mode 100644 index 00000000..0b72babd --- /dev/null +++ b/modules/indic/gujarati.c @@ -0,0 +1,387 @@ +/* Pango - Gujarati module + * + * Copyright (C) 2000 SuSE Linux Ltd + * Author: Robert Brady <robert@suse.co.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * Licence as published by the Free Software Foundation; either + * version 2.1 of the Licence, 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 + * Lesser General Public Licence for more details. + * + * You should have received a copy of the GNU Lesser General Public + * Licence along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + */ + + +#include <glib.h> +#include <stdio.h> + +#include "pango.h" +#include "pangox.h" + +#define RANGE_START 0xA80 +#define RANGE_SIZE 0x80 + +#define ISCII_BASED +#define SCRIPT_STRING "Gujarati" + +#include "pango-indic.h" +#include "pango-indic-script.h" + +static gboolean is_prefixing_vowel (gunichar i); +static gboolean is_vowel_sign (gunichar i); +static gunichar vowel_sign_to_matra (gunichar i); + +static PangoIndicScript script = { + SCRIPT_STRING, + &is_prefixing_vowel, + &is_vowel_sign, + NULL, /* vowel sign to matra must die! */ + NULL, /* no split vowels for Devanagari */ +}; + +#define INTERMEDIATE_HALF_FORM_OFFSET 0xf000 +#define FINAL_HALF_FORM_OFFSET 0xe000 +#define RA_SUPERSCRIPT 0xeaff +#define RA_SUBSCRIPT 0xeafe + +static char *default_charset = "iso10646-guj"; + +static PangoEngineRange pango_indic_range[] = +{ + {RANGE_START, RANGE_END, "*"}, + {ZERO_WIDTH_JOINER, ZERO_WIDTH_JOINER, "*"}, +}; + +SCRIPT_ENGINE_DEFINITION + +static PangoCoverage * +pango_indic_engine_get_coverage (PangoFont * font, const char *lang) +{ + gunichar i; + PangoCoverage *result = pango_coverage_new (); + PangoXSubfont subfont; + + int dev_font = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + + if (dev_font) + { + for (i = RANGE_START; i <= RANGE_END; i++) + pango_coverage_set (result, i, PANGO_COVERAGE_EXACT); + + pango_coverage_set (result, ZERO_WIDTH_JOINER, PANGO_COVERAGE_EXACT); + } + + return result; +} + +static gboolean +is_vowel_sign (gunichar i) +{ + /* one that combines, whether or not it spaces */ + return (i >= 0xABE && i <= 0xACC); +} + +static int +is_consonant (int i) +{ + return (i >= 0xA95 && i <= 0xAB9) || (i == 0xAE0); +} + +static int +is_ind_vowel (int i) +{ + return (i >= 0xA85 && i <= 0xA94); +} + +static gboolean +is_prefixing_vowel (gunichar i) +{ + return i == 0xABF; +} + +static void +dev_mini_shuffle (gunichar *s, gunichar *e) +{ + gunichar *dest = s; + while (s < e) + { + if (*s) + { + *dest = *s; + dest++; + } + s++; + } + while (dest < e) + { + *dest = 0; + dest++; + } +} + +static int +is_intermediate_form (int q) +{ + return (q >= 0xf000 && q <= 0xffff); +} + +static int +is_consonantal_form (int q) +{ + return (q == ZERO_WIDTH_JOINER) || is_consonant (q) || (q >= 0xc000); +} + +static int +nominal_form (int q) +{ + return q - 0xf000; +} + +static int +half_form (int q) +{ + return (q & 0xfff) + 0xe000; +} + +static void +shuffle_one_along (gunichar *start, gunichar *end) +{ + end--; + if (*end != 0) + { + return; + } + while (end > start) + { + end[0] = end[-1]; + end--; + } + start[0] = 0; +} + +static void +pango_indic_make_ligs (gunichar * start, gunichar * end) +{ + int num = end - start; + int i; + + for (i = 0; i < (end - start); i++) + { + gunichar t0 = pango_indic_get_char (start + i, end); + gunichar t1 = pango_indic_get_char (start + 1 + i, end); + + if (is_consonant (t0) && t1 == VIRAMA) + { + start[i+0] = t0 + INTERMEDIATE_HALF_FORM_OFFSET; + start[i+1] = 0; + } + } + + while (num && !is_consonant (start[num-1])) + { + num--; + } + if (num > 2 && start[0] == INTERMEDIATE_HALF_FORM_OFFSET + RA) + { + for (i=1;i<num;i++) + { + start[i-1] = start[i]; + } + start[num-1] = RA_SUPERSCRIPT; + } + + dev_mini_shuffle (start, end); + + for (i = 0; i < (end - start - 1); i++) + if (is_intermediate_form (start[i])) + { + if (start[i+1] == RA) + { + start[i] = nominal_form (start[i]); + start[i+1] = RA_SUBSCRIPT; + } + else if (start[i+1] == (RA + INTERMEDIATE_HALF_FORM_OFFSET)) + { + start[i] = nominal_form (start[i]); + start[i+1] = RA_SUBSCRIPT; + shuffle_one_along (start+2, end); + start[i+2] = VIRAMA; + } + } +} + +static void +pango_indic_engine_shape (PangoFont * font, + const char *text, + int length, + PangoAnalysis * analysis, PangoGlyphString * glyphs) +{ + PangoXSubfont subfont; + + int n_chars, n_glyph; + int lvl; + const char *p; + int i; + gunichar *wc; + int sb; + int n_syls; + gunichar **syls = g_malloc (sizeof (gunichar **)); + + 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 = n_glyph = g_utf8_strlen (text, length); + lvl = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + if (!lvl) + { + pango_x_fallback_shape (font, glyphs, text, n_chars); + return; + } + + pango_indic_split_out_characters (&script, text, n_chars, &wc, + &n_glyph, glyphs); + pango_indic_convert_vowels (&script, TRUE, &n_glyph, wc, FALSE); + + n_syls = 1; + syls[0] = wc; + sb = glyphs->log_clusters[0]; + for (i = 0; i < n_chars; i++) + { + if (i && (is_consonant (wc[i]) | is_ind_vowel (wc[i])) + && wc[i - 1] != VIRAMA) + { + syls = g_realloc (syls, ((n_syls + 2) * sizeof (gunichar **))); + syls[n_syls] = wc + i; + n_syls++; + sb = glyphs->log_clusters[i]; + } + glyphs->log_clusters[i] = sb; + } + syls[n_syls] = wc + i; + + for (i = 0; i < n_syls; i++) + { + pango_indic_make_ligs (syls[i], syls[i+1]); + pango_indic_shift_vowels (&script, syls[i], syls[i + 1]); + } + + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_x_apply_ligatures (font, subfont, &wc, &n_glyph, &glyphs->log_clusters); + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_glyph_string_set_size (glyphs, n_glyph); + + for (i = 0; i < n_glyph; i++) + { + PangoRectangle logical_rect; + if ((i != (n_glyph - 1)) && is_intermediate_form (wc[i]) && + is_consonantal_form (wc[i+1])) + { + wc[i] = half_form (wc[i]); + } + glyphs->glyphs[i].glyph = PANGO_X_MAKE_GLYPH (subfont, wc[i]); + pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, + NULL, &logical_rect); + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + glyphs->glyphs[i].geometry.width = logical_rect.width; + } + g_free (syls); +} + +static PangoEngine * +pango_indic_engine_x_new () +{ + PangoEngineShape *result; + result = g_new (PangoEngineShape, 1); + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_shape = pango_indic_engine_shape; + result->get_coverage = pango_indic_engine_get_coverage; + return (PangoEngine *) result; +} + +static void +pango_indic_engine_break (const char *text, + int len, + PangoAnalysis * analysis, PangoLogAttr * attrs) +{ + const char *cur = text; + gint i = 0; + gunichar wc; + + while (*cur && cur - text < len) + { + wc = g_utf8_get_char (cur); + if (wc == (gunichar)-1) + break; /* FIXME: ERROR */ + + attrs[i].is_white = (wc == ' ' || wc == '\t' || wc == 'n') ? 1 : 0; + attrs[i].is_break = (i > 0 && attrs[i - 1].is_white) || + attrs[i].is_white; + attrs[i].is_char_stop = 1; + attrs[i].is_word_stop = (i == 0) || attrs[i - 1].is_white; + /* actually, is_word_stop in not correct, but simple and good enough. */ + + i++; + cur = g_utf8_next_char (cur); + } +} + + +static PangoEngine * +pango_indic_engine_lang_new () +{ + PangoEngineLang *result; + + result = g_new (PangoEngineLang, 1); + + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_break = pango_indic_engine_break; + + return (PangoEngine *) result; +} + +#ifdef MODULE_PREFIX +#define MODULE_ENTRY(func) _pango_pango_indic_##func +#else +#define MODULE_ENTRY(func) func +#endif + +void +MODULE_ENTRY(script_engine_list) (PangoEngineInfo ** engines, int *n_engines) +{ + *engines = script_engines; + *n_engines = n_script_engines; +} + +PangoEngine * +MODULE_ENTRY(script_engine_load) (const char *id) +{ + if (!strcmp (id, SCRIPT_STRING "ScriptEngineLang")) + return pango_indic_engine_lang_new (); + else if (!strcmp (id, SCRIPT_STRING "ScriptEngineX")) + return pango_indic_engine_x_new (); + else + return NULL; +} + +void +MODULE_ENTRY(script_engine_unload) (PangoEngine * engine) +{ +} diff --git a/modules/indic/gurmukhi-x.c b/modules/indic/gurmukhi-x.c new file mode 100644 index 00000000..e448fb22 --- /dev/null +++ b/modules/indic/gurmukhi-x.c @@ -0,0 +1,301 @@ +/* Pango - Gurmukhi module + * gurmukhi.c: + * + * Copyright (C) 2000 SuSE Linux Ltd + * Author: Robert Brady <robert@suse.co.uk> + * + * 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. + */ + +/* + * This is the renderer for Gurmukhi. This script is primarily used + * to write the Panjabi (pa) language. + */ + + +#include <glib.h> +#include <stdio.h> + +#include "pango.h" +#include "pangox.h" +#include "pango-indic.h" + +#define RANGE_START 0xa00 +#define RANGE_SIZE 0x80 +#define SCRIPT_STRING "Gurmukhi" +#define ISCII_BASED + +#include "pango-indic-script.h" + +static gboolean is_prefixing_vowel (gunichar i); +static gunichar vowel_sign_to_matra (gunichar i); +static gboolean is_vowel_sign (gunichar i); +static gboolean is_vowel_half (gunichar i); + +static PangoIndicScript script = { + SCRIPT_STRING, + &is_prefixing_vowel, + &is_vowel_sign, + &vowel_sign_to_matra, + &is_vowel_half, +}; + +#define RA_SUBSCRIPT 0xea7e + +static char *default_charset = "iso10646-gur"; + +static PangoEngineRange pango_indic_range[] = +{ + {RANGE_START, RANGE_END, "*"}, +}; + +SCRIPT_ENGINE_DEFINITION + +static PangoCoverage * +pango_indic_engine_get_coverage (PangoFont * font, const char *lang) +{ + gunichar i; + PangoCoverage *result = pango_coverage_new (); + PangoXSubfont subfont; + + int dev_font = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + + if (dev_font) + { + for (i = RANGE_START; i <= RANGE_END; i++) + pango_coverage_set (result, i, PANGO_COVERAGE_EXACT); + + } + + return result; +} + +static gboolean +is_vowel_sign (gunichar i) +{ + /* one that combines, whether or not it spaces */ + return (i >= 0xa3e && i <= 0xa4c); +} + +static gunichar +vowel_sign_to_matra (gunichar i) +{ + if (i >= 0xa3e && i <= 0xa4c) + return i - 0xa3e + 0xa06; + return i; +} + +static int +is_consonant (int i) +{ + return (i >= 0xa15 && i <= 0xa39) || + (i >= 0xa59 && i <= 0xa5e); +} + +static int +is_ind_vowel (int i) +{ + return (i >= 0xa05 && i <= 0xa14); +} + +static gboolean +is_vowel_half (gunichar i) +{ + return 0; +} + +static int +is_prefixing_vowel (gunichar what) +{ + return (what == 0xa3f); +} + +static void +pango_indic_make_ligs (gunichar * start, gunichar * end) +{ + int i; + for (i = 0; i < (end-start-2);i++) + { + if (is_consonant (start[i])) + { + if (start[i+2]==RA && start[i+1]==VIRAMA) + { + start[i+1] = 0; + start[i+2] = RA_SUBSCRIPT; + } + } + } +} + +static void +pango_indic_engine_shape (PangoFont * font, + const char *text, + int length, + PangoAnalysis * analysis, PangoGlyphString * glyphs) +{ + PangoXSubfont subfont; + + int n_chars, n_glyph; + int lvl; + const char *p; + int i, k; + gunichar *wc; + int sb; + int n_syls; + gunichar **syls = g_malloc (sizeof (gunichar **)); + + 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 = n_glyph = g_utf8_strlen (text, length); + lvl = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + if (!lvl) + { + pango_x_fallback_shape (font, glyphs, text, n_chars); + return; + } + + pango_indic_split_out_characters (&script, text, n_chars, &wc, + &n_glyph, glyphs); + pango_indic_convert_vowels (&script, TRUE, &n_glyph, wc, FALSE); + + n_syls = 1; + syls[0] = wc; + sb = glyphs->log_clusters[0]; + for (i = 0; i < n_glyph; i++) + { + if (i && (is_consonant (wc[i]) | is_ind_vowel (wc[i])) + && wc[i - 1] != VIRAMA) + { + syls = g_realloc (syls, ((n_syls + 2) * sizeof (gunichar **))); + syls[n_syls] = wc + i; + n_syls++; + sb = glyphs->log_clusters[i]; + } + glyphs->log_clusters[i] = sb; + } + syls[n_syls] = wc + i; + + for (i = 0; i < n_syls; i++) + { + pango_indic_make_ligs (syls[i], syls[i+1]); + pango_indic_shift_vowels (&script, syls[i], syls[i + 1]); + } + + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_x_apply_ligatures (font, subfont, &wc, &n_glyph, &glyphs->log_clusters); + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_glyph_string_set_size (glyphs, n_glyph); + + for (i = 0; i < n_glyph; i++) + { + PangoRectangle logical_rect; + glyphs->glyphs[i].glyph = PANGO_X_MAKE_GLYPH (subfont, wc[i]); + pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, + NULL, &logical_rect); + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + glyphs->glyphs[i].geometry.width = logical_rect.width; + } + g_free (syls); +} + +static PangoEngine * +pango_indic_engine_x_new () +{ + PangoEngineShape *result; + result = g_new (PangoEngineShape, 1); + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_shape = pango_indic_engine_shape; + result->get_coverage = pango_indic_engine_get_coverage; + return (PangoEngine *) result; +} + +static void +pango_indic_engine_break (const char *text, + int len, + PangoAnalysis * analysis, PangoLogAttr * attrs) +{ + const char *cur = text; + gint i = 0; + gunichar wc; + + while (*cur && cur - text < len) + { + wc = g_utf8_get_char (cur); + if (wc == (gunichar)-1) + break; /* FIXME: ERROR */ + + attrs[i].is_white = (wc == ' ' || wc == '\t' || wc == 'n') ? 1 : 0; + attrs[i].is_break = (i > 0 && attrs[i - 1].is_white) || + attrs[i].is_white; + attrs[i].is_char_stop = 1; + attrs[i].is_word_stop = (i == 0) || attrs[i - 1].is_white; + /* actually, is_word_stop in not correct, but simple and good enough. */ + + i++; + cur = g_utf8_next_char (cur); + } +} + + +static PangoEngine * +pango_indic_engine_lang_new () +{ + PangoEngineLang *result; + + result = g_new (PangoEngineLang, 1); + + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_break = pango_indic_engine_break; + + return (PangoEngine *) result; +} + +#ifdef MODULE_PREFIX +#define MODULE_ENTRY(func) _pango_pango_##func +#else +#define MODULE_ENTRY(func) func +#endif + +void +MODULE_ENTRY(script_engine_list) (PangoEngineInfo ** engines, int *n_engines) +{ + *engines = script_engines; + *n_engines = n_script_engines; +} + +PangoEngine * +MODULE_ENTRY(script_engine_load) (const char *id) +{ + if (!strcmp (id, SCRIPT_STRING "ScriptEngineLang")) + return pango_indic_engine_lang_new (); + else if (!strcmp (id, SCRIPT_STRING "ScriptEngineX")) + return pango_indic_engine_x_new (); + else + return NULL; +} + +void +MODULE_ENTRY(script_engine_unload) (PangoEngine * engine) +{ +} diff --git a/modules/indic/gurmukhi.c b/modules/indic/gurmukhi.c new file mode 100644 index 00000000..e448fb22 --- /dev/null +++ b/modules/indic/gurmukhi.c @@ -0,0 +1,301 @@ +/* Pango - Gurmukhi module + * gurmukhi.c: + * + * Copyright (C) 2000 SuSE Linux Ltd + * Author: Robert Brady <robert@suse.co.uk> + * + * 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. + */ + +/* + * This is the renderer for Gurmukhi. This script is primarily used + * to write the Panjabi (pa) language. + */ + + +#include <glib.h> +#include <stdio.h> + +#include "pango.h" +#include "pangox.h" +#include "pango-indic.h" + +#define RANGE_START 0xa00 +#define RANGE_SIZE 0x80 +#define SCRIPT_STRING "Gurmukhi" +#define ISCII_BASED + +#include "pango-indic-script.h" + +static gboolean is_prefixing_vowel (gunichar i); +static gunichar vowel_sign_to_matra (gunichar i); +static gboolean is_vowel_sign (gunichar i); +static gboolean is_vowel_half (gunichar i); + +static PangoIndicScript script = { + SCRIPT_STRING, + &is_prefixing_vowel, + &is_vowel_sign, + &vowel_sign_to_matra, + &is_vowel_half, +}; + +#define RA_SUBSCRIPT 0xea7e + +static char *default_charset = "iso10646-gur"; + +static PangoEngineRange pango_indic_range[] = +{ + {RANGE_START, RANGE_END, "*"}, +}; + +SCRIPT_ENGINE_DEFINITION + +static PangoCoverage * +pango_indic_engine_get_coverage (PangoFont * font, const char *lang) +{ + gunichar i; + PangoCoverage *result = pango_coverage_new (); + PangoXSubfont subfont; + + int dev_font = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + + if (dev_font) + { + for (i = RANGE_START; i <= RANGE_END; i++) + pango_coverage_set (result, i, PANGO_COVERAGE_EXACT); + + } + + return result; +} + +static gboolean +is_vowel_sign (gunichar i) +{ + /* one that combines, whether or not it spaces */ + return (i >= 0xa3e && i <= 0xa4c); +} + +static gunichar +vowel_sign_to_matra (gunichar i) +{ + if (i >= 0xa3e && i <= 0xa4c) + return i - 0xa3e + 0xa06; + return i; +} + +static int +is_consonant (int i) +{ + return (i >= 0xa15 && i <= 0xa39) || + (i >= 0xa59 && i <= 0xa5e); +} + +static int +is_ind_vowel (int i) +{ + return (i >= 0xa05 && i <= 0xa14); +} + +static gboolean +is_vowel_half (gunichar i) +{ + return 0; +} + +static int +is_prefixing_vowel (gunichar what) +{ + return (what == 0xa3f); +} + +static void +pango_indic_make_ligs (gunichar * start, gunichar * end) +{ + int i; + for (i = 0; i < (end-start-2);i++) + { + if (is_consonant (start[i])) + { + if (start[i+2]==RA && start[i+1]==VIRAMA) + { + start[i+1] = 0; + start[i+2] = RA_SUBSCRIPT; + } + } + } +} + +static void +pango_indic_engine_shape (PangoFont * font, + const char *text, + int length, + PangoAnalysis * analysis, PangoGlyphString * glyphs) +{ + PangoXSubfont subfont; + + int n_chars, n_glyph; + int lvl; + const char *p; + int i, k; + gunichar *wc; + int sb; + int n_syls; + gunichar **syls = g_malloc (sizeof (gunichar **)); + + 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 = n_glyph = g_utf8_strlen (text, length); + lvl = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + if (!lvl) + { + pango_x_fallback_shape (font, glyphs, text, n_chars); + return; + } + + pango_indic_split_out_characters (&script, text, n_chars, &wc, + &n_glyph, glyphs); + pango_indic_convert_vowels (&script, TRUE, &n_glyph, wc, FALSE); + + n_syls = 1; + syls[0] = wc; + sb = glyphs->log_clusters[0]; + for (i = 0; i < n_glyph; i++) + { + if (i && (is_consonant (wc[i]) | is_ind_vowel (wc[i])) + && wc[i - 1] != VIRAMA) + { + syls = g_realloc (syls, ((n_syls + 2) * sizeof (gunichar **))); + syls[n_syls] = wc + i; + n_syls++; + sb = glyphs->log_clusters[i]; + } + glyphs->log_clusters[i] = sb; + } + syls[n_syls] = wc + i; + + for (i = 0; i < n_syls; i++) + { + pango_indic_make_ligs (syls[i], syls[i+1]); + pango_indic_shift_vowels (&script, syls[i], syls[i + 1]); + } + + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_x_apply_ligatures (font, subfont, &wc, &n_glyph, &glyphs->log_clusters); + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_glyph_string_set_size (glyphs, n_glyph); + + for (i = 0; i < n_glyph; i++) + { + PangoRectangle logical_rect; + glyphs->glyphs[i].glyph = PANGO_X_MAKE_GLYPH (subfont, wc[i]); + pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, + NULL, &logical_rect); + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + glyphs->glyphs[i].geometry.width = logical_rect.width; + } + g_free (syls); +} + +static PangoEngine * +pango_indic_engine_x_new () +{ + PangoEngineShape *result; + result = g_new (PangoEngineShape, 1); + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_shape = pango_indic_engine_shape; + result->get_coverage = pango_indic_engine_get_coverage; + return (PangoEngine *) result; +} + +static void +pango_indic_engine_break (const char *text, + int len, + PangoAnalysis * analysis, PangoLogAttr * attrs) +{ + const char *cur = text; + gint i = 0; + gunichar wc; + + while (*cur && cur - text < len) + { + wc = g_utf8_get_char (cur); + if (wc == (gunichar)-1) + break; /* FIXME: ERROR */ + + attrs[i].is_white = (wc == ' ' || wc == '\t' || wc == 'n') ? 1 : 0; + attrs[i].is_break = (i > 0 && attrs[i - 1].is_white) || + attrs[i].is_white; + attrs[i].is_char_stop = 1; + attrs[i].is_word_stop = (i == 0) || attrs[i - 1].is_white; + /* actually, is_word_stop in not correct, but simple and good enough. */ + + i++; + cur = g_utf8_next_char (cur); + } +} + + +static PangoEngine * +pango_indic_engine_lang_new () +{ + PangoEngineLang *result; + + result = g_new (PangoEngineLang, 1); + + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_break = pango_indic_engine_break; + + return (PangoEngine *) result; +} + +#ifdef MODULE_PREFIX +#define MODULE_ENTRY(func) _pango_pango_##func +#else +#define MODULE_ENTRY(func) func +#endif + +void +MODULE_ENTRY(script_engine_list) (PangoEngineInfo ** engines, int *n_engines) +{ + *engines = script_engines; + *n_engines = n_script_engines; +} + +PangoEngine * +MODULE_ENTRY(script_engine_load) (const char *id) +{ + if (!strcmp (id, SCRIPT_STRING "ScriptEngineLang")) + return pango_indic_engine_lang_new (); + else if (!strcmp (id, SCRIPT_STRING "ScriptEngineX")) + return pango_indic_engine_x_new (); + else + return NULL; +} + +void +MODULE_ENTRY(script_engine_unload) (PangoEngine * engine) +{ +} diff --git a/modules/indic/myanmar-x.c b/modules/indic/myanmar-x.c new file mode 100644 index 00000000..ae0424c6 --- /dev/null +++ b/modules/indic/myanmar-x.c @@ -0,0 +1,281 @@ +/* Pango - Myanmar module + * myanmar.c: + * + * Copyright (C) 2000 SuSE Linux Ltd + * Author: Robert Brady <robert@suse.co.uk> + * + * 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. + */ + +/* + * This is the renderer for the Burmese (Myanmar) script. This + * script is used to write the following languages : + * + * my Burmese + * shn Shan + * mkh Mon + * pi Pali + * + */ + + +#include <glib.h> +#include <stdio.h> + +#include "pango.h" +#include "pangox.h" +#include "pango-indic.h" + +#define RANGE_START 0x1000 +#define RANGE_SIZE 0x80 +#define SCRIPT_STRING "Myanmar" +#define VIRAMA 0x1039 + +#include "pango-indic-script.h" + +static gboolean is_prefixing_vowel (gunichar i); +static gboolean is_vowel_sign (gunichar i); +static gunichar vowel_sign_to_matra (gunichar i); + +static PangoIndicScript script = { + SCRIPT_STRING, + &is_prefixing_vowel, + &is_vowel_sign, + &vowel_sign_to_matra, +}; + +static char *default_charset = "iso10646-brm"; + +static PangoEngineRange pango_indic_range[] = +{ + {RANGE_START, RANGE_END, "*"}, +}; + +SCRIPT_ENGINE_DEFINITION + +static PangoCoverage * +pango_engine_get_coverage (PangoFont * font, const char *lang) +{ + gunichar i; + PangoCoverage *result = pango_coverage_new (); + PangoXSubfont subfont; + + int dev_font = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + + if (dev_font) + { + for (i = RANGE_START; i <= RANGE_END; i++) + pango_coverage_set (result, i, PANGO_COVERAGE_EXACT); + + } + + return result; +} + +static gboolean +is_vowel_sign (gunichar i) +{ + /* one that combines, whether or not it spaces */ + return (i >= 0x102c && i <= 0x1032) || (i >= 0x1056 && i <= 0x1059); +} + +static gunichar +vowel_sign_to_matra (gunichar i) +{ + if (i >= 0x102d && i <= 0x1032) + return i - 0x102d + 0x1023; + return i; +} + +static int +is_consonant (int i) +{ + return (i >= 0x1000 && i <= 0x1020) || (i >= 0x1052 && i <= 0x1053); +} + +static int +is_ind_vowel (int i) +{ + return (i >= 0x1021 && i <= 0x102a); +} + +static int +is_prefixing_vowel (gunichar what) +{ + return (what == 0x1031); +} + +static void +pango_engine_shape (PangoFont * font, + const char *text, + int length, + PangoAnalysis * analysis, PangoGlyphString * glyphs) +{ + PangoXSubfont subfont; + + int n_chars, n_glyph; + int lvl; + const char *p; + int i, k; + gunichar *wc; + int sb; + int n_syls; + gunichar **syls = g_malloc (sizeof (gunichar **)); + + 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 = n_glyph = g_utf8_strlen (text, length); + lvl = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + if (!lvl) + { + pango_x_fallback_shape (font, glyphs, text, n_chars); + return; + } + + pango_indic_split_out_characters (&script, text, n_chars, &wc, + &n_glyph, glyphs); + pango_indic_convert_vowels (&script, FALSE, &n_glyph, wc, FALSE); + + n_syls = 1; + syls[0] = wc; + sb = glyphs->log_clusters[0]; + for (i = 0; i < n_glyph; i++) + { + if (i && (is_consonant (wc[i]) | is_ind_vowel (wc[i])) + && wc[i - 1] != VIRAMA) + { + syls = g_realloc (syls, ((n_syls + 2) * sizeof (gunichar **))); + syls[n_syls] = wc + i; + n_syls++; + sb = glyphs->log_clusters[i]; + } + glyphs->log_clusters[i] = sb; + } + syls[n_syls] = wc + i; + + for (i = 0; i < n_syls; i++) + { + pango_indic_shift_vowels (&script, syls[i], syls[i + 1]); + } + + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + while ((i=pango_x_apply_ligatures (font, subfont, &wc, &n_glyph, &glyphs->log_clusters))) + { + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + } + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_glyph_string_set_size (glyphs, n_glyph); + + for (i = 0; i < n_glyph; i++) + { + PangoRectangle logical_rect; + glyphs->glyphs[i].glyph = PANGO_X_MAKE_GLYPH (subfont, wc[i]); + pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, + NULL, &logical_rect); + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + glyphs->glyphs[i].geometry.width = logical_rect.width; + } + g_free (syls); +} + +static PangoEngine * +pango_engine_x_new () +{ + PangoEngineShape *result; + result = g_new (PangoEngineShape, 1); + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_shape = pango_engine_shape; + result->get_coverage = pango_engine_get_coverage; + return (PangoEngine *) result; +} + +static void +pango_engine_break (const char *text, + int len, + PangoAnalysis * analysis, PangoLogAttr * attrs) +{ + const char *cur = text; + gint i = 0; + gunichar wc; + + while (*cur && cur - text < len) + { + wc = g_utf8_get_char (cur); + if (wc == (gunichar)-1) + break; /* FIXME: ERROR */ + + attrs[i].is_white = (wc == ' ' || wc == '\t' || wc == 'n') ? 1 : 0; + attrs[i].is_break = (i > 0 && attrs[i - 1].is_white) || + attrs[i].is_white; + attrs[i].is_char_stop = 1; + attrs[i].is_word_stop = (i == 0) || attrs[i - 1].is_white; + /* actually, is_word_stop in not correct, but simple and good enough. */ + + i++; + cur = g_utf8_next_char (cur); + } +} + + +static PangoEngine * +pango_engine_lang_new () +{ + PangoEngineLang *result; + + result = g_new (PangoEngineLang, 1); + + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_break = pango_engine_break; + + return (PangoEngine *) result; +} + +#ifdef MODULE_PREFIX +#define MODULE_ENTRY(func) _pango_pango_##func +#else +#define MODULE_ENTRY(func) func +#endif + +void +MODULE_ENTRY(script_engine_list) (PangoEngineInfo ** engines, int *n_engines) +{ + *engines = script_engines; + *n_engines = n_script_engines; +} + +PangoEngine * +MODULE_ENTRY(script_engine_load) (const char *id) +{ + if (!strcmp (id, SCRIPT_STRING "ScriptEngineLang")) + return pango_engine_lang_new (); + else if (!strcmp (id, SCRIPT_STRING "ScriptEngineX")) + return pango_engine_x_new (); + else + return NULL; +} + +void +MODULE_ENTRY(script_engine_unload) (PangoEngine * engine) +{ +} diff --git a/modules/indic/myanmar.c b/modules/indic/myanmar.c new file mode 100644 index 00000000..ae0424c6 --- /dev/null +++ b/modules/indic/myanmar.c @@ -0,0 +1,281 @@ +/* Pango - Myanmar module + * myanmar.c: + * + * Copyright (C) 2000 SuSE Linux Ltd + * Author: Robert Brady <robert@suse.co.uk> + * + * 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. + */ + +/* + * This is the renderer for the Burmese (Myanmar) script. This + * script is used to write the following languages : + * + * my Burmese + * shn Shan + * mkh Mon + * pi Pali + * + */ + + +#include <glib.h> +#include <stdio.h> + +#include "pango.h" +#include "pangox.h" +#include "pango-indic.h" + +#define RANGE_START 0x1000 +#define RANGE_SIZE 0x80 +#define SCRIPT_STRING "Myanmar" +#define VIRAMA 0x1039 + +#include "pango-indic-script.h" + +static gboolean is_prefixing_vowel (gunichar i); +static gboolean is_vowel_sign (gunichar i); +static gunichar vowel_sign_to_matra (gunichar i); + +static PangoIndicScript script = { + SCRIPT_STRING, + &is_prefixing_vowel, + &is_vowel_sign, + &vowel_sign_to_matra, +}; + +static char *default_charset = "iso10646-brm"; + +static PangoEngineRange pango_indic_range[] = +{ + {RANGE_START, RANGE_END, "*"}, +}; + +SCRIPT_ENGINE_DEFINITION + +static PangoCoverage * +pango_engine_get_coverage (PangoFont * font, const char *lang) +{ + gunichar i; + PangoCoverage *result = pango_coverage_new (); + PangoXSubfont subfont; + + int dev_font = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + + if (dev_font) + { + for (i = RANGE_START; i <= RANGE_END; i++) + pango_coverage_set (result, i, PANGO_COVERAGE_EXACT); + + } + + return result; +} + +static gboolean +is_vowel_sign (gunichar i) +{ + /* one that combines, whether or not it spaces */ + return (i >= 0x102c && i <= 0x1032) || (i >= 0x1056 && i <= 0x1059); +} + +static gunichar +vowel_sign_to_matra (gunichar i) +{ + if (i >= 0x102d && i <= 0x1032) + return i - 0x102d + 0x1023; + return i; +} + +static int +is_consonant (int i) +{ + return (i >= 0x1000 && i <= 0x1020) || (i >= 0x1052 && i <= 0x1053); +} + +static int +is_ind_vowel (int i) +{ + return (i >= 0x1021 && i <= 0x102a); +} + +static int +is_prefixing_vowel (gunichar what) +{ + return (what == 0x1031); +} + +static void +pango_engine_shape (PangoFont * font, + const char *text, + int length, + PangoAnalysis * analysis, PangoGlyphString * glyphs) +{ + PangoXSubfont subfont; + + int n_chars, n_glyph; + int lvl; + const char *p; + int i, k; + gunichar *wc; + int sb; + int n_syls; + gunichar **syls = g_malloc (sizeof (gunichar **)); + + 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 = n_glyph = g_utf8_strlen (text, length); + lvl = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); + if (!lvl) + { + pango_x_fallback_shape (font, glyphs, text, n_chars); + return; + } + + pango_indic_split_out_characters (&script, text, n_chars, &wc, + &n_glyph, glyphs); + pango_indic_convert_vowels (&script, FALSE, &n_glyph, wc, FALSE); + + n_syls = 1; + syls[0] = wc; + sb = glyphs->log_clusters[0]; + for (i = 0; i < n_glyph; i++) + { + if (i && (is_consonant (wc[i]) | is_ind_vowel (wc[i])) + && wc[i - 1] != VIRAMA) + { + syls = g_realloc (syls, ((n_syls + 2) * sizeof (gunichar **))); + syls[n_syls] = wc + i; + n_syls++; + sb = glyphs->log_clusters[i]; + } + glyphs->log_clusters[i] = sb; + } + syls[n_syls] = wc + i; + + for (i = 0; i < n_syls; i++) + { + pango_indic_shift_vowels (&script, syls[i], syls[i + 1]); + } + + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + while ((i=pango_x_apply_ligatures (font, subfont, &wc, &n_glyph, &glyphs->log_clusters))) + { + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + } + pango_indic_compact (&script, &n_glyph, wc, glyphs->log_clusters); + pango_glyph_string_set_size (glyphs, n_glyph); + + for (i = 0; i < n_glyph; i++) + { + PangoRectangle logical_rect; + glyphs->glyphs[i].glyph = PANGO_X_MAKE_GLYPH (subfont, wc[i]); + pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, + NULL, &logical_rect); + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + glyphs->glyphs[i].geometry.width = logical_rect.width; + } + g_free (syls); +} + +static PangoEngine * +pango_engine_x_new () +{ + PangoEngineShape *result; + result = g_new (PangoEngineShape, 1); + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_shape = pango_engine_shape; + result->get_coverage = pango_engine_get_coverage; + return (PangoEngine *) result; +} + +static void +pango_engine_break (const char *text, + int len, + PangoAnalysis * analysis, PangoLogAttr * attrs) +{ + const char *cur = text; + gint i = 0; + gunichar wc; + + while (*cur && cur - text < len) + { + wc = g_utf8_get_char (cur); + if (wc == (gunichar)-1) + break; /* FIXME: ERROR */ + + attrs[i].is_white = (wc == ' ' || wc == '\t' || wc == 'n') ? 1 : 0; + attrs[i].is_break = (i > 0 && attrs[i - 1].is_white) || + attrs[i].is_white; + attrs[i].is_char_stop = 1; + attrs[i].is_word_stop = (i == 0) || attrs[i - 1].is_white; + /* actually, is_word_stop in not correct, but simple and good enough. */ + + i++; + cur = g_utf8_next_char (cur); + } +} + + +static PangoEngine * +pango_engine_lang_new () +{ + PangoEngineLang *result; + + result = g_new (PangoEngineLang, 1); + + result->engine.id = SCRIPT_STRING "ScriptEngine"; + result->engine.type = PANGO_ENGINE_TYPE_LANG; + result->engine.length = sizeof (result); + result->script_break = pango_engine_break; + + return (PangoEngine *) result; +} + +#ifdef MODULE_PREFIX +#define MODULE_ENTRY(func) _pango_pango_##func +#else +#define MODULE_ENTRY(func) func +#endif + +void +MODULE_ENTRY(script_engine_list) (PangoEngineInfo ** engines, int *n_engines) +{ + *engines = script_engines; + *n_engines = n_script_engines; +} + +PangoEngine * +MODULE_ENTRY(script_engine_load) (const char *id) +{ + if (!strcmp (id, SCRIPT_STRING "ScriptEngineLang")) + return pango_engine_lang_new (); + else if (!strcmp (id, SCRIPT_STRING "ScriptEngineX")) + return pango_engine_x_new (); + else + return NULL; +} + +void +MODULE_ENTRY(script_engine_unload) (PangoEngine * engine) +{ +} diff --git a/modules/indic/pango-indic-script.h b/modules/indic/pango-indic-script.h new file mode 100644 index 00000000..90c69eca --- /dev/null +++ b/modules/indic/pango-indic-script.h @@ -0,0 +1,40 @@ +#ifndef __INDIC_SCRIPT__ +#define __INDIC_SCRIPT__ + +#define RANGE_END (RANGE_START + RANGE_SIZE - 1) + +#ifdef ISCII_BASED +#define VIRAMA (0x4d + RANGE_START) +#define CANDRA (0x01 + RANGE_START) +#define ANUSWAR (0x02 + RANGE_START) +#define NUKTA (0x3c + RANGE_START) +#define RA (0x30 + RANGE_START) +#endif + +#define SCRIPT_ENGINE_DEFINITION \ + static PangoEngineInfo script_engines[] = \ + { \ + { \ + SCRIPT_STRING "ScriptEngineLang", \ + PANGO_ENGINE_TYPE_LANG, \ + PANGO_RENDER_TYPE_NONE, \ + pango_indic_range, G_N_ELEMENTS (pango_indic_range)}, \ + { \ + SCRIPT_STRING "ScriptEngineX", \ + PANGO_ENGINE_TYPE_SHAPE, \ + PANGO_RENDER_TYPE_X, \ + pango_indic_range, G_N_ELEMENTS (pango_indic_range)} \ + }; \ + static gint n_script_engines = G_N_ELEMENTS (script_engines); + +inline gunichar +pango_indic_get_char (gunichar * chars, + gunichar * end) +{ + if (chars >= end) + return 0; + return *chars; +} + + +#endif |