[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[ft-devel] Re: Can not read the glyph~
From: |
Werner LEMBERG |
Subject: |
[ft-devel] Re: Can not read the glyph~ |
Date: |
Wed, 09 Jul 2008 16:51:36 +0200 (CEST) |
> Can you tell me which files you have change? I need a stable vision,
> I want merge you code to vision 2.3.7.
Below.
Werner
======================================================================
Index: ChangeLog
===================================================================
RCS file: /cvsroot/freetype/freetype2/ChangeLog,v
retrieving revision 1.1765
retrieving revision 1.1766
diff -u -r1.1765 -r1.1766
--- ChangeLog 5 Jul 2008 06:36:39 -0000 1.1765
+++ ChangeLog 9 Jul 2008 06:20:11 -0000 1.1766
@@ -1,3 +1,8 @@
+2008-07-09 Werner Lemberg <address@hidden>
+
+ * src/truetype/ttpload.c (tt_face_load_loca): Handle buggy fonts
+ where num_locations < num_glyphs. Problem reported by Ding Li.
+
2008-07-05 Werner Lemberg <address@hidden>
Since FreeType uses `$(value ...)', we now need GNU make 3.80 or
Index: src/truetype/ttpload.c
===================================================================
RCS file: /cvsroot/freetype/freetype2/src/truetype/ttpload.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -r1.41 -r1.42
--- src/truetype/ttpload.c 5 Jan 2007 12:41:49 -0000 1.41
+++ src/truetype/ttpload.c 9 Jul 2008 06:20:12 -0000 1.42
@@ -4,7 +4,7 @@
/* */
/* TrueType-specific tables loader (body). */
/* */
-/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -65,6 +65,7 @@
{
FT_Error error;
FT_ULong table_len;
+ FT_Int shift;
/* we need the size of the `glyf' table for malformed `loca' tables */
@@ -82,23 +83,65 @@
if ( face->header.Index_To_Loc_Format != 0 )
{
+ shift = 2;
+
if ( table_len >= 0x40000L )
{
FT_TRACE2(( "table too large!\n" ));
error = TT_Err_Invalid_Table;
goto Exit;
}
- face->num_locations = (FT_UInt)( table_len >> 2 );
+ face->num_locations = (FT_UInt)( table_len >> shift );
}
else
{
+ shift = 1;
+
if ( table_len >= 0x20000L )
{
FT_TRACE2(( "table too large!\n" ));
error = TT_Err_Invalid_Table;
goto Exit;
}
- face->num_locations = (FT_UInt)( table_len >> 1 );
+ face->num_locations = (FT_UInt)( table_len >> shift );
+ }
+
+ if ( face->num_locations != (FT_UInt)face->root.num_glyphs )
+ {
+ FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n",
+ face->num_locations, face->root.num_glyphs ));
+
+ /* we only handle the case where `maxp' gives a larger value */
+ if ( face->num_locations < (FT_UInt)face->root.num_glyphs )
+ {
+ FT_Long new_loca_len = (FT_Long)face->root.num_glyphs << shift;
+
+ TT_Table entry = face->dir_tables;
+ TT_Table limit = entry + face->num_tables;
+
+ FT_Long pos = FT_Stream_Pos( stream );
+ FT_Long dist = 0x7FFFFFFFL;
+
+
+ /* compute the distance to next table in font file */
+ for ( ; entry < limit; entry++ )
+ {
+ FT_Long diff = entry->Offset - pos;
+
+
+ if ( diff > 0 && diff < dist )
+ dist = diff;
+ }
+
+ if ( new_loca_len <= dist )
+ {
+ face->num_locations = (FT_Long)face->root.num_glyphs;
+ table_len = new_loca_len;
+
+ FT_TRACE2(( "adjusting num_locations to %d\n",
+ face->num_locations ));
+ }
+ }
}
/*