forked from minhngoc25a/freetype2
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:
parent
9f781c410b
commit
fbb7617183
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
265
tests/gview.c
265
tests/gview.c
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue