From 9d636b6d14dc5decc9651757e15faab5267b0873 Mon Sep 17 00:00:00 2001 From: David Turner Date: Tue, 27 Jun 2000 23:32:27 +0000 Subject: [PATCH] various cleanups to reduce compiler warnings + support for CID-keyed fonts in the CFF driver (still some unexpected bugs though..) --- CHANGES | 34 +++ config/win32/w32-dev.mk | 2 +- demos/src/ftmulti.c | 30 -- demos/src/ftstring.c | 32 -- demos/src/ftview.c | 121 ++------ include/freetype/config/ftmodule.h | 4 +- include/freetype/fterrors.h | 1 + include/freetype/ftrender.h | 3 +- include/freetype/internal/ftobjs.h | 12 +- include/freetype/internal/t2types.h | 55 +++- src/cff/t2gload.c | 34 ++- src/cff/t2gload.h | 3 + src/cff/t2load.c | 437 +++++++++++++++++++++------- src/cff/t2load.h | 4 + src/cff/t2objs.c | 3 + src/cff/t2parse.c | 14 +- src/cff/t2tokens.h | 2 +- src/sfnt/sfobjs.c | 3 + 18 files changed, 506 insertions(+), 288 deletions(-) diff --git a/CHANGES b/CHANGES index d19b854cb..659f0b451 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,39 @@ LATEST CHANGES + - added support for CID-keyed fonts to the CFF driver. There are still + some unexplained bugs though... ??? + + + - cleaned up source code in order to avoid two functions with the + same name. Also changed the names of the files in "type1z" from + "t1XXXX" to "z1XXXX" in order to avoid any conflicts. + + "make multi" now works well :-) + + + + - CHANGES TO THE RENDERER MODULES + + the monochrome and smooth renderers are now in two distinct directories, + namely "src/raster1" and "src/smooth". Note that the old "src/renderer" + is now gone.. + + I ditched the 5-gray-levels renderers. Basically, it involved a simple + #define toggle in 'src/raster1/ftraster.c' + + FT_Render_Glyph, FT_Outline_Render & FT_Outline_Get_Bitmap now select + the best renderer available, depending on render mode. If the current + renderer for a given glyph image format isn't capable of supporting + the render mode, another one will be found in the library's list. + + This means that client applications do not need to switch or set the + renderers themselves (as in the latest change), they'll get what they + want automatically... At last.. + + Changed the demo programs accordingly.. + + + - MAJOR INTERNAL REDESIGN: A lot of internal modifications have been performed lately on the diff --git a/config/win32/w32-dev.mk b/config/win32/w32-dev.mk index daa6a8af8..294d63aed 100644 --- a/config/win32/w32-dev.mk +++ b/config/win32/w32-dev.mk @@ -98,7 +98,7 @@ T := -o # Don't remove this comment line! We need the space after `-o'. # ANSI compliance. # ifndef CFLAGS - CFLAGS := -c -g -O0 -Wall + CFLAGS := -c -g -O0 -Wall -W endif # ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. diff --git a/demos/src/ftmulti.c b/demos/src/ftmulti.c index 5a5b20e6e..34fce60fd 100644 --- a/demos/src/ftmulti.c +++ b/demos/src/ftmulti.c @@ -13,7 +13,6 @@ /****************************************************************************/ #include -#include #include #include "common.h" @@ -74,10 +73,6 @@ int render_mode = 1; int use_grays = 1; - /* the standard raster's interface */ - FT_Renderer std_renderer; - FT_Renderer smooth_renderer; - FT_Multi_Master multimaster; FT_Long design_pos[T1_MAX_MM_AXIS]; @@ -432,7 +427,6 @@ grWriteln(" h : toggle outline hinting" ); grWriteln(" b : toggle embedded bitmaps" ); grWriteln(" l : toggle low precision rendering" ); - grWriteln(" g : toggle between `smooth' and `standard' anti-aliaser" ); grWriteln(" space : toggle rendering mode" ); grLn(); grWriteln(" Up : increase pointsize by 1 unit" ); @@ -457,15 +451,6 @@ } - static - void reset_raster( void ) - { - if ( antialias && use_grays && smooth_renderer ) - FT_Set_Renderer( library, smooth_renderer, 0, 0 ); - else - FT_Set_Renderer( library, std_renderer, 0, 0 ); - } - static int Process_Event( grEvent* event ) @@ -489,7 +474,6 @@ antialias = !antialias; new_header = antialias ? "anti-aliasing is now on" : "anti-aliasing is now off"; - reset_raster(); return 1; case grKEY( 'b' ): @@ -502,13 +486,6 @@ case grKEY( 'p' ): return (int)event->key; - case grKEY( 'g' ): - use_grays = !use_grays; - new_header = use_grays ? "now using the smooth anti-aliaser" - : "now using the standard anti-aliaser"; - reset_raster(); - break; - case grKEY( 'l' ): low_prec = !low_prec; new_header = low_prec ? "rendering precision is now forced to low" @@ -714,13 +691,6 @@ if ( error ) PanicZ( "Could not initialize FreeType library" ); - /* retrieve the standard raster's interface */ - std_renderer = (FT_Renderer)FT_Get_Module( library, "standard renderer" ); - if (!std_renderer) - PanicZ( "Could not retrieve standard renderer" ); - - smooth_renderer = (FT_Renderer)FT_Get_Module( library, "smooth renderer" ); - NewFile: ptsize = orig_ptsize; hinted = 1; diff --git a/demos/src/ftstring.c b/demos/src/ftstring.c index 6b0558d6a..3478f5cbd 100644 --- a/demos/src/ftstring.c +++ b/demos/src/ftstring.c @@ -11,7 +11,6 @@ /****************************************************************************/ #include -#include #include #include "common.h" @@ -60,11 +59,6 @@ static int graph_init = 0; static int render_mode = 1; - static int use_grays = 1; - - /* the standard raster's interface */ - FT_Renderer std_renderer; - FT_Renderer smooth_renderer; static FT_Matrix trans_matrix; static int transform = 0; @@ -449,7 +443,6 @@ grWriteln(" a : toggle anti-aliasing" ); grWriteln(" h : toggle outline hinting" ); grWriteln(" k : toggle kerning" ); - grWriteln(" g : toggle between 'smooth' and 'standard' anti-aliaser" ); grLn(); grWriteln(" Up : increase pointsize by 1 unit" ); grWriteln(" Down : decrease pointsize by 1 unit" ); @@ -468,15 +461,6 @@ } - static void reset_raster( void ) - { - if ( antialias && use_grays && smooth_renderer ) - FT_Set_Renderer( library, smooth_renderer, 0, 0 ); - else - FT_Set_Renderer( library, std_renderer, 0, 0 ); - } - - static int Process_Event( grEvent* event ) { int i; @@ -499,7 +483,6 @@ new_header = ( antialias ? "anti-aliasing is now on" : "anti-aliasing is now off" ); - reset_raster(); return 1; case grKEY('b'): @@ -513,14 +496,6 @@ case grKEY('p'): return (int)event->key; - case grKEY('g'): - use_grays = !use_grays; - new_header = ( use_grays - ? "now using the smooth anti-aliaser" - : "now using the standard anti-aliaser" ); - reset_raster(); - break; - case grKEY('h'): hinted = !hinted; new_header = ( hinted @@ -668,13 +643,6 @@ error = FT_Init_FreeType( &library ); if (error) PanicZ( "Could not initialise FreeType library" ); - /* retrieve the standard raster's interface */ - std_renderer = (FT_Renderer)FT_Get_Module( library, "standard renderer" ); - if (!std_renderer) - PanicZ( "Could not retrieve standard renderer" ); - - smooth_renderer = (FT_Renderer)FT_Get_Module( library, "smooth renderer" ); - NewFile: ptsize = orig_ptsize; hinted = 1; diff --git a/demos/src/ftview.c b/demos/src/ftview.c index 43f4dfe89..8b1e8bfce 100644 --- a/demos/src/ftview.c +++ b/demos/src/ftview.c @@ -17,7 +17,6 @@ #include -#include /* the following header shouldn't be used in normal programs */ #include @@ -64,7 +63,7 @@ int ptsize; /* current point size */ int hinted = 1; /* is glyph hinting active? */ - int antialias = 0; /* is anti-aliasing active? */ + int antialias = 1; /* is anti-aliasing active? */ int use_sbits = 1; /* do we use embedded bitmaps? */ int low_prec = 0; /* force low precision */ int Num; /* current first glyph index */ @@ -78,14 +77,9 @@ int graph_init = 0; int render_mode = 1; - int use_grays = 1; int debug = 0; int trace_level = 0; - /* the standard raster's interface */ - FT_Renderer std_renderer; - FT_Renderer smooth_renderer; - #define RASTER_BUFF_SIZE 32768 char raster_buff[RASTER_BUFF_SIZE]; @@ -152,79 +146,44 @@ #define CEIL( x ) ( ( (x) + 63 ) & -64 ) #define TRUNC( x ) ( (x) >> 6 ) - static - char bit_buffer[MAX_BUFFER]; - /* Render a single glyph with the `grays' component */ static FT_Error Render_Glyph( int x_offset, int y_offset ) { - /* first, render the glyph into an intermediate buffer */ - FT_Bitmap bit2; - grBitmap bit3; - int width, height, pitch, size; - int left, right, top, bottom; - int x_top, y_top; - - - left = FLOOR( glyph->metrics.horiBearingX ); - right = CEIL( glyph->metrics.horiBearingX + glyph->metrics.width ); - width = TRUNC( right - left ); - - top = CEIL( glyph->metrics.horiBearingY ); - bottom = FLOOR( glyph->metrics.horiBearingY - glyph->metrics.height ); - height = TRUNC( top - bottom ); - - if ( glyph->format == ft_glyph_format_outline ) + grBitmap bit3; + FT_Pos x_top, y_top; + + /* first, render the glyph image into a bitmap */ + if (glyph->format != ft_glyph_format_bitmap) { - pitch = antialias ? ( width + 3 ) & -4 - : ( width + 7 ) >> 3; - size = pitch * height; - - if ( size > MAX_BUFFER ) - return FT_Err_Out_Of_Memory; - - bit2.width = width; - bit2.rows = height; - bit2.pitch = pitch; - bit2.pixel_mode = antialias ? ft_pixel_mode_grays : ft_pixel_mode_mono; - bit2.buffer = bit_buffer; - - bit3.rows = bit2.rows; - bit3.width = bit2.width; - bit3.pitch = bit2.pitch; - bit3.mode = antialias ? bit.mode : gr_pixel_mode_mono; - bit3.buffer = bit_buffer; - bit3.grays = 256; - - FT_Outline_Translate( &glyph->outline, -left, -bottom ); - memset( bit_buffer, 0, size ); - - if ( low_prec ) - glyph->outline.flags &= ~ft_outline_high_precision; - - error = FT_Outline_Get_Bitmap( library, &glyph->outline, &bit2 ); + error = FT_Render_Glyph( glyph, antialias ? 1 : 0 ); + if (error) return error; + } - else + + /* now blit it to our display screen */ + bit3.rows = glyph->bitmap.rows; + bit3.width = glyph->bitmap.width; + bit3.pitch = glyph->bitmap.pitch; + bit3.buffer = glyph->bitmap.buffer; + + switch (glyph->bitmap.pixel_mode) { - bit3.rows = glyph->bitmap.rows; - bit3.width = glyph->bitmap.width; - bit3.pitch = glyph->bitmap.pitch; - bit3.mode = gr_pixel_mode_mono; - bit3.buffer = glyph->bitmap.buffer; - bit3.grays = 0; + case ft_pixel_mode_mono: + bit3.mode = gr_pixel_mode_mono; + bit3.grays = 0; + break; + + case ft_pixel_mode_grays: + bit3.mode = gr_pixel_mode_gray; + bit3.grays = glyph->bitmap.num_grays; } /* Then, blit the image to the target surface */ - x_top = x_offset + TRUNC( left ); - y_top = y_offset - TRUNC( top ); - -#if 0 - if ( bit.pitch < 0 ) - y_top = bit.rows - y_top; -#endif + x_top = x_offset + glyph->bitmap_left; + y_top = y_offset - glyph->bitmap_top; grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color ); @@ -431,7 +390,6 @@ grWriteln(" h : toggle outline hinting" ); grWriteln(" b : toggle embedded bitmaps" ); grWriteln(" l : toggle low precision rendering" ); - grWriteln(" g : toggle between `smooth' and `standard' anti-aliaser" ); grWriteln(" space : toggle rendering mode" ); grLn(); grWriteln(" Up : increase pointsize by 1 unit" ); @@ -456,15 +414,6 @@ } - static - void reset_raster( void ) - { - if ( antialias && use_grays && smooth_renderer ) - FT_Set_Renderer( library, smooth_renderer, 0, 0 ); - else - FT_Set_Renderer( library, std_renderer, 0, 0 ); - } - static int Process_Event( grEvent* event ) @@ -482,7 +431,6 @@ antialias = !antialias; new_header = antialias ? "anti-aliasing is now on" : "anti-aliasing is now off"; - reset_raster(); return 1; case grKEY( 'b' ): @@ -496,14 +444,6 @@ case grKEY( 'p' ): return (int)event->key; - case grKEY( 'g' ): - use_grays = !use_grays; - new_header = use_grays - ? "now using the smooth anti-aliaser" - : "now using the standard anti-aliaser"; - reset_raster(); - break; - case grKEY( 'l' ): low_prec = !low_prec; new_header = low_prec @@ -672,13 +612,6 @@ if ( error ) PanicZ( "Could not initialize FreeType library" ); - /* retrieve the standard raster's interface */ - std_renderer = (FT_Renderer)FT_Get_Module( library, "standard renderer" ); - if (!std_renderer) - PanicZ( "Could not retrieve standard renderer" ); - - smooth_renderer = (FT_Renderer)FT_Get_Module( library, "smooth renderer" ); - NewFile: ptsize = orig_ptsize; hinted = 1; diff --git a/include/freetype/config/ftmodule.h b/include/freetype/config/ftmodule.h index 1fb091a9b..69ef5f7c0 100644 --- a/include/freetype/config/ftmodule.h +++ b/include/freetype/config/ftmodule.h @@ -1,9 +1,9 @@ FT_USE_MODULE(cff_driver_class) FT_USE_MODULE(t1cid_driver_class) FT_USE_MODULE(psnames_module_class) -FT_USE_MODULE(ft_standard_renderer_class) -FT_USE_MODULE(ft_smooth_renderer_class) +FT_USE_MODULE(ft_raster1_renderer_class) FT_USE_MODULE(sfnt_module_class) +FT_USE_MODULE(ft_smooth_renderer_class) FT_USE_MODULE(tt_driver_class) FT_USE_MODULE(t1_driver_class) FT_USE_MODULE(t1z_driver_class) diff --git a/include/freetype/fterrors.h b/include/freetype/fterrors.h index de3f94571..3c7c76052 100644 --- a/include/freetype/fterrors.h +++ b/include/freetype/fterrors.h @@ -55,6 +55,7 @@ FT_ERROR_START_LIST FT_ERRORDEF( FT_Err_Unimplemented_Feature, 0x0020, "unimplemented feature" ) FT_ERRORDEF( FT_Err_Invalid_Glyph_Format, 0x0021, "invalid glyph image format" ) + FT_ERRORDEF( FT_Err_Cannot_Render_Glyph, 0x0022, "cannot render this glyph format" ) FT_ERRORDEF( FT_Err_Invalid_Library_Handle, 0x0030, "invalid library handle" ) FT_ERRORDEF( FT_Err_Invalid_Driver_Handle, 0x0031, "invalid module handle" ) diff --git a/include/freetype/ftrender.h b/include/freetype/ftrender.h index c0169f69b..f7d629587 100644 --- a/include/freetype/ftrender.h +++ b/include/freetype/ftrender.h @@ -49,7 +49,8 @@ typedef FT_Error (*FTRenderer_render)( FT_Renderer renderer, FT_GlyphSlot slot, - FT_UInt mode ); + FT_UInt mode, + FT_Vector* origin ); typedef FT_Error (*FTRenderer_transform)( FT_Renderer renderer, FT_GlyphSlot slot, diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h index 5c4e82430..a15bab448 100644 --- a/include/freetype/internal/ftobjs.h +++ b/include/freetype/internal/ftobjs.h @@ -384,14 +384,14 @@ FT_Generic generic; - FT_Int num_modules; + FT_UInt num_modules; FT_Module modules[ FT_MAX_MODULES ]; /* module objects */ FT_ListRec renderers; /* list of renderers */ FT_Renderer cur_renderer; /* current outline renderer */ void* raster_pool; /* scan-line conversion render pool */ - long raster_pool_size; /* size of render pool in bytes */ + unsigned long raster_pool_size; /* size of render pool in bytes */ FT_DebugHook_Func debug_hooks[4]; @@ -411,6 +411,14 @@ FT_DebugHook_Func debug_hook ); + BASE_DEF(FT_Renderer) FT_Lookup_Renderer( FT_Library library, + FT_Glyph_Format format, + FT_ListNode *node ); + + BASE_DEF(FT_Error) FT_Render_Glyph_Internal( FT_Library library, + FT_GlyphSlot slot, + FT_UInt render_mode ); + #ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM diff --git a/include/freetype/internal/t2types.h b/include/freetype/internal/t2types.h index 792235565..2b015891b 100644 --- a/include/freetype/internal/t2types.h +++ b/include/freetype/internal/t2types.h @@ -62,7 +62,7 @@ } CFF_Index; - typedef struct CFF_Top_Dict_ + typedef struct CFF_Font_Dict_ { FT_UInt version; FT_UInt notice; @@ -90,6 +90,7 @@ FT_UInt base_font_name; FT_UInt postscript; + /* these should only be used for the top-level font dict */ FT_UInt cid_registry; FT_UInt cid_ordering; FT_ULong cid_supplement; @@ -103,7 +104,9 @@ FT_ULong cid_fd_select_offset; FT_UInt cid_font_name; - } CFF_Top_Dict; + } CFF_Font_Dict; + + typedef struct CFF_Private_ { @@ -138,12 +141,49 @@ FT_Pos nominal_width; } CFF_Private; + + + typedef struct CFF_FD_Select_ + { + FT_Byte format; + FT_UInt range_count; + + /* that's the table, taken from the file 'as is' */ + FT_Byte* data; + FT_UInt data_size; + + /* small cache for format 3 only */ + FT_UInt cache_first; + FT_UInt cache_count; + FT_Byte cache_fd; + + } CFF_FD_Select; + + + + /* a SubFont packs a font dict and a private dict together. They're */ + /* needed to support CID-keyde CFF fonts.. */ + typedef struct CFF_SubFont_ + { + CFF_Font_Dict font_dict; + CFF_Private private_dict; + + CFF_Index local_subrs_index; + FT_UInt num_local_subrs; + FT_Byte** local_subrs; + + } CFF_SubFont; + + + /* maximum number of sub-fonts in a CID-keyed file */ + #define CFF_MAX_CID_FONTS 16 typedef struct CFF_Font_ { FT_Stream stream; FT_Memory memory; FT_UInt num_faces; + FT_UInt num_glyphs; FT_Byte version_major; FT_Byte version_minor; @@ -164,13 +204,14 @@ CFF_Index local_subrs_index; FT_String* font_name; - CFF_Top_Dict top_dict; - CFF_Private private_dict; - FT_UInt num_global_subrs; - FT_UInt num_local_subrs; FT_Byte** global_subrs; - FT_Byte** local_subrs; + + CFF_SubFont top_font; + FT_UInt num_subfonts; + CFF_SubFont* subfonts[ CFF_MAX_CID_FONTS ]; + + CFF_FD_Select fd_select; } CFF_Font; diff --git a/src/cff/t2gload.c b/src/cff/t2gload.c index 050332605..8a719519f 100644 --- a/src/cff/t2gload.c +++ b/src/cff/t2gload.c @@ -345,18 +345,37 @@ T2_Init_Builder( &decoder->builder, face, size, slot ); /* initialize Type2 decoder */ - decoder->num_locals = cff->num_local_subrs; decoder->num_globals = cff->num_global_subrs; - decoder->locals = cff->local_subrs; decoder->globals = cff->global_subrs; - decoder->locals_bias = t2_compute_bias( decoder->num_locals ); decoder->globals_bias = t2_compute_bias( decoder->num_globals ); - - decoder->glyph_width = cff->private_dict.default_width; - decoder->nominal_width = cff->private_dict.nominal_width; } + /* this function is used to select the locals subrs array */ + LOCAL_DEF + void T2_Prepare_Decoder( T2_Decoder* decoder, + FT_UInt glyph_index ) + { + CFF_Font* cff = (CFF_Font*)decoder->builder.face->extra.data; + CFF_SubFont* sub = &cff->top_font; + + /* manage CID fonts */ + if (cff->num_subfonts >= 1) + { + FT_Byte fd_index = CFF_Get_FD( &cff->fd_select, glyph_index ); + sub = cff->subfonts[fd_index]; + } + + decoder->num_locals = sub->num_local_subrs; + decoder->locals = sub->local_subrs; + decoder->locals_bias = t2_compute_bias( decoder->num_locals ); + + decoder->glyph_width = sub->private_dict.default_width; + decoder->nominal_width = sub->private_dict.nominal_width; + } + + + /* check that there is enough room for `count' more points */ static FT_Error check_points( T2_Builder* builder, @@ -509,7 +528,6 @@ FT_Fixed seed; FT_Fixed* stack; - /* set default width */ decoder->num_hints = 0; decoder->read_width = 1; @@ -1572,6 +1590,7 @@ &charstring, &charstring_len ); if ( !error ) { + T2_Prepare_Decoder( &decoder, glyph_index ); error = T2_Parse_CharStrings( &decoder, charstring, charstring_len ); T2_Forget_Element( &cff->charstrings_index, &charstring ); @@ -1648,6 +1667,7 @@ &charstring, &charstring_len ); if ( !error ) { + T2_Prepare_Decoder( &decoder, glyph_index ); error = T2_Parse_CharStrings( &decoder, charstring, charstring_len ); T2_Forget_Element( &cff->charstrings_index, &charstring ); diff --git a/src/cff/t2gload.h b/src/cff/t2gload.h index ef615765d..605ba5e19 100644 --- a/src/cff/t2gload.h +++ b/src/cff/t2gload.h @@ -166,6 +166,9 @@ T2_Size size, T2_GlyphSlot slot ); + LOCAL_DEF + void T2_Prepare_Decoder( T2_Decoder* decoder, + FT_UInt glyph_index ); #if 0 /* unused until we support pure CFF fonts */ diff --git a/src/cff/t2load.c b/src/cff/t2load.c index 6d16f60e4..8758cc296 100644 --- a/src/cff/t2load.c +++ b/src/cff/t2load.c @@ -318,6 +318,239 @@ #endif /* 0 */ + /**********************************************************************/ + /**********************************************************************/ + /*** ***/ + /*** FD Select table support ***/ + /*** ***/ + /*** ***/ + /**********************************************************************/ + /**********************************************************************/ + + static + void CFF_Done_FD_Select( CFF_FD_Select* select, + FT_Stream stream ) + { + if (select->data) + RELEASE_Frame( select->data ); + + select->data_size = 0; + select->format = 0; + select->range_count = 0; + } + + + static + FT_Error CFF_Load_FD_Select( CFF_FD_Select* select, + FT_UInt num_glyphs, + FT_Stream stream, + FT_ULong offset ) + { + FT_Error error; + FT_Byte format; + FT_UInt num_ranges; + + /* read format */ + if ( FILE_Seek(offset) || READ_Byte(format) ) + goto Exit; + + select->format = format; + switch (format) + { + case 0: /* format 0, that's simple */ + { + select->data_size = num_glyphs; + goto Load_Data; + } + + + case 3: /* format 3, a tad more complex */ + { + if ( READ_UShort(num_ranges) ) + goto Exit; + + select->data_size = num_ranges*3+2; + + Load_Data: + if ( EXTRACT_Frame( select->data_size, select->data ) ) + goto Exit; + } + break; + + + default: /* humm.. that's wrong */ + error = FT_Err_Invalid_File_Format; + } + Exit: + return error; + } + + + LOCAL_FUNC + FT_Byte CFF_Get_FD( CFF_FD_Select* select, + FT_UInt glyph_index ) + { + FT_Byte fd = 0; + + switch (select->format) + { + case 0: + fd = select->data[glyph_index]; + break; + + case 3: + /* first, compare to cache */ + if ((FT_UInt)(glyph_index-select->cache_first) < select->cache_count) + { + fd = select->cache_fd; + break; + } + + /* then, lookup the ranges array */ + { + FT_Byte* p = select->data; + FT_Byte* p_limit = p + select->data_size; + FT_Byte fd2; + FT_UInt first, limit; + + first = NEXT_UShort(p); + do + { + if (glyph_index < first) + break; + + fd2 = *p++; + limit = NEXT_UShort(p); + + if (glyph_index < limit) + { + fd = fd2; + + /* update cache */ + select->cache_first = first; + select->cache_count = limit-first; + select->cache_fd = fd2; + break; + } + first = limit; + } + while (p < p_limit); + } + break; + + default: + ; + } + return fd; + } + + + /**********************************************************************/ + /**********************************************************************/ + /*** ***/ + /*** CFF font support ***/ + /*** ***/ + /*** ***/ + /**********************************************************************/ + /**********************************************************************/ + + static + FT_Error CFF_Load_SubFont( CFF_SubFont* font, + CFF_Index* index, + FT_UInt font_index, + FT_Stream stream, + FT_ULong base_offset ) + { + FT_Error error; + T2_Parser parser; + FT_Byte* dict; + FT_ULong dict_len; + CFF_Font_Dict* top = &font->font_dict; + CFF_Private* priv = &font->private_dict; + + T2_Parser_Init( &parser, T2CODE_TOPDICT, &font->font_dict ); + + /* set defaults */ + MEM_Set( top, 0, sizeof ( *top ) ); + + top->underline_position = -100; + top->underline_thickness = 50; + top->charstring_type = 2; + top->font_matrix.xx = 0x10000L; + top->font_matrix.yy = 0x10000L; + top->cid_count = 8720; + + error = T2_Access_Element( index, font_index, &dict, &dict_len ) || + T2_Parser_Run( &parser, dict, dict + dict_len ); + + T2_Forget_Element( index, &dict ); + + if ( error ) + goto Exit; + + /* if it's a CID font, we stop there */ + if ( top->cid_registry ) + goto Exit; + + /* parse the private dictionary, if any */ + if ( top->private_offset && top->private_size) + { + /* set defaults */ + MEM_Set( priv, 0, sizeof(*priv) ); + + priv->blue_shift = 7; + priv->blue_fuzz = 1; + priv->lenIV = -1; + priv->expansion_factor = (FT_Fixed)0.06 * 0x10000L; + priv->blue_scale = (FT_Fixed)0.039625 * 0x10000L; + + T2_Parser_Init( &parser, T2CODE_PRIVATE, priv ); + + if ( FILE_Seek( base_offset + font->font_dict.private_offset ) || + ACCESS_Frame( font->font_dict.private_size ) ) + goto Exit; + + error = T2_Parser_Run( &parser, + (FT_Byte*)stream->cursor, + (FT_Byte*)stream->limit ); + FORGET_Frame(); + if ( error ) + goto Exit; + } + + /* read the local subrs, if any */ + if ( priv->local_subrs_offset ) + { + if ( FILE_Seek( base_offset + top->private_offset + + priv->local_subrs_offset ) ) + goto Exit; + + error = t2_new_cff_index( &font->local_subrs_index, stream, 1 ); + if ( error ) + goto Exit; + + font->num_local_subrs = font->local_subrs_index.count; + error = t2_explicit_cff_index( &font->local_subrs_index, + &font->local_subrs ); + } + + Exit: + return error; + } + + + static + void CFF_Done_SubFont( FT_Memory memory, + CFF_SubFont* subfont ) + { + if (subfont) + { + t2_done_cff_index( &subfont->local_subrs_index ); + FREE( subfont->local_subrs ); + } + } + + LOCAL_FUNC FT_Error T2_Load_CFF_Font( FT_Stream stream, @@ -334,14 +567,16 @@ FT_FRAME_END }; - FT_Error error; - FT_Memory memory = stream->memory; - FT_ULong base_offset; + FT_Error error; + FT_Memory memory = stream->memory; + FT_ULong base_offset; + CFF_Font_Dict* dict; MEM_Set( font, 0, sizeof ( *font ) ); font->stream = stream; font->memory = memory; + dict = &font->top_font.font_dict; base_offset = FILE_Pos(); /* read CFF font header */ @@ -353,7 +588,7 @@ font->header_size < 4 || font->absolute_offsize > 4 ) { - FT_ERROR(( "incorrect CFF font header!\n" )); + FT_TRACE2(( "[not a CFF font header!]\n" )); error = FT_Err_Unknown_File_Format; goto Exit; } @@ -363,7 +598,7 @@ /* read the name, top dict, string and global subrs index */ error = t2_new_cff_index( &font->name_index, stream, 0 ) || - t2_new_cff_index( &font->top_dict_index, stream, 0 ) || + t2_new_cff_index( &font->font_dict_index, stream, 0 ) || t2_new_cff_index( &font->string_index, stream, 0 ) || t2_new_cff_index( &font->global_subrs_index, stream, 1 ); if ( error ) @@ -371,7 +606,7 @@ /* well, we don't really forget the `disabled' fonts... */ font->num_faces = font->name_index.count; - if ( face_index >= font->num_faces ) + if ( face_index >= (FT_Int)font->num_faces ) { FT_ERROR(( "T2_Load_CFF_Font: incorrect face index = %d\n", face_index )); @@ -379,110 +614,95 @@ } /* in case of a font format check, simply exit now */ - if ( face_index >= 0 ) + if (face_index < 0) + goto Exit; + + /* now, parse the top-level font dictionary */ + error = CFF_Load_SubFont( &font->top_font, + &font->font_dict_index, + face_index, + stream, + base_offset ); + if (error) + goto Exit; + + /* now, check for a CID font */ + if ( dict->cid_registry ) { - T2_Parser parser; - FT_Byte* dict; - FT_ULong dict_len; - CFF_Index* index = &font->top_dict_index; - CFF_Top_Dict* top = &font->top_dict; + CFF_Index fd_index; + CFF_SubFont* sub; + FT_UInt index; - - /* parse the top-level font dictionary */ - T2_Parser_Init( &parser, T2CODE_TOPDICT, &font->top_dict ); - - /* set defaults */ - memset( top, 0, sizeof ( *top ) ); - - top->underline_position = -100; - top->underline_thickness = 50; - top->charstring_type = 2; - top->font_matrix.xx = 0x10000L; - top->font_matrix.yy = 0x10000L; - top->cid_count = 8720; - - error = T2_Access_Element( index, face_index, &dict, &dict_len ) || - T2_Parser_Run( &parser, dict, dict + dict_len ); - - T2_Forget_Element( &font->top_dict_index, &dict ); - - if ( error ) + /* this is a CID-keyed font, we must now allocate a table of */ + /* sub-fonts, then load each of them separately.. */ + if ( FILE_Seek( base_offset + dict->cid_fd_array_offset ) ) goto Exit; - - /* parse the private dictionary, if any */ - if (font->top_dict.private_offset && font->top_dict.private_size) + + error = t2_new_cff_index( &fd_index, stream, 0 ); + if (error) goto Exit; + + if (fd_index.count > CFF_MAX_CID_FONTS) { - CFF_Private* priv = &font->private_dict; + FT_ERROR(( "T2_Load_CFF_Font: FD array too large in CID font\n" )); + goto Fail_CID; + } + + /* allocate & read each font dict independently */ + font->num_subfonts = fd_index.count; + if ( ALLOC_ARRAY( sub, fd_index.count, CFF_SubFont ) ) + goto Fail_CID; - - /* set defaults */ - priv->blue_shift = 7; - priv->blue_fuzz = 1; - priv->lenIV = -1; - priv->expansion_factor = (FT_Fixed)0.06 * 0x10000L; - priv->blue_scale = (FT_Fixed)0.039625 * 0x10000L; - - T2_Parser_Init( &parser, T2CODE_PRIVATE, priv ); - - if ( FILE_Seek( base_offset + font->top_dict.private_offset ) || - ACCESS_Frame( font->top_dict.private_size ) ) - goto Exit; - - error = T2_Parser_Run( &parser, - (FT_Byte*)stream->cursor, - (FT_Byte*)stream->limit ); - FORGET_Frame(); - if ( error ) - goto Exit; + /* setup pointer table */ + for ( index = 0; index < fd_index.count; index++ ) + font->subfonts[index] = sub + index; + + /* now load each sub font independently */ + for ( index = 0; index < fd_index.count; index++ ) + { + sub = font->subfonts[index]; + error = CFF_Load_SubFont( sub, &fd_index, index, stream, base_offset ); + if (error) goto Fail_CID; } - /* read the charstrings index now */ - if ( font->top_dict.charstrings_offset == 0 ) - { - FT_ERROR(( "T2_Load_CFF_Font: no charstrings offset!\n" )); - error = FT_Err_Unknown_File_Format; - goto Exit; - } + /* now load the FD Select array */ + error = CFF_Load_FD_Select( &font->fd_select, + dict->cid_count, + stream, + base_offset + dict->cid_fd_select_offset ); - if ( FILE_Seek( base_offset + font->top_dict.charstrings_offset ) ) - goto Exit; - - error = t2_new_cff_index( &font->charstrings_index, stream, 0 ); - if ( error ) - goto Exit; - - /* read the local subrs, if any */ - - if ( font->private_dict.local_subrs_offset ) - { - if ( FILE_Seek( base_offset + font->top_dict.private_offset + - font->private_dict.local_subrs_offset ) ) - goto Exit; - - error = t2_new_cff_index( &font->local_subrs_index, stream, 1 ); - if ( error ) - goto Exit; - } - - /* explicit the global and local subrs */ - - if ( font->private_dict.local_subrs_offset ) - font->num_local_subrs = font->local_subrs_index.count; - else - font->num_local_subrs = 0; - - font->num_global_subrs = font->global_subrs_index.count; - - error = t2_explicit_cff_index( &font->global_subrs_index, - &font->global_subrs ) ; - - if ( font->private_dict.local_subrs_offset ) - error |= t2_explicit_cff_index( &font->local_subrs_index, - &font->local_subrs ) ; - - if ( error ) + Fail_CID: + t2_done_cff_index( &fd_index ); + + if (error) goto Exit; } + else + font->num_subfonts = 0; + + /* read the charstrings index now */ + if ( dict->charstrings_offset == 0 ) + { + FT_ERROR(( "T2_Load_CFF_Font: no charstrings offset!\n" )); + error = FT_Err_Unknown_File_Format; + goto Exit; + } + + if ( FILE_Seek( base_offset + dict->charstrings_offset ) ) + goto Exit; + + error = t2_new_cff_index( &font->charstrings_index, stream, 0 ); + if ( error ) + goto Exit; + + /* explicit the global subrs */ + font->num_global_subrs = font->global_subrs_index.count; + font->num_glyphs = font->charstrings_index.count; + + error = t2_explicit_cff_index( &font->global_subrs_index, + &font->global_subrs ) ; + + if ( error ) + goto Exit; /* get the font name */ font->font_name = T2_Get_Name( &font->name_index, face_index ); @@ -492,19 +712,28 @@ } + + LOCAL_FUNC void T2_Done_CFF_Font( CFF_Font* font ) { FT_Memory memory = font->memory; - + FT_UInt index; t2_done_cff_index( &font->global_subrs_index ); t2_done_cff_index( &font->string_index ); - t2_done_cff_index( &font->top_dict_index ); + t2_done_cff_index( &font->font_dict_index ); t2_done_cff_index( &font->name_index ); t2_done_cff_index( &font->charstrings_index ); - - FREE( font->local_subrs ); + + /* release font dictionaries */ + for ( index = 0; index < font->num_subfonts; index++ ) + CFF_Done_SubFont( memory, font->subfonts[index] ); + + CFF_Done_SubFont( memory, &font->top_font ); + + CFF_Done_FD_Select( &font->fd_select, font->stream ); + FREE( font->global_subrs ); FREE( font->font_name ); } diff --git a/src/cff/t2load.h b/src/cff/t2load.h index 05244e0d1..0cf64e065 100644 --- a/src/cff/t2load.h +++ b/src/cff/t2load.h @@ -56,6 +56,10 @@ LOCAL_DEF void T2_Done_CFF_Font( CFF_Font* font ); + LOCAL_DEF + FT_Byte CFF_Get_FD( CFF_FD_Select* select, + FT_UInt glyph_index ); + #ifdef __cplusplus } diff --git a/src/cff/t2objs.c b/src/cff/t2objs.c index 36b9c13ee..5c0b0a825 100644 --- a/src/cff/t2objs.c +++ b/src/cff/t2objs.c @@ -198,6 +198,7 @@ #ifdef TT_CONFIG_OPTION_EXTEND_ENGINE return TT_Init_Extensions( driver ); #else + UNUSED(driver); return T2_Err_Ok; #endif } @@ -220,6 +221,8 @@ /* destroy extensions registry if needed */ #ifdef TT_CONFIG_OPTION_EXTEND_ENGINE TT_Done_Extensions( driver ); +#else + UNUSED(driver); #endif } diff --git a/src/cff/t2parse.c b/src/cff/t2parse.c index cab4d7200..1b9207fbc 100644 --- a/src/cff/t2parse.c +++ b/src/cff/t2parse.c @@ -279,7 +279,7 @@ static FT_Error parse_font_matrix( T2_Parser* parser ) { - CFF_Top_Dict* dict = (CFF_Top_Dict*)parser->object; + CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object; FT_Matrix* matrix = &dict->font_matrix; FT_Byte** data = parser->stack; FT_Error error; @@ -303,7 +303,7 @@ static FT_Error parse_font_bbox( T2_Parser* parser ) { - CFF_Top_Dict* dict = (CFF_Top_Dict*)parser->object; + CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object; FT_BBox* bbox = &dict->font_bbox; FT_Byte** data = parser->stack; FT_Error error; @@ -327,7 +327,7 @@ static FT_Error parse_private_dict( T2_Parser* parser ) { - CFF_Top_Dict* dict = (CFF_Top_Dict*)parser->object; + CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object; FT_Byte** data = parser->stack; FT_Error error; @@ -348,7 +348,7 @@ static FT_Error parse_cid_ros( T2_Parser* parser ) { - CFF_Top_Dict* dict = (CFF_Top_Dict*)parser->object; + CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object; FT_Byte** data = parser->stack; FT_Error error; @@ -395,7 +395,7 @@ code | T2CODE, \ (FT_UInt)(char*)&T2_REF( T2TYPE, name ), \ sizeof( T2_REF( T2TYPE, name ) ), \ - 0 \ + 0, 0, 0 \ }, #undef T2_FIELD_DELTA @@ -478,7 +478,7 @@ /* and look for it in our current list. */ FT_UInt code; - FT_Int num_args = parser->top - parser->stack; + FT_UInt num_args = (FT_UInt)(parser->top - parser->stack); const T2_Field_Handler* field; @@ -498,7 +498,7 @@ for ( field = t2_field_handlers; field->kind; field++ ) { - if ( field->code == code ) + if ( field->code == (FT_Int)code ) { /* we found our field's handler; read it */ FT_Long val; diff --git a/src/cff/t2tokens.h b/src/cff/t2tokens.h index 7b6e4e6c5..13a15e43d 100644 --- a/src/cff/t2tokens.h +++ b/src/cff/t2tokens.h @@ -18,7 +18,7 @@ #undef T2TYPE #undef T2CODE -#define T2TYPE CFF_Top_Dict +#define T2TYPE CFF_Font_Dict #define T2CODE T2CODE_TOPDICT T2_FIELD_STRING ( 0, version ) diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c index 4b38c2c3c..acdbb759e 100644 --- a/src/sfnt/sfobjs.c +++ b/src/sfnt/sfobjs.c @@ -244,6 +244,9 @@ FT_Error error; SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt; + UNUSED(face_index); + UNUSED(num_params); + UNUSED(params); /* Load tables */ if ( LOAD_( header ) ||