* src/autofit/*: more updates

LAYOUT
David Turner 21 years ago
parent 0b58b0a94c
commit 25f45461ed
  1. 4
      ChangeLog
  2. 8
      README
  3. 2
      builds/unix/configure.ac
  4. 1
      docs/VERSION.DLL
  5. 2
      include/freetype/freetype.h
  6. 27
      src/autofit/afangles.c
  7. 231
      src/autofit/afglobal.c
  8. 42
      src/autofit/afglobal.h
  9. 495
      src/autofit/afhints.c
  10. 88
      src/autofit/afhints.h
  11. 1196
      src/autofit/aflatin.c
  12. 109
      src/autofit/aflatin.h
  13. 144
      src/autofit/aftypes.h

@ -1,3 +1,7 @@
2003-11-22 David Turner <david@freetype.org>
* src/autofit/*: more updates
2003-11-13 John A. Boyd Jr. <jaboydjr@netwalk.com>
* src/bdf/bdfdrivr.c (bdf_interpret_style), src/pcf/pcfread.c

@ -9,7 +9,7 @@
is called `libttf'. They are *not* compatible!
FreeType 2.1.7
FreeType 2.1.8
==============
Please read the docs/CHANGES file, it contains IMPORTANT INFORMATION.
@ -19,9 +19,9 @@
Note that the FreeType 2 documentation is now available as a
separate package from our sites. See:
ftp://ftp.freetype.org/pub/freetype2/ftdocs-2.1.7.tar.bz2
ftp://ftp.freetype.org/pub/freetype2/ftdocs-2.1.7.tar.gz
ftp://ftp.freetype.org/pub/freetype2/ftdoc216.zip
ftp://ftp.freetype.org/pub/freetype2/ftdocs-2.1.8.tar.bz2
ftp://ftp.freetype.org/pub/freetype2/ftdocs-2.1.8.tar.gz
ftp://ftp.freetype.org/pub/freetype2/ftdoc218.zip
Bugs

@ -8,7 +8,7 @@ AC_CONFIG_SRCDIR([ftconfig.in])
# Don't forget to update docs/VERSION.DLL!
version_info='9:5:3'
version_info='9:6:3'
AC_SUBST([version_info])
ft_version=`echo $version_info | tr : .`
AC_SUBST([ft_version])

@ -52,6 +52,7 @@ systems, but not all of them:
release libtool so
-------------------------------
2.1.8 9.6.3 6.3.6
2.1.7 9.5.3 6.3.5
2.1.6 9.5.3 6.3.5
2.1.5 9.4.3 6.3.4

@ -44,7 +44,7 @@
/* */
#define FREETYPE_MAJOR 2
#define FREETYPE_MINOR 1
#define FREETYPE_PATCH 7
#define FREETYPE_PATCH 8
#include <ft2build.h>

@ -9,6 +9,7 @@
90, 64, 38, 20, 10, 5, 3, 1, 1
};
static FT_Int
af_angle_prenorm( FT_Vector* vec )
{
@ -162,3 +163,29 @@
return delta;
}
/* well, this needs to be somewhere, right :-)
*/
FT_LOCAL_DEF( void )
af_sort_pos( FT_UInt count,
FT_Pos* table )
{
FT_Int i, j;
FT_Pos swap;
for ( i = 1; i < count; i++ )
{
for ( j = i; j > 0; j-- )
{
if ( table[j] > table[j - 1] )
break;
swap = table[j];
table[j] = table[j - 1];
table[j - 1] = swap;
}
}
}

