diff options
-rw-r--r-- | configure.in | 18 | ||||
-rw-r--r-- | modules/Makefile.am | 6 | ||||
-rw-r--r-- | modules/hangul/Makefile.am | 26 | ||||
-rw-r--r-- | modules/hangul/hangul-defs.h | 91 | ||||
-rw-r--r-- | modules/hangul/hangul-fc.c | 499 | ||||
-rw-r--r-- | modules/hangul/tables-jamos.i | 401 | ||||
-rw-r--r-- | modules/hebrew/Makefile.am | 24 | ||||
-rw-r--r-- | modules/hebrew/hebrew-fc.c | 355 | ||||
-rw-r--r-- | modules/hebrew/hebrew-shaper.c | 477 | ||||
-rw-r--r-- | modules/hebrew/hebrew-shaper.h | 50 | ||||
-rw-r--r-- | modules/khmer/Makefile.am | 23 | ||||
-rw-r--r-- | modules/khmer/khmer-fc.c | 721 | ||||
-rw-r--r-- | modules/tibetan/Makefile.am | 22 | ||||
-rw-r--r-- | modules/tibetan/tibetan-fc.c | 574 |
14 files changed, 2 insertions, 3285 deletions
diff --git a/configure.in b/configure.in index d87be78d..e2513c2b 100644 --- a/configure.in +++ b/configure.in @@ -513,18 +513,14 @@ GOBJECT_INTROSPECTION_CHECK([0.9.5]) # arabic_modules="arabic-lang" basic_modules="basic-fc,basic-win32,basic-x,basic-atsui,basic-coretext" -hangul_modules="hangul-fc" -hebrew_modules="hebrew-fc" indic_modules="indic-fc,indic-lang" -khmer_modules="khmer-fc" thai_modules="thai-fc" -tibetan_modules="tibetan-fc" if $have_libthai ; then thai_modules="$thai_modules,thai-lang" fi -all_modules="$arabic_modules,$basic_modules,$hangul_modules,$hebrew_modules,$indic_modules,$khmer_modules,$thai_modules,$tibetan_modules" +all_modules="$arabic_modules,$basic_modules,$indic_modules,$thai_modules" # # Allow building some or all modules included @@ -603,14 +599,10 @@ AM_CONDITIONAL(INCLUDE_BASIC_WIN32, echo $included_modules | egrep '(^|,)basic-w AM_CONDITIONAL(INCLUDE_BASIC_X, echo $included_modules | egrep '(^|,)basic-x($|,)' > /dev/null) AM_CONDITIONAL(INCLUDE_BASIC_ATSUI, echo $included_modules | egrep '(^|,)basic-atsui($|,)' > /dev/null) AM_CONDITIONAL(INCLUDE_BASIC_CORE_TEXT, echo $included_modules | egrep '(^|,)basic-coretext($|,)' > /dev/null) -AM_CONDITIONAL(INCLUDE_HANGUL_FC, echo $included_modules | egrep '(^|,)hangul-fc($|,)' > /dev/null) -AM_CONDITIONAL(INCLUDE_HEBREW_FC, echo $included_modules | egrep '(^|,)hebrew-fc($|,)' > /dev/null) AM_CONDITIONAL(INCLUDE_INDIC_FC, echo $included_modules | egrep '(^|,)indic-fc($|,)' > /dev/null) AM_CONDITIONAL(INCLUDE_INDIC_LANG, echo $included_modules | egrep '(^|,)indic-lang($|,)' > /dev/null) -AM_CONDITIONAL(INCLUDE_KHMER_FC, echo $included_modules | egrep '(^|,)khmer-fc($|,)' > /dev/null) AM_CONDITIONAL(INCLUDE_THAI_FC, echo $included_modules | egrep '(^|,)thai-fc($|,)' > /dev/null) AM_CONDITIONAL(INCLUDE_THAI_LANG, echo $included_modules | egrep '(^|,)thai-lang($|,)' > /dev/null) -AM_CONDITIONAL(INCLUDE_TIBETAN_FC, echo $included_modules | egrep '(^|,)tibetan-fc($|,)' > /dev/null) AM_CONDITIONAL(DYNAMIC_ARABIC_LANG, echo $dynamic_modules | egrep '(^|,)arabic-lang($|,)' > /dev/null) AM_CONDITIONAL(DYNAMIC_BASIC_FC, echo $dynamic_modules | egrep '(^|,)basic-fc($|,)' > /dev/null) @@ -618,14 +610,10 @@ AM_CONDITIONAL(DYNAMIC_BASIC_WIN32, echo $dynamic_modules | egrep '(^|,)basic-wi AM_CONDITIONAL(DYNAMIC_BASIC_X, echo $dynamic_modules | egrep '(^|,)basic-x($|,)' > /dev/null) AM_CONDITIONAL(DYNAMIC_BASIC_ATSUI, echo $dynamic_modules | egrep '(^|,)basic-atsui($|,)' > /dev/null) AM_CONDITIONAL(DYNAMIC_BASIC_CORE_TEXT, echo $dynamic_modules | egrep '(^|,)basic-coretext($|,)' > /dev/null) -AM_CONDITIONAL(DYNAMIC_HANGUL_FC, echo $dynamic_modules | egrep '(^|,)hangul-fc($|,)' > /dev/null) -AM_CONDITIONAL(DYNAMIC_HEBREW_FC, echo $dynamic_modules | egrep '(^|,)hebrew-fc($|,)' > /dev/null) AM_CONDITIONAL(DYNAMIC_INDIC_FC, echo $dynamic_modules | egrep '(^|,)indic-fc($|,)' > /dev/null) AM_CONDITIONAL(DYNAMIC_INDIC_LANG, echo $dynamic_modules | egrep '(^|,)indic-lang($|,)' > /dev/null) -AM_CONDITIONAL(DYNAMIC_KHMER_FC, echo $dynamic_modules | egrep '(^|,)khmer-fc($|,)' > /dev/null) AM_CONDITIONAL(DYNAMIC_THAI_FC, echo $dynamic_modules | egrep '(^|,)thai-fc($|,)' > /dev/null) AM_CONDITIONAL(DYNAMIC_THAI_LANG, echo $dynamic_modules | egrep '(^|,)thai-lang($|,)' > /dev/null) -AM_CONDITIONAL(DYNAMIC_TIBETAN_FC, echo $dynamic_modules | egrep '(^|,)tibetan-fc($|,)' > /dev/null) # # We use flockfile to implement pango_getline() - should be moved to GLib @@ -1023,12 +1011,8 @@ pango-view/Makefile modules/Makefile modules/arabic/Makefile modules/basic/Makefile -modules/hangul/Makefile -modules/hebrew/Makefile modules/indic/Makefile -modules/khmer/Makefile modules/thai/Makefile -modules/tibetan/Makefile examples/Makefile docs/Makefile docs/version.xml diff --git a/modules/Makefile.am b/modules/Makefile.am index 802c8b54..73b42f4d 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -3,12 +3,8 @@ SUBDIRS = \ arabic \ basic \ - hangul \ - hebrew \ indic \ - khmer \ - thai \ - tibetan + thai EXTRA_DIST = \ Module.mk \ diff --git a/modules/hangul/Makefile.am b/modules/hangul/Makefile.am deleted file mode 100644 index 4937d1b7..00000000 --- a/modules/hangul/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -include $(top_srcdir)/modules/Module.mk - -if HAVE_FREETYPE -INCLUDES += $(FREETYPE_CFLAGS) -if INCLUDE_HANGUL_FC -noinst_LTLIBRARIES += libpango-hangul-fc.la -else -if DYNAMIC_HANGUL_FC -module_LTLIBRARIES += pango-hangul-fc.la -endif -endif -endif - -fc_sources = hangul-fc.c hangul-defs.h - -pango_hangul_fc_la_LDFLAGS = -module $(MODULE_LIBTOOL_OPTIONS) -pango_hangul_fc_la_LIBADD = $(pangoft2libs) -pango_hangul_fc_la_SOURCES = $(fc_sources) -libpango_hangul_fc_la_SOURCES = $(fc_sources) -libpango_hangul_fc_la_CFLAGS = -DPANGO_MODULE_PREFIX=_pango_hangul_fc - - -EXTRA_DIST = \ - tables-jamos.i - --include $(top_srcdir)/git.mk diff --git a/modules/hangul/hangul-defs.h b/modules/hangul/hangul-defs.h deleted file mode 100644 index 8cef8ba8..00000000 --- a/modules/hangul/hangul-defs.h +++ /dev/null @@ -1,91 +0,0 @@ -/* Pango - * hangul-defs.h: - * - * Copyright (C) 2002-2006 Changwoo Ryu - * Author: Changwoo Ryu <cwryu@debian.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. - */ - -/* See 3.12 "Conjoining Jamo Behavior" in the Unicode Book for more - * information - */ - -/* The start of the Hangul Syllables (U+AC00-U+D7A3) */ -#define SBASE 0xAC00 -#define SCOUNT 11172 - -/* The starts/ends of the leading consonants (choseong), the vowels - * (jungseong) and the trailing consonants (jongseong). - */ -#define LBASE 0x1100 -#define VBASE 0x1161 -#define TBASE 0x11A7 -#define LEND 0x115F -#define VEND 0x11A7 -#define TEND 0x11FF - -/* Number of modern jamos */ -#define LCOUNT 19 -#define VCOUNT 21 -#define TCOUNT 28 -#define NCOUNT (VCOUNT * TCOUNT) /* number of syllables of a given choseong */ - -/* choseong and jungseong filler */ -#define LFILL 0x115F -#define VFILL 0x1160 - -/* Old tone marks. */ -#define HTONE1 0x302E -#define HTONE2 0x302F - -/* Useful macros - */ - -#define IS_JAMO(wc) ((wc) >= LBASE && (wc) <= TEND) -#define IS_L(wc) ((wc) >= LBASE && (wc) <= LEND) -#define IS_V(wc) ((wc) >= VFILL && (wc) <= VEND) -#define IS_T(wc) ((wc) > TBASE && (wc) <= TEND) -#define IS_M(wc) ((wc) == HTONE1 || (wc) == HTONE2) -#define IS_S(wc) (SBASE <= (wc) && (wc) < (SBASE + SCOUNT)) - -/* jamo which can be composited as a precomposed syllable */ -#define IS_L_S(wc) ((wc) >= LBASE && (wc) < (LBASE + LCOUNT)) -#define IS_V_S(wc) ((wc) >= VBASE && (wc) < (VBASE + VCOUNT)) -#define IS_T_S(wc) ((wc) > TBASE && (wc) < (TBASE + TCOUNT)) - -/* if a syllable has a jongseong */ -#define S_HAS_T(s) (((s) - SBASE) % TCOUNT) - -/* non hangul */ -#define IS_HANGUL(wc) (IS_S(wc) || IS_JAMO(wc) || IS_M(wc)) - -/* syllable boundary condition */ -#define IS_BOUNDARY(prev,next) \ - ((!IS_L(prev) && IS_S(wc)) || \ - !IS_HANGUL(next) || \ - (IS_S(prev) && S_HAS_T(prev) && IS_L(next)) || \ - (IS_T(prev) && (IS_L(next) || IS_V(next))) || \ - (IS_S(prev) && !S_HAS_T(prev) && IS_L(next)) || \ - (IS_V(prev) && IS_L(next)) || \ - IS_M(prev)) - -/* composing/decomposing */ -#define S_FROM_LVT(l,v,t) (SBASE + (((l) - LBASE) * VCOUNT + ((v) - VBASE)) * TCOUNT + ((t) - TBASE)) -#define S_FROM_LV(l,v) (SBASE + (((l) - LBASE) * VCOUNT + ((v) - VBASE)) * TCOUNT) -#define L_FROM_S(s) (LBASE + (((s) - SBASE) / NCOUNT)) -#define V_FROM_S(s) (VBASE + (((s) - SBASE) % NCOUNT) / TCOUNT) -#define T_FROM_S(s) (TBASE + (((s) - SBASE) % TCOUNT)) diff --git a/modules/hangul/hangul-fc.c b/modules/hangul/hangul-fc.c deleted file mode 100644 index 2ef56ec9..00000000 --- a/modules/hangul/hangul-fc.c +++ /dev/null @@ -1,499 +0,0 @@ -/* Pango - * hangul-fc.c: Hangul shaper for FreeType based backends - * - * Copyright (C) 2002-2006 Changwoo Ryu - * Author: Changwoo Ryu <cwryu@debian.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 "config.h" -#include <string.h> - -#include "pango-engine.h" -#include "pango-utils.h" -#include "pangofc-font.h" - -#include "hangul-defs.h" -#include "tables-jamos.i" - -/* No extra fields needed */ -typedef PangoEngineShape HangulEngineFc; -typedef PangoEngineShapeClass HangulEngineFcClass ; - -#define SCRIPT_ENGINE_NAME "HangulScriptEngineFc" -#define RENDER_TYPE PANGO_RENDER_TYPE_FC - -static PangoEngineScriptInfo hangul_scripts[] = { - { PANGO_SCRIPT_HANGUL, "*" } -}; - -static PangoEngineInfo script_engines[] = { - { - SCRIPT_ENGINE_NAME, - PANGO_ENGINE_TYPE_SHAPE, - RENDER_TYPE, - hangul_scripts, G_N_ELEMENTS(hangul_scripts) - } -}; - -static void -set_glyph (PangoFont *font, PangoGlyphString *glyphs, int i, int offset, PangoGlyph glyph) -{ - PangoRectangle logical_rect; - - glyphs->glyphs[i].glyph = glyph; - glyphs->glyphs[i].geometry.x_offset = 0; - glyphs->glyphs[i].geometry.y_offset = 0; - glyphs->log_clusters[i] = offset; - - pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, NULL, &logical_rect); - glyphs->glyphs[i].geometry.width = logical_rect.width; -} - -/* Add a Hangul tone mark glyph in a glyph string. - * Non-spacing glyph works pretty much automatically. - * Spacing-glyph takes some care: - * 1. Make a room for a tone mark at the beginning(leftmost end) of a cluster - * to attach it to. - * 2. Adjust x_offset so that it is drawn to the left of a cluster. - * 3. Set the logical width to zero. - */ - -static void -set_glyph_tone (PangoFont *font, PangoGlyphString *glyphs, int i, - int offset, PangoGlyph glyph) -{ - PangoRectangle logical_rect, ink_rect; - PangoRectangle logical_rect_cluster; - - glyphs->glyphs[i].glyph = glyph; - glyphs->glyphs[i].geometry.y_offset = 0; - glyphs->log_clusters[i] = offset; - - pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, - &ink_rect, &logical_rect); - - /* tone mark is not the first in a glyph string. We have info. on the - * preceding glyphs in a glyph string - */ - { - int j = i - 1; - /* search for the beg. of the preceding cluster */ - while (j >= 0 && glyphs->log_clusters[j] == glyphs->log_clusters[i - 1]) - j--; - - /* In .._extents_range(...,start,end,...), to my surprise start is - * inclusive but end is exclusive !! - */ - pango_glyph_string_extents_range (glyphs, j + 1, i, font, - NULL, &logical_rect_cluster); - - /* logical_rect_cluster.width is all the offset we need so that the - * inherent x_offset in the glyph (ink_rect.x) should be canceled out. - */ - glyphs->glyphs[i].geometry.x_offset = - logical_rect_cluster.width - - ink_rect.x ; - - - /* make an additional room for a tone mark if it has a spacing glyph - * because that's likely to be an indication that glyphs for other - * characters in the font are not designed for combining with tone marks. - */ - if (logical_rect.width) - { - glyphs->glyphs[i].geometry.x_offset -= ink_rect.width; - glyphs->glyphs[j + 1].geometry.width += ink_rect.width; - glyphs->glyphs[j + 1].geometry.x_offset += ink_rect.width; - } - } - - glyphs->glyphs[i].geometry.width = 0; -} - - -#define find_char(font,wc) \ - pango_fc_font_get_glyph((PangoFcFont *)font, wc) - -static void -render_tone (PangoFont *font, gunichar tone, PangoGlyphString *glyphs, - int *n_glyphs, int cluster_offset) -{ - int index; - - index = find_char (font, tone); - pango_glyph_string_set_size (glyphs, *n_glyphs + 1); - if (index) - { - set_glyph_tone (font, glyphs, *n_glyphs, cluster_offset, index); - } - else - { - /* fall back : HTONE1(0x302e) => middle-dot, HTONE2(0x302f) => colon */ - index = find_char (font, tone == HTONE1 ? 0x00b7 : 0x003a); - if (index) - { - set_glyph_tone (font, glyphs, *n_glyphs, cluster_offset, index); - } - else - set_glyph (font, glyphs, *n_glyphs, cluster_offset, - PANGO_GET_UNKNOWN_GLYPH (tone)); - } - (*n_glyphs)++; -} - -/* This is a fallback for when we get a tone mark not preceded - * by a syllable. - */ -static void -render_isolated_tone (PangoFont *font, gunichar tone, PangoGlyphString *glyphs, - int *n_glyphs, int cluster_offset) -{ -#if 0 /* FIXME: what kind of hack is it? it draws dummy glyphs. */ - /* Find a base character to render the mark on - */ - int index = find_char (font, 0x25cc); /* DOTTED CIRCLE */ - if (!index) - index = find_char (font, 0x25cb); /* WHITE CIRCLE, in KSC-5601 */ - if (!index) - index = find_char (font, ' '); /* Space */ - if (!index) /* Unknown glyph box with 0000 in it */ - index = find_char (font, PANGO_GET_UNKNOWN_GLYPH (0)); - - /* Add the base character - */ - pango_glyph_string_set_size (glyphs, *n_glyphs + 1); - set_glyph (font, glyphs, *n_glyphs, cluster_offset, index); - (*n_glyphs)++; -#endif - - /* And the tone mark - */ - render_tone(font, tone, glyphs, n_glyphs, cluster_offset); -} - -static void -render_syllable (PangoFont *font, const char *str, int length, - PangoGlyphString *glyphs, int *n_glyphs, int cluster_offset) -{ - int n_prev_glyphs = *n_glyphs; - int index; - gunichar wc = 0, tone = 0, text[4]; - int i, j, composed = 0; - const char *p; - - /* Normalize it only when the entire sequence is equivalent to a - * precomposed syllable. It's usually better than prefix - * normalization both for poor-featured fonts and for smart fonts. - * I have seen no smart font which can render S+T as a syllable - * form. - */ - - if (length == 3 || length == 4) - { - p = str; - text[0] = g_utf8_get_char(p); - p = g_utf8_next_char(p); - text[1] = g_utf8_get_char(p); - p = g_utf8_next_char(p); - text[2] = g_utf8_get_char(p); - - if (length == 4 && !IS_M(g_utf8_get_char(g_utf8_next_char(p)))) - goto lvt_out; /* draw the tone mark later */ - - if (IS_L_S(text[0]) && IS_V_S(text[1]) && IS_T_S(text[2])) - { - composed = 3; - wc = S_FROM_LVT(text[0], text[1], text[2]); - str = g_utf8_next_char(p); - goto normalize_out; - } - } - lvt_out: - - if (length == 2 || length == 3) - { - p = str; - text[0] = g_utf8_get_char(p); - p = g_utf8_next_char(p); - text[1] = g_utf8_get_char(p); - - if (length == 3 && !IS_M(g_utf8_get_char(g_utf8_next_char(p)))) - goto lv_out; /* draw the tone mark later */ - if (IS_L_S(text[0]) && IS_V_S(text[1])) - { - composed = 2; - wc = S_FROM_LV(text[0], text[1]); - str = g_utf8_next_char(p); - } - else if (IS_S(text[0] && !S_HAS_T(text[0]) && IS_T_S(text[1]))) - { - composed = 2; - wc = text[0] + (text[1] - TBASE); - str = g_utf8_next_char(p); - goto normalize_out; - } - } - lv_out: - normalize_out: - - if (composed) - { - index = find_char (font, wc); - pango_glyph_string_set_size (glyphs, *n_glyphs + 1); - if (!index) - set_glyph (font, glyphs, *n_glyphs, cluster_offset, - PANGO_GET_UNKNOWN_GLYPH (wc)); - else - set_glyph (font, glyphs, *n_glyphs, cluster_offset, index); - (*n_glyphs)++; - length -= composed; - } - - /* Render the remaining text as uncomposed forms as a fallback. */ - for (i = 0; i < length; i++, str = g_utf8_next_char(str)) - { - int jindex; - int oldlen; - - wc = g_utf8_get_char(str); - - if (wc == LFILL || wc == VFILL) - continue; - - if (IS_M(wc)) - { - tone = wc; - break; - } - - if (IS_S(wc)) - { - oldlen = *n_glyphs; - - text[0] = L_FROM_S(wc); - text[1] = V_FROM_S(wc); - if (S_HAS_T(wc)) - { - text[2] = T_FROM_S(wc); - composed = 3; - } - else - composed = 2; - - for (j = 0; j < composed; j++) - { - index = find_char (font, text[j]); - if (index) - { - pango_glyph_string_set_size (glyphs, *n_glyphs + 1); - set_glyph (font, glyphs, *n_glyphs, cluster_offset, index); - (*n_glyphs)++; - } - else - goto decompose_cancel; - } - - continue; - - decompose_cancel: - /* The font doesn't have jamos. Cancel it. */ - *n_glyphs = oldlen; - pango_glyph_string_set_size (glyphs, *n_glyphs); - } - - index = find_char (font, wc); - if (index) - { - pango_glyph_string_set_size (glyphs, *n_glyphs + 1); - set_glyph (font, glyphs, *n_glyphs, cluster_offset, index); - (*n_glyphs)++; - continue; - } - else if (IS_S(wc)) - { - pango_glyph_string_set_size (glyphs, *n_glyphs + 1); - set_glyph (font, glyphs, *n_glyphs, cluster_offset, - PANGO_GET_UNKNOWN_GLYPH (wc)); - (*n_glyphs)++; - continue; - } - - /* This font has no glyphs on the Hangul Jamo area! Find a - fallback from the Hangul Compatibility Jamo area. */ - jindex = wc - LBASE; - oldlen = *n_glyphs; - for (j = 0; j < 3 && (__jamo_to_ksc5601[jindex][j] != 0); j++) - { - gunichar comp_wc; - comp_wc = __jamo_to_ksc5601[jindex][j] - KSC_JAMOBASE + UNI_JAMOBASE; - index = (comp_wc >= 0x3131) ? find_char (font, comp_wc) : 0; - pango_glyph_string_set_size (glyphs, *n_glyphs + 1); - if (!index) - { - *n_glyphs = oldlen; - pango_glyph_string_set_size (glyphs, *n_glyphs + 1); - set_glyph (font, glyphs, *n_glyphs, cluster_offset, - PANGO_GET_UNKNOWN_GLYPH (wc)); - (*n_glyphs)++; - break; - } - else - set_glyph (font, glyphs, *n_glyphs, cluster_offset, index); - (*n_glyphs)++; - } - } - if (n_prev_glyphs == *n_glyphs) - { - index = find_char (font, 0x3164); /* U+3164 HANGUL FILLER */ - pango_glyph_string_set_size (glyphs, *n_glyphs + 1); - if (!index) - set_glyph (font, glyphs, *n_glyphs, cluster_offset, - PANGO_GET_UNKNOWN_GLYPH (index)); - else - set_glyph (font, glyphs, *n_glyphs, cluster_offset, index); - glyphs->log_clusters[*n_glyphs] = cluster_offset; - (*n_glyphs)++; - } - if (tone) - render_tone(font, tone, glyphs, n_glyphs, cluster_offset); -} - -static void -render_basic (PangoFont *font, gunichar wc, - PangoGlyphString *glyphs, int *n_glyphs, int cluster_offset) -{ - int index; - - if (wc == 0xa0) /* non-break-space */ - wc = 0x20; - - pango_glyph_string_set_size (glyphs, *n_glyphs + 1); - - if (pango_is_zero_width (wc)) - set_glyph (font, glyphs, *n_glyphs, cluster_offset, PANGO_GLYPH_EMPTY); - else - { - index = find_char (font, wc); - if (index) - set_glyph (font, glyphs, *n_glyphs, cluster_offset, index); - else - set_glyph (font, glyphs, *n_glyphs, cluster_offset, PANGO_GET_UNKNOWN_GLYPH (wc)); - } - (*n_glyphs)++; -} - -static void -hangul_engine_shape (PangoEngineShape *engine G_GNUC_UNUSED, - PangoFont *font, - const char *text, - gint length, - const PangoAnalysis *analysis G_GNUC_UNUSED, - PangoGlyphString *glyphs) -{ - int n_chars = g_utf8_strlen (text, length); - int n_glyphs; - int i; - const char *p, *start; - - int n_jamos; - gunichar prev = 0; - - n_glyphs = 0; - start = p = text; - n_jamos = 0; - - for (i = 0; i < n_chars; i++) - { - gunichar wc; - - wc = g_utf8_get_char (p); - - /* Check syllable boundaries. */ - if (n_jamos && IS_BOUNDARY (prev, wc)) - { - if (n_jamos == 1 && IS_S (prev)) - /* common case which the most people use */ - render_basic (font, prev, glyphs, &n_glyphs, start - text); - else - /* possibly complex composition */ - render_syllable (font, start, n_jamos, glyphs, - &n_glyphs, start - text); - n_jamos = 0; - start = p; - } - - prev = wc; - - if (!IS_HANGUL (wc)) - { - render_basic (font, wc, glyphs, &n_glyphs, start - text); - start = g_utf8_next_char (p); - } - else if (IS_M (wc) && !n_jamos) - { - /* Tone mark not following syllable */ - render_isolated_tone (font, wc, glyphs, &n_glyphs, start - text); - start = g_utf8_next_char (p); - } - else - n_jamos++; - p = g_utf8_next_char (p); - } - - if (n_jamos == 1 && IS_S (prev)) - render_basic (font, prev, glyphs, &n_glyphs, start - text); - else if (n_jamos > 0) - render_syllable (font, start, n_jamos, glyphs, &n_glyphs, - start - text); -} - -static void -hangul_engine_fc_class_init (PangoEngineShapeClass *class) -{ - class->script_shape = hangul_engine_shape; -} - -PANGO_ENGINE_SHAPE_DEFINE_TYPE (HangulEngineFc, hangul_engine_fc, - hangul_engine_fc_class_init, NULL) - -void -PANGO_MODULE_ENTRY(init) (GTypeModule *module) -{ - hangul_engine_fc_register_type (module); -} - -void -PANGO_MODULE_ENTRY(exit) (void) -{ -} - -void -PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, - int *n_engines) -{ - *engines = script_engines; - *n_engines = G_N_ELEMENTS (script_engines); -} - -PangoEngine * -PANGO_MODULE_ENTRY(create) (const char *id) -{ - if (!strcmp (id, SCRIPT_ENGINE_NAME)) - return g_object_new (hangul_engine_fc_type, NULL); - else - return NULL; -} diff --git a/modules/hangul/tables-jamos.i b/modules/hangul/tables-jamos.i deleted file mode 100644 index e5ea5942..00000000 --- a/modules/hangul/tables-jamos.i +++ /dev/null @@ -1,401 +0,0 @@ -/* -*-c-*- */ - -#define KSC_JAMOBASE 0x2420 -#define UNI_JAMOBASE 0x3130 - -#define KSC_KIYEOK 0x2421 -#define KSC_SSANGKIYEOK 0x2422 -#define KSC_KIYEOK_SIOS 0x2423 -#define KSC_NIEUN 0x2424 -#define KSC_NIEUN_CIEUC 0x2425 -#define KSC_NIEUN_HIEUH 0x2426 -#define KSC_TIKEUT 0x2427 -#define KSC_SSANGTIKEUT 0x2428 -#define KSC_RIEUL 0x2429 -#define KSC_RIEUL_KIYEOK 0x242a -#define KSC_RIEUL_MIEUM 0x242b -#define KSC_RIEUL_PIEUP 0x242c -#define KSC_RIEUL_SIOS 0x242d -#define KSC_RIEUL_THIEUTH 0x242e -#define KSC_RIEUL_PHIEUPH 0x242f -#define KSC_RIEUL_HIEUH 0x2430 -#define KSC_MIEUM 0x2431 -#define KSC_PIEUP 0x2432 -#define KSC_SSANGPIEUP 0x2433 -#define KSC_PIEUP_SIOS 0x2434 -#define KSC_SIOS 0x2435 -#define KSC_SSANGSIOS 0x2436 -#define KSC_IEUNG 0x2437 -#define KSC_CIEUC 0x2438 -#define KSC_SSANGCIEUC 0x2439 -#define KSC_CHIEUCH 0x243a -#define KSC_KHIEUKH 0x243b -#define KSC_THIEUTH 0x243c -#define KSC_PHIEUPH 0x243d -#define KSC_HIEUH 0x243e - -#define KSC_A 0x243f -#define KSC_AE 0x2440 -#define KSC_YA 0x2441 -#define KSC_YAE 0x2442 -#define KSC_EO 0x2443 -#define KSC_E 0x2444 -#define KSC_YEO 0x2445 -#define KSC_YE 0x2446 -#define KSC_O 0x2447 -#define KSC_WA 0x2448 -#define KSC_WAE 0x2449 -#define KSC_OE 0x244a -#define KSC_YO 0x244b -#define KSC_U 0x244c -#define KSC_WEO 0x244d -#define KSC_WE 0x244e -#define KSC_WI 0x244f -#define KSC_YU 0x2450 -#define KSC_EU 0x2451 -#define KSC_YI 0x2452 -#define KSC_I 0x2453 - -#define KSC_SSANGNIEUN 0x2455 -#define KSC_NIEUN_TIKEUT 0x2456 -#define KSC_NIEUN_SIOS 0x2457 -#define KSC_NIEUN_PANSIOS 0x2458 -#define KSC_RIEUL_KIYEOK_SIOS 0x2459 -#define KSC_RIEUL_TIKEUT 0x245a -#define KSC_RIEUL_PIEUP_SIOS 0x245b -#define KSC_RIEUL_PANSIOS 0x245c -#define KSC_RIEUL_YEORINHIEUH 0x245d -#define KSC_MIEUM_PIEUP 0x245e -#define KSC_MIEUM_SIOS 0x245f -#define KSC_MIEUM_PANSIOS 0x2460 -#define KSC_KAPYEOUNMIEUM 0x2461 -#define KSC_PIEUP_KIYEOK 0x2462 -#define KSC_PIEUP_TIKEUT 0x2463 -#define KSC_PIEUP_SIOS_KIYEOK 0x2464 -#define KSC_PIEUP_SIOS_TIKEUT 0x2465 -#define KSC_PIEUP_CIEUC 0x2466 -#define KSC_PIEUP_THIEUTH 0x2467 -#define KSC_KAPYEOUNPIEUP 0x2468 -#define KSC_KAPYEOUNSSANGPIEUP 0x2469 -#define KSC_SIOS_KIYEOK 0x246a -#define KSC_SIOS_NIEUN 0x246b -#define KSC_SIOS_TIKEUT 0x246c -#define KSC_SIOS_PIEUP 0x246d -#define KSC_SIOS_CIEUC 0x246e -#define KSC_PANSIOS 0x246f -#define KSC_SSANGIEUNG 0x2470 -#define KSC_YESIEUNG 0x2471 -#define KSC_IEUNG_CIEUC 0x2472 -#define KSC_IEUNG_PANSIOS 0x2473 -#define KSC_KAPYEOUNPHIEUPH 0x2474 -#define KSC_SSANGHIEUH 0x2475 -#define KSC_YEORINHIEUH 0x2476 -#define KSC_YO_YA 0x2477 -#define KSC_YO_YAE 0x2478 -#define KSC_YO_I 0x2479 -#define KSC_YU_YEO 0x247a -#define KSC_YU_YE 0x247b -#define KSC_YU_I 0x247c -#define KSC_ARAEA 0x247d -#define KSC_ARAEA_I 0x247e - -/* - * Some jamos are not representable with KSC5601. These are ugly - * fallbacks: - * - * CHITUEUMSIOS: 0x233c (less than) - * CEONGCHITUEUMSIOS: 0x233e (greater than) - * CHITUEUMCIEUC 0x237b (left bracket) - * CEONGEUMCIEUC 0x237d (right bracket) - * CHITUEUMCHIEUCH 0x237b (left brace) - * CEONGEUMCHIEUCH 0x237d (right brace) - */ -#define KSC_CHITUEUMSIOS 0x233c -#define KSC_CEONGCHITUEUMSIOS 0x233e -#define KSC_CHITUEUMCIEUC 0x235b -#define KSC_CEONGEUMCIEUC 0x235d -#define KSC_CHITUEUMCHIEUCH 0x237b -#define KSC_CEONGEUMCHIEUCH 0x237d - -static const guint16 __jamo_to_ksc5601[0x100][3] = -{ - /* - * CHOSEONG - */ - /* CHOSEONG 0x1100 -- 0x1112 : matched to each ksc5601 Jamos extactly. */ - {KSC_KIYEOK, 0, 0}, - {KSC_SSANGKIYEOK, 0, 0}, - {KSC_NIEUN, 0, 0}, - {KSC_TIKEUT, 0, 0}, - {KSC_SSANGTIKEUT, 0, 0}, - {KSC_RIEUL, 0, 0}, - {KSC_MIEUM, 0, 0}, - {KSC_PIEUP, 0, 0}, - {KSC_SSANGPIEUP, 0, 0}, - {KSC_SIOS, 0, 0}, - {KSC_SSANGSIOS, 0, 0}, - {KSC_IEUNG, 0, 0}, - {KSC_CIEUC, 0, 0}, - {KSC_SSANGCIEUC, 0, 0}, - {KSC_CHIEUCH, 0, 0}, - {KSC_KHIEUKH, 0, 0}, - {KSC_THIEUTH, 0, 0}, - {KSC_PHIEUPH, 0, 0}, - {KSC_HIEUH, 0, 0}, - /* Some of the following are representable as a glyph, the others not. */ - {KSC_NIEUN, KSC_KIYEOK, 0}, - {KSC_SSANGNIEUN, 0, 0}, - {KSC_NIEUN_TIKEUT, 0, 0}, - {KSC_NIEUN, KSC_PIEUP, 0}, - {KSC_TIKEUT, KSC_KIYEOK, 0}, - {KSC_RIEUL, KSC_NIEUN, 0}, - {KSC_RIEUL, KSC_RIEUL, 0}, - {KSC_RIEUL_HIEUH, 0, 0}, - {KSC_RIEUL, KSC_IEUNG, 0}, - {KSC_MIEUM_PIEUP, 0, 0}, - {KSC_KAPYEOUNMIEUM, 0, 0}, - {KSC_PIEUP_KIYEOK, 0, 0}, - {KSC_PIEUP, KSC_NIEUN, 0}, - {KSC_PIEUP_TIKEUT, 0, 0}, - {KSC_PIEUP_SIOS, 0, 0}, - {KSC_PIEUP_SIOS_KIYEOK, 0, 0}, - {KSC_PIEUP_SIOS_TIKEUT, 0, 0}, - {KSC_PIEUP, KSC_SIOS, KSC_PIEUP}, - {KSC_PIEUP, KSC_SIOS, KSC_SIOS}, - {KSC_PIEUP, KSC_SIOS, KSC_CIEUC}, - {KSC_PIEUP_CIEUC, 0, 0}, - {KSC_PIEUP, KSC_CHIEUCH, 0}, - {KSC_PIEUP_THIEUTH, 0, 0}, - {KSC_PIEUP, KSC_PHIEUPH, 0}, - {KSC_KAPYEOUNPIEUP, 0, 0}, - {KSC_KAPYEOUNSSANGPIEUP, 0, 0}, - {KSC_SIOS_KIYEOK, 0, 0}, - {KSC_SIOS_NIEUN, 0, 0}, - {KSC_SIOS_TIKEUT, 0, 0}, - {KSC_SIOS, KSC_RIEUL, 0}, - {KSC_SIOS, KSC_MIEUM, 0}, - {KSC_SIOS_PIEUP, 0, 0}, - {KSC_SIOS, KSC_PIEUP, KSC_KIYEOK}, - {KSC_SIOS, KSC_SIOS, KSC_SIOS}, - {KSC_SIOS, KSC_IEUNG, 0}, - {KSC_SIOS_CIEUC, 0, 0}, - {KSC_SIOS, KSC_CHIEUCH, 0}, - {KSC_SIOS, KSC_KHIEUKH, 0}, - {KSC_SIOS, KSC_THIEUTH, 0}, - {KSC_SIOS, KSC_PHIEUPH, 0}, - {KSC_SIOS, KSC_HIEUH, 0}, - {KSC_CHITUEUMSIOS, 0, 0}, - {KSC_CHITUEUMSIOS, KSC_CHITUEUMSIOS, 0}, - {KSC_CEONGCHITUEUMSIOS, 0, 0}, - {KSC_CEONGCHITUEUMSIOS, KSC_CEONGCHITUEUMSIOS, 0}, - {KSC_PANSIOS, 0, 0}, - {KSC_IEUNG, KSC_KIYEOK, 0}, - {KSC_IEUNG, KSC_TIKEUT, 0}, - {KSC_IEUNG, KSC_MIEUM, 0}, - {KSC_IEUNG, KSC_PIEUP, 0}, - {KSC_IEUNG, KSC_SIOS, 0}, - {KSC_IEUNG_PANSIOS, 0, 0}, - {KSC_SSANGIEUNG, 0, 0}, - {KSC_IEUNG_CIEUC, 0, 0}, - {KSC_IEUNG, KSC_CHIEUCH, 0}, - {KSC_IEUNG, KSC_THIEUTH, 0}, - {KSC_IEUNG, KSC_PHIEUPH, 0}, - {KSC_YESIEUNG, 0, 0}, - {KSC_CIEUC, KSC_IEUNG, 0}, - {KSC_CHITUEUMCIEUC, 0, 0}, - {KSC_CHITUEUMCIEUC, KSC_CHITUEUMCIEUC, 0}, - {KSC_CEONGEUMCIEUC, 0, 0}, - {KSC_CEONGEUMCIEUC, KSC_CEONGEUMCIEUC, 0}, - {KSC_CHIEUCH, KSC_KHIEUKH, 0}, - {KSC_CHIEUCH, KSC_HIEUH, 0}, - {KSC_CHITUEUMCHIEUCH, 0, 0}, - {KSC_CEONGEUMCHIEUCH, 0, 0}, - {KSC_PHIEUPH, KSC_PIEUP, 0}, - {KSC_KAPYEOUNPHIEUPH, 0, 0}, - {KSC_SSANGHIEUH, 0, 0}, - {KSC_YEORINHIEUH, 0, 0}, - /* 0x115A ~ 0x115E -- reserved */ - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, - /* CHOSEONG FILLER */ - {0, 0, 0}, - - /* - * JUNGSEONG - */ - /* - * JUNGSEONG - */ - {0, 0, 0}, /* JUNGSEONG FILL */ - /* JUNGSEONG 0x1161 -- 0x1175 : matched to each ksc5601 Jamos extactly. */ - {KSC_A, 0, 0}, - {KSC_AE, 0, 0}, - {KSC_YA, 0, 0}, - {KSC_YAE, 0, 0}, - {KSC_EO, 0, 0}, - {KSC_E, 0, 0}, - {KSC_YEO, 0, 0}, - {KSC_YE, 0, 0}, - {KSC_O, 0, 0}, - {KSC_WA, 0, 0}, - {KSC_WAE, 0, 0}, - {KSC_OE, 0, 0}, - {KSC_YO, 0, 0}, - {KSC_U, 0, 0}, - {KSC_WEO, 0, 0}, - {KSC_WE, 0, 0}, - {KSC_WI, 0, 0}, - {KSC_YU, 0, 0}, - {KSC_EU, 0, 0}, - {KSC_YI, 0, 0}, - {KSC_I, 0, 0}, - /* Some of the following are representable as a glyph, the others not. */ - {KSC_A, KSC_O, 0}, - {KSC_A, KSC_U, 0}, - {KSC_YA, KSC_O, 0}, - {KSC_YA, KSC_YO, 0}, - {KSC_EO, KSC_O, 0}, - {KSC_EO, KSC_U, 0}, - {KSC_EO, KSC_EU, 0}, - {KSC_YEO, KSC_O, 0}, - {KSC_YEO, KSC_U, 0}, - {KSC_O, KSC_EO, 0}, - {KSC_O, KSC_E, 0}, - {KSC_O, KSC_YE, 0}, - {KSC_O, KSC_O, 0}, - {KSC_O, KSC_U, 0}, - {KSC_YO_YA, 0, 0}, - {KSC_YO_YAE, 0, 0}, - {KSC_YO, KSC_YEO, 0}, - {KSC_YO, KSC_O, 0}, - {KSC_YO_I, 0, 0}, - {KSC_U, KSC_A, 0}, - {KSC_U, KSC_AE, 0}, - {KSC_U, KSC_EO, KSC_EU}, - {KSC_U, KSC_YE, 0}, - {KSC_U, KSC_U, 0}, - {KSC_YU, KSC_A, 0}, - {KSC_YU, KSC_EO, 0}, - {KSC_YU, KSC_E, 0}, - {KSC_YU_YEO, 0, 0}, - {KSC_YU_YE, 0, 0}, - {KSC_YU, KSC_U, 0}, - {KSC_YU_I, 0, 0}, - {KSC_EU, KSC_U, 0}, - {KSC_EU, KSC_EU, 0}, - {KSC_YI, KSC_U, 0}, - {KSC_I, KSC_A, 0}, - {KSC_I, KSC_YA, 0}, - {KSC_I, KSC_O, 0}, - {KSC_I, KSC_U, 0}, - {KSC_I, KSC_EU, 0}, - {KSC_I, KSC_ARAEA, 0}, - {KSC_ARAEA, 0, 0}, - {KSC_ARAEA, KSC_EO, 0}, - {KSC_ARAEA, KSC_U, 0}, - {KSC_ARAEA, KSC_I, 0}, - {KSC_ARAEA, KSC_ARAEA, 0}, - /* 0x11A3 ~ 0x11A7 -- reserved */ - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, /* (INTERNAL) JONGSEONG FILL */ - - /* - * JONGSEONG - */ - {KSC_KIYEOK, 0, 0}, - {KSC_SSANGKIYEOK, 0, 0}, - {KSC_KIYEOK_SIOS, 0, 0}, - {KSC_NIEUN, 0, 0}, - {KSC_NIEUN_CIEUC, 0, 0}, - {KSC_NIEUN_HIEUH, 0, 0}, - {KSC_TIKEUT, 0, 0}, - {KSC_RIEUL, 0, 0}, - {KSC_RIEUL_KIYEOK, 0, 0}, - {KSC_RIEUL_MIEUM, 0, 0}, - {KSC_RIEUL_PIEUP, 0, 0}, - {KSC_RIEUL_SIOS, 0, 0}, - {KSC_RIEUL_TIKEUT, 0, 0}, - {KSC_RIEUL_PHIEUPH, 0, 0}, - {KSC_RIEUL_HIEUH, 0, 0}, - {KSC_MIEUM, 0, 0}, - {KSC_PIEUP, 0, 0}, - {KSC_PIEUP_SIOS, 0, 0}, - {KSC_SIOS, 0, 0}, - {KSC_SSANGSIOS, 0, 0}, - {KSC_IEUNG, 0, 0}, - {KSC_CIEUC, 0, 0}, - {KSC_CHIEUCH, 0, 0}, - {KSC_KHIEUKH, 0, 0}, - {KSC_THIEUTH, 0, 0}, - {KSC_PHIEUPH, 0, 0}, - {KSC_HIEUH, 0, 0}, - {KSC_KIYEOK, KSC_RIEUL, 0}, - {KSC_KIYEOK, KSC_SIOS, KSC_KIYEOK}, - {KSC_NIEUN, KSC_KIYEOK, 0}, - {KSC_NIEUN_TIKEUT, 0, 0}, - {KSC_NIEUN_SIOS, 0, 0}, - {KSC_NIEUN_PANSIOS, 0, 0}, - {KSC_NIEUN, KSC_THIEUTH, 0}, - {KSC_TIKEUT, KSC_KIYEOK, 0}, - {KSC_TIKEUT, KSC_RIEUL, 0}, - {KSC_RIEUL_KIYEOK_SIOS, 0, 0}, - {KSC_RIEUL, KSC_NIEUN, 0}, - {KSC_RIEUL_TIKEUT, 0, 0}, - {KSC_RIEUL, KSC_TIKEUT, KSC_HIEUH}, - {KSC_RIEUL, KSC_RIEUL, 0}, - {KSC_RIEUL, KSC_MIEUM, KSC_KIYEOK}, - {KSC_RIEUL, KSC_MIEUM, KSC_SIOS}, - {KSC_RIEUL_PIEUP_SIOS, 0, 0}, - {KSC_RIEUL, KSC_PHIEUPH, KSC_HIEUH}, - {KSC_RIEUL, KSC_KAPYEOUNPIEUP, 0}, - {KSC_RIEUL, KSC_SIOS, KSC_SIOS}, - {KSC_RIEUL_PANSIOS, 0, 0}, - {KSC_RIEUL, KSC_KHIEUKH, 0}, - {KSC_RIEUL_YEORINHIEUH, 0, 0}, - {KSC_MIEUM, KSC_KIYEOK, 0}, - {KSC_MIEUM, KSC_RIEUL, 0}, - {KSC_MIEUM_PIEUP, 0, 0}, - {KSC_MIEUM_SIOS, 0, 0}, - {KSC_MIEUM, KSC_SIOS, KSC_SIOS}, - {KSC_MIEUM_PANSIOS, 0, 0}, - {KSC_MIEUM, KSC_CHIEUCH, 0}, - {KSC_MIEUM, KSC_HIEUH, 0}, - {KSC_KAPYEOUNMIEUM, 0, 0}, - {KSC_PIEUP, KSC_RIEUL, 0}, - {KSC_PIEUP, KSC_PHIEUPH, 0}, - {KSC_PIEUP, KSC_HIEUH, 0}, - {KSC_KAPYEOUNPIEUP, 0, 0}, - {KSC_SIOS_KIYEOK, 0, 0}, - {KSC_SIOS_TIKEUT, 0, 0}, - {KSC_SIOS, KSC_RIEUL, 0}, - {KSC_SIOS_PIEUP, 0, 0}, - {KSC_PANSIOS, 0, 0}, - {KSC_IEUNG, KSC_KIYEOK, 0}, - {KSC_IEUNG, KSC_KIYEOK, KSC_KIYEOK}, - {KSC_SSANGIEUNG, 0, 0}, - {KSC_IEUNG, KSC_KHIEUKH, 0}, - {KSC_YESIEUNG, 0, 0}, - {KSC_YESIEUNG, KSC_SIOS, 0}, - {KSC_YESIEUNG, KSC_PANSIOS, 0}, - {KSC_PHIEUPH, KSC_PIEUP, 0}, - {KSC_KAPYEOUNPHIEUPH, 0, 0}, - {KSC_HIEUH, KSC_NIEUN, 0}, - {KSC_HIEUH, KSC_RIEUL, 0}, - {KSC_HIEUH, KSC_MIEUM, 0}, - {KSC_HIEUH, KSC_PIEUP, 0}, - {KSC_YEORINHIEUH, 0, 0}, - /* reserved */ - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0} -}; - diff --git a/modules/hebrew/Makefile.am b/modules/hebrew/Makefile.am deleted file mode 100644 index 52abcda1..00000000 --- a/modules/hebrew/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -include $(top_srcdir)/modules/Module.mk - -common_sources = hebrew-shaper.c hebrew-shaper.h - -if HAVE_FREETYPE -INCLUDES += $(FREETYPE_CFLAGS) -if INCLUDE_HEBREW_FC -noinst_LTLIBRARIES += libpango-hebrew-fc.la -else -if DYNAMIC_HEBREW_FC -module_LTLIBRARIES += pango-hebrew-fc.la -endif -endif -endif - -hebrew_fc_sources = $(common_sources) hebrew-fc.c - -pango_hebrew_fc_la_LDFLAGS = -module $(MODULE_LIBTOOL_OPTIONS) -pango_hebrew_fc_la_LIBADD = $(pangoft2libs) -pango_hebrew_fc_la_SOURCES = $(hebrew_fc_sources) -libpango_hebrew_fc_la_SOURCES = $(hebrew_fc_sources) -libpango_hebrew_fc_la_CFLAGS = -DPANGO_MODULE_PREFIX=_pango_hebrew_fc - --include $(top_srcdir)/git.mk diff --git a/modules/hebrew/hebrew-fc.c b/modules/hebrew/hebrew-fc.c deleted file mode 100644 index 12f25c5e..00000000 --- a/modules/hebrew/hebrew-fc.c +++ /dev/null @@ -1,355 +0,0 @@ -/* Pango - * hebrew-fc.h: Hebrew shaper for FreeType-based backends - * - * Copyright (C) 2000, 2007 Red Hat Software - * Authors: - * Owen Taylor <otaylor@redhat.com> - * Dov Grobgeld <dov.grobgeld@weizmann.ac.il> - * Behdad Esfahbod <behdad@behdad.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 "config.h" -#include <string.h> - -#include <pango/pango-ot.h> - -#include "pango-engine.h" -#include "pango-utils.h" -#include "pangofc-font.h" -#include "hebrew-shaper.h" - -/* No extra fields needed */ -typedef PangoEngineShape HebrewEngineFc; -typedef PangoEngineShapeClass HebrewEngineFcClass ; - -#define MAX_CLUSTER_CHRS 20 - -static PangoEngineScriptInfo hebrew_scripts[] = { - { PANGO_SCRIPT_HEBREW, "*" } -}; - -#define SCRIPT_ENGINE_NAME "HebrewScriptEngineFc" -#define RENDER_TYPE PANGO_RENDER_TYPE_FC - -static PangoEngineInfo script_engines[] = { - { - SCRIPT_ENGINE_NAME, - PANGO_ENGINE_TYPE_SHAPE, - RENDER_TYPE, - hebrew_scripts, G_N_ELEMENTS(hebrew_scripts) - } -}; - -static void -get_cluster_glyphs(PangoFont *font, - gunichar cluster[], - gint cluster_size, - gboolean do_mirror, - /* output */ - gint glyph_num[], - PangoGlyph glyph[], - gint widths[], - PangoRectangle ink_rects[]) -{ - int i; - for (i=0; i<cluster_size; i++) - { - PangoRectangle logical_rect; - gunichar wc = cluster[i]; - gunichar mirrored_ch; - - if (do_mirror) - if (pango_get_mirror_char (wc, &mirrored_ch)) - wc = mirrored_ch; - - if (pango_is_zero_width (wc)) - glyph_num[i] = PANGO_GLYPH_EMPTY; - else - { - glyph_num[i] = pango_fc_font_get_glyph ((PangoFcFont *)font, wc); - - if (!glyph_num[i]) - glyph_num[i] = PANGO_GET_UNKNOWN_GLYPH ( wc); - } - - glyph[i] = glyph_num[i]; - - pango_font_get_glyph_extents (font, - glyph[i], &ink_rects[i], &logical_rect); - - /* Assign the base char width to the last character in the cluster */ - if (i==0) - { - widths[i] = 0; - widths[cluster_size-1] = logical_rect.width; - } - else if (i < cluster_size-1) - widths[i] = 0; - } -} - -static void -add_glyph (PangoGlyphString *glyphs, - gint cluster_start, - PangoGlyph glyph, - gboolean is_combining, - gint width, - gint x_offset, - gint y_offset - ) -{ - gint index = glyphs->num_glyphs; - - pango_glyph_string_set_size (glyphs, index + 1); - - glyphs->glyphs[index].glyph = glyph; - glyphs->glyphs[index].attr.is_cluster_start = is_combining ? 0 : 1; - - glyphs->log_clusters[index] = cluster_start; - - glyphs->glyphs[index].geometry.x_offset = x_offset; - glyphs->glyphs[index].geometry.y_offset = y_offset; - glyphs->glyphs[index].geometry.width = width; -} - -static void -add_cluster(PangoGlyphString *glyphs, - int cluster_size, - int cluster_start, - PangoGlyph glyph[], - int width[], - int x_offset[], - int y_offset[]) -{ - int i; - - for (i=0; i<cluster_size; i++) - { - add_glyph (glyphs, cluster_start, glyph[i], - i == 0 ? FALSE : TRUE, width[i], x_offset[i], y_offset[i]); - } -} - -static void -fallback_shape (PangoEngineShape *engine G_GNUC_UNUSED, - PangoFont *font, - const char *text, - gint length, - const PangoAnalysis *analysis, - PangoGlyphString *glyphs) -{ - const char *p; - const char *log_cluster; - gunichar cluster[MAX_CLUSTER_CHRS]; - gint cluster_size; - gint glyph_num[MAX_CLUSTER_CHRS]; - gint glyph_width[MAX_CLUSTER_CHRS], x_offset[MAX_CLUSTER_CHRS], y_offset[MAX_CLUSTER_CHRS]; - PangoRectangle ink_rects[MAX_CLUSTER_CHRS]; - PangoGlyph glyph[MAX_CLUSTER_CHRS]; - - pango_glyph_string_set_size (glyphs, 0); - - p = text; - while (p < text + length) - { - log_cluster = p; - p = hebrew_shaper_get_next_cluster (p, text + length - p, - /* output */ - cluster, &cluster_size); - get_cluster_glyphs(font, - cluster, - cluster_size, - analysis->level % 2, - /* output */ - glyph_num, - glyph, - glyph_width, - ink_rects); - - /* Kern the glyphs! */ - hebrew_shaper_get_cluster_kerning(cluster, - cluster_size, - /* Input and output */ - ink_rects, - glyph_width, - /* output */ - x_offset, - y_offset); - - add_cluster(glyphs, - cluster_size, - log_cluster - text, - glyph, - glyph_width, - x_offset, - y_offset); - - } - - if (analysis->level % 2) - hebrew_shaper_bidi_reorder(glyphs); -} - -static const PangoOTFeatureMap gsub_features[] = -{ - {"ccmp", PANGO_OT_ALL_GLYPHS}, - {"locl", PANGO_OT_ALL_GLYPHS}, - {"rlig", PANGO_OT_ALL_GLYPHS}, - /* 'dlig' should be turned-on/off-able. lets turn off for now. */ - /* {"dlig", PANGO_OT_ALL_GLYPHS}, */ -}; - -static const PangoOTFeatureMap gpos_features[] = -{ - {"kern", PANGO_OT_ALL_GLYPHS}, - {"mark", PANGO_OT_ALL_GLYPHS}, - {"mkmk", PANGO_OT_ALL_GLYPHS} -}; - -static void -hebrew_engine_shape (PangoEngineShape *engine, - PangoFont *font, - const char *text, - gint length, - const PangoAnalysis *analysis, - PangoGlyphString *glyphs) -{ - PangoFcFont *fc_font; - FT_Face face; - PangoOTRulesetDescription desc; - const PangoOTRuleset *ruleset; - PangoOTBuffer *buffer; - guint n_gpos_features = 0; - glong n_chars; - const char *p; - int cluster = 0; - int i; - - g_return_if_fail (font != NULL); - g_return_if_fail (text != NULL); - g_return_if_fail (length >= 0); - g_return_if_fail (analysis != NULL); - - fc_font = PANGO_FC_FONT (font); - face = pango_fc_font_lock_face (fc_font); - if (!face) - return; - - desc.script = analysis->script; - desc.language = analysis->language; - - desc.n_static_gsub_features = G_N_ELEMENTS (gsub_features); - desc.static_gsub_features = gsub_features; - desc.n_static_gpos_features = G_N_ELEMENTS (gpos_features); - desc.static_gpos_features = gpos_features; - - /* TODO populate other_features from analysis->extra_attrs */ - desc.n_other_features = 0; - desc.other_features = NULL; - - ruleset = pango_ot_ruleset_get_for_description (pango_ot_info_get (face), &desc); - - pango_ot_ruleset_get_feature_count (ruleset, NULL, &n_gpos_features); - if (n_gpos_features == 0) - { - fallback_shape (engine, font, text, length, analysis, glyphs); - goto out; - } - - buffer = pango_ot_buffer_new (fc_font); - pango_ot_buffer_set_rtl (buffer, analysis->level % 2 != 0); - - n_chars = g_utf8_strlen (text, length); - - p = text; - for (i=0; i < n_chars; i++) - { - gunichar wc; - PangoGlyph glyph; - - wc = g_utf8_get_char (p); - - if (g_unichar_type (wc) != G_UNICODE_NON_SPACING_MARK) - cluster = p - text; - - if (pango_is_zero_width (wc)) - glyph = PANGO_GLYPH_EMPTY; - else - { - gunichar c = wc; - - if (analysis->level % 2) - g_unichar_get_mirror_char (c, &c); - - glyph = pango_fc_font_get_glyph (fc_font, c); - } - - if (!glyph) - glyph = PANGO_GET_UNKNOWN_GLYPH (wc); - - pango_ot_buffer_add_glyph (buffer, glyph, 0, cluster); - - p = g_utf8_next_char (p); - } - - pango_ot_ruleset_substitute (ruleset, buffer); - pango_ot_ruleset_position (ruleset, buffer); - pango_ot_buffer_output (buffer, glyphs); - - pango_ot_buffer_destroy (buffer); - - out: - pango_fc_font_unlock_face (fc_font); -} - -static void -hebrew_engine_fc_class_init (PangoEngineShapeClass *class) -{ - class->script_shape = hebrew_engine_shape; -} - -PANGO_ENGINE_SHAPE_DEFINE_TYPE (HebrewEngineFc, hebrew_engine_fc, - hebrew_engine_fc_class_init, NULL) - -void -PANGO_MODULE_ENTRY(init) (GTypeModule *module) -{ - hebrew_engine_fc_register_type (module); -} - -void -PANGO_MODULE_ENTRY(exit) (void) -{ -} - -void -PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, - int *n_engines) -{ - *engines = script_engines; - *n_engines = G_N_ELEMENTS (script_engines); -} - -PangoEngine * -PANGO_MODULE_ENTRY(create) (const char *id) -{ - if (!strcmp (id, SCRIPT_ENGINE_NAME)) - return g_object_new (hebrew_engine_fc_type, NULL); - else - return NULL; -} diff --git a/modules/hebrew/hebrew-shaper.c b/modules/hebrew/hebrew-shaper.c deleted file mode 100644 index db3055b7..00000000 --- a/modules/hebrew/hebrew-shaper.c +++ /dev/null @@ -1,477 +0,0 @@ -/* Pango - * hebrew-shaper.c: - * - * Copyright (c) 2001 by Sun Microsystems, Inc. - * Author: Chookij Vanatham <Chookij.Vanatham@Eng.Sun.COM> - * - * Hebrew points positioning improvements 2001 - * Author: Dov Grobgeld <dov.grobgeld@gmail.com> - * - * 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. - * - * Note March 9, 2003: I fixed a crash with regards to precomposed - * characters, by wraping all of them to be considered as ALEF as - * far as consideration about composability is concerned. The rendering - * with regards to precomposed characters AND nikud comes out really - * bad though, and should be fixed, once I have more time. - */ - -#include "config.h" -#include <glib.h> -#include "pango-engine.h" -#include "hebrew-shaper.h" - -/* Wrap all characters above 0xF00 to ALEF. */ -#define ishebrew(wc) ((wc)>0x590 && (wc)<0x600) -#define ucs2iso8859_8(wc) ((unsigned int)((unsigned int)(wc) - 0x0590 + 0x10)) -#define iso8859_8_2uni(c) ((gunichar)(c) - 0x10 + 0x0590) - -#define MAX_CLUSTER_CHRS 256 - -/* Define Hebrew character classes */ -#define _ND 0 -#define _SP 1 -#define _NS (1<<1) -#define _DA (1<<2) /* only for dagesh... */ - -#define NoDefine _ND -#define SpacingLetter _SP -#define NonSpacingPunc _NS - -/* Define Hebrew character types */ -#define __ND 0 -#define __SP 1 -#define __NS 2 -#define __DA 3 - -/* Unicode definitions needed in logics below... */ -#define UNI_ALEF 0x05D0 -#define UNI_BET 0x05D1 -#define UNI_GIMMEL 0x05d2 -#define UNI_DALED 0x05D3 -#define UNI_KAF 0x05DB -#define UNI_FINAL_KAF 0x05DA -#define UNI_VAV 0x05D5 -#define UNI_YOD 0x05D9 -#define UNI_RESH 0x05E8 -#define UNI_LAMED 0x05DC -#define UNI_SHIN 0x05E9 -#define UNI_FINAL_PE 0x05E3 -#define UNI_PE 0x05E4 -#define UNI_QOF 0x05E7 -#define UNI_TAV 0x05EA -#define UNI_SHIN_DOT 0x05C1 -#define UNI_SIN_DOT 0x05C2 -#define UNI_MAPIQ 0x05BC -#define UNI_SHEVA 0x05B0 -#define UNI_HOLAM 0x05B9 -#define UNI_QUBUTS 0x05BB -#define UNI_HATAF_SEGOL 0x05B1 -#define UNI_HATAF_QAMATZ 0x05B3 -#define UNI_TSERE 0x05B5 -#define UNI_QAMATS 0x05B8 -#define UNI_QUBUTS 0x05BB - -/*====================================================================== -// In the tables below all Hebrew characters are categorized to -// one of the following four classes: -// -// non used entries Not defined (ND) -// accents, points Non spacing (NS) -// punctuation and characters Spacing characters (SP) -// dagesh "Dagesh" (DA) -//----------------------------------------------------------------------*/ -static const gint char_class_table[128] = { - /* 0, 1, 2, 3, 4, 5, 6, 7 */ - - /*00*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND, - _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND, - - /*10*/ _ND, _NS, _NS, _NS, _NS, _NS, _NS, _NS, - _NS, _NS, _NS, _NS, _NS, _NS, _NS, _NS, - /*20*/ _NS, _NS, _ND, _NS, _NS, _NS, _NS, _NS, - _NS, _NS, _NS, _NS, _NS, _NS, _NS, _NS, - /*30*/ _NS, _NS, _NS, _NS, _NS, _NS, _NS, _NS, - _NS, _NS, _ND, _NS, _DA, _NS, _SP, _NS, - /*40*/ _SP, _NS, _NS, _SP, _NS, _ND, _ND, _ND, - _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND, - /*50*/ _SP, _SP, _SP, _SP, _SP, _SP, _SP, _SP, - _SP, _SP, _SP, _SP, _SP, _SP, _SP, _SP, - /*60*/ _SP, _SP, _SP, _SP, _SP, _SP, _SP, _SP, - _SP, _SP, _SP, _ND, _ND, _ND, _ND, _ND, - /*70*/ _SP, _SP, _SP, _SP, _SP, _ND, _ND, _ND, - _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND, -}; - -static const gint char_type_table[128] = { - /* 0, 1, 2, 3, 4, 5, 6, 7 */ - - /*00*/ __ND, __ND, __ND, __ND, __ND, __ND, __ND, __ND, - __ND, __ND, __ND, __ND, __ND, __ND, __ND, __ND, - - /*10*/ __ND, __NS, __NS, __NS, __NS, __NS, __NS, __NS, - __NS, __NS, __NS, __NS, __NS, __NS, __NS, __NS, - /*20*/ __NS, __NS, __ND, __NS, __NS, __NS, __NS, __NS, - __NS, __NS, __NS, __NS, __NS, __NS, __NS, __NS, - /*30*/ __NS, __NS, __NS, __NS, __NS, __NS, __NS, __NS, - __NS, __NS, __ND, __NS, __DA, __NS, __SP, __NS, - /*40*/ __SP, __NS, __NS, __SP, __NS, __ND, __ND, __ND, - __ND, __ND, __ND, __ND, __ND, __ND, __ND, __ND, - /*50*/ __SP, __SP, __SP, __SP, __SP, __SP, __SP, __SP, - __SP, __SP, __SP, __SP, __SP, __SP, __SP, __SP, - /*60*/ __SP, __SP, __SP, __SP, __SP, __SP, __SP, __SP, - __SP, __SP, __SP, __ND, __ND, __ND, __ND, __ND, - /*70*/ __SP, __SP, __SP, __SP, __SP, __ND, __ND, __ND, - __ND, __ND, __ND, __ND, __ND, __ND, __ND, __ND, -}; - -/*====================================================================== -// The following table answers the question whether two characters -// are composible or not. The decision is made by looking at the -// char_type_table values for the first character in a cluster -// vs a following charactrer. The only three combinations that -// are composible in Hebrew according to the table are: -// -// 1. a spacing character followed by non-spacing character -// 2. a spacing character followed by a dagesh. -// 3. a dagesh followed by a non-spacing character. -// -// Note that a spacing character may be followed by several non-spacing -// accents, as the decision is always made on the base character of -// a combination. -//----------------------------------------------------------------------*/ -static const gboolean compose_table[4][4] = { - /* Cn */ /* 0, 1, 2, 3, */ -/* Cn-1 00 */ { FALSE, FALSE, FALSE, FALSE }, - /* 10 */ { FALSE, FALSE, TRUE, TRUE }, - /* 20 */ { FALSE, FALSE, FALSE, FALSE }, - /* 30 */ { FALSE, FALSE, TRUE, FALSE }, -}; - -/* Treat all characters above 0xF000 as characters */ -#define is_hebrew(wc) ((wc) >= 0x590 && (wc) < 0x600) -#define is_char_class(wc, mask) (char_class_table[ucs2iso8859_8 ((wc))] & (mask)) -#define is_composible(cur_wc, nxt_wc) (compose_table[char_type_table[ucs2iso8859_8 (cur_wc)]]\ - [char_type_table[ucs2iso8859_8 (nxt_wc)]]) - -const char * -hebrew_shaper_get_next_cluster(const char *text, - gint length, - gunichar *cluster, - gint *num_chrs) -{ - const char *p; - gint n_chars = 0; - - p = text; - - while (p < text + length && n_chars < MAX_CLUSTER_CHRS) - { - gunichar current = g_utf8_get_char (p); - - if (!ishebrew (current) || - (n_chars == 0 && is_char_class(current, ~(NoDefine|SpacingLetter)))) - { - /* Not a legal Hebrew cluster */ - - if (n_chars == 0) - { - cluster[n_chars++] = current; - p = g_utf8_next_char (p); - } - break; - } - else if (n_chars == 0 || - is_composible (cluster[0], current)) - { - cluster[n_chars++] = current; - p = g_utf8_next_char (p); - } - else - break; - } - - *num_chrs = n_chars; - return p; -} - -void -hebrew_shaper_get_cluster_kerning(gunichar *cluster, - gint cluster_length, - PangoRectangle ink_rect[], - - /* input and output */ - gint width[], - gint x_offset[], - gint y_offset[]) -{ - int i; - int base_ink_x_offset, base_ink_y_offset, base_ink_width, base_ink_height; - gunichar base_char = cluster[0]; - - x_offset[0] = 0; - y_offset[0] = 0; - - if (cluster_length == 1) - { - /* Make lone 'vav dot' have zero width */ - if (base_char == UNI_SHIN_DOT - || base_char == UNI_SIN_DOT - || base_char == UNI_HOLAM - ) { - x_offset[0] = -ink_rect[0].x - ink_rect[0].width; - width[0] = 0; - } - - return; - } - - base_ink_x_offset = ink_rect[0].x; - base_ink_y_offset = ink_rect[0].y; - base_ink_width = ink_rect[0].width; - base_ink_height = ink_rect[0].height; - - /* Do heuristics */ - for (i=1; i<cluster_length; i++) - { - int gl = cluster[i]; - x_offset[i] = 0; - y_offset[i] = 0; - - /* Check if it is a point */ - if (gl < 0x5B0 || gl >= 0x05D0) - continue; - - /* Center dot of VAV */ - if (gl == UNI_MAPIQ && base_char == UNI_VAV) - { - x_offset[i] = base_ink_x_offset - ink_rect[i].x; - - /* If VAV is a vertical bar without a roof, then we - need to make room for the dot by increasing the - cluster width. But how can I check if that is the - case?? - */ - /* This is wild, but it does the job of differentiating - between two M$ fonts... Base the decision on the - aspect ratio of the vav... - */ - if (base_ink_height > base_ink_width * 3.5) - { - int j; - double space = 0.7; - double kern = 0.5; - - /* Shift all characters to make place for the mapiq */ - for (j=0; j<i; j++) - x_offset[j] += ink_rect[i].width*(1+space-kern); - - width[cluster_length-1] += ink_rect[i].width*(1+space-kern); - x_offset[i] -= ink_rect[i].width*(kern); - } - } - - /* Dot over SHIN */ - else if (gl == UNI_SHIN_DOT && base_char == UNI_SHIN) - { - x_offset[i] = base_ink_x_offset + base_ink_width - - ink_rect[i].x - ink_rect[i].width; - } - - /* Dot over SIN */ - else if (gl == UNI_SIN_DOT && base_char == UNI_SHIN) - { - x_offset[i] = base_ink_x_offset - ink_rect[i].x; - } - - /* VOWEL DOT above to any other character than - SHIN or VAV should stick out a bit to the left. */ - else if ((gl == UNI_SIN_DOT || gl == UNI_HOLAM) - && base_char != UNI_SHIN && base_char != UNI_VAV) - { - x_offset[i] = base_ink_x_offset -ink_rect[i].x - ink_rect[i].width * 3/ 2; - } - - /* VOWELS under resh or vav are right aligned, if they are - narrower than the characters. Otherwise they are centered. - */ - else if ((base_char == UNI_VAV - || base_char == UNI_RESH - || base_char == UNI_YOD - || base_char == UNI_DALED - ) - && ((gl >= UNI_SHEVA && gl <= UNI_QAMATS) || - gl == UNI_QUBUTS) - && ink_rect[i].width < base_ink_width - ) - { - x_offset[i] = base_ink_x_offset + base_ink_width - - ink_rect[i].x - ink_rect[i].width; - } - - /* VOWELS under FINAL KAF are offset centered and offset in - y */ - else if ((base_char == UNI_FINAL_KAF - ) - && ((gl >= UNI_SHEVA && gl <= UNI_QAMATS) || - gl == UNI_QUBUTS)) - { - /* x are at 1/3 to take into accoun the stem */ - x_offset[i] = base_ink_x_offset - ink_rect[i].x - + base_ink_width * 1/3 - ink_rect[i].width/2; - - /* Center in y */ - y_offset[i] = base_ink_y_offset - ink_rect[i].y - + base_ink_height * 1/2 - ink_rect[i].height/2; - } - - - /* MAPIQ in PE or FINAL PE */ - else if (gl == UNI_MAPIQ - && (base_char == UNI_PE || base_char == UNI_FINAL_PE)) - { - x_offset[i]= base_ink_x_offset - ink_rect[i].x - + base_ink_width * 2/3 - ink_rect[i].width/2; - - /* Another option is to offset the MAPIQ in y... - glyphs->glyphs[cluster_start_idx+i].geometry.y_offset - -= base_ink_height/5; */ - } - - /* MAPIQ in SHIN should be moved a bit to the right */ - else if (gl == UNI_MAPIQ - && base_char == UNI_SHIN) - { - x_offset[i]= base_ink_x_offset - ink_rect[i].x - + base_ink_width * 3/5 - ink_rect[i].width/2; - } - - /* MAPIQ in YUD is right aligned */ - else if (gl == UNI_MAPIQ - && base_char == UNI_YOD) - { - x_offset[i]= base_ink_x_offset - ink_rect[i].x; - - /* Lower left in y */ - y_offset[i] = base_ink_y_offset - ink_rect[i].y - + base_ink_height - ink_rect[i].height*1.75; - - if (base_ink_height > base_ink_width * 2) - { - int j; - double space = 0.7; - double kern = 0.5; - - /* Shift all cluster characters to make space for mapiq */ - for (j=0; j<i; j++) - x_offset[j] += ink_rect[i].width*(1+space-kern); - - width[cluster_length-1] += ink_rect[i].width*(1+space-kern); - } - - } - - /* VOWEL DOT next to any other character */ - else if ((gl == UNI_SIN_DOT || gl == UNI_HOLAM) - && (base_char != UNI_VAV)) - { - x_offset[i] = base_ink_x_offset -ink_rect[i].x; - } - - /* Move nikud of taf a bit ... */ - else if (base_char == UNI_TAV && gl == UNI_MAPIQ) - { - x_offset[i] = base_ink_x_offset - ink_rect[i].x - + base_ink_width * 5/8 - ink_rect[i].width/2; - } - - /* Move center dot of characters with a right stem and no - left stem. */ - else if (gl == UNI_MAPIQ && - (base_char == UNI_BET - || base_char == UNI_DALED - || base_char == UNI_KAF - || base_char == UNI_GIMMEL - )) - { - x_offset[i] = base_ink_x_offset - ink_rect[i].x - + base_ink_width * 3/8 - ink_rect[i].width/2; - } - - /* Right align wide nikud under QOF */ - else if (base_char == UNI_QOF && - ( (gl >= UNI_HATAF_SEGOL - && gl <= UNI_HATAF_QAMATZ) - || (gl >= UNI_TSERE - && gl<= UNI_QAMATS) - || (gl == UNI_QUBUTS))) - { - x_offset[i] = base_ink_x_offset + base_ink_width - - ink_rect[i].x - ink_rect[i].width; - } - - /* Center by default */ - else - { - x_offset[i] = base_ink_x_offset - ink_rect[i].x - + base_ink_width/2 - ink_rect[i].width/2; - } - } - -} - -void -hebrew_shaper_swap_range (PangoGlyphString *glyphs, - int start, - int end) -{ - int i, j; - - for (i = start, j = end - 1; i < j; i++, j--) - { - PangoGlyphInfo glyph_info; - gint log_cluster; - - glyph_info = glyphs->glyphs[i]; - glyphs->glyphs[i] = glyphs->glyphs[j]; - glyphs->glyphs[j] = glyph_info; - - log_cluster = glyphs->log_clusters[i]; - glyphs->log_clusters[i] = glyphs->log_clusters[j]; - glyphs->log_clusters[j] = log_cluster; - } -} - -void -hebrew_shaper_bidi_reorder(PangoGlyphString *glyphs) -{ - int start, end; - - /* Swap all glyphs */ - hebrew_shaper_swap_range (glyphs, 0, glyphs->num_glyphs); - - /* Now reorder glyphs within each cluster back to LTR */ - for (start = 0; start < glyphs->num_glyphs;) - { - end = start; - while (end < glyphs->num_glyphs && - glyphs->log_clusters[end] == glyphs->log_clusters[start]) - end++; - - hebrew_shaper_swap_range (glyphs, start, end); - start = end; - } -} diff --git a/modules/hebrew/hebrew-shaper.h b/modules/hebrew/hebrew-shaper.h deleted file mode 100644 index 24603433..00000000 --- a/modules/hebrew/hebrew-shaper.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Pango - * hebrew-shaper.h: Hebrew shaper internal functions - * - * Copyright (c) 2001 by Sun Microsystems, Inc. - * Author: Chookij Vanatham <Chookij.Vanatham@Eng.Sun.COM> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef HEBREW_SHAPER_H -#define HEBREW_SHAPER_H - -const char * -hebrew_shaper_get_next_cluster(const char *text, - gint length, - gunichar *cluster, - gint *num_chrs); - -void -hebrew_shaper_get_cluster_kerning(gunichar *cluster, - gint cluster_length, - PangoRectangle ink_rect[], - - /* input and output */ - gint width[], - gint x_offset[], - gint y_offset[]); - -void -hebrew_shaper_swap_range (PangoGlyphString *glyphs, - int start, - int end); - -void -hebrew_shaper_bidi_reorder(PangoGlyphString *glyphs); - -#endif diff --git a/modules/khmer/Makefile.am b/modules/khmer/Makefile.am deleted file mode 100644 index f191ea51..00000000 --- a/modules/khmer/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -include $(top_srcdir)/modules/Module.mk - -if HAVE_FREETYPE -INCLUDES += $(FREETYPE_CFLAGS) -if INCLUDE_KHMER_FC -noinst_LTLIBRARIES += libpango-khmer-fc.la -else -if DYNAMIC_KHMER_FC -module_LTLIBRARIES += pango-khmer-fc.la -endif -endif -endif - -fc_sources = \ - khmer-fc.c - -pango_khmer_fc_la_LDFLAGS = -module $(MODULE_LIBTOOL_OPTIONS) -pango_khmer_fc_la_LIBADD = $(pangoft2libs) -pango_khmer_fc_la_SOURCES = $(fc_sources) -libpango_khmer_fc_la_SOURCES = $(fc_sources) -libpango_khmer_fc_la_CFLAGS = -DPANGO_MODULE_PREFIX=_pango_khmer_fc - --include $(top_srcdir)/git.mk diff --git a/modules/khmer/khmer-fc.c b/modules/khmer/khmer-fc.c deleted file mode 100644 index 14357d78..00000000 --- a/modules/khmer/khmer-fc.c +++ /dev/null @@ -1,721 +0,0 @@ -/* Pango - * khmer-fc.c: Shaper for Khmer script - * - * Copyright (C) 2004 Open Forum of Cambodia (www.forum.org.kh / www.khmeros.info) - * Authors: Jens Herden <jens@khmeros.info> and Javier Sola <javier@khmeros.info> - * - * Based on code from other shapers - * Copyright (C) 1999-2004 Red Hat Software - * Author: Owen Taylor <otaylor@redhat.com> - - * Partially based on Indic shaper - * Copyright (C) 2001, 2002 IBM Corporation - * Author: Eric Mader <mader@jtcsv.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * The license on the original Indic shaper code is as follows: - * - * * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished - * to do so, provided that the above copyright notice(s) and this - * permission notice appear in all copies of the Software and that - * both the above copyright notice(s) and this permission notice - * appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR - * ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY - * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder - * shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written - * authorization of the copyright holder. - */ -#include "config.h" -#include <string.h> - -#include "pango-engine.h" -#include "pango-ot.h" -#include "pango-utils.h" -#include "pangofc-font.h" - - -#define SCRIPT_ENGINE_NAME "KhmerScriptEngineFc" -#define RENDER_TYPE PANGO_RENDER_TYPE_FC - - -typedef PangoEngineShape KhmerEngineFc; -typedef PangoEngineShapeClass KhmerEngineFcClass ; - - -static PangoEngineScriptInfo khmer_scripts[] = -{ - { PANGO_SCRIPT_KHMER, "*" } -}; - -static PangoEngineInfo script_engines[] = -{ - { - SCRIPT_ENGINE_NAME, - PANGO_ENGINE_TYPE_SHAPE, - RENDER_TYPE, - khmer_scripts, G_N_ELEMENTS (khmer_scripts) - } -}; - - -/* Vocabulary - * Base -> A consonant or an independent vowel in its full (not subscript) form. It is the - * center of the syllable, it can be surrounded by coeng (subscript) consonants, vowels, - * split vowels, signs... but there is only one base in a syllable, it has to be coded as - * the first character of the syllable. - * split vowel --> vowel that has two parts placed separately (e.g. Before and after the consonant). - * Khmer language has five of them. Khmer split vowels either have one part before the - * base and one after the base or they have a part before the base and a part above the base. - * The first part of all Khmer split vowels is the same character, identical to - * the glyph of Khmer dependent vowel SRA EI - * coeng --> modifier used in Khmer to construct coeng (subscript) consonants - * Differently than indian languages, the coeng modifies the consonant that follows it, - * not the one preceding it Each consonant has two forms, the base form and the subscript form - * the base form is the normal one (using the consonants code-point), the subscript form is - * displayed when the combination coeng + consonant is encountered. - * Consonant of type 1 -> A consonant which has subscript for that only occupies space under a base consonant - * Consonant of type 2.-> Its subscript form occupies space under and before the base (only one, RO) - * Consonant of Type 3 -> Its subscript form occupies space under and after the base (KHO, CHHO, THHO, BA, YO, SA) - * Consonant shifter -> Khmer has to series of consonants. The same dependent vowel has different sounds - * if it is attached to a consonant of the first series or a consonant of the second series - * Most consonants have an equivalent in the other series, but some of theme exist only in - * one series (for example SA). If we want to use the consonant SA with a vowel sound that - * can only be done with a vowel sound that corresponds to a vowel accompanying a consonant - * of the other series, then we need to use a consonant shifter: TRIISAP or MUSIKATOAN - * x17C9 y x17CA. TRIISAP changes a first series consonant to second series sound and - * MUSIKATOAN a second series consonant to have a first series vowel sound. - * Consonant shifter are both normally supercript marks, but, when they are followed by a - * superscript, they change shape and take the form of subscript dependent vowel SRA U. - * If they are in the same syllable as a coeng consonant, Unicode 3.0 says that they - * should be typed before the coeng. Unicode 4.0 breaks the standard and says that it should - * be placed after the coeng consonant. - * Dependent vowel -> In khmer dependent vowels can be placed above, below, before or after the base - * Each vowel has its own position. Only one vowel per syllable is allowed. - * Signs -> Khmer has above signs and post signs. Only one above sign and/or one post sign are - * Allowed in a syllable. - * - * - * order is important here! This order must be the same that is found in each horizontal - * line in the statetable for Khmer (see khmerStateTable) . - */ -enum KhmerCharClassValues -{ - CC_RESERVED = 0, - CC_CONSONANT = 1, /* Consonant of type 1 or independent vowel */ - CC_CONSONANT2 = 2, /* Consonant of type 2 */ - CC_CONSONANT3 = 3, /* Consonant of type 3 */ - CC_ZERO_WIDTH_NJ_MARK = 4, /* Zero Width non joiner character (0x200C) */ - CC_CONSONANT_SHIFTER = 5, - CC_ROBAT = 6, /* Khmer special diacritic accent -treated differently in state table */ - CC_COENG = 7, /* Subscript consonant combining character */ - CC_DEPENDENT_VOWEL = 8, - CC_SIGN_ABOVE = 9, - CC_SIGN_AFTER = 10, - CC_ZERO_WIDTH_J_MARK = 11, /* Zero width joiner character */ - CC_COUNT = 12 /* This is the number of character classes */ -}; - - -enum KhmerCharClassFlags -{ - CF_CLASS_MASK = 0x0000FFFF, - - CF_CONSONANT = 0x01000000, /* flag to speed up comparing */ - CF_SPLIT_VOWEL = 0x02000000, /* flag for a split vowel -> the first part is added in front of the syllable */ - CF_DOTTED_CIRCLE = 0x04000000, /* add a dotted circle if a character with this flag is the first in a syllable */ - CF_COENG = 0x08000000, /* flag to speed up comparing */ - CF_SHIFTER = 0x10000000, /* flag to speed up comparing */ - CF_ABOVE_VOWEL = 0x20000000, /* flag to speed up comparing */ - - /* position flags */ - CF_POS_BEFORE = 0x00080000, - CF_POS_BELOW = 0x00040000, - CF_POS_ABOVE = 0x00020000, - CF_POS_AFTER = 0x00010000, - CF_POS_MASK = 0x000f0000 -}; - - -/* Characters that get refrered to by name */ -enum KhmerChar -{ - C_SIGN_ZWNJ = 0x200C, - C_SIGN_ZWJ = 0x200D, - C_DOTTED_CIRCLE = 0x25CC, - C_RO = 0x179A, - C_VOWEL_AA = 0x17B6, - C_SIGN_NIKAHIT = 0x17C6, - C_VOWEL_E = 0x17C1, - C_COENG = 0x17D2 -}; - - -enum -{ - /* simple classes, they are used in the state table (in this file) to control the length of a syllable - * they are also used to know where a character should be placed (location in reference to the base character) - * and also to know if a character, when independently displayed, should be displayed with a dotted-circle to - * indicate error in syllable construction - */ - _xx = CC_RESERVED, - _sa = CC_SIGN_ABOVE | CF_DOTTED_CIRCLE | CF_POS_ABOVE, - _sp = CC_SIGN_AFTER | CF_DOTTED_CIRCLE| CF_POS_AFTER, - _c1 = CC_CONSONANT | CF_CONSONANT, - _c2 = CC_CONSONANT2 | CF_CONSONANT, - _c3 = CC_CONSONANT3 | CF_CONSONANT, - _rb = CC_ROBAT | CF_POS_ABOVE | CF_DOTTED_CIRCLE, - _cs = CC_CONSONANT_SHIFTER | CF_DOTTED_CIRCLE | CF_SHIFTER, - _dl = CC_DEPENDENT_VOWEL | CF_POS_BEFORE | CF_DOTTED_CIRCLE, - _db = CC_DEPENDENT_VOWEL | CF_POS_BELOW | CF_DOTTED_CIRCLE, - _da = CC_DEPENDENT_VOWEL | CF_POS_ABOVE | CF_DOTTED_CIRCLE | CF_ABOVE_VOWEL, - _dr = CC_DEPENDENT_VOWEL | CF_POS_AFTER | CF_DOTTED_CIRCLE, - _co = CC_COENG | CF_COENG | CF_DOTTED_CIRCLE, - - /* split vowel */ - _va = _da | CF_SPLIT_VOWEL, - _vr = _dr | CF_SPLIT_VOWEL -}; - - -/* Character class: a character class value - * ORed with character class flags. - */ -typedef glong KhmerCharClass; - - -/* Character class tables - * _xx character does not combine into syllable, such as numbers, puntuation marks, non-Khmer signs... - * _sa Sign placed above the base - * _sp Sign placed after the base - * _c1 Consonant of type 1 or independent vowel (independent vowels behave as type 1 consonants) - * _c2 Consonant of type 2 (only RO) - * _c3 Consonant of type 3 - * _rb Khmer sign robat u17CC. combining mark for subscript consonants - * _cd Consonant-shifter - * _dl Dependent vowel placed before the base (left of the base) - * _db Dependent vowel placed below the base - * _da Dependent vowel placed above the base - * _dr Dependent vowel placed behind the base (right of the base) - * _co Khmer combining mark COENG u17D2, combines with the consonant or independent vowel following - * it to create a subscript consonant or independent vowel - * _va Khmer split vowel in wich the first part is before the base and the second one above the base - * _vr Khmer split vowel in wich the first part is before the base and the second one behind (right of) the base - */ -static const KhmerCharClass khmerCharClasses[] = -{ - _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c1, _c1, /* 1780 - 178F */ - _c1, _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c2, _c1, _c1, _c1, _c3, _c3, /* 1790 - 179F */ - _c1, _c3, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, /* 17A0 - 17AF */ - _c1, _c1, _c1, _c1, _dr, _dr, _dr, _da, _da, _da, _da, _db, _db, _db, _va, _vr, /* 17B0 - 17BF */ - _vr, _dl, _dl, _dl, _vr, _vr, _sa, _sp, _sp, _cs, _cs, _sa, _rb, _sa, _sa, _sa, /* 17C0 - 17CF */ - _sa, _sa, _co, _sa, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _sa, _xx, _xx, /* 17D0 - 17DF */ -}; - -/* this define must reflect the range of khmerCharClasses */ -#define firstChar 0x1780 -#define lastChar 0x17df - - - -/* The stateTable is used to calculate the end (the length) of a well - * formed Khmer Syllable. - * - * Each horizontal line is ordered exactly the same way as the values in KhmerClassTable - * CharClassValues. This coincidence of values allows the follow up of the table. - * - * Each line corresponds to a state, which does not necessarily need to be a type - * of component... for example, state 2 is a base, with is always a first character - * in the syllable, but the state could be produced a consonant of any type when - * it is the first character that is analysed (in ground state). - * - * Differentiating 3 types of consonants is necessary in order to - * forbid the use of certain combinations, such as having a second - * coeng after a coeng RO, - * The inexistent possibility of having a type 3 after another type 3 is permitted, - * eliminating it would very much complicate the table, and it does not create typing - * problems, as the case above. - * - * The table is quite complex, in order to limit the number of coeng consonants - * to 2 (by means of the table). - * - * There a peculiarity, as far as Unicode is concerned: - * - The consonant-shifter is considered in two possible different - * locations, the one considered in Unicode 3.0 and the one considered in - * Unicode 4.0. (there is a backwards compatibility problem in this standard). - * - * - * xx independent character, such as a number, punctuation sign or non-khmer char - * - * c1 Khmer consonant of type 1 or an independent vowel - * that is, a letter in which the subscript for is only under the - * base, not taking any space to the right or to the left - * - * c2 Khmer consonant of type 2, the coeng form takes space under - * and to the left of the base (only RO is of this type) - * - * c3 Khmer consonant of type 3. Its subscript form takes space under - * and to the right of the base. - * - * cs Khmer consonant shifter - * - * rb Khmer robat - * - * co coeng character (u17D2) - * - * dv dependent vowel (including split vowels, they are treated in the same way). - * even if dv is not defined above, the component that is really tested for is - * KhmerClassTable::CC_DEPENDENT_VOWEL, which is common to all dependent vowels - * - * zwj Zero Width joiner - * - * zwnj Zero width non joiner - * - * sa above sign - * - * sp post sign - * - * there are lines with equal content but for an easier understanding - * (and maybe change in the future) we did not join them - */ -static const gint8 khmerStateTable[][CC_COUNT] = -{ -/* xx c1 c2 c3 zwnj cs rb co dv sa sp zwj */ - { 1, 2, 2, 2, 1, 1, 1, 6, 1, 1, 1, 2}, /* 0 - ground state */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 1 - exit state (or sign to the right of the syllable) */ - {-1, -1, -1, -1, 3, 4, 5, 6, 16, 17, 1, -1}, /* 2 - Base consonant */ - {-1, -1, -1, -1, -1, 4, -1, -1, 16, -1, -1, -1}, /* 3 - First ZWNJ before a register shifter - It can only be followed by a shifter or a vowel */ - {-1, -1, -1, -1, 15, -1, -1, 6, 16, 17, 1, 14}, /* 4 - First register shifter */ - {-1, -1, -1, -1, -1, -1, -1, -1, 20, -1, 1, -1}, /* 5 - Robat */ - {-1, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1}, /* 6 - First Coeng */ - {-1, -1, -1, -1, 12, 13, -1, 10, 16, 17, 1, 14}, /* 7 - First consonant of type 1 after coeng */ - {-1, -1, -1, -1, 12, 13, -1, -1, 16, 17, 1, 14}, /* 8 - First consonant of type 2 after coeng */ - {-1, -1, -1, -1, 12, 13, -1, 10, 16, 17, 1, 14}, /* 9 - First consonant or type 3 after ceong */ - {-1, 11, 11, 11, -1, -1, -1, -1, -1, -1, -1, -1}, /* 10 - Second Coeng (no register shifter before) */ - {-1, -1, -1, -1, 15, -1, -1, -1, 16, 17, 1, 14}, /* 11 - Second coeng consonant (or ind. vowel) no register shifter before */ - {-1, -1, -1, -1, -1, 13, -1, -1, 16, -1, -1, -1}, /* 12 - Second ZWNJ before a register shifter */ - {-1, -1, -1, -1, 15, -1, -1, -1, 16, 17, 1, 14}, /* 13 - Second register shifter */ - {-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, /* 14 - ZWJ before vowel */ - {-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, /* 15 - ZWNJ before vowel */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 1, 18}, /* 16 - dependent vowel */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 18}, /* 17 - sign above */ - {-1, -1, -1, -1, -1, -1, -1, 19, -1, -1, -1, -1}, /* 18 - ZWJ after vowel */ - {-1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19 - Third coeng */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1}, /* 20 - dependent vowel after a Robat */ -}; - - -enum property_flags -{ - abvf = 0x0001, - pref = 0x0002, - pstf = 0x0004, - blwf = 0x0008, - - pres = 0x0010, - blws = 0x0020, - abvs = 0x0040, - psts = 0x0080, - clig = 0x0100, - - dist = 0x0200, - blwm = 0x0400, - abvm = 0x0800, -}; - - -enum properties -{ - blwf_p = /*(blwf | blws | clig | dist | blwm)*/ (abvf | pref | pstf | pres | abvs | psts | abvm), - pstf_p = /*(blwf | blws | pref | pres | pstf | psts | clig | dist | blwm)*/ (abvf | abvs | abvm), - abvf_p = /*(abvf | abvs | clig | dist | abvm)*/ (pref | pstf | blwf | pres | blws | psts | blwm), - pref_p = /*(pref | pres | clig | dist)*/ (abvf | pstf | blwf | blws | abvs | psts | blwm | abvm), - default_p = /*(pres | blws | clig | dist | abvm | blwm)*/ (pref | blwf |abvf | pstf | abvs | psts) -}; - - -/* Below we define how a character in the input string is either in the khmerCharClasses table - * (in which case we get its type back), a ZWJ or ZWNJ (two characters that may appear - * within the syllable, but are not in the table) we also get their type back, or an unknown object - * in which case we get _xx (CC_RESERVED) back - */ -static KhmerCharClass -get_char_class (gunichar ch) -{ - if (ch == C_SIGN_ZWJ) - return CC_ZERO_WIDTH_J_MARK; - - if (ch == C_SIGN_ZWNJ) - return CC_ZERO_WIDTH_NJ_MARK; - - if (ch < firstChar || ch > lastChar) - return CC_RESERVED; - - return khmerCharClasses[ch - firstChar]; -} - - -/* Given an input string of characters and a location in which to start looking - * calculate, using the state table, which one is the last character of the syllable - * that starts in the starting position. - */ -static glong -find_syllable (const gunichar *chars, - glong start, - glong char_count) -{ - glong cursor = start; - gint8 state = 0; - KhmerCharClass charClass; - - while (cursor < char_count) - { - charClass = get_char_class (chars[cursor]) & CF_CLASS_MASK; - state = khmerStateTable[state][charClass]; - - if (state < 0) - break; - - cursor += 1; - } - - return cursor; -} - -static const PangoOTFeatureMap gsub_features[] = -{ - {"ccmp", PANGO_OT_ALL_GLYPHS}, - {"locl", PANGO_OT_ALL_GLYPHS}, - {"pref", pref}, - {"blwf", blwf}, - {"abvf", abvf}, - {"pstf", pstf}, - {"pres", pres}, - {"blws", blws}, - {"abvs", abvs}, - {"psts", psts}, - {"clig", clig}, - {"calt", PANGO_OT_ALL_GLYPHS} -}; - -static const PangoOTFeatureMap gpos_features[] = -{ - {"dist", dist}, - {"blwm", blwm}, - {"abvm", abvm}, - {"kern", PANGO_OT_ALL_GLYPHS}, - {"mark", PANGO_OT_ALL_GLYPHS}, - {"mkmk", PANGO_OT_ALL_GLYPHS} -}; - -static PangoGlyph -get_index (PangoFcFont *fc_font, gunichar wc) -{ - PangoGlyph index = pango_fc_font_get_glyph (fc_font, wc); - if (!index) - index = PANGO_GET_UNKNOWN_GLYPH ( wc); - return index; -} - - -static void -khmer_engine_shape (PangoEngineShape *engine G_GNUC_UNUSED, - PangoFont *font, - const char *text, - int length, - const PangoAnalysis *analysis, - PangoGlyphString *glyphs) -{ - PangoFcFont *fc_font; - FT_Face face; - PangoOTRulesetDescription desc; - const PangoOTRuleset *ruleset; - PangoOTBuffer *buffer; - glong n_chars; - gunichar *wcs; - const char *p; - int i; - glong syllable; - KhmerCharClass charClass; - glong cursor = 0; - - g_return_if_fail (font != NULL); - g_return_if_fail (text != NULL); - g_return_if_fail (length >= 0); - g_return_if_fail (analysis != NULL); - - fc_font = PANGO_FC_FONT (font); - face = pango_fc_font_lock_face (fc_font); - if (!face) - return; - - buffer = pango_ot_buffer_new (fc_font); - pango_ot_buffer_set_rtl (buffer, analysis->level % 2 != 0); - - wcs = g_utf8_to_ucs4_fast (text, length, &n_chars); - - p = text; - /* This loop only exits when we reach the end of a run, which may contain - * several syllables. - */ - while (cursor < n_chars) - { - /* write a pre vowel or the pre part of a split vowel first - * and look out for coeng + ro. RO is the only vowel of type 2, and - * therefore the only one that requires saving space before the base. - */ - glong coengRo = -1; /* There is no Coeng Ro, if found this value will change */ - - syllable = find_syllable (wcs, cursor, n_chars); - - for (i = cursor; i < syllable; i += 1) - { - charClass = get_char_class (wcs[i]); - - /* if a split vowel, write the pre part. In Khmer the pre part - * is the same for all split vowels, same glyph as pre vowel C_VOWEL_E - */ - if (charClass & CF_SPLIT_VOWEL) - { - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, C_VOWEL_E), pref_p, p - text); - break; /* there can be only one vowel */ - } - - /* if a vowel with pos before write it out */ - if (charClass & CF_POS_BEFORE) - { - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), pref_p, p - text); - break; /* there can be only one vowel */ - } - - /* look for coeng + ro and remember position - * works because coeng + ro is always in front of a vowel (if there is a vowel) - * and because CC_CONSONANT2 is enough to identify it, as it is the only consonant - * with this flag - */ - if ((charClass & CF_COENG) && (i + 1 < syllable) && - ((get_char_class (wcs[i + 1]) & CF_CLASS_MASK) == CC_CONSONANT2)) - { - coengRo = i; - } - } - - /* write coeng + ro if found */ - if (coengRo > -1) - { - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, C_COENG), pref_p, p - text); - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, C_RO), pref_p, p - text); - } - - /* shall we add a dotted circle? - * If in the position in which the base should be (first char in the string) there is - * a character that has the Dotted circle flag (a character that cannot be a base) - * then write a dotted circle - */ - if (get_char_class (wcs[cursor]) & CF_DOTTED_CIRCLE) - { - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, C_DOTTED_CIRCLE), default_p, p - text); - } - - /* copy what is left to the output, skipping before vowels and - * coeng Ro if they are present - */ - for (i = cursor; i < syllable; i += 1) - { - charClass = get_char_class (wcs[i]); - - /* skip a before vowel, it was already processed */ - if (charClass & CF_POS_BEFORE) - { - p = g_utf8_next_char (p); - continue; - } - - /* skip coeng + ro, it was already processed */ - if (i == coengRo) - { - p = g_utf8_next_char (p); - i += 1; - p = g_utf8_next_char (p); - continue; - } - - switch (charClass & CF_POS_MASK) - { - case CF_POS_ABOVE : - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), abvf_p, p - text); - break; - - case CF_POS_AFTER : - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), pstf_p, p - text); - break; - - case CF_POS_BELOW : - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text); - break; - - default: - /* assign the correct flags to a coeng consonant - * Consonants of type 3 are taged as Post forms and those type 1 as below forms - */ - if ((charClass & CF_COENG) && i + 1 < syllable) - { - if ((get_char_class (wcs[i + 1]) & CF_CLASS_MASK) == CC_CONSONANT3) - { - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), pstf_p, p - text); - p = g_utf8_next_char (p); - i += 1; - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), pstf_p, p - text); - break; - } - else - { - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text); - p = g_utf8_next_char (p); - i += 1; - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text); - break; - } - } - - /* if a shifter is followed by an above vowel change the shifter to below form, - * an above vowel can have two possible positions i + 1 or i + 3 - * (position i+1 corresponds to unicode 3, position i+3 to Unicode 4) - * and there is an extra rule for C_VOWEL_AA + C_SIGN_NIKAHIT also for two - * different positions, right after the shifter or after a vowel (Unicode 4) - */ - if ((charClass & CF_SHIFTER) && (i + 1 < syllable)) - { - if (get_char_class (wcs[i + 1]) & CF_ABOVE_VOWEL) - { - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text); - break; - } - if (i + 2 < syllable && - (wcs[i + 1] == C_VOWEL_AA) && - (wcs[i + 2] == C_SIGN_NIKAHIT) ) - { - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text); - break; - } - if (i + 3 < syllable && (get_char_class (wcs[i + 3]) & CF_ABOVE_VOWEL) ) - { - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text); - break; - } - if (i + 4 < syllable && - (wcs[i + 3] == C_VOWEL_AA) && - (wcs[i + 4] == C_SIGN_NIKAHIT) ) - { - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text); - break; - } - - } - - /* default - any other characters */ - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), default_p, p - text); - break; - } /* switch */ - p = g_utf8_next_char (p); - } /* for */ - - cursor = syllable; /* move the pointer to the start of next syllable */ - } /* while */ - - desc.script = analysis->script; - desc.language = analysis->language; - - desc.n_static_gsub_features = G_N_ELEMENTS (gsub_features); - desc.static_gsub_features = gsub_features; - desc.n_static_gpos_features = G_N_ELEMENTS (gpos_features); - desc.static_gpos_features = gpos_features; - - /* TODO populate other_features from analysis->extra_attrs */ - desc.n_other_features = 0; - desc.other_features = NULL; - - ruleset = pango_ot_ruleset_get_for_description (pango_ot_info_get (face), &desc); - - pango_ot_ruleset_substitute (ruleset, buffer); - pango_ot_ruleset_position (ruleset, buffer); - pango_ot_buffer_output (buffer, glyphs); - - g_free (wcs); - pango_ot_buffer_destroy (buffer); - - pango_fc_font_unlock_face (fc_font); -} - - -static void -khmer_engine_fc_class_init (PangoEngineShapeClass *class) -{ - class->script_shape = khmer_engine_shape; -} - -PANGO_ENGINE_SHAPE_DEFINE_TYPE (KhmerEngineFc, khmer_engine_fc, - khmer_engine_fc_class_init, NULL) - - -void -PANGO_MODULE_ENTRY(init) (GTypeModule *module) -{ - khmer_engine_fc_register_type (module); -} - - -void -PANGO_MODULE_ENTRY(exit) (void) -{ -} - - -void -PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, - int *n_engines) -{ - *engines = script_engines; - *n_engines = G_N_ELEMENTS (script_engines); -} - - -PangoEngine * -PANGO_MODULE_ENTRY(create) (const char *id) -{ - if (!strcmp (id, SCRIPT_ENGINE_NAME)) - return g_object_new (khmer_engine_fc_type, NULL); - else - return NULL; -} diff --git a/modules/tibetan/Makefile.am b/modules/tibetan/Makefile.am deleted file mode 100644 index 96ee4225..00000000 --- a/modules/tibetan/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -include $(top_srcdir)/modules/Module.mk - -if HAVE_FREETYPE -INCLUDES += $(FREETYPE_CFLAGS) -if INCLUDE_TIBETAN_FC -noinst_LTLIBRARIES += libpango-tibetan-fc.la -else -if DYNAMIC_TIBETAN_FC -module_LTLIBRARIES += pango-tibetan-fc.la -endif -endif -endif - -tibetan_fc_sources = $(common_sources) tibetan-fc.c - -pango_tibetan_fc_la_LDFLAGS = -module $(MODULE_LIBTOOL_OPTIONS) -pango_tibetan_fc_la_LIBADD = $(pangoft2libs) -pango_tibetan_fc_la_SOURCES = $(tibetan_fc_sources) -libpango_tibetan_fc_la_SOURCES = $(tibetan_fc_sources) -libpango_tibetan_fc_la_CFLAGS = -DPANGO_MODULE_PREFIX=_pango_tibetan_fc - --include $(top_srcdir)/git.mk diff --git a/modules/tibetan/tibetan-fc.c b/modules/tibetan/tibetan-fc.c deleted file mode 100644 index 4e894165..00000000 --- a/modules/tibetan/tibetan-fc.c +++ /dev/null @@ -1,574 +0,0 @@ -/* Pango - * tibetan-fc.c: Shaper for Tibetan script - * - * Copyright (C) 2005 DIT, Government of Bhutan <http://www.dit.gov.bt> - * Contact person : Pema Geyleg <pema_geyleg@druknet.bt> - * - * Based on code from khmer shapers developed by Jens Herden - * <jens@tibetanos.inf > and Javier Sola <javier@tibetanos.info> - * - * Based on code from other shapers - * Copyright (C) 1999-2004 Red Hat Software - * Author: Owen Taylor <otaylor@redhat.com> - - * Partially based on Indic shaper - * Copyright (C) 2001, 2002 IBM Corporation - * Author: Eric Mader <mader@jtcsv.com> - * - * The first module for Tibetan shaper was developed by Mr. Karunakar under - * PanLocalization project. - * Mr. Chris Fynn, Mr.Javier Sola, Mr. Namgay Thinley were involved - * while developing this shaper. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * The license on the original Indic shaper code is as follows: - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished - * to do so, provided that the above copyright notice(s) and this - * permission notice appear in all copies of the Software and that - * both the above copyright notice(s) and this permission notice - * appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR - * ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY - * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder - * shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written - * authorization of the copyright holder. - */ -#include "config.h" -#include <string.h> - -#include "pango-engine.h" -#include "pango-ot.h" -#include "pango-utils.h" -#include "pangofc-font.h" - - -#define SCRIPT_ENGINE_NAME "TibetanScriptEngineFc" -#define RENDER_TYPE PANGO_RENDER_TYPE_FC - - -typedef PangoEngineShape TibetanEngineFc; -typedef PangoEngineShapeClass TibetanEngineFcClass ; - - -static PangoEngineScriptInfo tibetan_scripts[] = -{ - { PANGO_SCRIPT_TIBETAN, "*" } -}; - -static PangoEngineInfo script_engines[] = -{ - { - SCRIPT_ENGINE_NAME, - PANGO_ENGINE_TYPE_SHAPE, - RENDER_TYPE, - tibetan_scripts, G_N_ELEMENTS (tibetan_scripts) - } -}; - - -/* - * Vocabulary - * Base -> A consonant in its full (not subscript) form. It is the - * center of the syllable, it can be souranded by subjoined consonants, vowels, - * signs... but there is only one base in a stack, it has to be coded as - * the first character of the syllable.Included here are also groups of base + subjoined - * which are represented by one single code point in unicode (e.g. 0F43) Also other characters - * that might take subjoined consonants or other combining characters. - * Subjoined -> Subjoined consonants and groups of subjoined consonants which have a single code-point - * to repersent the group (even if each subjoined consonant is represented independently - * by anothe code-point - * Tsa Phru --> Tsa Phru character, Bhutanese people will always place it right after the base, but sometimes, due to - * "normalization" is placed after all the subjoined consonants, and it is also permitted there. - * A Chung Vowel lengthening mark --> . 0F71 It is placed after the base and any subjoined consonants but before any vowels - * Precomposed Sanskrit vowels --> The are combinations of subjoined consonants + vowels that have been assigned - * a given code-point (in spite of each single part of them having also a code-point - * They are avoided, and users are encouraged to use the combination of code-points that - * represents the same sound instead of using this combined characters. This is included here - * for compatibility with possible texts that use them (they are not in the Dzongkha keyboard). - * Halanta -> The Halanta or Virama character 0F84 indicates that a consonant should not use its inheernt vowel, - * in spite of not having other vowels present. It is usually placed immediatly after a base consonant, - * but in some special cases it can also be placed after a subjoined consonant, so this is also - * permitted in this algorithm. (Halanta is always displayed in Tibetan not used as a connecting char) - * - * Subjoined vowels -> Dependent vowels (matras) placed below the base and below all subjoined consonants. There - * might be as much as three subjoined vowels in a given stack (only one in general text, but up - * to three for abreviations, they have to be permitted). - * Superscript vowels -> There are three superscript vowels, and they can be repeated or combined (up to three - * times. They can combine with subjoined vowels, and are always coded after these. - * Anusvara --> Nasalisation sign. Traditioinally placed in absence of vowels, but also after vowels. In some - * special cases it can be placed before a vowel, so this is also permitted - * Candrabindu -> Forms of the Anusvara with different glyphs (and different in identity) which can be placed - * without vowel or after the vowel, but never before. Cannot combine with Anusvara. - * Stress marks -> Marks placed above or below a syllable, affecting the whole syllable. They are combining - * marks, so they have to be attached to a specific stack. The are using to emphasise a syllable. - * - * Digits -> Digits are not considered as non-combining characters because there are a few characters which - * combine with them, so they have to be considered independently. - * Digit combining marks -> dependent marks that combine with digits. - * - * TODO - * There are a number of characters in the CJK block that are used in Tibetan script, two of these are symbols - * are used as bases for combining glyphs, and have not been encoded in Tibetan. As these characters are outside - * of the tibetan block, they have not been treated in this program. -*/ - - -enum TibetanCharClassValues -{ - CC_RESERVED = 0, /* Non Combining Characters*/ - CC_BASE = 1, /* Base Consonants, Base Consonants with Subjoined attached in code point, Sanskrit base marks*/ - CC_SUBJOINED = 2, /* Subjoined Consonats, combination of more than Subjoined Consonants in the code point*/ - CC_TSA_PHRU = 3, /* Tsa-Phru character 0F39*/ - CC_A_CHUNG = 4, /* Vowel Lenthening a-chung mark 0F71*/ - CC_COMP_SANSKRIT = 5, /* Precomposed Sanskrit vowels including Subjoined characters and vowels*/ - CC_HALANTA = 6, /* Halanta Character 0F84*/ - CC_BELOW_VOWEL = 7, /* Subjoined vowels*/ - CC_ABOVE_VOWEL = 8, /* Superscript vowels*/ - CC_ANUSVARA = 9, /* Tibetan sign Rjes Su Nga Ro 0F7E*/ - CC_CANDRABINDU = 10, /* Tibetan sign Sna Ldan and Nyi Zla Naa Da 0F82, 0F83*/ - CC_VISARGA = 11, /* Tibetan sign Rnam Bcad (0F7F)*/ - CC_ABOVE_S_MARK = 12, /* Stress Marks placed above the text*/ - CC_BELOW_S_MARK = 13, /* Stress Marks placed below the text*/ - CC_DIGIT = 14, /* Dzongkha Digits*/ - CC_PRE_DIGIT_MARK = 15, /* Mark placed before the digit*/ - CC_POST_BELOW_DIGIT_M = 16, /* Mark placed below or after the digit*/ - CC_COUNT = 17 /* This is the number of character classes*/ -}; - - -enum TibetanCharClassFlags -{ - CF_CLASS_MASK = 0x0000FFFF, - - CF_DOTTED_CIRCLE = 0x04000000, /* add a dotted circle if a character with this flag is the first in a syllable*/ - CF_DIGIT = 0x01000000, /* flag to speed up comparaisson*/ - CF_PREDIGIT = 0x02000000, /* flag to detect pre-digit marks for reordering*/ - - /* position flags*/ - CF_POS_BEFORE = 0x00080000, - CF_POS_BELOW = 0x00040000, - CF_POS_ABOVE = 0x00020000, - CF_POS_AFTER = 0x00010000, - CF_POS_MASK = 0x000f0000 -}; - - -/* Characters that get refrered to by name */ -enum TibetanChar -{ - C_DOTTED_CIRCLE = 0x25CC, - C_PRE_NUMBER_MARK = 0x0F3F -}; - - -enum -{ - /* simple classes, they are used in the statetable (in this file) to control the length of a syllable - * they are also used to know where a character should be placed (location in reference to the base character) - * and also to know if a character, when independtly displayed, should be displayed with a dotted-circle to - * indicate error in syllable construction - */ - _xx = CC_RESERVED, - _ba = CC_BASE, - _sj = CC_SUBJOINED | CF_DOTTED_CIRCLE | CF_POS_BELOW, - _tp = CC_TSA_PHRU | CF_DOTTED_CIRCLE | CF_POS_ABOVE, - _ac = CC_A_CHUNG | CF_DOTTED_CIRCLE | CF_POS_BELOW, - _cs = CC_COMP_SANSKRIT | CF_DOTTED_CIRCLE | CF_POS_BELOW, - _ha = CC_HALANTA | CF_DOTTED_CIRCLE | CF_POS_BELOW, - _bv = CC_BELOW_VOWEL | CF_DOTTED_CIRCLE | CF_POS_BELOW, - _av = CC_ABOVE_VOWEL | CF_DOTTED_CIRCLE | CF_POS_ABOVE, - _an = CC_ANUSVARA | CF_DOTTED_CIRCLE | CF_POS_ABOVE, - _cb = CC_CANDRABINDU | CF_DOTTED_CIRCLE | CF_POS_ABOVE, - _vs = CC_VISARGA | CF_DOTTED_CIRCLE| CF_POS_AFTER, - _as = CC_ABOVE_S_MARK | CF_DOTTED_CIRCLE | CF_POS_ABOVE, - _bs = CC_BELOW_S_MARK | CF_DOTTED_CIRCLE | CF_POS_BELOW, - _di = CC_DIGIT | CF_DIGIT, - _pd = CC_PRE_DIGIT_MARK | CF_DOTTED_CIRCLE | CF_PREDIGIT | CF_POS_BEFORE , - _bd = CC_POST_BELOW_DIGIT_M | CF_DOTTED_CIRCLE | CF_POS_AFTER -}; - - -/* Character class: a character class value - * ORed with character class flags. - */ -typedef glong TibetanCharClass; -/*_xx Non Combining characters*/ -/*_ba Base Consonants*/ -/*_sj Subjoined consonants*/ -/*_tp Tsa - phru*/ -/*_ac A-chung, Vowel Lengthening mark*/ -/*_cs Precomposed Sanskrit vowel + subjoined consonants*/ -/*_ha Halanta/Virama*/ -/*_bv Below vowel*/ -/*_av above vowel*/ -/*_an Anusvara*/ -/*_cb Candrabindu*/ -/*_vs Visaraga/Post mark*/ -/*_as Upper Stress marks*/ -/*_bs Lower Stress marks*/ -/*_di Digit*/ -/*_pd Number pre combining, Needs reordering*/ -/*_bd Other number combining marks*/ - - -static const TibetanCharClass tibetanCharClasses[] = -{ - /* 0 1 2 3 4 5 6 7 8 9 a b c d e f*/ - _xx, _ba, _xx, _xx, _ba, _ba, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, /* 0F00 - 0F0F 0*/ - _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _bd, _bd, _xx, _xx, _xx, _xx, _xx, _xx, /* 0F10 - 0F1F 1*/ - _di, _di, _di, _di, _di, _di, _di, _di, _di, _di, _xx, _xx, _xx, _xx, _xx, _xx, /* 0F20 - 0F2F 2*/ - _xx, _xx, _xx, _xx, _xx, _bs, _xx, _bs, _xx, _tp, _xx, _xx, _xx, _xx, _bd, _pd, /* 0F30 - 0F3F 3*/ - _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _xx, _ba, _ba, _ba, _ba, _ba, _ba, _ba, /* 0F40 - 0F4F 4*/ - _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, /* 0F50 - 0F5F 5*/ - _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _xx, _xx, _xx, _xx, _xx, /* 0F60 - 0F6F 6*/ - _xx, _ac, _av, _cs, _bv, _bv, _cs, _cs, _cs, _cs, _av, _av, _av, _av, _an, _vs, /* 0F70 - 0F7F 7*/ - _av, _cs, _cb, _cb, _ha, _xx, _as, _as, _ba, _ba, _ba, _ba, _xx, _xx, _xx, _xx, /* 0F80 - 0F8F 8*/ - _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _xx, _sj, _sj, _sj, _sj, _sj, _sj, _sj, /* 0F90 - 0F9F 9*/ - _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, /* 0FA0 - 0FAF a*/ - _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _xx, _sj, _sj, /* 0FB0 - 0FBF b*/ - _xx, _xx, _xx, _xx, _xx, _xx, _bs, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, /* 0FC0 - 0FCF c*/ - _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, /* 0FD0 - 0FDF d*/ - _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, /* 0FE0 - 0FEF e*/ - _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, /* 0FF0 - 0FFF f*/ -}; - -/* this define must reflect the range of tibetanCharClasses */ -/*First Tibetan Character*/ -#define firstChar 0x0F00 -/*Last Tibetan Character*/ -#define lastChar 0x0FFF - -/* The stateTable is used to calculate the end (the length) of a well - * formed Tibetan Stack - * - * Each horizontal line is ordered exactly the same way as the values in TibetanClassTable - * CharClassValues.This coincidence of values allows the follow up of the table. - * - * Each line corresponds to a state, which does not necessarily need to be a type - * of component... for example, state 2 is a base, with is always a first character - * in the Stack but the state could be produced a consonant of any type when - * it is the first character that is analysed (in ground state). - */ - -static const gint8 tibetanStateTable[][CC_COUNT] = -{ - /*Dzongkha state table*/ - /*xx ba sj tp ac cs ha bv av an cb vs as bs di pd bd*/ - { 1, 2, 4, 3, 8, 7, 9, 10, 14, 13, 17, 18, 19, 19, 20, 21, 21,}, /* 0 - ground state*/ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,}, /* 1 - exit state (or sign to the right of the syllable)*/ - {-1, -1, 4, 3, 8, 7, 9, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, /* 2 - Base consonant*/ - {-1, -1, 5, -1, 8, 7, -1, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, /* 3 - Tsa phru after base*/ - {-1, -1, 4, 6, 8, 7, 9, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, /* 4 - Subjoined consonant after base*/ - {-1, -1, 5, -1, 8, 7, -1, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, /* 5 - Subjoined consonant after tsa phru*/ - {-1, -1, -1, -1, 8, 7, -1, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, /* 6 - Tsa phru after subjoined consonant*/ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, 19, -1, -1, -1,}, /* 7 - Pre Composed Sanskrit*/ - {-1, -1, -1, -1, -1, -1, -1, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, /* 8 - A-chung*/ - {-1, -1, -1, -1, -1, -1, -1, -1, 14, 13, 17, -1, 19, 19, -1, -1, -1,}, /* 9 - Halanta*/ - {-1, -1, -1, -1, -1, -1, -1, 11, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, /* 10 - below vowel 1*/ - {-1, -1, -1, -1, -1, -1, -1, 12, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, /* 11 - below vowel 2*/ - {-1, -1, -1, -1, -1, -1, -1, -1, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, /* 12 - below vowel 3*/ - {-1, -1, -1, -1, -1, -1, -1, -1, 14, 17, 17, 18, 19, 19, -1, -1, -1,}, /* 13 - Anusvara before vowel*/ - {-1, -1, -1, -1, -1, -1, -1, -1, 15, 17, 17, 18, 19, 19, -1, -1, -1,}, /* 14 - above vowel 1*/ - {-1, -1, -1, -1, -1, -1, -1, -1, 16, 17, 17, 18, 19, 19, -1, -1, -1,}, /* 15 - above vowel 2*/ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 17, 18, 19, 19, -1, -1, -1,}, /* 16 - above vowel 3*/ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, 19, 19, -1, -1, -1,}, /* 17 - Anusvara or Candrabindu after vowel*/ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, 19, -1, -1, -1,}, /* 18 - Visarga*/ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,}, /* 19 - strss mark*/ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 21,}, /* 20 - digit*/ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,}, /* 21 - digit mark*/ -}; - - -enum property_flags -{ - abvf = 0x0001, - pref = 0x0002, - pstf = 0x0004, - blwf = 0x0008, - - pres = 0x0010, - blws = 0x0020, - abvs = 0x0040, - psts = 0x0080, - clig = 0x0100, - - dist = 0x0200, - blwm = 0x0400, - abvm = 0x0800, -}; - - -enum properties -{ - blwf_p = /*(blwf | blws | clig | dist | blwm)*/ (abvf | pref | pstf | pres | abvs | psts | abvm), - pstf_p = /*(blwf | blws | pref | pres | pstf | psts | clig | dist | blwm)*/ (abvf | abvs | abvm), - abvf_p = /*(abvf | abvs | clig | dist | abvm)*/ (pref | pstf | blwf | pres | blws | psts | blwm), - pref_p = /*(pref | pres | clig | dist)*/ (abvf | pstf | blwf | blws | abvs | psts | blwm | abvm), - default_p = /*(pres | blws | clig | dist | abvm | blwm)*/ (pref | blwf |abvf | pstf | abvs | psts) -}; - - -/* Below we define how a character in the input string is either in the tibetanCharClasses table - * (in which case we get its type back), or an unknown object in which case we get _xx (CC_RESERVED) back - */ -static TibetanCharClass -get_char_class (gunichar ch) -{ - - if (ch < firstChar || ch > lastChar) - return CC_RESERVED; - - return tibetanCharClasses[ch - firstChar]; -} - - -/* Given an input string of characters and a location in which to start looking - * calculate, using the state table, which one is the last character of the syllable - * that starts in the starting position. - */ -static glong -find_syllable (const gunichar *chars, - glong start, - glong char_count) -{ - glong cursor = start; - gint8 state = 0; - TibetanCharClass charClass; - - while (cursor < char_count) - { - charClass = get_char_class (chars[cursor]) & CF_CLASS_MASK; - state = tibetanStateTable[state][charClass]; - - if (state < 0) - break; - - cursor += 1; - } - - return cursor; -} - -static const PangoOTFeatureMap gsub_features[] = -{ - {"ccmp", PANGO_OT_ALL_GLYPHS}, - {"locl", PANGO_OT_ALL_GLYPHS}, - {"blws", blws}, - {"abvs", abvs}, - {"psts", psts}, - {"clig", clig}, - {"calt", PANGO_OT_ALL_GLYPHS} -}; - -static const PangoOTFeatureMap gpos_features[] = -{ - {"dist", dist}, - {"blwm", blwm}, - {"abvm", abvm}, - {"kern", PANGO_OT_ALL_GLYPHS}, - {"mark", PANGO_OT_ALL_GLYPHS}, - {"mkmk", PANGO_OT_ALL_GLYPHS} -}; - -static PangoGlyph -get_index (PangoFcFont *fc_font, gunichar wc) -{ - PangoGlyph index = pango_fc_font_get_glyph (fc_font, wc); - if (!index) - index = PANGO_GET_UNKNOWN_GLYPH ( wc); - return index; -} - - -static void -tibetan_engine_shape (PangoEngineShape *engine G_GNUC_UNUSED, - PangoFont *font, - const char *text, - int length, - const PangoAnalysis *analysis, - PangoGlyphString *glyphs) -{ - PangoFcFont *fc_font; - FT_Face face; - PangoOTRulesetDescription desc; - const PangoOTRuleset *ruleset; - PangoOTBuffer *buffer; - glong n_chars; - gunichar *wcs; - const char *p; - int i; - glong syllable; - TibetanCharClass charClass; - glong cursor = 0; - - g_return_if_fail (font != NULL); - g_return_if_fail (text != NULL); - g_return_if_fail (length >= 0); - g_return_if_fail (analysis != NULL); - - fc_font = PANGO_FC_FONT (font); - face = pango_fc_font_lock_face (fc_font); - if (!face) - return; - - buffer = pango_ot_buffer_new (fc_font); - pango_ot_buffer_set_rtl (buffer, analysis->level % 2 != 0); - - wcs = g_utf8_to_ucs4_fast (text, length, &n_chars); - - p = text; - /* This loop only exits when we reach the end of a run, which may contain - * several syllables. - */ - while (cursor < n_chars) - { - syllable = find_syllable (wcs, cursor, n_chars); - - /* shall we add a dotted circle? - * If in the position in which the base should be (first char in the string) there is - * a character that has the Dotted circle flag (a character that cannot be a base) - * then write a dotted circle - */ - if (get_char_class (wcs[cursor]) & CF_DOTTED_CIRCLE) - { - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, C_DOTTED_CIRCLE), default_p, p - text); - } - - /* If it encounters a digit followed by number pre combining mark, then reorder the two characters - * coeng Ro if they are present - */ - for (i = cursor; i < syllable; i += 1) - { - charClass = get_char_class (wcs[i]); - - if ((charClass & CF_DIGIT ) - && ( get_char_class (wcs[i+1]) & CF_PREDIGIT)) - { - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, C_PRE_NUMBER_MARK), pref_p, p - text); - p = g_utf8_next_char (p); - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), pref_p, p - text); - i += 1; - } else { - switch (charClass & CF_POS_MASK) - { - case CF_POS_ABOVE : - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), abvf_p, p - text); - break; - - case CF_POS_AFTER : - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), pstf_p, p - text); - break; - - case CF_POS_BELOW : - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text); - break; - - default: - /* default - any other characters */ - pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), default_p, p - text); - break; - } /* switch */ - } - - p = g_utf8_next_char (p); - } /* for */ - - cursor = syllable; /* move the pointer to the start of next syllable */ - } /* while */ - - desc.script = analysis->script; - desc.language = analysis->language; - - desc.n_static_gsub_features = G_N_ELEMENTS (gsub_features); - desc.static_gsub_features = gsub_features; - desc.n_static_gpos_features = G_N_ELEMENTS (gpos_features); - desc.static_gpos_features = gpos_features; - - /* TODO populate other_features from analysis->extra_attrs */ - desc.n_other_features = 0; - desc.other_features = NULL; - - ruleset = pango_ot_ruleset_get_for_description (pango_ot_info_get (face), &desc); - - pango_ot_ruleset_substitute (ruleset, buffer); - pango_ot_ruleset_position (ruleset, buffer); - pango_ot_buffer_output (buffer, glyphs); - - g_free (wcs); - pango_ot_buffer_destroy (buffer); - - pango_fc_font_unlock_face (fc_font); -} - - -static void -tibetan_engine_fc_class_init (PangoEngineShapeClass *class) -{ - class->script_shape = tibetan_engine_shape; -} - -PANGO_ENGINE_SHAPE_DEFINE_TYPE (TibetanEngineFc, tibetan_engine_fc, - tibetan_engine_fc_class_init, NULL) - - -void -PANGO_MODULE_ENTRY(init) (GTypeModule *module) -{ - tibetan_engine_fc_register_type (module); -} - - -void -PANGO_MODULE_ENTRY(exit) (void) -{ -} - - -void -PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, - int *n_engines) -{ - *engines = script_engines; - *n_engines = G_N_ELEMENTS (script_engines); -} - - -PangoEngine * -PANGO_MODULE_ENTRY(create) (const char *id) -{ - if (!strcmp (id, SCRIPT_ENGINE_NAME)) - return g_object_new (tibetan_engine_fc_type, NULL); - else - return NULL; -} |