add support for new postscript hinter

This commit is contained in:
David Turner 2001-10-18 11:49:26 +00:00
parent 573a98d048
commit 5893c1bb2a
14 changed files with 300 additions and 81 deletions

View File

@ -4,9 +4,11 @@ FT_USE_MODULE(t1cid_driver_class)
FT_USE_MODULE(pcf_driver_class)
FT_USE_MODULE(psaux_module_class)
FT_USE_MODULE(psnames_module_class)
FT_USE_MODULE(pshinter_module_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(winfnt_driver_class)

View File

@ -171,13 +171,16 @@ FT_BEGIN_HEADER
/* glyph_delta :: The 2d translation vector corresponding to */
/* the glyph transformation, if necessary. */
/* */
/* glyph_hints :: format-specific glyph hints management */
/* */
typedef struct FT_Slot_InternalRec_
{
FT_GlyphLoader* loader;
FT_Bool glyph_transformed;
FT_Matrix glyph_matrix;
FT_Vector glyph_delta;
void* glyph_hints;
} FT_GlyphSlot_InternalRec;

View File

@ -40,8 +40,10 @@
#define FT_INTERNAL_CFF_TYPES_H <freetype/internal/cfftypes.h>
#define FT_INTERNAL_FNT_TYPES_H <freetype/internal/fnttypes.h>
#define FT_INTERNAL_POSTSCRIPT_NAMES_H <freetype/internal/psnames.h>
#define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h>
#define FT_INTERNAL_POSTSCRIPT_NAMES_H <freetype/internal/psnames.h>
#define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h>
#define FT_INTERNAL_POSTSCRIPT_HINTS_H <freetype/internal/pshints.h>
#define FT_INTERNAL_POSTSCRIPT_GLOBALS_H <freetype/internal/psglobal.h>
#define FT_INTERNAL_AUTOHINT_H <freetype/internal/autohint.h>

View File

@ -426,19 +426,11 @@ FT_BEGIN_HEADER
typedef struct T1_Builder_Funcs_
{
<<<<<<< psaux.h
void
(*init)( T1_Builder* builder,
FT_Face face,
FT_Size size,
FT_GlyphSlot slot );
=======
void (*init)( T1_Builder* builder,
FT_Face face,
FT_Size size,
FT_GlyphSlot slot,
FT_Bool hinting );
>>>>>>> 1.14.2.2
void
(*done)( T1_Builder* builder );

View File

@ -24,7 +24,7 @@
#include<ft2build.h>
#include FT_TYPE1_TABLES_H
#include FT_INTERNAL_POSTSCRIPT_NAMES_H
#include FT_INTERNAL_POSTSCRIPT_HINTS_H
FT_BEGIN_HEADER
@ -172,6 +172,9 @@ FT_BEGIN_HEADER
/* support for Multiple Masters fonts */
T1_Blend* blend;
/* since FT 2.1 - interface to Postscript hinter */
void* pshinter;
} T1_FaceRec;

View File

@ -14,6 +14,7 @@ SubDirHdrs [ FT2_SubDir src ] ;
#
HDRMACRO [ FT2_SubDir include internal internal.h ] ;
SubInclude FT2_TOP src pshinter ;
SubInclude FT2_TOP src autohint ;
SubInclude FT2_TOP src base ;
SubInclude FT2_TOP src cache ;

View File

@ -101,7 +101,7 @@
static FT_Error
reallocate_t1_table( PS_Table* table,
FT_Long new_size )
FT_Int new_size )
{
FT_Memory memory = table->memory;
FT_Byte* old_base = table->block;
@ -1071,7 +1071,8 @@
T1_Builder_Init( T1_Builder* builder,
FT_Face face,
FT_Size size,
FT_GlyphSlot glyph )
FT_GlyphSlot glyph,
FT_Bool hinting )
{
builder->path_begun = 0;
builder->load_points = 1;
@ -1085,10 +1086,16 @@
FT_GlyphLoader* loader = glyph->internal->loader;
builder->loader = loader;
builder->base = &loader->base.outline;
builder->current = &loader->current.outline;
builder->loader = loader;
builder->base = &loader->base.outline;
builder->current = &loader->current.outline;
FT_GlyphLoader_Rewind( loader );
builder->hints_globals = size->internal;
builder->hints_funcs = 0;
if (hinting)
builder->hints_funcs = glyph->internal->glyph_hints;
}
if ( size )

View File

