diff options
author | Chookij Vanatham <chookij@src.gnome.org> | 2002-01-17 01:11:39 +0000 |
---|---|---|
committer | Chookij Vanatham <chookij@src.gnome.org> | 2002-01-17 01:11:39 +0000 |
commit | ef8b7d001fe4d7422f682284bc4ca777aa7ec1b5 (patch) | |
tree | 99615134bbc4c2be7385994ce4ce93519a8649d8 /modules | |
parent | 807e62c50179007e9cc455ac34033a45c9a15247 (diff) | |
download | pango-ef8b7d001fe4d7422f682284bc4ca777aa7ec1b5.tar.gz |
bug#: 68350 pango module for xft and freetype2.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/hebrew/Makefile.am | 83 | ||||
-rw-r--r-- | modules/hebrew/hebrew-x.c | 663 |
2 files changed, 237 insertions, 509 deletions
diff --git a/modules/hebrew/Makefile.am b/modules/hebrew/Makefile.am index df71511c..836f0c4d 100644 --- a/modules/hebrew/Makefile.am +++ b/modules/hebrew/Makefile.am @@ -1,30 +1,95 @@ ## Process this file with automake to create Makefile.in. -sources = hebrew-x.c +common_sources = hebrew-shaper.c +hebrew_x_sources = $(common_sources) hebrew-x.c +hebrew_xft_sources = $(common_sources) hebrew-xft.c +hebrew_ft2_sources = $(common_sources) hebrew-ft2.c pangolibs = $(top_builddir)/pango/libpango.la $(FRIBIDI_LIBS) $(GLIB_LIBS) pangoxlibs = $(top_builddir)/pango/libpangox.la $(X_LIBS) $(pangolibs) pangoxftlibs = $(top_builddir)/pango/libpangoxft.la $(XFT_LIBS) $(pangolibs) pangoft2libs = $(top_builddir)/pango/libpangoft2.la $(FREETYPE_LIBS) $(pangolibs) +if HAVE_XFT +if INCLUDE_BASIC_XFT +XFT_INCLUDED=libpango-hebrew-xft.la +XFT_MODULES= +XFT_PREFIX=-DXFT_MODULE_PREFIX +else +XFT_INCLUDED= +XFT_MODULES=pango-hebrew-xft.la +XFT_PREFIX= +hebrew_xft_libadd=$(pangoxlibs) $(pangoxftlibs) +endif +else +XFT_MODULES= +XFT_INCLUDED= +XFT_PREFIX= +endif + if HAVE_X -if INCLUDE_HEBREW_X -noinst_LTLIBRARIES = libpango-hebrew-x.la -moddefine = -DX_MODULE_PREFIX +if INCLUDE_BASIC_X +X_INCLUDED=libpango-hebrew-x.la +X_MODULES= +X_PREFIX=-DX_MODULE_PREFIX else -moduledir = $(libdir)/pango/modules -module_LTLIBRARIES = pango-hebrew-x.la +X_INCLUDED= +X_MODULES=pango-hebrew-x.la +X_PREFIX= hebrew_x_libadd=$(pangoxlibs) endif +else +X_INCLUDED= +X_MODULES= +X_PREFIX= +endif + +if HAVE_FREETYPE +if INCLUDE_BASIC_FT2 +FT2_INCLUDED=libpango-hebrew-ft2.la +FT2_MODULES= +FT2_PREFIX=-DFT2_MODULE_PREFIX +else +FT2_INCLUDED= +FT2_MODULES=pango-hebrew-ft2.la +FT2_PREFIX= +hebrew_ft2_libadd=$(pangoft2libs) +endif +else +FT2_MODULES= +FT2_INCLUDED= +FT2_PREFIX= endif -INCLUDES = -DPANGO_ENABLE_ENGINE -DG_DISABLE_DEPRECATED -I$(top_srcdir) -I$(top_srcdir)/pango/ $(moddefine) $(X_CFLAGS) +noinst_LTLIBRARIES = $(X_INCLUDED) $(FT2_INCLUDED) $(XFT_INCLUDED) +module_LTLIBRARIES = $(X_MODULES) $(FT2_MODULES) $(XFT_MODULES) +moddefine = $(X_PREFIX) $(FT2_PREFIX) $(XFT_PREFIX) +moduledir = $(libdir)/pango/modules + +INCLUDES = \ + -DPANGO_ENABLE_ENGINE \ + -DG_DISABLE_DEPRECATED \ + -I$(top_srcdir) \ + -I$(top_srcdir)/pango/ \ + $(X_CFLAGS) \ + $(FREETYPE_CFLAGS) \ + $(moddefine) pango_hebrew_x_la_LDFLAGS = -export-dynamic -avoid-version -module pango_hebrew_x_la_LIBADD = $(hebrew_x_libadd) -pango_hebrew_x_la_SOURCES = $(sources) +pango_hebrew_x_la_SOURCES = $(hebrew_x_sources) +libpango_hebrew_x_la_SOURCES = $(hebrew_x_sources) + +pango_hebrew_xft_la_LDFLAGS = -export-dynamic -avoid-version -module +pango_hebrew_xft_la_LIBADD = $(hebrew_xft_libadd) +pango_hebrew_xft_la_SOURCES = $(hebrew_xft_sources) +libpango_hebrew_xft_la_SOURCES = $(hebrew_xft_sources) + +pango_hebrew_ft2_la_LDFLAGS = -export-dynamic -avoid-version -module $(no_undefined) +pango_hebrew_ft2_la_LIBADD = $(hebrew_ft2_libadd) +pango_hebrew_ft2_la_SOURCES = $(hebrew_ft2_sources) +libpango_hebrew_ft2_la_SOURCES = $(hebrew_ft2_sources) -libpango_hebrew_x_la_SOURCES = $(sources) included-modules: $(noinst_LTLIBRARIES) diff --git a/modules/hebrew/hebrew-x.c b/modules/hebrew/hebrew-x.c index 8f7697e4..14968c28 100644 --- a/modules/hebrew/hebrew-x.c +++ b/modules/hebrew/hebrew-x.c @@ -33,169 +33,14 @@ #include <string.h> #include "pangox.h" #include "pango-engine.h" +#include "hebrew-shaper.h" #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 MAX_GLYPHS 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_BET 0x05D1 -#define UNI_DALED 0x05D3 -#define UNI_KAF 0x05DB -#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_TAV 0x05EA -#define UNI_SHIN_DOT 0x05C1 -#define UNI_SIN_DOT 0x05C2 -#define UNI_MAPIQ 0x05BC -#define UNI_SHEVA 0x05B0 -#define UNI_QAMATS 0x05B8 -#define UNI_HOLAM 0x05B9 -#define UNI_QUBUTS 0x05BB - -#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)]]) - #define SCRIPT_ENGINE_NAME "HebrewScriptEngineX" +#define MAX_CLUSTER_CHRS 20 -/* We handle the range U+0591 to U+05f4 exactly - */ -static PangoEngineRange hebrew_ranges[] = { - { 0x0591, 0x05f4, "*" }, /* Hebrew */ -}; - -static PangoEngineInfo script_engines[] = { - { - SCRIPT_ENGINE_NAME, - PANGO_ENGINE_TYPE_SHAPE, - PANGO_RENDER_TYPE_X, - hebrew_ranges, G_N_ELEMENTS(hebrew_ranges) - } -}; - -/* - * X window system script engine portion - */ - -typedef struct _HebrewFontInfo HebrewFontInfo; - -/* The type of encoding that we will use - */ -typedef enum { - HEBREW_FONT_NONE, - HEBREW_FONT_ISO8859_8, - HEBREW_FONT_ISO10646, -} HebrewFontType; - -struct _HebrewFontInfo -{ - PangoFont *font; - HebrewFontType type; - PangoXSubfont subfont; -}; - -/*====================================================================== -// 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 }, -}; - -/* ISO 8859_8 Hebrew Font Layout. Does not include any accents. - */ static const gint iso_8859_8_shape_table[128] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -242,6 +87,42 @@ static const gint Unicode_shape_table[128] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }; +/* We handle the range U+0591 to U+05f4 exactly + */ +static PangoEngineRange hebrew_ranges[] = { + { 0x0591, 0x05f4, "*" }, /* Hebrew */ +}; + +static PangoEngineInfo script_engines[] = { + { + SCRIPT_ENGINE_NAME, + PANGO_ENGINE_TYPE_SHAPE, + PANGO_RENDER_TYPE_X, + hebrew_ranges, G_N_ELEMENTS(hebrew_ranges) + } +}; + +/* + * X window system script engine portion + */ + +typedef struct _HebrewFontInfo HebrewFontInfo; + +/* The type of encoding that we will use + */ +typedef enum { + HEBREW_FONT_NONE, + HEBREW_FONT_ISO8859_8, + HEBREW_FONT_ISO10646, +} HebrewFontType; + +struct _HebrewFontInfo +{ + PangoFont *font; + HebrewFontType type; + PangoXSubfont subfont; +}; + /* Returns a structure with information we will use to rendering given the * #PangoFont. This is computed once per font and cached for later retrieval. */ @@ -302,7 +183,6 @@ get_font_info (PangoFont *font) break; } } - g_free (subfont_ids); g_free (subfont_charsets); } @@ -315,9 +195,12 @@ add_glyph (HebrewFontInfo *font_info, PangoGlyphString *glyphs, gint cluster_start, PangoGlyph glyph, - gboolean is_combining) + gboolean is_combining, + gint width, + gint x_offset, + gint y_offset + ) { - PangoRectangle ink_rect, logical_rect; gint index = glyphs->num_glyphs; pango_glyph_string_set_size (glyphs, index + 1); @@ -327,347 +210,96 @@ add_glyph (HebrewFontInfo *font_info, glyphs->log_clusters[index] = cluster_start; - pango_font_get_glyph_extents (font_info->font, - glyphs->glyphs[index].glyph, &ink_rect, &logical_rect); + glyphs->glyphs[index].geometry.x_offset = x_offset; + glyphs->glyphs[index].geometry.y_offset = y_offset; + glyphs->glyphs[index].geometry.width = width; - if (is_combining) - { - if (font_info->type == HEBREW_FONT_ISO8859_8) - { - /* There are no accents in 8859_8 so this should never be - called... Therefore I have't even checked his. */ - glyphs->glyphs[index].geometry.width = - logical_rect.width + glyphs->glyphs[index - 1].geometry.width; - if (logical_rect.width > 0) - glyphs->glyphs[index].geometry.x_offset = glyphs->glyphs[index - 1].geometry.width; - else - glyphs->glyphs[index].geometry.x_offset = glyphs->glyphs[index].geometry.width; - glyphs->glyphs[index - 1].geometry.width = 0; - } - else - { - /* Unicode. Always make width of cluster according to the width - of the base character and never take the punctuation into - consideration. - */ - glyphs->glyphs[index].geometry.width = - MAX (logical_rect.width, glyphs->glyphs[index -1].geometry.width); - /* Dov's new logic... */ - glyphs->glyphs[index].geometry.width = glyphs->glyphs[index -1].geometry.width; - - glyphs->glyphs[index - 1].geometry.width = 0; - - /* Here we should put in heuristics to center nikud. */ - glyphs->glyphs[index].geometry.x_offset = 0; - } - } - else - { - glyphs->glyphs[index].geometry.x_offset = 0; - glyphs->glyphs[index].geometry.width = logical_rect.width; - } - - glyphs->glyphs[index].geometry.y_offset = 0; +#if 0 + { + PangoRectangle ink_rect, logical_rect; + + pango_font_get_glyph_extents (font_info->font, + glyphs->glyphs[index].glyph, &ink_rect, &logical_rect); + + printf("width logical_rect.width x_offset y_offset = %d %d %d %d\n", width, logical_rect.width, x_offset, y_offset); + glyphs->glyphs[index].geometry.x_offset = 0; + glyphs->glyphs[index].geometry.y_offset = 0; + glyphs->glyphs[index].geometry.width = width; + } +#endif } -static gint -get_adjusted_glyphs_list (HebrewFontInfo *font_info, - gunichar *cluster, - gint num_chrs, - PangoGlyph *glyph_lists, - const gint *shaping_table) +static PangoGlyph +get_glyph(HebrewFontInfo *font_info, + int glyph_num) { - gint i = 0; - - if ((num_chrs == 1) && - is_char_class (cluster[0], NonSpacingPunc)) - { - if (font_info->type == HEBREW_FONT_ISO8859_8) - { - glyph_lists[0] = PANGO_X_MAKE_GLYPH (font_info->subfont, 0x20); - glyph_lists[1] = PANGO_X_MAKE_GLYPH (font_info->subfont, - shaping_table[ucs2iso8859_8 (cluster[0])]); - return 2; - } - else - { - glyph_lists[0] = PANGO_X_MAKE_GLYPH (font_info->subfont, - shaping_table[ucs2iso8859_8 (cluster[0])]); - return 1; - } - } - else - { - while (i < num_chrs) { - glyph_lists[i] = PANGO_X_MAKE_GLYPH (font_info->subfont, - shaping_table[ucs2iso8859_8 (cluster[i])]); - i++; - } - return num_chrs; - } + return PANGO_X_MAKE_GLYPH (font_info->subfont, glyph_num); } -static gint -get_glyphs_list (HebrewFontInfo *font_info, - gunichar *cluster, - gint num_chrs, - PangoGlyph *glyph_lists) +static void +add_cluster(HebrewFontInfo *font_info, + PangoFont *font, + PangoGlyphString *glyphs, + int cluster_size, + int cluster_start, + int glyph_num[], + PangoGlyph glyph[], + int width[], + int x_offset[], + int y_offset[]) { - gint i; + int i; - switch (font_info->type) + for (i=0; i<cluster_size; i++) { - case HEBREW_FONT_NONE: - for (i=0; i < num_chrs; i++) - glyph_lists[i] = pango_x_get_unknown_glyph (font_info->font); - return num_chrs; - - case HEBREW_FONT_ISO8859_8: - return get_adjusted_glyphs_list (font_info, cluster, - num_chrs, glyph_lists, iso_8859_8_shape_table); - - case HEBREW_FONT_ISO10646: - return get_adjusted_glyphs_list (font_info, cluster, - num_chrs, glyph_lists, Unicode_shape_table); + add_glyph (font_info, glyphs, cluster_start, glyph[i], + i == 0 ? FALSE : TRUE, width[i], x_offset[i], y_offset[i]); } - return 0; } -static void -add_cluster (HebrewFontInfo *font_info, - PangoGlyphString *glyphs, - gint cluster_start, - gunichar *cluster, - gint num_chrs) - +gint get_glyph_num(HebrewFontInfo *font_info, + PangoFont *font, + gunichar uch) { - PangoGlyph glyphs_list[MAX_GLYPHS]; - gint num_glyphs; - gint i; - - num_glyphs = get_glyphs_list(font_info, cluster, num_chrs, glyphs_list); - - for (i=0; i<num_glyphs; i++) - add_glyph (font_info, glyphs, cluster_start, glyphs_list[i], - i == 0 ? FALSE : TRUE); - - /* Here the fun starts. Post process the positions of glyphs in the - cluster in order to make nikud look nice... The following is based - on lots of heuristic rules and could probably be improved. Especially - we could improve things considerably if we would access the rendered - bitmap and move nikud to avoid collisions etc. - - Todo: - - * Take care of several points and accents below the characters. - - * Figure out what to do with dot inside vav if it the vav does - not have a "roof". (Happens e.g. in Ariel). - */ - if (num_glyphs > 1) + if (font_info->type == HEBREW_FONT_ISO8859_8) { - int i; - int cluster_start_idx = glyphs->num_glyphs - num_glyphs; - - if (font_info->type == HEBREW_FONT_ISO10646) - { - PangoRectangle ink_rect, logical_rect; - int base_char = glyphs_list[0] & 0x0fff; - int base_ink_x_offset; - int base_ink_width, base_ink_height; - - pango_font_get_glyph_extents (font_info->font, - glyphs->glyphs[cluster_start_idx].glyph, &ink_rect, &logical_rect); - base_ink_x_offset = ink_rect.x; - base_ink_width = ink_rect.width; - base_ink_height = ink_rect.height; - - for (i=1; i<num_glyphs; i++) - { - int gl = glyphs_list[i] & 0x0fff; - - /* Check if it is a point */ - if (gl < 0x5B0 || gl >= 0x05D0) - continue; - - pango_font_get_glyph_extents (font_info->font, - glyphs->glyphs[cluster_start_idx+i].glyph, &ink_rect, &logical_rect); - - /* The list of logical rules */ - - /* Center dot of VAV */ - if (gl == UNI_MAPIQ && base_char == UNI_VAV) - { - glyphs->glyphs[cluster_start_idx+i].geometry.x_offset - = base_ink_x_offset - ink_rect.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; - - for (j=0; j<i; j++) - { - glyphs->glyphs[cluster_start_idx+j].geometry.x_offset - += ink_rect.width*(1+space-kern); - } - - glyphs->glyphs[cluster_start_idx+i].geometry.width - += ink_rect.width*(1+space-kern); - glyphs->glyphs[cluster_start_idx+i].geometry.x_offset - -= ink_rect.width*(kern); - } - } - - /* Dot over SHIN */ - else if (gl == UNI_SHIN_DOT && base_char == UNI_SHIN) - { - glyphs->glyphs[cluster_start_idx+i].geometry.x_offset - = base_ink_x_offset + base_ink_width - - ink_rect.x - ink_rect.width; - } - - /* Dot over SIN */ - else if (gl == UNI_SIN_DOT && base_char == UNI_SHIN) - { - glyphs->glyphs[cluster_start_idx+i].geometry.x_offset - = base_ink_x_offset -ink_rect.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) - { - glyphs->glyphs[cluster_start_idx+i].geometry.x_offset - = base_ink_x_offset -ink_rect.x - 2*ink_rect.width; - } - - /* VOWELS under resh or vav are right aligned */ - else if ((base_char == UNI_VAV || base_char == UNI_RESH - || base_char == UNI_YOD) - && ((gl >= UNI_SHEVA && gl <= UNI_QAMATS) || - gl == UNI_QUBUTS)) - { - glyphs->glyphs[cluster_start_idx+i].geometry.x_offset - = base_ink_x_offset + base_ink_width - - ink_rect.x - ink_rect.width; - } - - /* MAPIQ in PE or FINAL PE */ - else if (gl == UNI_MAPIQ - && (base_char == UNI_PE || base_char == UNI_FINAL_PE)) - { - glyphs->glyphs[cluster_start_idx+i].geometry.x_offset - = base_ink_x_offset - ink_rect.x - + base_ink_width * 2/3 - ink_rect.width/2; - - /* Another option is to offset the MAPIQ in y... - glyphs->glyphs[cluster_start_idx+i].geometry.y_offset - -= base_ink_height/5; */ - } - - /* VOWEL DOT next to any other character */ - else if ((gl == UNI_SIN_DOT || gl == UNI_HOLAM) - && (base_char != UNI_VAV)) - { - glyphs->glyphs[cluster_start_idx+i].geometry.x_offset - = base_ink_x_offset -ink_rect.x; - } - - /* Move nikud of taf a bit ... */ - else if (base_char == UNI_TAV) - { - glyphs->glyphs[cluster_start_idx+i].geometry.x_offset - = base_ink_x_offset - ink_rect.x - + base_ink_width * 5/8 - ink_rect.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 - )) - { - glyphs->glyphs[cluster_start_idx+i].geometry.x_offset - = base_ink_x_offset - ink_rect.x - + base_ink_width * 3/8 - ink_rect.width/2; - } - - /* Center by default */ - else - { - glyphs->glyphs[cluster_start_idx+i].geometry.x_offset - = base_ink_x_offset - ink_rect.x - + base_ink_width/2 - ink_rect.width/2; - } - } - } + return iso_8859_8_shape_table[ucs2iso8859_8(uch)]; } -} - -static const char * -get_next_cluster(const char *text, - gint length, - gunichar *cluster, - gint *num_chrs) -{ - const char *p; - gint n_chars = 0; - - p = text; - /* What is the maximum size of a Hebrew cluster? It is certainly - bigger than two characters... */ - while (p < text + length && n_chars < MAX_CLUSTER_CHRS) + else { - gunichar current = g_utf8_get_char (p); - - if (n_chars == 0 || - is_composible ((gunichar)(cluster[0]), current) ) - { - cluster[n_chars++] = current; - p = g_utf8_next_char (p); - if (n_chars == 1 && - is_char_class(cluster[0], ~(NoDefine|SpacingLetter)) ) - break; - } - else - break; + return Unicode_shape_table[ucs2iso8859_8(uch)]; } - - *num_chrs = n_chars; - return p; } static void -swap_range (PangoGlyphString *glyphs, int start, int end) +get_cluster_glyphs(HebrewFontInfo *font_info, + PangoFont *font, + gunichar cluster[], + gint cluster_size, + /* output */ + gint glyph_num[], + PangoGlyph glyph[], + gint widths[], + PangoRectangle ink_rects[]) { - int i, j; - - for (i = start, j = end - 1; i < j; i++, j--) + int i; + for (i=0; i<cluster_size; i++) { - PangoGlyphInfo glyph_info; - gint log_cluster; - - glyph_info = glyphs->glyphs[i]; - glyphs->glyphs[i] = glyphs->glyphs[j]; - glyphs->glyphs[j] = glyph_info; + PangoRectangle logical_rect; + glyph_num[i] = get_glyph_num(font_info, font, cluster[i]); + glyph[i] = get_glyph(font_info, glyph_num[i]); - log_cluster = glyphs->log_clusters[i]; - glyphs->log_clusters[i] = glyphs->log_clusters[j]; - glyphs->log_clusters[j] = log_cluster; + pango_font_get_glyph_extents (font_info->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; } } @@ -682,7 +314,11 @@ hebrew_engine_shape (PangoFont *font, const char *p; const char *log_cluster; gunichar cluster[MAX_CLUSTER_CHRS]; - gint num_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); @@ -692,31 +328,58 @@ hebrew_engine_shape (PangoFont *font, while (p < text + length) { log_cluster = p; - p = get_next_cluster (p, text + length - p, cluster, &num_chrs); - add_cluster (font_info, glyphs, log_cluster - text, cluster, num_chrs); + p = hebrew_shaper_get_next_cluster (p, text + length - p, + /* output */ + cluster, &cluster_size); + get_cluster_glyphs(font_info, + font, + cluster, + cluster_size, + /* output */ + glyph_num, + glyph, + glyph_width, + ink_rects); +#if 0 + { + int i; + for (i=0; i< cluster_size; i++) + { + printf("cluster %d: U+%04x %d\n", i, glyph_num[i], glyph_width[i]); + } + } +#endif + + /* Kern the glyphs! */ + hebrew_shaper_get_cluster_kerning(cluster, + cluster_size, + /* Input and output */ + ink_rects, + glyph_width, + /* output */ + x_offset, + y_offset); + + +#if 0 + old_add_cluster (font_info, glyphs, log_cluster - text, cluster, cluster_size); +#endif + add_cluster(font_info, + font, + glyphs, + cluster_size, + log_cluster - text, + glyph_num, + glyph, + glyph_width, + x_offset, + y_offset); + } /* Simple bidi support */ if (analysis->level % 2) - { - int start, end; - - /* Swap all glyphs */ - 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++; - - if (end > start + 1) - swap_range (glyphs, start, end); - start = end; - } - } + hebrew_shaper_bidi_reorder(glyphs); } static PangoCoverage * |