* src/autofit/*: more updates

This commit is contained in:
David Turner 2003-11-23 21:39:51 +00:00
parent 0b58b0a94c
commit 25f45461ed
13 changed files with 1993 additions and 402 deletions

View File

@ -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> 2003-11-13 John A. Boyd Jr. <jaboydjr@netwalk.com>
* src/bdf/bdfdrivr.c (bdf_interpret_style), src/pcf/pcfread.c * src/bdf/bdfdrivr.c (bdf_interpret_style), src/pcf/pcfread.c

8
README
View File

@ -9,7 +9,7 @@
is called `libttf'. They are *not* compatible! 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. 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 Note that the FreeType 2 documentation is now available as a
separate package from our sites. See: 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.8.tar.bz2
ftp://ftp.freetype.org/pub/freetype2/ftdocs-2.1.7.tar.gz ftp://ftp.freetype.org/pub/freetype2/ftdocs-2.1.8.tar.gz
ftp://ftp.freetype.org/pub/freetype2/ftdoc216.zip ftp://ftp.freetype.org/pub/freetype2/ftdoc218.zip
Bugs Bugs

View File

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

View File

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

View File

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

View File

@ -9,6 +9,7 @@
90, 64, 38, 20, 10, 5, 3, 1, 1 90, 64, 38, 20, 10, 5, 3, 1, 1
}; };
static FT_Int static FT_Int
af_angle_prenorm( FT_Vector* vec ) af_angle_prenorm( FT_Vector* vec )
{ {
@ -162,3 +163,29 @@
return delta; 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;
}
}
}

231
src/autofit/afglobal.c Normal file
View File

@ -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;
}

42
src/autofit/afglobal.h Normal file
View File

@ -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__ */

View File

@ -5,7 +5,7 @@
#include <stdio.h> #include <stdio.h>
void void
af_outline_hints_dump_edges( AF_OutlineHints hints ) af_glyph_hints_dump_edges( AF_GlyphHints hints )
{ {
AF_Edge edges; AF_Edge edges;
AF_Edge edge_limit; AF_Edge edge_limit;
@ -57,7 +57,7 @@
/* A function used to dump the array of linked segments */ /* A function used to dump the array of linked segments */
void void
af_outline_hints_dump_segments( AF_OutlineHints hints ) af_glyph_hints_dump_segments( AF_GlyphHints hints )
{ {
AF_Segment segments; AF_Segment segments;
AF_Segment segment_limit; AF_Segment segment_limit;
@ -139,15 +139,12 @@
/* compute all inflex points in a given glyph */ /* compute all inflex points in a given glyph */
static void 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 = hints->contours;
AF_Point* contour_limit = contour + hints->num_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 */ /* do each contour separately */
for ( ; contour < contour_limit; contour++ ) for ( ; contour < contour_limit; contour++ )
{ {
@ -172,10 +169,10 @@
if ( end == first ) if ( end == first )
goto Skip; 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, angle_seg = af_angle( end->fx - start->fx,
end->v - start->v ); end->fy - start->fy );
/* extend the segment start whenever possible */ /* extend the segment start whenever possible */
before = start; before = start;
@ -188,10 +185,10 @@
if ( before == first ) if ( before == first )
goto Skip; 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, angle_in = af_angle( start->fx - before->fx,
start->v - before->v ); start->fy - before->fy );
} while ( angle_in == angle_seg ); } while ( angle_in == angle_seg );
@ -212,12 +209,12 @@
if ( after == first ) if ( after == first )
finished = 1; 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.x = after->fx - end->fx;
vec.y = after->v - end->v; vec.y = after->fy - end->fy;
angle_out = af_angle( after->u - end->u, angle_out = af_angle( after->fx - end->fx,
after->v - end->v ); after->fy - end->fy );
} while ( angle_out == angle_seg ); } while ( angle_out == angle_seg );
@ -252,17 +249,17 @@
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_outline_hints_init( AF_OutlineHints hints, af_glyph_hints_init( AF_GlyphHints hints,
FT_Memory memory ) FT_Memory memory )
{ {
FT_ZERO( hints ); FT_ZERO( hints );
hints->memory = memory; hints->memory = memory;
} }
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_outline_hints_done( AF_OutlineHints hints ) af_glyph_hints_done( AF_GlyphHints hints )
{ {
if ( hints && hints->memory ) if ( hints && hints->memory )
{ {
@ -275,7 +272,7 @@
for ( dim = 0; dim < 2; dim++ ) for ( dim = 0; dim < 2; dim++ )
{ {
AF_AxisHints axis = &hints->axis[ dim ]; AF_AxisHints axis = &hints->axis[ dim ];
axis->num_segments = 0; axis->num_segments = 0;
axis->num_edges = 0; axis->num_edges = 0;
axis->segments = NULL; axis->segments = NULL;
@ -285,11 +282,11 @@
FT_FREE( hints->contours ); FT_FREE( hints->contours );
hints->max_contours = 0; hints->max_contours = 0;
hints->num_contours = 0; hints->num_contours = 0;
FT_FREE( hints->points ); FT_FREE( hints->points );
hints->num_points = 0; hints->num_points = 0;
hints->max_points = 0; hints->max_points = 0;
hints->memory = NULL; hints->memory = NULL;
} }
} }
@ -297,23 +294,25 @@
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
af_outline_hints_reset( AF_OutlineHints hints, af_glyph_hints_reset( AF_GlyphHints hints,
FT_Outline* outline, FT_Outline* outline,
FT_Fixed x_scale, FT_Fixed x_scale,
FT_Fixed y_scale ) FT_Fixed y_scale,
FT_Pos x_delta,
FT_Pos y_delta )
{ {
FT_Error error = AF_Err_Ok; FT_Error error = AF_Err_Ok;
FT_UInt old_max, new_max; FT_UInt old_max, new_max;
hints->num_points = 0; hints->num_points = 0;
hints->num_contours = 0; hints->num_contours = 0;
hints->axis[0].num_segments = 0; hints->axis[0].num_segments = 0;
hints->axis[0].num_edges = 0; hints->axis[0].num_edges = 0;
hints->axis[1].num_segments = 0; hints->axis[1].num_segments = 0;
hints->axis[1].num_edges = 0; hints->axis[1].num_edges = 0;
/* first of all, reallocate the contours array when necessary /* first of all, reallocate the contours array when necessary
*/ */
new_max = (FT_UInt) outline->n_contours; new_max = (FT_UInt) outline->n_contours;
@ -321,34 +320,34 @@
if ( new_max > old_max ) if ( new_max > old_max )
{ {
new_max = (new_max + 3) & ~3; new_max = (new_max + 3) & ~3;
if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
goto Exit; goto Exit;
hints->max_contours = new_max; hints->max_contours = new_max;
} }
/* then, reallocate the points, segments & edges arrays if needed -- /* then, reallocate the points, segments & edges 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
*/ */
new_max = (FT_UInt)( outline->n_points + 2 ); new_max = (FT_UInt)( outline->n_points + 2 );
old_max = hints->max_points; old_max = hints->max_points;
if ( new_max > old_max ) if ( new_max > old_max )
{ {
FT_Byte* items; FT_Byte* items;
FT_ULong off1, off2, off3; FT_ULong off1, off2, off3;
/* we store in a single buffer the following arrays: /* we store in a single buffer the following arrays:
* *
* - an array of N AF_PointRec items * - an array of N AF_PointRec items
* - an array of 2*N AF_SegmentRec 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; new_max = ( new_max + 2 + 7 ) & ~7;
#undef OFF_INCREMENT #undef OFF_INCREMENT
#define OFF_INCREMENT( _off, _type, _count ) \ #define OFF_INCREMENT( _off, _type, _count ) \
((((_off) + sizeof(_type)) & ~(sizeof(_type)) + ((_count)*sizeof(_type))) ((((_off) + sizeof(_type)) & ~(sizeof(_type)) + ((_count)*sizeof(_type)))
@ -368,15 +367,15 @@
hints->axis[1].edges = NULL; hints->axis[1].edges = NULL;
goto Exit; goto Exit;
} }
/* readjust some pointers /* readjust some pointers
*/ */
hints->max_points = new_max; hints->max_points = new_max;
hints->points = (AF_Point) items; hints->points = (AF_Point) items;
hints->axis[0].segments = (AF_Segment)( items + off1 ); hints->axis[0].segments = (AF_Segment)( items + off1 );
hints->axis[1].segments = hints->axis[0].segments + new_max; hints->axis[1].segments = hints->axis[0].segments + new_max;
hints->axis[0].edges = (AF_Edge) ( items + off2 ); hints->axis[0].edges = (AF_Edge) ( items + off2 );
hints->axis[1].edges = hints->axis[0].edges + new_max; hints->axis[1].edges = hints->axis[0].edges + new_max;
} }
@ -422,8 +421,8 @@
{ {
point->fx = vec->x; point->fx = vec->x;
point->fy = vec->y; point->fy = vec->y;
point->ox = point->x = FT_MulFix( vec->x, x_scale ); point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;
point->oy = point->y = FT_MulFix( vec->y, y_scale ); point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta;
switch ( FT_CURVE_TAG( *tag ) ) switch ( FT_CURVE_TAG( *tag ) )
{ {
@ -503,7 +502,7 @@
prev = point->prev; prev = point->prev;
in_x = point->fx - prev->fx; in_x = point->fx - prev->fx;
in_y = point->fy - prev->fy; in_y = point->fy - prev->fy;
point->in_dir = af_compute_direction( in_x, in_y ); point->in_dir = af_compute_direction( in_x, in_y );
next = point->next; next = point->next;
@ -539,88 +538,400 @@
} }
/* compute inflection points /* compute inflection points
*/ */
af_outline_hints_compute_inflections( hints ); af_glyph_hints_compute_inflections( hints );
Exit: Exit:
return error; 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 ) FT_LOCAL_DEF( void )
af_outline_hints_setup_uv( AF_OutlineHints hints, af_glyph_hints_align_edge_points( AF_GlyphHints hints,
AF_UV source ) AF_Dimension dim )
{ {
AF_Point point = hints->points; AF_AxisHints axis = & hints->axis[ dim ];
AF_Point point_limit = point + hints->num_points; AF_Edge edges = axis->edges;
AF_Edge edge_limit = edges + axis->num_edges;
AF_Edge edge;
for ( edge = edges; edge < edge_limit; edge++ )
switch ( source )
{ {
case AF_UV_FXY: /* move the points of each segment */
for ( ; point < point_limit; point++ ) /* in each edge to the edge's position */
{ AF_Segment seg = edge->first;
point->u = point->fx;
point->v = point->fy;
}
break;
case AF_UV_FYX:
for ( ; point < point_limit; point++ )
{
point->u = point->fy;
point->v = point->fx;
}
break;
case AF_UV_OXY: do
for ( ; point < point_limit; point++ )
{ {
point->u = point->ox; AF_Point point = seg->first;
point->v = point->oy;
}
break;
case AF_UV_OYX:
for ( ; point < point_limit; point++ )
{
point->u = point->oy;
point->v = point->ox;
}
break;
case AF_UV_YX: for (;;)
for ( ; point < point_limit; point++ ) {
{ if ( dim == AF_DIMENSION_HORZ )
point->u = point->y; {
point->v = point->x; point->x = edge->pos;
} point->flags |= AF_FLAG_TOUCH_X;
break; }
else
{
point->y = edge->pos;
point->flags |= AF_FLAG_TOUCH_Y;
}
case AF_UV_OX: if ( point == seg->last )
for ( ; point < point_limit; point++ ) break;
{
point->u = point->x;
point->v = point->ox;
}
break;
case AF_UV_OY: point = point->next;
for ( ; point < point_limit; point++ ) }
{
point->u = point->y;
point->v = point->oy;
}
break;
default: seg = seg->edge_next;
for ( ; point < point_limit; point++ )
} 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;
for ( point = points; point < point_limit; point++ )
{ {
point->u = point->x; FT_Pos u, ou, fu; /* point position */
point->v = point->y; 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;
} }
} }
} }
/*
*
* 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;
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++ )
{
u = p->v;
if ( u <= v1 )
u += d1;
else
u += d2;
p->u = u;
}
return;
}
if ( v1 < v2 )
{
for ( p = p1; p <= p2; p++ )
{
u = p->v;
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++ )
{
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;
}
}
}
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;
/* 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;
}
}
else
{
touch_flag = AF_FLAG_TOUCH_Y;
for ( point = points; point < point_limit; points++ )
{
point->u = point->y;
point->v = point->oy;
}
}
point = points;
for ( ; contour < contour_limit; contour++ )
{
point = *contour;
end_point = point->prev;
first_point = point;
while ( point <= end_point && !( point->flags & touch_flag ) )
point++;
if ( point <= end_point )
{
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;
}
}

View File

@ -6,8 +6,8 @@
FT_BEGIN_HEADER FT_BEGIN_HEADER
/* /*
* The definition of outline hints. These are shared by all * The definition of outline glyph hints. These are shared by all
* script analysis routines * 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_VERT = 1, /* y coordinates, i.e. horizontal segments & edges */
AF_DIMENSION_MAX /* do not remove */ AF_DIMENSION_MAX /* do not remove */
} AF_Dimension; } AF_Dimension;
@ -30,7 +30,7 @@ FT_BEGIN_HEADER
AF_DIR_LEFT = -1, AF_DIR_LEFT = -1,
AF_DIR_UP = 2, AF_DIR_UP = 2,
AF_DIR_DOWN = -2 AF_DIR_DOWN = -2
} AF_Direction; } AF_Direction;
@ -38,32 +38,32 @@ FT_BEGIN_HEADER
typedef enum typedef enum
{ {
AF_FLAG_NONE = 0, AF_FLAG_NONE = 0,
/* point type flags */ /* point type flags */
AF_FLAG_CONIC = (1 << 0), AF_FLAG_CONIC = (1 << 0),
AF_FLAG_CUBIC = (1 << 1), AF_FLAG_CUBIC = (1 << 1),
AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC, AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC,
/* point extremum flags */ /* point extremum flags */
AF_FLAG_EXTREMA_X = (1 << 2), AF_FLAG_EXTREMA_X = (1 << 2),
AF_FLAG_EXTREMA_Y = (1 << 3), AF_FLAG_EXTREMA_Y = (1 << 3),
/* point roundness flags */ /* point roundness flags */
AF_FLAG_ROUND_X = (1 << 4), AF_FLAG_ROUND_X = (1 << 4),
AF_FLAG_ROUND_Y = (1 << 5), AF_FLAG_ROUND_Y = (1 << 5),
/* point touch flags */ /* point touch flags */
AF_FLAG_TOUCH_X = (1 << 6), AF_FLAG_TOUCH_X = (1 << 6),
AF_FLAG_TOUCH_Y = (1 << 7), AF_FLAG_TOUCH_Y = (1 << 7),
/* candidates for weak interpolation have this flag set */ /* candidates for weak interpolation have this flag set */
AF_FLAG_WEAK_INTERPOLATION = (1 << 8), AF_FLAG_WEAK_INTERPOLATION = (1 << 8),
/* all inflection points in the outline have this flag set */ /* all inflection points in the outline have this flag set */
AF_FLAG_INFLECTION = (1 << 9) AF_FLAG_INFLECTION = (1 << 9)
} AF_Flags; } AF_Flags;
/* edge hint flags */ /* edge hint flags */
typedef enum typedef enum
@ -72,7 +72,7 @@ FT_BEGIN_HEADER
AF_EDGE_ROUND = (1 << 0), AF_EDGE_ROUND = (1 << 0),
AF_EDGE_SERIF = (1 << 1), AF_EDGE_SERIF = (1 << 1),
AF_EDGE_DONE = (1 << 2) AF_EDGE_DONE = (1 << 2)
} AF_Edge_Flags; } AF_Edge_Flags;
@ -110,10 +110,10 @@ FT_BEGIN_HEADER
AF_Edge edge; /* the segment's parent edge */ AF_Edge edge; /* the segment's parent edge */
AF_Segment edge_next; /* link to next segment in 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 */ AF_Segment serif; /* primary segment for serifs */
FT_Pos num_linked; /* number of linked segments */ 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 first; /* first point in edge segment */
AF_Point last; /* last 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_Edge_Flags flags; /* edge flags */
AF_Direction dir; /* edge direction */ AF_Direction dir; /* edge direction */
FT_Fixed scale; /* used to speed up interpolation between edges */ 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 link;
AF_Edge serif; AF_Edge serif;
@ -142,7 +142,6 @@ FT_BEGIN_HEADER
AF_Segment first; AF_Segment first;
AF_Segment last; AF_Segment last;
} AF_EdgeRec; } AF_EdgeRec;
@ -150,7 +149,7 @@ FT_BEGIN_HEADER
{ {
FT_Int num_segments; FT_Int num_segments;
AF_Segment segments; AF_Segment segments;
FT_Int num_edges; FT_Int num_edges;
AF_Edge edges; AF_Edge edges;
@ -158,8 +157,8 @@ FT_BEGIN_HEADER
} AF_AxisHintsRec, *AF_AxisHints; } AF_AxisHintsRec, *AF_AxisHints;
typedef struct AF_OutlineHintsRec_ typedef struct AF_GlyphHintsRec_
{ {
FT_Memory memory; FT_Memory memory;
@ -177,7 +176,7 @@ FT_BEGIN_HEADER
AF_AxisHintsRec axis[ AF_DIMENSION_MAX ]; AF_AxisHintsRec axis[ AF_DIMENSION_MAX ];
} AF_OutlineHintsRec; } AF_GlyphHintsRec;
@ -188,43 +187,36 @@ FT_BEGIN_HEADER
FT_LOCAL( void ) FT_LOCAL( void )
af_outline_hints_init( AF_OutlineHints hints ); af_glyph_hints_init( AF_GlyphHints hints,
FT_Memory memory );
/* 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! */
} AH_UV; /* recomputes all AF_Point in a AF_GlyphHints from the definitions
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
* in a source outline * in a source outline
*/ */
FT_LOCAL( FT_Error ) FT_LOCAL( FT_Error )
af_outline_hints_reset( AF_OutlineHints hints, af_glyph_hints_reset( AF_GlyphHints hints,
FT_Outline* outline, FT_Outline* outline,
FT_Fixed x_scale, FT_Fixed x_scale,
FT_Fixed y_scale ); FT_Fixed y_scale,
FT_Pos x_delta,
FT_Pos y_delta );
FT_LOCAL( void ) 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

