ref: 9a966b7d1bbc9e35eddb68136b73cbe006dff675
parent: cc272c51667fb0a286bf9b8e46096f74f50aa335
author: Werner Lemberg <[email protected]>
date: Mon Oct 15 13:21:32 EDT 2007
Add support for cmap type 14. * devel/ftoption.h, include/freetype/config/ftoption.h (TT_CONFIG_CMAP_FORMAT_14): New macro. * include/freetype/internal/ftobjs.h (FT_CMap_CharVarIndexFunc, FT_CMap_CharVarIsDefaultFunc, FT_CMap_VariantListFunc, FT_CMap_CharVariantListFunc, FT_CMap_VariantCharListFunc): New support function prototypes. (FT_CMap_ClassRec): Add them. Update all users. * include/freetype/ttnameid.h (TT_APPLE_ID_VARIANT_SELECTOR): New macro. * include/freetype/freetype.h (FT_Get_Char_Variant_Index, FT_Get_Char_Variant_IsDefault, FT_Get_Variant_Selectors, FT_Get_Variants_Of_Char, FT_Get_Chars_Of_Variant): New API functions. * src/base/ftobjs.c (find_variant_selector_charmap): New auxiliary function. (FT_Set_Charmap): Disallow cmaps of type 14. (FT_Get_Char_Variant_Index, FT_Get_Char_Variant_IsDefault, FT_Get_Variant_Selectors, FT_Get_Variants_Of_Char, FT_Get_Chars_Of_Variant): New API functions. * src/sfnt/ttcmap.c (TT_PEEK_UINT24, TT_NEXT_UINT24): New macros. (TT_CMap14Rec, tt_cmap14_init, tt_cmap14_validate, tt_cmap14_char_index, tt_cmap14_char_next, tt_cmap14_get_info, tt_cmap14_char_map_def_binary, tt_cmap14_char_map_nondef_binary, tt_cmap14_find_variant, tt_cmap14_char_var_index, tt_cmap14_char_var_isdefault, tt_cmap14_variants, tt_cmap14_char_variants, tt_cmap14_def_char_count, tt_cmap14_get_def_chars, tt_cmap14_get_nondef_chars, tt_cmap14_variant_chars, tt_cmap14_class_rec): New functions and structures for cmap 14 support. (tt_cmap_classes): Register tt_cmap14_class_rec. (tt_face_build_cmaps): One more error message. * docs/CHANGES: Mention cmap 14 support.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,48 @@
+2007-10-15 George Williams <[email protected]>
+
+ Add support for cmap type 14.
+
+ * devel/ftoption.h, include/freetype/config/ftoption.h
+ (TT_CONFIG_CMAP_FORMAT_14): New macro.
+
+ * include/freetype/internal/ftobjs.h (FT_CMap_CharVarIndexFunc,
+ FT_CMap_CharVarIsDefaultFunc, FT_CMap_VariantListFunc,
+ FT_CMap_CharVariantListFunc, FT_CMap_VariantCharListFunc): New
+ support function prototypes.
+ (FT_CMap_ClassRec): Add them.
+ Update all users.
+
+ * include/freetype/ttnameid.h (TT_APPLE_ID_VARIANT_SELECTOR): New
+ macro.
+
+ * include/freetype/freetype.h (FT_Get_Char_Variant_Index,
+ FT_Get_Char_Variant_IsDefault, FT_Get_Variant_Selectors,
+ FT_Get_Variants_Of_Char, FT_Get_Chars_Of_Variant): New API
+ functions.
+
+ * src/base/ftobjs.c (find_variant_selector_charmap): New auxiliary
+ function.
+ (FT_Set_Charmap): Disallow cmaps of type 14.
+ (FT_Get_Char_Variant_Index, FT_Get_Char_Variant_IsDefault,
+ FT_Get_Variant_Selectors, FT_Get_Variants_Of_Char,
+ FT_Get_Chars_Of_Variant): New API functions.
+
+ * src/sfnt/ttcmap.c (TT_PEEK_UINT24, TT_NEXT_UINT24): New macros.
+
+ (TT_CMap14Rec, tt_cmap14_init, tt_cmap14_validate,
+ tt_cmap14_char_index, tt_cmap14_char_next, tt_cmap14_get_info,
+ tt_cmap14_char_map_def_binary, tt_cmap14_char_map_nondef_binary,
+ tt_cmap14_find_variant, tt_cmap14_char_var_index,
+ tt_cmap14_char_var_isdefault, tt_cmap14_variants,
+ tt_cmap14_char_variants, tt_cmap14_def_char_count,
+ tt_cmap14_get_def_chars, tt_cmap14_get_nondef_chars,
+ tt_cmap14_variant_chars, tt_cmap14_class_rec): New functions and
+ structures for cmap 14 support.
+ (tt_cmap_classes): Register tt_cmap14_class_rec.
+ (tt_face_build_cmaps): One more error message.
+
+ * docs/CHANGES: Mention cmap 14 support.
+
2007-10-01 Werner Lemberg <[email protected]>
* src/base/ftobjs.c (find_unicode_charmap): If search for a UCS-4
@@ -6,10 +51,10 @@
2007-08-29 suzuki toshiya <[email protected]>
- * src/base/ftmac.c: Introduction of abstract "short" data types,
- ResFileRefNum and ResID. These types were introduced for Copland,
- then backported to MPW. The variables exchanged with FileManager
- QuickDraw frameworks are redefined by these data types. Patch was
+ * src/base/ftmac.c: Introduction of abstract `short' data types,
+ ResFileRefNum and ResID. These types were introduced for Copland,
+ then backported to MPW. The variables exchanged with FileManager
+ QuickDraw frameworks are redefined by these data types. Patch was
proposed by Sean McBride.
* builds/mac/ftmac.c: Ditto.
--- a/devel/ftoption.h
+++ b/devel/ftoption.h
@@ -436,6 +436,7 @@
#define TT_CONFIG_CMAP_FORMAT_8
#define TT_CONFIG_CMAP_FORMAT_10
#define TT_CONFIG_CMAP_FORMAT_12
+#define TT_CONFIG_CMAP_FORMAT_14
/*************************************************************************/
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -1,6 +1,16 @@
CHANGES BETWEEN 2.3.6 and 2.3.5
+ I. IMPORTANT BUG FIXES
+
+ - Microsoft Unicode cmaps in TrueType fonts are now always
+ preferred over Apple cmaps. This is not a bug per se, but there
+ exist some buggy fonts created for MS which have broken Apple
+ cmaps. This affects only the automatic selection of FreeType;
+ it's always possible to manually select an Apple Unicode cmap if
+ desired.
+
+
II. IMPORTANT CHANGES
- The new function `FT_Get_CID_Registry_Ordering_Supplement' gives
@@ -10,6 +20,9 @@
- George Williams contributed code to validate the new `MATH'
OpenType table (within the `otvalid' module). The `ftvalid'
demo program has been extended accordingly.
+
+ - An API for cmap 14 support (for Unicode Variant Selectors, UVS)
+ has been contributed by George Williams.
======================================================================
--- a/include/freetype/config/ftoption.h
+++ b/include/freetype/config/ftoption.h
@@ -436,6 +436,7 @@
#define TT_CONFIG_CMAP_FORMAT_8
#define TT_CONFIG_CMAP_FORMAT_10
#define TT_CONFIG_CMAP_FORMAT_12
+#define TT_CONFIG_CMAP_FORMAT_14
/*************************************************************************/
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -2852,6 +2852,8 @@
/* the face (i.e., if it is not listed in the `face->charmaps' */
/* table). */
/* */
+ /* It also fails if a type 14 charmap is selected. */
+ /* */
FT_EXPORT( FT_Error )
FT_Set_Charmap( FT_Face face,
FT_CharMap charmap );
@@ -2988,6 +2990,162 @@
FT_Get_Next_Char( FT_Face face,
FT_ULong char_code,
FT_UInt *agindex );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Char_Variant_Index */
+ /* */
+ /* <Description> */
+ /* Return the glyph index of a given character code as modified by */
+ /* the variation selector. */
+ /* */
+ /* <Input> */
+ /* face :: */
+ /* A handle to the source face object. */
+ /* */
+ /* charcode :: */
+ /* The character code point in Unicode. */
+ /* */
+ /* variantSelector :: */
+ /* The Unicode code point of the variation selector. */
+ /* */
+ /* <Return> */
+ /* The glyph index. 0 means either `undefined character code', or */
+ /* `undefined selector code', or `no variation selector cmap */
+ /* subtable', or `current CharMap is not Unicode'. */
+ /* */
+ /* <Note> */
+ /* If you use FreeType to manipulate the contents of font files */
+ /* directly, be aware that the glyph index returned by this function */
+ /* doesn't always correspond to the internal indices used within */
+ /* the file. This is done to ensure that value 0 always corresponds */
+ /* to the `missing glyph'. */
+ /* */
+ /* <Note> */
+ /* This function is only meaningful if: */
+ /* a) the font has a variation selector cmap sub table */
+ /* b) the current charmap has a Unicode encoding */
+ /* */
+ FT_EXPORT( FT_UInt )
+ FT_Get_Char_Variant_Index( FT_Face face,
+ FT_ULong charcode,
+ FT_ULong variantSelector );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Char_Variant_IsDefault */
+ /* */
+ /* <Description> */
+ /* Check whether this variant of this Unicode character is the one to */
+ /* be found in the `cmap'. */
+ /* */
+ /* <Input> */
+ /* face :: */
+ /* A handle to the source face object. */
+ /* */
+ /* charcode :: */
+ /* The character codepoint in Unicode. */
+ /* */
+ /* variantSelector :: */
+ /* The Unicode codepoint of the variation selector. */
+ /* */
+ /* <Return> */
+ /* 1 if found in the standard (Unicode) cmap, 0 if found in the */
+ /* variation selector cmap, or -1 if it is not a variant. */
+ /* */
+ /* <Note> */
+ /* This function is only meaningful if the font has a variation */
+ /* selector cmap subtable. */
+ /* */
+ FT_EXPORT( FT_Int )
+ FT_Get_Char_Variant_IsDefault( FT_Face face,
+ FT_ULong charcode,
+ FT_ULong variantSelector );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Variant_Selectors */
+ /* */
+ /* <Description> */
+ /* Return a zero-terminated list of Unicode variant selectors found */
+ /* in the font. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the source face object. */
+ /* */
+ /* <Return> */
+ /* A list of all the variant selector code points in the cmap */
+ /* or NULL if there is no valid variant selector cmap subtable. */
+ /* */
+ /* <Note> */
+ /* User is responsible for deallocating the returned list. */
+ /* */
+ FT_EXPORT( FT_UInt32* )
+ FT_Get_Variant_Selectors( FT_Face face );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Variants_Of_Char */
+ /* */
+ /* <Description> */
+ /* Return a zero-terminated list of Unicode variant selectors found */
+ /* for the specified character code. */
+ /* */
+ /* <Input> */
+ /* face :: */
+ /* A handle to the source face object. */
+ /* */
+ /* charcode :: */
+ /* The character codepoint in Unicode. */
+ /* */
+ /* <Return> */
+ /* A list of all the variant selector code points which are active */
+ /* for the given character or NULL if there is no valid variant */
+ /* selector cmap subtable (or if if this character has no variants). */
+ /* */
+ /* <Note> */
+ /* User is responsible for deallocating the returned list. */
+ /* */
+ FT_EXPORT( FT_UInt32* )
+ FT_Get_Variants_Of_Char( FT_Face face,
+ FT_ULong charcode );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Chars_Of_Variant */
+ /* */
+ /* <Description> */
+ /* Return a zero-terminated list of Unicode character codes found for */
+ /* the specified variant selector. */
+ /* */
+ /* <Input> */
+ /* face :: */
+ /* A handle to the source face object. */
+ /* */
+ /* variantSelector :: */
+ /* The variant selector code point in Unicode. */
+ /* */
+ /* <Return> */
+ /* A list of all the code points which are specified by this selector */
+ /* (both default and non-default codes are returned) or NULL if there */
+ /* is no valid cmap or the variant selector is invalid. */
+ /* */
+ /* <Note> */
+ /* User is responsible for deallocating the returned list. */
+ /* */
+ FT_EXPORT( FT_UInt32* )
+ FT_Get_Chars_Of_Variant( FT_Face face,
+ FT_ULong variantSelector );
/*************************************************************************/
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -160,7 +160,32 @@
(*FT_CMap_CharNextFunc)( FT_CMap cmap,
FT_UInt32 *achar_code );
+ typedef FT_UInt
+ (*FT_CMap_CharVarIndexFunc)( FT_CMap cmap,
+ FT_CMap unicode_cmap,
+ FT_UInt32 char_code,
+ FT_UInt32 variant_selector );
+ typedef FT_Bool
+ (*FT_CMap_CharVarIsDefaultFunc)( FT_CMap cmap,
+ FT_UInt32 char_code,
+ FT_UInt32 variant_selector );
+
+ typedef FT_UInt32 *
+ (*FT_CMap_VariantListFunc)( FT_CMap cmap,
+ FT_Memory mem );
+
+ typedef FT_UInt32 *
+ (*FT_CMap_CharVariantListFunc)( FT_CMap cmap,
+ FT_Memory mem,
+ FT_UInt32 char_code );
+
+ typedef FT_UInt32 *
+ (*FT_CMap_VariantCharListFunc)( FT_CMap cmap,
+ FT_Memory mem,
+ FT_UInt32 variant_selector );
+
+
typedef struct FT_CMap_ClassRec_
{
FT_ULong size;
@@ -168,6 +193,15 @@
FT_CMap_DoneFunc done;
FT_CMap_CharIndexFunc char_index;
FT_CMap_CharNextFunc char_next;
+
+ /* Subsequent entries are special ones for format 14 -- the variant */
+ /* selector subtable which behaves like no other */
+
+ FT_CMap_CharVarIndexFunc char_var_index;
+ FT_CMap_CharVarIsDefaultFunc char_var_default;
+ FT_CMap_VariantListFunc variant_list;
+ FT_CMap_CharVariantListFunc charvariant_list;
+ FT_CMap_VariantCharListFunc variantchar_list;
} FT_CMap_ClassRec;
--- a/include/freetype/ttnameid.h
+++ b/include/freetype/ttnameid.h
@@ -108,13 +108,18 @@
*
* TT_APPLE_ID_UNICODE_32 ::
* Unicode 3.1 and beyond, using UTF-32.
+ *
+ * TT_APPLE_ID_VARIANT_SELECTOR ::
+ * From Adobe, not Apple. Not a normal cmap. Specifies variations
+ * on a real cmap.
*/
-#define TT_APPLE_ID_DEFAULT 0 /* Unicode 1.0 */
-#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */
-#define TT_APPLE_ID_ISO_10646 2 /* deprecated */
-#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */
-#define TT_APPLE_ID_UNICODE_32 4 /* 2.0 or later, full repertoire */
+#define TT_APPLE_ID_DEFAULT 0 /* Unicode 1.0 */
+#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */
+#define TT_APPLE_ID_ISO_10646 2 /* deprecated */
+#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */
+#define TT_APPLE_ID_UNICODE_32 4 /* 2.0 or later, full repertoire */
+#define TT_APPLE_ID_VARIANT_SELECTOR 5 /* variation selector data */
/***********************************************************************
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -967,6 +967,45 @@
/*************************************************************************/
/* */
/* <Function> */
+ /* find_variant_selector_charmap */
+ /* */
+ /* <Description> */
+ /* This function finds the variant selector charmap, if there is one. */
+ /* There can only be one (platform=0, specific=5, format=14). */
+ /* */
+ static FT_CharMap
+ find_variant_selector_charmap( FT_Face face )
+ {
+ FT_CharMap* first;
+ FT_CharMap* end;
+ FT_CharMap* cur;
+
+
+ /* caller should have already checked that `face' is valid */
+ FT_ASSERT( face );
+
+ first = face->charmaps;
+
+ if ( !first )
+ return NULL;
+
+ end = first + face->num_charmaps; /* points after the last one */
+
+ for ( cur = first; cur < end; ++cur )
+ {
+ if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE &&
+ cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR &&
+ FT_Get_CMap_Format( cur[0] ) == 14 )
+ return cur[0];
+ }
+
+ return NULL;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
/* open_face */
/* */
/* <Description> */
@@ -2631,6 +2670,8 @@
cur = face->charmaps;
if ( !cur )
return FT_Err_Invalid_CharMap_Handle;
+ if ( FT_Get_CMap_Format( charmap ) == 14 )
+ return FT_Err_Invalid_Argument;
limit = cur + face->num_charmaps;
@@ -2844,6 +2885,149 @@
if ( agindex )
*agindex = gindex;
+
+ return result;
+ }
+
+
+ /* documentation is in freetype.h */
+
+ FT_EXPORT_DEF( FT_UInt )
+ FT_Get_Char_Variant_Index( FT_Face face,
+ FT_ULong charcode,
+ FT_ULong variantSelector )
+ {
+ FT_UInt result = 0;
+
+
+ if ( face && face->charmap &&
+ face->charmap->encoding == FT_ENCODING_UNICODE )
+ {
+ FT_CharMap charmap = find_variant_selector_charmap( face );
+ FT_CMap ucmap = FT_CMAP( face->charmap );
+
+
+ if ( charmap != NULL )
+ {
+ FT_CMap vcmap = FT_CMAP( charmap );
+
+
+ result = vcmap->clazz->char_var_index( vcmap, ucmap, charcode,
+ variantSelector );
+ }
+ }
+
+ return result;
+ }
+
+
+ /* documentation is in freetype.h */
+
+ FT_EXPORT_DEF( FT_Int )
+ FT_Get_Char_Variant_IsDefault( FT_Face face,
+ FT_ULong charcode,
+ FT_ULong variantSelector )
+ {
+ FT_Int result = -1;
+
+
+ if ( face )
+ {
+ FT_CharMap charmap = find_variant_selector_charmap( face );
+
+
+ if ( charmap != NULL )
+ {
+ FT_CMap vcmap = FT_CMAP( charmap );
+
+
+ result = vcmap->clazz->char_var_default( vcmap, charcode,
+ variantSelector );
+ }
+ }
+
+ return result;
+ }
+
+
+ /* documentation is in freetype.h */
+
+ FT_EXPORT_DEF( FT_UInt32* )
+ FT_Get_Variant_Selectors( FT_Face face )
+ {
+ FT_UInt32 *result = NULL;
+
+
+ if ( face )
+ {
+ FT_CharMap charmap = find_variant_selector_charmap( face );
+
+
+ if ( charmap != NULL )
+ {
+ FT_CMap vcmap = FT_CMAP( charmap );
+ FT_Memory memory = FT_FACE_MEMORY( face );
+
+
+ result = vcmap->clazz->variant_list( vcmap, memory );
+ }
+ }
+
+ return result;
+ }
+
+
+ /* documentation is in freetype.h */
+
+ FT_EXPORT_DEF( FT_UInt32* )
+ FT_Get_Variants_Of_Char( FT_Face face,
+ FT_ULong charcode )
+ {
+ FT_UInt32 *result = NULL;
+
+
+ if ( face )
+ {
+ FT_CharMap charmap = find_variant_selector_charmap( face );
+
+
+ if ( charmap != NULL )
+ {
+ FT_CMap vcmap = FT_CMAP( charmap );
+ FT_Memory memory = FT_FACE_MEMORY( face );
+
+
+ result = vcmap->clazz->charvariant_list( vcmap, memory, charcode );
+ }
+ }
+ return result;
+ }
+
+
+ /* documentation is in freetype.h */
+
+ FT_EXPORT_DEF( FT_UInt32* )
+ FT_Get_Chars_Of_Variant( FT_Face face,
+ FT_ULong variantSelector )
+ {
+ FT_UInt32 *result = NULL;
+
+
+ if ( face )
+ {
+ FT_CharMap charmap = find_variant_selector_charmap( face );
+
+
+ if ( charmap != NULL )
+ {
+ FT_CMap vcmap = FT_CMAP( charmap );
+ FT_Memory memory = FT_FACE_MEMORY( face );
+
+
+ result = vcmap->clazz->variantchar_list( vcmap, memory,
+ variantSelector );
+ }
+ }
return result;
}
--- a/src/bdf/bdfdrivr.c
+++ b/src/bdf/bdfdrivr.c
@@ -181,7 +181,9 @@
bdf_cmap_init,
bdf_cmap_done,
bdf_cmap_char_index,
- bdf_cmap_char_next
+ bdf_cmap_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
};
--- a/src/cff/cffcmap.c
+++ b/src/cff/cffcmap.c
@@ -4,7 +4,7 @@
/* */
/* CFF character mapping table (cmap) support (body). */
/* */
-/* Copyright 2002, 2003, 2004, 2005, 2006 by */
+/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -107,7 +107,9 @@
(FT_CMap_InitFunc) cff_cmap_encoding_init,
(FT_CMap_DoneFunc) cff_cmap_encoding_done,
(FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index,
- (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next
+ (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
};
@@ -213,7 +215,9 @@
(FT_CMap_InitFunc) cff_cmap_unicode_init,
(FT_CMap_DoneFunc) cff_cmap_unicode_done,
(FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index,
- (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next
+ (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
};
--- a/src/pcf/pcfdrivr.c
+++ b/src/pcf/pcfdrivr.c
@@ -2,7 +2,7 @@
FreeType font driver for pcf files
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006 by
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006, 2007 by
Francesco Zappa Nardelli
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -187,7 +187,9 @@
pcf_cmap_init,
pcf_cmap_done,
pcf_cmap_char_index,
- pcf_cmap_char_next
+ pcf_cmap_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
};
--- a/src/pfr/pfrcmap.c
+++ b/src/pfr/pfrcmap.c
@@ -158,7 +158,9 @@
(FT_CMap_InitFunc) pfr_cmap_init,
(FT_CMap_DoneFunc) pfr_cmap_done,
(FT_CMap_CharIndexFunc)pfr_cmap_char_index,
- (FT_CMap_CharNextFunc) pfr_cmap_char_next
+ (FT_CMap_CharNextFunc) pfr_cmap_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
};
--- a/src/psaux/t1cmap.c
+++ b/src/psaux/t1cmap.c
@@ -4,7 +4,7 @@
/* */
/* Type 1 character map support (body). */
/* */
-/* Copyright 2002, 2003, 2006 by */
+/* Copyright 2002, 2003, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -135,7 +135,9 @@
(FT_CMap_InitFunc) t1_cmap_standard_init,
(FT_CMap_DoneFunc) t1_cmap_std_done,
(FT_CMap_CharIndexFunc)t1_cmap_std_char_index,
- (FT_CMap_CharNextFunc) t1_cmap_std_char_next
+ (FT_CMap_CharNextFunc) t1_cmap_std_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
};
@@ -154,7 +156,9 @@
(FT_CMap_InitFunc) t1_cmap_expert_init,
(FT_CMap_DoneFunc) t1_cmap_std_done,
(FT_CMap_CharIndexFunc)t1_cmap_std_char_index,
- (FT_CMap_CharNextFunc) t1_cmap_std_char_next
+ (FT_CMap_CharNextFunc) t1_cmap_std_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
};
@@ -245,7 +249,9 @@
(FT_CMap_InitFunc) t1_cmap_custom_init,
(FT_CMap_DoneFunc) t1_cmap_custom_done,
(FT_CMap_CharIndexFunc)t1_cmap_custom_char_index,
- (FT_CMap_CharNextFunc) t1_cmap_custom_char_next
+ (FT_CMap_CharNextFunc) t1_cmap_custom_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
};
@@ -326,7 +332,9 @@
(FT_CMap_InitFunc) t1_cmap_unicode_init,
(FT_CMap_DoneFunc) t1_cmap_unicode_done,
(FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index,
- (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next
+ (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
};
--- a/src/sfnt/ttcmap.c
+++ b/src/sfnt/ttcmap.c
@@ -39,11 +39,13 @@
#define TT_PEEK_SHORT FT_PEEK_SHORT
#define TT_PEEK_USHORT FT_PEEK_USHORT
+#define TT_PEEK_UINT24 FT_PEEK_UOFF3
#define TT_PEEK_LONG FT_PEEK_LONG
#define TT_PEEK_ULONG FT_PEEK_ULONG
#define TT_NEXT_SHORT FT_NEXT_SHORT
#define TT_NEXT_USHORT FT_NEXT_USHORT
+#define TT_NEXT_UINT24 FT_NEXT_UOFF3
#define TT_NEXT_LONG FT_NEXT_LONG
#define TT_NEXT_ULONG FT_NEXT_ULONG
@@ -171,7 +173,9 @@
(FT_CMap_InitFunc) tt_cmap_init,
(FT_CMap_DoneFunc) NULL,
(FT_CMap_CharIndexFunc)tt_cmap0_char_index,
- (FT_CMap_CharNextFunc) tt_cmap0_char_next
+ (FT_CMap_CharNextFunc) tt_cmap0_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
},
0,
(TT_CMap_ValidateFunc) tt_cmap0_validate,
@@ -544,7 +548,9 @@
(FT_CMap_InitFunc) tt_cmap_init,
(FT_CMap_DoneFunc) NULL,
(FT_CMap_CharIndexFunc)tt_cmap2_char_index,
- (FT_CMap_CharNextFunc) tt_cmap2_char_next
+ (FT_CMap_CharNextFunc) tt_cmap2_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
},
2,
(TT_CMap_ValidateFunc) tt_cmap2_validate,
@@ -1320,7 +1326,9 @@
(FT_CMap_InitFunc) tt_cmap4_init,
(FT_CMap_DoneFunc) NULL,
(FT_CMap_CharIndexFunc)tt_cmap4_char_index,
- (FT_CMap_CharNextFunc) tt_cmap4_char_next
+ (FT_CMap_CharNextFunc) tt_cmap4_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
},
4,
(TT_CMap_ValidateFunc) tt_cmap4_validate,
@@ -1481,7 +1489,9 @@
(FT_CMap_InitFunc) tt_cmap_init,
(FT_CMap_DoneFunc) NULL,
(FT_CMap_CharIndexFunc)tt_cmap6_char_index,
- (FT_CMap_CharNextFunc) tt_cmap6_char_next
+ (FT_CMap_CharNextFunc) tt_cmap6_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
},
6,
(TT_CMap_ValidateFunc) tt_cmap6_validate,
@@ -1735,7 +1745,9 @@
(FT_CMap_InitFunc) tt_cmap_init,
(FT_CMap_DoneFunc) NULL,
(FT_CMap_CharIndexFunc)tt_cmap8_char_index,
- (FT_CMap_CharNextFunc) tt_cmap8_char_next
+ (FT_CMap_CharNextFunc) tt_cmap8_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
},
8,
(TT_CMap_ValidateFunc) tt_cmap8_validate,
@@ -1884,7 +1896,9 @@
(FT_CMap_InitFunc) tt_cmap_init,
(FT_CMap_DoneFunc) NULL,
(FT_CMap_CharIndexFunc)tt_cmap10_char_index,
- (FT_CMap_CharNextFunc) tt_cmap10_char_next
+ (FT_CMap_CharNextFunc) tt_cmap10_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
},
10,
(TT_CMap_ValidateFunc) tt_cmap10_validate,
@@ -2201,7 +2215,9 @@
(FT_CMap_InitFunc) tt_cmap12_init,
(FT_CMap_DoneFunc) NULL,
(FT_CMap_CharIndexFunc)tt_cmap12_char_index,
- (FT_CMap_CharNextFunc) tt_cmap12_char_next
+ (FT_CMap_CharNextFunc) tt_cmap12_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
},
12,
(TT_CMap_ValidateFunc) tt_cmap12_validate,
@@ -2208,10 +2224,703 @@
(TT_CMap_Info_GetFunc) tt_cmap12_get_info
};
-
#endif /* TT_CONFIG_CMAP_FORMAT_12 */
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** FORMAT 14 *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /*************************************************************************/
+ /* */
+ /* TABLE OVERVIEW */
+ /* -------------- */
+ /* */
+ /* NAME OFFSET TYPE DESCRIPTION */
+ /* */
+ /* format 0 USHORT must be 14 */
+ /* length 2 ULONG table length in bytes */
+ /* numSelector 6 ULONG number of variation sel. records */
+ /* */
+ /* Followed by numSelector records, each of which looks like */
+ /* */
+ /* varSelector 0 UINT24 Unicode codepoint of sel. */
+ /* defaultOff 3 ULONG offset to a default UVS table */
+ /* describing any variants to be found in */
+ /* the normal Unicode subtable. */
+ /* nonDefOff 7 ULONG offset to a non-default UVS table */
+ /* describing any variants not in the */
+ /* standard cmap, with GIDs here */
+ /* (either offset may be 0 NULL) */
+ /* */
+ /* Selectors are sorted by code point. */
+ /* */
+ /* A default Unicode Variation Selector (UVS) subtable is just a list of */
+ /* ranges of code points which are to be found in the standard cmap. No */
+ /* glyph IDs (GIDs) here. */
+ /* */
+ /* numRanges 0 ULONG number of ranges following */
+ /* */
+ /* A range looks like */
+ /* */
+ /* uniStart 0 UINT24 code point of the first character in */
+ /* this range */
+ /* additionalCnt 3 UBYTE count of additional characters in this */
+ /* range (zero means a range of a single */
+ /* character) */
+ /* */
+ /* Ranges are sorted by `uniStart'. */
+ /* */
+ /* A non-default Unicode Variation Selector (UVS) subtable is a list of */
+ /* mappings from codepoint to GID. */
+ /* */
+ /* numMappings 0 ULONG number of mappings */
+ /* */
+ /* A range looks like */
+ /* */
+ /* uniStart 0 UINT24 code point of the first character in */
+ /* this range */
+ /* GID 3 USHORT and its GID */
+ /* */
+ /* Ranges are sorted by `uniStart'. */
+
+#ifdef TT_CONFIG_CMAP_FORMAT_14
+
+ typedef struct TT_CMap14Rec_
+ {
+ TT_CMapRec cmap;
+ FT_ULong num_selectors;
+
+ } TT_CMap14Rec, *TT_CMap14;
+
+
+ FT_CALLBACK_DEF( FT_Error )
+ tt_cmap14_init( TT_CMap14 cmap,
+ FT_Byte* table )
+ {
+ cmap->cmap.data = table;
+
+ table += 6;
+ cmap->num_selectors = FT_PEEK_ULONG( table );
+
+ return SFNT_Err_Ok;
+ }
+
+
+ FT_CALLBACK_DEF( FT_Error )
+ tt_cmap14_validate( FT_Byte* table,
+ FT_Validator valid )
+ {
+ FT_Byte* p = table + 2;
+ FT_ULong length = TT_NEXT_ULONG( p );
+ FT_ULong num_selectors = TT_NEXT_ULONG( p );
+
+
+ if ( table + length > valid->limit || length < 10 + 11 * num_selectors )
+ FT_INVALID_TOO_SHORT;
+
+ /* check selectors, they must be in increasing order */
+ {
+ FT_ULong n, varSel, defOff, nondefOff, last = 0;
+
+
+ for ( n = 0; n < num_selectors; n++ )
+ {
+ varSel = TT_NEXT_UINT24( p );
+ defOff = TT_NEXT_ULONG( p );
+ nondefOff = TT_NEXT_ULONG( p );
+
+ if ( defOff >= length || nondefOff >= length )
+ FT_INVALID_TOO_SHORT;
+
+ if ( n > 0 && varSel <= last )
+ FT_INVALID_DATA;
+ last = varSel;
+
+ /* check the default table (these glyphs should be reached */
+ /* through the normal Unicode cmap, no GIDs, just check order) */
+ if ( defOff != 0 )
+ {
+ FT_Byte* defp = table + defOff;
+ FT_ULong numRanges = TT_NEXT_ULONG( defp );
+ FT_ULong i, base, cnt;
+
+
+ for ( i = 0; i < numRanges; ++i )
+ {
+ base = TT_NEXT_UINT24( defp );
+ cnt = FT_NEXT_BYTE( defp );
+
+ if ( base + cnt >= 0x110000UL ) /* end of Unicode */
+ FT_INVALID_DATA;
+
+ if ( i > 0 && base <= last )
+ FT_INVALID_DATA;
+ last = base + cnt;
+ }
+ }
+
+ /* and the non-default table (these glyphs are specified here) */
+ if ( nondefOff != 0 ) {
+ FT_Byte* ndp = table + nondefOff;
+ FT_ULong numMappings = TT_NEXT_ULONG( ndp );
+ FT_ULong i, uni, gid;
+
+
+ for ( i = 0; i < numMappings; ++i )
+ {
+ uni = TT_NEXT_UINT24( ndp );
+ gid = TT_NEXT_USHORT( ndp );
+
+ if ( uni >= 0x110000UL ) /* end of Unicode */
+ FT_INVALID_DATA;
+
+ if ( i > 0 && uni <= last )
+ FT_INVALID_DATA;
+ last = uni;
+
+ if ( valid->level >= FT_VALIDATE_TIGHT &&
+ gid >= TT_VALID_GLYPH_COUNT( valid ) )
+ FT_INVALID_GLYPH_ID;
+ }
+ }
+ }
+ }
+
+ return SFNT_Err_Ok;
+ }
+
+
+ FT_CALLBACK_DEF( FT_UInt )
+ tt_cmap14_char_index( TT_CMap cmap,
+ FT_UInt32 char_code )
+ {
+ FT_UNUSED( cmap );
+ FT_UNUSED( char_code );
+
+ /* This can't happen */
+ return 0;
+ }
+
+
+ FT_CALLBACK_DEF( FT_UInt )
+ tt_cmap14_char_next( TT_CMap cmap,
+ FT_UInt32 *pchar_code )
+ {
+ FT_UNUSED( cmap );
+
+ /* This can't happen */
+ *pchar_code = 0;
+ return 0;
+ }
+
+
+ FT_CALLBACK_DEF( FT_Error )
+ tt_cmap14_get_info( TT_CMap cmap,
+ TT_CMapInfo *cmap_info )
+ {
+ FT_UNUSED( cmap );
+
+ cmap_info->format = 14;
+ /* subtable 14 does not define a language field */
+ cmap_info->language = 0xFFFFFFFFUL;
+
+ return SFNT_Err_Ok;
+ }
+
+
+ static FT_UInt
+ tt_cmap14_char_map_def_binary( FT_Byte *base,
+ FT_UInt32 char_code )
+ {
+ FT_Byte* p;
+ FT_UInt32 numRanges = TT_PEEK_ULONG( base );
+ FT_UInt32 start, cnt;
+ FT_UInt32 max, min, mid;
+
+
+ if ( !numRanges )
+ return FALSE;
+
+ /* make compiler happy */
+ mid = numRanges;
+
+ min = 0;
+ max = numRanges;
+
+ /* binary search */
+ while ( min < max )
+ {
+ mid = ( min + max ) >> 1;
+ p = base + 4 + 4 * mid;
+
+ start = TT_NEXT_UINT24( p );
+ cnt = FT_NEXT_BYTE( p );
+
+ if ( char_code < start )
+ max = mid;
+ else if ( char_code > start+cnt )
+ min = mid + 1;
+ else
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+
+ static FT_UInt
+ tt_cmap14_char_map_nondef_binary( FT_Byte *base,
+ FT_UInt32 char_code )
+ {
+ FT_Byte* p;
+ FT_UInt32 numMappings = TT_PEEK_ULONG( base );
+ FT_UInt32 uni, gid;
+ FT_UInt32 max, min, mid;
+
+
+ if ( !numMappings )
+ return 0;
+
+ /* make compiler happy */
+ mid = numMappings;
+
+ min = 0;
+ max = numMappings;
+
+ /* binary search */
+ while ( min < max )
+ {
+ mid = ( min + max ) >> 1;
+ p = base + 4 + 5 * mid;
+
+ uni = TT_NEXT_UINT24( p );
+ gid = TT_NEXT_USHORT( p );
+
+ if ( char_code < uni )
+ max = mid;
+ else if ( char_code > uni )
+ min = mid + 1;
+ else
+ return gid;
+ }
+
+ return 0;
+ }
+
+
+ static FT_Byte*
+ tt_cmap14_find_variant( FT_Byte *base,
+ FT_UInt32 variantCode )
+ {
+ FT_Byte* p;
+ FT_UInt32 numVar = TT_PEEK_ULONG( base );
+ FT_ULong varSel;
+ FT_UInt32 max, min, mid;
+
+
+ if ( !numVar )
+ return NULL;
+
+ /* make compiler happy */
+ mid = numVar;
+
+ min = 0;
+ max = numVar;
+
+ /* binary search */
+ while ( min < max )
+ {
+ mid = ( min + max ) >> 1;
+ p = base + 4 + 11 * mid;
+
+ varSel = TT_NEXT_UINT24( p );
+
+ if ( variantCode < varSel )
+ max = mid;
+ else if ( variantCode > varSel )
+ min = mid + 1;
+ else
+ return p;
+ }
+
+ return NULL;
+ }
+
+
+ FT_CALLBACK_DEF( FT_UInt )
+ tt_cmap14_char_var_index( TT_CMap cmap,
+ TT_CMap ucmap,
+ FT_ULong charcode,
+ FT_ULong variantSelector)
+ {
+ FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
+ FT_ULong defOff;
+ FT_ULong nondefOff;
+
+
+ if ( !p )
+ return 0;
+
+ defOff = TT_NEXT_ULONG( p );
+ nondefOff = TT_NEXT_ULONG( p );
+
+ if ( defOff != 0 &&
+ tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
+ {
+ /* This is the default variant of this charcode. GID not stored */
+ /* here; stored in the normal Unicode charmap instead. */
+ return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode );
+ }
+
+ if ( nondefOff != 0 )
+ return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
+ charcode );
+
+ return 0;
+ }
+
+
+ FT_CALLBACK_DEF( FT_Int )
+ tt_cmap14_char_var_isdefault( TT_CMap cmap,
+ FT_ULong charcode,
+ FT_ULong variantSelector )
+ {
+ FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
+ FT_ULong defOff;
+ FT_ULong nondefOff;
+
+
+ if ( !p )
+ return -1;
+
+ defOff = TT_NEXT_ULONG( p );
+ nondefOff = TT_NEXT_ULONG( p );
+
+ if ( defOff != 0 &&
+ tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
+ return 1;
+
+ if ( nondefOff != 0 &&
+ tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
+ charcode ) != 0 )
+ return 0;
+
+ return -1;
+ }
+
+
+ FT_CALLBACK_DEF( FT_UInt32 * )
+ tt_cmap14_variants( TT_CMap cmap,
+ FT_Memory memory )
+ {
+ TT_CMap14 cmap14 = (TT_CMap14)cmap;
+ FT_Byte* p = cmap->data + 10;
+ FT_UInt32* ret;
+ FT_UInt i;
+ FT_Error error;
+
+
+ if ( FT_ALLOC( ret,
+ ( cmap14->num_selectors + 1 ) * sizeof ( FT_UInt32 ) ) )
+ return NULL;
+
+ for ( i = 0; i < cmap14->num_selectors; ++i )
+ {
+ ret[i] = TT_NEXT_UINT24( p );
+ p += 8;
+ }
+ ret[i] = 0;
+
+ return ret;
+ }
+
+
+ FT_CALLBACK_DEF( FT_UInt32 * )
+ tt_cmap14_char_variants( TT_CMap cmap,
+ FT_Memory memory,
+ FT_ULong charCode )
+ {
+ TT_CMap14 cmap14 = (TT_CMap14) cmap;
+ FT_Byte* p = cmap->data + 10;
+ FT_UInt32 *ret;
+ FT_UInt i, j;
+ FT_UInt32 varSel;
+ FT_ULong defOff;
+ FT_ULong nondefOff;
+ FT_Error error;
+
+
+ if ( FT_ALLOC( ret,
+ ( cmap14->num_selectors + 1 ) * sizeof ( FT_UInt32 ) ) )
+ return NULL;
+
+ for ( i = j = 0; i < cmap14->num_selectors; ++i )
+ {
+ varSel = TT_NEXT_UINT24( p );
+ defOff = TT_NEXT_ULONG( p );
+ nondefOff = TT_NEXT_ULONG( p );
+ if ( ( defOff != 0 &&
+ tt_cmap14_char_map_def_binary( cmap->data + defOff,
+ charCode ) ) ||
+ ( nondefOff != 0 &&
+ tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
+ charCode ) != 0 ) )
+ ret[j++] = varSel;
+ }
+ ret[j] = 0;
+
+ return ret;
+ }
+
+
+ static FT_UInt
+ tt_cmap14_def_char_count( FT_Byte *p )
+ {
+ FT_UInt32 numRanges;
+ FT_UInt tot;
+ FT_UInt cnt;
+ FT_UInt i;
+
+
+ numRanges = TT_NEXT_ULONG( p );
+
+ tot = 0;
+ for ( i = 0; i < numRanges; ++i )
+ {
+ p += 3;
+ cnt = FT_NEXT_BYTE( p );
+ tot += cnt + 1;
+ }
+
+ return tot;
+ }
+
+
+ static FT_UInt*
+ tt_cmap14_get_def_chars( FT_Byte *p,
+ FT_Memory memory )
+ {
+ FT_UInt32 numRanges;
+ FT_UInt uni;
+ FT_UInt cnt;
+ FT_UInt i, j, k;
+ FT_UInt32 *ret;
+ FT_Error error;
+
+
+ cnt = tt_cmap14_def_char_count( p );
+ numRanges = TT_NEXT_ULONG( p );
+
+ if ( FT_ALLOC( ret , ( cnt + 1 ) * sizeof ( FT_UInt32 ) ) )
+ return NULL;
+
+ for ( i = j = 0; i < numRanges; ++i )
+ {
+ uni = TT_NEXT_UINT24( p );
+ cnt = FT_NEXT_BYTE( p );
+
+ for ( k = 0; k <= cnt; ++k )
+ ret[j++] = uni + k;
+ }
+ ret[j] = 0;
+
+ return ret;
+ }
+
+
+ static FT_UInt*
+ tt_cmap14_get_nondef_chars( FT_Byte *p,
+ FT_Memory memory )
+ {
+ FT_UInt32 numMappings;
+ FT_UInt i;
+ FT_UInt32 *ret;
+ FT_Error error;
+
+
+ numMappings = TT_NEXT_ULONG( p );
+
+ if ( FT_ALLOC( ret, ( numMappings + 1 ) * sizeof ( FT_UInt32 ) ) )
+ return NULL;
+
+ for ( i = 0; i < numMappings; ++i )
+ {
+ ret[i] = TT_NEXT_UINT24( p );
+ p += 2;
+ }
+ ret[i] = 0;
+
+ return( ret );
+ }
+
+
+ FT_CALLBACK_DEF( FT_UInt32 * )
+ tt_cmap14_variant_chars( TT_CMap cmap,
+ FT_Memory memory,
+ FT_ULong variantSelector )
+ {
+ FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6,
+ variantSelector );
+ FT_UInt32 *ret;
+ FT_Int i;
+ FT_ULong defOff;
+ FT_ULong nondefOff;
+
+
+ if ( !p )
+ return NULL;
+
+ defOff = TT_NEXT_ULONG( p );
+ nondefOff = TT_NEXT_ULONG( p );
+
+ if ( defOff == 0 && nondefOff == 0 )
+ return NULL;
+
+ if ( defOff == 0 )
+ return tt_cmap14_get_nondef_chars( cmap->data + nondefOff, memory );
+ else if ( nondefOff == 0 )
+ return tt_cmap14_get_def_chars( cmap->data + defOff, memory );
+ else
+ {
+ /* Both a default and a non-default glyph set? That's probably not */
+ /* good font design, but the spec allows for it... */
+ FT_UInt32 numRanges;
+ FT_UInt32 numMappings;
+ FT_UInt32 duni;
+ FT_UInt32 dcnt;
+ FT_UInt32 nuni;
+ FT_Byte* dp;
+ FT_UInt di, ni, k;
+ FT_Error error;
+
+
+ p = cmap->data + nondefOff;
+ dp = cmap->data + defOff;
+
+ numMappings = TT_NEXT_ULONG( p );
+ dcnt = tt_cmap14_def_char_count( dp );
+ numRanges = TT_NEXT_ULONG( dp );
+
+ if ( numMappings == 0 )
+ return tt_cmap14_get_def_chars( cmap->data + defOff, memory );
+ if ( dcnt == 0 )
+ return tt_cmap14_get_nondef_chars( cmap->data + nondefOff, memory );
+
+ if ( FT_ALLOC( ret,
+ ( dcnt + numMappings + 1 ) * sizeof ( FT_UInt32 ) ) )
+ return NULL;
+
+ duni = TT_NEXT_UINT24( dp );
+ dcnt = FT_NEXT_BYTE( dp );
+ di = 1;
+ nuni = TT_NEXT_UINT24( p );
+ p += 2;
+ ni = 1;
+ i = 0;
+
+ for ( ;; )
+ {
+ if ( nuni > duni + dcnt )
+ {
+ for ( k = 0; k <= dcnt; ++k )
+ ret[i++] = duni + k;
+
+ ++di;
+
+ if ( di <= numRanges )
+ {
+ duni = TT_NEXT_UINT24( dp );
+ dcnt = FT_NEXT_BYTE( dp );
+ }
+ else
+ break;
+ }
+ else
+ {
+ if ( nuni < duni )
+ ret[i++] = nuni;
+ /* If it is within the default range then ignore it -- */
+ /* that should not have happened */
+ ++ni;
+ if ( ni <= numMappings )
+ {
+ nuni = TT_NEXT_UINT24( p );
+ p += 2;
+ }
+ else
+ break;
+ }
+ }
+
+ if ( ni <= numMappings )
+ {
+ /* If we get here then we have run out of all default ranges. */
+ /* We have read one non-default mapping which we haven't stored */
+ /* and there may be others that need to be read. */
+ ret[i++] = nuni;
+ while ( ni < numMappings )
+ {
+ ret[i++] = TT_NEXT_UINT24( p );
+ p += 2;
+ ++ni;
+ }
+ }
+ else if ( di < numRanges )
+ {
+ /* If we get here then we have run out of all non-default */
+ /* mappings. We have read one default range which we haven't */
+ /* stored and there may be others that need to be read. */
+ for ( k = 0; k <= dcnt; ++k )
+ ret[i++] = duni + k;
+
+ while ( di < numRanges )
+ {
+ duni = TT_NEXT_UINT24( dp );
+ dcnt = FT_NEXT_BYTE( dp );
+
+ for ( k = 0; k <= dcnt; ++k )
+ ret[i++] = duni + k;
+ ++di;
+ }
+ }
+
+ ret[i] = 0;
+
+ return ret;
+ }
+ }
+
+
+ FT_CALLBACK_TABLE_DEF
+ const TT_CMap_ClassRec tt_cmap14_class_rec =
+ {
+ {
+ sizeof ( TT_CMap14Rec ),
+
+ (FT_CMap_InitFunc) tt_cmap14_init,
+ (FT_CMap_DoneFunc) NULL,
+ (FT_CMap_CharIndexFunc)tt_cmap14_char_index,
+ (FT_CMap_CharNextFunc) tt_cmap14_char_next,
+ /* Format 14 extension functions */
+ (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index,
+ (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault,
+ (FT_CMap_VariantListFunc) tt_cmap14_variants,
+ (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants,
+ (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars
+ },
+ 14,
+ (TT_CMap_ValidateFunc)tt_cmap14_validate,
+ (TT_CMap_Info_GetFunc)tt_cmap14_get_info
+ };
+
+#endif /* TT_CONFIG_CMAP_FORMAT_0 */
+
+
static const TT_CMap_Class tt_cmap_classes[] =
{
#ifdef TT_CONFIG_CMAP_FORMAT_0
@@ -2242,6 +2951,10 @@
&tt_cmap12_class_rec,
#endif
+#ifdef TT_CONFIG_CMAP_FORMAT_14
+ &tt_cmap14_class_rec,
+#endif
+
NULL,
};
@@ -2318,6 +3031,10 @@
FT_CMap ttcmap;
+ /* It might make sense to store the single variation selector */
+ /* cmap somewhere special. But it would have to be in the */
+ /* public FT_FaceRec, and we can't change that. */
+
if ( !FT_CMap_New( (FT_CMap_Class)clazz,
cmap, &charmap, &ttcmap ) )
{
@@ -2333,6 +3050,12 @@
}
break;
}
+ }
+
+ if ( *pclazz == NULL )
+ {
+ FT_ERROR(( "tt_face_build_cmaps:" ));
+ FT_ERROR(( " unsupported cmap sub-table ignored!\n" ));
}
}
}
--- a/src/winfonts/winfnt.c
+++ b/src/winfonts/winfnt.c
@@ -652,7 +652,9 @@
(FT_CMap_InitFunc) fnt_cmap_init,
(FT_CMap_DoneFunc) NULL,
(FT_CMap_CharIndexFunc)fnt_cmap_char_index,
- (FT_CMap_CharNextFunc) fnt_cmap_char_next
+ (FT_CMap_CharNextFunc) fnt_cmap_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
};
static FT_CMap_Class const fnt_cmap_class = &fnt_cmap_class_rec;