@ -0,0 +1,231 @@
#include "afglobal.h"
#include "aflatin.h"
/* populate this list when you add new scripts
*/
static AF_ScriptClass const af_script_class_list[] =
{
& af_latin_script_class,
NULL /* do not remove */
};
#define AF_SCRIPT_LIST_DEFAULT 0 /* index of default script in 'af_script_class_list' */
#define AF_SCRIPT_LIST_NONE 255 /* indicates an uncovered glyph */
/*
* note that glyph_scripts[] is used to map each glyph into
* an index into the 'af_script_class_list' array.
*
*/
typedef struct AF_FaceGlobalsRec_
{
FT_Face face;
FT_UInt glyph_count; /* same as face->num_glyphs */
FT_Byte* glyph_scripts;
AF_ScriptMetrics metrics[ AF_SCRIPT_MAX ];
} AF_FaceGlobalsRec, *AF_FaceGlobals;
/* this function is used to compute the script index of each glyph
* within a given face
*/
static FT_Error
af_face_globals_compute_script_coverage( AF_FaceGlobals globals )
{
FT_Error error = 0;
FT_Face face = globals->face;
FT_CharMap old_charmap = face->charmap;
FT_Byte* gscripts = globals->glyph_scripts;
FT_UInt ss;
/* the value 255 means "uncovered glyph"
*/
FT_MEM_SET( globals->glyph_scripts,
AF_SCRIPT_LIST_NONE,
globals->glyph_count );
error = FT_Select_Charmap( face, FT_ENCODING_UNICODE );
if ( error )
{
/* ignore this error, we'll simply use Latin as the standard
* script. XXX: Shouldn't we rather disable hinting ??
*/
error = 0;
goto Exit;
}
/* scan each script in a Unicode charmap
*/
for ( ss = 0; af_script_classes[ss]; ss++ )
{
AF_ScriptClass clazz = af_script_classes[ss];
AF_Script_UniRange range;
/* scan all unicode points in the range, and set the corresponding
* glyph script index
*/
for ( range = clazz->script_uni_ranges; range->first != 0; range++ )
{
FT_ULong charcode = range->first;
FT_UInt gindex;
gindex = FT_Get_Char_Index( face, charcode );
if ( gindex != 0 &&
gindex < globals->glyph_count &&
gscripts[ gindex ] == AF_SCRIPT_LIST_NONE )
{
gscripts[ gindex ] = (FT_Byte) ss;
}
for (;;)
{
charcode = FT_Get_Next_Char( face, charcode, &gindex );
if ( gindex == 0 || charcode > range->last )
break;
if ( gindex < globals->glyph_count &&
gscripts[ gindex ] == AF_SCRIPT_LIST_NONE )
{
gscripts[ gindex ] = (FT_Byte) ss;
}
}
}
}
Exit:
/* by default, all uncovered glyphs are set to the latin script
* XXX: shouldnt' we disable hinting or do something similar ?
*/
{
FT_UInt nn;
for ( nn = 0; nn < globals->glyph_count; nn++ )
{
if ( gscripts[ nn ] == AF_SCRIPT_LIST_NONE )
gscripts[ nn ] = AF_SCRIPT_LIST_DEFAULT;
}
}
FT_Set_Charmap( face, old_charmap );
return error;
}
FT_LOCAL_DEF( FT_Error )
af_face_globals_new( FT_Face face,
AF_FaceGlobals *aglobals )
{
FT_Error error;
FT_Memory memory;
AF_FaceGlobals globals;
memory = face->memory;
if ( !FT_ALLOC( globals, sizeof(*globals) +
face->num_glyphs*sizeof(FT_Byte) ) )
{
globals->face = face;
globals->glyph_count = face->num_glyphs;
globals->glyph_scripts = (FT_Byte*)( globals+1 );
error = af_face_globals_compute_script_coverage( globals );
if ( error )
{
af_face_globals_free( globals );
globals = NULL;
}
}
Exit:
*aglobals = globals;
return error;
}
FT_LOCAL_DEF( void )
af_face_globals_free( AF_FaceGlobals globals )
{
if ( globals )
{
FT_Memory memory = globals->face->memory;
FT_UInt nn;
for ( nn = 0; nn < AF_SCRIPT_MAX; nn++ )
{
if ( globals->metrics[nn] )
{
AF_ScriptClass clazz = af_script_classes[nn];
FT_ASSERT( globals->metrics[nn].clazz == clazz );
if ( clazz->script_metrics_done )
clazz->script_metrics_done( globals->metrics[nn] );
FT_FREE( globals->metrics[nn] );
}
}
globals->glyph_count = NULL;
globals->glyph_scripts = NULL; /* no need to free this one !! */
globals->face = NULL;
FT_FREE( globals );
}
}
FT_LOCAL_DEF( FT_Error )
af_face_globals_get_metrics( AF_FaceGlobals globals,
FT_UInt gindex,
AF_ScriptMetrics *ametrics )
{
FT_Script script;
AF_ScriptMetrics metrics = NULL;
FT_UInt index;
AF_ScriptClass clazz;
FT_Error error;
if ( gindex >= globals->glyph_count )
{
error = FT_Err_Invalid_Argument;
goto Exit;
}
index = globals->glyph_scripts[ gindex ];
clazz = af_script_class_list[ index ];
metrics = globals->metrics[ clazz->script ];
if ( metrics == NULL )
{
/* create the global metrics object when needed
*/
if ( FT_ALLOC( metrics, clazz->script_metrics_size ) )
goto Exit;
metrics->clazz = clazz;
if ( clazz->script_metrics_init )
{
error = clazz->script_metrics_init( metrics, face );
if ( error )
{
if ( clazz->script_metrics_done )
clazz->script_metrics_done( metrics );
FT_FREE( metrics );
goto Exit;
}
}
globals->metrics[ script ] = metrics;
}
Exit:
*ametrics = metrics;
return error;
}

@ -0,0 +1,42 @@
#ifndef __AF_GLOBAL_H__
#define __AF_GLOBAL_H__
#include "aftypes.h"
FT_BEGIN_HEADER
/**************************************************************************/
/**************************************************************************/
/***** *****/
/***** F A C E G L O B A L S *****/
/***** *****/
/**************************************************************************/
/**************************************************************************/
/*
* models the global hints data for a given face, decomposed into
* script-specific items..
*
*/
typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals;
FT_LOCAL( FT_Error )
af_face_globals_new( FT_Face face,
AF_FaceGlobals *aglobals );
FT_LOCAL( FT_Error )
af_face_globals_get_metrics( AF_FaceGlobals globals,
FT_UInt gindex,
AF_ScriptMetrics *ametrics );
FT_LOCAL( void )
af_face_globals_free( AF_FaceGlobals globals );
/* */
FT_END_HEADER
#endif /* __AF_GLOBALS_H__ */

