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.
This commit is contained in:
Werner Lemberg 2007-10-15 17:21:32 +00:00
parent cc272c5166
commit 9a966b7d1b
15 changed files with 1214 additions and 30 deletions

View File

@ -1,3 +1,48 @@
2007-10-15 George Williams <gww@silcom.com>
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 <wl@gnu.org>
* src/base/ftobjs.c (find_unicode_charmap): If search for a UCS-4
@ -6,10 +51,10 @@
2007-08-29 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
* 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.

View File

@ -436,6 +436,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_14
/*************************************************************************/

View File

@ -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
@ -11,6 +21,9 @@ CHANGES BETWEEN 2.3.6 and 2.3.5
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.
======================================================================

View File

@ -436,6 +436,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_14
/*************************************************************************/

View File

@ -2852,6 +2852,8 @@ FT_BEGIN_HEADER
/* 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 );
@ -2990,6 +2992,162 @@ FT_BEGIN_HEADER
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 );
/*************************************************************************/
/* */
/* <Function> */

View File

@ -160,6 +160,31 @@ FT_BEGIN_HEADER
(*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_
{
@ -169,6 +194,15 @@ FT_BEGIN_HEADER
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;

View File

@ -108,13 +108,18 @@ FT_BEGIN_HEADER
*
* 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 */
/***********************************************************************

View File

@ -964,6 +964,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> */
@ -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;
@ -2849,6 +2890,149 @@
}
/* 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;
}
/* documentation is in freetype.h */
FT_EXPORT_DEF( FT_UInt )

View File

@ -181,7 +181,9 @@ THE SOFTWARE.
bdf_cmap_init,
bdf_cmap_done,
bdf_cmap_char_index,
bdf_cmap_char_next
bdf_cmap_char_next,
NULL, NULL, NULL, NULL, NULL
};

View File

@ -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
};

View File

@ -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 @@ THE SOFTWARE.
pcf_cmap_init,
pcf_cmap_done,
pcf_cmap_char_index,
pcf_cmap_char_next
pcf_cmap_char_next,
NULL, NULL, NULL, NULL, NULL
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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,17 +2215,712 @@
(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,
(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 ) )
{
@ -2334,6 +3051,12 @@
break;
}
}
if ( *pclazz == NULL )
{
FT_ERROR(( "tt_face_build_cmaps:" ));
FT_ERROR(( " unsupported cmap sub-table ignored!\n" ));
}
}
}

View File

@ -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;