#include <freetype/internal/ftobjs.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftcalc.h>
#include "pshalgo.h"
#include "pshnterr.h"
#undef FT_COMPONENT
#define FT_COMPONENT …
#ifdef DEBUG_HINTER
PSH_Hint_Table ps_debug_hint_table = NULL;
PSH_HintFunc ps_debug_hint_func = NULL;
PSH_Glyph ps_debug_glyph = NULL;
#endif
#define COMPUTE_INFLEXS …
static FT_Int
psh_hint_overlap( PSH_Hint hint1,
PSH_Hint hint2 )
{ … }
static void
psh_hint_table_done( PSH_Hint_Table table,
FT_Memory memory )
{ … }
static void
psh_hint_table_deactivate( PSH_Hint_Table table )
{ … }
static void
psh_hint_table_record( PSH_Hint_Table table,
FT_UInt idx )
{ … }
static void
psh_hint_table_record_mask( PSH_Hint_Table table,
PS_Mask hint_mask )
{ … }
static FT_Error
psh_hint_table_init( PSH_Hint_Table table,
PS_Hint_Table hints,
PS_Mask_Table hint_masks,
PS_Mask_Table counter_masks,
FT_Memory memory )
{ … }
static void
psh_hint_table_activate_mask( PSH_Hint_Table table,
PS_Mask hint_mask )
{ … }
#if 1
static FT_Pos
psh_dimension_quantize_len( PSH_Dimension dim,
FT_Pos len,
FT_Bool do_snapping )
{ … }
#endif
#ifdef DEBUG_HINTER
static void
ps_simple_scale( PSH_Hint_Table table,
FT_Fixed scale,
FT_Fixed delta,
FT_Int dimension )
{
FT_UInt count;
for ( count = 0; count < table->max_hints; count++ )
{
PSH_Hint hint = table->hints + count;
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, dimension );
}
}
#endif
static FT_Fixed
psh_hint_snap_stem_side_delta( FT_Fixed pos,
FT_Fixed len )
{ … }
static void
psh_hint_align( PSH_Hint hint,
PSH_Globals globals,
FT_Int dimension,
PSH_Glyph glyph )
{ … }
#if 0
static void
psh_hint_align_light( PSH_Hint hint,
PSH_Globals globals,
FT_Int dimension,
PSH_Glyph glyph )
{
PSH_Dimension dim = &globals->dimension[dimension];
FT_Fixed scale = dim->scale_mult;
FT_Fixed delta = dim->scale_delta;
if ( !psh_hint_is_fitted( hint ) )
{
FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta;
FT_Pos len = FT_MulFix( hint->org_len, scale );
FT_Pos fit_len;
PSH_AlignmentRec align;
if ( ( dimension == 0 && !glyph->do_horz_hints ) ||
( dimension == 1 && !glyph->do_vert_hints ) )
{
hint->cur_pos = pos;
hint->cur_len = len;
psh_hint_set_fitted( hint );
return;
}
fit_len = len;
hint->cur_len = fit_len;
align.align = PSH_BLUE_ALIGN_NONE;
align.align_bot = align.align_top = 0;
if ( dimension == 1 )
psh_blues_snap_stem( &globals->blues,
ADD_INT( hint->org_pos, hint->org_len ),
hint->org_pos,
&align );
switch ( align.align )
{
case PSH_BLUE_ALIGN_TOP:
hint->cur_pos = align.align_top - fit_len;
break;
case PSH_BLUE_ALIGN_BOT:
hint->cur_pos = align.align_bot;
break;
case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT:
hint->cur_pos = align.align_bot;
hint->cur_len = align.align_top - align.align_bot;
break;
default:
{
PSH_Hint parent = hint->parent;
if ( parent )
{
FT_Pos par_org_center, par_cur_center;
FT_Pos cur_org_center, cur_delta;
if ( !psh_hint_is_fitted( parent ) )
psh_hint_align_light( parent, globals, dimension, glyph );
par_org_center = parent->org_pos + ( parent->org_len / 2 );
par_cur_center = parent->cur_pos + ( parent->cur_len / 2 );
cur_org_center = hint->org_pos + ( hint->org_len / 2 );
cur_delta = FT_MulFix( cur_org_center - par_org_center, scale );
pos = par_cur_center + cur_delta - ( len >> 1 );
}
if ( len <= 64 )
{
if ( ( pos + len + 63 ) / 64 != pos / 64 + 1 )
pos += psh_hint_snap_stem_side_delta ( pos, len );
}
else
{
FT_Fixed frac_len = len & 63;
FT_Fixed center = pos + ( len >> 1 );
FT_Fixed delta_a, delta_b;
if ( ( len / 64 ) & 1 )
{
delta_a = FT_PIX_FLOOR( center ) + 32 - center;
delta_b = FT_PIX_ROUND( center ) - center;
}
else
{
delta_a = FT_PIX_ROUND( center ) - center;
delta_b = FT_PIX_FLOOR( center ) + 32 - center;
}
if ( frac_len < 32 )
{
pos += psh_hint_snap_stem_side_delta ( pos, len );
}
else if ( frac_len < 48 )
{
FT_Fixed side_delta = psh_hint_snap_stem_side_delta ( pos,
len );
if ( FT_ABS( side_delta ) < FT_ABS( delta_b ) )
pos += side_delta;
else
pos += delta_b;
}
else
{
pos += delta_b;
}
}
hint->cur_pos = pos;
}
}
psh_hint_set_fitted( hint );
#ifdef DEBUG_HINTER
if ( ps_debug_hint_func )
ps_debug_hint_func( hint, dimension );
#endif
}
}
#endif
static void
psh_hint_table_align_hints( PSH_Hint_Table table,
PSH_Globals globals,
FT_Int dimension,
PSH_Glyph glyph )
{ … }
#define xxDEBUG_ZONES
#ifdef DEBUG_ZONES
#include FT_CONFIG_STANDARD_LIBRARY_H
static void
psh_print_zone( PSH_Zone zone )
{
printf( "zone [scale,delta,min,max] = [%.5f,%.2f,%d,%d]\n",
zone->scale / 65536.0,
zone->delta / 64.0,
zone->min,
zone->max );
}
#endif
#define psh_corner_is_flat …
#define psh_corner_orientation …
#ifdef COMPUTE_INFLEXS
static void
psh_glyph_compute_inflections( PSH_Glyph glyph )
{ … }
#endif
static void
psh_glyph_done( PSH_Glyph glyph )
{ … }
static PSH_Dir
psh_compute_dir( FT_Pos dx,
FT_Pos dy )
{ … }
static void
psh_glyph_load_points( PSH_Glyph glyph,
FT_Int dimension )
{ … }
static void
psh_glyph_save_points( PSH_Glyph glyph,
FT_Int dimension )
{ … }
static FT_Error
psh_glyph_init( PSH_Glyph glyph,
FT_Outline* outline,
PS_Hints ps_hints,
PSH_Globals globals )
{ … }
static void
psh_glyph_compute_extrema( PSH_Glyph glyph )
{ … }
static void
psh_hint_table_find_strong_points( PSH_Hint_Table table,
PSH_Point point,
FT_UInt count,
FT_Int threshold,
PSH_Dir major_dir )
{ … }
#define PSH_STRONG_THRESHOLD …
#define PSH_STRONG_THRESHOLD_MAXIMUM …
static void
psh_glyph_find_strong_points( PSH_Glyph glyph,
FT_Int dimension )
{ … }
static void
psh_glyph_find_blue_points( PSH_Blues blues,
PSH_Glyph glyph )
{ … }
static void
psh_glyph_interpolate_strong_points( PSH_Glyph glyph,
FT_Int dimension )
{ … }
#define PSH_MAX_STRONG_INTERNAL …
static void
psh_glyph_interpolate_normal_points( PSH_Glyph glyph,
FT_Int dimension )
{ … }
static void
psh_glyph_interpolate_other_points( PSH_Glyph glyph,
FT_Int dimension )
{ … }
FT_Error
ps_hints_apply( PS_Hints ps_hints,
FT_Outline* outline,
PSH_Globals globals,
FT_Render_Mode hint_mode )
{ … }