* src/autofit/{afhints.h,afhints.c,aflatin.h,aflatin.c,afloader.c}:
various bug-fixes and drastic heap usage reduction improvements. * include/freetype/config/ftmodule.h: the auto-fitter is now the only supported auto-hinting module * include/freetype/config/ftstdlib.h: adding FT_INT_MAX definition
This commit is contained in:
parent
e793092d0a
commit
b9c22aff61
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2005-03-01 David Turner <david@freetype.org>
|
||||||
|
|
||||||
|
* src/autofit/{afhints.h,afhints.c,aflatin.h,aflatin.c,afloader.c}:
|
||||||
|
various bug-fixes and drastic heap usage reduction improvements.
|
||||||
|
|
||||||
|
* include/freetype/config/ftmodule.h: the auto-fitter is now the
|
||||||
|
only supported auto-hinting module
|
||||||
|
|
||||||
|
* include/freetype/config/ftstdlib.h: adding FT_INT_MAX definition
|
||||||
|
|
||||||
2005-02-28 Werner Lemberg <wl@gnu.org>
|
2005-02-28 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
* src/truetype/ttpload.c (tt_face_load_loca): Fix typo.
|
* src/truetype/ttpload.c (tt_face_load_loca): Fix typo.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FT_USE_MODULE(autohint_module_class)
|
FT_USE_MODULE(autofit_module_class)
|
||||||
FT_USE_MODULE(tt_driver_class)
|
FT_USE_MODULE(tt_driver_class)
|
||||||
FT_USE_MODULE(t1_driver_class)
|
FT_USE_MODULE(t1_driver_class)
|
||||||
FT_USE_MODULE(cff_driver_class)
|
FT_USE_MODULE(cff_driver_class)
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#define FT_UINT_MAX UINT_MAX
|
#define FT_UINT_MAX UINT_MAX
|
||||||
|
#define FT_INT_MAX INT_MAX
|
||||||
#define FT_ULONG_MAX ULONG_MAX
|
#define FT_ULONG_MAX ULONG_MAX
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,96 @@
|
||||||
#include "afhints.h"
|
#include "afhints.h"
|
||||||
|
|
||||||
|
|
||||||
|
FT_LOCAL_DEF( FT_Error )
|
||||||
|
af_axis_hints_new_segment( AF_AxisHints axis,
|
||||||
|
FT_Memory memory,
|
||||||
|
AF_Segment *asegment )
|
||||||
|
{
|
||||||
|
FT_Error error = 0;
|
||||||
|
AF_Segment segment = NULL;
|
||||||
|
|
||||||
|
if ( axis->num_segments >= axis->max_segments )
|
||||||
|
{
|
||||||
|
FT_Int old_max = axis->max_segments;
|
||||||
|
FT_Int new_max = old_max;
|
||||||
|
FT_Int big_max = FT_INT_MAX / sizeof(*segment);
|
||||||
|
|
||||||
|
if ( old_max >= big_max )
|
||||||
|
{
|
||||||
|
error = FT_Err_Out_Of_Memory;
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_max += (new_max >> 1) + 4;
|
||||||
|
if ( new_max < old_max || new_max > big_max )
|
||||||
|
new_max = big_max;
|
||||||
|
|
||||||
|
if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
|
axis->max_segments = new_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
segment = axis->segments + axis->num_segments++;
|
||||||
|
FT_ZERO( segment );
|
||||||
|
|
||||||
|
Exit:
|
||||||
|
*asegment = segment;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
FT_LOCAL( FT_Error)
|
||||||
|
af_axis_hints_new_edge( AF_AxisHints axis,
|
||||||
|
FT_Int fpos,
|
||||||
|
FT_Memory memory,
|
||||||
|
AF_Edge *aedge )
|
||||||
|
{
|
||||||
|
FT_Error error = 0;
|
||||||
|
AF_Edge edge = NULL;
|
||||||
|
AF_Edge edges;
|
||||||
|
|
||||||
|
if ( axis->num_edges >= axis->max_edges )
|
||||||
|
{
|
||||||
|
FT_Int old_max = axis->max_edges;
|
||||||
|
FT_Int new_max = old_max;
|
||||||
|
FT_Int big_max = FT_INT_MAX / sizeof(*edge);
|
||||||
|
|
||||||
|
if ( old_max >= big_max )
|
||||||
|
{
|
||||||
|
error = FT_Err_Out_Of_Memory;
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_max += (new_max >> 1) + 4;
|
||||||
|
if ( new_max < old_max || new_max > big_max )
|
||||||
|
new_max = big_max;
|
||||||
|
|
||||||
|
if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
|
axis->max_edges = new_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
edges = axis->edges;
|
||||||
|
edge = edges + axis->num_edges;
|
||||||
|
|
||||||
|
while ( edge > edges && edge[-1].fpos > fpos )
|
||||||
|
{
|
||||||
|
edge[0] = edge[-1];
|
||||||
|
edge--;
|
||||||
|
}
|
||||||
|
|
||||||
|
axis->num_edges++;
|
||||||
|
|
||||||
|
FT_ZERO(edge);
|
||||||
|
edge->fpos = (FT_Short) fpos;
|
||||||
|
|
||||||
|
Exit:
|
||||||
|
*aedge = edge;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef AF_DEBUG
|
#ifdef AF_DEBUG
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -295,9 +386,12 @@
|
||||||
AF_AxisHints axis = &hints->axis[ dim ];
|
AF_AxisHints axis = &hints->axis[ dim ];
|
||||||
|
|
||||||
axis->num_segments = 0;
|
axis->num_segments = 0;
|
||||||
|
axis->max_segments = 0;
|
||||||
|
FT_FREE( axis->segments );
|
||||||
|
|
||||||
axis->num_edges = 0;
|
axis->num_edges = 0;
|
||||||
axis->segments = NULL;
|
axis->max_edges = 0;
|
||||||
axis->edges = NULL;
|
FT_FREE( axis->edges );
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_FREE( hints->contours );
|
FT_FREE( hints->contours );
|
||||||
|
@ -359,7 +453,7 @@
|
||||||
hints->max_contours = new_max;
|
hints->max_contours = new_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* then, reallocate the points, segments & edges arrays if needed --
|
/* then, reallocate the points arrays if needed --
|
||||||
* note that we reserved two additional point positions, used to
|
* note that we reserved two additional point positions, used to
|
||||||
* hint metrics appropriately
|
* hint metrics appropriately
|
||||||
*/
|
*/
|
||||||
|
@ -367,59 +461,17 @@
|
||||||
old_max = hints->max_points;
|
old_max = hints->max_points;
|
||||||
if ( new_max > old_max )
|
if ( new_max > old_max )
|
||||||
{
|
{
|
||||||
FT_Byte* items;
|
|
||||||
FT_ULong off1, off2, off3;
|
|
||||||
|
|
||||||
/* we store in a single buffer the following arrays:
|
|
||||||
*
|
|
||||||
* - an array of N AF_PointRec items
|
|
||||||
* - an array of 2*N AF_SegmentRec items
|
|
||||||
* - an array of 2*N AF_EdgeRec items
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
new_max = ( new_max + 2 + 7 ) & ~7;
|
new_max = ( new_max + 2 + 7 ) & ~7;
|
||||||
|
|
||||||
#define OFF_PAD2(x,y) (((x)+(y)-1) & ~((y)-1))
|
if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) )
|
||||||
#define OFF_PADX(x,y) ((((x)+(y)-1)/(y))*(y))
|
|
||||||
#define OFF_PAD(x,y) ( ((y) & ((y)-1)) ? OFF_PADX(x,y) : OFF_PAD2(x,y) )
|
|
||||||
|
|
||||||
#undef OFF_INCREMENT
|
|
||||||
#define OFF_INCREMENT( _off, _type, _count ) \
|
|
||||||
( OFF_PAD( _off, sizeof(_type) ) + (_count)*sizeof(_type))
|
|
||||||
|
|
||||||
off1 = OFF_INCREMENT( 0, AF_PointRec, new_max );
|
|
||||||
off2 = OFF_INCREMENT( off1, AF_SegmentRec, new_max*2 );
|
|
||||||
off3 = OFF_INCREMENT( off2, AF_EdgeRec, new_max*2 );
|
|
||||||
|
|
||||||
FT_FREE( hints->points );
|
|
||||||
|
|
||||||
if ( FT_ALLOC( items, off3 ) )
|
|
||||||
{
|
|
||||||
hints->max_points = 0;
|
|
||||||
hints->axis[0].segments = NULL;
|
|
||||||
hints->axis[0].edges = NULL;
|
|
||||||
hints->axis[1].segments = NULL;
|
|
||||||
hints->axis[1].edges = NULL;
|
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
|
||||||
|
|
||||||
/* readjust some pointers
|
hints->max_points = new_max;
|
||||||
*/
|
|
||||||
hints->max_points = new_max;
|
|
||||||
hints->points = (AF_Point) items;
|
|
||||||
|
|
||||||
hints->axis[0].segments = (AF_Segment)( items + off1 );
|
|
||||||
hints->axis[1].segments = hints->axis[0].segments + new_max;
|
|
||||||
|
|
||||||
hints->axis[0].edges = (AF_Edge) ( items + off2 );
|
|
||||||
hints->axis[1].edges = hints->axis[0].edges + new_max;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hints->num_points = outline->n_points;
|
hints->num_points = outline->n_points;
|
||||||
hints->num_contours = outline->n_contours;
|
hints->num_contours = outline->n_contours;
|
||||||
|
|
||||||
|
|
||||||
/* We can't rely on the value of `FT_Outline.flags' to know the fill */
|
/* We can't rely on the value of `FT_Outline.flags' to know the fill */
|
||||||
/* direction used for a glyph, given that some fonts are broken (e.g. */
|
/* direction used for a glyph, given that some fonts are broken (e.g. */
|
||||||
/* the Arphic ones). We thus recompute it each time we need to. */
|
/* the Arphic ones). We thus recompute it each time we need to. */
|
||||||
|
|
|
@ -84,15 +84,15 @@ FT_BEGIN_HEADER
|
||||||
|
|
||||||
typedef struct AF_PointRec_
|
typedef struct AF_PointRec_
|
||||||
{
|
{
|
||||||
AF_Flags flags; /* point flags used by hinter */
|
FT_UShort flags; /* point flags used by hinter */
|
||||||
|
FT_Char in_dir; /* direction of inwards vector */
|
||||||
|
FT_Char out_dir; /* direction of outwards vector */
|
||||||
|
|
||||||
FT_Pos ox, oy; /* original, scaled position */
|
FT_Pos ox, oy; /* original, scaled position */
|
||||||
FT_Short fx, fy; /* original, unscaled position (font units) */
|
FT_Short fx, fy; /* original, unscaled position (font units) */
|
||||||
FT_Pos x, y; /* current position */
|
FT_Pos x, y; /* current position */
|
||||||
FT_Pos u, v; /* current (x,y) or (y,x) depending on context */
|
FT_Pos u, v; /* current (x,y) or (y,x) depending on context */
|
||||||
|
|
||||||
FT_Char in_dir; /* direction of inwards vector */
|
|
||||||
FT_Char out_dir; /* direction of outwards vector */
|
|
||||||
|
|
||||||
AF_Point next; /* next point in contour */
|
AF_Point next; /* next point in contour */
|
||||||
AF_Point prev; /* previous point in contour */
|
AF_Point prev; /* previous point in contour */
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ FT_BEGIN_HEADER
|
||||||
|
|
||||||
typedef struct AF_SegmentRec_
|
typedef struct AF_SegmentRec_
|
||||||
{
|
{
|
||||||
AF_Edge_Flags flags; /* edge/segment flags for this segment */
|
FT_Byte flags; /* edge/segment flags for this segment */
|
||||||
FT_Char dir; /* segment direction */
|
FT_Char dir; /* segment direction */
|
||||||
FT_Short pos; /* position of segment */
|
FT_Short pos; /* position of segment */
|
||||||
FT_Short min_coord; /* minimum coordinate of segment */
|
FT_Short min_coord; /* minimum coordinate of segment */
|
||||||
|
@ -148,9 +148,11 @@ FT_BEGIN_HEADER
|
||||||
typedef struct AF_AxisHintsRec_
|
typedef struct AF_AxisHintsRec_
|
||||||
{
|
{
|
||||||
FT_Int num_segments;
|
FT_Int num_segments;
|
||||||
|
FT_Int max_segments;
|
||||||
AF_Segment segments;
|
AF_Segment segments;
|
||||||
|
|
||||||
FT_Int num_edges;
|
FT_Int num_edges;
|
||||||
|
FT_Int max_edges;
|
||||||
AF_Edge edges;
|
AF_Edge edges;
|
||||||
|
|
||||||
AF_Direction major_dir;
|
AF_Direction major_dir;
|
||||||
|
@ -205,6 +207,17 @@ FT_BEGIN_HEADER
|
||||||
FT_Pos dy );
|
FT_Pos dy );
|
||||||
|
|
||||||
|
|
||||||
|
FT_LOCAL( FT_Error )
|
||||||
|
af_axis_hints_new_segment( AF_AxisHints axis,
|
||||||
|
FT_Memory memory,
|
||||||
|
AF_Segment *asegment );
|
||||||
|
|
||||||
|
FT_LOCAL( FT_Error)
|
||||||
|
af_axis_hints_new_edge( AF_AxisHints axis,
|
||||||
|
FT_Int fpos,
|
||||||
|
FT_Memory memory,
|
||||||
|
AF_Edge *edge );
|
||||||
|
|
||||||
FT_LOCAL( void )
|
FT_LOCAL( void )
|
||||||
af_glyph_hints_init( AF_GlyphHints hints,
|
af_glyph_hints_init( AF_GlyphHints hints,
|
||||||
FT_Memory memory );
|
FT_Memory memory );
|
||||||
|
|
|
@ -58,7 +58,10 @@
|
||||||
FT_UInt num_widths = 0;
|
FT_UInt num_widths = 0;
|
||||||
FT_Pos edge_distance_threshold = 32000;
|
FT_Pos edge_distance_threshold = 32000;
|
||||||
|
|
||||||
af_latin_hints_compute_segments( hints, dim );
|
error = af_latin_hints_compute_segments( hints, dim );
|
||||||
|
if ( error )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
af_latin_hints_link_segments ( hints, dim );
|
af_latin_hints_link_segments ( hints, dim );
|
||||||
|
|
||||||
seg = axhints->segments;
|
seg = axhints->segments;
|
||||||
|
@ -506,9 +509,6 @@
|
||||||
af_latin_metrics_scale( AF_LatinMetrics metrics,
|
af_latin_metrics_scale( AF_LatinMetrics metrics,
|
||||||
AF_Scaler scaler )
|
AF_Scaler scaler )
|
||||||
{
|
{
|
||||||
if ( AF_SCALER_EQUAL_SCALES( scaler, &metrics->root.scaler ) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ );
|
af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ );
|
||||||
af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT );
|
af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT );
|
||||||
}
|
}
|
||||||
|
@ -522,14 +522,14 @@
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
FT_LOCAL_DEF( void )
|
FT_LOCAL_DEF( FT_Error )
|
||||||
af_latin_hints_compute_segments( AF_GlyphHints hints,
|
af_latin_hints_compute_segments( AF_GlyphHints hints,
|
||||||
AF_Dimension dim )
|
AF_Dimension dim )
|
||||||
{
|
{
|
||||||
AF_AxisHints axis = &hints->axis[dim];
|
AF_AxisHints axis = &hints->axis[dim];
|
||||||
AF_Segment segments = axis->segments;
|
FT_Memory memory = hints->memory;
|
||||||
AF_Segment segment = segments;
|
FT_Error error = 0;
|
||||||
FT_Int num_segments = 0;
|
AF_Segment segment = NULL;
|
||||||
AF_Point* contour = hints->contours;
|
AF_Point* contour = hints->contours;
|
||||||
AF_Point* contour_limit = contour + hints->num_contours;
|
AF_Point* contour_limit = contour + hints->num_contours;
|
||||||
AF_Direction major_dir, segment_dir;
|
AF_Direction major_dir, segment_dir;
|
||||||
|
@ -544,6 +544,8 @@
|
||||||
major_dir = FT_ABS( axis->major_dir );
|
major_dir = FT_ABS( axis->major_dir );
|
||||||
segment_dir = major_dir;
|
segment_dir = major_dir;
|
||||||
|
|
||||||
|
axis->num_segments = 0;
|
||||||
|
|
||||||
/* set up (u,v) in each point */
|
/* set up (u,v) in each point */
|
||||||
if ( dim == AF_DIMENSION_HORZ )
|
if ( dim == AF_DIMENSION_HORZ )
|
||||||
{
|
{
|
||||||
|
@ -656,8 +658,7 @@
|
||||||
segment->max_coord = max_pos;
|
segment->max_coord = max_pos;
|
||||||
|
|
||||||
on_edge = 0;
|
on_edge = 0;
|
||||||
num_segments++;
|
segment = NULL;
|
||||||
segment++;
|
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -676,7 +677,9 @@
|
||||||
segment_dir = point->out_dir;
|
segment_dir = point->out_dir;
|
||||||
|
|
||||||
/* clear all segment fields */
|
/* clear all segment fields */
|
||||||
FT_ZERO( segment );
|
error = af_axis_hints_new_segment( axis, memory, &segment );
|
||||||
|
if ( error )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
segment->dir = segment_dir;
|
segment->dir = segment_dir;
|
||||||
segment->flags = AF_EDGE_NORMAL;
|
segment->flags = AF_EDGE_NORMAL;
|
||||||
|
@ -740,7 +743,9 @@
|
||||||
if ( min_point )
|
if ( min_point )
|
||||||
{
|
{
|
||||||
/* clear all segment fields */
|
/* clear all segment fields */
|
||||||
FT_ZERO( segment );
|
error = af_axis_hints_new_segment( axis, memory, &segment );
|
||||||
|
if ( error )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
segment->dir = segment_dir;
|
segment->dir = segment_dir;
|
||||||
segment->flags = AF_EDGE_NORMAL;
|
segment->flags = AF_EDGE_NORMAL;
|
||||||
|
@ -750,15 +755,16 @@
|
||||||
segment->score = 32000;
|
segment->score = 32000;
|
||||||
segment->link = NULL;
|
segment->link = NULL;
|
||||||
|
|
||||||
num_segments++;
|
segment = NULL;
|
||||||
segment++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* insert maximum segment */
|
/* insert maximum segment */
|
||||||
if ( max_point )
|
if ( max_point )
|
||||||
{
|
{
|
||||||
/* clear all segment fields */
|
/* clear all segment fields */
|
||||||
FT_ZERO( segment );
|
error = af_axis_hints_new_segment( axis, memory, &segment );
|
||||||
|
if ( error)
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
segment->dir = segment_dir;
|
segment->dir = segment_dir;
|
||||||
segment->flags = AF_EDGE_NORMAL;
|
segment->flags = AF_EDGE_NORMAL;
|
||||||
|
@ -768,13 +774,13 @@
|
||||||
segment->score = 32000;
|
segment->score = 32000;
|
||||||
segment->link = NULL;
|
segment->link = NULL;
|
||||||
|
|
||||||
num_segments++;
|
segment = NULL;
|
||||||
segment++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* AF_HINT_METRICS */
|
#endif /* AF_HINT_METRICS */
|
||||||
|
|
||||||
axis->num_segments = num_segments;
|
Exit:
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -858,14 +864,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FT_LOCAL_DEF( void )
|
FT_LOCAL_DEF( FT_Error )
|
||||||
af_latin_hints_compute_edges( AF_GlyphHints hints,
|
af_latin_hints_compute_edges( AF_GlyphHints hints,
|
||||||
AF_Dimension dim )
|
AF_Dimension dim )
|
||||||
{
|
{
|
||||||
AF_AxisHints axis = &hints->axis[dim];
|
AF_AxisHints axis = &hints->axis[dim];
|
||||||
|
FT_Error error = 0;
|
||||||
|
FT_Memory memory = hints->memory;
|
||||||
AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim];
|
AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim];
|
||||||
AF_Edge edges = axis->edges;
|
|
||||||
AF_Edge edge, edge_limit;
|
|
||||||
|
|
||||||
AF_Segment segments = axis->segments;
|
AF_Segment segments = axis->segments;
|
||||||
AF_Segment segment_limit = segments + axis->num_segments;
|
AF_Segment segment_limit = segments + axis->num_segments;
|
||||||
|
@ -875,6 +881,7 @@
|
||||||
FT_Fixed scale;
|
FT_Fixed scale;
|
||||||
FT_Pos edge_distance_threshold;
|
FT_Pos edge_distance_threshold;
|
||||||
|
|
||||||
|
axis->num_edges = 0;
|
||||||
|
|
||||||
scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale
|
scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale
|
||||||
: hints->y_scale;
|
: hints->y_scale;
|
||||||
|
@ -906,16 +913,16 @@
|
||||||
edge_distance_threshold = FT_DivFix( edge_distance_threshold,
|
edge_distance_threshold = FT_DivFix( edge_distance_threshold,
|
||||||
scale );
|
scale );
|
||||||
|
|
||||||
edge_limit = edges;
|
|
||||||
for ( seg = segments; seg < segment_limit; seg++ )
|
for ( seg = segments; seg < segment_limit; seg++ )
|
||||||
{
|
{
|
||||||
AF_Edge found = 0;
|
AF_Edge found = 0;
|
||||||
|
FT_Int ee;
|
||||||
|
|
||||||
/* look for an edge corresponding to the segment */
|
/* look for an edge corresponding to the segment */
|
||||||
for ( edge = edges; edge < edge_limit; edge++ )
|
for ( ee = 0; ee < axis->num_edges; ee++ )
|
||||||
{
|
{
|
||||||
FT_Pos dist;
|
AF_Edge edge = axis->edges + ee;
|
||||||
|
FT_Pos dist;
|
||||||
|
|
||||||
|
|
||||||
dist = seg->pos - edge->fpos;
|
dist = seg->pos - edge->fpos;
|
||||||
|
@ -931,19 +938,17 @@
|
||||||
|
|
||||||
if ( !found )
|
if ( !found )
|
||||||
{
|
{
|
||||||
|
AF_Edge edge;
|
||||||
|
|
||||||
/* insert a new edge in the list and */
|
/* insert a new edge in the list and */
|
||||||
/* sort according to the position */
|
/* sort according to the position */
|
||||||
while ( edge > edges && edge[-1].fpos > seg->pos )
|
error = af_axis_hints_new_edge( axis, seg->pos, memory, &edge );
|
||||||
{
|
if ( error )
|
||||||
edge[0] = edge[-1];
|
goto Exit;
|
||||||
edge--;
|
|
||||||
}
|
|
||||||
edge_limit++;
|
|
||||||
|
|
||||||
/* clear all edge fields */
|
|
||||||
FT_ZERO( edge );
|
|
||||||
|
|
||||||
/* add the segment to the new edge's list */
|
/* add the segment to the new edge's list */
|
||||||
|
FT_ZERO(edge);
|
||||||
|
|
||||||
edge->first = seg;
|
edge->first = seg;
|
||||||
edge->last = seg;
|
edge->last = seg;
|
||||||
edge->fpos = seg->pos;
|
edge->fpos = seg->pos;
|
||||||
|
@ -954,12 +959,11 @@
|
||||||
{
|
{
|
||||||
/* if an edge was found, simply add the segment to the edge's */
|
/* if an edge was found, simply add the segment to the edge's */
|
||||||
/* list */
|
/* list */
|
||||||
seg->edge_next = edge->first;
|
seg->edge_next = found->first;
|
||||||
edge->last->edge_next = seg;
|
found->last->edge_next = seg;
|
||||||
edge->last = seg;
|
found->last = seg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
axis->num_edges = (FT_Int)( edge_limit - edges );
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
@ -982,133 +986,148 @@
|
||||||
* code above. For some reason, it slows down execution
|
* code above. For some reason, it slows down execution
|
||||||
* speed -- on a Sun.
|
* speed -- on a Sun.
|
||||||
*/
|
*/
|
||||||
for ( edge = edges; edge < edge_limit; edge++ )
|
|
||||||
{
|
{
|
||||||
seg = edge->first;
|
AF_Edge edges = axis->edges;
|
||||||
if ( seg )
|
AF_Edge edge_limit = edges + axis->num_edges;
|
||||||
|
AF_Edge edge;
|
||||||
|
|
||||||
|
for ( edge = edges; edge < edge_limit; edge++ )
|
||||||
|
{
|
||||||
|
seg = edge->first;
|
||||||
|
if ( seg )
|
||||||
|
do
|
||||||
|
{
|
||||||
|
seg->edge = edge;
|
||||||
|
seg = seg->edge_next;
|
||||||
|
}
|
||||||
|
while ( seg != edge->first );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now, compute each edge properties */
|
||||||
|
for ( edge = edges; edge < edge_limit; edge++ )
|
||||||
|
{
|
||||||
|
FT_Int is_round = 0; /* does it contain round segments? */
|
||||||
|
FT_Int is_straight = 0; /* does it contain straight segments? */
|
||||||
|
FT_Pos ups = 0; /* number of upwards segments */
|
||||||
|
FT_Pos downs = 0; /* number of downwards segments */
|
||||||
|
|
||||||
|
|
||||||
|
seg = edge->first;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
seg->edge = edge;
|
FT_Bool is_serif;
|
||||||
seg = seg->edge_next;
|
|
||||||
}
|
|
||||||
while ( seg != edge->first );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now, compute each edge properties */
|
|
||||||
for ( edge = edges; edge < edge_limit; edge++ )
|
|
||||||
{
|
|
||||||
FT_Int is_round = 0; /* does it contain round segments? */
|
|
||||||
FT_Int is_straight = 0; /* does it contain straight segments? */
|
|
||||||
FT_Pos ups = 0; /* number of upwards segments */
|
|
||||||
FT_Pos downs = 0; /* number of downwards segments */
|
|
||||||
|
|
||||||
|
|
||||||
seg = edge->first;
|
/* check for roundness of segment */
|
||||||
|
if ( seg->flags & AF_EDGE_ROUND )
|
||||||
|
is_round++;
|
||||||
|
else
|
||||||
|
is_straight++;
|
||||||
|
|
||||||
do
|
/* check for segment direction */
|
||||||
{
|
if ( seg->dir == up_dir )
|
||||||
FT_Bool is_serif;
|
ups += seg->max_coord-seg->min_coord;
|
||||||
|
else
|
||||||
|
downs += seg->max_coord-seg->min_coord;
|
||||||
|
|
||||||
|
/* check for links -- if seg->serif is set, then seg->link must */
|
||||||
|
/* be ignored */
|
||||||
|
is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge );
|
||||||
|
|
||||||
/* check for roundness of segment */
|
if ( seg->link || is_serif )
|
||||||
if ( seg->flags & AF_EDGE_ROUND )
|
|
||||||
is_round++;
|
|
||||||
else
|
|
||||||
is_straight++;
|
|
||||||
|
|
||||||
/* check for segment direction */
|
|
||||||
if ( seg->dir == up_dir )
|
|
||||||
ups += seg->max_coord-seg->min_coord;
|
|
||||||
else
|
|
||||||
downs += seg->max_coord-seg->min_coord;
|
|
||||||
|
|
||||||
/* check for links -- if seg->serif is set, then seg->link must */
|
|
||||||
/* be ignored */
|
|
||||||
is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge );
|
|
||||||
|
|
||||||
if ( seg->link || is_serif )
|
|
||||||
{
|
|
||||||
AF_Edge edge2;
|
|
||||||
AF_Segment seg2;
|
|
||||||
|
|
||||||
|
|
||||||
edge2 = edge->link;
|
|
||||||
seg2 = seg->link;
|
|
||||||
|
|
||||||
if ( is_serif )
|
|
||||||
{
|
{
|
||||||
seg2 = seg->serif;
|
AF_Edge edge2;
|
||||||
edge2 = edge->serif;
|
AF_Segment seg2;
|
||||||
}
|
|
||||||
|
|
||||||
if ( edge2 )
|
|
||||||
{
|
|
||||||
FT_Pos edge_delta;
|
|
||||||
FT_Pos seg_delta;
|
|
||||||
|
|
||||||
|
|
||||||
edge_delta = edge->fpos - edge2->fpos;
|
edge2 = edge->link;
|
||||||
if ( edge_delta < 0 )
|
seg2 = seg->link;
|
||||||
edge_delta = -edge_delta;
|
|
||||||
|
|
||||||
seg_delta = seg->pos - seg2->pos;
|
if ( is_serif )
|
||||||
if ( seg_delta < 0 )
|
{
|
||||||
seg_delta = -seg_delta;
|
seg2 = seg->serif;
|
||||||
|
edge2 = edge->serif;
|
||||||
|
}
|
||||||
|
|
||||||
if ( seg_delta < edge_delta )
|
if ( edge2 )
|
||||||
|
{
|
||||||
|
FT_Pos edge_delta;
|
||||||
|
FT_Pos seg_delta;
|
||||||
|
|
||||||
|
|
||||||
|
edge_delta = edge->fpos - edge2->fpos;
|
||||||
|
if ( edge_delta < 0 )
|
||||||
|
edge_delta = -edge_delta;
|
||||||
|
|
||||||
|
seg_delta = seg->pos - seg2->pos;
|
||||||
|
if ( seg_delta < 0 )
|
||||||
|
seg_delta = -seg_delta;
|
||||||
|
|
||||||
|
if ( seg_delta < edge_delta )
|
||||||
|
edge2 = seg2->edge;
|
||||||
|
}
|
||||||
|
else
|
||||||
edge2 = seg2->edge;
|
edge2 = seg2->edge;
|
||||||
|
|
||||||
|
if ( is_serif )
|
||||||
|
{
|
||||||
|
edge->serif = edge2;
|
||||||
|
edge2->flags |= AF_EDGE_SERIF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
edge->link = edge2;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
edge2 = seg2->edge;
|
|
||||||
|
|
||||||
if ( is_serif )
|
seg = seg->edge_next;
|
||||||
{
|
|
||||||
edge->serif = edge2;
|
|
||||||
edge2->flags |= AF_EDGE_SERIF;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
edge->link = edge2;
|
|
||||||
}
|
|
||||||
|
|
||||||
seg = seg->edge_next;
|
} while ( seg != edge->first );
|
||||||
|
|
||||||
} while ( seg != edge->first );
|
/* set the round/straight flags */
|
||||||
|
edge->flags = AF_EDGE_NORMAL;
|
||||||
|
|
||||||
/* set the round/straight flags */
|
if ( is_round > 0 && is_round >= is_straight )
|
||||||
edge->flags = AF_EDGE_NORMAL;
|
edge->flags |= AF_EDGE_ROUND;
|
||||||
|
|
||||||
if ( is_round > 0 && is_round >= is_straight )
|
/* set the edge's main direction */
|
||||||
edge->flags |= AF_EDGE_ROUND;
|
edge->dir = AF_DIR_NONE;
|
||||||
|
|
||||||
/* set the edge's main direction */
|
if ( ups > downs )
|
||||||
edge->dir = AF_DIR_NONE;
|
edge->dir = up_dir;
|
||||||
|
|
||||||
if ( ups > downs )
|
else if ( ups < downs )
|
||||||
edge->dir = up_dir;
|
edge->dir = -up_dir;
|
||||||
|
|
||||||
else if ( ups < downs )
|
else if ( ups == downs )
|
||||||
edge->dir = -up_dir;
|
edge->dir = 0; /* both up and down! */
|
||||||
|
|
||||||
else if ( ups == downs )
|
/* gets rid of serifs if link is set */
|
||||||
edge->dir = 0; /* both up and down! */
|
/* XXX: This gets rid of many unpleasant artefacts! */
|
||||||
|
/* Example: the `c' in cour.pfa at size 13 */
|
||||||
|
|
||||||
/* gets rid of serifs if link is set */
|
if ( edge->serif && edge->link )
|
||||||
/* XXX: This gets rid of many unpleasant artefacts! */
|
edge->serif = 0;
|
||||||
/* Example: the `c' in cour.pfa at size 13 */
|
}
|
||||||
|
|
||||||
if ( edge->serif && edge->link )
|
|
||||||
edge->serif = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Exit:
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FT_LOCAL_DEF( void )
|
FT_LOCAL_DEF( FT_Error )
|
||||||
af_latin_hints_detect_features( AF_GlyphHints hints,
|
af_latin_hints_detect_features( AF_GlyphHints hints,
|
||||||
AF_Dimension dim )
|
AF_Dimension dim )
|
||||||
{
|
{
|
||||||
af_latin_hints_compute_segments( hints, dim );
|
FT_Error error;
|
||||||
af_latin_hints_link_segments ( hints, dim );
|
|
||||||
af_latin_hints_compute_edges ( hints, dim );
|
error = af_latin_hints_compute_segments( hints, dim );
|
||||||
|
if ( !error )
|
||||||
|
{
|
||||||
|
af_latin_hints_link_segments ( hints, dim );
|
||||||
|
error = af_latin_hints_compute_edges ( hints, dim );
|
||||||
|
}
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1812,11 +1831,18 @@
|
||||||
/* analyze glyph outline
|
/* analyze glyph outline
|
||||||
*/
|
*/
|
||||||
if ( AF_HINTS_DO_HORIZONTAL(hints) )
|
if ( AF_HINTS_DO_HORIZONTAL(hints) )
|
||||||
af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ );
|
{
|
||||||
|
error = af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ );
|
||||||
|
if ( error )
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
if ( AF_HINTS_DO_VERTICAL(hints) )
|
if ( AF_HINTS_DO_VERTICAL(hints) )
|
||||||
{
|
{
|
||||||
af_latin_hints_detect_features( hints, AF_DIMENSION_VERT );
|
error = af_latin_hints_detect_features( hints, AF_DIMENSION_VERT );
|
||||||
|
if ( error )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
af_latin_hints_compute_blue_edges( hints, metrics );
|
af_latin_hints_compute_blue_edges( hints, metrics );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ FT_BEGIN_HEADER
|
||||||
/* this shouldn't normally be exported. However, other scripts might
|
/* this shouldn't normally be exported. However, other scripts might
|
||||||
* like to use this function as-is
|
* like to use this function as-is
|
||||||
*/
|
*/
|
||||||
FT_LOCAL( void )
|
FT_LOCAL( FT_Error )
|
||||||
af_latin_hints_compute_segments( AF_GlyphHints hints,
|
af_latin_hints_compute_segments( AF_GlyphHints hints,
|
||||||
AF_Dimension dim );
|
AF_Dimension dim );
|
||||||
|
|
||||||
|
@ -154,11 +154,11 @@ FT_BEGIN_HEADER
|
||||||
/* this shouldn't normally be exported. However, other scripts might
|
/* this shouldn't normally be exported. However, other scripts might
|
||||||
* want to use this function as-is
|
* want to use this function as-is
|
||||||
*/
|
*/
|
||||||
FT_LOCAL( void )
|
FT_LOCAL( FT_Error )
|
||||||
af_latin_hints_compute_edges( AF_GlyphHints hints,
|
af_latin_hints_compute_edges( AF_GlyphHints hints,
|
||||||
AF_Dimension dim );
|
AF_Dimension dim );
|
||||||
|
|
||||||
FT_LOCAL( void )
|
FT_LOCAL( FT_Error )
|
||||||
af_latin_hints_detect_features( AF_GlyphHints hints,
|
af_latin_hints_detect_features( AF_GlyphHints hints,
|
||||||
AF_Dimension dim );
|
AF_Dimension dim );
|
||||||
|
|
||||||
|
|
|
@ -449,10 +449,10 @@
|
||||||
{
|
{
|
||||||
loader->metrics = metrics;
|
loader->metrics = metrics;
|
||||||
|
|
||||||
metrics->scaler = scaler;
|
|
||||||
|
|
||||||
if ( metrics->clazz->script_metrics_scale )
|
if ( metrics->clazz->script_metrics_scale )
|
||||||
metrics->clazz->script_metrics_scale( metrics, &scaler );
|
metrics->clazz->script_metrics_scale( metrics, &scaler );
|
||||||
|
else
|
||||||
|
metrics->scaler = scaler;
|
||||||
|
|
||||||
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM;
|
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM;
|
||||||
load_flags &= ~FT_LOAD_RENDER;
|
load_flags &= ~FT_LOAD_RENDER;
|
||||||
|
|
Loading…
Reference in New Issue