@ -5,7 +5,7 @@
#include <stdio.h>
void
af_outline_hints_dump_edges( AF_OutlineHints hints )
af_glyph_hints_dump_edges( AF_GlyphHints hints )
{
AF_Edge edges;
AF_Edge edge_limit;
@ -57,7 +57,7 @@
/* A function used to dump the array of linked segments */
void
af_outline_hints_dump_segments( AF_OutlineHints hints )
af_glyph_hints_dump_segments( AF_GlyphHints hints )
{
AF_Segment segments;
AF_Segment segment_limit;
@ -139,15 +139,12 @@
/* compute all inflex points in a given glyph */
static void
af_outline_hints_compute_inflections( AF_OutlineHints hints )
af_glyph_hints_compute_inflections( AF_GlyphHints hints )
{
AF_Point* contour = hints->contours;
AF_Point* contour_limit = contour + hints->num_contours;
/* load original coordinates in (u,v) */
af_outline_hints_setup_uv( hints, outline, AF_UV_FXY );
/* do each contour separately */
for ( ; contour < contour_limit; contour++ )
{
@ -172,10 +169,10 @@
if ( end == first )
goto Skip;
} while ( end->u == first->u && end->v == first->v );
} while ( end->fx == first->fx && end->fy == first->fy );
angle_seg = af_angle( end->u - start->u,
end->v - start->v );
angle_seg = af_angle( end->fx - start->fx,
end->fy - start->fy );
/* extend the segment start whenever possible */
before = start;
@ -188,10 +185,10 @@
if ( before == first )
goto Skip;
} while ( before->u == start->u && before->v == start->v );
} while ( before->fx == start->fx && before->fy == start->fy );
angle_in = af_angle( start->u - before->u,
start->v - before->v );
angle_in = af_angle( start->fx - before->fx,
start->fy - before->fy );
} while ( angle_in == angle_seg );
@ -212,12 +209,12 @@
if ( after == first )
finished = 1;
} while ( end->u == after->u && end->v == after->v );
} while ( end->fx == after->fx && end->fy == after->fy );
vec.x = after->u - end->u;
vec.y = after->v - end->v;
angle_out = af_angle( after->u - end->u,
after->v - end->v );
vec.x = after->fx - end->fx;
vec.y = after->fy - end->fy;
angle_out = af_angle( after->fx - end->fx,
after->fy - end->fy );
} while ( angle_out == angle_seg );
@ -252,17 +249,17 @@
FT_LOCAL_DEF( void )
af_outline_hints_init( AF_OutlineHints hints,
FT_Memory memory )
af_glyph_hints_init( AF_GlyphHints hints,
FT_Memory memory )
{
FT_ZERO( hints );
hints->memory = memory;
}
}
FT_LOCAL_DEF( void )
af_outline_hints_done( AF_OutlineHints hints )
af_glyph_hints_done( AF_GlyphHints hints )
{
if ( hints && hints->memory )
{
@ -275,7 +272,7 @@
for ( dim = 0; dim < 2; dim++ )
{
AF_AxisHints axis = &hints->axis[ dim ];
axis->num_segments = 0;
axis->num_edges = 0;
axis->segments = NULL;
@ -285,11 +282,11 @@
FT_FREE( hints->contours );
hints->max_contours = 0;
hints->num_contours = 0;
FT_FREE( hints->points );
hints->num_points = 0;
hints->max_points = 0;
hints->memory = NULL;
}
}
@ -297,23 +294,25 @@
FT_LOCAL_DEF( FT_Error )
af_outline_hints_reset( AF_OutlineHints hints,
FT_Outline* outline,
FT_Fixed x_scale,
FT_Fixed y_scale )
af_glyph_hints_reset( AF_GlyphHints hints,
FT_Outline* outline,
FT_Fixed x_scale,
FT_Fixed y_scale,
FT_Pos x_delta,
FT_Pos y_delta )
{
FT_Error error = AF_Err_Ok;
FT_UInt old_max, new_max;
hints->num_points = 0;
hints->num_contours = 0;
hints->axis[0].num_segments = 0;
hints->axis[0].num_edges = 0;
hints->axis[1].num_segments = 0;
hints->axis[1].num_edges = 0;
/* first of all, reallocate the contours array when necessary
*/
new_max = (FT_UInt) outline->n_contours;
@ -321,34 +320,34 @@
if ( new_max > old_max )
{
new_max = (new_max + 3) & ~3;
if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
goto Exit;
hints->max_contours = new_max;
}
/* then, reallocate the points, segments & edges arrays if needed --
* note that we reserved two additional point positions, used to
* hint metrics appropriately
*/
/* then, reallocate the points, segments & edges arrays if needed --
* note that we reserved two additional point positions, used to
* hint metrics appropriately
*/
new_max = (FT_UInt)( outline->n_points + 2 );
old_max = hints->max_points;
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
* - an array of 2*N AF_EdgeRec items
*
*/
new_max = ( new_max + 2 + 7 ) & ~7;
#undef OFF_INCREMENT
#define OFF_INCREMENT( _off, _type, _count ) \
((((_off) + sizeof(_type)) & ~(sizeof(_type)) + ((_count)*sizeof(_type)))
@ -368,15 +367,15 @@
hints->axis[1].edges = NULL;
goto Exit;
}
/* readjust some pointers
*/
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;
}
@ -422,8 +421,8 @@
{
point->fx = vec->x;
point->fy = vec->y;
point->ox = point->x = FT_MulFix( vec->x, x_scale );
point->oy = point->y = FT_MulFix( vec->y, y_scale );
point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;
point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta;
switch ( FT_CURVE_TAG( *tag ) )
{
@ -503,7 +502,7 @@
prev = point->prev;
in_x = point->fx - prev->fx;
in_y = point->fy - prev->fy;
point->in_dir = af_compute_direction( in_x, in_y );
next = point->next;
@ -539,88 +538,400 @@
}
/* compute inflection points
*/
af_outline_hints_compute_inflections( hints );
*/
af_glyph_hints_compute_inflections( hints );
Exit:
return error;
}
/*
*
* E D G E P O I N T G R I D - F I T T I N G
*
*/
FT_LOCAL_DEF( void )
af_outline_hints_setup_uv( AF_OutlineHints hints,
AF_UV source )
af_glyph_hints_align_edge_points( AF_GlyphHints hints,
AF_Dimension dim )
{
AF_Point point = hints->points;
AF_Point point_limit = point + hints->num_points;
AF_AxisHints axis = & hints->axis[ dim ];
AF_Edge edges = axis->edges;
AF_Edge edge_limit = edges + axis->num_edges;
AF_Edge edge;
switch ( source )
for ( edge = edges; edge < edge_limit; edge++ )
{
case AF_UV_FXY:
for ( ; point < point_limit; point++ )
/* move the points of each segment */
/* in each edge to the edge's position */
AF_Segment seg = edge->first;
do
{
point->u = point->fx;
point->v = point->fy;
}
break;
AF_Point point = seg->first;
for (;;)
{
if ( dim == AF_DIMENSION_HORZ )
{
point->x = edge->pos;
point->flags |= AF_FLAG_TOUCH_X;
}
else
{
point->y = edge->pos;
point->flags |= AF_FLAG_TOUCH_Y;
}
if ( point == seg->last )
break;
point = point->next;
}
seg = seg->edge_next;
} while ( seg != edge->first );
}
}
/*
*
* S T R O N G P O I N T I N T E R P O L A T I O N
*
*/
/* hint the strong points -- this is equivalent to the TrueType `IP' */
/* hinting instruction */
FT_LOCAL_DEF( void )
af_glyph_hints_align_strong_points( AF_GlyphHints hints,
AF_Dimension dim )
{
AF_Point points = hints->points;
AF_Point point_limit = points + hints->num_points;;
AF_AxisHints axis = &hints->axis[dim];
AF_Edge edges = axis->edges;
AF_Edge edge_limit = edges + axis->num_edges;
AF_Flags touch_flag;
AF_Point point;
AF_Edge edge;
if ( dim == AF_DIMENSION_HORZ )
touch_flag = AF_FLAG_TOUCH_X;
else
touch_flag = AF_FLAG_TOUCH_Y;
if ( edges < edge_limit )
{
AF_Point point;
AF_Edge edge;
case AF_UV_FYX:
for ( ; point < point_limit; point++ )
for ( point = points; point < point_limit; point++ )
{
point->u = point->fy;
point->v = point->fx;
FT_Pos u, ou, fu; /* point position */
FT_Pos delta;
if ( point->flags & touch_flag )
continue;
/* if this point is candidate to weak interpolation, we will */
/* interpolate it after all strong points have been processed */
if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) &&
!( point->flags & AF_FLAG_INFLECTION ) )
continue;
if ( dimension )
{
u = point->fy;
ou = point->oy;
}
else
{
u = point->fx;
ou = point->ox;
}
fu = u;
/* is the point before the first edge? */
edge = edges;
delta = edge->fpos - u;
if ( delta >= 0 )
{
u = edge->pos - ( edge->opos - ou );
goto Store_Point;
}
/* is the point after the last edge? */
edge = edge_limit - 1;
delta = u - edge->fpos;
if ( delta >= 0 )
{
u = edge->pos + ( ou - edge->opos );
goto Store_Point;
}
{
FT_UInt min, max, mid;
FT_Pos fpos;
/* find enclosing edges */
min = 0;
max = edge_limit - edges;
while ( min < max )
{
mid = ( max + min ) >> 1;
edge = edges + mid;
fpos = edge->fpos;
if ( u < fpos )
max = mid;
else if ( u > fpos )
min = mid + 1;
else
{
/* we are on the edge */
u = edge->pos;
goto Store_Point;
}
}
{
AF_Edge before = edges + min - 1;
AF_Edge after = edges + min + 0;
/* assert( before && after && before != after ) */
if ( before->scale == 0 )
before->scale = FT_DivFix( after->pos - before->pos,
after->fpos - before->fpos );
u = before->pos + FT_MulFix( fu - before->fpos,
before->scale );
}
}
Store_Point:
/* save the point position */
if ( dim == AF_DIMENSION_HORZ )
point->x = u;
else
point->y = u;
point->flags |= touch_flag;
}
break;
}
}
/*
*
* W E A K P O I N T I N T E R P O L A T I O N
*
*/
static void
af_iup_shift( AF_Point p1,
AF_Point p2,
AF_Point ref )
{
AF_Point p;
FT_Pos delta = ref->u - ref->v;
case AF_UV_OXY:
for ( ; point < point_limit; point++ )
for ( p = p1; p < ref; p++ )
p->u = p->v + delta;
for ( p = ref + 1; p <= p2; p++ )
p->u = p->v + delta;
}
static void
af_iup_interp( AF_Point p1,
AF_Point p2,
AF_Point ref1,
AF_Point ref2 )
{
AF_Point p;
FT_Pos u;
FT_Pos v1 = ref1->v;
FT_Pos v2 = ref2->v;
FT_Pos d1 = ref1->u - v1;
FT_Pos d2 = ref2->u - v2;
if ( p1 > p2 )
return;
if ( v1 == v2 )
{
for ( p = p1; p <= p2; p++ )
{
point->u = point->ox;
point->v = point->oy;
u = p->v;
if ( u <= v1 )
u += d1;
else
u += d2;
p->u = u;
}
break;
return;
}
case AF_UV_OYX:
for ( ; point < point_limit; point++ )
if ( v1 < v2 )
{
for ( p = p1; p <= p2; p++ )
{
point->u = point->oy;
point->v = point->ox;
}
break;
u = p->v;
case AF_UV_YX:
for ( ; point < point_limit; point++ )
if ( u <= v1 )
u += d1;
else if ( u >= v2 )
u += d2;
else
u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
p->u = u;
}
}
else
{
for ( p = p1; p <= p2; p++ )
{
point->u = point->y;
point->v = point->x;
u = p->v;
if ( u <= v2 )
u += d2;
else if ( u >= v1 )
u += d1;
else
u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
p->u = u;
}
break;
}
}
FT_LOCAL_DEF( void )
af_glyph_hints_align_weak_points( AF_GlyphHints hints,
AF_Dimension dim )
{
AF_Point points = hints->points;
AF_Point point_limit = points + hints->num_points;
AF_Point* contour = hints->contours;
AF_Point* contour_limit = contour + hints->num_contours;
AF_Flags touch_flag;
AF_Point point;
AF_Point end_point;
AF_Point first_point;
case AF_UV_OX:
for ( ; point < point_limit; point++ )
/* PASS 1: Move segment points to edge positions */
if ( dim == AF_DIMENSION_HORZ )
{
touch_flag = AF_FLAG_TOUCH_X;
for ( point = points; point < point_limit; point++ )
{
point->u = point->x;
point->v = point->ox;
}
break;
}
else
{
touch_flag = AF_FLAG_TOUCH_Y;
case AF_UV_OY:
for ( ; point < point_limit; point++ )
for ( point = points; point < point_limit; points++ )
{
point->u = point->y;
point->v = point->oy;
}
break;
}
point = points;
for ( ; contour < contour_limit; contour++ )
{
point = *contour;
end_point = point->prev;
first_point = point;
default:
for ( ; point < point_limit; point++ )
while ( point <= end_point && !( point->flags & touch_flag ) )
point++;
if ( point <= end_point )
{
point->u = point->x;
point->v = point->y;
AF_Point first_touched = point;
AF_Point cur_touched = point;
point++;
while ( point <= end_point )
{
if ( point->flags & touch_flag )
{
/* we found two successive touched points; we interpolate */
/* all contour points between them */
af_iup_interp( cur_touched + 1, point - 1,
cur_touched, point );
cur_touched = point;
}
point++;
}
if ( cur_touched == first_touched )
{
/* this is a special case: only one point was touched in the */
/* contour; we thus simply shift the whole contour */
af_iup_shift( first_point, end_point, cur_touched );
}
else
{
/* now interpolate after the last touched point to the end */
/* of the contour */
af_iup_interp( cur_touched + 1, end_point,
cur_touched, first_touched );
/* if the first contour point isn't touched, interpolate */
/* from the contour start to the first touched point */
if ( first_touched > points )
af_iup_interp( first_point, first_touched - 1,
cur_touched, first_touched );
}
}
}
/* now save the interpolated values back to x/y */
if ( dim == AF_DIMENSION_HORZ )
{
for ( point = points; point < point_limit; point++ )
point->x = point->u;
}
else
{
for ( point = points; point < point_limit; point++ )
point->y = point->u;
}
}

@ -6,8 +6,8 @@
FT_BEGIN_HEADER
/*
* The definition of outline hints. These are shared by all
* script analysis routines
* The definition of outline glyph hints. These are shared by all
* script analysis routines (until now)
*
*/
@ -17,7 +17,7 @@ FT_BEGIN_HEADER
AF_DIMENSION_VERT = 1, /* y coordinates, i.e. horizontal segments & edges */
AF_DIMENSION_MAX /* do not remove */
} AF_Dimension;
@ -30,7 +30,7 @@ FT_BEGIN_HEADER
AF_DIR_LEFT = -1,
AF_DIR_UP = 2,
AF_DIR_DOWN = -2
} AF_Direction;
@ -38,32 +38,32 @@ FT_BEGIN_HEADER
typedef enum
{
AF_FLAG_NONE = 0,
/* point type flags */
AF_FLAG_CONIC = (1 << 0),
AF_FLAG_CUBIC = (1 << 1),
AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC,
/* point extremum flags */
AF_FLAG_EXTREMA_X = (1 << 2),
AF_FLAG_EXTREMA_Y = (1 << 3),
/* point roundness flags */
AF_FLAG_ROUND_X = (1 << 4),
AF_FLAG_ROUND_Y = (1 << 5),
/* point touch flags */
AF_FLAG_TOUCH_X = (1 << 6),
AF_FLAG_TOUCH_Y = (1 << 7),
/* candidates for weak interpolation have this flag set */
AF_FLAG_WEAK_INTERPOLATION = (1 << 8),
/* all inflection points in the outline have this flag set */
AF_FLAG_INFLECTION = (1 << 9)
} AF_Flags;
/* edge hint flags */
typedef enum
@ -72,7 +72,7 @@ FT_BEGIN_HEADER
AF_EDGE_ROUND = (1 << 0),
AF_EDGE_SERIF = (1 << 1),
AF_EDGE_DONE = (1 << 2)
} AF_Edge_Flags;
@ -110,10 +110,10 @@ FT_BEGIN_HEADER
AF_Edge edge; /* the segment's parent edge */
AF_Segment edge_next; /* link to next segment in parent edge */
AF_Segment link; /* link segment */
AF_Segment link; /* (stem) link segment */
AF_Segment serif; /* primary segment for serifs */
FT_Pos num_linked; /* number of linked segments */
FT_Pos score;
FT_Pos score; /* used during stem matching */
AF_Point first; /* first point in edge segment */
AF_Point last; /* last point in edge segment */
@ -131,7 +131,7 @@ FT_BEGIN_HEADER
AF_Edge_Flags flags; /* edge flags */
AF_Direction dir; /* edge direction */
FT_Fixed scale; /* used to speed up interpolation between edges */
FT_Pos* blue_edge; /* non-NULL if this is a blue edge */
AF_Width blue_edge; /* non-NULL if this is a blue edge */
AF_Edge link;
AF_Edge serif;
@ -142,7 +142,6 @@ FT_BEGIN_HEADER
AF_Segment first;
AF_Segment last;
} AF_EdgeRec;
@ -150,7 +149,7 @@ FT_BEGIN_HEADER
{
FT_Int num_segments;
AF_Segment segments;
FT_Int num_edges;
AF_Edge edges;
@ -158,8 +157,8 @@ FT_BEGIN_HEADER
} AF_AxisHintsRec, *AF_AxisHints;
typedef struct AF_OutlineHintsRec_
typedef struct AF_GlyphHintsRec_
{
FT_Memory memory;
@ -177,7 +176,7 @@ FT_BEGIN_HEADER
AF_AxisHintsRec axis[ AF_DIMENSION_MAX ];
} AF_OutlineHintsRec;
} AF_GlyphHintsRec;
@ -188,43 +187,36 @@ FT_BEGIN_HEADER
FT_LOCAL( void )
af_outline_hints_init( AF_OutlineHints hints );
/* used to set the (u,v) fields of each AF_Point in a AF_OutlineHints
* object.
*/
typedef enum AH_UV_
{
AH_UV_FXY, /* (u,v) = (fx,fy) */
AH_UV_FYX, /* (u,v) = (fy,fx) */
AH_UV_OXY, /* (u,v) = (ox,oy) */
AH_UV_OYX, /* (u,v) = (oy,ox) */
AH_UV_OX, /* (u,v) = (ox,x) */
AH_UV_OY, /* (u,v) = (oy,y) */
AH_UV_YX, /* (u,v) = (y,x) */
AH_UV_XY /* (u,v) = (x,y) * should always be last! */
af_glyph_hints_init( AF_GlyphHints hints,
FT_Memory memory );
} AH_UV;
FT_LOCAL_DEF( void )
af_outline_hints_setup_uv( AF_OutlineHints hints,
AF_UV source );
/* recomputes all AF_Point in a AF_OutlineHints from the definitions
/* recomputes all AF_Point in a AF_GlyphHints from the definitions
* in a source outline
*/
FT_LOCAL( FT_Error )
af_outline_hints_reset( AF_OutlineHints hints,
FT_Outline* outline,
FT_Fixed x_scale,
FT_Fixed y_scale );
af_glyph_hints_reset( AF_GlyphHints hints,
FT_Outline* outline,
FT_Fixed x_scale,
FT_Fixed y_scale,
FT_Pos x_delta,
FT_Pos y_delta );
FT_LOCAL( void )
af_outline_hints_done( AF_OutlineHints hints );
af_glyph_hints_align_edge_points( AF_GlyphHints hints,
AF_Dimension dim );
FT_LOCAL( void )
af_glyph_hints_align_strong_points( AF_GlyphHints hints,
AF_Dimension dim );
FT_LOCAL( void )
af_glyph_hints_align_weak_points( AF_GlyphHints hints,
AF_Dimension dim );
FT_LOCAL( void )
af_glyph_hints_done( AF_GlyphHints hints );
/* */

