OpenType Patches



Hello,

I've been chasing an obscure bug having to do with accent positioning in OpenType fonts. The symptom is that sometimes, accents are positioned too far to left. After chasing my tail for quite a while, I've narrowed this bug down to the fact that the face the indic-ot shaper passes to the OpenType routines has face->size.metrics.x_scale == 0. (actually everything in the metrics record is zero) This causes the OT code which returns anchor points to return them all as zero 'cause it multiplies to co-ordinates by x_scale. My shaper gets the face like this:

    face = pango_xft_font_lock_face (font);

So I assume that the problem is somewhere in pango_xft_font_lock_face... does anybody have any idea where I should start looking?

In the process of tracking this bug, I fixed some things that I knew were wrong with the GPOS positioning code. I'm pretty sure that what I did is better than what was there before, but I'd appreciate some other eyes looking at the changes - especially since it took me almost a full day to get them to where they seem to work ;-)

Anyhow, I've attached all the patches I've made to pango/pango/opentype. This includes the final version of my infamous LangSys patch.

Regards,
Eric
? opentype.patch
Index: ftxopen.c
===================================================================
RCS file: /cvs/gnome/pango/pango/opentype/ftxopen.c,v
retrieving revision 1.6
diff -u -p -r1.6 ftxopen.c
--- ftxopen.c	7 Aug 2002 17:01:52 -0000	1.6
+++ ftxopen.c	31 Aug 2002 01:51:17 -0000
@@ -130,7 +130,7 @@
 
     if ( s->LangSysCount == 0 && s->DefaultLangSys.FeatureCount == 0 )
     {
-      error = TTO_Err_Invalid_SubTable;
+      error = TTO_Err_Empty_Script;
       goto Fail2;
     }
 
@@ -205,7 +205,7 @@
     FT_Error   error;
     FT_Memory  memory = stream->memory;
 
-    FT_UShort          n, m, count;
+    FT_UShort          n, script_count;
     FT_ULong           cur_offset, new_offset, base_offset;
 
     TTO_ScriptRecord*  sr;
@@ -216,39 +216,53 @@
     if ( ACCESS_Frame( 2L ) )
       return error;
 
-    count = sl->ScriptCount = GET_UShort();
+    script_count = GET_UShort();
 
     FORGET_Frame();
 
     sl->ScriptRecord = NULL;
 
-    if ( ALLOC_ARRAY( sl->ScriptRecord, count, TTO_ScriptRecord ) )
+    if ( ALLOC_ARRAY( sl->ScriptRecord, script_count, TTO_ScriptRecord ) )
       return error;
 
     sr = sl->ScriptRecord;
 
-    for ( n = 0; n < count; n++ )
+    sl->ScriptCount= 0;
+    for ( n = 0; n < script_count; n++ )
     {
       if ( ACCESS_Frame( 6L ) )
         goto Fail;
 
-      sr[n].ScriptTag = GET_ULong();
+      sr[sl->ScriptCount].ScriptTag = GET_ULong();
       new_offset = GET_UShort() + base_offset;
 
       FORGET_Frame();
 
       cur_offset = FILE_Pos();
-      if ( FILE_Seek( new_offset ) ||
-           ( error = Load_Script( &sr[n].Script, stream ) ) != TT_Err_Ok )
-        goto Fail;
+
+      if ( FILE_Seek( new_offset ) )
+	goto Fail;
+
+      error = Load_Script( &sr[sl->ScriptCount].Script, stream );
+      if ( error == TT_Err_Ok )
+	sl->ScriptCount += 1;
+      else if ( error != TTO_Err_Empty_Script )
+	goto Fail;
+
       (void)FILE_Seek( cur_offset );
     }
 
+    if ( sl->ScriptCount == 0 )
+    {
+      error = TTO_Err_Invalid_SubTable;
+      goto Fail;
+    }
+    
     return TT_Err_Ok;
 
   Fail:
-    for ( m = 0; m < n; m++ )
-      Free_Script( &sr[m].Script, memory );
+    for ( n = 0; n < sl->ScriptCount; n++ )
+      Free_Script( &sr[n].Script, memory );
 
     FREE( sl->ScriptRecord );
     return error;
Index: ftxopen.h
===================================================================
RCS file: /cvs/gnome/pango/pango/opentype/ftxopen.h,v
retrieving revision 1.1
diff -u -p -r1.1 ftxopen.h
--- ftxopen.h	20 Dec 2000 04:41:36 -0000	1.1
+++ ftxopen.h	31 Aug 2002 01:51:17 -0000
@@ -38,6 +38,7 @@ extern "C" {
 #define TTO_Err_Not_Covered               0x1002
 #define TTO_Err_Too_Many_Nested_Contexts  0x1003
 #define TTO_Err_No_MM_Interpreter         0x1004
+#define TTO_Err_Empty_Script              0x1005
 
 
   /* Script list related structures */
Index: pango-ot-ruleset.c
===================================================================
RCS file: /cvs/gnome/pango/pango/opentype/pango-ot-ruleset.c,v
retrieving revision 1.4
diff -u -p -r1.4 pango-ot-ruleset.c
--- pango-ot-ruleset.c	7 May 2002 20:38:50 -0000	1.4
+++ pango-ot-ruleset.c	31 Aug 2002 01:51:17 -0000
@@ -247,18 +247,25 @@ pango_ot_ruleset_shape (PangoOTRuleset  
 	{
 	  for (i = 0; i < result_string->length; i++)
 	    {
-	      int j;
+	      FT_Pos x_pos = outgpos[i].x_pos, y_pos = outgpos[i].y_pos;
+	      PangoGlyphUnit x_adj = 0;
+	      int back = i;
 
-	      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);
+	      while (outgpos[back].back != 0)
+		{
+		  back  -= outgpos[back].back;
+		  x_pos += outgpos[back].x_pos;
+		  y_pos += outgpos[back].y_pos;
+		  x_adj += glyphs->glyphs[back].geometry.width;
+		}
+
+	      glyphs->glyphs[i].geometry.x_offset += PANGO_UNITS_26_6(x_pos) - x_adj;
+	      glyphs->glyphs[i].geometry.y_offset += PANGO_UNITS_26_6(y_pos);
 
-	      for (j = i - outgpos[i].back; j < i; j++)
-		glyphs->glyphs[i].geometry.x_offset -= glyphs->glyphs[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;
+		glyphs->glyphs[i].geometry.width  = PANGO_UNITS_26_6(outgpos[i].x_advance);
 	      else
 		glyphs->glyphs[i].geometry.width += PANGO_UNITS_26_6(outgpos[i].x_advance);
 	    }


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