ref: 9d636b6d14dc5decc9651757e15faab5267b0873
parent: 74abee8e2ea269b983916b8eb55bef385b98f2e2
author: David Turner <[email protected]>
date: Tue Jun 27 19:32:27 EDT 2000
various cleanups to reduce compiler warnings + support for CID-keyed fonts in the CFF driver (still some unexpected bugs though..)
--- 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
--- a/config/win32/w32-dev.mk
+++ b/config/win32/w32-dev.mk
@@ -98,7 +98,7 @@
# 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.
--- a/demos/src/ftmulti.c
+++ b/demos/src/ftmulti.c
@@ -13,7 +13,6 @@
/****************************************************************************/
#include <freetype/freetype.h>
-#include <freetype/ftrender.h>
#include <freetype/ftmm.h>
#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,16 +451,7 @@
}
- 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"
@@ -713,13 +690,6 @@
error = FT_Init_FreeType( &library );
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;
--- a/demos/src/ftstring.c
+++ b/demos/src/ftstring.c
@@ -11,7 +11,6 @@
/****************************************************************************/
#include <freetype/freetype.h>
-#include <freetype/ftrender.h>
#include <freetype/ftglyph.h>
#include "common.h"
@@ -60,12 +59,7 @@
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
@@ -667,13 +642,6 @@
/* Initialize engine */
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;
--- a/demos/src/ftview.c
+++ b/demos/src/ftview.c
@@ -17,7 +17,6 @@
#include <freetype/freetype.h>
-#include <freetype/ftrender.h>
/* the following header shouldn't be used in normal programs */
#include <freetype/internal/ftdebug.h>
@@ -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,15 +77,10 @@
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,80 +146,45 @@
#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 );
+ x_top = x_offset + glyph->bitmap_left;
+ y_top = y_offset - glyph->bitmap_top;
-#if 0
- if ( bit.pitch < 0 )
- y_top = bit.rows - y_top;
-#endif
-
grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color );
return 0;
@@ -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,16 +414,7 @@
}
- 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;
--- 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)
--- a/include/freetype/fterrors.h
+++ b/include/freetype/fterrors.h
@@ -55,6 +55,7 @@
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" )
--- 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,
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -384,7 +384,7 @@
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 */
@@ -391,7 +391,7 @@
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];
@@ -410,6 +410,14 @@
FT_UInt hook_index,
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 );
--- 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,8 +104,10 @@
FT_ULong cid_fd_select_offset;
FT_UInt cid_font_name;
- } CFF_Top_Dict;
+ } CFF_Font_Dict;
+
+
typedef struct CFF_Private_
{
FT_Byte num_blue_values;
@@ -138,6 +141,42 @@
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_
{
@@ -144,6 +183,7 @@
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;
--- 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 );
--- 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 */
--- a/src/cff/t2load.c
+++ b/src/cff/t2load.c
@@ -318,8 +318,241 @@
#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,
FT_Int face_index,
CFF_Font* font )
@@ -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,111 +614,96 @@
}
/* 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;
-
-
- /* 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;
+ 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;
- /* read the charstrings index now */
- if ( font->top_dict.charstrings_offset == 0 )
+ /* 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++ )
{
- FT_ERROR(( "T2_Load_CFF_Font: no charstrings offset!\n" ));
- error = FT_Err_Unknown_File_Format;
- goto Exit;
+ sub = font->subfonts[index];
+ error = CFF_Load_SubFont( sub, &fd_index, index, stream, base_offset );
+ if (error) goto Fail_CID;
}
- if ( FILE_Seek( base_offset + font->top_dict.charstrings_offset ) )
- 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 );
- error = t2_new_cff_index( &font->charstrings_index, stream, 0 );
- if ( error )
+ Fail_CID:
+ t2_done_cff_index( &fd_index );
+
+ if (error)
goto Exit;
+ }
+ else
+ font->num_subfonts = 0;
- /* read the local subrs, if any */
+ /* 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 ( font->private_dict.local_subrs_offset )
- {
- if ( FILE_Seek( base_offset + font->top_dict.private_offset +
- font->private_dict.local_subrs_offset ) )
- goto Exit;
+ if ( FILE_Seek( base_offset + dict->charstrings_offset ) )
+ goto Exit;
- error = t2_new_cff_index( &font->local_subrs_index, stream, 1 );
- if ( error )
- goto Exit;
- }
+ error = t2_new_cff_index( &font->charstrings_index, stream, 0 );
+ if ( error )
+ goto Exit;
- /* explicit the global and local subrs */
+ /* explicit the global subrs */
+ font->num_global_subrs = font->global_subrs_index.count;
+ font->num_glyphs = font->charstrings_index.count;
- if ( font->private_dict.local_subrs_offset )
- font->num_local_subrs = font->local_subrs_index.count;
- else
- font->num_local_subrs = 0;
+ error = t2_explicit_cff_index( &font->global_subrs_index,
+ &font->global_subrs ) ;
- font->num_global_subrs = font->global_subrs_index.count;
+ if ( error )
+ goto Exit;
- 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 )
- 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 );
}
--- 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
}
--- 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
}
--- 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;
--- 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 )
--- 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 ) ||