updates to the Postscript hinter, some _big_ bugs have been

fixed, and the results are now a bit more decent.., but there
are still problems I can't explain just yet

(I guess some information from the Private dictionary is not
 processed correctly !!)
This commit is contained in:
David Turner 2001-09-10 17:03:37 +00:00
parent 9f781c410b
commit fbb7617183
11 changed files with 555 additions and 226 deletions

View File

@ -22,143 +22,11 @@
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_TYPE1_TABLES_H
#include FT_INTERNAL_POSTSCRIPT_GLOBALS_H
FT_BEGIN_HEADER
/**********************************************************************/
/**********************************************************************/
/***** *****/
/***** EXTERNAL REPRESENTATION OF GLOBALS *****/
/***** *****/
/**********************************************************************/
/**********************************************************************/
/****************************************************************
*
* @constant: PS_GLOBALS_MAX_BLUE_ZONES
*
* @description:
* the maximum number of blue zones in a font global hints
* structure. See @PS_Globals_BluesRec
*/
#define PS_GLOBALS_MAX_BLUE_ZONES 16
/****************************************************************
*
* @constant: PS_GLOBALS_MAX_STD_WIDTHS
*
* @description:
* the maximum number of standard and snap widths in either the
* horizontal or vertical direction. See @PS_Globals_WidthsRec
*/
#define PS_GLOBALS_MAX_STD_WIDTHS 16
/****************************************************************
*
* @type: PS_Globals
*
* @description:
* a handle to a @PS_GlobalsRec structure used to
* describe the global hints of a given font
*/
typedef struct PS_GlobalsRec_* PS_Globals;
/****************************************************************
*
* @struct: PS_Globals_BluesRec
*
* @description:
* a structure used to model the global blue zones of a given
* font
*
* @fields:
* count :: number of blue zones
* zones :: an array of (count*2) coordinates describing the zones
*
* count_family :: number of family blue zones
* zones_family :: an array of (count_family*2) coordinates describing
* the family blue zones
*
* scale :: the blue scale to be used (fixed float)
* shift :: the blue shift to be used
* fuzz :: the blue fuzz to be used
*
* @note:
* each blue zone is modeled by a (reference,overshoot) coordinate pair
* in the table. zones can be placed in any order..
*/
typedef struct PS_Globals_BluesRec
{
FT_UInt count;
FT_Int16 zones[ 2*PS_GLOBALS_MAX_BLUE_ZONES ];
FT_UInt count_family;
FT_Int16 zones_family[ 2*PS_GLOBALS_MAX_BLUE_ZONES ];
FT_Fixed scale;
FT_Int16 shift;
FT_Int16 fuzz;
} PS_Globals_BluesRec, *PS_Globals_Blues;
/****************************************************************
*
* @type: PS_Global_Widths;
*
* @description:
* a handle to a @PS_Globals_WidthsRec structure used to model
* the global standard and snap widths in a given direction
*/
typedef struct PS_Globals_WidthsRec_* PS_Globals_Widths;
/****************************************************************
*
* @struct: PS_Globals_WidthsRec
*
* @description:
* a structure used to model the global standard and snap widths
* in a given font
*
* @fields:
* count :: number of widths
* widths :: an array of 'count' widths in font units.
*
* @note:
* 'widths[0]' must be the standard width or height, while
* remaining elements of the array are snap widths or heights
*/
typedef struct PS_Globals_WidthsRec_
{
FT_UInt count;
FT_Int16 widths[ PS_GLOBALS_MAX_STD_WIDTHS ];
} PS_Globals_WidthsRec;
/****************************************************************
*
* @struct: PS_Globals_GlobalsRec
*
* @description:
* a structure used to model the global hints for a given font
*
* @fields:
* horizontal :: horizontal widths
* vertical :: vertical heights
* blues :: blue zones
*/
typedef struct PS_GlobalsRec_
{
PS_Globals_WidthsRec horizontal;
PS_Globals_WidthsRec vertical;
PS_Globals_BluesRec blues;
} PS_GlobalsRec;
/**********************************************************************/
/**********************************************************************/
/***** *****/
@ -170,11 +38,9 @@ FT_BEGIN_HEADER
typedef struct PSH_GlobalsRec_* PSH_Globals;
typedef FT_Error (*PSH_Globals_NewFunc)( FT_Memory memory,
T1_Private* private_dict,
PSH_Globals* aglobals );
typedef FT_Error (*PSH_Globals_ResetFunc)( PSH_Globals globals,
PS_Globals ps_globals );
typedef FT_Error (*PSH_Globals_SetScaleFunc)( PSH_Globals globals,
FT_Fixed x_scale,
FT_Fixed y_scale,
@ -186,7 +52,6 @@ FT_BEGIN_HEADER
typedef struct
{
PSH_Globals_NewFunc create;
PSH_Globals_ResetFunc reset;
PSH_Globals_SetScaleFunc set_scale;
PSH_Globals_DestroyFunc destroy;

View File

@ -994,7 +994,10 @@
/* record horizontal hint */
if ( hinter )
{
/* top[0] += builder->left_bearing.y; */
hinter->stem( hinter->hints, 0, top );
}
break;
@ -1012,7 +1015,10 @@
/* record vertical hint */
if ( hinter )
{
top[0] += builder->left_bearing.x;
hinter->stem( hinter->hints, 1, top );
}
break;

View File

@ -481,7 +481,7 @@
{
FT_Pos x, *px;
px = vertical ? &vec->y : &vec->x;
px = vertical ? &vec->x : &vec->y;
x = *px;
*px = psh_hint_table_tune_coord( table, (FT_Int)x );
@ -501,12 +501,12 @@
if ( vertical )
{
for ( ; count > 0; count--, vec++ )
vec->y = FT_MulFix( vec->y, scale ) + delta;
vec->x = FT_MulFix( vec->x, scale ) + delta;
}
else
{
for ( ; count > 0; count--, vec++ )
vec->x = FT_MulFix( vec->x, scale ) + delta;
vec->y = FT_MulFix( vec->y, scale ) + delta;
}
}
}

View File

@ -41,9 +41,11 @@ FT_BEGIN_HEADER
} PSH_Hint_Flags;
#define psh_hint_is_active(x) (((x)->flags & PSH_HINT_FLAG_ACTIVE) != 0)
#define psh_hint_is_ghost(x) (((x)->flags & PSH_HINT_FLAG_GHOST ) != 0)
#define psh_hint_activate(x) (x)->flags |= PSH_HINT_FLAG_ACTIVE
#define psh_hint_deactivate(x) (x)->flags &= ~PSH_HINT_FLAG_ACTIVE
typedef struct PSH_HintRec_
{
FT_Int org_pos;
@ -94,6 +96,15 @@ FT_BEGIN_HEADER
PSH_Globals globals );
#ifdef DEBUG_VIEW
extern int ps_debug_no_horz_hints;
extern int ps_debug_no_vert_hints;
extern PSH_Hint_Table ps_debug_hint_table;
typedef void (*PSH_HintFunc)( PSH_Hint hint, FT_Bool vertical );
extern PSH_HintFunc ps_debug_hint_func;
#endif
FT_END_HEADER
#endif /* __PS_HINTER_FITTER_H__ */