File diff suppressed because it is too large Load Diff

@ -11,6 +11,14 @@ FT_BEGIN_HEADER
*/
FT_LOCAL( const FT_ScriptClassRec ) af_latin_script_class;
/***************************************************************************/
/***************************************************************************/
/***** *****/
/***** L A T I N G L O B A L M E T R I C S *****/
/***** *****/
/***************************************************************************/
/***************************************************************************/
/*
* the following declarations could be embedded in the file "aflatin.c"
* they've been made semi-public to allow alternate script hinters to
@ -21,29 +29,65 @@ FT_BEGIN_HEADER
* Latin (global) metrics management
*
*/
enum
{
AF_LATIN_BLUE_CAPITAL_TOP,
AF_LATIN_BLUE_CAPITAL_BOTTOM,
AF_LATIN_BLUE_SMALL_F_TOP,
AF_LATIN_BLUE_SMALL_TOP,
AF_LATIN_BLUE_SMALL_BOTTOM,
AF_LATIN_BLUE_SMALL_MINOR,
AF_LATIN_BLUE_MAX
};
#define AF_LATIN_IS_TOP_BLUE( b ) ( (b) == AF_LATIN_BLUE_CAPITAL_TOP || \
(b) == AF_LATIN_BLUE_SMALL_F_TOP || \
(b) == AF_LATIN_BLUE_SMALL_TOP )
#define AF_LATIN_MAX_WIDTHS 16
#define AF_LATIN_MAX_BLUES 32
#define AF_LATIN_MAX_BLUES AF_LATIN_BLUE_MAX
enum
{
AF_LATIN_BLUE_ACTIVE = (1 << 0),
AF_LATIN_BLUE_TOP = (1 << 1),
AF_LATIN_BLUE_MAX
};
typedef struct AF_LatinBlueRec_
{
AF_WidthRec ref;
AF_WidthRec shoot;
FT_UInt flags;
} AF_LatinBlueRec, *AF_LatinBlue;
typedef struct AF_LatinAxisRec_
{
FT_Fixed scale;
FT_Pos delta;
FT_Fixed scale;
FT_Pos delta;
FT_UInt width_count;
AF_WidthRec widths[ AF_LATIN_MAX_WIDTHS ];
FT_UInt width_count;
AF_WidthRec widths[ AF_LATIN_MAX_WIDTHS ];
FT_Pos edge_distance_threshold;
/* ignored for horizontal metrics */
FT_Bool control_overshoot;
FT_UInt blue_count;
AF_WidthRec blue_refs [ AF_MAX_BLUES ];
AF_WidthRec blue_shoots[ AF_MAX_BLUES ];
FT_Bool control_overshoot;
FT_UInt blue_count;
AF_LatinBlueRec blues;
} AF_LatinAxisRec, *AF_LatinAxis;
typedef struct AF_LatinMetricsRec_
{
AF_OutlineMetricsRec root;
AF_ScriptMetricsRec root;
FT_UInt units_per_em;
AF_LatinAxisRec axis[ AF_DIMENSION_MAX ];
} AF_LatinMetricsRec, *AF_LatinMetrics;
@ -58,29 +102,40 @@ FT_BEGIN_HEADER
AF_Scaler scaler );
/*
* Latin (glyph) hints management
*
*/
FT_LOCAL(
/***************************************************************************/
/***************************************************************************/
/***** *****/
/***** L A T I N G L Y P H A N A L Y S I S *****/
/***** *****/
/***************************************************************************/
/***************************************************************************/
FT_LOCAL( void )
af_latin_hints_compute_segments( AF_OutlineHints hints,
AF_Dimension dim );
/* this shouldn't normally be exported. However, other scripts might
* like to use this function as-is
*/
FT_LOCAL( void )
af_latin_hints_link_segments( AF_OutlineHints hints,
AF_Dimension dim );
af_latin_hints_compute_segments( AF_GlyphHints hints,
AF_Dimension dim );
/* this shouldn't normally be exported. However, other scripts might
* want to use this function as-is
*/
FT_LOCAL( void )
af_latin_hints_compute_edges( AF_OutlineHints hints,
AF_Dimension dim );
af_latin_hints_link_segments( AF_GlyphHints hints,
AF_Dimension dim );
/* this shouldn't normally be exported. However, other scripts might
* want to use this function as-is
*/
FT_LOCAL( void )
af_latin_hints_init( AF_OutlineHints hints,
AF_Dimension dim );
af_latin_hints_compute_edges( AF_GlyphHints hints,
AF_Dimension dim );
FT_LOCAL( void )
af_latin_hints_detect_features( AF_GlyphHints hints,
AF_Dimension dim );
/* */

@ -1,6 +1,9 @@
#ifndef __AFTYPES_H__
#define __AFTYPES_H__
#include <ft2build.h>
#include FT_FREETYPE_H
FT_BEGIN_HEADER
/**************************************************************************/
@ -24,6 +27,27 @@ FT_BEGIN_HEADER
#endif /* AF_DEBUG */
/**************************************************************************/
/**************************************************************************/
/***** *****/
/***** U T I L I T Y *****/
/***** *****/
/**************************************************************************/
/**************************************************************************/
typedef struct AF_WidthRec_
{
FT_Pos org; /* original position/width in font units */
FT_Pos cur; /* current/scaled position/width in device sub-pixels */
FT_Pos fit; /* current/fitted position/width in device sub-pixels */
} AF_WidthRec, *AF_Width;
AF_LOCAL( void )
af_sort_pos( FT_UInt count,
FT_Pos* table );
/**************************************************************************/
/**************************************************************************/
/***** *****/
@ -73,13 +97,17 @@ FT_BEGIN_HEADER
/**************************************************************************/
/**************************************************************************/
typedef struct AF_OutlineHintsRec_* AF_OutlineHints;
typedef struct AF_GlobalHintsRec_* AF_GlobalHints;
/* opaque handle to glyph-specific hints. see "afhints.h" for more
* details
*/
typedef struct AF_GlyphHintsRec_* AF_GlyphHints;
/* this structure is used to model an input glyph outline to
* the auto-hinter. The latter will set the "hints" field
* depending on the glyph's script
*/
typedef struct AF_OutlineRec_
{
FT_Memory memory;
FT_Face face;
FT_OutlineRec outline;
FT_UInt outline_resolution;
@ -87,53 +115,10 @@ FT_BEGIN_HEADER
FT_Int advance;
FT_UInt metrics_resolution;
AF_OutlineHints hints;
AF_GlyphHints hints;
} AF_OutlineRec;
/**************************************************************************/
/**************************************************************************/
/***** *****/
/***** G L O B A L M E T R I C S *****/
/***** *****/
/**************************************************************************/
/**************************************************************************/
/*
* the following define global metrics in a _single_ dimension
*
* the "blue_refs" and "blue_shoots" arrays are ignored in
* the horizontal dimension
*/
typedef struct AF_WidthRec_
{
FT_Pos org; /* original position/width in font units */
FT_Pos cur; /* current/scaled position/width in device sub-pixels */
FT_Pos fit; /* current/fitted position/width in device sub-pixels */
} AF_WidthRec, *AF_Width;
#define AF_MAX_WIDTHS 16
#define AF_MAX_BLUES 32
typedef struct AF_GlobalMetricsRec_
{
FT_Int num_widths;
AF_WidthRec widths[ AF_MAX_WIDTHS ];
FT_Fixed scale; /* used to scale from org to cur with: */
FT_Pos delta; /* x_cur = x_org * scale + delta */
/* ignored for horizontal metrics */
AF_WidthRec blue_refs [ AF_MAX_BLUES ];
AF_WidthRec blue_shoots[ AF_MAX_BLUES ];
FT_Bool control_overshoot;
} AF_GlobalMetricsRec, *AF_GlobalMetrics;
/**************************************************************************/
/**************************************************************************/
@ -190,30 +175,32 @@ FT_BEGIN_HEADER
* - a specific global analyzer that will compute global metrics
* specific to the script.
*
* - a specific hinting routine
* - a specific glyph analyzer that will compute segments and
* edges for each glyph covered by the script
*
* - a specific grid-fitting algorithm that will distort the
* scaled glyph outline according to the results of the glyph
* analyzer
*
* all scripts should share the same analysis routine though
* note that a given analyzer and/or grid-fitting algorithm can be
* used by more than one script
*/
typedef enum
{
AF_SCRIPT_LATIN = 0,
/* add new scripts here */
/* add new scripts here. don't forget to update the list in "afglobal.c" */
AF_SCRIPT_MAX /* do not remove */
} AF_Script;
typedef struct AF_ScriptClassRec_ const* AF_ScriptClass;
/*
* root class for script-specific metrics
*/
typedef struct AF_ScriptMetricsRec_
{
AF_ScriptClass script_class;
AF_GlobalMetricsRec horz_metrics;
AF_GlobalMetricsRec vert_metrics;
AF_ScriptClass clazz;
} AF_ScriptMetricsRec, *AF_ScriptMetrics;
@ -221,21 +208,23 @@ FT_BEGIN_HEADER
/* this function parses a FT_Face to compute global metrics for
* a specific script
*/
typedef FT_Error (*AF_Script_InitMetricsFunc)( AF_ScriptMetrics metrics,
FT_Face face );
typedef FT_Error (*AF_Script_InitMetricsFunc)( AF_ScriptMetrics metrics,
FT_Face face );
typedef void (*AF_Script_ScaleMetricsFunc)( AF_ScriptMetrics metrics,
AF_Scaler scaler );
typedef void (*AF_Script_DoneMetricsFunc)( AF_ScriptMetrics metrics );
typedef void (*AF_Script_DoneMetricsFunc)( AF_ScriptMetrics metrics );
typedef FT_Error (*AF_Script_InitHintsFunc)( AF_OutlineHints hints,
typedef FT_Error (*AF_Script_InitHintsFunc)( AF_GlyphHints hints,
AF_Scaler scaler,
AF_ScriptMetrics metrics );
typedef void (*AF_Script_ApplyHintsFunc)( AF_OutlineHints hints );
typedef void (*AF_Script_ApplyHintsFunc)( AF_GlyphHints hints,
AF_Scaler scaler,
AF_ScriptMetrics metrics );
typedef struct AF_Script_UniRangeRec_
{
@ -248,40 +237,19 @@ FT_BEGIN_HEADER
typedef struct AF_ScriptClassRec_
{
AF_Script script;
AF_Scipt_UniRange script_uni_ranges; /* last must be { 0, 0 } */
AF_Script_UniRange script_uni_ranges; /* last must be { 0, 0 } */
FT_UInt script_metrics_size;
AF_Script_InitMetricsFunc script_metrics_init;
AF_Script_ScaleMetricsFunc script_metrics_scale;
AF_Script_DoneMetricsFunc script_metrics_done;
} AF_ScriptClassRec;
AF_Script_InitHintsFunc script_hints_init;
AF_Script_ApplyHintsFunc script_hints_apply;
} AF_ScriptClassRec;
/**************************************************************************/
/**************************************************************************/
/***** *****/
/***** F A C E G L O B A L S *****/
/***** *****/
/**************************************************************************/
/**************************************************************************/
/*
* models the global hints data for a given face, decomposed into
* script-specific items..
*
*/
typedef struct AF_FaceGlobalsRec_
{
FT_Face face;
FT_UInt glyph_count; /* same as face->num_glyphs */
FT_Byte* glyph_scripts; /* maps each gindex to a script */
FT_ScriptMetrics metrics[ AF_SCRIPT_MAX ];
} AF_FaceGlobalsRec, *AF_FaceGlobals;
/* */
FT_END_HEADER

Loading…
Cancel
Save