@ -147,7 +147,8 @@ FT_BEGIN_HEADER
T1_Builder_Init( T1_Builder* builder,
FT_Face face,
FT_Size size,
FT_GlyphSlot glyph );
FT_GlyphSlot glyph,
FT_Bool hinting );
FT_LOCAL void
T1_Builder_Done( T1_Builder* builder );
@ -176,7 +177,6 @@ FT_BEGIN_HEADER
FT_Pos x,
FT_Pos y );
FT_LOCAL void
T1_Builder_Close_Contour( T1_Builder* builder );

View File

@ -18,6 +18,7 @@
#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_POSTSCRIPT_HINTS_H
#include FT_OUTLINE_H
#include "t1decode.h"
@ -140,7 +141,7 @@
FT_String* name = (FT_String*)decoder->glyph_names[n];
if ( name && strcmp( name,glyph_name ) == 0 )
if ( name && name[0] == glyph_name[0] && strcmp( name,glyph_name ) == 0 )
return n;
}
@ -244,6 +245,7 @@
glyph->format = ft_glyph_format_composite;
loader->current.num_subglyphs = 2;
goto Exit;
}
/* First load `bchar' in builder */
@ -266,6 +268,9 @@
decoder->builder.left_bearing.x = 0;
decoder->builder.left_bearing.y = 0;
decoder->builder.pos_x = adx - asb;
decoder->builder.pos_y = ady;
/* Now load `achar' on top of */
/* the base outline */
error = T1_Decoder_Parse_Glyph( decoder, achar_index );
@ -278,17 +283,22 @@
decoder->builder.left_bearing = left_bearing;
decoder->builder.advance = advance;
/* XXX: old code doesn't work with postscript hinter */
#if 0
/* Finally, move the accent */
if ( decoder->builder.load_points )
{
FT_Outline dummy;
dummy.n_points = (short)( base->n_points - n_base_points );
dummy.points = base->points + n_base_points;
FT_Outline_Translate( &dummy, adx - asb, ady );
}
#else
decoder->builder.pos_x = 0;
decoder->builder.pos_y = 0;
#endif
Exit:
return error;
@ -323,8 +333,9 @@
FT_Byte* ip;
FT_Byte* limit;
T1_Builder* builder = &decoder->builder;
FT_Pos x, y;
FT_Pos x, y, orig_x, orig_y;
T1_Hints_Funcs hinter;
/* we don't want to touch the source code -- use macro trick */
#define start_point T1_Builder_Start_Point
@ -341,14 +352,20 @@
builder->path_begun = 0;
hinter = (T1_Hints_Funcs) builder->hints_funcs;
zone->base = charstring_base;
limit = zone->limit = charstring_base + charstring_len;
ip = zone->cursor = zone->base;
error = PSaux_Err_Ok;
x = builder->pos_x;
y = builder->pos_y;
x = orig_x = builder->pos_x;
y = orig_y = builder->pos_y;
/* begin hints recording session, if any */
if ( hinter )
hinter->open( hinter->hints );
/* now, execute loop */
while ( ip < limit )
@ -613,6 +630,10 @@
goto Syntax_Error;
}
ip += 2;
if ( hinter )
hinter->reset( hinter->hints, builder->current->n_points );
break;
case 12:
@ -707,7 +728,19 @@
FT_TRACE4(( " endchar" ));
close_contour( builder );
/* close hints recording session */
if ( hinter )
{
if (hinter->close( hinter->hints, builder->current->n_points ))
goto Syntax_Error;
/* apply hints to the loaded glyph outline now */
hinter->apply( hinter->hints,
builder->current,
(PSH_Globals) builder->hints_globals );
}
/* add current outline to the glyph slot */
FT_GlyphLoader_Add( builder->loader );
@ -722,8 +755,8 @@
builder->advance.x = top[1];
builder->advance.y = 0;
builder->last.x = x = top[0];
builder->last.y = y = 0;
orig_x = builder->last.x = x = builder->pos_x + top[0];
orig_y = builder->last.y = y = builder->pos_y;
/* the `metrics_only' indicates that we only want to compute */
/* the glyph's metrics (lsb + advance width), not load the */
@ -746,8 +779,8 @@
builder->advance.x = top[2];
builder->advance.y = top[3];
builder->last.x = x = top[0];
builder->last.y = y = top[1];
builder->last.x = x = builder->pos_x + top[0];
builder->last.y = y = builder->pos_y + top[1];
/* the `metrics_only' indicates that we only want to compute */
/* the glyph's metrics (lsb + advance width), not load the */
@ -973,22 +1006,50 @@
case op_hstem:
FT_TRACE4(( " hstem" ));
/* record horizontal hint */
if ( hinter )
{
/* top[0] += builder->left_bearing.y; */
hinter->stem( hinter->hints, 0, top );
}
break;
case op_hstem3:
FT_TRACE4(( " hstem3" ));
/* record horizontal counter-controlled hints */
if ( hinter )
hinter->stem3( hinter->hints, 0, top );
break;
case op_vstem:
FT_TRACE4(( " vstem" ));
/* record vertical hint */
if ( hinter )
{
top[0] += orig_x;
hinter->stem( hinter->hints, 1, top );
}
break;
case op_vstem3:
FT_TRACE4(( " vstem3" ));
/* record vertical counter-controlled hints */
if ( hinter )
{
FT_Pos dx = orig_x;
top[0] += dx;
top[2] += dx;
top[4] += dx;
hinter->stem3( hinter->hints, 1, top );
}
break;
case op_setcurrentpoint:
@ -1011,6 +1072,7 @@
} /* while ip < limit */
FT_TRACE4(( "..end..\n\n" ));
return error;
Syntax_Error:
@ -1024,6 +1086,7 @@
}
/* parse a single Type 1 glyph */
FT_LOCAL_DEF FT_Error
T1_Decoder_Parse_Glyph( T1_Decoder* decoder,
FT_UInt glyph )
@ -1032,6 +1095,7 @@
}
/* initialise T1 decoder */
FT_LOCAL_DEF FT_Error
T1_Decoder_Init( T1_Decoder* decoder,
FT_Face face,
@ -1039,6 +1103,7 @@
FT_GlyphSlot slot,
FT_Byte** glyph_names,
T1_Blend* blend,
FT_Bool hinting,
T1_Decoder_Callback parse_callback )
{
MEM_Set( decoder, 0, sizeof ( *decoder ) );
@ -1059,7 +1124,7 @@
decoder->psnames = psnames;
}
T1_Builder_Init( &decoder->builder, face, size, slot );
T1_Builder_Init( &decoder->builder, face, size, slot, hinting );
decoder->num_glyphs = face->num_glyphs;
decoder->glyph_names = glyph_names;
@ -1072,6 +1137,7 @@
}
/* finalize T1 decoder */
FT_LOCAL_DEF void
T1_Decoder_Done( T1_Decoder* decoder )
{

View File

@ -49,6 +49,7 @@ FT_BEGIN_HEADER
FT_GlyphSlot slot,
FT_Byte** glyph_names,
T1_Blend* blend,
FT_Bool hinting,
T1_Decoder_Callback parse_glyph );
FT_LOCAL void