View File

@ -13,30 +13,6 @@
/*************************************************************************/
/*************************************************************************/
/* reset the widths/heights table */
static void
psh_globals_reset_widths( PSH_Globals globals,
FT_UInt direction,
PS_Globals_Widths widths )
{
PSH_Dimension dim = &globals->dimension[direction];
/* simple copy of the original widths values - no sorting */
{
FT_UInt count = widths->count;
PSH_Width write = dim->std.widths;
FT_Int16* read = widths->widths;
dim->std.count = count;
for ( ; count > 0; count-- )
{
write->org = read[0];
write++;
read++;
}
}
}
/* scale the widths/heights table */
static void
@ -109,40 +85,20 @@
/*************************************************************************/
/*************************************************************************/
/* re-read blue zones from the original fonts, and store them into out */
/* private structure. This function re-orders, sanitizes and fuzz-expands */
/* the zones as well.. */
static void
psh_blues_reset_zones( PSH_Blues target,
PS_Globals_Blues source,
FT_Int family )
psh_blues_set_zones_0( PSH_Blues target,
FT_UInt read_count,
FT_Short* read,
PSH_Blue_Table top_table,
PSH_Blue_Table bot_table )
{
PSH_Blue_Table top_table, bot_table;
FT_Int16* read;
FT_Int read_count, count, count_top, count_bot;
FT_UInt count_top = top_table->count;
FT_UInt count_bot = bot_table->count;
if ( family )
{
top_table = &target->family_top;
bot_table = &target->family_bottom;
read = source->zones_family;
read_count = (FT_Int)source->count_family;
}
else
{
top_table = &target->normal_top;
bot_table = &target->normal_bottom;
read = source->zones;
read_count = (FT_Int)source->count;
}
/* read the input blue zones, and build two sorted tables */
/* (one for the top zones, the other for the bottom zones */
count_top = 0;
count_bot = 0;
for ( ; read_count > 0; read_count-- )
for ( ; read_count > 0; read_count -= 2 )
{
FT_Int reference, delta;
FT_UInt count;
PSH_Blue_Zone zones, zone;
/* read blue zone entry, and select target top/bottom zone */
@ -204,8 +160,49 @@
top_table->count = count_top;
bot_table->count = count_bot;
}
/* re-read blue zones from the original fonts, and store them into out */
/* private structure. This function re-orders, sanitizes and fuzz-expands */
/* the zones as well.. */
static void
psh_blues_set_zones( PSH_Blues target,
FT_UInt count,
FT_Short* blues,
FT_UInt count_others,
FT_Short* other_blues,
FT_Int fuzz,
FT_Int family )
{
PSH_Blue_Table top_table, bot_table;
FT_Int count_top, count_bot;
if ( family )
{
top_table = &target->family_top;
bot_table = &target->family_bottom;
}
else
{
top_table = &target->normal_top;
bot_table = &target->normal_bottom;
}
/* read the input blue zones, and build two sorted tables */
/* (one for the top zones, the other for the bottom zones */
top_table->count = 0;
bot_table->count = 0;
/* first, the blues */
psh_blues_set_zones_0( target, count, blues, top_table, bot_table );
psh_blues_set_zones_0( target, count_others, other_blues, top_table, bot_table );
count_top = top_table->count;
count_bot = bot_table->count;
/* sanitize top table */
if ( count_top > 0 )
{
PSH_Blue_Zone zone = top_table->zones;
@ -223,6 +220,7 @@
}
/* sanitize bottom table */
if ( count_bot > 0 )
{
PSH_Blue_Zone zone = bot_table->zones;
@ -241,10 +239,9 @@
/* expand top and bottom tables with blue fuzz */
{
FT_Int dim, top, bot, delta, fuzz;
FT_Int dim, top, bot, delta;
PSH_Blue_Zone zone;
fuzz = source->fuzz;
zone = top_table->zones;
count = count_top;
@ -287,6 +284,7 @@
}
/* reset the blues table when the device transform changes */
static void
psh_blues_scale_zones( PSH_Blues blues,
@ -404,36 +402,78 @@
static FT_Error
psh_globals_new( FT_Memory memory, PSH_Globals *aglobals )
psh_globals_new( FT_Memory memory,
T1_Private* priv,
PSH_Globals *aglobals )
{
PSH_Globals globals;
FT_Error error;
if ( !ALLOC( globals, sizeof(*globals) ) )
{
FT_UInt count;
FT_Short* read;
globals->memory = memory;
/* copy standard widths */
{
PSH_Dimension dim = &globals->dimension[1];
PSH_Width write = dim->std.widths;
write->org = priv->standard_width[1];
write++;
read = priv->snap_widths;
for ( count = priv->num_snap_widths; count > 0; count-- )
{
write->org = *read;
write++;
read++;
}
dim->std.count = write - dim->std.widths;
}
/* copy standard heights */
{
PSH_Dimension dim = &globals->dimension[0];
PSH_Width write = dim->std.widths;
write->org = priv->standard_height[1];
write++;
read = priv->snap_heights;
for ( count = priv->num_snap_heights; count > 0; count-- )
{
write->org = *read;
write++;
read++;
}
dim->std.count = write - dim->std.widths;
}
/* copy blue zones */
psh_blues_set_zones( &globals->blues, priv->num_blue_values,
priv->blue_values, priv->num_other_blues,
priv->other_blues, priv->blue_fuzz, 0 );
psh_blues_set_zones( &globals->blues, priv->num_family_blues,
priv->family_blues, priv->num_family_other_blues,
priv->family_other_blues, priv->blue_fuzz, 1 );
globals->dimension[0].scale_mult = 0;
globals->dimension[0].scale_delta = 0;
globals->dimension[1].scale_mult = 0;
globals->dimension[1].scale_delta = 0;
}
*aglobals = globals;
return error;
}
static FT_Error
psh_globals_reset( PSH_Globals globals,
PS_Globals ps_globals )
{
psh_globals_reset_widths( globals, 0, &ps_globals->horizontal );
psh_globals_reset_widths( globals, 1, &ps_globals->vertical );
psh_blues_reset_zones( &globals->blues, &ps_globals->blues, 0 );
psh_blues_reset_zones( &globals->blues, &ps_globals->blues, 1 );
globals->dimension[0].scale_mult = 0;
globals->dimension[0].scale_delta = 0;
globals->dimension[1].scale_mult = 0;
globals->dimension[1].scale_delta = 0;
return 0;
}
static FT_Error
psh_globals_set_scale( PSH_Globals globals,
@ -473,7 +513,6 @@
psh_globals_funcs_init( PSH_Globals_FuncsRec* funcs )
{
funcs->create = psh_globals_new;
funcs->reset = psh_globals_reset;
funcs->set_scale = psh_globals_set_scale;
funcs->destroy = psh_globals_destroy;
}

View File

@ -31,6 +31,26 @@ FT_BEGIN_HEADER
/***** *****/
/**********************************************************************/
/**********************************************************************/
/****************************************************************
*
* @constant: PS_GLOBALS_MAX_BLUE_ZONES
*
* @description:
* the maximum number of blue zones in a font global hints
* structure. See @PS_Globals_BluesRec
*/
#define PS_GLOBALS_MAX_BLUE_ZONES 16
/****************************************************************
*
* @constant: PS_GLOBALS_MAX_STD_WIDTHS
*
* @description:
* the maximum number of standard and snap widths in either the
* horizontal or vertical direction. See @PS_Globals_WidthsRec
*/
#define PS_GLOBALS_MAX_STD_WIDTHS 16
/* standard and snap width */
typedef struct PSH_WidthRec_

View File

@ -1,5 +1,31 @@
#include "pshoptim.h"
#ifdef DEBUG_VIEW
void
ps_simple_scale( PSH_Hint_Table table,
FT_Fixed scale,
FT_Fixed delta,
FT_Bool vertical )
{
PSH_Hint hint;
FT_UInt count;
for ( count = 0; count < table->num_hints; count++ )
{
hint = table->sort[count];
if ( psh_hint_is_active(hint) )
{
hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta;
hint->cur_len = FT_MulFix( hint->org_len, scale );
if (ps_debug_hint_func)
ps_debug_hint_func( hint, vertical );
}
}
}
#endif
FT_LOCAL_DEF FT_Error
psh_hint_table_optimize( PSH_Hint_Table table,
PSH_Globals globals,
@ -10,6 +36,20 @@
FT_Fixed scale = dim->scale_mult;
FT_Fixed delta = dim->scale_delta;
#ifdef DEBUG_VIEW
if ( ps_debug_no_vert_hints && vertical )
{
ps_simple_scale( table, scale, delta, vertical );
return 0;
}
if ( ps_debug_no_horz_hints && !vertical )
{
ps_simple_scale( table, scale, delta, vertical );
return 0;
}
#endif
/* XXXX: for now, we only scale the hints to test all other aspects */
/* of the Postscript Hinter.. */
{
@ -21,10 +61,85 @@
hint = table->sort[count];
if ( psh_hint_is_active(hint) )
{
hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta;
hint->cur_len = FT_MulFix( hint->org_len, scale );
# if 1
FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta;
FT_Pos len = FT_MulFix( hint->org_len, scale );
FT_Pos fit_center;
FT_Pos fit_len;
PSH_Blue_AlignementRec align;
/* compute fitted width/height */
fit_len = psh_dimension_snap_width( dim, hint->org_len );
if ( fit_len < 64 )
fit_len = 64;
else
fit_len = (fit_len + 16 ) & -64;
hint->cur_len = fit_len;
/* check blue zones for horizontal stems */
align.align = 0;
if (!vertical)
{
psh_blues_snap_stem( &globals->blues,
hint->org_pos + hint->org_len,
hint->org_pos,
&align );
}
switch (align.align)
{
case PSH_BLUE_ALIGN_TOP:
{
/* the top of the stem is aligned against a blue zone */
hint->cur_pos = align.align_top - fit_len;
break;
}
case PSH_BLUE_ALIGN_BOT:
{
/* the bottom of the stem is aligned against a blue zone */
hint->cur_pos = align.align_bot;
break;
}
case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT:
{
/* both edges of the stem are aligned against blue zones */
hint->cur_pos = align.align_bot;
hint->cur_len = align.align_top - align.align_bot;
}
break;
default:
/* normal processing */
if ( (fit_len/64) & 1 )
{
/* odd number of pixels */
fit_center = ((pos + (len >> 1)) & -64) + 32;
}
else
{
/* even number of pixels */
fit_center = (pos + (len >> 1) + 32) & -64;
}
hint->cur_pos = fit_center - (fit_len >> 1);
}
# else
hint->cur_pos = (FT_MulFix( hint->org_pos, scale ) + delta + 32) & -64;
hint->cur_len = FT_MulFix( hint->org_len, scale );
# endif
#ifdef DEBUG_VIEW
if (ps_debug_hint_func)
ps_debug_hint_func( hint, vertical );
#endif
}
}
}
return 0;
}

View File

@ -1000,6 +1000,11 @@
error = ps_dimension_end( &dim[1], end_point, memory );
}
}
#ifdef DEBUG_VIEW
if (!error)
the_ps_hints = hints;
#endif
return error;
}
@ -1095,4 +1100,5 @@
funcs->apply = (T2_Hints_ApplyFunc) ps_hints_apply;
}

