Handle unsorted SFNT type 4 cmaps correctly (reported by Dirck

Blaskey).

* src/sfnt/ttcmap.h (TT_CMap): Add member `unsorted'.
* src/sfnt/ttcmac.c: Use SFNT_Err_Ok where appropriate.

(tt_cmap0_validate, tt_cmap2_validate, tt_cmap6_validate,
tt_cmap8_validate, tt_cmap10_validate, tt_cmap12_validate): Use
`FT_Error' as return type.
(tt_cmap4_validate): Use `FT_Error' as return type.
Return error code for unsorted cmap.
(tt_cmap4_char_index, tt_cmap4_char_next): Use old code for unsorted
cmaps.
(tt_face_build_cmaps): Set `unsorted' variable in cmap.


Minor formatting.
This commit is contained in:
Werner Lemberg 2005-05-09 22:11:36 +00:00
parent 43ebad4207
commit 22ad9ef024
16 changed files with 251 additions and 213 deletions

View File

@ -1,3 +1,20 @@
2005-05-07 Werner Lemberg <wl@gnu.org>
Handle unsorted SFNT type 4 cmaps correctly (reported by Dirck
Blaskey).
* src/sfnt/ttcmap.h (TT_CMap): Add member `unsorted'.
* src/sfnt/ttcmac.c: Use SFNT_Err_Ok where appropriate.
(tt_cmap0_validate, tt_cmap2_validate, tt_cmap6_validate,
tt_cmap8_validate, tt_cmap10_validate, tt_cmap12_validate): Use
`FT_Error' as return type.
(tt_cmap4_validate): Use `FT_Error' as return type.
Return error code for unsorted cmap.
(tt_cmap4_char_index, tt_cmap4_char_next): Use old code for unsorted
cmaps.
(tt_face_build_cmaps): Set `unsorted' variable in cmap.
2005-05-07 Werner Lemberg <wl@gnu.org> 2005-05-07 Werner Lemberg <wl@gnu.org>
* src/truetype/ttpload.c (tt_face_get_location): Fix typo. * src/truetype/ttpload.c (tt_face_get_location): Fix typo.

View File

@ -688,7 +688,7 @@
{ {
/* we are just leaving an edge; record a new segment! */ /* we are just leaving an edge; record a new segment! */
segment->last = point; segment->last = point;
segment->pos = (FT_Short)(( min_pos + max_pos ) >> 1); segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 );
/* a segment is round if either its first or last point */ /* a segment is round if either its first or last point */
/* is a control point */ /* is a control point */
@ -705,8 +705,8 @@
if ( v > max_pos ) if ( v > max_pos )
max_pos = v; max_pos = v;
segment->min_coord = (FT_Short) min_pos; segment->min_coord = (FT_Short)min_pos;
segment->max_coord = (FT_Short) max_pos; segment->max_coord = (FT_Short)max_pos;
on_edge = 0; on_edge = 0;
segment = NULL; segment = NULL;
@ -732,7 +732,7 @@
if ( error ) if ( error )
goto Exit; goto Exit;
segment->dir = (FT_Char) segment_dir; segment->dir = (FT_Char)segment_dir;
segment->flags = AF_EDGE_NORMAL; segment->flags = AF_EDGE_NORMAL;
min_pos = max_pos = point->u; min_pos = max_pos = point->u;
segment->first = point; segment->first = point;
@ -1150,10 +1150,10 @@
edge->dir = AF_DIR_NONE; edge->dir = AF_DIR_NONE;
if ( ups > downs ) if ( ups > downs )
edge->dir = (FT_Char) up_dir; edge->dir = (FT_Char)up_dir;
else if ( ups < downs ) else if ( ups < downs )
edge->dir = (FT_Char) -up_dir; edge->dir = (FT_Char)-up_dir;
else if ( ups == downs ) else if ( ups == downs )
edge->dir = 0; /* both up and down! */ edge->dir = 0; /* both up and down! */
@ -1232,7 +1232,7 @@
/* zone, check for left edges */ /* zone, check for left edges */
/* */ /* */
/* of course, that's for TrueType */ /* of course, that's for TrueType */
is_top_blue = (FT_Byte)(( blue->flags & AF_LATIN_BLUE_TOP ) != 0); is_top_blue = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 );
is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); is_major_dir = FT_BOOL( edge->dir == axis->major_dir );
/* if it is a top zone, the edge must be against the major */ /* if it is a top zone, the edge must be against the major */

View File

@ -4,7 +4,7 @@
/* */ /* */
/* FreeType path stroker (body). */ /* FreeType path stroker (body). */
/* */ /* */
/* Copyright 2002, 2003, 2004 by */ /* Copyright 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -1425,7 +1425,7 @@
dst_tag[0] &= ~FT_STROKE_TAG_BEGIN_END; dst_tag[0] &= ~FT_STROKE_TAG_BEGIN_END;
else else
{ {
FT_Byte ttag = (FT_Byte)(dst_tag[0] & FT_STROKE_TAG_BEGIN_END); FT_Byte ttag = (FT_Byte)( dst_tag[0] & FT_STROKE_TAG_BEGIN_END );
/* switch begin/end tags if necessary */ /* switch begin/end tags if necessary */

View File

@ -2,7 +2,7 @@
FreeType font driver for bdf files FreeType font driver for bdf files
Copyright (C) 2001, 2002, 2003, 2004 by Copyright (C) 2001, 2002, 2003, 2004, 2005 by
Francesco Zappa Nardelli Francesco Zappa Nardelli
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy

View File

@ -4,7 +4,7 @@
/* */ /* */
/* The FreeType basic cache interface (body). */ /* The FreeType basic cache interface (body). */
/* */ /* */
/* Copyright 2003, 2004 by */ /* Copyright 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -38,8 +38,8 @@
} FTC_BasicAttrRec, *FTC_BasicAttrs; } FTC_BasicAttrRec, *FTC_BasicAttrs;
#define FTC_BASIC_ATTR_COMPARE( a, b ) \ #define FTC_BASIC_ATTR_COMPARE( a, b ) \
FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \ FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \
(a)->load_flags == (b)->load_flags ) (a)->load_flags == (b)->load_flags )
#define FTC_BASIC_ATTR_HASH( a ) \ #define FTC_BASIC_ATTR_HASH( a ) \

2
src/cache/ftccmap.c vendored
View File

@ -4,7 +4,7 @@
/* */ /* */
/* FreeType CharMap cache (body) */ /* FreeType CharMap cache (body) */
/* */ /* */
/* Copyright 2000-2001, 2002, 2003, 2004 by */ /* Copyright 2000-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */

View File

@ -4,7 +4,7 @@
/* */ /* */
/* FreeType Cache Manager (body). */ /* FreeType Cache Manager (body). */
/* */ /* */
/* Copyright 2000-2001, 2002, 2003, 2004 by */ /* Copyright 2000-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -164,7 +164,7 @@
FTC_FaceID face_id = (FTC_FaceID)ftcface_id; FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
return FT_BOOL(node->scaler.face_id == face_id); return FT_BOOL( node->scaler.face_id == face_id );
} }

View File

@ -4,7 +4,7 @@
/* */ /* */
/* OpenType and CFF data/program tables loader (body). */ /* OpenType and CFF data/program tables loader (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */

View File

@ -4,7 +4,7 @@
/* */ /* */
/* CID-keyed Type1 font loader (body). */ /* CID-keyed Type1 font loader (body). */
/* */ /* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -536,11 +536,11 @@
} }
if ( ft_isdigit( *p ) ) if ( ft_isdigit( *p ) )
val = (FT_Byte)(*p - '0'); val = (FT_Byte)( *p - '0' );
else if ( *p >= 'a' && *p <= 'f' ) else if ( *p >= 'a' && *p <= 'f' )
val = (FT_Byte)(*p - 'a'); val = (FT_Byte)( *p - 'a' );
else if ( *p >= 'A' && *p <= 'F' ) else if ( *p >= 'A' && *p <= 'F' )
val = (FT_Byte)(*p - 'A' + 10); val = (FT_Byte)( *p - 'A' + 10 );
else if ( *p == ' ' || else if ( *p == ' ' ||
*p == '\t' || *p == '\t' ||
*p == '\r' || *p == '\r' ||
@ -563,14 +563,14 @@
} }
if ( upper_nibble ) if ( upper_nibble )
*d = (FT_Byte)(val << 4); *d = (FT_Byte)( val << 4 );
else else
{ {
*d = (FT_Byte)(*d + val); *d = (FT_Byte)( *d + val );
d++; d++;
} }
upper_nibble = (FT_Byte)(1 - upper_nibble); upper_nibble = (FT_Byte)( 1 - upper_nibble );
if ( done ) if ( done )
break; break;

View File

@ -35,7 +35,7 @@
/*- /*-
* *
* Copyright (c) 2004 * Copyright (c) 2004, 2005
* Albert Chin-A-Young. * Albert Chin-A-Young.
* *
* Modified to work with FreeType's PCF driver. * Modified to work with FreeType's PCF driver.
@ -276,8 +276,8 @@ middle:
/* Generate the new entry. */ /* Generate the new entry. */
if ((code = free_ent) < maxmaxcode) { if ((code = free_ent) < maxmaxcode) {
tab_prefixof(code) = (unsigned short) oldcode; tab_prefixof(code) = (unsigned short)oldcode;
tab_suffixof(code) = (unsigned char) finchar; tab_suffixof(code) = (unsigned char)finchar;
free_ent = code + 1; free_ent = code + 1;
} }

View File

@ -4,7 +4,7 @@
/* */ /* */
/* OpenType GDEF table validation (body). */ /* OpenType GDEF table validation (body). */
/* */ /* */
/* Copyright 2004 by */ /* Copyright 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */

View File

@ -208,7 +208,7 @@
case TT_MS_ID_SYMBOL_CS: case TT_MS_ID_SYMBOL_CS:
case TT_MS_ID_UNICODE_CS: case TT_MS_ID_UNICODE_CS:
case TT_MS_ID_UCS_4: case TT_MS_ID_UCS_4:
is_english = FT_BOOL(( rec->languageID & 0x3FF ) == 0x009); is_english = FT_BOOL( ( rec->languageID & 0x3FF ) == 0x009 );
found_win = n; found_win = n;
break; break;

View File

@ -53,7 +53,7 @@
FT_Byte* table ) FT_Byte* table )
{ {
cmap->data = table; cmap->data = table;
return 0; return SFNT_Err_Ok;
} }
@ -81,7 +81,7 @@
#ifdef TT_CONFIG_CMAP_FORMAT_0 #ifdef TT_CONFIG_CMAP_FORMAT_0
FT_CALLBACK_DEF( void ) FT_CALLBACK_DEF( FT_Error )
tt_cmap0_validate( FT_Byte* table, tt_cmap0_validate( FT_Byte* table,
FT_Validator valid ) FT_Validator valid )
{ {
@ -106,6 +106,8 @@
FT_INVALID_GLYPH_ID; FT_INVALID_GLYPH_ID;
} }
} }
return SFNT_Err_Ok;
} }
@ -266,7 +268,7 @@
#ifdef TT_CONFIG_CMAP_FORMAT_2 #ifdef TT_CONFIG_CMAP_FORMAT_2
FT_CALLBACK_DEF( void ) FT_CALLBACK_DEF( FT_Error )
tt_cmap2_validate( FT_Byte* table, tt_cmap2_validate( FT_Byte* table,
FT_Validator valid ) FT_Validator valid )
{ {
@ -355,6 +357,8 @@
} }
} }
} }
return SFNT_Err_Ok;
} }
@ -625,7 +629,7 @@
#ifdef OPT_CMAP4 #ifdef OPT_CMAP4
typedef struct TT_CMap4Rec_ typedef struct TT_CMap4Rec_
{ {
TT_CMapRec cmap; TT_CMapRec cmap;
FT_UInt32 old_charcode; /* old charcode */ FT_UInt32 old_charcode; /* old charcode */
@ -650,7 +654,7 @@
FT_Byte* p; FT_Byte* p;
cmap->cmap.data = table; cmap->cmap.data = table;
p = table + 2; p = table + 2;
cmap->table_length = FT_PEEK_USHORT( p ); cmap->table_length = FT_PEEK_USHORT( p );
@ -662,7 +666,7 @@
cmap->cur_charcode = 0; cmap->cur_charcode = 0;
cmap->cur_gindex = 0; cmap->cur_gindex = 0;
return 0; return SFNT_Err_Ok;
} }
@ -792,7 +796,7 @@
FT_CALLBACK_DEF( void ) FT_CALLBACK_DEF( FT_Error )
tt_cmap4_validate( FT_Byte* table, tt_cmap4_validate( FT_Byte* table,
FT_Validator valid ) FT_Validator valid )
{ {
@ -800,6 +804,7 @@
FT_UInt length = TT_NEXT_USHORT( p ); FT_UInt length = TT_NEXT_USHORT( p );
FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids; FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids;
FT_UInt num_segs; FT_UInt num_segs;
FT_Error error = SFNT_Err_Ok;
/* in certain fonts, the `length' field is invalid and goes */ /* in certain fonts, the `length' field is invalid and goes */
@ -894,10 +899,12 @@
/* unfortunately, some popular Asian fonts present overlapping */ /* unfortunately, some popular Asian fonts present overlapping */
/* ranges in their charmaps */ /* ranges in their charmaps */
/* */ /* */
if ( valid->level >= FT_VALIDATE_TIGHT ) if ( n > 0 && start <= last )
{ {
if ( n > 0 && start <= last ) if ( valid->level >= FT_VALIDATE_TIGHT )
FT_INVALID_DATA; FT_INVALID_DATA;
else
error = SFNT_Err_Invalid_CharMap_Format;
} }
if ( offset && offset != 0xFFFFU ) if ( offset && offset != 0xFFFFU )
@ -951,6 +958,8 @@
last = end; last = end;
} }
} }
return error;
} }
@ -972,11 +981,11 @@
p = table + 6; p = table + 6;
num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); /* be paranoid! */ num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); /* be paranoid! */
#if 1 if ( !cmap->unsorted )
/* Some fonts have more than 170 segments in their charmaps! */
/* We changed this function to use a more efficient binary */
/* search for improving performance */
{ {
/* Some fonts have more than 170 segments in their charmaps! */
/* We changed this function to use a more efficient binary */
/* search for improving performance */
FT_UInt min = 0; FT_UInt min = 0;
FT_UInt max = num_segs2 >> 1; FT_UInt max = num_segs2 >> 1;
FT_UInt mid, start, end, offset; FT_UInt mid, start, end, offset;
@ -1021,9 +1030,7 @@
} }
} }
} }
else
#else /* 0 - old code */
{ {
FT_UInt n; FT_UInt n;
FT_Byte* q; FT_Byte* q;
@ -1066,9 +1073,6 @@
} }
} }
} }
#endif /* 0 */
} }
Exit: Exit:
@ -1111,173 +1115,172 @@
code = (FT_UInt)char_code + 1; code = (FT_UInt)char_code + 1;
p = table + 6; p = table + 6;
num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT(p), 2 ); /* ensure even-ness */ num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); /* ensure even-ness */
#if 1 if ( !cmap->unsorted )
for (;;)
{ {
/* Some fonts have more than 170 segments in their charmaps! */ for (;;)
/* We changed this function to use a more efficient binary */
/* search */
FT_UInt offset;
FT_Int delta;
FT_UInt min = 0;
FT_UInt max = num_segs2 >> 1;
FT_UInt mid, start, end;
FT_UInt hi;
/* we begin by finding the segment which end is
closer to our code point */
hi = max + 1;
while ( min < max )
{ {
mid = ( min + max ) >> 1; /* Some fonts have more than 170 segments in their charmaps! */
p = table + 14 + mid * 2; /* We changed this function to use a more efficient binary */
end = TT_PEEK_USHORT( p ); /* search */
FT_UInt offset;
FT_Int delta;
FT_UInt min = 0;
FT_UInt max = num_segs2 >> 1;
FT_UInt mid, start, end;
FT_UInt hi;
if ( end < code )
min = mid + 1; /* we begin by finding the segment which end is
else closer to our code point */
hi = max + 1;
while ( min < max )
{ {
hi = mid; mid = ( min + max ) >> 1;
max = mid; p = table + 14 + mid * 2;
} end = TT_PEEK_USHORT( p );
}
if ( hi > max ) if ( end < code )
{ min = mid + 1;
/* the point is behind the last segment; else
we will exit right now */
goto Exit;
}
p = table + 14 + hi * 2;
end = TT_PEEK_USHORT( p );
p += 2 + num_segs2;
start = TT_PEEK_USHORT( p );
if ( code < start )
code = start;
p += num_segs2;
delta = TT_PEEK_USHORT( p );
p += num_segs2;
offset = TT_PEEK_USHORT( p );
if ( offset != 0 && offset != 0xFFFFU )
{
/* parse the glyph ids array for non-zero index */
p += offset + ( code - start ) * 2;
while ( code <= end )
{
gindex = TT_NEXT_USHORT( p );
if ( gindex != 0 )
{ {
gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; hi = mid;
if ( gindex != 0 ) max = mid;
{
result = code;
#ifdef OPT_CMAP4
tt_cmap4_reset( (TT_CMap4)cmap, code, hi );
#endif
goto Exit;
}
} }
code++;
} }
}
else if ( offset == 0xFFFFU ) if ( hi > max )
{
/* an offset of 0xFFFF means an empty segment in certain fonts! */
code = end + 1;
}
else /* offset == 0 */
{
gindex = (FT_UInt)( code + delta ) & 0xFFFFU;
if ( gindex != 0 )
{ {
result = code; /* the point is behind the last segment;
#ifdef OPT_CMAP4 we will exit right now */
tt_cmap4_reset( (TT_CMap4)cmap, code, hi );
#endif
goto Exit; goto Exit;
} }
code++;
}
}
#else /* old code -- kept for reference */ p = table + 14 + hi * 2;
end = TT_PEEK_USHORT( p );
for ( ;; )
{
FT_UInt offset, n;
FT_Int delta;
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 );
p += 2 + num_segs2;
start = TT_PEEK_USHORT( p );
if ( code < start ) if ( code < start )
code = start; code = start;
if ( code <= end ) p += num_segs2;
{ delta = TT_PEEK_USHORT( p );
p = q + num_segs2 - 2;
delta = TT_PEEK_SHORT( p );
p += num_segs2;
offset = TT_PEEK_USHORT( p );
if ( offset != 0 && offset != 0xFFFFU ) p += num_segs2;
offset = TT_PEEK_USHORT( p );
if ( offset != 0 && offset != 0xFFFFU )
{
/* parse the glyph ids array for non-zero index */
p += offset + ( code - start ) * 2;
while ( code <= end )
{ {
/* parse the glyph ids array for non-0 index */ gindex = TT_NEXT_USHORT( p );
p += offset + ( code - start ) * 2; if ( gindex != 0 )
while ( code <= end )
{ {
gindex = TT_NEXT_USHORT( p ); gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU;
if ( gindex != 0 ) if ( gindex != 0 )
{ {
gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; result = code;
if ( gindex != 0 ) #ifdef OPT_CMAP4
break; tt_cmap4_reset( (TT_CMap4)cmap, code, hi );
#endif
goto Exit;
} }
code++;
} }
code++;
} }
else if ( offset == 0xFFFFU ) }
else if ( offset == 0xFFFFU )
{
/* an offset of 0xFFFF means an empty segment in certain fonts! */
code = end + 1;
}
else /* offset == 0 */
{
gindex = (FT_UInt)( code + delta ) & 0xFFFFU;
if ( gindex != 0 )
{ {
/* an offset of 0xFFFF means an empty glyph in certain fonts! */ result = code;
code = end; #ifdef OPT_CMAP4
break; tt_cmap4_reset( (TT_CMap4)cmap, code, hi );
#endif
goto Exit;
} }
else code++;
gindex = (FT_UInt)( code + delta ) & 0xFFFFU;
if ( gindex == 0 )
break;
result = code;
goto Exit;
} }
} }
/* loop to next trial charcode */
if ( code >= 0xFFFFU )
break;
code++;
} }
else
{
for ( ;; )
{
FT_UInt offset, n;
FT_Int delta;
FT_Byte* q;
#endif /* !1 */
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 );
if ( code < start )
code = start;
if ( code <= end )
{
p = q + num_segs2 - 2;
delta = TT_PEEK_SHORT( p );
p += num_segs2;
offset = TT_PEEK_USHORT( p );
if ( offset != 0 && offset != 0xFFFFU )
{
/* parse the glyph ids array for non-0 index */
p += offset + ( code - start ) * 2;
while ( code <= end )
{
gindex = TT_NEXT_USHORT( p );
if ( gindex != 0 )
{
gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU;
if ( gindex != 0 )
break;
}
code++;
}
}
else if ( offset == 0xFFFFU )
{
/* an offset of 0xFFFF means an empty glyph in certain fonts! */
code = end;
break;
}
else
gindex = (FT_UInt)( code + delta ) & 0xFFFFU;
if ( gindex == 0 )
break;
result = code;
goto Exit;
}
}
/* loop to next trial charcode */
if ( code >= 0xFFFFU )
break;
code++;
}
}
Exit: Exit:
*pchar_code = result; *pchar_code = result;
@ -1349,7 +1352,7 @@
#ifdef TT_CONFIG_CMAP_FORMAT_6 #ifdef TT_CONFIG_CMAP_FORMAT_6
FT_CALLBACK_DEF( void ) FT_CALLBACK_DEF( FT_Error )
tt_cmap6_validate( FT_Byte* table, tt_cmap6_validate( FT_Byte* table,
FT_Validator valid ) FT_Validator valid )
{ {
@ -1382,6 +1385,8 @@
FT_INVALID_GLYPH_ID; FT_INVALID_GLYPH_ID;
} }
} }
return SFNT_Err_Ok;
} }
@ -1535,7 +1540,7 @@
#ifdef TT_CONFIG_CMAP_FORMAT_8 #ifdef TT_CONFIG_CMAP_FORMAT_8
FT_CALLBACK_DEF( void ) FT_CALLBACK_DEF( FT_Error )
tt_cmap8_validate( FT_Byte* table, tt_cmap8_validate( FT_Byte* table,
FT_Validator valid ) FT_Validator valid )
{ {
@ -1624,6 +1629,8 @@
last = end; last = end;
} }
} }
return SFNT_Err_Ok;
} }
@ -1757,7 +1764,7 @@
#ifdef TT_CONFIG_CMAP_FORMAT_10 #ifdef TT_CONFIG_CMAP_FORMAT_10
FT_CALLBACK_DEF( void ) FT_CALLBACK_DEF( FT_Error )
tt_cmap10_validate( FT_Byte* table, tt_cmap10_validate( FT_Byte* table,
FT_Validator valid ) FT_Validator valid )
{ {
@ -1788,6 +1795,8 @@
FT_INVALID_GLYPH_ID; FT_INVALID_GLYPH_ID;
} }
} }
return SFNT_Err_Ok;
} }
@ -1907,7 +1916,7 @@
#ifdef TT_CONFIG_CMAP_FORMAT_12 #ifdef TT_CONFIG_CMAP_FORMAT_12
FT_CALLBACK_DEF( void ) FT_CALLBACK_DEF( FT_Error )
tt_cmap12_validate( FT_Byte* table, tt_cmap12_validate( FT_Byte* table,
FT_Validator valid ) FT_Validator valid )
{ {
@ -1954,6 +1963,8 @@
last = end; last = end;
} }
} }
return SFNT_Err_Ok;
} }
@ -2149,6 +2160,7 @@
if ( clazz->format == format ) if ( clazz->format == format )
{ {
volatile TT_ValidatorRec valid; volatile TT_ValidatorRec valid;
FT_Error error = SFNT_Err_Ok;
ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit, ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit,
@ -2159,11 +2171,19 @@
if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer ) == 0 ) if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer ) == 0 )
{ {
/* validate this cmap sub-table */ /* validate this cmap sub-table */
clazz->validate( cmap, FT_VALIDATOR( &valid ) ); error = clazz->validate( cmap, FT_VALIDATOR( &valid ) );
} }
if ( valid.validator.error == 0 ) if ( valid.validator.error == 0 )
{
(void)FT_CMap_New( (FT_CMap_Class)clazz, cmap, &charmap, NULL ); (void)FT_CMap_New( (FT_CMap_Class)clazz, cmap, &charmap, NULL );
/* it is simpler to directly set the `unsorted' flag instead */
/* of adding a parameter to FT_CMap_New */
((TT_CMap)(face->root.charmaps
[face->root.num_charmaps - 1]))->unsorted =
FT_BOOL( error );
}
else else
{ {
FT_ERROR(( "tt_face_build_cmaps:" )); FT_ERROR(( "tt_face_build_cmaps:" ));
@ -2175,7 +2195,7 @@
} }
} }
return 0; return SFNT_Err_Ok;
} }

View File

@ -4,7 +4,7 @@
/* */ /* */
/* TrueType character mapping table (cmap) support (specification). */ /* TrueType character mapping table (cmap) support (specification). */
/* */ /* */
/* Copyright 2002, 2003, 2004 by */ /* Copyright 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -31,6 +31,7 @@ FT_BEGIN_HEADER
{ {
FT_CMapRec cmap; FT_CMapRec cmap;
FT_Byte* data; /* pointer to in-memory cmap table */ FT_Byte* data; /* pointer to in-memory cmap table */
FT_Bool unsorted; /* for format 4 only */
} TT_CMapRec, *TT_CMap; } TT_CMapRec, *TT_CMap;

View File

@ -134,22 +134,22 @@
} }
/* In theory, we should check the values of `search_range', */ /* In theory, we should check the values of `search_range', */
/* `entry_selector', and `range_shift' to detect non-SFNT based files */ /* `entry_selector', and `range_shift' to detect non-SFNT based files */
/* whose header might also start with 0x100000L (yes, these exist). */ /* whose header might also start with 0x100000L (yes, these exist). */
/* */ /* */
/* Very unfortunately, many TrueType fonts don't have these fields */ /* Very unfortunately, many TrueType fonts don't have these fields */
/* set correctly and we must ignore them to support them. An alternative */ /* set correctly and we must ignore them to support them. An */
/* way to check the font file is thus to: */ /* alternative way to check the font file is thus to: */
/* */ /* */
/* - check that `num_tables' is valid */ /* - check that `num_tables' is valid */
/* - look for a "head" table, check its size, and parse it to */ /* - look for a "head" table, check its size, and parse it to */
/* see if its "magic" field is correctly set */ /* see if its "magic" field is correctly set */
/* */ /* */
/* When checking directory entries, ignore the tables `glyx' and `locx' */ /* When checking directory entries, ignore the tables `glyx' and `locx' */
/* which are hacked-out versions of `glyf' and `loca' in some PostScript */ /* which are hacked-out versions of `glyf' and `loca' in some PostScript */
/* Type 42 fonts, and will generally be invalid. */ /* Type 42 fonts, and will generally be invalid. */
/* */ /* */
static FT_Error static FT_Error
sfnt_dir_check( FT_Stream stream, sfnt_dir_check( FT_Stream stream,
FT_ULong offset, FT_ULong offset,
@ -239,7 +239,7 @@
goto Bad_Format; goto Bad_Format;
Exit: Exit:
return error; return error;
Bad_Format: Bad_Format:
error = SFNT_Err_Unknown_File_Format; error = SFNT_Err_Unknown_File_Format;

View File

@ -4,7 +4,7 @@
/* */ /* */
/* TrueType GX Font Variation loader */ /* TrueType GX Font Variation loader */
/* */ /* */
/* Copyright 2004 by */ /* Copyright 2004, 2005 by */
/* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ /* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -92,7 +92,7 @@
/* indicates that there is a delta for every point without needing to */ /* indicates that there is a delta for every point without needing to */
/* enumerate all of them. */ /* enumerate all of them. */
/* */ /* */
#define ALL_POINTS (FT_UShort*)(-1) #define ALL_POINTS (FT_UShort*)( -1 )
enum enum
@ -1209,7 +1209,7 @@
} }
apply = ft_var_apply_tuple( blend, apply = ft_var_apply_tuple( blend,
(FT_UShort) tupleIndex, (FT_UShort)tupleIndex,
tuple_coords, tuple_coords,
im_start_coords, im_start_coords,
im_end_coords ); im_end_coords );
@ -1238,8 +1238,8 @@
{ {
/* this means that there are deltas for every entry in cvt */ /* this means that there are deltas for every entry in cvt */
for ( j = 0; j < face->cvt_size; ++j ) for ( j = 0; j < face->cvt_size; ++j )
face->cvt[j] = (FT_Short)( face->cvt[j] + FT_MulFix( deltas[j], face->cvt[j] = (FT_Short)( face->cvt[j] +
apply ) ); FT_MulFix( deltas[j], apply ) );
} }
else else
@ -1404,7 +1404,7 @@
} }
apply = ft_var_apply_tuple( blend, apply = ft_var_apply_tuple( blend,
(FT_UShort) tupleIndex, (FT_UShort)tupleIndex,
tuple_coords, tuple_coords,
im_start_coords, im_start_coords,
im_end_coords ); im_end_coords );