Re: Problems w/ Mangal?



Eric Mader <mader jtcsv com> writes:

> I've got my indic-xft shaper limping along. It seems to shape well,
> but when I display Hindi text using an IBM Devanagari font
> ("Devanagari MT for IBM" - built for IBM's JDK) the text display looks
> pretty bad. In particular, the placement of the long-I matra looks way
> off. (And there's no hinting; TrueType Devanagari fonts tend to look
> pretty bad w/o hinting...)

Unfortunately, that is a problem we can't solve within the scope 
of Pango since it's a legal one not a technical one.
(http://www.freetype.org/patents.html)

Its a reasonably simple matter to recompile FreeType with hinting on.

There have been some improvements in the FreeType autohinter recently
since the version shipped in Red Hat 7.2, but I suspect they probably
won't help much here since the autohinter is really tuned for
roman type. 

> In an attempt to see if this was a font problem (though the font
> *does* display correctly on Windoze ;-) I tried using Mangal
> instead. With Mangal, I get this error: "Error loading GSUB table
> 4097" (TTO_Err_Invalid_SubTable)
> 
> I've narrowed the error down to a bad ClassRangeRecord in
> Load_ClassDef2 in ftxopen.c. I've tried dumping the GSUB table using
> the tools on Windows, and I don't see the error that this code is
> reporting - I suspect that ftxopen is getting lost somehow and isn't
> really reading what it thinks it is...
> 
> Has anyone else seem this kind of a problem with Mangal?

Without any shapers that could use Mangal, probably not. :-)

And if there is is any portion of the code I'd expect to have
bugs when not thoroughly tested, it would be the handling of
'GSUB Chaining Context Substitution Format 2: Class-based Chaining 
Context Glyph Substitution', which is just about as complex
as OpenType gets. (And that's saying a lot...) :-(

Looking into this a little bit, I _think_ what is going on is that
pango/opentype/ftxgsub.c:Load_ChainContextSubst2() is not handling
that if lookahead_offset (and presumably the other similar offsets)
are 0, then the class is empty. I can't find any reference to that in
the docs for this particular table, but it seems to be a common
convention in the OpenType format and would make sense with the
values in mangal.ttf.

I tried fixing that, but then it died a bit later. It might be
useful to have the dump of the font when debugging this; otherwise,
it's probably just a lot of staring at the code. The diff I was
working with is attached ... most of it is just freeing some problems with
memory cleanup on error.

Regards,
                                        Owen

Index: ftxgsub.c
===================================================================
RCS file: /cvs/gnome/pango/pango/opentype/ftxgsub.c,v
retrieving revision 1.2
diff -u -p -r1.2 ftxgsub.c
--- ftxgsub.c	2001/09/19 21:20:36	1.2
+++ ftxgsub.c	2002/01/31 23:10:28
@@ -827,7 +827,7 @@
     FT_Error error;
     FT_Memory memory = stream->memory;
 
-    FT_UShort          n, count;
+    FT_UShort          n = 0, m, count;
     FT_ULong           cur_offset, new_offset, base_offset;
 
     TTO_AlternateSet*  aset;
@@ -882,8 +882,8 @@
     return TT_Err_Ok;
 
   Fail1:
-    for ( n = 0; n < count; n++ )
-      Free_AlternateSet( &aset[n], memory );
+    for ( m = 0; m < n; m++ )
+      Free_AlternateSet( &aset[m], memory );
 
     FREE( aset );
 
@@ -1030,7 +1030,7 @@
     FT_Error error;
     FT_Memory memory = stream->memory;
 
-    FT_UShort      n, count;
+    FT_UShort      n = 0, m, count;
     FT_ULong       cur_offset, new_offset, base_offset;
 
     TTO_Ligature*  l;
@@ -1071,8 +1071,8 @@
     return TT_Err_Ok;
 
   Fail:
-    for ( n = 0; n < count; n++ )
-      Free_Ligature( &l[n], memory );
+    for ( m = 0; m < n; m++ )
+      Free_Ligature( &l[m], memory );
 
     FREE( l );
     return error;
@@ -1108,7 +1108,7 @@
     FT_Error error;
     FT_Memory memory = stream->memory;
 
-    FT_UShort         n, count;
+    FT_UShort         n = 0, m, count;
     FT_ULong          cur_offset, new_offset, base_offset;
 
     TTO_LigatureSet*  lset;
@@ -1163,8 +1163,8 @@
     return TT_Err_Ok;
 
   Fail1:
-    for ( n = 0; n < count; n++ )
-      Free_LigatureSet( &lset[n], memory );
+    for ( m = 0; m < n; m++ )
+      Free_LigatureSet( &lset[m], memory );
 
     FREE( lset );
 
@@ -1478,7 +1478,7 @@
     FT_Error error;
     FT_Memory memory = stream->memory;
 
-    FT_UShort     n, count;
+    FT_UShort     n = 0, m, count;
     FT_ULong      cur_offset, new_offset, base_offset;
 
     TTO_SubRule*  sr;
@@ -1519,8 +1519,8 @@
     return TT_Err_Ok;
 
   Fail:
-    for ( n = 0; n < count; n++ )
-      Free_SubRule( &sr[n], memory );
+    for ( m = 0; m < n; m++ )
+      Free_SubRule( &sr[m], memory );
 
     FREE( sr );
     return error;
@@ -1556,7 +1556,7 @@
     FT_Error error;
     FT_Memory memory = stream->memory;
 
-    FT_UShort        n, count;
+    FT_UShort        n = 0, m, count;
     FT_ULong         cur_offset, new_offset, base_offset;
 
     TTO_SubRuleSet*  srs;
@@ -1610,8 +1610,8 @@
     return TT_Err_Ok;
 
   Fail1:
-    for ( n = 0; n < count; n++ )
-      Free_SubRuleSet( &srs[n], memory );
+    for ( m = 0; m < n; m++ )
+      Free_SubRuleSet( &srs[m], memory );
 
     FREE( srs );
 
@@ -1823,7 +1823,7 @@
     FT_Error error;
     FT_Memory memory = stream->memory;
 
-    FT_UShort         n, count;
+    FT_UShort         n = 0, m, count;
     FT_ULong          cur_offset, new_offset, base_offset;
 
     TTO_SubClassSet*  scs;
@@ -1901,8 +1901,8 @@
     return TT_Err_Ok;
 
   Fail1:
-    for ( n = 0; n < count; n++ )
-      Free_SubClassSet( &scs[n], memory );
+    for ( m = 0; m < n; m++ )
+      Free_SubClassSet( &scs[m], memory );
 
     FREE( scs );
 
@@ -2519,7 +2519,7 @@
     FT_Error error;
     FT_Memory memory = stream->memory;
 
-    FT_UShort          n, count;
+    FT_UShort          n = 0, m, count;
     FT_ULong           cur_offset, new_offset, base_offset;
 
     TTO_ChainSubRule*  csr;
@@ -2560,8 +2560,8 @@
     return TT_Err_Ok;
 
   Fail:
-    for ( n = 0; n < count; n++ )
-      Free_ChainSubRule( &csr[n], memory );
+    for ( m = 0; m < n; m++ )
+      Free_ChainSubRule( &csr[m], memory );
 
     FREE( csr );
     return error;
@@ -2598,7 +2598,7 @@
     FT_Error error;
     FT_Memory memory = stream->memory;
 
-    FT_UShort             n, count;
+    FT_UShort             n = 0, m, count;
     FT_ULong              cur_offset, new_offset, base_offset;
 
     TTO_ChainSubRuleSet*  csrs;
@@ -2652,8 +2652,8 @@
     return TT_Err_Ok;
 
   Fail1:
-    for ( n = 0; n < count; n++ )
-      Free_ChainSubRuleSet( &csrs[n], memory );
+    for ( m = 0; m < n; m++ )
+      Free_ChainSubRuleSet( &csrs[m], memory );
 
     FREE( csrs );
 
@@ -2872,7 +2872,7 @@
     FT_Error error;
     FT_Memory memory = stream->memory;
 
-    FT_UShort               n, count;
+    FT_UShort               n = 0, m, count;
     FT_ULong                cur_offset, new_offset, base_offset;
 
     TTO_ChainSubClassRule*  cscr;
@@ -2915,8 +2915,8 @@
     return TT_Err_Ok;
 
   Fail:
-    for ( n = 0; n < count; n++ )
-      Free_ChainSubClassRule( &cscr[n], memory );
+    for ( m = 0; m < n; n++ )
+      Free_ChainSubClassRule( &cscr[m], memory );
 
     FREE( cscr );
     return error;
@@ -2943,7 +2943,31 @@
     }
   }
 
+  static FT_Error Load_EmptyOrClassDefinition( TTO_ClassDefinition*  cd,
+                                               FT_UShort             limit,
+					       FT_ULong              class_offset,
+					       FT_ULong              base_offset,
+				               FT_Stream             stream )
+  {
+    FT_Error error;
+    FT_ULong               cur_offset;
 
+    cur_offset = FILE_Pos();
+
+    if ( class_offset )
+      {
+        if ( FILE_Seek( class_offset + base_offset ) )
+          error = Load_ClassDefinition( cd, limit, stream ) == TT_Err_Ok;
+      }
+    else
+       error = Load_EmptyClassDefinition ( cd, stream );
+
+    (void)FILE_Seek( cur_offset );
+
+    return error;
+  }
+
+
   /* ChainContextSubstFormat2 */
 
   static FT_Error  Load_ChainContextSubst2(
@@ -2953,7 +2977,7 @@
     FT_Error error;
     FT_Memory memory = stream->memory;
 
-    FT_UShort              n, count;
+    FT_UShort              n = 0, m, count;
     FT_ULong               cur_offset, new_offset, base_offset;
     FT_ULong               backtrack_offset, input_offset, lookahead_offset;
 
@@ -2978,9 +3002,9 @@
     if ( ACCESS_Frame( 8L ) )
       goto Fail5;
 
-    backtrack_offset = GET_UShort() + base_offset;
-    input_offset     = GET_UShort() + base_offset;
-    lookahead_offset = GET_UShort() + base_offset;
+    backtrack_offset = GET_UShort();
+    input_offset     = GET_UShort();
+    lookahead_offset = GET_UShort();
 
     /* `ChainSubClassSetCount' is the upper limit for input class values,
        thus we read it now to make an additional safety check.            */
@@ -2989,18 +3013,18 @@
 
     FORGET_Frame();
 
-    cur_offset = FILE_Pos();
-    if ( FILE_Seek( backtrack_offset ) ||
-         ( error = Load_ClassDefinition( &ccsf2->BacktrackClassDef, count,
-                                         stream ) ) != TT_Err_Ok )
-      goto Fail5;
-    if ( FILE_Seek( input_offset ) ||
-         ( error = Load_ClassDefinition( &ccsf2->InputClassDef, count,
-                                         stream ) ) != TT_Err_Ok )
-      goto Fail4;
-    if ( FILE_Seek( lookahead_offset ) ||
-         ( error = Load_ClassDefinition( &ccsf2->LookaheadClassDef, count,
-                                         stream ) ) != TT_Err_Ok )
+    if ( ( error = Load_EmptyOrClassDefinition( &ccsf2->BacktrackClassDef, count,
+                                                backtrack_offset, base_offset,
+					        stream ) ) != TT_Err_Ok )
+        goto Fail5;
+	       
+    if ( ( error = Load_EmptyOrClassDefinition( &ccsf2->InputClassDef, count,
+                                                input_offset, base_offset,
+                                                stream ) ) != TT_Err_Ok )
+        goto Fail4;
+    if ( ( error = Load_EmptyOrClassDefinition( &ccsf2->LookaheadClassDef, count,
+                                                lookahead_offset, base_offset,
+                                                stream ) ) != TT_Err_Ok )
       goto Fail3;
     (void)FILE_Seek( cur_offset );
 
@@ -3044,8 +3068,8 @@
     return TT_Err_Ok;
 
   Fail1:
-    for ( n = 0; n < count; n++ )
-      Free_ChainSubClassSet( &cscs[n], memory );
+    for ( m = 0; m < n; m++ )
+      Free_ChainSubClassSet( &cscs[m], memory );
 
     FREE( cscs );
 
Index: ftxopen.c
===================================================================
RCS file: /cvs/gnome/pango/pango/opentype/ftxopen.c,v
retrieving revision 1.3
diff -u -p -r1.3 ftxopen.c
--- ftxopen.c	2001/09/19 21:20:36	1.3
+++ ftxopen.c	2002/01/31 23:10:28
@@ -569,7 +569,7 @@
     FT_Error   error;
     FT_Memory  memory = stream->memory;
 
-    FT_UShort      n, count;
+    FT_UShort      n = 0, m, count;
     FT_ULong       cur_offset, new_offset, base_offset;
 
     TTO_SubTable*  st;
@@ -613,8 +613,8 @@
     return TT_Err_Ok;
 
   Fail:
-    for ( n = 0; n < count; n++ )
-      Free_SubTable( &st[n], type, l->LookupType, memory );
+    for ( m = 0; m < n; m++ )
+      Free_SubTable( &st[m], type, l->LookupType, memory );
 
     FREE( l->SubTable );
     return error;
@@ -1203,6 +1203,29 @@
     return error;
   }
 
