- removal of compiler warnings
- slight improvements to the Postscript hinter
This commit is contained in:
parent
0e36c31d73
commit
fab5018b69
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
2002-08-20 David Turner <david@freetype.org>
|
||||
|
||||
* src/pshinter/pshalgo1.c, src/pshinter/pshalog2.c,
|
||||
src/pshinter/pshglob.c, src/pshinter/pshrec.c,
|
||||
src/autohint/ahmodule.c: removing compiler warnings with
|
||||
DEBUG_HINTER defined (only used in development builds anyway)
|
||||
|
||||
* src/pshinter/pshalgo3.h, src/pshinter/pshalgo3.c: removing
|
||||
compiler warnings, and improving the support of local extrema
|
||||
and stem edge points
|
||||
|
||||
* test/gview.c: small updates to the hinting debugger
|
||||
* Jamfile: small updates
|
||||
|
||||
2002-08-18 Arkadiusz Miskiewicz <misiek@pld.ORG.PL>
|
||||
|
||||
* builds/unix/install.mk (install, uninstall): Add $(DESTDIR) to
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
|
||||
#ifdef DEBUG_HINTER
|
||||
extern AH_Hinter* ah_debug_hinter = NULL;
|
||||
extern FT_Bool ah_debug_disable_horz = 0;
|
||||
extern FT_Bool ah_debug_disable_vert = 0;
|
||||
AH_Hinter* ah_debug_hinter = NULL;
|
||||
FT_Bool ah_debug_disable_horz = 0;
|
||||
FT_Bool ah_debug_disable_vert = 0;
|
||||
#endif
|
||||
|
||||
typedef struct FT_AutoHinterRec_
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
#define FT_COMPONENT trace_pshalgo1
|
||||
|
||||
#ifdef DEBUG_HINTER
|
||||
extern PSH1_Hint_Table ps1_debug_hint_table = 0;
|
||||
extern PSH1_HintFunc ps1_debug_hint_func = 0;
|
||||
PSH1_Hint_Table ps1_debug_hint_table = 0;
|
||||
PSH1_HintFunc ps1_debug_hint_func = 0;
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
#define FT_COMPONENT trace_pshalgo2
|
||||
|
||||
#ifdef DEBUG_HINTER
|
||||
extern PSH2_Hint_Table ps2_debug_hint_table = 0;
|
||||
extern PSH2_HintFunc ps2_debug_hint_func = 0;
|
||||
extern PSH2_Glyph ps2_debug_glyph = 0;
|
||||
PSH2_Hint_Table ps2_debug_hint_table = 0;
|
||||
PSH2_HintFunc ps2_debug_hint_func = 0;
|
||||
PSH2_Glyph ps2_debug_glyph = 0;
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -27,15 +27,16 @@
|
|||
|
||||
|
||||
#ifdef DEBUG_HINTER
|
||||
extern PSH3_Hint_Table ps3_debug_hint_table = 0;
|
||||
extern PSH3_HintFunc ps3_debug_hint_func = 0;
|
||||
extern PSH3_Glyph ps3_debug_glyph = 0;
|
||||
PSH3_Hint_Table ps3_debug_hint_table = 0;
|
||||
PSH3_HintFunc ps3_debug_hint_func = 0;
|
||||
PSH3_Glyph ps3_debug_glyph = 0;
|
||||
#endif
|
||||
|
||||
|
||||
#undef SNAP_STEMS
|
||||
#undef ONLY_ALIGN_Y
|
||||
|
||||
#define COMPUTE_INFLEXS
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
@ -51,7 +52,7 @@
|
|||
PSH3_Hint hint2 )
|
||||
{
|
||||
return ( hint1->org_pos + hint1->org_len >= hint2->org_pos &&
|
||||
hint2->org_pos + hint2->org_len >= hint1->org_pos );
|
||||
hint2->org_pos + hint2->org_len >= hint1->org_pos );
|
||||
}
|
||||
|
||||
|
||||
|
@ -427,7 +428,7 @@
|
|||
hint->cur_len = fit_len;
|
||||
|
||||
/* check blue zones for horizontal stems */
|
||||
align.align = PSH_BLUE_ALIGN_NONE;
|
||||
align.align = PSH_BLUE_ALIGN_NONE;
|
||||
align.align_bot = align.align_top = 0;
|
||||
|
||||
if ( dimension == 1 )
|
||||
|
@ -469,9 +470,9 @@
|
|||
if ( !psh3_hint_is_fitted( parent ) )
|
||||
psh3_hint_align( parent, globals, dimension, hint_flags );
|
||||
|
||||
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 );
|
||||
par_org_center = parent->org_pos + ( parent->org_len >> 1 );
|
||||
par_cur_center = parent->cur_pos + ( parent->cur_len >> 1 );
|
||||
cur_org_center = hint->org_pos + ( hint->org_len >> 1 );
|
||||
|
||||
cur_delta = FT_MulFix( cur_org_center - par_org_center, scale );
|
||||
pos = par_cur_center + cur_delta - ( len >> 1 );
|
||||
|
@ -480,7 +481,7 @@
|
|||
if ( ( hint_flags & FT_HINT_NO_INTEGER_STEM ) == 0 )
|
||||
{
|
||||
/* normal processing */
|
||||
if ( ( fit_len / 64 ) & 1 )
|
||||
if ( fit_len & 64 )
|
||||
{
|
||||
/* odd number of pixels */
|
||||
fit_center = ( ( pos + ( len >> 1 ) ) & -64 ) + 32;
|
||||
|
@ -663,39 +664,107 @@
|
|||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
static int
|
||||
psh3_point_is_extremum( PSH3_Point point )
|
||||
#ifdef COMPUTE_INFLEXS
|
||||
/* compute all inflex points in a given glyph */
|
||||
static void
|
||||
psh3_glyph_compute_inflections( PSH3_Glyph glyph )
|
||||
{
|
||||
PSH3_Point before = point;
|
||||
PSH3_Point after = point;
|
||||
FT_Pos d_before;
|
||||
FT_Pos d_after;
|
||||
FT_UInt n;
|
||||
|
||||
|
||||
do
|
||||
for ( n = 0; n < glyph->num_contours; n++ )
|
||||
{
|
||||
before = before->prev;
|
||||
if ( before == point )
|
||||
return 0;
|
||||
PSH3_Point first, start, end, before, after;
|
||||
FT_Angle angle_in, angle_seg, angle_out;
|
||||
FT_Angle diff_in, diff_out;
|
||||
FT_Int finished = 0;
|
||||
|
||||
d_before = before->org_u - point->org_u;
|
||||
/* we need at least 4 points to create an inflection point */
|
||||
if ( glyph->contours[n].count < 4 )
|
||||
continue;
|
||||
|
||||
} while ( d_before == 0 );
|
||||
/* compute first segment in contour */
|
||||
first = glyph->contours[n].start;
|
||||
|
||||
do
|
||||
{
|
||||
after = after->next;
|
||||
if ( after == point )
|
||||
return 0;
|
||||
start = end = first;
|
||||
do
|
||||
{
|
||||
end = end->next;
|
||||
if ( end == first )
|
||||
goto Skip;
|
||||
}
|
||||
while ( PSH3_POINT_EQUAL_ORG( end, first ) );
|
||||
|
||||
d_after = after->org_u - point->org_u;
|
||||
angle_seg = PSH3_POINT_ANGLE( start, end );
|
||||
|
||||
} while ( d_after == 0 );
|
||||
/* extend the segment start whenever possible */
|
||||
before = start;
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
start = before;
|
||||
before = before->prev;
|
||||
if ( before == first )
|
||||
goto Skip;
|
||||
}
|
||||
while ( PSH3_POINT_EQUAL_ORG( before, start ) );
|
||||
|
||||
return ( ( d_before > 0 && d_after > 0 ) ||
|
||||
( d_before < 0 && d_after < 0 ) );
|
||||
angle_in = PSH3_POINT_ANGLE( before, start );
|
||||
}
|
||||
while ( angle_in == angle_seg );
|
||||
|
||||
first = start;
|
||||
diff_in = FT_Angle_Diff( angle_in, angle_seg );
|
||||
|
||||
/* now, process all segments in the contour */
|
||||
do
|
||||
{
|
||||
/* first, extend current segment's end whenever possible */
|
||||
after = end;
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
end = after;
|
||||
after = after->next;
|
||||
if ( after == first )
|
||||
finished = 1;
|
||||
}
|
||||
while ( PSH3_POINT_EQUAL_ORG( end, after ) );
|
||||
|
||||
angle_out = PSH3_POINT_ANGLE( end, after );
|
||||
}
|
||||
while ( angle_out == angle_seg );
|
||||
|
||||
diff_out = FT_Angle_Diff( angle_seg, angle_out );
|
||||
|
||||
if ( diff_in ^ diff_out < 0 )
|
||||
{
|
||||
/* diff_in and diff_out have different signs, we have */
|
||||
/* inflection points here... */
|
||||
|
||||
do
|
||||
{
|
||||
psh3_point_set_inflex( start );
|
||||
start = start->next;
|
||||
}
|
||||
while ( start != end );
|
||||
|
||||
psh3_point_set_inflex( start );
|
||||
}
|
||||
|
||||
start = end;
|
||||
end = after;
|
||||
angle_seg = angle_out;
|
||||
diff_in = diff_out;
|
||||
}
|
||||
while ( !finished );
|
||||
|
||||
Skip:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* COMPUTE_INFLEXS */
|
||||
|
||||
static void
|
||||
psh3_glyph_done( PSH3_Glyph glyph )
|
||||
|
@ -742,6 +811,81 @@
|
|||
}
|
||||
|
||||
|
||||
/* load outline point coordinates into hinter glyph */
|
||||
static void
|
||||
psh3_glyph_load_points( PSH3_Glyph glyph,
|
||||
FT_Int dimension )
|
||||
{
|
||||
FT_Vector* vec = glyph->outline->points;
|
||||
PSH3_Point point = glyph->points;
|
||||
FT_UInt count = glyph->num_points;
|
||||
|
||||
|
||||
for ( ; count > 0; count--, point++, vec++ )
|
||||
{
|
||||
point->flags2 = 0;
|
||||
point->hint = NULL;
|
||||
if ( dimension == 0 )
|
||||
{
|
||||
point->org_u = vec->x;
|
||||
point->org_v = vec->y;
|
||||
}
|
||||
else
|
||||
{
|
||||
point->org_u = vec->y;
|
||||
point->org_v = vec->x;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_HINTER
|
||||
point->org_x = vec->x;
|
||||
point->org_y = vec->y;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* save hinted point coordinates back to outline */
|
||||
static void
|
||||
psh3_glyph_save_points( PSH3_Glyph glyph,
|
||||
FT_Int dimension )
|
||||
{
|
||||
FT_UInt n;
|
||||
PSH3_Point point = glyph->points;
|
||||
FT_Vector* vec = glyph->outline->points;
|
||||
char* tags = glyph->outline->tags;
|
||||
|
||||
|
||||
for ( n = 0; n < glyph->num_points; n++ )
|
||||
{
|
||||
if ( dimension == 0 )
|
||||
vec[n].x = point->cur_u;
|
||||
else
|
||||
vec[n].y = point->cur_u;
|
||||
|
||||
if ( psh3_point_is_strong( point ) )
|
||||
tags[n] |= (char)( ( dimension == 0 ) ? 32 : 64 );
|
||||
|
||||
#ifdef DEBUG_HINTER
|
||||
|
||||
if ( dimension == 0 )
|
||||
{
|
||||
point->cur_x = point->cur_u;
|
||||
point->flags_x = point->flags2 | point->flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
point->cur_y = point->cur_u;
|
||||
point->flags_y = point->flags2 | point->flags;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
point++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
psh3_glyph_init( PSH3_Glyph glyph,
|
||||
FT_Outline* outline,
|
||||
|
@ -866,6 +1010,11 @@
|
|||
glyph->outline = outline;
|
||||
glyph->globals = globals;
|
||||
|
||||
#ifdef COMPUTE_INFLEXS
|
||||
psh3_glyph_load_points( glyph, 0 );
|
||||
psh3_glyph_compute_inflections( glyph );
|
||||
#endif /* COMPUTE_INFLEXS */
|
||||
|
||||
/* now deal with hints tables */
|
||||
error = psh3_hint_table_init( &glyph->hint_tables [0],
|
||||
&ps_hints->dimension[0].hints,
|
||||
|
@ -888,78 +1037,133 @@
|
|||
}
|
||||
|
||||
|
||||
/* load outline point coordinates into hinter glyph */
|
||||
|
||||
|
||||
/* compute all extrema in a glyph for a given dimension */
|
||||
static void
|
||||
psh3_glyph_load_points( PSH3_Glyph glyph,
|
||||
FT_Int dimension )
|
||||
psh3_glyph_compute_extrema( PSH3_Glyph glyph )
|
||||
{
|
||||
FT_Vector* vec = glyph->outline->points;
|
||||
PSH3_Point point = glyph->points;
|
||||
FT_UInt count = glyph->num_points;
|
||||
FT_UInt first = 0, next, n;
|
||||
PSH3_Point points = glyph->points;
|
||||
PSH3_Contour contour = glyph->contours;
|
||||
|
||||
|
||||
for ( ; count > 0; count--, point++, vec++ )
|
||||
/* first of all, compute all local extrema */
|
||||
for ( n = 0; n < glyph->num_contours; n++ )
|
||||
{
|
||||
point->flags &= PSH3_POINT_OFF | PSH3_POINT_SMOOTH;
|
||||
point->hint = 0;
|
||||
if ( dimension == 0 )
|
||||
point->org_u = vec->x;
|
||||
else
|
||||
point->org_u = vec->y;
|
||||
PSH3_Point first = glyph->contours[n].start;
|
||||
PSH3_Point point, before, after;
|
||||
|
||||
#ifdef DEBUG_HINTER
|
||||
point->org_x = vec->x;
|
||||
point->org_y = vec->y;
|
||||
#endif
|
||||
point = first;
|
||||
before = point;
|
||||
after = point;
|
||||
|
||||
do
|
||||
{
|
||||
before = before->prev;
|
||||
if ( before == first )
|
||||
goto Skip;
|
||||
|
||||
} while ( before->org_u == point->org_u );
|
||||
|
||||
first = point = before->next;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
after = point;
|
||||
do
|
||||
{
|
||||
after = after->next;
|
||||
if ( after == first )
|
||||
goto Next;
|
||||
}
|
||||
while ( after->org_u == point->org_u );
|
||||
|
||||
if ( before->org_u < point->org_u )
|
||||
{
|
||||
if ( after->org_u < point->org_u )
|
||||
{
|
||||
/* local maximum */
|
||||
goto Extremum;
|
||||
}
|
||||
}
|
||||
else /* before->org_u > point->org_u */
|
||||
{
|
||||
if ( after->org_u > point->org_u )
|
||||
{
|
||||
/* local minimum */
|
||||
Extremum:
|
||||
do
|
||||
{
|
||||
psh3_point_set_extremum( point );
|
||||
point = point->next;
|
||||
}
|
||||
while ( point != after );
|
||||
}
|
||||
}
|
||||
|
||||
before = after->prev;
|
||||
point = after;
|
||||
|
||||
} /* for */
|
||||
|
||||
Next:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* save hinted point coordinates back to outline */
|
||||
static void
|
||||
psh3_glyph_save_points( PSH3_Glyph glyph,
|
||||
FT_Int dimension )
|
||||
{
|
||||
FT_UInt n;
|
||||
PSH3_Point point = glyph->points;
|
||||
FT_Vector* vec = glyph->outline->points;
|
||||
char* tags = glyph->outline->tags;
|
||||
|
||||
|
||||
/* for each extrema, determine its direction along the */
|
||||
/* orthogonal axis */
|
||||
for ( n = 0; n < glyph->num_points; n++ )
|
||||
{
|
||||
if ( dimension == 0 )
|
||||
vec[n].x = point->cur_u;
|
||||
else
|
||||
vec[n].y = point->cur_u;
|
||||
PSH3_Point point, before, after;
|
||||
|
||||
if ( psh3_point_is_strong( point ) )
|
||||
tags[n] |= (char)( ( dimension == 0 ) ? 32 : 64 );
|
||||
|
||||
#ifdef DEBUG_HINTER
|
||||
|
||||
if ( dimension == 0 )
|
||||
point = &glyph->points[n];
|
||||
if ( psh3_point_is_extremum( point ) )
|
||||
{
|
||||
point->cur_x = point->cur_u;
|
||||
point->flags_x = point->flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
point->cur_y = point->cur_u;
|
||||
point->flags_y = point->flags;
|
||||
PSH3_Point before = point;
|
||||
PSH3_Point after = point;
|
||||
|
||||
do
|
||||
{
|
||||
before = before->prev;
|
||||
if ( before == point )
|
||||
goto Skip;
|
||||
}
|
||||
while ( before->org_v == point->org_v );
|
||||
|
||||
do
|
||||
{
|
||||
after = after->next;
|
||||
if ( after == point )
|
||||
goto Skip;
|
||||
}
|
||||
while ( after->org_v == point->org_v );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
point++;
|
||||
if ( before->org_v < point->org_v &&
|
||||
after->org_v > point->org_v )
|
||||
{
|
||||
psh3_point_set_positive( point );
|
||||
}
|
||||
else if ( before->org_v > point->org_v &&
|
||||
after->org_v < point->org_v )
|
||||
{
|
||||
psh3_point_set_negative( point );
|
||||
}
|
||||
Skip:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define PSH3_STRONG_THRESHOLD 10
|
||||
|
||||
|
||||
#define PSH3_STRONG_THRESHOLD 30
|
||||
|
||||
|
||||
/* major_dir is the direction for points on the bottom/left of the stem;
|
||||
* Points on the top/right of the stem will have a direction of
|
||||
* -major_dir.
|
||||
*/
|
||||
static void
|
||||
psh3_hint_table_find_strong_point( PSH3_Hint_Table table,
|
||||
PSH3_Point point,
|
||||
|
@ -967,47 +1171,97 @@
|
|||
{
|
||||
PSH3_Hint* sort = table->sort;
|
||||
FT_UInt num_hints = table->num_hints;
|
||||
FT_Int point_dir = 0;
|
||||
FT_UInt flag;
|
||||
|
||||
if ( PSH3_DIR_COMPARE( point->dir_in, major_dir ) )
|
||||
point_dir = point->dir_in;
|
||||
|
||||
for ( ; num_hints > 0; num_hints--, sort++ )
|
||||
else if ( PSH3_DIR_COMPARE( point->dir_out, major_dir ) )
|
||||
point_dir = point->dir_out;
|
||||
|
||||
if ( point_dir )
|
||||
{
|
||||
PSH3_Hint hint = sort[0];
|
||||
FT_UInt flag;
|
||||
|
||||
|
||||
if ( ABS( point->dir_in ) == major_dir ||
|
||||
ABS( point->dir_out ) == major_dir )
|
||||
for ( ; num_hints > 0; num_hints--, sort++ )
|
||||
{
|
||||
FT_Pos d;
|
||||
PSH3_Hint hint = sort[0];
|
||||
FT_Pos d;
|
||||
|
||||
|
||||
d = point->org_u - hint->org_pos;
|
||||
if ( ABS( d ) < PSH3_STRONG_THRESHOLD )
|
||||
if ( point_dir == major_dir )
|
||||
{
|
||||
Is_Strong:
|
||||
psh3_point_set_strong( point );
|
||||
point->hint = hint;
|
||||
break;
|
||||
flag = PSH3_POINT_EDGE_MIN;
|
||||
d = point->org_u - hint->org_pos;
|
||||
if ( ABS( d ) < PSH3_STRONG_THRESHOLD )
|
||||
{
|
||||
Is_Strong:
|
||||
psh3_point_set_strong( point );
|
||||
point->flags2 |= flag;
|
||||
point->hint = hint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( point_dir == -major_dir )
|
||||
{
|
||||
flag = PSH3_POINT_EDGE_MAX;
|
||||
d = point->org_u - hint->org_pos - hint->org_len;
|
||||
if ( ABS( d ) < PSH3_STRONG_THRESHOLD )
|
||||
goto Is_Strong;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
else if ( psh3_point_is_extremum( point ) )
|
||||
{
|
||||
/* treat extrema as special cases for stem edge alignment */
|
||||
FT_UInt min_flag, max_flag;
|
||||
|
||||
if ( major_dir == PSH3_DIR_HORIZONTAL )
|
||||
{
|
||||
min_flag = PSH3_POINT_POSITIVE;
|
||||
max_flag = PSH3_POINT_NEGATIVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
min_flag = PSH3_POINT_NEGATIVE;
|
||||
max_flag = PSH3_POINT_POSITIVE;
|
||||
}
|
||||
|
||||
for ( ; num_hints > 0; num_hints--, sort++ )
|
||||
{
|
||||
PSH3_Hint hint = sort[0];
|
||||
FT_Pos d, flag;
|
||||
|
||||
if ( point->flags2 & min_flag )
|
||||
{
|
||||
flag = PSH3_POINT_EDGE_MIN;
|
||||
d = point->org_u - hint->org_pos;
|
||||
if ( ABS( d ) < PSH3_STRONG_THRESHOLD )
|
||||
{
|
||||
Is_Strong2:
|
||||
point->flags2 |= flag;
|
||||
point->hint = hint;
|
||||
psh3_point_set_strong( point );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( point->flags2 & max_flag )
|
||||
{
|
||||
flag = PSH3_POINT_EDGE_MAX;
|
||||
d = point->org_u - hint->org_pos - hint->org_len;
|
||||
if ( ABS( d ) < PSH3_STRONG_THRESHOLD )
|
||||
goto Is_Strong2;
|
||||
}
|
||||
|
||||
d -= hint->org_len;
|
||||
if ( ABS( d ) < PSH3_STRONG_THRESHOLD )
|
||||
goto Is_Strong;
|
||||
if ( point->org_u >= hint->org_pos &&
|
||||
point->org_u <= hint->org_pos + hint->org_len )
|
||||
{
|
||||
point->hint = hint;
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
||||
if ( point->org_u >= hint->org_pos &&
|
||||
point->org_u <= hint->org_pos + hint->org_len &&
|
||||
psh3_point_is_extremum( point ) )
|
||||
{
|
||||
/* attach to hint, but don't mark as strong */
|
||||
point->hint = hint;
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -1023,8 +1277,8 @@
|
|||
PS_Mask mask = table->hint_masks->masks;
|
||||
FT_UInt num_masks = table->hint_masks->num_masks;
|
||||
FT_UInt first = 0;
|
||||
FT_Int major_dir = dimension == 0 ? PSH3_DIR_UP
|
||||
: PSH3_DIR_RIGHT;
|
||||
FT_Int major_dir = dimension == 0 ? PSH3_DIR_VERTICAL
|
||||
: PSH3_DIR_HORIZONTAL;
|
||||
|
||||
|
||||
/* process secondary hints to "selected" points */
|
||||
|
@ -1107,22 +1361,31 @@
|
|||
{
|
||||
FT_Pos delta;
|
||||
|
||||
|
||||
delta = point->org_u - hint->org_pos;
|
||||
|
||||
if ( delta <= 0 )
|
||||
point->cur_u = hint->cur_pos + FT_MulFix( delta, scale );
|
||||
|
||||
else if ( delta >= hint->org_len )
|
||||
point->cur_u = hint->cur_pos + hint->cur_len +
|
||||
FT_MulFix( delta - hint->org_len, scale );
|
||||
|
||||
else if ( hint->org_len > 0 )
|
||||
point->cur_u = hint->cur_pos +
|
||||
FT_MulDiv( delta, hint->cur_len, hint->org_len );
|
||||
else
|
||||
if ( psh3_point_is_edge_min( point ) )
|
||||
{
|
||||
point->cur_u = hint->cur_pos;
|
||||
}
|
||||
else if ( psh3_point_is_edge_max( point ) )
|
||||
{
|
||||
point->cur_u = hint->cur_pos + hint->cur_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = point->org_u - hint->org_pos;
|
||||
|
||||
if ( delta <= 0 )
|
||||
point->cur_u = hint->cur_pos + FT_MulFix( delta, scale );
|
||||
|
||||
else if ( delta >= hint->org_len )
|
||||
point->cur_u = hint->cur_pos + hint->cur_len +
|
||||
FT_MulFix( delta - hint->org_len, scale );
|
||||
|
||||
else if ( hint->org_len > 0 )
|
||||
point->cur_u = hint->cur_pos +
|
||||
FT_MulDiv( delta, hint->cur_len, hint->org_len );
|
||||
else
|
||||
point->cur_u = hint->cur_pos;
|
||||
}
|
||||
psh3_point_set_fitted( point );
|
||||
}
|
||||
}
|
||||
|
@ -1435,6 +1698,9 @@
|
|||
{
|
||||
/* load outline coordinates into glyph */
|
||||
psh3_glyph_load_points( glyph, dimension );
|
||||
|
||||
/* compute local extrema */
|
||||
psh3_glyph_compute_extrema( glyph );
|
||||
|
||||
/* compute aligned stem/hints positions */
|
||||
psh3_hint_table_align_hints( &glyph->hint_tables[dimension],
|
||||
|
|
|
@ -28,8 +28,10 @@
|
|||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/* handle to Hint structure */
|
||||
typedef struct PSH3_HintRec_* PSH3_Hint;
|
||||
|
||||
|
||||
/* hint bit-flags */
|
||||
typedef enum
|
||||
{
|
||||
PSH3_HINT_GHOST = PS_HINT_FLAG_GHOST,
|
||||
|
@ -48,7 +50,7 @@ FT_BEGIN_HEADER
|
|||
#define psh3_hint_deactivate( x ) (x)->flags &= ~PSH3_HINT_ACTIVE
|
||||
#define psh3_hint_set_fitted( x ) (x)->flags |= PSH3_HINT_FITTED
|
||||
|
||||
|
||||
/* hint structure */
|
||||
typedef struct PSH3_HintRec_
|
||||
{
|
||||
FT_Int org_pos;
|
||||
|
@ -83,7 +85,7 @@ FT_BEGIN_HEADER
|
|||
PSH3_Hint* sort;
|
||||
PSH3_Hint* sort_global;
|
||||
FT_UInt num_zones;
|
||||
PSH3_Zone zones;
|
||||
PSH3_ZoneRec* zones;
|
||||
PSH3_Zone zone;
|
||||
PS_Mask_Table hint_masks;
|
||||
PS_Mask_Table counter_masks;
|
||||
|
@ -97,20 +99,65 @@ FT_BEGIN_HEADER
|
|||
enum
|
||||
{
|
||||
PSH3_DIR_NONE = 4,
|
||||
PSH3_DIR_UP = 1,
|
||||
PSH3_DIR_DOWN = -1,
|
||||
PSH3_DIR_UP = -1,
|
||||
PSH3_DIR_DOWN = 1,
|
||||
PSH3_DIR_LEFT = -2,
|
||||
PSH3_DIR_RIGHT = 2
|
||||
};
|
||||
|
||||
#define PSH3_DIR_HORIZONTAL 2
|
||||
#define PSH3_DIR_VERTICAL 1
|
||||
|
||||
#define PSH3_DIR_COMPARE(d1,d2) ( (d1) == (d2) || (d1) == -(d2) )
|
||||
#define PSH3_DIR_IS_HORIZONTAL(d) PSH3_DIR_COMPARE(d,PSH3_DIR_HORIZONTAL)
|
||||
#define PSH3_DIR_IS_VERTICAL(d) PSH3_DIR_COMPARE(d,PSH3_DIR_VERTICAL)
|
||||
|
||||
|
||||
/* the following bit-flags are computed once by the glyph */
|
||||
/* analyzer, for both dimensions */
|
||||
enum
|
||||
{
|
||||
PSH3_POINT_OFF = 1, /* point is off the curve */
|
||||
PSH3_POINT_STRONG = 2, /* point is strong */
|
||||
PSH3_POINT_SMOOTH = 4, /* point is smooth */
|
||||
PSH3_POINT_FITTED = 8 /* point is already fitted */
|
||||
PSH3_POINT_OFF = 1, /* point is off the curve */
|
||||
PSH3_POINT_SMOOTH = 2, /* point is smooth */
|
||||
PSH3_POINT_INFLEX = 4 /* point is inflection */
|
||||
};
|
||||
|
||||
#define psh3_point_is_smooth( p ) ( (p)->flags & PSH3_POINT_SMOOTH )
|
||||
#define psh3_point_is_off( p ) ( (p)->flags & PSH3_POINT_OFF )
|
||||
#define psh3_point_is_inflection( p ) ( (p)->flags & PSH3_POINT_INFLEX )
|
||||
|
||||
#define psh3_point_set_smooth( p ) (p)->flags |= PSH3_POINT_SMOOTH
|
||||
#define psh3_point_set_off( p ) (p)->flags |= PSH3_POINT_OFF
|
||||
#define psh3_point_set_inflex( p ) (p)->flags |= PSH3_POINT_INFLEX
|
||||
|
||||
/* the following bit-flags are re-computed for each dimension */
|
||||
enum
|
||||
{
|
||||
PSH3_POINT_STRONG = 16, /* point is strong */
|
||||
PSH3_POINT_FITTED = 32, /* point is already fitted */
|
||||
PSH3_POINT_EXTREMUM = 64, /* point is local extremum */
|
||||
PSH3_POINT_POSITIVE = 128, /* extremum has positive contour flow */
|
||||
PSH3_POINT_NEGATIVE = 256, /* extremum has negative contour flow */
|
||||
PSH3_POINT_EDGE_MIN = 512, /* point is aligned to left/bottom stem edge */
|
||||
PSH3_POINT_EDGE_MAX = 1024 /* point is aligned to top/right stem edge */
|
||||
};
|
||||
|
||||
#define psh3_point_is_strong( p ) ( (p)->flags2 & PSH3_POINT_STRONG )
|
||||
#define psh3_point_is_fitted( p ) ( (p)->flags2 & PSH3_POINT_FITTED )
|
||||
#define psh3_point_is_extremum( p ) ( (p)->flags2 & PSH3_POINT_EXTREMUM )
|
||||
#define psh3_point_is_positive( p ) ( (p)->flags2 & PSH3_POINT_POSITIVE )
|
||||
#define psh3_point_is_negative( p ) ( (p)->flags2 & PSH3_POINT_NEGATIVE )
|
||||
#define psh3_point_is_edge_min( p ) ( (p)->flags2 & PSH3_POINT_EDGE_MIN )
|
||||
#define psh3_point_is_edge_max( p ) ( (p)->flags2 & PSH3_POINT_EDGE_MAX )
|
||||
|
||||
#define psh3_point_set_strong( p ) (p)->flags2 |= PSH3_POINT_STRONG
|
||||
#define psh3_point_set_fitted( p ) (p)->flags2 |= PSH3_POINT_FITTED
|
||||
#define psh3_point_set_extremum( p ) (p)->flags2 |= PSH3_POINT_EXTREMUM
|
||||
#define psh3_point_set_positive( p ) (p)->flags2 |= PSH3_POINT_POSITIVE
|
||||
#define psh3_point_set_negative( p ) (p)->flags2 |= PSH3_POINT_NEGATIVE
|
||||
#define psh3_point_set_edge_min( p ) (p)->flags2 |= PSH3_POINT_EDGE_MIN
|
||||
#define psh3_point_set_edge_max( p ) (p)->flags2 |= PSH3_POINT_EDGE_MAX
|
||||
|
||||
|
||||
typedef struct PSH3_PointRec_
|
||||
{
|
||||
|
@ -118,12 +165,14 @@ FT_BEGIN_HEADER
|
|||
PSH3_Point next;
|
||||
PSH3_Contour contour;
|
||||
FT_UInt flags;
|
||||
FT_UInt flags2;
|
||||
FT_Char dir_in;
|
||||
FT_Char dir_out;
|
||||
FT_Angle angle_in;
|
||||
FT_Angle angle_out;
|
||||
PSH3_Hint hint;
|
||||
FT_Pos org_u;
|
||||
FT_Pos org_v;
|
||||
FT_Pos cur_u;
|
||||
#ifdef DEBUG_HINTER
|
||||
FT_Pos org_x;
|
||||
|
@ -137,14 +186,11 @@ FT_BEGIN_HEADER
|
|||
} PSH3_PointRec;
|
||||
|
||||
|
||||
#define psh3_point_is_strong( p ) ( (p)->flags & PSH3_POINT_STRONG )
|
||||
#define psh3_point_is_fitted( p ) ( (p)->flags & PSH3_POINT_FITTED )
|
||||
#define psh3_point_is_smooth( p ) ( (p)->flags & PSH3_POINT_SMOOTH )
|
||||
|
||||
#define psh3_point_set_strong( p ) (p)->flags |= PSH3_POINT_STRONG
|
||||
#define psh3_point_set_fitted( p ) (p)->flags |= PSH3_POINT_FITTED
|
||||
#define psh3_point_set_smooth( p ) (p)->flags |= PSH3_POINT_SMOOTH
|
||||
#define PSH3_POINT_EQUAL_ORG(a,b) ( (a)->org_u == (b)->org_u && \
|
||||
(a)->org_v == (b)->org_v )
|
||||
|
||||
#define PSH3_POINT_ANGLE(a,b) FT_Atan2( (b)->org_u - (a)->org_u, \
|
||||
(b)->org_v - (a)->org_v )
|
||||
|
||||
typedef struct PSH3_ContourRec_
|
||||
{
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "pshglob.h"
|
||||
|
||||
#ifdef DEBUG_HINTER
|
||||
extern PSH_Globals ps_debug_globals = 0;
|
||||
PSH_Globals ps_debug_globals = 0;
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -27,9 +27,9 @@
|
|||
#define FT_COMPONENT trace_pshrec
|
||||
|
||||
#ifdef DEBUG_HINTER
|
||||
extern PS_Hints ps_debug_hints = 0;
|
||||
extern int ps_debug_no_horz_hints = 0;
|
||||
extern int ps_debug_no_vert_hints = 0;
|
||||
PS_Hints ps_debug_hints = 0;
|
||||
int ps_debug_no_horz_hints = 0;
|
||||
int ps_debug_no_vert_hints = 0;
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -7,28 +7,35 @@ test_programs = gview ;
|
|||
|
||||
SubDirHdrs [ FT2_SubDir .. nirvana include ] ;
|
||||
|
||||
NV_TOP = [ FT2_SubDir .. .. nirvana ] ;
|
||||
NV_TOP = [ FT2_SubDir .. .. nirvana ] ;
|
||||
|
||||
NIRVANA_LINKLIBS = $(NV_TOP)\\objs\\nirvana$(SUFLIB) ;
|
||||
NIRVANA_LINKLIBS = $(NV_TOP)/objs/libnirvana$(SUFLIB) ;
|
||||
|
||||
{
|
||||
local t ;
|
||||
|
||||
|
||||
for t in $(test_programs)
|
||||
{
|
||||
Main $(t) : $(t).c ;
|
||||
|
||||
|
||||
LinkLibraries $(t) : $(FT2_LIB) ;
|
||||
|
||||
if $(TOOLSET) = MINGW
|
||||
|
||||
if $(WIN)
|
||||
{
|
||||
LINKKLIBS on $(t)$(SUFEXE) = "-luser32 -lgdi32" ;
|
||||
if $(TOOLSET) = MINGW
|
||||
{
|
||||
LINKKLIBS on $(t)$(SUFEXE) = "-luser32 -lgdi32" ;
|
||||
}
|
||||
else
|
||||
{
|
||||
LINKLIBS on $(t)$(SUFEXE) = user32.lib gdi32.lib ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LINKLIBS on $(t)$(SUFEXE) = user32.lib gdi32.lib ;
|
||||
LINKLIBS on $(t)$(SUFEXE) = -L/usr/X11R6/lib -lX11 -lm ;
|
||||
}
|
||||
|
||||
|
||||
NEEDLIBS on $(t)$(SUFEXE) += $(NIRVANA_LINKLIBS) ;
|
||||
}
|
||||
}
|
||||
|
|
162
tests/gview.c
162
tests/gview.c
|
@ -9,6 +9,7 @@
|
|||
#include <../src/pshinter/pshrec.h>
|
||||
#include <../src/pshinter/pshalgo1.h>
|
||||
#include <../src/pshinter/pshalgo2.h>
|
||||
#include <../src/pshinter/pshalgo3.h>
|
||||
|
||||
#include <../src/autohint/ahtypes.h>
|
||||
|
||||
|
@ -610,6 +611,155 @@ ps2_draw_control_points( void )
|
|||
}
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** POSTSCRIPT HINTER ALGORITHM 3 ROUTINES *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
#include <../src/pshinter/pshalgo3.h>
|
||||
|
||||
static void
|
||||
draw_ps3_hint( PSH3_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,
|
||||
psh3_hint_is_ghost(hint)
|
||||
? GHOST_HINT_COLOR : STEM_HINT_COLOR );
|
||||
|
||||
if ( psh3_hint_is_ghost(hint) )
|
||||
{
|
||||
x1 --;
|
||||
x2 = x1 + 2;
|
||||
}
|
||||
else
|
||||
nv_pixmap_fill_rect( target, x2, 0, 1, target->height,
|
||||
psh3_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,
|
||||
psh3_hint_is_ghost(hint)
|
||||
? GHOST_HINT_COLOR : STEM_HINT_COLOR );
|
||||
|
||||
if ( psh3_hint_is_ghost(hint) )
|
||||
{
|
||||
x1 --;
|
||||
x2 = x1 + 2;
|
||||
}
|
||||
else
|
||||
nv_pixmap_fill_rect( target, 0, x2, target->width, 1,
|
||||
psh3_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 );
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf( "[%7.3f %7.3f] %c\n", hint->cur_pos/64.0, (hint->cur_pos+hint->cur_len)/64.0, vertical ? 'v' : 'h' );
|
||||
#endif
|
||||
|
||||
pshint_cpos += 10;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ps3_draw_control_points( void )
|
||||
{
|
||||
if ( ps3_debug_glyph )
|
||||
{
|
||||
PSH3_Glyph glyph = ps3_debug_glyph;
|
||||
PSH3_Point point = glyph->points;
|
||||
FT_UInt count = glyph->num_points;
|
||||
NV_Transform transform, *trans = &transform;
|
||||
NV_Path vert_rect;
|
||||
NV_Path horz_rect;
|
||||
NV_Path dot, circle;
|
||||
|
||||
for ( ; count > 0; count--, point++ )
|
||||
{
|
||||
NV_Vector vec;
|
||||
|
||||
vec.x = point->cur_x;
|
||||
vec.y = point->cur_y;
|
||||
nv_vector_transform( &vec, &size_transform );
|
||||
|
||||
nv_transform_set_translate( trans, vec.x, vec.y );
|
||||
|
||||
if ( option_show_smooth && !psh3_point_is_smooth(point) )
|
||||
{
|
||||
nv_painter_set_color( painter, SMOOTH_COLOR, 256 );
|
||||
nv_painter_fill_path( painter, trans, 0, symbol_circle );
|
||||
}
|
||||
|
||||
if (option_show_horz_hints)
|
||||
{
|
||||
if ( point->flags_y & PSH3_POINT_STRONG )
|
||||
{
|
||||
nv_painter_set_color( painter, STRONG_COLOR, 256 );
|
||||
nv_painter_fill_path( painter, trans, 0, symbol_rect_h );
|
||||
}
|
||||
}
|
||||
|
||||
if (option_show_vert_hints)
|
||||
{
|
||||
if ( point->flags_x & PSH3_POINT_STRONG )
|
||||
{
|
||||
nv_painter_set_color( painter, STRONG_COLOR, 256 );
|
||||
nv_painter_fill_path( painter, trans, 0, symbol_rect_v );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ps_print_hints( void )
|
||||
|
@ -742,7 +892,7 @@ ah_draw_edges( void )
|
|||
|
||||
if ( option_show_edges )
|
||||
{
|
||||
/* draw verticla edges */
|
||||
/* draw vertical edges */
|
||||
if ( option_show_vert_hints )
|
||||
{
|
||||
count = glyph->num_vedges;
|
||||
|
@ -956,12 +1106,11 @@ draw_glyph( int glyph_index )
|
|||
|
||||
ps1_debug_hint_func = option_show_ps_hints ? draw_ps1_hint : 0;
|
||||
ps2_debug_hint_func = option_show_ps_hints ? draw_ps2_hint : 0;
|
||||
ps3_debug_hint_func = option_show_ps_hints ? draw_ps3_hint : 0;
|
||||
|
||||
ah_debug_hinter = NULL;
|
||||
|
||||
error = FT_Load_Glyph( face, glyph_index, option_hinting
|
||||
? FT_LOAD_NO_BITMAP
|
||||
: FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING );
|
||||
error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_BITMAP );
|
||||
if (error) Panic( "could not load glyph" );
|
||||
|
||||
if ( face->glyph->format != ft_glyph_format_outline )
|
||||
|
@ -1182,6 +1331,9 @@ handle_event( NVV_EventRec* ev )
|
|||
TOGGLE_OPTION( option_show_blues, "blue zones display" );
|
||||
|
||||
case NVV_KEY('h'):
|
||||
ps_debug_no_horz_hints = option_hinting;
|
||||
ps_debug_no_vert_hints = option_hinting;
|
||||
|
||||
TOGGLE_OPTION( option_hinting, "hinting" )
|
||||
|
||||
case NVV_KEY('H'):
|
||||
|
@ -1302,7 +1454,7 @@ int main( int argc, char** argv )
|
|||
|
||||
draw_ps_blue_zones();
|
||||
draw_glyph( glyph_index );
|
||||
ps2_draw_control_points();
|
||||
ps3_draw_control_points();
|
||||
|
||||
nvv_surface_refresh( surface, NULL );
|
||||
|
||||
|
|
Loading…
Reference in New Issue