View File

@ -331,7 +331,10 @@
const FT_Driver_Class t1_driver_class =
{
{
ft_module_font_driver | ft_module_driver_scalable,
ft_module_font_driver |
ft_module_driver_scalable |
ft_module_driver_has_hinter,
sizeof( FT_DriverRec ),
"type1",
@ -340,8 +343,8 @@
0, /* format interface */
(FT_Module_Constructor)T1_Init_Driver,
(FT_Module_Destructor) T1_Done_Driver,
(FT_Module_Constructor)T1_Driver_Init,
(FT_Module_Destructor) T1_Driver_Done,
(FT_Module_Requester) Get_Interface,
},
@ -349,15 +352,15 @@
sizeof( T1_SizeRec ),
sizeof( T1_GlyphSlotRec ),
(FTDriver_initFace) T1_Init_Face,
(FTDriver_doneFace) T1_Done_Face,
(FTDriver_initSize) 0,
(FTDriver_doneSize) 0,
(FTDriver_initGlyphSlot)0,
(FTDriver_doneGlyphSlot)0,
(FTDriver_initFace) T1_Face_Init,
(FTDriver_doneFace) T1_Face_Done,
(FTDriver_initSize) T1_Size_Init,
(FTDriver_doneSize) T1_Size_Done,
(FTDriver_initGlyphSlot)T1_GlyphSlot_Init,
(FTDriver_doneGlyphSlot)T1_GlyphSlot_Done,
(FTDriver_setCharSizes) 0,
(FTDriver_setPixelSizes)0,
(FTDriver_setCharSizes) T1_Size_Reset,
(FTDriver_setPixelSizes)T1_Size_Reset,
(FTDriver_loadGlyph) T1_Load_Glyph,
(FTDriver_getCharIndex) Get_Char_Index,

View File

@ -93,6 +93,7 @@
0, /* glyph slot */
(FT_Byte**)type1->glyph_names,
face->blend,
0,
T1_Parse_Glyph );
if ( error )
return error;
@ -172,6 +173,7 @@
(FT_GlyphSlot)glyph,
(FT_Byte**)type1->glyph_names,
face->blend,
FT_BOOL(hinting),
T1_Parse_Glyph );
if ( error )
goto Exit;
@ -239,20 +241,15 @@
if ( size && size->root.metrics.y_ppem < 24 )
glyph->root.outline.flags |= ft_outline_high_precision;
/* apply the font matrix */
/* XXXX: the following needs serious work to work properly with hinting !! */
#if 0
/* apply the font matrix, if any.. */
FT_Outline_Transform( &glyph->root.outline, &font_matrix );
FT_Outline_Translate( &glyph->root.outline,
font_offset.x,
font_offset.y );
#if 0
glyph->root.outline.second_pass = TRUE;
glyph->root.outline.high_precision = size->root.metrics.y_ppem < 24;
glyph->root.outline.dropout_mode = 2;
#endif /* 0 */
#endif
if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
{
@ -264,12 +261,13 @@
FT_Fixed y_scale = glyph->y_scale;
/* First of all, scale the points */
for ( n = cur->n_points; n > 0; n--, vec++ )
{
vec->x = FT_MulFix( vec->x, x_scale );
vec->y = FT_MulFix( vec->y, y_scale );
}
/* First of all, scale the points, fi we're not hinting */
if ( !hinting )
for ( n = cur->n_points; n > 0; n--, vec++ )
{
vec->x = FT_MulFix( vec->x, x_scale );
vec->y = FT_MulFix( vec->y, y_scale );
}
FT_Outline_Get_CBox( &glyph->root.outline, &cbox );

View File

@ -45,6 +45,121 @@
#define FT_COMPONENT trace_t1objs
/*************************************************************************/
/* */
/* SIZE FUNCTIONS */
/* */
/* note that we store the global hints in the size's "internal" root */
/* field.. */
/* */
/*************************************************************************/
static PSH_Globals_Funcs
T1_Size_Get_Globals_Funcs( T1_Size size )
{
T1_Face face = (T1_Face) size->root.face;
PSHinter_Interface* pshinter = face->pshinter;
FT_Module module;
module = FT_Get_Module( size->root.face->driver->root.library, "pshinter" );
return ( module && pshinter && pshinter->get_globals_funcs )
? pshinter->get_globals_funcs( module )
: 0 ;
}
FT_LOCAL_DEF
void T1_Size_Done( T1_Size size )
{
if ( size->root.internal )
{
PSH_Globals_Funcs funcs;
funcs = T1_Size_Get_Globals_Funcs(size);
if (funcs)
funcs->destroy( (PSH_Globals) size->root.internal );
size->root.internal = 0;
}
}
FT_LOCAL_DEF
FT_Error T1_Size_Init( T1_Size size )
{
FT_Error error = 0;
PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size );
if ( funcs )
{
PSH_Globals globals;
T1_Face face = (T1_Face) size->root.face;
error = funcs->create( size->root.face->memory,
&face->type1.private_dict, &globals );
if (!error)
size->root.internal = (FT_Size_Internal)(void*) globals;
}
return error;
}
FT_LOCAL_DEF
FT_Error T1_Size_Reset( T1_Size size )
{
PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs(size);
FT_Error error = 0;
if (funcs)
error = funcs->set_scale( (PSH_Globals) size->root.internal,
size->root.metrics.x_scale,
size->root.metrics.y_scale,
0, 0 );
return error;
}
/*************************************************************************/
/* */
/* SLOT FUNCTIONS */
/* */
/*************************************************************************/
FT_LOCAL_DEF void
T1_GlyphSlot_Done( T1_GlyphSlot slot )
{
slot->root.internal->glyph_hints = 0;
}
FT_LOCAL_DEF FT_Error
T1_GlyphSlot_Init( T1_GlyphSlot slot )
{
T1_Face face;
PSHinter_Interface* pshinter;
face = (T1_Face) slot->root.face;
pshinter = face->pshinter;
if (pshinter)
{
FT_Module module;
module = FT_Get_Module( slot->root.face->driver->root.library, "pshinter" );
if (module)
{
T1_Hints_Funcs funcs;
funcs = pshinter->get_t1_funcs( module );
slot->root.internal->glyph_hints = (void*)funcs;
}
}
return 0;
}
/*************************************************************************/
/* */
/* FACE FUNCTIONS */
@ -55,7 +170,7 @@
/*************************************************************************/
/* */
/* <Function> */
/* T1_Done_Face */
/* T1_Face_Done */
/* */
/* <Description> */
/* The face object destructor. */
@ -63,8 +178,8 @@
/* <Input> */
/* face :: A typeless pointer to the face object to destroy. */
/* */
FT_LOCAL_DEF void
T1_Done_Face( T1_Face face )
FT_LOCAL_DEF
void T1_Face_Done( T1_Face face )
{
FT_Memory memory;
T1_Font* type1 = &face->type1;
@ -124,10 +239,11 @@
}
/*************************************************************************/
/* */
/* <Function> */
/* T1_Init_Face */
/* T1_Face_Init */
/* */
/* <Description> */
/* The face object constructor. */
@ -148,15 +264,16 @@
/* FreeType error code. 0 means success. */
/* */
FT_LOCAL_DEF FT_Error
T1_Init_Face( FT_Stream stream,
T1_Face_Init( FT_Stream stream,
T1_Face face,
FT_Int face_index,
FT_Int num_params,
FT_Parameter* params )
{
FT_Error error;
PSNames_Interface* psnames;
PSAux_Interface* psaux;
FT_Error error;
PSNames_Interface* psnames;
PSAux_Interface* psaux;
PSHinter_Interface* pshinter;
FT_UNUSED( num_params );
FT_UNUSED( params );
@ -183,6 +300,15 @@
face->psaux = psaux;
}
pshinter = (PSHinter_Interface*)face->pshinter;
if ( !pshinter )
{
pshinter = (PSHinter_Interface*)
FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "pshinter" );
face->pshinter = pshinter;
}
/* open the tokenizer, this will also check the font format */
error = T1_Open_Face( face );
@ -196,7 +322,7 @@
/* check the face index */
if ( face_index != 0 )
{
FT_ERROR(( "T1_Init_Face: invalid face index\n" ));
FT_ERROR(( "T1_Face_Init: invalid face index\n" ));
error = T1_Err_Invalid_Argument;
goto Exit;
}
@ -375,7 +501,7 @@
/*************************************************************************/
/* */
/* <Function> */
/* T1_Init_Driver */
/* T1_Driver_Init */
/* */
/* <Description> */
/* Initializes a given Type 1 driver object. */
@ -387,7 +513,7 @@
/* FreeType error code. 0 means success. */
/* */
FT_LOCAL_DEF FT_Error
T1_Init_Driver( T1_Driver driver )
T1_Driver_Init( T1_Driver driver )
{
FT_UNUSED( driver );
@ -398,7 +524,7 @@
/*************************************************************************/
/* */
/* <Function> */
/* T1_Done_Driver */
/* T1_Driver_Done */
/* */
/* <Description> */
/* Finalizes a given Type 1 driver. */
@ -407,7 +533,7 @@
/* driver :: A handle to the target Type 1 driver. */
/* */
FT_LOCAL_DEF void
T1_Done_Driver( T1_Driver driver )
T1_Driver_Done( T1_Driver driver )
{
FT_UNUSED( driver );
}

View File

@ -100,15 +100,20 @@ FT_BEGIN_HEADER
/* */
typedef struct T1_SizeRec_
{
FT_SizeRec root;
FT_Bool valid;
T1_Size_Hints* hints; /* defined in the hinter. This allows */
/* us to experiment with different */
/* hinting schemes without having to */
/* change `t1objs' each time. */
FT_SizeRec root;
} T1_SizeRec;
FT_LOCAL
void T1_Size_Done( T1_Size size );
FT_LOCAL
FT_Error T1_Size_Reset( T1_Size size );
FT_LOCAL
FT_Error T1_Size_Init( T1_Size size );
/*************************************************************************/
/* */
/* <Type> */
@ -130,26 +135,36 @@ FT_BEGIN_HEADER
FT_Fixed x_scale;
FT_Fixed y_scale;
T1_Glyph_Hints* hints; /* defined in the hinter */
} T1_GlyphSlotRec;
FT_LOCAL FT_Error
T1_Init_Face( FT_Stream stream,
T1_Face_Init( FT_Stream stream,
T1_Face face,
FT_Int face_index,
FT_Int num_params,
FT_Parameter* params );
FT_LOCAL void
T1_Done_Face( T1_Face face );
T1_Face_Done( T1_Face face );
FT_LOCAL FT_Error
T1_Init_Driver( T1_Driver driver );
T1_Size_Init( T1_Size size );
FT_LOCAL void
T1_Size_Done( T1_Size size );
FT_LOCAL FT_Error
T1_GlyphSlot_Init( T1_GlyphSlot slot );
FT_LOCAL void
T1_GlyphSlot_Done( T1_GlyphSlot slot );
FT_LOCAL FT_Error
T1_Driver_Init( T1_Driver driver );
FT_LOCAL void
T1_Done_Driver( T1_Driver driver );
T1_Driver_Done( T1_Driver driver );
FT_END_HEADER