* src/sfnt/ttcmap0.c (tt_cmap4_validate):
fixed over-restrictive validation test. the charmap validator now accepts overlapping ranges in format 4 charmaps. * src/sfnt/ttcmap0.c (tt_cmap4_char_index): switched to a binary search algorithm. Certain fonts contain more than 170 distinct segments !!
This commit is contained in:
parent
af48e32c17
commit
3c5a3e45c9
|
@ -638,7 +638,7 @@
|
||||||
offsets = deltas + num_segs * 2;
|
offsets = deltas + num_segs * 2;
|
||||||
glyph_ids = offsets + num_segs * 2;
|
glyph_ids = offsets + num_segs * 2;
|
||||||
|
|
||||||
if ( glyph_ids >= table + length )
|
if ( glyph_ids > table + length )
|
||||||
FT_INVALID_TOO_SHORT;
|
FT_INVALID_TOO_SHORT;
|
||||||
|
|
||||||
/* check last segment, its end count must be FFFF */
|
/* check last segment, its end count must be FFFF */
|
||||||
|
@ -670,8 +670,15 @@
|
||||||
if ( start > end )
|
if ( start > end )
|
||||||
FT_INVALID_DATA;
|
FT_INVALID_DATA;
|
||||||
|
|
||||||
if ( n > 0 && start <= last )
|
/* this test should be performed at default validation level */
|
||||||
FT_INVALID_DATA;
|
/* unfortunately, some popular asian fonts present overlapping */
|
||||||
|
/* ranges in their charmaps.. */
|
||||||
|
/* */
|
||||||
|
if ( valid->level >= FT_VALIDATE_TIGHT )
|
||||||
|
{
|
||||||
|
if ( n > 0 && start <= last )
|
||||||
|
FT_INVALID_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
if ( offset )
|
if ( offset )
|
||||||
{
|
{
|
||||||
|
@ -718,49 +725,108 @@
|
||||||
|
|
||||||
if ( char_code < 0x10000UL )
|
if ( char_code < 0x10000UL )
|
||||||
{
|
{
|
||||||
FT_Byte* p;
|
|
||||||
FT_Byte* q;
|
|
||||||
FT_UInt idx, num_segs2;
|
FT_UInt idx, num_segs2;
|
||||||
FT_Int delta;
|
FT_Int delta;
|
||||||
FT_UInt n, code = (FT_UInt)char_code;
|
FT_UInt code = (FT_UInt)char_code;
|
||||||
|
FT_Byte* p;
|
||||||
|
|
||||||
|
|
||||||
p = table + 6;
|
p = table + 6;
|
||||||
num_segs2 = TT_PEEK_USHORT( p ) & -2; /* be paranoid! */
|
num_segs2 = TT_PEEK_USHORT( p ) & -2; /* be paranoid! */
|
||||||
|
|
||||||
p = table + 14; /* ends table */
|
#if 1
|
||||||
q = table + 16 + num_segs2; /* starts table */
|
/* some fonts have more than 170 segments in their charmaps !! */
|
||||||
|
/* we changed this function to use a more efficient binary */
|
||||||
for ( n = 0; n < num_segs2; n += 2 )
|
/* search to boost its performance */
|
||||||
{
|
{
|
||||||
FT_UInt end = TT_NEXT_USHORT( p );
|
FT_UInt min = 0;
|
||||||
FT_UInt start = TT_NEXT_USHORT( q );
|
FT_UInt max = num_segs2 >> 1;
|
||||||
FT_UInt offset;
|
FT_UInt mid, start, end, offset;
|
||||||
|
|
||||||
|
|
||||||
if ( code < start )
|
while ( min < max )
|
||||||
break;
|
|
||||||
|
|
||||||
if ( code <= end )
|
|
||||||
{
|
{
|
||||||
idx = code;
|
mid = ( min + max ) >> 1;
|
||||||
|
p = table + 14 + mid*2;
|
||||||
|
end = TT_NEXT_USHORT( p );
|
||||||
|
p += num_segs2;
|
||||||
|
start = TT_PEEK_USHORT( p);
|
||||||
|
|
||||||
p = q + num_segs2 - 2;
|
if ( code < start )
|
||||||
delta = TT_PEEK_SHORT( p );
|
max = mid;
|
||||||
p += num_segs2;
|
|
||||||
offset = TT_PEEK_USHORT( p );
|
|
||||||
|
|
||||||
if ( offset != 0 )
|
else if ( code > end )
|
||||||
|
min = mid+1;
|
||||||
|
|
||||||
|
else
|
||||||
{
|
{
|
||||||
p += offset + 2 * ( idx - start );
|
/* we found the segment */
|
||||||
idx = TT_PEEK_USHORT( p );
|
idx = code;
|
||||||
}
|
|
||||||
|
|
||||||
if ( idx != 0 )
|
p += num_segs2;
|
||||||
result = (FT_UInt)( idx + delta ) & 0xFFFFU;
|
delta = TT_PEEK_SHORT( p );
|
||||||
|
|
||||||
|
p += num_segs2;
|
||||||
|
offset = TT_PEEK_USHORT( p );
|
||||||
|
|
||||||
|
if ( offset != 0 )
|
||||||
|
{
|
||||||
|
p += offset + 2*( idx - start );
|
||||||
|
idx = TT_PEEK_USHORT( p );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( idx != 0 )
|
||||||
|
result = (FT_UInt)( idx + delta ) & 0xFFFU;
|
||||||
|
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else /* 0 - old code */
|
||||||
|
{
|
||||||
|
FT_UInt n;
|
||||||
|
FT_Byte* q;
|
||||||
|
|
||||||
|
|
||||||
|
p = table + 14; /* ends table */
|
||||||
|
q = table + 16 + num_segs2; /* starts table */
|
||||||
|
|
||||||
|
|
||||||
|
for ( n = 0; n < num_segs2; n += 2 )
|
||||||
|
{
|
||||||
|
FT_UInt end = TT_NEXT_USHORT( p );
|
||||||
|
FT_UInt start = TT_NEXT_USHORT( q );
|
||||||
|
FT_UInt offset;
|
||||||
|
|
||||||
|
|
||||||
|
if ( code < start )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ( code <= end )
|
||||||
|
{
|
||||||
|
idx = code;
|
||||||
|
|
||||||
|
p = q + num_segs2 - 2;
|
||||||
|
delta = TT_PEEK_SHORT( p );
|
||||||
|
p += num_segs2;
|
||||||
|
offset = TT_PEEK_USHORT( p );
|
||||||
|
|
||||||
|
if ( offset != 0 )
|
||||||
|
{
|
||||||
|
p += offset + 2 * ( idx - start );
|
||||||
|
idx = TT_PEEK_USHORT( p );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( idx != 0 )
|
||||||
|
result = (FT_UInt)( idx + delta ) & 0xFFFFU;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* 0 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Exit:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue