Add support for cmap type 13.
* devel/ftoption.h, include/freetype/config/ftoption.h (TT_CONFIG_CMAP_FORMAT_13): New macro. * src/sfnt/ttcmap.c (TT_CMap13Rec, tt_cmap13_init, tt_cmap13_validate, tt_cmap13_char_index, tt_cmap13_char_next, tt_cmap13_get_info, tt_cmap13_char_map_def_binary, tt_cmap14_class_rec): New functions and structures for cmap 13 support. (tt_cmap_classes): Register tt_cmap13_class_rec. * docs/CHANGES: Mention cmap 13 support.
This commit is contained in:
parent
8566d4a096
commit
ca98f8cc2b
16
ChangeLog
16
ChangeLog
@ -1,3 +1,19 @@
|
||||
2009-04-04 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
Add support for cmap type 13.
|
||||
|
||||
* devel/ftoption.h, include/freetype/config/ftoption.h
|
||||
(TT_CONFIG_CMAP_FORMAT_13): New macro.
|
||||
|
||||
* src/sfnt/ttcmap.c (TT_CMap13Rec, tt_cmap13_init,
|
||||
tt_cmap13_validate, tt_cmap13_char_index, tt_cmap13_char_next,
|
||||
tt_cmap13_get_info, tt_cmap13_char_map_def_binary,
|
||||
tt_cmap14_class_rec): New functions and structures for cmap 13
|
||||
support.
|
||||
(tt_cmap_classes): Register tt_cmap13_class_rec.
|
||||
|
||||
* docs/CHANGES: Mention cmap 13 support.
|
||||
|
||||
2009-04-01 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
Ignore empty contours in CFF glyphs.
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* User-selectable configuration macros (specification only). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -457,6 +457,7 @@ FT_BEGIN_HEADER
|
||||
#define TT_CONFIG_CMAP_FORMAT_8
|
||||
#define TT_CONFIG_CMAP_FORMAT_10
|
||||
#define TT_CONFIG_CMAP_FORMAT_12
|
||||
#define TT_CONFIG_CMAP_FORMAT_13
|
||||
#define TT_CONFIG_CMAP_FORMAT_14
|
||||
|
||||
|
||||
|
10
docs/CHANGES
10
docs/CHANGES
@ -1,3 +1,13 @@
|
||||
CHANGES BETWEEN 2.3.10 and 2.3.9
|
||||
|
||||
I. IMPORTANT CHANGES
|
||||
|
||||
- Support for the SFNT cmap 13 table format (as defined by the new
|
||||
OpenType 1.6 specification) has been added.
|
||||
|
||||
|
||||
======================================================================
|
||||
|
||||
CHANGES BETWEEN 2.3.9 and 2.3.8
|
||||
|
||||
I. IMPORTANT BUG FIXES
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* User-selectable configuration macros (specification only). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -457,6 +457,7 @@ FT_BEGIN_HEADER
|
||||
#define TT_CONFIG_CMAP_FORMAT_8
|
||||
#define TT_CONFIG_CMAP_FORMAT_10
|
||||
#define TT_CONFIG_CMAP_FORMAT_12
|
||||
#define TT_CONFIG_CMAP_FORMAT_13
|
||||
#define TT_CONFIG_CMAP_FORMAT_14
|
||||
|
||||
|
||||
|
@ -157,7 +157,7 @@
|
||||
FT_Byte* p = cmap->data + 4;
|
||||
|
||||
|
||||
cmap_info->format = 0;
|
||||
cmap_info->format = 0;
|
||||
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
|
||||
|
||||
return SFNT_Err_Ok;
|
||||
@ -536,7 +536,7 @@
|
||||
FT_Byte* p = cmap->data + 4;
|
||||
|
||||
|
||||
cmap_info->format = 2;
|
||||
cmap_info->format = 2;
|
||||
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
|
||||
|
||||
return SFNT_Err_Ok;
|
||||
@ -1375,7 +1375,7 @@
|
||||
FT_Byte* p = cmap->data + 4;
|
||||
|
||||
|
||||
cmap_info->format = 4;
|
||||
cmap_info->format = 4;
|
||||
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
|
||||
|
||||
return SFNT_Err_Ok;
|
||||
@ -1537,7 +1537,7 @@
|
||||
FT_Byte* p = cmap->data + 4;
|
||||
|
||||
|
||||
cmap_info->format = 6;
|
||||
cmap_info->format = 6;
|
||||
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
|
||||
|
||||
return SFNT_Err_Ok;
|
||||
@ -1793,7 +1793,7 @@
|
||||
FT_Byte* p = cmap->data + 8;
|
||||
|
||||
|
||||
cmap_info->format = 8;
|
||||
cmap_info->format = 8;
|
||||
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
|
||||
|
||||
return SFNT_Err_Ok;
|
||||
@ -1945,7 +1945,7 @@
|
||||
FT_Byte* p = cmap->data + 8;
|
||||
|
||||
|
||||
cmap_info->format = 10;
|
||||
cmap_info->format = 10;
|
||||
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
|
||||
|
||||
return SFNT_Err_Ok;
|
||||
@ -2265,7 +2265,7 @@
|
||||
FT_Byte* p = cmap->data + 8;
|
||||
|
||||
|
||||
cmap_info->format = 12;
|
||||
cmap_info->format = 12;
|
||||
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
|
||||
|
||||
return SFNT_Err_Ok;
|
||||
@ -2293,6 +2293,325 @@
|
||||
#endif /* TT_CONFIG_CMAP_FORMAT_12 */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** FORMAT 13 *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* TABLE OVERVIEW */
|
||||
/* -------------- */
|
||||
/* */
|
||||
/* NAME OFFSET TYPE DESCRIPTION */
|
||||
/* */
|
||||
/* format 0 USHORT must be 13 */
|
||||
/* reserved 2 USHORT reserved */
|
||||
/* length 4 ULONG length in bytes */
|
||||
/* language 8 ULONG Mac language code */
|
||||
/* count 12 ULONG number of groups */
|
||||
/* 16 */
|
||||
/* */
|
||||
/* This header is followed by `count' groups of the following format: */
|
||||
/* */
|
||||
/* start 0 ULONG first charcode */
|
||||
/* end 4 ULONG last charcode */
|
||||
/* glyphId 8 ULONG glyph ID for the whole group */
|
||||
/* */
|
||||
|
||||
#ifdef TT_CONFIG_CMAP_FORMAT_13
|
||||
|
||||
typedef struct TT_CMap13Rec_
|
||||
{
|
||||
TT_CMapRec cmap;
|
||||
FT_Bool valid;
|
||||
FT_ULong cur_charcode;
|
||||
FT_UInt cur_gindex;
|
||||
FT_ULong cur_group;
|
||||
FT_ULong num_groups;
|
||||
|
||||
} TT_CMap13Rec, *TT_CMap13;
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
tt_cmap13_init( TT_CMap13 cmap,
|
||||
FT_Byte* table )
|
||||
{
|
||||
cmap->cmap.data = table;
|
||||
|
||||
table += 12;
|
||||
cmap->num_groups = FT_PEEK_ULONG( table );
|
||||
|
||||
cmap->valid = 0;
|
||||
|
||||
return SFNT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
tt_cmap13_validate( FT_Byte* table,
|
||||
FT_Validator valid )
|
||||
{
|
||||
FT_Byte* p;
|
||||
FT_ULong length;
|
||||
FT_ULong num_groups;
|
||||
|
||||
|
||||
if ( table + 16 > valid->limit )
|
||||
FT_INVALID_TOO_SHORT;
|
||||
|
||||
p = table + 4;
|
||||
length = TT_NEXT_ULONG( p );
|
||||
|
||||
p = table + 12;
|
||||
num_groups = TT_NEXT_ULONG( p );
|
||||
|
||||
if ( length > (FT_ULong)( valid->limit - table ) ||
|
||||
length < 16 + 12 * num_groups )
|
||||
FT_INVALID_TOO_SHORT;
|
||||
|
||||
/* check groups, they must be in increasing order */
|
||||
{
|
||||
FT_ULong n, start, end, glyph_id, last = 0;
|
||||
|
||||
|
||||
for ( n = 0; n < num_groups; n++ )
|
||||
{
|
||||
start = TT_NEXT_ULONG( p );
|
||||
end = TT_NEXT_ULONG( p );
|
||||
glyph_id = TT_NEXT_ULONG( p );
|
||||
|
||||
if ( start > end )
|
||||
FT_INVALID_DATA;
|
||||
|
||||
if ( n > 0 && start <= last )
|
||||
FT_INVALID_DATA;
|
||||
|
||||
if ( valid->level >= FT_VALIDATE_TIGHT )
|
||||
{
|
||||
if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) )
|
||||
FT_INVALID_GLYPH_ID;
|
||||
}
|
||||
|
||||
last = end;
|
||||
}
|
||||
}
|
||||
|
||||
return SFNT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/* search the index of the charcode next to cmap->cur_charcode */
|
||||
/* cmap->cur_group should be set up properly by caller */
|
||||
/* */
|
||||
static void
|
||||
tt_cmap13_next( TT_CMap13 cmap )
|
||||
{
|
||||
FT_Byte* p;
|
||||
FT_ULong start, end, glyph_id, char_code;
|
||||
FT_ULong n;
|
||||
FT_UInt gindex;
|
||||
|
||||
|
||||
if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
|
||||
goto Fail;
|
||||
|
||||
char_code = cmap->cur_charcode + 1;
|
||||
|
||||
n = cmap->cur_group;
|
||||
|
||||
for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
|
||||
{
|
||||
p = cmap->cmap.data + 16 + 12 * n;
|
||||
start = TT_NEXT_ULONG( p );
|
||||
end = TT_NEXT_ULONG( p );
|
||||
glyph_id = TT_PEEK_ULONG( p );
|
||||
|
||||
if ( char_code < start )
|
||||
char_code = start;
|
||||
|
||||
if ( char_code <= end )
|
||||
{
|
||||
gindex = (FT_UInt)glyph_id;
|
||||
|
||||
if ( gindex )
|
||||
{
|
||||
cmap->cur_charcode = char_code;;
|
||||
cmap->cur_gindex = gindex;
|
||||
cmap->cur_group = n;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Fail:
|
||||
cmap->valid = 0;
|
||||
}
|
||||
|
||||
|
||||
static FT_UInt
|
||||
tt_cmap13_char_map_binary( TT_CMap cmap,
|
||||
FT_UInt32* pchar_code,
|
||||
FT_Bool next )
|
||||
{
|
||||
FT_UInt gindex = 0;
|
||||
FT_Byte* p = cmap->data + 12;
|
||||
FT_UInt32 num_groups = TT_PEEK_ULONG( p );
|
||||
FT_UInt32 char_code = *pchar_code;
|
||||
FT_UInt32 start, end;
|
||||
FT_UInt32 max, min, mid;
|
||||
|
||||
|
||||
if ( !num_groups )
|
||||
return 0;
|
||||
|
||||
/* make compiler happy */
|
||||
mid = num_groups;
|
||||
end = 0xFFFFFFFFUL;
|
||||
|
||||
if ( next )
|
||||
char_code++;
|
||||
|
||||
min = 0;
|
||||
max = num_groups;
|
||||
|
||||
/* binary search */
|
||||
while ( min < max )
|
||||
{
|
||||
mid = ( min + max ) >> 1;
|
||||
p = cmap->data + 16 + 12 * mid;
|
||||
|
||||
start = TT_NEXT_ULONG( p );
|
||||
end = TT_NEXT_ULONG( p );
|
||||
|
||||
if ( char_code < start )
|
||||
max = mid;
|
||||
else if ( char_code > end )
|
||||
min = mid + 1;
|
||||
else
|
||||
{
|
||||
gindex = (FT_UInt)TT_PEEK_ULONG( p );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( next )
|
||||
{
|
||||
TT_CMap13 cmap13 = (TT_CMap13)cmap;
|
||||
|
||||
|
||||
/* if `char_code' is not in any group, then `mid' is */
|
||||
/* the group nearest to `char_code' */
|
||||
/* */
|
||||
|
||||
if ( char_code > end )
|
||||
{
|
||||
mid++;
|
||||
if ( mid == num_groups )
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmap13->valid = 1;
|
||||
cmap13->cur_charcode = char_code;
|
||||
cmap13->cur_group = mid;
|
||||
|
||||
if ( !gindex )
|
||||
{
|
||||
tt_cmap13_next( cmap13 );
|
||||
|
||||
if ( cmap13->valid )
|
||||
gindex = cmap13->cur_gindex;
|
||||
}
|
||||
else
|
||||
cmap13->cur_gindex = gindex;
|
||||
|
||||
if ( gindex )
|
||||
*pchar_code = cmap13->cur_charcode;
|
||||
}
|
||||
|
||||
return gindex;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_UInt )
|
||||
tt_cmap13_char_index( TT_CMap cmap,
|
||||
FT_UInt32 char_code )
|
||||
{
|
||||
return tt_cmap13_char_map_binary( cmap, &char_code, 0 );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_UInt )
|
||||
tt_cmap13_char_next( TT_CMap cmap,
|
||||
FT_UInt32 *pchar_code )
|
||||
{
|
||||
TT_CMap13 cmap13 = (TT_CMap13)cmap;
|
||||
FT_ULong gindex;
|
||||
|
||||
|
||||
if ( cmap13->cur_charcode >= 0xFFFFFFFFUL )
|
||||
return 0;
|
||||
|
||||
/* no need to search */
|
||||
if ( cmap13->valid && cmap13->cur_charcode == *pchar_code )
|
||||
{
|
||||
tt_cmap13_next( cmap13 );
|
||||
if ( cmap13->valid )
|
||||
{
|
||||
gindex = cmap13->cur_gindex;
|
||||
if ( gindex )
|
||||
*pchar_code = cmap13->cur_charcode;
|
||||
}
|
||||
else
|
||||
gindex = 0;
|
||||
}
|
||||
else
|
||||
gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 );
|
||||
|
||||
return gindex;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
tt_cmap13_get_info( TT_CMap cmap,
|
||||
TT_CMapInfo *cmap_info )
|
||||
{
|
||||
FT_Byte* p = cmap->data + 8;
|
||||
|
||||
|
||||
cmap_info->format = 13;
|
||||
cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
|
||||
|
||||
return SFNT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE_DEF
|
||||
const TT_CMap_ClassRec tt_cmap13_class_rec =
|
||||
{
|
||||
{
|
||||
sizeof ( TT_CMap13Rec ),
|
||||
|
||||
(FT_CMap_InitFunc) tt_cmap13_init,
|
||||
(FT_CMap_DoneFunc) NULL,
|
||||
(FT_CMap_CharIndexFunc)tt_cmap13_char_index,
|
||||
(FT_CMap_CharNextFunc) tt_cmap13_char_next,
|
||||
|
||||
NULL, NULL, NULL, NULL, NULL
|
||||
},
|
||||
13,
|
||||
(TT_CMap_ValidateFunc) tt_cmap13_validate,
|
||||
(TT_CMap_Info_GetFunc) tt_cmap13_get_info
|
||||
};
|
||||
|
||||
#endif /* TT_CONFIG_CMAP_FORMAT_13 */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
@ -2553,7 +2872,7 @@
|
||||
{
|
||||
FT_UNUSED( cmap );
|
||||
|
||||
cmap_info->format = 14;
|
||||
cmap_info->format = 14;
|
||||
/* subtable 14 does not define a language field */
|
||||
cmap_info->language = 0xFFFFFFFFUL;
|
||||
|
||||
@ -3062,6 +3381,10 @@
|
||||
&tt_cmap12_class_rec,
|
||||
#endif
|
||||
|
||||
#ifdef TT_CONFIG_CMAP_FORMAT_13
|
||||
&tt_cmap13_class_rec,
|
||||
#endif
|
||||
|
||||
#ifdef TT_CONFIG_CMAP_FORMAT_14
|
||||
&tt_cmap14_class_rec,
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user