Patches for Indic OT



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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]