View File

@ -11,6 +11,14 @@ FT_BEGIN_HEADER
*/ */
FT_LOCAL( const FT_ScriptClassRec ) af_latin_script_class; 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" * the following declarations could be embedded in the file "aflatin.c"
* they've been made semi-public to allow alternate script hinters to * they've been made semi-public to allow alternate script hinters to
@ -21,29 +29,65 @@ FT_BEGIN_HEADER
* Latin (global) metrics management * 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_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_ typedef struct AF_LatinAxisRec_
{ {
FT_Fixed scale; FT_Fixed scale;
FT_Pos delta; FT_Pos delta;
FT_UInt width_count; FT_UInt width_count;
AF_WidthRec widths[ AF_LATIN_MAX_WIDTHS ]; AF_WidthRec widths[ AF_LATIN_MAX_WIDTHS ];
FT_Pos edge_distance_threshold;
/* ignored for horizontal metrics */ /* ignored for horizontal metrics */
FT_Bool control_overshoot; FT_Bool control_overshoot;
FT_UInt blue_count; FT_UInt blue_count;
AF_WidthRec blue_refs [ AF_MAX_BLUES ]; AF_LatinBlueRec blues;
AF_WidthRec blue_shoots[ AF_MAX_BLUES ];
} AF_LatinAxisRec, *AF_LatinAxis; } AF_LatinAxisRec, *AF_LatinAxis;
typedef struct AF_LatinMetricsRec_ typedef struct AF_LatinMetricsRec_
{ {
AF_OutlineMetricsRec root; AF_ScriptMetricsRec root;
FT_UInt units_per_em;
AF_LatinAxisRec axis[ AF_DIMENSION_MAX ]; AF_LatinAxisRec axis[ AF_DIMENSION_MAX ];
} AF_LatinMetricsRec, *AF_LatinMetrics; } AF_LatinMetricsRec, *AF_LatinMetrics;
@ -58,29 +102,40 @@ FT_BEGIN_HEADER
AF_Scaler scaler ); AF_Scaler scaler );
/*
* Latin (glyph) hints management /***************************************************************************/
* /***************************************************************************/
/***** *****/
/***** L A T I N G L Y P H A N A L Y S I S *****/
/***** *****/
/***************************************************************************/
/***************************************************************************/
/* this shouldn't normally be exported. However, other scripts might
* like to use this function as-is
*/ */
FT_LOCAL( void )
af_latin_hints_compute_segments( AF_GlyphHints hints,
AF_Dimension dim );
FT_LOCAL( /* this shouldn't normally be exported. However, other scripts might
* want to use this function as-is
*/
FT_LOCAL( void )
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_compute_edges( AF_GlyphHints hints,
AF_Dimension dim );
FT_LOCAL( void ) FT_LOCAL( void )
af_latin_hints_compute_segments( AF_OutlineHints hints, af_latin_hints_detect_features( AF_GlyphHints hints,
AF_Dimension dim ); AF_Dimension dim );
FT_LOCAL( void )
af_latin_hints_link_segments( AF_OutlineHints hints,
AF_Dimension dim );
FT_LOCAL( void )
af_latin_hints_compute_edges( AF_OutlineHints hints,
AF_Dimension dim );
FT_LOCAL( void )
af_latin_hints_init( AF_OutlineHints hints,
AF_Dimension dim );
/* */ /* */

View File

@ -1,6 +1,9 @@
#ifndef __AFTYPES_H__ #ifndef __AFTYPES_H__
#define __AFTYPES_H__ #define __AFTYPES_H__
#include <ft2build.h>
#include FT_FREETYPE_H
FT_BEGIN_HEADER FT_BEGIN_HEADER
/**************************************************************************/ /**************************************************************************/
@ -24,6 +27,27 @@ FT_BEGIN_HEADER
#endif /* AF_DEBUG */ #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; /* opaque handle to glyph-specific hints. see "afhints.h" for more
* details
typedef struct AF_GlobalHintsRec_* AF_GlobalHints; */
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_ typedef struct AF_OutlineRec_
{ {
FT_Memory memory;
FT_Face face; FT_Face face;
FT_OutlineRec outline; FT_OutlineRec outline;
FT_UInt outline_resolution; FT_UInt outline_resolution;
@ -87,53 +115,10 @@ FT_BEGIN_HEADER
FT_Int advance; FT_Int advance;
FT_UInt metrics_resolution; FT_UInt metrics_resolution;
AF_OutlineHints hints; AF_GlyphHints hints;
} AF_OutlineRec; } 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 * - a specific global analyzer that will compute global metrics
* specific to the script. * 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
* *
* all scripts should share the same analysis routine though * - a specific grid-fitting algorithm that will distort the
* scaled glyph outline according to the results of the glyph
* analyzer
*
* note that a given analyzer and/or grid-fitting algorithm can be
* used by more than one script
*/ */
typedef enum typedef enum
{ {
AF_SCRIPT_LATIN = 0, 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_MAX /* do not remove */
} AF_Script; } AF_Script;
typedef struct AF_ScriptClassRec_ const* AF_ScriptClass; typedef struct AF_ScriptClassRec_ const* AF_ScriptClass;
/*
* root class for script-specific metrics
*/
typedef struct AF_ScriptMetricsRec_ typedef struct AF_ScriptMetricsRec_
{ {
AF_ScriptClass script_class; AF_ScriptClass clazz;
AF_GlobalMetricsRec horz_metrics;
AF_GlobalMetricsRec vert_metrics;
} AF_ScriptMetricsRec, *AF_ScriptMetrics; } AF_ScriptMetricsRec, *AF_ScriptMetrics;
@ -221,21 +208,23 @@ FT_BEGIN_HEADER
/* this function parses a FT_Face to compute global metrics for /* this function parses a FT_Face to compute global metrics for
* a specific script * a specific script
*/ */
typedef FT_Error (*AF_Script_InitMetricsFunc)( AF_ScriptMetrics metrics, typedef FT_Error (*AF_Script_InitMetricsFunc)( AF_ScriptMetrics metrics,
FT_Face face ); FT_Face face );
typedef void (*AF_Script_ScaleMetricsFunc)( AF_ScriptMetrics metrics, typedef void (*AF_Script_ScaleMetricsFunc)( AF_ScriptMetrics metrics,
AF_Scaler scaler ); 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_Scaler scaler,
AF_ScriptMetrics metrics ); 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_ typedef struct AF_Script_UniRangeRec_
{ {
@ -248,40 +237,19 @@ FT_BEGIN_HEADER
typedef struct AF_ScriptClassRec_ typedef struct AF_ScriptClassRec_
{ {
AF_Script script; 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; FT_UInt script_metrics_size;
AF_Script_InitMetricsFunc script_metrics_init; AF_Script_InitMetricsFunc script_metrics_init;
AF_Script_ScaleMetricsFunc script_metrics_scale; AF_Script_ScaleMetricsFunc script_metrics_scale;
AF_Script_DoneMetricsFunc script_metrics_done; AF_Script_DoneMetricsFunc script_metrics_done;
AF_Script_InitHintsFunc script_hints_init;
AF_Script_ApplyHintsFunc script_hints_apply;
} AF_ScriptClassRec; } 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 FT_END_HEADER