View File

@ -151,6 +151,12 @@ FT_BEGIN_HEADER
FT_LOCAL void
t2_hints_funcs_init( T2_Hints_FuncsRec* funcs );
#define xxxDEBUG_VIEW
#ifdef DEBUG_VIEW
extern PS_Hints the_ps_hints;
#endif
/* */
FT_END_HEADER

View File

@ -55,7 +55,7 @@
/*************************************************************************/
static PSH_Globals_Funcs
T1_Size_Get_Globals( T1_Size size )
T1_Size_Get_Globals_Funcs( T1_Size size )
{
T1_Face face = (T1_Face) size->root.face;
PSHinter_Interface* pshinter = face->pshinter;
@ -75,7 +75,7 @@
{
PSH_Globals_Funcs funcs;
funcs = T1_Size_Get_Globals(size);
funcs = T1_Size_Get_Globals_Funcs(size);
if (funcs)
funcs->destroy( (PSH_Globals) size->root.internal );
@ -89,13 +89,15 @@
FT_Error T1_Size_Init( T1_Size size )
{
FT_Error error = 0;
PSH_Globals_Funcs funcs = T1_Size_Get_Globals( size );
PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size );
if ( funcs )
{
PSH_Globals globals;
PSH_Globals globals;
T1_Face face = (T1_Face) size->root.face;
error = funcs->create( size->root.face->memory, &globals );
error = funcs->create( size->root.face->memory,
&face->type1.private_dict, &globals );
if (!error)
size->root.internal = (FT_Size_Internal)(void*) globals;
}
@ -108,7 +110,7 @@
FT_LOCAL_DEF
FT_Error T1_Size_Reset( T1_Size size )
{
PSH_Globals_Funcs funcs = T1_Size_Get_Globals(size);
PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs(size);
FT_Error error = 0;
if (funcs)

View File

@ -5,6 +5,10 @@
#include <ft2build.h>
#include FT_FREETYPE_H
/* include FreeType internals to debug hints */
#include <../src/pshinter/pshrec.h>
#include <../src/pshinter/pshfit.h>
#include <time.h> /* for clock() */
/* SunOS 4.1.* does not define CLOCKS_PER_SEC, so include <sys/param.h> */
@ -45,8 +49,20 @@ static int option_show_glyph = 1;
static int option_show_grid = 1;
static int option_show_em = 0;
static int option_show_ps_hints = 1;
static int option_show_horz_hints = 1;
static int option_show_vert_hints = 1;
static int option_hinting = 1;
static char temp_message[1024];
PS_Hints the_ps_hints = 0;
int ps_debug_no_horz_hints = 0;
int ps_debug_no_vert_hints = 0;
PSH_HintFunc ps_debug_hint_func = 0;
#define AXIS_COLOR 0xFFFF0000
#define GRID_COLOR 0xFFD0D0D0
#define ON_COLOR 0xFFFF2000
@ -55,6 +71,10 @@ static int option_hinting = 1;
#define TEXT_COLOR 0xFF000000
#define EM_COLOR 0x80008000
#define GHOST_HINT_COLOR 0xE00000FF
#define STEM_HINT_COLOR 0xE02020FF
#define STEM_JOIN_COLOR 0xE020FF20
/* print message and abort program */
static void
Panic( const char* message )
@ -168,11 +188,105 @@ draw_grid( void )
}
static int pshint_cpos = 0;
static int pshint_vertical = -1;
static void
draw_ps_hint( PSH_Hint hint, FT_Bool vertical )
{
int x1, x2;
NV_Vector v;
if ( pshint_vertical != vertical )
{
if (vertical)
pshint_cpos = 40;
else
pshint_cpos = 10;
pshint_vertical = vertical;
}
if (vertical)
{
if ( !option_show_vert_hints )
return;
v.x = hint->cur_pos;
v.y = 0;
nv_vector_transform( &v, &size_transform );
x1 = (int)(v.x + 0.5);
v.x = hint->cur_pos + hint->cur_len;
v.y = 0;
nv_vector_transform( &v, &size_transform );
x2 = (int)(v.x + 0.5);
nv_pixmap_fill_rect( target, x1, 0, 1, target->height,
psh_hint_is_ghost(hint)
? GHOST_HINT_COLOR : STEM_HINT_COLOR );
if ( psh_hint_is_ghost(hint) )
{
x1 --;
x2 = x1 + 2;
}
else
nv_pixmap_fill_rect( target, x2, 0, 1, target->height,
psh_hint_is_ghost(hint)
? GHOST_HINT_COLOR : STEM_HINT_COLOR );
nv_pixmap_fill_rect( target, x1, pshint_cpos, x2+1-x1, 1,
STEM_JOIN_COLOR );
}
else
{
if (!option_show_horz_hints)
return;
v.y = hint->cur_pos;
v.x = 0;
nv_vector_transform( &v, &size_transform );
x1 = (int)(v.y + 0.5);
v.y = hint->cur_pos + hint->cur_len;
v.x = 0;
nv_vector_transform( &v, &size_transform );
x2 = (int)(v.y + 0.5);
nv_pixmap_fill_rect( target, 0, x1, target->width, 1,
psh_hint_is_ghost(hint)
? GHOST_HINT_COLOR : STEM_HINT_COLOR );
if ( psh_hint_is_ghost(hint) )
{
x1 --;
x2 = x1 + 2;
}
else
nv_pixmap_fill_rect( target, 0, x2, target->width, 1,
psh_hint_is_ghost(hint)
? GHOST_HINT_COLOR : STEM_HINT_COLOR );
nv_pixmap_fill_rect( target, pshint_cpos, x2, 1, x1+1-x2,
STEM_JOIN_COLOR );
}
printf( "[%7.3f %7.3f] %c\n", hint->cur_pos/64.0, (hint->cur_pos+hint->cur_len)/64.0, vertical ? 'v' : 'h' );
pshint_cpos += 10;
}
static void
draw_glyph( int glyph_index )
{
NV_Path path;
NV_Scale scale;
pshint_vertical = -1;
ps_debug_hint_func = option_show_ps_hints ? draw_ps_hint : 0;
error = FT_Load_Glyph( face, glyph_index, option_hinting
? FT_LOAD_NO_BITMAP
@ -266,10 +380,115 @@ draw_glyph( int glyph_index )
sprintf( temp, "glyph %4d: %s", glyph_index, temp2 );
nv_pixmap_cell_text( target, 0, 8, temp, TEXT_COLOR );
if ( temp_message[0] )
{
nv_pixmap_cell_text( target, 0, 16, temp_message, TEXT_COLOR );
temp_message[0] = 0;
}
}
}
#if 0
static void
draw_ps_hints( void )
{
if ( option_show_ps_hints && the_ps_hints )
{
PS_Dimension dim;
PS_Hint hint;
NV_UInt count;
NV_Int cpos;
NV_Vector v;
/* draw vertical stems */
if ( option_show_vert_hints )
{
dim = &the_ps_hints->dimension[1];
hint = dim->hints.hints;
cpos = 40;
for ( count = dim->hints.num_hints; count > 0; count--, hint++ )
{
NV_Int x1, x2;
v.x = hint->pos;
v.y = 0;
nv_vector_transform( &v, &glyph_transform );
x1 = (int)(v.x+0.5);
x1 = glyph_org_x + hint->pos*glyph_scale;
nv_pixmap_fill_rect( target, x1, 0, 1, target->height,
ps_hint_is_ghost(hint)
? GHOST_HINT_COLOR : STEM_HINT_COLOR );
if ( !ps_hint_is_ghost(hint) )
{
v.x = hint->pos + hint->len;
v.y = 0;
nv_vector_transform( &v, &glyph_transform );
x2 = (int)(v.x+0.5);
x2 = glyph_org_x + (hint->pos + hint->len)*glyph_scale;
nv_pixmap_fill_rect( target, x2, 0, 1, target->height,
STEM_HINT_COLOR );
}
else
{
x1 -= 1;
x2 = x1 + 2;
}
nv_pixmap_fill_rect( target, x1, cpos, x2-x1+1, 1,
STEM_JOIN_COLOR );
cpos += 10;
}
}
/* draw horizontal stems */
if ( option_show_horz_hints )
{
dim = &the_ps_hints->dimension[0];
hint = dim->hints.hints;
cpos = 10;
for ( count = dim->hints.num_hints; count > 0; count--, hint++ )
{
NV_Int y1, y2;
v.x = 0;
v.y = hint->pos;
nv_vector_transform( &v, &glyph_transform );
y1 = (int)(v.y+0.5);
y1 = glyph_org_y - hint->pos*glyph_scale;
nv_pixmap_fill_rect( target, 0, y1, target->width, 1,
ps_hint_is_ghost(hint)
? GHOST_HINT_COLOR : STEM_HINT_COLOR );
if ( !ps_hint_is_ghost(hint) )
{
v.x = 0;
v.y = hint->pos + hint->len;
nv_vector_transform( &v, &glyph_transform );
y2 = (int)(v.y+0.5);
y2 = glyph_org_y - (hint->pos + hint->len)*glyph_scale;
nv_pixmap_fill_rect( target, 0, y2, target->width, 1,
STEM_HINT_COLOR );
}
else
{
y1 -= 1;
y2 = y1 + 2;
}
nv_pixmap_fill_rect( target, cpos, y2, 1, y1-y2+1,
STEM_JOIN_COLOR );
cpos += 10;
}
}
}
}
#endif
static void
handle_event( NVV_EventRec* ev )
{
@ -289,7 +508,7 @@ handle_event( NVV_EventRec* ev )
break;
}
case NVV_KEY('a'):
case NVV_KEY('x'):
{
option_show_axis = !option_show_axis;
break;
@ -340,6 +559,7 @@ handle_event( NVV_EventRec* ev )
{
pixel_size++;
reset_size( pixel_size, grid_scale );
sprintf( temp_message, "pixel size = %d", pixel_size );
break;
}
@ -349,14 +569,49 @@ handle_event( NVV_EventRec* ev )
{
pixel_size--;
reset_size( pixel_size, grid_scale );
sprintf( temp_message, "pixel size = %d", pixel_size );
}
break;
}
case NVV_KEY('z'):
{
ps_debug_no_vert_hints = !ps_debug_no_vert_hints;
sprintf( temp_message, "vertical hints processing is now %s",
ps_debug_no_vert_hints ? "off" : "on" );
break;
}
case NVV_KEY('a'):
{
ps_debug_no_horz_hints = !ps_debug_no_horz_hints;
sprintf( temp_message, "horizontal hints processing is now %s",
ps_debug_no_horz_hints ? "off" : "on" );
break;
}
case NVV_KEY('Z'):
{
option_show_vert_hints = !option_show_vert_hints;
sprintf( temp_message, "vertical hints display is now %s",
option_show_vert_hints ? "off" : "on" );
break;
}
case NVV_KEY('A'):
{
option_show_horz_hints = !option_show_horz_hints;
sprintf( temp_message, "horizontal hints display is now %s",
option_show_horz_hints ? "off" : "on" );
break;
}
case NVV_KEY('h'):
{
option_hinting = !option_hinting;
sprintf( temp_message, "hinting is now %s",
option_hinting ? "off" : "on" );
break;
}
}
@ -389,7 +644,7 @@ int main( int argc, char** argv )
error = FT_Init_FreeType( &freetype );
if (error) Panic( "could not initialise FreeType" );
error = FT_New_Face( freetype, "c:/winnt/fonts/times.ttf", 0, &face );
error = FT_New_Face( freetype, "h:/fonts/cour.pfa", 0, &face );
if (error) Panic( "could not open font face" );
reset_size( pixel_size, grid_scale );
@ -405,7 +660,11 @@ int main( int argc, char** argv )
{
clear_background();
draw_grid();
the_ps_hints = 0;
draw_glyph( glyph_index );
/* draw_ps_hints(); */
nvv_surface_refresh( surface, NULL );
nvv_surface_listen( surface, 0, &event );