From a38fc482eeeb2c1929803c233835369dcf1b8781 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Tue, 21 Oct 2008 07:00:00 -0700 Subject: Initial Contribution --- src/sfnt/Jamfile | 29 -- src/sfnt/module.mk | 23 -- src/sfnt/rules.mk | 76 ------ src/sfnt/sfobjs.c | 84 ++++-- src/sfnt/ttcmap.c | 783 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/sfnt/ttload.c | 11 +- src/sfnt/ttmtx.c | 3 +- src/sfnt/ttsbit.c | 5 +- src/sfnt/ttsbit0.c | 4 +- 9 files changed, 857 insertions(+), 161 deletions(-) delete mode 100644 src/sfnt/Jamfile delete mode 100644 src/sfnt/module.mk delete mode 100644 src/sfnt/rules.mk (limited to 'src/sfnt') diff --git a/src/sfnt/Jamfile b/src/sfnt/Jamfile deleted file mode 100644 index 6b8a401..0000000 --- a/src/sfnt/Jamfile +++ /dev/null @@ -1,29 +0,0 @@ -# FreeType 2 src/sfnt Jamfile -# -# Copyright 2001, 2002, 2004, 2005 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - -SubDir FT2_TOP $(FT2_SRC_DIR) sfnt ; - -{ - local _sources ; - - if $(FT2_MULTI) - { - _sources = sfobjs sfdriver ttcmap ttpost ttload ttsbit ttkern ttbdf ; - } - else - { - _sources = sfnt ; - } - - Library $(FT2_LIB) : $(_sources).c ; -} - -# end of src/sfnt Jamfile diff --git a/src/sfnt/module.mk b/src/sfnt/module.mk deleted file mode 100644 index d339138..0000000 --- a/src/sfnt/module.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 SFNT module definition -# - - -# Copyright 1996-2000, 2006 by -# David Turner, Robert Wilhelm, and Werner Lemberg. -# -# This file is part of the FreeType project, and may only be used, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -FTMODULE_H_COMMANDS += SFNT_MODULE - -define SFNT_MODULE -$(OPEN_DRIVER)sfnt_module_class$(CLOSE_DRIVER) -$(ECHO_DRIVER)sfnt $(ECHO_DRIVER_DESC)helper module for TrueType & OpenType formats$(ECHO_DRIVER_DONE) -endef - -# EOF diff --git a/src/sfnt/rules.mk b/src/sfnt/rules.mk deleted file mode 100644 index ff7840e..0000000 --- a/src/sfnt/rules.mk +++ /dev/null @@ -1,76 +0,0 @@ -# -# FreeType 2 SFNT driver configuration rules -# - - -# Copyright 1996-2000, 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, modified, -# and distributed under the terms of the FreeType project license, -# LICENSE.TXT. By continuing to use, modify, or distribute this file you -# indicate that you have read the license and understand and accept it -# fully. - - -# SFNT driver directory -# -SFNT_DIR := $(SRC_DIR)/sfnt - - -# compilation flags for the driver -# -SFNT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SFNT_DIR)) - - -# SFNT driver sources (i.e., C files) -# -SFNT_DRV_SRC := $(SFNT_DIR)/ttload.c \ - $(SFNT_DIR)/ttmtx.c \ - $(SFNT_DIR)/ttcmap.c \ - $(SFNT_DIR)/ttsbit.c \ - $(SFNT_DIR)/ttpost.c \ - $(SFNT_DIR)/ttkern.c \ - $(SFNT_DIR)/ttbdf.c \ - $(SFNT_DIR)/sfobjs.c \ - $(SFNT_DIR)/sfdriver.c - -# SFNT driver headers -# -SFNT_DRV_H := $(SFNT_DRV_SRC:%c=%h) \ - $(SFNT_DIR)/sferrors.h - - -# SFNT driver object(s) -# -# SFNT_DRV_OBJ_M is used during `multi' builds. -# SFNT_DRV_OBJ_S is used during `single' builds. -# -SFNT_DRV_OBJ_M := $(SFNT_DRV_SRC:$(SFNT_DIR)/%.c=$(OBJ_DIR)/%.$O) -SFNT_DRV_OBJ_S := $(OBJ_DIR)/sfnt.$O - -# SFNT driver source file for single build -# -SFNT_DRV_SRC_S := $(SFNT_DIR)/sfnt.c - - -# SFNT driver - single object -# -$(SFNT_DRV_OBJ_S): $(SFNT_DRV_SRC_S) $(SFNT_DRV_SRC) \ - $(FREETYPE_H) $(SFNT_DRV_H) - $(SFNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(SFNT_DRV_SRC_S)) - - -# SFNT driver - multiple objects -# -$(OBJ_DIR)/%.$O: $(SFNT_DIR)/%.c $(FREETYPE_H) $(SFNT_DRV_H) - $(SFNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) - - -# update main driver object lists -# -DRV_OBJS_S += $(SFNT_DRV_OBJ_S) -DRV_OBJS_M += $(SFNT_DRV_OBJ_M) - - -# EOF diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c index cc90110..c25b87d 100644 --- a/src/sfnt/sfobjs.c +++ b/src/sfnt/sfobjs.c @@ -4,7 +4,7 @@ /* */ /* SFNT object management (base). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -285,7 +285,7 @@ sfnt_find_encoding( int platform_id, int encoding_id ) { - typedef struct TEncoding + typedef struct TEncoding_ { int platform_id; int encoding_id; @@ -696,22 +696,60 @@ face->root.num_glyphs = face->max_profile.numGlyphs; - face->root.family_name = tt_face_get_name( face, - TT_NAME_ID_PREFERRED_FAMILY ); - if ( !face->root.family_name ) - face->root.family_name = tt_face_get_name( face, - TT_NAME_ID_FONT_FAMILY ); +#if 0 + /* Bit 8 of the `fsSelection' field in the `OS/2' table denotes */ + /* a WWS-only font face. `WWS' stands for `weight', width', and */ + /* `slope', a term used by Microsoft's Windows Presentation */ + /* Foundation (WPF). This flag will be introduced in version */ + /* 1.5 of the OpenType specification (but is already in use). */ + + if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 ) +#endif + { + face->root.family_name = + tt_face_get_name( face, TT_NAME_ID_PREFERRED_FAMILY ); + if ( !face->root.family_name ) + face->root.family_name = + tt_face_get_name( face, TT_NAME_ID_FONT_FAMILY ); + + face->root.style_name = + tt_face_get_name( face, TT_NAME_ID_PREFERRED_SUBFAMILY ); + if ( !face->root.style_name ) + face->root.style_name = + tt_face_get_name( face, TT_NAME_ID_FONT_SUBFAMILY ); + } +#if 0 + else + { + /* Support for `name' table ID 21 (WWS family) and 22 (WWS */ + /* subfamily) is still under consideration by Microsoft and */ + /* not implemented in the current version of WPF. */ + + face->root.family_name = + tt_face_get_name( face, TT_NAME_ID_WWS_FAMILY ); + if ( !face->root.family_name ) + face->root.family_name = + tt_face_get_name( face, TT_NAME_ID_PREFERRED_FAMILY ); + if ( !face->root.family_name ) + face->root.family_name = + tt_face_get_name( face, TT_NAME_ID_FONT_FAMILY ); + + face->root.style_name = + tt_face_get_name( face, TT_NAME_ID_WWS_SUBFAMILY ); + if ( !face->root.style_name ) + face->root.style_name = + tt_face_get_name( face, TT_NAME_ID_PREFERRED_SUBFAMILY ); + if ( !face->root.style_name ) + face->root.style_name = + tt_face_get_name( face, TT_NAME_ID_FONT_SUBFAMILY ); + } +#endif - face->root.style_name = tt_face_get_name( face, - TT_NAME_ID_PREFERRED_SUBFAMILY ); - if ( !face->root.style_name ) - face->root.style_name = tt_face_get_name( face, - TT_NAME_ID_FONT_SUBFAMILY ); /* now set up root fields */ { - FT_Face root = &face->root; - FT_Int32 flags = root->face_flags; + FT_Face root = &face->root; + FT_Int32 flags = root->face_flags; /*********************************************************************/ @@ -727,7 +765,7 @@ FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - if ( psnames_error == SFNT_Err_Ok && + if ( psnames_error == SFNT_Err_Ok && face->postscript.FormatType != 0x00030000L ) flags |= FT_FACE_FLAG_GLYPH_NAMES; #endif @@ -759,14 +797,21 @@ /* */ /* Compute style flags. */ /* */ + flags = 0; if ( has_outline == TRUE && face->os2.version != 0xFFFFU ) { - /* we have an OS/2 table; use the `fsSelection' field */ - if ( face->os2.fsSelection & 1 ) + /* We have an OS/2 table; use the `fsSelection' field. Bit 9 */ + /* indicates an oblique font face. This flag will be */ + /* introduced in version 1.5 of the OpenType specification (but */ + /* is already in use). */ + + if ( face->os2.fsSelection & 512 ) /* bit 9 */ + flags |= FT_STYLE_FLAG_ITALIC; + else if ( face->os2.fsSelection & 1 ) /* bit 0 */ flags |= FT_STYLE_FLAG_ITALIC; - if ( face->os2.fsSelection & 32 ) + if ( face->os2.fsSelection & 32 ) /* bit 5 */ flags |= FT_STYLE_FLAG_BOLD; } else @@ -1051,7 +1096,8 @@ face->gasp.numRanges = 0; /* freeing the name table */ - sfnt->free_name( face ); + if ( sfnt ) + sfnt->free_name( face ); /* freeing family and style name */ FT_FREE( face->root.family_name ); diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c index 854d567..b70b64c 100644 --- 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,17 +2215,756 @@ (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; + + /* This array is used to store the results of various + * cmap 14 query functions. The data is overwritten + * on each call to these functions. + */ + FT_UInt max_results; + FT_UInt32* results; + FT_Memory memory; + + } TT_CMap14Rec, *TT_CMap14; + + + FT_CALLBACK_DEF( void ) + tt_cmap14_done( TT_CMap14 cmap ) + { + FT_Memory memory = cmap->memory; + + + cmap->max_results = 0; + if ( memory != NULL && cmap->results != NULL ) + FT_FREE( cmap->results ); + } + + + static FT_Error + tt_cmap14_ensure( TT_CMap14 cmap, + FT_UInt num_results, + FT_Memory memory ) + { + FT_UInt old_max = cmap->max_results; + FT_Error error = 0; + + + if ( num_results > cmap->max_results ) + { + cmap->memory = memory; + + if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) ) + return error; + + cmap->max_results = num_results; + } + + return error; + } + + + 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 ); + cmap->max_results = 0; + cmap->results = NULL; + + 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 */ + { + /* we start lastVarSel at 1 because a variant selector value of 0 + * isn't valid. + */ + FT_ULong n, lastVarSel = 1; + + + for ( n = 0; n < num_selectors; n++ ) + { + FT_ULong varSel = TT_NEXT_UINT24( p ); + FT_ULong defOff = TT_NEXT_ULONG( p ); + FT_ULong nondefOff = TT_NEXT_ULONG( p ); + + + if ( defOff >= length || nondefOff >= length ) + FT_INVALID_TOO_SHORT; + + if ( varSel < lastVarSel ) + FT_INVALID_DATA; + + lastVarSel = varSel + 1; + + /* 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; + FT_ULong lastBase = 0; + + + if ( defp + numRanges * 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + for ( i = 0; i < numRanges; ++i ) + { + FT_ULong base = TT_NEXT_UINT24( defp ); + FT_ULong cnt = FT_NEXT_BYTE( defp ); + + + if ( base + cnt >= 0x110000UL ) /* end of Unicode */ + FT_INVALID_DATA; + + if ( base < lastBase ) + FT_INVALID_DATA; + + lastBase = base + cnt + 1U; + } + } + + /* 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, lastUni = 0; + + + if ( ndp + numMappings * 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + for ( i = 0; i < numMappings; ++i ) + { + FT_ULong uni = TT_NEXT_UINT24( ndp ); + FT_ULong gid = TT_NEXT_USHORT( ndp ); + + + if ( uni >= 0x110000UL ) /* end of Unicode */ + FT_INVALID_DATA; + + if ( uni < lastUni ) + FT_INVALID_DATA; + + lastUni = uni + 1U; + + 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_UInt32 numRanges = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numRanges; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 4 * mid; + FT_ULong start = TT_NEXT_UINT24( p ); + FT_UInt 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_UInt32 numMappings = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numMappings; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 5 * mid; + FT_UInt32 uni = TT_NEXT_UINT24( p ); + + + if ( char_code < uni ) + max = mid; + else if ( char_code > uni ) + min = mid + 1; + else + return TT_PEEK_USHORT( p ); + } + + return 0; + } + + + static FT_Byte* + tt_cmap14_find_variant( FT_Byte *base, + FT_UInt32 variantCode ) + { + FT_UInt32 numVar = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numVar; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 11 * mid; + FT_ULong 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_PEEK_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_UInt count = cmap14->num_selectors; + FT_Byte* p = cmap->data + 10; + FT_UInt32* result; + FT_UInt i; + + + if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) + return NULL; + + result = cmap14->results; + for ( i = 0; i < count; ++i ) + { + result[i] = TT_NEXT_UINT24( p ); + p += 8; + } + result[i] = 0; + + return result; + } + + + 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_UInt count = cmap14->num_selectors; + FT_Byte* p = cmap->data + 10; + FT_UInt32* q; + + + if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) + return NULL; + + for ( q = cmap14->results; count > 0; --count ) + { + FT_UInt32 varSel = TT_NEXT_UINT24( p ); + FT_ULong defOff = TT_NEXT_ULONG( p ); + FT_ULong 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 ) ) + { + q[0] = varSel; + q++; + } + } + q[0] = 0; + + return cmap14->results; + } + + + static FT_UInt + tt_cmap14_def_char_count( FT_Byte *p ) + { + FT_UInt32 numRanges = TT_NEXT_ULONG( p ); + FT_UInt tot = 0; + + + p += 3; /* point to the first 'cnt' field */ + for ( ; numRanges > 0; numRanges-- ) + { + tot += 1 + p[0]; + p += 4; + } + + return tot; + } + + + static FT_UInt32* + tt_cmap14_get_def_chars( TT_CMap cmap, + FT_Byte* p, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numRanges; + FT_UInt cnt; + FT_UInt32* q; + + + cnt = tt_cmap14_def_char_count( p ); + numRanges = TT_NEXT_ULONG( p ); + + if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) ) + return NULL; + + for ( q = cmap14->results; numRanges > 0; --numRanges ) + { + FT_UInt uni = TT_NEXT_UINT24( p ); + + + cnt = FT_NEXT_BYTE( p ) + 1; + do + { + q[0] = uni; + uni += 1; + q += 1; + } while ( --cnt != 0 ); + } + q[0] = 0; + + return cmap14->results; + } + + + static FT_UInt* + tt_cmap14_get_nondef_chars( TT_CMap cmap, + FT_Byte *p, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numMappings; + FT_UInt i; + FT_UInt32 *ret; + + + numMappings = TT_NEXT_ULONG( p ); + + if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) ) + return NULL; + + ret = cmap14->results; + 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, cmap->data + nondefOff, + memory ); + else if ( nondefOff == 0 ) + return tt_cmap14_get_def_chars( cmap, 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... */ + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numRanges; + FT_UInt32 numMappings; + FT_UInt32 duni; + FT_UInt32 dcnt; + FT_UInt32 nuni; + FT_Byte* dp; + FT_UInt di, ni, k; + + + 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, cmap->data + defOff, + memory ); + if ( dcnt == 0 ) + return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, + memory ); + + if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) ) + return NULL; + + ret = cmap14->results; + 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 ) + break; + + duni = TT_NEXT_UINT24( dp ); + dcnt = FT_NEXT_BYTE( dp ); + } + 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 ) + break; + + nuni = TT_NEXT_UINT24( p ); + p += 2; + } + } + + 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) tt_cmap14_done, + (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 +2995,10 @@ &tt_cmap12_class_rec, #endif +#ifdef TT_CONFIG_CMAP_FORMAT_14 + &tt_cmap14_class_rec, +#endif + NULL, }; @@ -2318,6 +3075,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 +3095,12 @@ break; } } + + if ( *pclazz == NULL ) + { + FT_ERROR(( "tt_face_build_cmaps:" )); + FT_ERROR(( " unsupported cmap sub-table ignored!\n" )); + } } } diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c index abe0278..6b7c342 100644 --- a/src/sfnt/ttload.c +++ b/src/sfnt/ttload.c @@ -5,7 +5,7 @@ /* Load the basic TrueType tables, i.e., tables that can be either in */ /* TTF or OTF fonts (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -618,6 +618,15 @@ if ( maxProfile->maxFunctionDefs == 0 ) maxProfile->maxFunctionDefs = 64; + + /* we add 4 phantom points later */ + if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) ) + { + FT_ERROR(( "Too much twilight points in `maxp' table;\n" )); + FT_ERROR(( " some glyphs might be rendered incorrectly.\n" )); + + maxProfile->maxTwilightPoints = 0xFFFFU - 4; + } } FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs )); diff --git a/src/sfnt/ttmtx.c b/src/sfnt/ttmtx.c index 286bd0c..55f681a 100644 --- a/src/sfnt/ttmtx.c +++ b/src/sfnt/ttmtx.c @@ -431,7 +431,8 @@ { void* v = &face->vertical; void* h = &face->horizontal; - TT_HoriHeader* header = vertical ? (TT_HoriHeader*)v : h; + TT_HoriHeader* header = vertical ? (TT_HoriHeader*)v + : (TT_HoriHeader*)h; TT_LongMetrics longs_m; FT_UShort k = header->number_Of_HMetrics; diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c index eff49da..8261ba5 100644 --- a/src/sfnt/ttsbit.c +++ b/src/sfnt/ttsbit.c @@ -382,8 +382,9 @@ break; case 5: - error = Load_SBit_Const_Metrics( range, stream ) || - Load_SBit_Range_Codes( range, stream, 0 ); + error = Load_SBit_Const_Metrics( range, stream ); + if ( !error ) + error = Load_SBit_Range_Codes( range, stream, 0 ); break; default: diff --git a/src/sfnt/ttsbit0.c b/src/sfnt/ttsbit0.c index f8adc64..37c7a9b 100644 --- a/src/sfnt/ttsbit0.c +++ b/src/sfnt/ttsbit0.c @@ -5,7 +5,7 @@ /* TrueType and OpenType embedded bitmap support (body). */ /* This is a heap-optimized version. */ /* */ -/* Copyright 2005, 2006, 2007 by */ +/* Copyright 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -207,7 +207,7 @@ } - typedef struct + typedef struct TT_SBitDecoderRec_ { TT_Face face; FT_Stream stream; -- cgit v1.2.3