From 295ffce55e0198e7a9f7d46b33f5c2b4147bf821 Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Wed, 3 Mar 2010 14:24:57 -0800 Subject: Update to FreeType 2.3.12 --- src/sfnt/sfdriver.c | 194 ++++++++--------- src/sfnt/sfdriver.h | 2 +- src/sfnt/sfnt.c | 1 + src/sfnt/sfntpic.c | 101 +++++++++ src/sfnt/sfntpic.h | 88 ++++++++ src/sfnt/sfobjs.c | 35 +++- src/sfnt/ttbdf.c | 16 +- src/sfnt/ttcmap.c | 591 ++++++++++++++++++++++++++++++++++++++++------------ src/sfnt/ttcmap.h | 40 ++++ src/sfnt/ttcmapc.h | 55 +++++ src/sfnt/ttkern.c | 13 +- src/sfnt/ttload.c | 25 ++- src/sfnt/ttmtx.c | 6 +- src/sfnt/ttpost.c | 3 +- src/sfnt/ttsbit.c | 2 +- src/sfnt/ttsbit0.c | 56 ++++- 16 files changed, 952 insertions(+), 276 deletions(-) create mode 100644 src/sfnt/sfntpic.c create mode 100644 src/sfnt/sfntpic.h create mode 100644 src/sfnt/ttcmapc.h (limited to 'src/sfnt') diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c index 142ef76..1097efb 100644 --- a/src/sfnt/sfdriver.c +++ b/src/sfnt/sfdriver.c @@ -17,12 +17,14 @@ #include +#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_SFNT_H #include FT_INTERNAL_OBJECTS_H #include "sfdriver.h" #include "ttload.h" #include "sfobjs.h" +#include "sfntpic.h" #include "sferrors.h" @@ -48,6 +50,15 @@ #include FT_SERVICE_SFNT_H #include FT_SERVICE_TT_CMAP_H + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_sfdriver + /* * SFNT TABLE SERVICE @@ -103,27 +114,28 @@ sfnt_table_info( TT_Face face, FT_UInt idx, FT_ULong *tag, + FT_ULong *offset, FT_ULong *length ) { - if ( !tag || !length ) + if ( !tag || !offset || !length ) return SFNT_Err_Invalid_Argument; if ( idx >= face->num_tables ) return SFNT_Err_Table_Missing; *tag = face->dir_tables[idx].Tag; + *offset = face->dir_tables[idx].Offset; *length = face->dir_tables[idx].Length; return SFNT_Err_Ok; } - static const FT_Service_SFNT_TableRec sfnt_service_sfnt_table = - { + FT_DEFINE_SERVICE_SFNT_TABLEREC(sfnt_service_sfnt_table, (FT_SFNT_TableLoadFunc)tt_face_load_any, (FT_SFNT_TableGetFunc) get_sfnt_table, (FT_SFNT_TableInfoFunc)sfnt_table_info - }; + ) #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES @@ -155,11 +167,19 @@ sfnt_get_name_index( TT_Face face, FT_String* glyph_name ) { - FT_Face root = &face->root; - FT_Long i; + FT_Face root = &face->root; + FT_UInt i, max_gid = FT_UINT_MAX; + + if ( root->num_glyphs < 0 ) + return 0; + else if ( ( FT_ULong ) root->num_glyphs < FT_UINT_MAX ) + max_gid = ( FT_UInt ) root->num_glyphs; + else + FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n", + FT_UINT_MAX, root->num_glyphs )); - for ( i = 0; i < root->num_glyphs; i++ ) + for ( i = 0; i < max_gid; i++ ) { FT_String* gname; FT_Error error = tt_face_get_ps_name( face, i, &gname ); @@ -169,18 +189,17 @@ continue; if ( !ft_strcmp( glyph_name, gname ) ) - return (FT_UInt)i; + return i; } return 0; } - static const FT_Service_GlyphDictRec sfnt_service_glyph_dict = - { + FT_DEFINE_SERVICE_GLYPHDICTREC(sfnt_service_glyph_dict, (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index - }; + ) #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ @@ -300,19 +319,17 @@ return result; } - static const FT_Service_PsFontNameRec sfnt_service_ps_name = - { + FT_DEFINE_SERVICE_PSFONTNAMEREC(sfnt_service_ps_name, (FT_PsName_GetFunc)sfnt_get_ps_name - }; + ) /* * TT CMAP INFO */ - static const FT_Service_TTCMapsRec tt_service_get_cmap_info = - { + FT_DEFINE_SERVICE_TTCMAPSREC(tt_service_get_cmap_info, (TT_CMap_Info_GetFunc)tt_get_cmap_info - }; + ) #ifdef TT_CONFIG_OPTION_BDF @@ -353,11 +370,10 @@ } - static const FT_Service_BDFRec sfnt_service_bdf = - { + FT_DEFINE_SERVICE_BDFRec(sfnt_service_bdf, (FT_BDF_GetCharsetIdFunc) sfnt_get_charset_id, - (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop, - }; + (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop + ) #endif /* TT_CONFIG_OPTION_BDF */ @@ -366,20 +382,35 @@ * SERVICE LIST */ - static const FT_ServiceDescRec sfnt_services[] = - { - { FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table }, - { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name }, -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - { FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict }, -#endif -#ifdef TT_CONFIG_OPTION_BDF - { FT_SERVICE_ID_BDF, &sfnt_service_bdf }, +#if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF + FT_DEFINE_SERVICEDESCREC5(sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET, + FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET + ) +#elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES + FT_DEFINE_SERVICEDESCREC4(sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET + ) +#elif defined TT_CONFIG_OPTION_BDF + FT_DEFINE_SERVICEDESCREC4(sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET, + FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET + ) +#else + FT_DEFINE_SERVICEDESCREC3(sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET + ) #endif - { FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info }, - - { NULL, NULL } - }; FT_CALLBACK_DEF( FT_Module_Interface ) @@ -388,7 +419,7 @@ { FT_UNUSED( module ); - return ft_service_list_lookup( sfnt_services, module_interface ); + return ft_service_list_lookup( FT_SFNT_SERVICES_GET, module_interface ); } @@ -519,10 +550,18 @@ #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#define PUT_EMBEDDED_BITMAPS(a) a +#else +#define PUT_EMBEDDED_BITMAPS(a) 0 +#endif +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES +#define PUT_PS_NAMES(a) a +#else +#define PUT_PS_NAMES(a) 0 +#endif - static - const SFNT_Interface sfnt_interface = - { + FT_DEFINE_SFNT_INTERFACE(sfnt_interface, tt_face_goto_table, sfnt_init_face, @@ -532,10 +571,8 @@ tt_face_load_any, -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_load_sfnt_header_stub, - tt_face_load_directory_stub, -#endif + tt_face_load_sfnt_header_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_load_directory_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ tt_face_load_head, tt_face_load_hhea, @@ -547,53 +584,32 @@ tt_face_load_name, tt_face_free_name, -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_load_hdmx_stub, - tt_face_free_hdmx_stub, -#endif + tt_face_load_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_free_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ tt_face_load_kern, tt_face_load_gasp, tt_face_load_pclt, -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS /* see `ttload.h' */ - tt_face_load_bhed, -#else - 0, -#endif + PUT_EMBEDDED_BITMAPS(tt_face_load_bhed), -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_set_sbit_strike_stub, - tt_face_load_sbit_stub, + tt_face_set_sbit_strike_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_load_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ - tt_find_sbit_image, - tt_load_sbit_metrics, -#endif + tt_find_sbit_image, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_load_sbit_metrics, /* FT_CONFIG_OPTION_OLD_INTERNALS */ -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - tt_face_load_sbit_image, -#else - 0, -#endif + PUT_EMBEDDED_BITMAPS(tt_face_load_sbit_image), -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_free_sbit_stub, -#endif + tt_face_free_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES /* see `ttpost.h' */ - tt_face_get_ps_name, - tt_face_free_ps_names, -#else - 0, - 0, -#endif + PUT_PS_NAMES(tt_face_get_ps_name), + PUT_PS_NAMES(tt_face_free_ps_names), -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_load_charmap_stub, - tt_face_free_charmap_stub, -#endif + tt_face_load_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_free_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ /* since version 2.1.8 */ @@ -604,27 +620,19 @@ tt_face_load_font_dir, tt_face_load_hmtx, -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS /* see `ttsbit.h' and `sfnt.h' */ - tt_face_load_eblc, - tt_face_free_eblc, + PUT_EMBEDDED_BITMAPS(tt_face_load_eblc), + PUT_EMBEDDED_BITMAPS(tt_face_free_eblc), - tt_face_set_sbit_strike, - tt_face_load_strike_metrics, -#else - 0, - 0, - 0, - 0, -#endif + PUT_EMBEDDED_BITMAPS(tt_face_set_sbit_strike), + PUT_EMBEDDED_BITMAPS(tt_face_load_strike_metrics), tt_face_get_metrics - }; + ) - FT_CALLBACK_TABLE_DEF - const FT_Module_Class sfnt_module_class = - { + FT_DEFINE_MODULE(sfnt_module_class, + 0, /* not a font driver or renderer */ sizeof( FT_ModuleRec ), @@ -632,12 +640,12 @@ 0x10000L, /* driver version 1.0 */ 0x20000L, /* driver requires FreeType 2.0 or higher */ - (const void*)&sfnt_interface, /* module specific interface */ + (const void*)&FT_SFNT_INTERFACE_GET, /* module specific interface */ (FT_Module_Constructor)0, (FT_Module_Destructor) 0, (FT_Module_Requester) sfnt_get_interface - }; + ) /* END */ diff --git a/src/sfnt/sfdriver.h b/src/sfnt/sfdriver.h index 92db796..5de25d5 100644 --- a/src/sfnt/sfdriver.h +++ b/src/sfnt/sfdriver.h @@ -27,7 +27,7 @@ FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Module_Class ) sfnt_module_class; + FT_DECLARE_MODULE( sfnt_module_class ) FT_END_HEADER diff --git a/src/sfnt/sfnt.c b/src/sfnt/sfnt.c index 45a820b..fc507b4 100644 --- a/src/sfnt/sfnt.c +++ b/src/sfnt/sfnt.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include +#include "sfntpic.c" #include "ttload.c" #include "ttmtx.c" #include "ttcmap.c" diff --git a/src/sfnt/sfntpic.c b/src/sfnt/sfntpic.c new file mode 100644 index 0000000..fd3cf4e --- /dev/null +++ b/src/sfnt/sfntpic.c @@ -0,0 +1,101 @@ +/***************************************************************************/ +/* */ +/* sfntpic.c */ +/* */ +/* The FreeType position independent code services for sfnt module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#include +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "sfntpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from sfdriver.c */ + FT_Error FT_Create_Class_sfnt_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_sfnt_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_sfnt_service_bdf( FT_Service_BDFRec*); + void FT_Init_Class_sfnt_interface( FT_Library, SFNT_Interface*); + void FT_Init_Class_sfnt_service_glyph_dict( FT_Library, FT_Service_GlyphDictRec*); + void FT_Init_Class_sfnt_service_ps_name( FT_Library, FT_Service_PsFontNameRec*); + void FT_Init_Class_tt_service_get_cmap_info( FT_Library, FT_Service_TTCMapsRec*); + void FT_Init_Class_sfnt_service_sfnt_table( FT_Service_SFNT_TableRec*); + + /* forward declaration of PIC init functions from ttcmap.c */ + FT_Error FT_Create_Class_tt_cmap_classes( FT_Library, TT_CMap_Class**); + void FT_Destroy_Class_tt_cmap_classes( FT_Library, TT_CMap_Class*); + + void + sfnt_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->sfnt ) + { + sfntModulePIC* container = (sfntModulePIC*)pic_container->sfnt; + if(container->sfnt_services) + FT_Destroy_Class_sfnt_services(library, container->sfnt_services); + container->sfnt_services = NULL; + if(container->tt_cmap_classes) + FT_Destroy_Class_tt_cmap_classes(library, container->tt_cmap_classes); + container->tt_cmap_classes = NULL; + FT_FREE( container ); + pic_container->sfnt = NULL; + } + } + + + FT_Error + sfnt_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + sfntModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->sfnt = container; + + /* initialize pointer table - this is how the module usually expects this data */ + error = FT_Create_Class_sfnt_services(library, &container->sfnt_services); + if(error) + goto Exit; + error = FT_Create_Class_tt_cmap_classes(library, &container->tt_cmap_classes); + if(error) + goto Exit; + FT_Init_Class_sfnt_service_glyph_dict(library, &container->sfnt_service_glyph_dict); + FT_Init_Class_sfnt_service_ps_name(library, &container->sfnt_service_ps_name); + FT_Init_Class_tt_service_get_cmap_info(library, &container->tt_service_get_cmap_info); + FT_Init_Class_sfnt_service_sfnt_table(&container->sfnt_service_sfnt_table); +#ifdef TT_CONFIG_OPTION_BDF + FT_Init_Class_sfnt_service_bdf(&container->sfnt_service_bdf); +#endif + FT_Init_Class_sfnt_interface(library, &container->sfnt_interface); + +Exit: + if(error) + sfnt_module_class_pic_free(library); + return error; + } + + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/src/sfnt/sfntpic.h b/src/sfnt/sfntpic.h new file mode 100644 index 0000000..6943b42 --- /dev/null +++ b/src/sfnt/sfntpic.h @@ -0,0 +1,88 @@ +/***************************************************************************/ +/* */ +/* sfntpic.h */ +/* */ +/* The FreeType position independent code services for sfnt module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __SFNTPIC_H__ +#define __SFNTPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + + #ifndef FT_CONFIG_OPTION_PIC +#define FT_SFNT_SERVICES_GET sfnt_services +#define FT_SFNT_SERVICE_GLYPH_DICT_GET sfnt_service_glyph_dict +#define FT_SFNT_SERVICE_PS_NAME_GET sfnt_service_ps_name +#define FT_TT_SERVICE_GET_CMAP_INFO_GET tt_service_get_cmap_info +#define FT_SFNT_SERVICES_GET sfnt_services +#define FT_TT_CMAP_CLASSES_GET tt_cmap_classes +#define FT_SFNT_SERVICE_SFNT_TABLE_GET sfnt_service_sfnt_table +#define FT_SFNT_SERVICE_BDF_GET sfnt_service_bdf +#define FT_SFNT_INTERFACE_GET sfnt_interface + +#else /* FT_CONFIG_OPTION_PIC */ + +/* some include files required for members of sfntModulePIC */ +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_SFNT_H +#include FT_SERVICE_TT_CMAP_H +#ifdef TT_CONFIG_OPTION_BDF +#include "ttbdf.h" +#include FT_SERVICE_BDF_H +#endif +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include "ttcmap.h" + +typedef struct sfntModulePIC_ + { + FT_ServiceDescRec* sfnt_services; + FT_Service_GlyphDictRec sfnt_service_glyph_dict; + FT_Service_PsFontNameRec sfnt_service_ps_name; + FT_Service_TTCMapsRec tt_service_get_cmap_info; + TT_CMap_Class* tt_cmap_classes; + FT_Service_SFNT_TableRec sfnt_service_sfnt_table; +#ifdef TT_CONFIG_OPTION_BDF + FT_Service_BDFRec sfnt_service_bdf; +#endif + SFNT_Interface sfnt_interface; + } sfntModulePIC; + +#define GET_PIC(lib) ((sfntModulePIC*)((lib)->pic_container.sfnt)) +#define FT_SFNT_SERVICES_GET (GET_PIC(library)->sfnt_services) +#define FT_SFNT_SERVICE_GLYPH_DICT_GET (GET_PIC(library)->sfnt_service_glyph_dict) +#define FT_SFNT_SERVICE_PS_NAME_GET (GET_PIC(library)->sfnt_service_ps_name) +#define FT_TT_SERVICE_GET_CMAP_INFO_GET (GET_PIC(library)->tt_service_get_cmap_info) +#define FT_SFNT_SERVICES_GET (GET_PIC(library)->sfnt_services) +#define FT_TT_CMAP_CLASSES_GET (GET_PIC(library)->tt_cmap_classes) +#define FT_SFNT_SERVICE_SFNT_TABLE_GET (GET_PIC(library)->sfnt_service_sfnt_table) +#define FT_SFNT_SERVICE_BDF_GET (GET_PIC(library)->sfnt_service_bdf) +#define FT_SFNT_INTERFACE_GET (GET_PIC(library)->sfnt_interface) + +#endif /* FT_CONFIG_OPTION_PIC */ + +/* */ + +FT_END_HEADER + +#endif /* __SFNTPIC_H__ */ + + +/* END */ diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c index c826b92..b74b1a9 100644 --- a/src/sfnt/sfobjs.c +++ b/src/sfnt/sfobjs.c @@ -26,6 +26,7 @@ #include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_SFNT_NAMES_H #include "sferrors.h" #ifdef TT_CONFIG_OPTION_BDF @@ -527,13 +528,27 @@ #endif FT_Bool has_outline; FT_Bool is_apple_sbit; + FT_Bool ignore_preferred_family = FALSE; + FT_Bool ignore_preferred_subfamily = FALSE; SFNT_Service sfnt = (SFNT_Service)face->sfnt; FT_UNUSED( face_index ); - FT_UNUSED( num_params ); - FT_UNUSED( params ); + /* Check parameters */ + + { + FT_Int i; + + + for ( i = 0; i < num_params; i++ ) + { + if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY ) + ignore_preferred_family = TRUE; + else if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY ) + ignore_preferred_subfamily = TRUE; + } + } /* Load tables */ @@ -722,26 +737,30 @@ /* Foundation (WPF). This flag has been introduced in version */ /* 1.5 of the OpenType specification (May 2008). */ + face->root.family_name = NULL; + face->root.style_name = NULL; if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 ) { - GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); + if ( !ignore_preferred_family ) + GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); if ( !face->root.family_name ) GET_NAME( FONT_FAMILY, &face->root.family_name ); - GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); + if ( !ignore_preferred_subfamily ) + GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); if ( !face->root.style_name ) GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); } else { GET_NAME( WWS_FAMILY, &face->root.family_name ); - if ( !face->root.family_name ) + if ( !face->root.family_name && !ignore_preferred_family ) GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); if ( !face->root.family_name ) GET_NAME( FONT_FAMILY, &face->root.family_name ); GET_NAME( WWS_SUBFAMILY, &face->root.style_name ); - if ( !face->root.style_name ) + if ( !face->root.style_name && !ignore_preferred_subfamily ) GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); if ( !face->root.style_name ) GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); @@ -749,8 +768,8 @@ /* now set up root fields */ { - FT_Face root = &face->root; - FT_Int32 flags = root->face_flags; + FT_Face root = &face->root; + FT_Long flags = root->face_flags; /*********************************************************************/ diff --git a/src/sfnt/ttbdf.c b/src/sfnt/ttbdf.c index 6c95387..206cece 100644 --- a/src/sfnt/ttbdf.c +++ b/src/sfnt/ttbdf.c @@ -84,7 +84,7 @@ FT_Byte* p = bdf->table; FT_UInt version = FT_NEXT_USHORT( p ); FT_UInt num_strikes = FT_NEXT_USHORT( p ); - FT_UInt32 strings = FT_NEXT_ULONG ( p ); + FT_ULong strings = FT_NEXT_ULONG ( p ); FT_UInt count; FT_Byte* strike; @@ -141,13 +141,13 @@ const char* property_name, BDF_PropertyRec *aprop ) { - TT_BDF bdf = &face->bdf; - FT_Size size = FT_FACE(face)->size; - FT_Error error = 0; - FT_Byte* p; - FT_UInt count; - FT_Byte* strike; - FT_UInt property_len; + TT_BDF bdf = &face->bdf; + FT_Size size = FT_FACE(face)->size; + FT_Error error = 0; + FT_Byte* p; + FT_UInt count; + FT_Byte* strike; + FT_Offset property_len; aprop->type = BDF_PROPERTY_TYPE_NONE; diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c index 6830391..b283f6d 100644 --- a/src/sfnt/ttcmap.c +++ b/src/sfnt/ttcmap.c @@ -25,6 +25,7 @@ #include FT_INTERNAL_STREAM_H #include "ttload.h" #include "ttcmap.h" +#include "sfntpic.h" /*************************************************************************/ @@ -124,7 +125,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap0_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -157,17 +158,14 @@ FT_Byte* p = cmap->data + 4; - cmap_info->format = 0; + cmap_info->format = 0; cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap0_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap0_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, @@ -176,11 +174,11 @@ (FT_CMap_CharNextFunc) tt_cmap0_char_next, NULL, NULL, NULL, NULL, NULL - }, + , 0, (TT_CMap_ValidateFunc) tt_cmap0_validate, (TT_CMap_Info_GetFunc) tt_cmap0_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_0 */ @@ -462,7 +460,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap2_char_next( TT_CMap cmap, FT_UInt32 *pcharcode ) { @@ -536,17 +534,14 @@ FT_Byte* p = cmap->data + 4; - cmap_info->format = 2; + cmap_info->format = 2; cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap2_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap2_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, @@ -555,11 +550,11 @@ (FT_CMap_CharNextFunc) tt_cmap2_char_next, NULL, NULL, NULL, NULL, NULL - }, + , 2, (TT_CMap_ValidateFunc) tt_cmap2_validate, (TT_CMap_Info_GetFunc) tt_cmap2_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_2 */ @@ -664,7 +659,7 @@ p = table + 6; cmap->num_ranges = FT_PEEK_USHORT( p ) >> 1; - cmap->cur_charcode = 0xFFFFFFFFUL; + cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; cmap->cur_gindex = 0; return SFNT_Err_Ok; @@ -742,7 +737,7 @@ if ( cmap->cur_charcode >= 0xFFFFUL ) goto Fail; - charcode = cmap->cur_charcode + 1; + charcode = (FT_UInt)cmap->cur_charcode + 1; if ( charcode < cmap->cur_start ) charcode = cmap->cur_start; @@ -804,7 +799,7 @@ } Fail: - cmap->cur_charcode = 0xFFFFFFFFUL; + cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; cmap->cur_gindex = 0; } @@ -1093,7 +1088,7 @@ FT_UInt num_segs2, start, end, offset; FT_Int delta; FT_UInt max, min, mid, num_segs; - FT_UInt charcode = *pcharcode; + FT_UInt charcode = (FT_UInt)*pcharcode; FT_UInt gindex = 0; FT_Byte* p; @@ -1335,7 +1330,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap4_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -1375,17 +1370,14 @@ FT_Byte* p = cmap->data + 4; - cmap_info->format = 4; + cmap_info->format = 4; cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap4_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap4_class_rec, sizeof ( TT_CMap4Rec ), (FT_CMap_InitFunc) tt_cmap4_init, (FT_CMap_DoneFunc) NULL, @@ -1393,11 +1385,11 @@ (FT_CMap_CharNextFunc) tt_cmap4_char_next, NULL, NULL, NULL, NULL, NULL - }, + , 4, (TT_CMap_ValidateFunc) tt_cmap4_validate, (TT_CMap_Info_GetFunc) tt_cmap4_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_4 */ @@ -1489,7 +1481,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap6_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -1537,17 +1529,14 @@ FT_Byte* p = cmap->data + 4; - cmap_info->format = 6; + cmap_info->format = 6; cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap6_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap6_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, @@ -1556,11 +1545,11 @@ (FT_CMap_CharNextFunc) tt_cmap6_char_next, NULL, NULL, NULL, NULL, NULL - }, + , 6, (TT_CMap_ValidateFunc) tt_cmap6_validate, (TT_CMap_Info_GetFunc) tt_cmap6_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_6 */ @@ -1635,7 +1624,7 @@ FT_INVALID_TOO_SHORT; length = TT_NEXT_ULONG( p ); - if ( table + length > valid->limit || length < 8208 ) + if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 ) FT_INVALID_TOO_SHORT; is32 = table + 12; @@ -1745,7 +1734,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap8_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -1793,17 +1782,14 @@ FT_Byte* p = cmap->data + 8; - cmap_info->format = 8; + cmap_info->format = 8; cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap8_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap8_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, @@ -1812,11 +1798,11 @@ (FT_CMap_CharNextFunc) tt_cmap8_char_next, NULL, NULL, NULL, NULL, NULL - }, + , 8, (TT_CMap_ValidateFunc) tt_cmap8_validate, (TT_CMap_Info_GetFunc) tt_cmap8_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_8 */ @@ -1863,7 +1849,8 @@ p = table + 16; count = TT_NEXT_ULONG( p ); - if ( table + length > valid->limit || length < 20 + count * 2 ) + if ( length > (FT_ULong)( valid->limit - table ) || + length < 20 + count * 2 ) FT_INVALID_TOO_SHORT; /* check glyph indices */ @@ -1905,7 +1892,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap10_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -1944,17 +1931,14 @@ FT_Byte* p = cmap->data + 8; - cmap_info->format = 10; + cmap_info->format = 10; cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap10_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap10_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, @@ -1963,11 +1947,11 @@ (FT_CMap_CharNextFunc) tt_cmap10_char_next, NULL, NULL, NULL, NULL, NULL - }, + , 10, (TT_CMap_ValidateFunc) tt_cmap10_validate, (TT_CMap_Info_GetFunc) tt_cmap10_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_10 */ @@ -2048,7 +2032,8 @@ p = table + 12; num_groups = TT_NEXT_ULONG( p ); - if ( table + length > valid->limit || length < 16 + 12 * num_groups ) + if ( length > (FT_ULong)( valid->limit - table ) || + length < 16 + 12 * num_groups ) FT_INVALID_TOO_SHORT; /* check groups, they must be in increasing order */ @@ -2225,7 +2210,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap12_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -2243,8 +2228,10 @@ if ( cmap12->valid ) { gindex = cmap12->cur_gindex; + + /* XXX: check cur_charcode overflow is expected */ if ( gindex ) - *pchar_code = cmap12->cur_charcode; + *pchar_code = (FT_UInt32)cmap12->cur_charcode; } else gindex = 0; @@ -2252,7 +2239,8 @@ else gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 ); - return gindex; + /* XXX: check gindex overflow is expected */ + return (FT_UInt32)gindex; } @@ -2263,17 +2251,14 @@ FT_Byte* p = cmap->data + 8; - cmap_info->format = 12; + cmap_info->format = 12; cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap12_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap12_class_rec, sizeof ( TT_CMap12Rec ), (FT_CMap_InitFunc) tt_cmap12_init, @@ -2282,15 +2267,331 @@ (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 13 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 13 */ + /* reserved 2 USHORT reserved */ + /* length 4 ULONG length in bytes */ + /* language 8 ULONG Mac language code */ + /* count 12 ULONG number of groups */ + /* 16 */ + /* */ + /* This header is followed by `count' groups of the following format: */ + /* */ + /* start 0 ULONG first charcode */ + /* end 4 ULONG last charcode */ + /* glyphId 8 ULONG glyph ID for the whole group */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_13 + + typedef struct TT_CMap13Rec_ + { + TT_CMapRec cmap; + FT_Bool valid; + FT_ULong cur_charcode; + FT_UInt cur_gindex; + FT_ULong cur_group; + FT_ULong num_groups; + + } TT_CMap13Rec, *TT_CMap13; + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_init( TT_CMap13 cmap, + FT_Byte* table ) + { + cmap->cmap.data = table; + + table += 12; + cmap->num_groups = FT_PEEK_ULONG( table ); + + cmap->valid = 0; + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p; + FT_ULong length; + FT_ULong num_groups; + + + if ( table + 16 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 4; + length = TT_NEXT_ULONG( p ); + + p = table + 12; + num_groups = TT_NEXT_ULONG( p ); + + if ( length > (FT_ULong)( valid->limit - table ) || + length < 16 + 12 * num_groups ) + FT_INVALID_TOO_SHORT; + + /* check groups, they must be in increasing order */ + { + FT_ULong n, start, end, glyph_id, last = 0; + + + for ( n = 0; n < num_groups; n++ ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + glyph_id = TT_NEXT_ULONG( p ); + + if ( start > end ) + FT_INVALID_DATA; + + if ( n > 0 && start <= last ) + FT_INVALID_DATA; + + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + + last = end; + } + } + + return SFNT_Err_Ok; + } + + + /* search the index of the charcode next to cmap->cur_charcode */ + /* cmap->cur_group should be set up properly by caller */ + /* */ + static void + tt_cmap13_next( TT_CMap13 cmap ) + { + FT_Byte* p; + FT_ULong start, end, glyph_id, char_code; + FT_ULong n; + FT_UInt gindex; + + + if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) + goto Fail; + + char_code = cmap->cur_charcode + 1; + + n = cmap->cur_group; + + for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) + { + p = cmap->cmap.data + 16 + 12 * n; + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + glyph_id = TT_PEEK_ULONG( p ); + + if ( char_code < start ) + char_code = start; + + if ( char_code <= end ) + { + gindex = (FT_UInt)glyph_id; + + if ( gindex ) + { + cmap->cur_charcode = char_code;; + cmap->cur_gindex = gindex; + cmap->cur_group = n; + + return; + } + } + } + + Fail: + cmap->valid = 0; + } + + + static FT_UInt + tt_cmap13_char_map_binary( TT_CMap cmap, + FT_UInt32* pchar_code, + FT_Bool next ) + { + FT_UInt gindex = 0; + FT_Byte* p = cmap->data + 12; + FT_UInt32 num_groups = TT_PEEK_ULONG( p ); + FT_UInt32 char_code = *pchar_code; + FT_UInt32 start, end; + FT_UInt32 max, min, mid; + + + if ( !num_groups ) + return 0; + + /* make compiler happy */ + mid = num_groups; + end = 0xFFFFFFFFUL; + + if ( next ) + char_code++; + + min = 0; + max = num_groups; + + /* binary search */ + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = cmap->data + 16 + 12 * mid; + + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + + if ( char_code < start ) + max = mid; + else if ( char_code > end ) + min = mid + 1; + else + { + gindex = (FT_UInt)TT_PEEK_ULONG( p ); + + break; + } + } + + if ( next ) + { + TT_CMap13 cmap13 = (TT_CMap13)cmap; + + + /* if `char_code' is not in any group, then `mid' is */ + /* the group nearest to `char_code' */ + /* */ + + if ( char_code > end ) + { + mid++; + if ( mid == num_groups ) + return 0; + } + + cmap13->valid = 1; + cmap13->cur_charcode = char_code; + cmap13->cur_group = mid; + + if ( !gindex ) + { + tt_cmap13_next( cmap13 ); + + if ( cmap13->valid ) + gindex = cmap13->cur_gindex; + } + else + cmap13->cur_gindex = gindex; + + if ( gindex ) + *pchar_code = cmap13->cur_charcode; + } + + return gindex; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap13_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + return tt_cmap13_char_map_binary( cmap, &char_code, 0 ); + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap13_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + TT_CMap13 cmap13 = (TT_CMap13)cmap; + FT_UInt gindex; + + + if ( cmap13->cur_charcode >= 0xFFFFFFFFUL ) + return 0; + + /* no need to search */ + if ( cmap13->valid && cmap13->cur_charcode == *pchar_code ) + { + tt_cmap13_next( cmap13 ); + if ( cmap13->valid ) + { + gindex = cmap13->cur_gindex; + if ( gindex ) + *pchar_code = cmap13->cur_charcode; + } + else + gindex = 0; + } + else + gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 ); + + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->format = 13; + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + + return SFNT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP(tt_cmap13_class_rec, + sizeof ( TT_CMap13Rec ), + + (FT_CMap_InitFunc) tt_cmap13_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap13_char_index, + (FT_CMap_CharNextFunc) tt_cmap13_char_next, + + NULL, NULL, NULL, NULL, NULL + , + 13, + (TT_CMap_ValidateFunc) tt_cmap13_validate, + (TT_CMap_Info_GetFunc) tt_cmap13_get_info + ) + +#endif /* TT_CONFIG_CMAP_FORMAT_13 */ + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -2363,7 +2664,7 @@ * cmap 14 query functions. The data is overwritten * on each call to these functions. */ - FT_UInt max_results; + FT_UInt32 max_results; FT_UInt32* results; FT_Memory memory; @@ -2384,10 +2685,10 @@ static FT_Error tt_cmap14_ensure( TT_CMap14 cmap, - FT_UInt num_results, + FT_UInt32 num_results, FT_Memory memory ) { - FT_UInt old_max = cmap->max_results; + FT_UInt32 old_max = cmap->max_results; FT_Error error = 0; @@ -2429,7 +2730,8 @@ FT_ULong num_selectors = TT_NEXT_ULONG( p ); - if ( table + length > valid->limit || length < 10 + 11 * num_selectors ) + if ( length > (FT_ULong)( valid->limit - table ) || + length < 10 + 11 * num_selectors ) FT_INVALID_TOO_SHORT; /* check selectors, they must be in increasing order */ @@ -2491,7 +2793,7 @@ FT_ULong i, lastUni = 0; - if ( ndp + numMappings * 4 > valid->limit ) + if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) ) FT_INVALID_TOO_SHORT; for ( i = 0; i < numMappings; ++i ) @@ -2532,7 +2834,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap14_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -2550,7 +2852,7 @@ { FT_UNUSED( cmap ); - cmap_info->format = 14; + cmap_info->format = 14; /* subtable 14 does not define a language field */ cmap_info->language = 0xFFFFFFFFUL; @@ -2610,7 +2912,7 @@ { FT_UInt32 mid = ( min + max ) >> 1; FT_Byte* p = base + 5 * mid; - FT_UInt32 uni = TT_NEXT_UINT24( p ); + FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); if ( char_code < uni ) @@ -2659,10 +2961,10 @@ FT_CALLBACK_DEF( FT_UInt ) - tt_cmap14_char_var_index( TT_CMap cmap, - TT_CMap ucmap, - FT_ULong charcode, - FT_ULong variantSelector) + tt_cmap14_char_var_index( TT_CMap cmap, + TT_CMap ucmap, + FT_UInt32 charcode, + FT_UInt32 variantSelector) { FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); FT_ULong defOff; @@ -2692,9 +2994,9 @@ FT_CALLBACK_DEF( FT_Int ) - tt_cmap14_char_var_isdefault( TT_CMap cmap, - FT_ULong charcode, - FT_ULong variantSelector ) + tt_cmap14_char_var_isdefault( TT_CMap cmap, + FT_UInt32 charcode, + FT_UInt32 variantSelector ) { FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); FT_ULong defOff; @@ -2725,10 +3027,10 @@ FT_Memory memory ) { TT_CMap14 cmap14 = (TT_CMap14)cmap; - FT_UInt count = cmap14->num_selectors; + FT_UInt32 count = cmap14->num_selectors; FT_Byte* p = cmap->data + 10; FT_UInt32* result; - FT_UInt i; + FT_UInt32 i; if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) @@ -2737,7 +3039,7 @@ result = cmap14->results; for ( i = 0; i < count; ++i ) { - result[i] = TT_NEXT_UINT24( p ); + result[i] = (FT_UInt32)TT_NEXT_UINT24( p ); p += 8; } result[i] = 0; @@ -2749,10 +3051,10 @@ FT_CALLBACK_DEF( FT_UInt32 * ) tt_cmap14_char_variants( TT_CMap cmap, FT_Memory memory, - FT_ULong charCode ) + FT_UInt32 charCode ) { TT_CMap14 cmap14 = (TT_CMap14) cmap; - FT_UInt count = cmap14->num_selectors; + FT_UInt32 count = cmap14->num_selectors; FT_Byte* p = cmap->data + 10; FT_UInt32* q; @@ -2787,7 +3089,7 @@ static FT_UInt tt_cmap14_def_char_count( FT_Byte *p ) { - FT_UInt32 numRanges = TT_NEXT_ULONG( p ); + FT_UInt32 numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); FT_UInt tot = 0; @@ -2814,14 +3116,14 @@ cnt = tt_cmap14_def_char_count( p ); - numRanges = TT_NEXT_ULONG( p ); + numRanges = (FT_UInt32)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 ); + FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); cnt = FT_NEXT_BYTE( p ) + 1; @@ -2849,7 +3151,7 @@ FT_UInt32 *ret; - numMappings = TT_NEXT_ULONG( p ); + numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) ) return NULL; @@ -2857,7 +3159,7 @@ ret = cmap14->results; for ( i = 0; i < numMappings; ++i ) { - ret[i] = TT_NEXT_UINT24( p ); + ret[i] = (FT_UInt32)TT_NEXT_UINT24( p ); p += 2; } ret[i] = 0; @@ -2869,7 +3171,7 @@ FT_CALLBACK_DEF( FT_UInt32 * ) tt_cmap14_variant_chars( TT_CMap cmap, FT_Memory memory, - FT_ULong variantSelector ) + FT_UInt32 variantSelector ) { FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); @@ -2911,9 +3213,9 @@ p = cmap->data + nondefOff; dp = cmap->data + defOff; - numMappings = TT_NEXT_ULONG( p ); + numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); dcnt = tt_cmap14_def_char_count( dp ); - numRanges = TT_NEXT_ULONG( dp ); + numRanges = (FT_UInt32)TT_NEXT_ULONG( dp ); if ( numMappings == 0 ) return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, @@ -2926,10 +3228,10 @@ return NULL; ret = cmap14->results; - duni = TT_NEXT_UINT24( dp ); + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); dcnt = FT_NEXT_BYTE( dp ); di = 1; - nuni = TT_NEXT_UINT24( p ); + nuni = (FT_UInt32)TT_NEXT_UINT24( p ); p += 2; ni = 1; i = 0; @@ -2946,7 +3248,7 @@ if ( di > numRanges ) break; - duni = TT_NEXT_UINT24( dp ); + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); dcnt = FT_NEXT_BYTE( dp ); } else @@ -2959,7 +3261,7 @@ if ( ni > numMappings ) break; - nuni = TT_NEXT_UINT24( p ); + nuni = (FT_UInt32)TT_NEXT_UINT24( p ); p += 2; } } @@ -2972,7 +3274,7 @@ ret[i++] = nuni; while ( ni < numMappings ) { - ret[i++] = TT_NEXT_UINT24( p ); + ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p ); p += 2; ++ni; } @@ -2987,7 +3289,7 @@ while ( di < numRanges ) { - duni = TT_NEXT_UINT24( dp ); + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); dcnt = FT_NEXT_BYTE( dp ); for ( k = 0; k <= dcnt; ++k ) @@ -3003,10 +3305,7 @@ } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap14_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap14_class_rec, sizeof ( TT_CMap14Rec ), (FT_CMap_InitFunc) tt_cmap14_init, @@ -3020,51 +3319,66 @@ (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_14 */ +#ifndef FT_CONFIG_OPTION_PIC + static const TT_CMap_Class tt_cmap_classes[] = { -#ifdef TT_CONFIG_CMAP_FORMAT_0 - &tt_cmap0_class_rec, -#endif +#define TTCMAPCITEM(a) &a, +#include "ttcmapc.h" + NULL, + }; -#ifdef TT_CONFIG_CMAP_FORMAT_2 - &tt_cmap2_class_rec, -#endif +#else /*FT_CONFIG_OPTION_PIC*/ -#ifdef TT_CONFIG_CMAP_FORMAT_4 - &tt_cmap4_class_rec, -#endif + void FT_Destroy_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class* clazz) + { + FT_Memory memory = library->memory; + if ( clazz ) + FT_FREE( clazz ); + } -#ifdef TT_CONFIG_CMAP_FORMAT_6 - &tt_cmap6_class_rec, -#endif + FT_Error FT_Create_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class** output_class) + { + TT_CMap_Class* clazz; + TT_CMap_ClassRec* recs; + FT_Error error; + FT_Memory memory = library->memory; + int i = 0; -#ifdef TT_CONFIG_CMAP_FORMAT_8 - &tt_cmap8_class_rec, -#endif +#define TTCMAPCITEM(a) i++; +#include "ttcmapc.h" -#ifdef TT_CONFIG_CMAP_FORMAT_10 - &tt_cmap10_class_rec, -#endif + /* allocate enough space for both the pointers +terminator and the class instances */ + if ( FT_ALLOC( clazz, sizeof(*clazz)*(i+1)+sizeof(TT_CMap_ClassRec)*i ) ) + return error; -#ifdef TT_CONFIG_CMAP_FORMAT_12 - &tt_cmap12_class_rec, -#endif + /* the location of the class instances follows the array of pointers */ + recs = (TT_CMap_ClassRec*) (((char*)clazz)+(sizeof(*clazz)*(i+1))); + i=0; -#ifdef TT_CONFIG_CMAP_FORMAT_14 - &tt_cmap14_class_rec, -#endif +#undef TTCMAPCITEM +#define TTCMAPCITEM(a) \ + FT_Init_Class_##a(&recs[i]); \ + clazz[i] = &recs[i]; \ + i++; +#include "ttcmapc.h" - NULL, - }; + clazz[i] = NULL; + + *output_class = clazz; + return FT_Err_Ok; + } + +#endif /*FT_CONFIG_OPTION_PIC*/ /* parse the `cmap' table and build the corresponding TT_CMap objects */ @@ -3077,6 +3391,8 @@ FT_Byte* limit = table + face->cmap_size; FT_UInt volatile num_cmaps; FT_Byte* volatile p = table; + FT_Library library = FT_FACE_LIBRARY(face); + FT_UNUSED(library); if ( p + 4 > limit ) @@ -3086,7 +3402,8 @@ if ( TT_NEXT_USHORT( p ) != 0 ) { p -= 2; - FT_ERROR(( "tt_face_build_cmaps: unsupported `cmap' table format = %d\n", + FT_ERROR(( "tt_face_build_cmaps:" + " unsupported `cmap' table format = %d\n", TT_PEEK_USHORT( p ) )); return SFNT_Err_Invalid_Table; } @@ -3109,7 +3426,7 @@ { FT_Byte* volatile cmap = table + offset; volatile FT_UInt format = TT_PEEK_USHORT( cmap ); - const TT_CMap_Class* volatile pclazz = tt_cmap_classes; + const TT_CMap_Class* volatile pclazz = FT_TT_CMAP_CLASSES_GET; TT_CMap_Class volatile clazz; @@ -3153,8 +3470,8 @@ } else { - FT_ERROR(( "tt_face_build_cmaps:" )); - FT_ERROR(( " broken cmap sub-table ignored!\n" )); + FT_TRACE0(( "tt_face_build_cmaps:" + " broken cmap sub-table ignored\n" )); } break; } @@ -3162,8 +3479,8 @@ if ( *pclazz == NULL ) { - FT_ERROR(( "tt_face_build_cmaps:" )); - FT_ERROR(( " unsupported cmap sub-table ignored!\n" )); + FT_TRACE0(( "tt_face_build_cmaps:" + " unsupported cmap sub-table ignored\n" )); } } } diff --git a/src/sfnt/ttcmap.h b/src/sfnt/ttcmap.h index a10a3e2..15a4a21 100644 --- a/src/sfnt/ttcmap.h +++ b/src/sfnt/ttcmap.h @@ -55,6 +55,46 @@ FT_BEGIN_HEADER } TT_CMap_ClassRec; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_,variantchar_list_, \ + format_, validate_, get_cmap_info_) \ + FT_CALLBACK_TABLE_DEF \ + const TT_CMap_ClassRec class_ = \ + { \ + {size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_, variantchar_list_}, \ + format_, validate_, get_cmap_info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_,variantchar_list_, \ + format_, validate_, get_cmap_info_) \ + void \ + FT_Init_Class_##class_( TT_CMap_ClassRec* clazz ) \ + { \ + clazz->clazz.size = size_; \ + clazz->clazz.init = init_; \ + clazz->clazz.done = done_; \ + clazz->clazz.char_index = char_index_; \ + clazz->clazz.char_next = char_next_; \ + clazz->clazz.char_var_index = char_var_index_; \ + clazz->clazz.char_var_default = char_var_default_; \ + clazz->clazz.variant_list = variant_list_; \ + clazz->clazz.charvariant_list = charvariant_list_; \ + clazz->clazz.variantchar_list = variantchar_list_; \ + clazz->format = format_; \ + clazz->validate = validate_; \ + clazz->get_cmap_info = get_cmap_info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ typedef struct TT_ValidatorRec_ { diff --git a/src/sfnt/ttcmapc.h b/src/sfnt/ttcmapc.h new file mode 100644 index 0000000..4c9c6a5 --- /dev/null +++ b/src/sfnt/ttcmapc.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* ttcmapc.h */ +/* */ +/* TT CMAP classes definitions (specification only). */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#ifdef TT_CONFIG_CMAP_FORMAT_0 + TTCMAPCITEM(tt_cmap0_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_2 + TTCMAPCITEM(tt_cmap2_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_4 + TTCMAPCITEM(tt_cmap4_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_6 + TTCMAPCITEM(tt_cmap6_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_8 + TTCMAPCITEM(tt_cmap8_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_10 + TTCMAPCITEM(tt_cmap10_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_12 + TTCMAPCITEM(tt_cmap12_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_13 + TTCMAPCITEM(tt_cmap13_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_14 + TTCMAPCITEM(tt_cmap14_class_rec) +#endif + + /* END */ diff --git a/src/sfnt/ttkern.c b/src/sfnt/ttkern.c index 67d5115..c154080 100644 --- a/src/sfnt/ttkern.c +++ b/src/sfnt/ttkern.c @@ -22,7 +22,6 @@ #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H #include "ttkern.h" -#include "ttload.h" #include "sferrors.h" @@ -60,14 +59,16 @@ if ( table_size < 4 ) /* the case of a malformed table */ { - FT_ERROR(( "kerning table is too small - ignored\n" )); + FT_ERROR(( "tt_face_load_kern:" + " kerning table is too small - ignored\n" )); error = SFNT_Err_Table_Missing; goto Exit; } if ( FT_FRAME_EXTRACT( table_size, face->kern_table ) ) { - FT_ERROR(( "could not extract kerning table\n" )); + FT_ERROR(( "tt_face_load_kern:" + " could not extract kerning table\n" )); goto Exit; } @@ -86,7 +87,7 @@ { FT_UInt num_pairs, length, coverage; FT_Byte* p_next; - FT_UInt32 mask = 1UL << nn; + FT_UInt32 mask = (FT_UInt32)1UL << nn; if ( p + 6 > p_limit ) @@ -125,8 +126,8 @@ */ if ( num_pairs > 0 ) { - FT_UInt count; - FT_UInt old_pair; + FT_ULong count; + FT_ULong old_pair; old_pair = FT_NEXT_ULONG( p ); diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c index c45a1ed..3ad33bd 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, 2008 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -91,9 +91,9 @@ #ifdef FT_DEBUG_LEVEL_TRACE if ( zero_length ) - FT_TRACE4(( "ignoring empty table!\n" )); + FT_TRACE4(( "ignoring empty table\n" )); else - FT_TRACE4(( "could not find table!\n" )); + FT_TRACE4(( "could not find table\n" )); #endif return NULL; @@ -168,10 +168,10 @@ check_table_dir( SFNT_Header sfnt, FT_Stream stream ) { - FT_Error error; - FT_UInt nn, valid_entries = 0; - FT_UInt has_head = 0, has_sing = 0, has_meta = 0; - FT_ULong offset = sfnt->offset + 12; + FT_Error error; + FT_UShort nn, valid_entries = 0; + FT_UInt has_head = 0, has_sing = 0, has_meta = 0; + FT_ULong offset = sfnt->offset + 12; static const FT_Frame_Field table_dir_entry_fields[] = { @@ -364,7 +364,8 @@ error = check_table_dir( &sfnt, stream ); if ( error ) { - FT_TRACE2(( "tt_face_load_font_dir: invalid table directory for TrueType!\n" )); + FT_TRACE2(( "tt_face_load_font_dir:" + " invalid table directory for TrueType\n" )); goto Exit; } @@ -685,8 +686,10 @@ /* 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" )); + FT_TRACE0(( "tt_face_load_maxp:" + " too much twilight points in `maxp' table;\n" + " " + " some glyphs might be rendered incorrectly\n" )); maxProfile->maxTwilightPoints = 0xFFFFU - 4; } @@ -779,7 +782,7 @@ if ( storage_start > storage_limit ) { - FT_ERROR(( "invalid `name' table\n" )); + FT_ERROR(( "tt_face_load_name: invalid `name' table\n" )); error = SFNT_Err_Name_Table_Missing; goto Exit; } diff --git a/src/sfnt/ttmtx.c b/src/sfnt/ttmtx.c index 2a7d22c..53e6ac7 100644 --- a/src/sfnt/ttmtx.c +++ b/src/sfnt/ttmtx.c @@ -4,7 +4,7 @@ /* */ /* Load the metrics tables common to TTF and OTF fonts (body). */ /* */ -/* Copyright 2006, 2007, 2008 by */ +/* Copyright 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -161,7 +161,9 @@ if ( num_shorts < 0 ) { - FT_ERROR(( "%cmtx has more metrics than glyphs.\n" )); + FT_TRACE0(( "tt_face_load_hmtx:" + " %cmtx has more metrics than glyphs.\n", + vertical ? "v" : "h" )); /* Adobe simply ignores this problem. So we shall do the same. */ #if 0 diff --git a/src/sfnt/ttpost.c b/src/sfnt/ttpost.c index ce628e2..aa0bf1e 100644 --- a/src/sfnt/ttpost.c +++ b/src/sfnt/ttpost.c @@ -5,7 +5,7 @@ /* Postcript name table processing for TrueType and OpenType fonts */ /* (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,7 +29,6 @@ #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H #include "ttpost.h" -#include "ttload.h" #include "sferrors.h" diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c index eadaade..833bb2a 100644 --- a/src/sfnt/ttsbit.c +++ b/src/sfnt/ttsbit.c @@ -494,7 +494,7 @@ if ( version != 0x00020000L || num_strikes >= 0x10000L ) { - FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version!\n" )); + FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); error = SFNT_Err_Invalid_File_Format; goto Exit; diff --git a/src/sfnt/ttsbit0.c b/src/sfnt/ttsbit0.c index 3ebcbbd..38bcf21 100644 --- a/src/sfnt/ttsbit0.c +++ b/src/sfnt/ttsbit0.c @@ -62,7 +62,7 @@ if ( table_size < 8 ) { - FT_ERROR(( "tt_face_load_sbit_strikes: table too short!\n" )); + FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" )); error = SFNT_Err_Invalid_File_Format; goto Exit; } @@ -80,7 +80,7 @@ if ( version != 0x00020000UL || num_strikes >= 0x10000UL ) { - FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version!\n" )); + FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); error = SFNT_Err_Invalid_File_Format; goto Fail; } @@ -469,6 +469,41 @@ } + /* + * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap + * (with pointer `write'). In the example below, the width is 3 pixel, + * and `x_pos' is 1 pixel. + * + * p p+1 + * | | | + * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |... + * | | | + * +-------+ +-------+ +-------+ ... + * . . . + * . . . + * v . . + * +-------+ . . + * | | . + * | 7 6 5 4 3 2 1 0 | . + * | | . + * write . . + * . . + * v . + * +-------+ . + * | | + * | 7 6 5 4 3 2 1 0 | + * | | + * write+1 . + * . + * v + * +-------+ + * | | + * | 7 6 5 4 3 2 1 0 | + * | | + * write+2 + * + */ + static FT_Error tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, FT_Byte* p, @@ -514,6 +549,8 @@ } /* now do the blit */ + + /* adjust `line' to point to the first byte of the bitmap */ line += y_pos * pitch + ( x_pos >> 3 ); x_pos &= 7; @@ -524,21 +561,23 @@ for ( h = height; h > 0; h--, line += pitch ) { FT_Byte* write = line; - FT_Int w = width; + FT_Int w = width; + /* handle initial byte (in target bitmap) specially if necessary */ if ( x_pos ) { w = ( width < 8 - x_pos ) ? width : 8 - x_pos; if ( h == height ) { - rval |= *p++; - nbits += x_pos; + rval = *p++; + nbits = x_pos; } else if ( nbits < w ) { - rval |= *p++; + if ( p < limit ) + rval |= *p++; nbits += 8 - w; } else @@ -554,6 +593,7 @@ w = width - w; } + /* handle medial bytes */ for ( ; w >= 8; w -= 8 ) { rval |= *p++; @@ -562,11 +602,13 @@ rval <<= 8; } + /* handle final byte if necessary */ if ( w > 0 ) { if ( nbits < w ) { - rval |= *p++; + if ( p < limit ) + rval |= *p++; *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); nbits += 8 - w; -- cgit v1.2.3