ref: ca98f8cc2b091a7d2ab3782d944491dc0939acf0
parent: 8566d4a096d5229354d826e52c7ec89e7436ec3c
author: Werner Lemberg <[email protected]>
date: Sat Apr 4 03:42:38 EDT 2009
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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2009-04-04 Werner Lemberg <[email protected]>
+
+ 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 <[email protected]>
Ignore empty contours in CFF glyphs.
--- a/devel/ftoption.h
+++ b/devel/ftoption.h
@@ -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 @@
#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
--- a/docs/CHANGES
+++ b/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
--- a/include/freetype/config/ftoption.h
+++ b/include/freetype/config/ftoption.h
@@ -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 @@
#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
--- a/src/sfnt/ttcmap.c
+++ b/src/sfnt/ttcmap.c
@@ -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;
@@ -2296,6 +2296,325 @@
/*************************************************************************/
/*************************************************************************/
/***** *****/
+ /***** 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 */
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
/***** FORMAT 14 *****/
/***** *****/
/*************************************************************************/
@@ -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;
@@ -3060,6 +3379,10 @@
#ifdef TT_CONFIG_CMAP_FORMAT_12
&tt_cmap12_class_rec,
+#endif
+
+#ifdef TT_CONFIG_CMAP_FORMAT_13
+ &tt_cmap13_class_rec,
#endif
#ifdef TT_CONFIG_CMAP_FORMAT_14