various cleanups to reduce compiler warnings

+ support for CID-keyed fonts in the CFF driver
(still some unexpected bugs though..)
This commit is contained in:
David Turner 2000-06-27 23:32:27 +00:00
parent 74abee8e2e
commit 9d636b6d14
18 changed files with 506 additions and 288 deletions

34
CHANGES
View File

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

View File

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

View File

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

View File

@ -11,7 +11,6 @@
/****************************************************************************/
#include <freetype/freetype.h>
#include <freetype/ftrender.h>
#include <freetype/ftglyph.h>
#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;

View File

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

View File

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

View File

@ -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" )

View File

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

View File

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

View File

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

View File

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

View File

@ -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 */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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