Here are my patches for adding Indic OT support. A few notes:* This includes a slightly modified version of Elliot Lee's patches to add GPOS support, which doesn't seem to work correctly.
* The patches include some debugging printf's.* I've patched modules/arabic/arabic-ft2.c so that it compiles, but it probably won't work correctly.
* This includes four new modules, which I've included in a separate tarball (they go in modules/indic)
* Because the GPOS stuff isn't working, GPOS tagging is #if 0'd out.* Post-GSUB fixup of left matras for Tamil and Malayalam isn't implemented because there was no obvious way to port that code from ICU.
Eric Mader IBM GCoC - San José 5600 Cottle Rd. MS 502/B11 San Jose, CA 95193
? docs/pango-symbols.txt ? modules/indic/indic-ot.c ? modules/indic/indic-ot-class-tables.c ? modules/indic/indic-ot.h ? modules/indic/indic-xft.c cvs server: Diffing . Index: ChangeLog =================================================================== RCS file: /cvs/gnome/pango/ChangeLog,v retrieving revision 1.447 diff -r1.447 ChangeLog 0a1,14 > Tue Feb 19 10:07:52 2002 Eric Mader <mader jtcsv com> > * configure.in: Add module indic-xft > > * modules/indic/Makefile.am: changes for indic-xft module > > * modules/indic/indic-ot.h, modules/indic/indic-ot.c, > * modules/indic/indic-ot-class-tables.c, modules/indic/indic-xft.c: new files > > * modules/arabic/arabic-xft.c (arabic-engine-shape): comment out num_glyphs == n_chars > assertion (need a real solution for this!) > > * modules/arabic/arabic-ft2.c (arabic-engine-shape): added font argument to > pang_ot_ruleset_shape call. This makes it compile, but it's probably still broken... > 370a385,391 > > 2001-12-01 Elliot Lee <sopwith redhat com> > > * pango/opentype/pango-ot-ruleset.c, pango/pango-ot.h (pango_ot_ruleset_shape): > Function now attempts to do glyph positioning. Handle OpenType GPOS tables for layout, > or fall back to a basic routine if not. > * modules/arabic/arabic-xft.c: Use above API, and handle non-spacing marks. Index: configure.in =================================================================== RCS file: /cvs/gnome/pango/configure.in,v retrieving revision 1.95 diff -r1.95 configure.in 277c277 < indic_modules="bengali-x,devanagari-x,gurmukhi-x,gujarati-x,myanmar-x" --- > indic_modules="bengali-x,devanagari-x,gurmukhi-x,gujarati-x,myanmar-x,indic-xft" 347a348 > AM_CONDITIONAL(INCLUDE_INDIC_XFT,echo $included_modules | grep '\(^\|,\)indic-xft\($\|,\)' > /dev/null) cvs server: Diffing docs cvs server: Diffing docs/TEXT cvs server: Diffing docs/tmpl Index: docs/tmpl/opentype.sgml =================================================================== RCS file: /cvs/gnome/pango/docs/tmpl/opentype.sgml,v retrieving revision 1.4 diff -r1.4 opentype.sgml 152a153 > @font: cvs server: Diffing examples cvs server: Diffing modules cvs server: Diffing modules/arabic Index: modules/arabic/arabic-ft2.c =================================================================== RCS file: /cvs/gnome/pango/modules/arabic/arabic-ft2.c,v retrieving revision 1.1 diff -r1.1 arabic-ft2.c 300c300 < pango_ot_ruleset_shape (ruleset, glyphs, properties); --- > pango_ot_ruleset_shape (ruleset, font, glyphs, properties); Index: modules/arabic/arabic-xft.c =================================================================== RCS file: /cvs/gnome/pango/modules/arabic/arabic-xft.c,v retrieving revision 1.6 diff -r1.6 arabic-xft.c 143,146c143,146 < const char *text, < gint length, < PangoAnalysis *analysis, < PangoGlyphString *glyphs) --- > const char *text, > gint length, > PangoAnalysis *analysis, > PangoGlyphString *glyphs) 149c149 < int i; --- > int i, prev_i; 167a168,169 > > wcs = g_utf8_to_ucs4_fast (text, length, NULL); 170d171 < wcs = g_utf8_to_ucs4_fast (text, length, NULL); 250,260c251,253 < ruleset = get_ruleset (font); < < if (ruleset) < { < pango_ot_ruleset_shape (ruleset, glyphs, properties); < < g_free (wcs); < g_free (properties); < < } < --- > pango_ot_ruleset_shape (ruleset, font, glyphs, properties); > /* g_assert(glyphs->num_glyphs == n_chars);*/ > prev_i = -1; 262a256 > int x = 0; 264c258 < if (glyphs->glyphs[i].glyph) --- > if (g_unichar_type(wcs[i]) != G_UNICODE_NON_SPACING_MARK) 266,269c260,273 < PangoRectangle logical_rect; < < pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, NULL, &logical_rect); < glyphs->glyphs[i].geometry.width = logical_rect.width; --- > prev_i = i; /* Need to know what the last 'normal' character was, in case of multiple marks */ > } > else if (glyphs->glyphs[i].geometry.width && prev_i >= 0) > { > glyphs->glyphs[i].geometry.x_offset -= glyphs->glyphs[prev_i].geometry.width; /* Position the mark over the tail of the > previous 'normal' character... */ > x = glyphs->glyphs[prev_i].geometry.width - glyphs->glyphs[i].geometry.width; > if (x > 0) > /* ... then if it is shorter than the previous char, back > the mark up so it is centered over the last quarter of the > previous glyph. Or something. */ > glyphs->glyphs[i].geometry.x_offset += x / 4; > > glyphs->glyphs[i].geometry.width = 0; 271,275d274 < else < glyphs->glyphs[i].geometry.width = 0; < < glyphs->glyphs[i].geometry.x_offset = 0; < glyphs->glyphs[i].geometry.y_offset = 0; 276a276,278 > > g_free (wcs); > g_free (properties); cvs server: Diffing modules/basic cvs server: Diffing modules/hangul cvs server: Diffing modules/hebrew cvs server: Diffing modules/indic Index: modules/indic/Makefile.am =================================================================== RCS file: /cvs/gnome/pango/modules/indic/Makefile.am,v retrieving revision 1.9 diff -r1.9 Makefile.am 10a11,16 > xft_sources = \ > indic-xft.c \ > indic-ot-class-tables.c \ > indic-ot.c \ > indic-ot.h > 15a22,38 > if HAVE_XFT > if INCLUDE_INDIC_XFT > XFT_MODULES= > XFT_INCLUDED=libpango-indic-xft.la > XFT_PREFIX=-DXFT_MODULE_PREFIX > else > XFT_MODULES=pango-indic-xft.la > XFT_INCLUDED= > XFT_PREFIX= > indic_xft_libadd=$(pangoxftlibs) > endif > else > XFT_MODULES= > XFT_INCLUDED= > XFT_PREFIX= > endif > 58c81 < noinst_LTLIBRARIES = $(myanmar_x_noinst) $(gurmukhi_x_noinst) $(bengali_x_noinst) $(devanagari_x_noinst) $(gujarati_x_noinst) --- > noinst_LTLIBRARIES = $(myanmar_x_noinst) $(gurmukhi_x_noinst) $(bengali_x_noinst) $(devanagari_x_noinst) $(gujarati_x_noinst) $(XFT_INCLUDED) 61c84 < module_LTLIBRARIES = $(myanmar_x_inst) $(gurmukhi_x_inst) $(bengali_x_inst) $(devanagari_x_inst) $(gujarati_x_inst) --- > module_LTLIBRARIES = $(myanmar_x_inst) $(gurmukhi_x_inst) $(bengali_x_inst) $(devanagari_x_inst) $(gujarati_x_inst) $(XFT_MODULES) 65c88 < INCLUDES = -DPANGO_ENABLE_ENGINE -DG_DISABLE_DEPRECATED -I$(top_srcdir) -I$(top_srcdir)/pango/ $(X_CFLAGS) $(myanmar_x_cflags) $(gurmukhi_x_cflags) $(bengali_x_cflags) $(devanagari_x_cflags) $(gujarati_x_cflags) --- > INCLUDES = -DPANGO_ENABLE_ENGINE -DG_DISABLE_DEPRECATED -I$(top_srcdir) -I$(top_srcdir)/pango/ $(X_CFLAGS) $(myanmar_x_cflags) $(gurmukhi_x_cflags) $(bengali_x_cflags) $(devanagari_x_cflags) $(gujarati_x_cflags) $(FREETYPE_CFLAGS) 108a132,137 > > pango_indic_xft_la_LDFLAGS = -export-dynamic -avoid-version -module > pango_indic_xft_la_LIBADD = $(indic_xft_libadd) > pango_indic_xft_la_SOURCES = $(xft_sources) > > libpango_indic_xft_la_SOURCES = $(xft_sources) cvs server: Diffing modules/tamil cvs server: Diffing modules/thai cvs server: Diffing pango Index: pango/pango-ot.h =================================================================== RCS file: /cvs/gnome/pango/pango/pango-ot.h,v retrieving revision 1.3 diff -r1.3 pango-ot.h 80a81 > PangoFont *font, cvs server: Diffing pango/mini-fribidi cvs server: Diffing pango/mini-xft cvs server: Diffing pango/opentype Index: pango/opentype/ftxgpos.c =================================================================== RCS file: /cvs/gnome/pango/pango/opentype/ftxgpos.c,v retrieving revision 1.3 diff -r1.3 ftxgpos.c 36a37,38 > #include <stdio.h> > 805a808 > printf("Load_Anchor: an->PosFormat = %d?\n", an->PosFormat); 1084a1088 > printf("Load_SinglePos: sp->PosFormat = %d?\n", sp->PosFormat); 1562a1567 > printf("Load_PairPos: pp->PosFormat = %d?\n", pp->PosFormat); 1732a1738 > printf("Lookup_PairPos: pp->PosFormat = %d?\n", pp->PosFormat); 3858a3865 > printf("Load_ContextPos: cp->PosFormat = %d?\n", cp->PosFormat); 4144a4152 > printf("Lookup_ContextPos: cp->PosFormat = %d?\n", cp->PosFormat); 5115a5124 > printf("Load_ChainContextPos: ccp->PosFormat = %d?\n", ccp->PosFormat); 5650a5660 > printf("Lookup_ChainContextPos: ccp->PosFormat = %d?\n", ccp->PosFormat); 5786c5796,5799 < return TTO_Err_Invalid_GPOS_SubTable_Format; --- > { > printf("TT_GPOS_Select_Feature: fi[n] = %d, FeatureCount = %d?\n", fi[n], fl->FeatureCount); > return TTO_Err_Invalid_GPOS_SubTable_Format; > } 5934a5948 > printf("TT_GPOS_Query_Features: fi[n] = %d, FeatureCount = %d?\n", fi[n], fl->FeatureCount); Index: pango/opentype/ftxgsub.c =================================================================== RCS file: /cvs/gnome/pango/pango/opentype/ftxgsub.c,v retrieving revision 1.2 diff -r1.2 ftxgsub.c 36a37,38 > #include <stdio.h> > 273a276,277 > > printf("TT_Load_GSUB_Table: Hello!\n"); Index: pango/opentype/ftxopen.c =================================================================== RCS file: /cvs/gnome/pango/pango/opentype/ftxopen.c,v retrieving revision 1.3 diff -r1.3 ftxopen.c 26a27,28 > #include <stdio.h> > 132a135 > printf("LangSysCount == 0 && DefaultLangSys.FeatureCount == 0!\n"); 457c460 < #if 0 --- > #if 1 828a832 > printf("coverage format 2: start > end || range >= 0x10000L\n"); 871a876 > printf("coverage format %d?\n", c->CoverageFormat); 1001a1007 > printf("Coverage_Index: coverage format %d?\n", c->CoverageFormat); 1045c1051,1054 < return TTO_Err_Invalid_SubTable; --- > { > printf("convrage format 1: count >= 0x10000L\n"); > return TTO_Err_Invalid_SubTable; > } 1062a1072 > printf("cva[n] >= limit\n"); 1134a1145,1147 > printf("crr[n].Start >= crr[n].End || crr[n].Class >= limit\n"); > printf("n = %d, Start = %4.4X, End = %4.4X, Class = %d, limit = %d, pos = %8.8X\n", n, crr[n].Start, crr[n].End, crr[n].Class, limit, stream->pos); > #if 0 1136a1150,1156 > #else > if (crr[n].Start > crr[n].End) > crr[n].End = crr[n].Start; > > if (crr[n].Class >= limit) > crr[n].Class = limit - 1; > #endif 1189a1210 > printf("Class format %d?\n", cd->ClassFormat); 1329a1351 > printf("Get_Class: class format %d?\n", cd->ClassFormat); 1365c1387,1390 < return TTO_Err_Invalid_SubTable; --- > { > printf("StartSize > EndSize || DeltaFormat == 0 || DeltaFormat > 3\n"); > return TTO_Err_Invalid_SubTable; > } Index: pango/opentype/pango-ot-ruleset.c =================================================================== RCS file: /cvs/gnome/pango/pango/opentype/pango-ot-ruleset.c,v retrieving revision 1.3 diff -r1.3 pango-ot-ruleset.c 23a24,26 > #include <pango/pango-font.h> > #include <pango/pango-utils.h> > #include <pango/pangoft2.h> 26a30,40 > #include <pango/pangoxft.h> > > #ifndef PANGO_UNITS_26_6 > #define PANGO_SCALE_26_6 (PANGO_SCALE / (1<<6)) > #define PANGO_PIXELS_26_6(d) \ > (((d) >= 0) ? \ > ((d) + PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6 : \ > ((d) - PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6) > #define PANGO_UNITS_26_6(d) (PANGO_SCALE_26_6 * (d)) > #endif > 139,152c153,158 < /** < * pango_ot_ruleset_shape: < * @ruleset: a #PangoOTRuleset. < * @glyphs: a pointer to a #PangoGlyphString. < * @properties: an array containing one #gulong bitfield for each glyph, < * which gives the glyph's properties: If a certain bit is set for a glyph, < * the feature which has the same bit set in its property value is applied. < * < * Shapes a string of glyphs with the given properties according to @ruleset. < **/ < void < pango_ot_ruleset_shape (PangoOTRuleset *ruleset, < PangoGlyphString *glyphs, < gulong *properties) --- > /* Returns true if the GPOS table was found to allow positioning the glyphs */ > static gboolean > pango_ot_ruleset_shape_internal(PangoOTRuleset *ruleset, > PangoFont *font, > PangoGlyphString *glyphs, > gulong *properties) 165c171 < gboolean need_gpos = FALSE; --- > gboolean need_gpos = FALSE, did_gpos = FALSE; 167c173 < g_return_if_fail (PANGO_OT_IS_RULESET (ruleset)); --- > g_return_val_if_fail (PANGO_OT_IS_RULESET (ruleset), FALSE); 212c218 < return; --- > return FALSE; 236c242,273 < --- > > if (gpos && font) > { > TTO_GPOS_Data *outgpos = NULL; > > if (!TT_GPOS_Apply_String (pango_xft_font_get_face(font), gpos, 0, result_string, &outgpos, > FALSE /* enable device-dependant values */, > FALSE /* Even though this might be r2l text, RTL is handled elsewhere afaik */)) > { > > for (i = 0; i < result_string->length; i++) > { > int j; > glyphs->glyphs[i].geometry.x_offset = PANGO_UNITS_26_6(outgpos[i].x_pos); > glyphs->glyphs[i].geometry.y_offset = PANGO_UNITS_26_6(outgpos[i].y_pos); > > for(j = 0; j < outgpos[i].back; j++) > glyphs->glyphs[i].geometry.x_offset -= glyphs->glyphs[i-j].geometry.width; > > if (outgpos[i].new_advance) > /* Can't set new x offset for marks, so just make sure not to increase it. > Can do better than this by playing with ->x_offset. */ > glyphs->glyphs[i].geometry.width = 0; > else > glyphs->glyphs[i].geometry.width = PANGO_UNITS_26_6(outgpos[i].x_advance); > } > > FT_Free(gpos->memory, (void *)outgpos); > did_gpos = TRUE; > } > } > 257a295,340 > > return did_gpos; > } > > /** > * pango_ot_ruleset_shape: > * @ruleset: a #PangoOTRuleset. > * @glyphs: a pointer to a #PangoGlyphString. > * @properties: an array containing one #gulong bitfield for each glyph, > * which gives the glyph's properties: If a certain bit is set for a glyph, > * the feature which has the same bit set in its property value is applied. > * > * Shapes a string of glyphs with the given properties according to @ruleset. > **/ > void > pango_ot_ruleset_shape (PangoOTRuleset *ruleset, > PangoFont *font, > PangoGlyphString *glyphs, > gulong *properties) > { > int i; > > if(pango_ot_ruleset_shape_internal(ruleset, font, glyphs, properties)) > return; > > if(!font) > return; > > g_return_if_fail (PANGO_IS_FONT (font)); > > /* Fall back to some basic shaping */ > for (i = 0; i < glyphs->num_glyphs; i++) > { > if (glyphs->glyphs[i].glyph) > { > PangoRectangle logical_rect; > > pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, NULL, &logical_rect); > glyphs->glyphs[i].geometry.width = logical_rect.width; > } > else > glyphs->glyphs[i].geometry.width = 0; > > glyphs->glyphs[i].geometry.x_offset = 0; > glyphs->glyphs[i].geometry.y_offset = 0; > } cvs server: Diffing tests cvs server: Diffing tools cvs server: Diffing tools/maps
Attachment:
indic.tar.gz
Description: Binary data