+
+  FT_Error  Load_EmptyClassDefinition( TTO_ClassDefinition*  cd,
+				       FT_Stream             stream )
+  {
+    FT_Error   error;
+    FT_Memory  memory = stream->memory;
+
+
+    if ( ALLOC_ARRAY( cd->Defined, 1, FT_Bool ) )
+      return error;
+
+    cd->ClassFormat = 1; /* Meaningless */
+    cd->Defined[0] = FALSE;
+
+    if ( ALLOC_ARRAY( cd->cd.cd1.ClassValueArray, 1, FT_UShort ) )
+      goto Fail;
+
+    return TT_Err_Ok;
+
+  Fail:
+    FREE( cd->Defined );
+    return error;
+  }
 
   void  Free_ClassDefinition( TTO_ClassDefinition*  cd,
 			      FT_Memory             memory )
Index: ftxopenf.h
===================================================================
RCS file: /cvs/gnome/pango/pango/opentype/ftxopenf.h,v
retrieving revision 1.1
diff -u -p -r1.1 ftxopenf.h
--- ftxopenf.h	2000/12/20 04:41:36	1.1
+++ ftxopenf.h	2002/01/31 23:10:28
@@ -39,6 +39,8 @@ extern "C" {
   FT_Error  Load_ClassDefinition( TTO_ClassDefinition*  cd,
                                   FT_UShort             limit,
                                   FT_Stream             input );
+  FT_Error  Load_EmptyClassDefinition( TTO_ClassDefinition*  cd,
+                                       FT_Stream             input );
   FT_Error  Load_Device( TTO_Device*  d,
                          FT_Stream    input );
 


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