* src/autofit/afdummy.c, src/autofit/afdummy.h

(af_dummy_script_class): Fix type.

* src/autofit/aflatin.c, src/autofit/aflatin.h
(af_latin_script_class): Fix type.

* src/autofit/rules.mk (AUTOF_DRV_SRC): Fix typo.

Formatting.
This commit is contained in:
Werner Lemberg 2005-03-02 11:24:23 +00:00
parent 4bdee1ff76
commit f9a1be3d23
12 changed files with 617 additions and 474 deletions

View File

@ -1,20 +1,59 @@
2005-03-02 Werner Lemberg <wl@gnu.org>
* src/autofit/afdummy.c, src/autofit/afdummy.h
(af_dummy_script_class): Fix type.
* src/autofit/aflatin.c, src/autofit/aflatin.h
(af_latin_script_class): Fix type.
* src/autofit/rules.mk (AUTOF_DRV_SRC): Fix typo.
2005-03-01 David Turner <david@freetype.org>
* src/sfnt/{ttkern.c,ttsbit.h,ttsbit0.c,ttload.c},: removing compiler
warnings
* src/sfnt/ttkern.c (tt_face_load_kern, tt_face_get_kerning),
src/sfnt/ttsbit0.c (tt_face_load_sbit_strikes,
tt_sbit_decoder_load_byte_aligned, tt_sbit_decoder_load_compound,
tt_sbit_decoder_load_image), src/sfnt/ttload.c
(tt_face_load_metrics): Remove compiler warnings
-- redundant variables, missing initializations, etc.
* src/autofit/{rules.mk,module.mk,afangles.h}: adding missing files
* src/sfnt/ttsbit.h: Handle FT_OPTIMIZE_MEMORY.
* src/autofit/afloader.c: fixing small bug that could crash the engine
with certain fonts.
* src/autofit/rules.mk, src/autofit/module.mk,
src/autofit/afangles.h: New files.
* src/autofit/{afhints.h,afhints.c,aflatin.h,aflatin.c,afloader.c}:
various bug-fixes and drastic heap usage reduction improvements.
* src/autofit/afhints.c (af_axis_hints_new_segment,
af_axis_hints_new_edge): New functions.
(af_glyph_hints_done): Do proper deallocation.
(af_glyph_hints_reload): Only reallocate points array. This
drastically reduces heap usage.
* include/freetype/config/ftmodule.h: the auto-fitter is now the
only supported auto-hinting module
* src/autofit/afhints.h (AF_PointRec, AF_SegmentRec): Optimize
member types and positions.
(AF_AxisHintsRec): Add `max_segments' and `max_edges'.
(af_axis_hints_new_segment, af_axis_hints_new_edge): New prototypes.
* include/freetype/config/ftstdlib.h: adding FT_INT_MAX definition
* src/autofit/aflatin.c (af_latin_metricsc_scale): Don't call
AF_SCALER_EQUAL_SCALES.
(af_latin_hints_compute_segments): Change return type to FT_Error.
Update all callers.
Improve segment allocation.
(af_latin_hints_compute_edges): Change return type to FT_Error.
Update all callers.
Improve edge allocation and link handling.
(af_latin_hints_detect_features): Change return type to FT_Error.
Update all callers.
* src/autofit/aflatin.h: Updated.
* src/autofit/afloader.c (af_loader_load_g)
<FT_GLYPH_FORMAT_OUTLINE>: Assure axis->num_edges > 1. This fixes
a bug with certain fonts.
* include/freetype/config/ftmodule.h: The auto-fitter is now the
only supported auto-hinting module.
* include/freetype/config/ftstdlib.h (FT_INT_MAX): New macro.
2005-02-28 Werner Lemberg <wl@gnu.org>

View File

@ -1,3 +1,7 @@
/* this is a dummy file. used to please the build system. It is never
* included by the auto-fitter sources
/*
* afangles.h
*
* This is a dummy file, used to please the build system. It is never
* included by the auto-fitter sources.
*
*/

View File

@ -22,7 +22,8 @@
}
FT_LOCAL_DEF( const AF_ScriptClassRec ) af_dummy_script_class =
FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec
af_dummy_script_class =
{
AF_SCRIPT_NONE,
NULL,
@ -35,3 +36,6 @@
(AF_Script_InitHintsFunc) af_dummy_hints_init,
(AF_Script_ApplyHintsFunc) af_dummy_hints_apply
};
/* END */

View File

@ -5,14 +5,18 @@
FT_BEGIN_HEADER
/* a dummy script metrics class used when no hinting should
* be performed. This is the default for non-latin glyphs !
/* A dummy script metrics class used when no hinting should
* be performed. This is the default for non-latin glyphs!
*/
FT_LOCAL( const AF_ScriptClassRec ) af_dummy_script_class;
FT_CALLBACK_TABLE const AF_ScriptClassRec
af_dummy_script_class;
/* */
FT_END_HEADER
#endif /* __AFDUMMY_H__ */
/* END */

View File

@ -9,11 +9,13 @@
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);
FT_Int big_max = FT_INT_MAX / sizeof ( *segment );
if ( old_max >= big_max )
{
@ -21,7 +23,7 @@
goto Exit;
}
new_max += (new_max >> 1) + 4;
new_max += ( new_max >> 1 ) + 4;
if ( new_max < old_max || new_max > big_max )
new_max = big_max;
@ -39,21 +41,24 @@
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;
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);
FT_Int big_max = FT_INT_MAX / sizeof ( *edge );
if ( old_max >= big_max )
{
@ -61,7 +66,7 @@
goto Exit;
}
new_max += (new_max >> 1) + 4;
new_max += ( new_max >> 1 ) + 4;
if ( new_max < old_max || new_max > big_max )
new_max = big_max;
@ -82,8 +87,8 @@
axis->num_edges++;
FT_ZERO(edge);
edge->fpos = (FT_Short) fpos;
FT_ZERO( edge );
edge->fpos = (FT_Short)fpos;
Exit:
*aedge = edge;
@ -95,22 +100,36 @@
#include <stdio.h>
static const char* af_dir_str( AF_Direction dir )
static const char*
af_dir_str( AF_Direction dir )
{
const char* result;
switch (dir)
switch ( dir )
{
case AF_DIR_UP: result = "up"; break;
case AF_DIR_DOWN: result = "down"; break;
case AF_DIR_LEFT: result = "left"; break;
case AF_DIR_RIGHT: result = "right"; break;
default: result = "none";
case AF_DIR_UP:
result = "up";
break;
case AF_DIR_DOWN:
result = "down";
break;
case AF_DIR_LEFT:
result = "left";
break;
case AF_DIR_RIGHT:
result = "right";
break;
default:
result = "none";
}
return result;
}
#define AF_INDEX_NUM(ptr,base) ( (ptr) ? ((ptr)-(base)) : -1 )
#define AF_INDEX_NUM( ptr, base ) ( (ptr) ? ( (ptr) - (base) ) : -1 )
void
af_glyph_hints_dump_points( AF_GlyphHints hints )
@ -119,11 +138,15 @@
AF_Point limit = points + hints->num_points;
AF_Point point;
printf( "Table of points:\n" );
printf( " [ index | xorg | yorg | xscale | yscale | xfit | yfit | flags ]\n" );
printf( " [ index | xorg | yorg | xscale | yscale "
"| xfit | yfit | flags ]\n" );
for ( point = points; point < limit; point++ )
{
printf( " [ %5d | %5d | %5d | %-5.2f | %-5.2f | %-5.2f | %-5.2f | %c%c%c%c%c%c ]\n",
printf( " [ %5d | %5d | %5d | %-5.2f | %-5.2f "
"| %-5.2f | %-5.2f | %c%c%c%c%c%c ]\n",
point - points,
point->fx,
point->fy,
@ -131,28 +154,28 @@
point->oy/64.0,
point->x/64.0,
point->y/64.0,
(point->flags & AF_FLAG_WEAK_INTERPOLATION) ? 'w' : ' ',
(point->flags & AF_FLAG_INFLECTION) ? 'i' : ' ',
(point->flags & AF_FLAG_EXTREMA_X) ? '<' : ' ',
(point->flags & AF_FLAG_EXTREMA_Y) ? 'v' : ' ',
(point->flags & AF_FLAG_ROUND_X) ? '(' : ' ',
(point->flags & AF_FLAG_ROUND_Y) ? 'u' : ' '
);
( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ',
( point->flags & AF_FLAG_INFLECTION ) ? 'i' : ' ',
( point->flags & AF_FLAG_EXTREMA_X ) ? '<' : ' ',
( point->flags & AF_FLAG_EXTREMA_Y ) ? 'v' : ' ',
( point->flags & AF_FLAG_ROUND_X ) ? '(' : ' ',
( point->flags & AF_FLAG_ROUND_Y ) ? 'u' : ' ');
}
printf( "\n" );
}
/* A function used to dump the array of linked segments */
/* A function to dump the array of linked segments. */
void
af_glyph_hints_dump_segments( AF_GlyphHints hints )
{
AF_Point points = hints->points;
FT_Int dimension;
AF_Point points = hints->points;
FT_Int dimension;
for ( dimension = 1; dimension >= 0; dimension-- )
{
AF_AxisHints axis = &hints->axis[dimension];
AF_AxisHints axis = &hints->axis[dimension];
AF_Segment segments = axis->segments;
AF_Segment limit = segments + axis->num_segments;
AF_Segment seg;
@ -183,18 +206,21 @@
void
af_glyph_hints_dump_edges( AF_GlyphHints hints )
{
FT_Int dimension;
FT_Int dimension;
for ( dimension = 1; dimension >= 0; dimension-- )
{
AF_AxisHints axis = &hints->axis[ dimension ];
AF_AxisHints axis = &hints->axis[dimension];
AF_Edge edges = axis->edges;
AF_Edge limit = edges + axis->num_edges;
AF_Edge edge;
/* note: AF_DIMENSION_HORZ corresponds to _vertical_ edges
* since they have constant X coordinate
*/
/*
* note: AF_DIMENSION_HORZ corresponds to _vertical_ edges
* since they have constant a X coordinate.
*/
printf ( "Table of %s edges:\n",
dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );
printf ( " [ index | pos | dir | link |"
@ -202,7 +228,8 @@
for ( edge = edges; edge < limit; edge++ )
{
printf ( " [ %5d | %4d | %5s | %4d | %5d | %c | %5.2f | %5.2f ]\n",
printf ( " [ %5d | %4d | %5s | %4d |"
" %5d | %c | %5.2f | %5.2f ]\n",
edge - edges,
(int)edge->fpos,
af_dir_str( edge->dir ),
@ -212,13 +239,10 @@
edge->opos / 64.0,
edge->pos / 64.0 );
}
printf( "\n" );
}
}
#endif /* AF_DEBUG */
@ -359,7 +383,6 @@
}
FT_LOCAL_DEF( void )
af_glyph_hints_init( AF_GlyphHints hints,
FT_Memory memory )
@ -369,7 +392,6 @@
}
FT_LOCAL_DEF( void )
af_glyph_hints_done( AF_GlyphHints hints )
{
@ -378,12 +400,15 @@
FT_Memory memory = hints->memory;
AF_Dimension dim;
/* note that we don't need to free the segment and edge
* buffers, since they're really within the hints->points array
*/
/*
* note that we don't need to free the segment and edge
* buffers, since they are really within the hints->points array
*/
for ( dim = 0; dim < 2; dim++ )
{
AF_AxisHints axis = &hints->axis[ dim ];
AF_AxisHints axis = &hints->axis[dim];
axis->num_segments = 0;
axis->max_segments = 0;
@ -407,7 +432,6 @@
}
FT_LOCAL_DEF( void )
af_glyph_hints_rescale( AF_GlyphHints hints,
AF_ScriptMetrics metrics )
@ -417,18 +441,19 @@
FT_LOCAL_DEF( FT_Error )
af_glyph_hints_reload( AF_GlyphHints hints,
FT_Outline* outline )
af_glyph_hints_reload( AF_GlyphHints hints,
FT_Outline* outline )
{
FT_Error error = FT_Err_Ok;
AF_Point points;
FT_UInt old_max, new_max;
AF_Scaler scaler = &hints->metrics->scaler;
FT_Fixed x_scale = hints->x_scale;
FT_Fixed y_scale = hints->y_scale;
FT_Pos x_delta = hints->x_delta;
FT_Pos y_delta = hints->y_delta;
FT_Memory memory = hints->memory;
FT_Error error = FT_Err_Ok;
AF_Point points;
FT_UInt old_max, new_max;
AF_Scaler scaler = &hints->metrics->scaler;
FT_Fixed x_scale = hints->x_scale;
FT_Fixed y_scale = hints->y_scale;
FT_Pos x_delta = hints->x_delta;
FT_Pos y_delta = hints->y_delta;
FT_Memory memory = hints->memory;
hints->scaler_flags = scaler->flags;
hints->num_points = 0;
@ -439,13 +464,12 @@
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;
/* first of all, reallocate the contours array when necessary */
new_max = (FT_UInt)outline->n_contours;
old_max = hints->max_contours;
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 ) )
goto Exit;
@ -453,10 +477,11 @@
hints->max_contours = new_max;
}
/* then, reallocate the points arrays if needed --
* note that we reserved two additional point positions, used to
* hint metrics appropriately
*/
/*
* then, reallocate the points arrays if needed --
* note that we reserve 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 )
@ -472,17 +497,17 @@
hints->num_points = outline->n_points;
hints->num_contours = outline->n_contours;
/* 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. */
/* the Arphic ones). We thus recompute it each time we need to. */
/* */
hints->axis[ AF_DIMENSION_HORZ ].major_dir = AF_DIR_UP;
hints->axis[ AF_DIMENSION_VERT ].major_dir = AF_DIR_LEFT;
/* 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., */
/* the Arphic ones). We thus recompute it each time we need to. */
/* */
hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_UP;
hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_LEFT;
if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT )
{
hints->axis[ AF_DIMENSION_HORZ ].major_dir = AF_DIR_DOWN;
hints->axis[ AF_DIMENSION_VERT ].major_dir = AF_DIR_RIGHT;
hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_DOWN;
hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_RIGHT;
}
hints->x_scale = x_scale;
@ -499,7 +524,7 @@
AF_Point point_limit = points + hints->num_points;
/* compute coordinates & bezier flags */
/* compute coordinates & Bezier flags */
{
FT_Vector* vec = outline->points;
char* tag = outline->tags;
@ -582,9 +607,9 @@
{
for ( point = points; point < point_limit; point++ )
{
AF_Point prev;
AF_Point next;
FT_Pos in_x, in_y, out_x, out_y;
AF_Point prev;
AF_Point next;
FT_Pos in_x, in_y, out_x, out_y;
prev = point->prev;
@ -625,8 +650,7 @@
}
}
/* compute inflection points
*/
/* compute inflection points */
af_glyph_hints_compute_inflections( hints );
Exit:
@ -635,18 +659,19 @@
FT_LOCAL_DEF( void )
af_glyph_hints_save( AF_GlyphHints hints,
FT_Outline* outline )
af_glyph_hints_save( AF_GlyphHints hints,
FT_Outline* outline )
{
AF_Point point = hints->points;
AF_Point limit = point + hints->num_points;
FT_Vector* vec = outline->points;
char* tag = outline->tags;
for ( ; point < limit; point++, vec++, tag++ )
{
vec->x = (FT_Pos) point->x;
vec->y = (FT_Pos) point->y;
vec->x = (FT_Pos)point->x;
vec->y = (FT_Pos)point->y;
if ( point->flags & AF_FLAG_CONIC )
tag[0] = FT_CURVE_TAG_CONIC;
@ -658,22 +683,23 @@
}
/*
*
* E D G E P O I N T G R I D - F I T T I N G
*
*/
/****************************************************************
*
* EDGE POINT GRID-FITTING
*
****************************************************************/
FT_LOCAL_DEF( void )
af_glyph_hints_align_edge_points( AF_GlyphHints hints,
AF_Dimension dim )
{
AF_AxisHints axis = & hints->axis[ dim ];
AF_AxisHints axis = & hints->axis[dim];
AF_Edge edges = axis->edges;
AF_Edge edge_limit = edges + axis->num_edges;
AF_Edge edge;
for ( edge = edges; edge < edge_limit; edge++ )
{
/* move the points of each segment */
@ -712,15 +738,16 @@
}
/*
*
* S T R O N G P O I N T I N T E R P O L A T I O N
*
*/
/****************************************************************
*
* STRONG POINT INTERPOLATION
*
****************************************************************/
/* 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 )
@ -743,6 +770,7 @@
AF_Point point;
AF_Edge edge;
for ( point = points; point < point_limit; point++ )
{
FT_Pos u, ou, fu; /* point position */
@ -752,8 +780,9 @@
if ( point->flags & touch_flag )
continue;
/* if this point is candidate to weak interpolation, we will */
/* if this point is candidate to weak interpolation, we */
/* interpolate it after all strong points have been processed */
if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) &&
!( point->flags & AF_FLAG_INFLECTION ) )
continue;
@ -831,7 +860,6 @@
}
}
Store_Point:
/* save the point position */
@ -846,11 +874,12 @@
}
/*
*
* W E A K P O I N T I N T E R P O L A T I O N
*
*/
/****************************************************************
*
* WEAK POINT INTERPOLATION
*
****************************************************************/
static void
af_iup_shift( AF_Point p1,
@ -974,7 +1003,7 @@
}
}
point = points;
point = points;
for ( ; contour < contour_limit; contour++ )
{
@ -1039,3 +1068,6 @@
point->y = point->u;
}
}
/* END */

View File

@ -1,12 +1,13 @@
#include "aflatin.h"
/***************************************************************************/
/***************************************************************************/
/***** *****/
/***** L A T I N G L O B A L M E T R I C S *****/
/***** *****/
/***************************************************************************/
/***************************************************************************/
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** L A T I N G L O B A L M E T R I C S *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
static void
af_latin_metrics_init_widths( AF_LatinMetrics metrics,
@ -15,19 +16,21 @@
/* scan the array of segments in each direction */
AF_GlyphHintsRec hints[1];
af_glyph_hints_init( hints, face->memory );
metrics->axis[ AF_DIMENSION_HORZ ].width_count = 0;
metrics->axis[ AF_DIMENSION_VERT ].width_count = 0;
metrics->axis[AF_DIMENSION_HORZ].width_count = 0;
metrics->axis[AF_DIMENSION_VERT].width_count = 0;
/* For now, compute the standard width and height from the `o' */
/* For now, compute the standard width and height from the `o'. */
{
FT_Error error;
FT_UInt glyph_index;
AF_Dimension dim;
FT_Error error;
FT_UInt glyph_index;
AF_Dimension dim;
AF_ScriptMetricsRec dummy[1];
AF_Scaler scaler = &dummy->scaler;
glyph_index = FT_Get_Char_Index( face, 'o' );
if ( glyph_index == 0 )
goto Exit;
@ -52,17 +55,19 @@
for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
{
AF_LatinAxis axis = & metrics->axis[ dim ];
AF_AxisHints axhints = & hints->axis[ dim ];
AF_LatinAxis axis = &metrics->axis[dim];
AF_AxisHints axhints = &hints->axis[dim];
AF_Segment seg, limit, link;
FT_UInt num_widths = 0;
FT_UInt num_widths = 0;
FT_Pos edge_distance_threshold = 32000;
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;
limit = seg + axhints->num_segments;
@ -70,6 +75,7 @@
for ( ; seg < limit; seg++ )
{
link = seg->link;
/* we only consider stem segments there! */
if ( link && link->link == seg && link > seg )
{
@ -93,7 +99,7 @@
edge_distance_threshold = axis->widths[0].org;
/* Now, compute the edge distance threshold as a fraction of the */
/* smallest width in the font. Set it in `hinter->glyph' too! */
/* smallest width in the font. Set it in `hinter->glyph' too! */
if ( edge_distance_threshold == 32000 )
edge_distance_threshold = 50;
@ -111,7 +117,7 @@
#define AF_LATIN_MAX_TEST_CHARACTERS 12
static const char* const af_latin_blue_chars[ AF_LATIN_MAX_BLUES ] =
static const char* const af_latin_blue_chars[AF_LATIN_MAX_BLUES] =
{
"THEZOCQS",
"HEZLOCUS",
@ -126,16 +132,17 @@
af_latin_metrics_init_blues( AF_LatinMetrics metrics,
FT_Face face )
{
FT_Pos flats [ AF_LATIN_MAX_TEST_CHARACTERS ];
FT_Pos rounds[ AF_LATIN_MAX_TEST_CHARACTERS ];
FT_Pos flats [AF_LATIN_MAX_TEST_CHARACTERS];
FT_Pos rounds[AF_LATIN_MAX_TEST_CHARACTERS];
FT_Int num_flats;
FT_Int num_rounds;
FT_Int bb;
AF_LatinBlue blue;
FT_Error error;
AF_LatinAxis axis = &metrics->axis[ AF_DIMENSION_VERT ];
AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT];
FT_GlyphSlot glyph = face->glyph;
/* we compute the blues simply by loading each character from the */
/* 'af_latin_blue_chars[blues]' string, then compute its top-most or */
/* bottom-most points (depending on `AF_IS_TOP_BLUE') */
@ -150,6 +157,7 @@
FT_Pos* blue_ref;
FT_Pos* blue_shoot;
AF_LOG(( "blue %3d: ", bb ));
num_flats = 0;
@ -276,10 +284,11 @@
if ( num_flats == 0 && num_rounds == 0 )
{
/* we couldn't find a single glyph to compute this blue zone,
* we will simply ignore it then
*/
AF_LOG(( "empty !!\n" ));
/*
* we couldn't find a single glyph to compute this blue zone,
* we will simply ignore it then
*/
AF_LOG(( "empty!\n" ));
continue;
}
@ -289,15 +298,15 @@
af_sort_pos( num_rounds, rounds );
af_sort_pos( num_flats, flats );
blue = & axis->blues[ axis->blue_count ];
blue = & axis->blues[axis->blue_count];
blue_ref = & blue->ref.org;
blue_shoot = & blue->shoot.org;
axis->blue_count ++;
axis->blue_count++;
if ( num_flats == 0 )
{
*blue_ref =
*blue_ref =
*blue_shoot = rounds[num_rounds / 2];
}
else if ( num_rounds == 0 )
@ -326,13 +335,14 @@
}
blue->flags = 0;
if ( AF_LATIN_IS_TOP_BLUE(bb) )
if ( AF_LATIN_IS_TOP_BLUE( bb ) )
blue->flags |= AF_LATIN_BLUE_TOP;
/* the following flags is used later to adjust the y and x scales
* in order to optimize the pixel grid alignment of the top of small
* letters.
*/
/*
* The following flags is used later to adjust the y and x scales
* in order to optimize the pixel grid alignment of the top of small
* letters.
*/
if ( bb == AF_LATIN_BLUE_SMALL_TOP )
blue->flags |= AF_LATIN_BLUE_ADJUSTMENT;
@ -347,12 +357,14 @@
af_latin_metrics_init( AF_LatinMetrics metrics,
FT_Face face )
{
FT_Error error;
FT_CharMap oldmap = face->charmap;
FT_Error error;
FT_CharMap oldmap = face->charmap;
/* do we have a Unicode charmap in there? */
error = FT_Select_Charmap( face, FT_ENCODING_UNICODE );
if ( error ) goto Exit;
if ( error )
goto Exit;
metrics->units_per_em = face->units_per_EM;
@ -366,15 +378,16 @@
static void
af_latin_metrics_scale_dim( AF_LatinMetrics metrics,
AF_Scaler scaler,
AF_Dimension dim )
af_latin_metrics_scale_dim( AF_LatinMetrics metrics,
AF_Scaler scaler,
AF_Dimension dim )
{
FT_Fixed scale;
FT_Pos delta;
AF_LatinAxis axis;
FT_UInt nn;
if ( dim == AF_DIMENSION_HORZ )
{
scale = scaler->x_scale;
@ -386,7 +399,7 @@
delta = scaler->y_delta;
}
axis = & metrics->axis[ dim ];
axis = & metrics->axis[dim];
if ( axis->org_scale == scale && axis->org_delta == delta )
return;
@ -394,14 +407,16 @@
axis->org_scale = scale;
axis->org_delta = delta;
/* correct X and Y scale to optimize the alignment of the top of small
* letters to the pixel grid
*/
/*
* correct X and Y scale to optimize the alignment of the top of small
* letters to the pixel grid
*/
{
AF_LatinAxis axis = &metrics->axis[ AF_DIMENSION_VERT ];
AF_LatinBlue blue = NULL;
AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT];
AF_LatinBlue blue = NULL;
FT_UInt nn;
for ( nn = 0; nn < axis->blue_count; nn++ )
{
if ( axis->blues[nn].flags & AF_LATIN_BLUE_ADJUSTMENT )
@ -446,38 +461,38 @@
metrics->root.scaler.y_delta = delta;
}
/* scale the standard widths
*/
/* scale the standard widths */
for ( nn = 0; nn < axis->width_count; nn++ )
{
AF_Width width = axis->widths + nn;
width->cur = FT_MulFix( width->org, scale );
width->fit = width->cur;
}
if ( dim == AF_DIMENSION_VERT )
{
/* scale the blue zones
*/
/* scale the blue zones */
for ( nn = 0; nn < axis->blue_count; nn++ )
{
AF_LatinBlue blue = & axis->blues[nn];
AF_LatinBlue blue = &axis->blues[nn];
FT_Pos dist;
blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta;
blue->ref.fit = blue->ref.cur;
blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta;
blue->shoot.fit = blue->shoot.cur;
blue->flags &= ~AF_LATIN_BLUE_ACTIVE;
/* a blue zone is only active when it is less than 3/4 pixels tall
*/
/* a blue zone is only active if it is less than 3/4 pixels tall */
dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale );
if ( dist <= 48 && dist >= -48 )
{
FT_Pos delta, delta2;
delta = blue->shoot.org - blue->ref.org;
delta2 = delta;
if ( delta < 0 )
@ -514,13 +529,13 @@
}
/***************************************************************************/
/***************************************************************************/
/***** *****/
/***** L A T I N G L Y P H A N A L Y S I S *****/
/***** *****/
/***************************************************************************/
/***************************************************************************/
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** L A T I N G L Y P H A N A L Y S I S *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL_DEF( FT_Error )
af_latin_hints_compute_segments( AF_GlyphHints hints,
@ -528,17 +543,17 @@
{
AF_AxisHints axis = &hints->axis[dim];
FT_Memory memory = hints->memory;
FT_Error error = 0;
AF_Segment segment = NULL;
AF_Point* contour = hints->contours;
AF_Point* contour_limit = contour + hints->num_contours;
FT_Error error = FT_Err_Ok;
AF_Segment segment = NULL;
AF_Point* contour = hints->contours;
AF_Point* contour_limit = contour + hints->num_contours;
AF_Direction major_dir, segment_dir;
#ifdef AF_HINT_METRICS
AF_Point min_point = 0;
AF_Point max_point = 0;
FT_Pos min_coord = 32000;
FT_Pos max_coord = -32000;
AF_Point min_point = 0;
AF_Point max_point = 0;
FT_Pos min_coord = 32000;
FT_Pos max_coord = -32000;
#endif
major_dir = FT_ABS( axis->major_dir );
@ -552,6 +567,7 @@
AF_Point point = hints->points;
AF_Point limit = point + hints->num_points;
for ( ; point < limit; point++ )
{
point->u = point->fx;
@ -563,6 +579,7 @@
AF_Point point = hints->points;
AF_Point limit = point + hints->num_points;
for ( ; point < limit; point++ )
{
point->u = point->fy;
@ -570,7 +587,6 @@
}
}
/* do each contour separately */
for ( ; contour < contour_limit; contour++ )
{
@ -709,6 +725,7 @@
/* we need to ensure that there are edges on the left-most and */
/* right-most points of the glyph in order to hint the metrics; */
/* we do this by inserting fake segments when needed */
if ( dim == AF_DIMENSION_HORZ )
{
AF_Point point = hints->points;
@ -763,7 +780,7 @@
{
/* clear all segment fields */
error = af_axis_hints_new_segment( axis, memory, &segment );
if ( error)
if ( error )
goto Exit;
segment->dir = segment_dir;
@ -794,6 +811,7 @@
AF_Direction major_dir = axis->major_dir;
AF_Segment seg1, seg2;
/* now compare each segment to the others */
for ( seg1 = segments; seg1 < segment_limit; seg1++ )
{
@ -871,9 +889,9 @@
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_Segment segments = axis->segments;
AF_Segment segments = axis->segments;
AF_Segment segment_limit = segments + axis->num_segments;
AF_Segment seg;
@ -881,6 +899,7 @@
FT_Fixed scale;
FT_Pos edge_distance_threshold;
axis->num_edges = 0;
scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale
@ -918,6 +937,7 @@
AF_Edge found = 0;
FT_Int ee;
/* look for an edge corresponding to the segment */
for ( ee = 0; ee < axis->num_edges; ee++ )
{
@ -940,6 +960,7 @@
{
AF_Edge edge;
/* insert a new edge in the list and */
/* sort according to the position */
error = af_axis_hints_new_edge( axis, seg->pos, memory, &edge );
@ -947,7 +968,7 @@
goto Exit;
/* add the segment to the new edge's list */
FT_ZERO(edge);
FT_ZERO( edge );
edge->first = seg;
edge->last = seg;
@ -981,16 +1002,17 @@
/* first of all, set the `edge' field in each segment -- this is */
/* required in order to compute edge links */
/* Note that I've tried to remove this loop, setting
* the "edge" field of each segment directly in the
* code above. For some reason, it slows down execution
* speed -- on a Sun.
/*
* Note that removing this loop and setting the `edge' field of each
* segment directly in the code above slows down execution speed for
* some reasons on platforms like the Sun.
*/
{
AF_Edge edges = axis->edges;
AF_Edge edge_limit = edges + axis->num_edges;
AF_Edge edge;
for ( edge = edges; edge < edge_limit; edge++ )
{
seg = edge->first;
@ -999,8 +1021,8 @@
{
seg->edge = edge;
seg = seg->edge_next;
}
while ( seg != edge->first );
} while ( seg != edge->first );
}
/* now, compute each edge properties */
@ -1121,11 +1143,13 @@
{
FT_Error error;
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 );
af_latin_hints_link_segments( hints, dim );
error = af_latin_hints_compute_edges( hints, dim );
}
return error;
}
@ -1145,12 +1169,12 @@
/* compute which blue zones are active, i.e. have their scaled */
/* size < 3/4 pixels */
/* for each horizontal edge search the blue zone which is closest */
/* for each horizontal edge search the blue zone which is closest */
for ( ; edge < edge_limit; edge++ )
{
FT_Int bb;
AF_Width best_blue = NULL;
FT_Pos best_dist; /* initial threshold */
FT_Int bb;
AF_Width best_blue = NULL;
FT_Pos best_dist; /* initial threshold */
/* compute the initial threshold as a fraction of the EM size */
@ -1164,16 +1188,16 @@
AF_LatinBlue blue = latin->blues + bb;
FT_Bool is_top_blue, is_major_dir;
/* skip inactive blue zones (i.e. those that are too small
*/
if ( !(blue->flags & AF_LATIN_BLUE_ACTIVE) )
/* skip inactive blue zones (i.e., those that are too small) */
if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) )
continue;
/* if it is a top zone, check for right edges -- if it is a bottom */
/* zone, check for left edges */
/* */
/* of course, that's for TrueType */
is_top_blue = (blue->flags & AF_LATIN_BLUE_TOP) != 0;
is_top_blue = ( blue->flags & AF_LATIN_BLUE_TOP ) != 0;
is_major_dir = FT_BOOL( edge->dir == axis->major_dir );
/* if it is a top zone, the edge must be against the major */
@ -1181,7 +1205,7 @@
/* direction */
if ( is_top_blue ^ is_major_dir )
{
FT_Pos dist;
FT_Pos dist;
/* first of all, compare it to the reference position */
@ -1234,35 +1258,39 @@
{
FT_Render_Mode mode;
af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics );
/* correct x_scale and y_scale when needed, since they may have
* been modified af_latin_scale_dim above
*/
hints->x_scale = metrics->axis[ AF_DIMENSION_HORZ ].scale;
hints->x_delta = metrics->axis[ AF_DIMENSION_HORZ ].delta;
hints->y_scale = metrics->axis[ AF_DIMENSION_VERT ].scale;
hints->y_delta = metrics->axis[ AF_DIMENSION_VERT ].delta;
/*
* correct x_scale and y_scale when needed, since they may have
* been modified af_latin_scale_dim above
*/
hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale;
hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta;
hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale;
hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta;
/* compute flags depending on render mode, etc...
*/
/* compute flags depending on render mode, etc... */
mode = metrics->root.scaler.render_mode;
/* we snap the width of vertical stems for the monochrome and
* horizontal LCD rendering targets only.
*/
/*
* We snap the width of vertical stems for the monochrome and
* horizontal LCD rendering targets only.
*/
if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD )
hints->other_flags |= AF_LATIN_HINTS_HORZ_SNAP;
/* we snap the width of horizontal stems for the monochrome and
* vertical LCD rendering targets only.
*/
/*
* We snap the width of horizontal stems for the monochrome and
* vertical LCD rendering targets only.
*/
if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V )
hints->other_flags |= AF_LATIN_HINTS_VERT_SNAP;
/* XXX
*/
/*
* We adjust stems to full pixels only if we don't use the `light' mode.
*/
if ( mode != FT_RENDER_MODE_LIGHT )
hints->other_flags |= AF_LATIN_HINTS_STEM_ADJUST;
@ -1273,17 +1301,17 @@
}
/***************************************************************************/
/***************************************************************************/
/***** *****/
/***** L A T I N G L Y P H G R I D - F I T T I N G *****/
/***** *****/
/***************************************************************************/
/***************************************************************************/
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** L A T I N G L Y P H G R I D - F I T T I N G *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* snap a given width in scaled coordinates to one of the */
/* current standard widths */
static FT_Pos
af_latin_snap_width( AF_Width widths,
FT_Int count,
@ -1339,7 +1367,7 @@
AF_Edge_Flags stem_flags )
{
AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics;
AF_LatinAxis axis = & metrics->axis[ dim ];
AF_LatinAxis axis = & metrics->axis[dim];
FT_Pos dist = width;
FT_Int sign = 0;
FT_Int vertical = AF_HINTS_DO_VERTICAL( hints );
@ -1358,7 +1386,6 @@
( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) )
{
/* smooth hinting process: very lightly quantize the stem width */
/* */
/* leave the widths of serifs alone */
@ -1377,8 +1404,8 @@
{
FT_Pos delta;
/* compare to standard width
*/
/* compare to standard width */
if ( axis->width_count > 0 )
{
delta = dist - axis->widths[0].cur;
@ -1388,7 +1415,7 @@
if ( delta < 40 )
{
dist = axis->widths[ 0 ].cur;
dist = axis->widths[0].cur;
if ( dist < 48 )
dist = 48;
@ -1420,13 +1447,14 @@
else
{
/* strong hinting process: snap the stem width to integer pixels */
/* */
dist = af_latin_snap_width( axis->widths, axis->width_count, dist );
if ( vertical )
{
/* in the case of vertical hinting, always round */
/* the stem heights to integer pixels */
if ( dist >= 64 )
dist = ( dist + 16 ) & ~63;
else
@ -1438,6 +1466,7 @@
{
/* monochrome horizontal hinting: snap widths to integer pixels */
/* with a different threshold */
if ( dist < 64 )
dist = 64;
else
@ -1448,6 +1477,7 @@
/* for horizontal anti-aliased hinting, we adopt a more subtle */
/* approach: we strengthen small stems, round stems whose size */
/* is between 1 and 2 pixels to an integer, otherwise nothing */
if ( dist < 48 )
dist = ( dist + 64 ) >> 1;
@ -1468,8 +1498,8 @@
}
/* align one stem edge relative to the previous stem edge */
static void
af_latin_align_linked_edge( AF_GlyphHints hints,
AF_Dimension dim,
@ -1484,6 +1514,7 @@
base_edge->flags,
stem_edge->flags );
stem_edge->pos = base_edge->pos + fitted_width;
}
@ -1498,11 +1529,12 @@
serif->pos = base->pos + (serif->opos - base->opos);
}
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** E D G E H I N T I N G ****/
/**** E D G E H I N T I N G ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
@ -1510,20 +1542,21 @@
FT_LOCAL_DEF( void )
af_latin_hint_edges( AF_GlyphHints hints,
AF_Dimension dim )
af_latin_hint_edges( AF_GlyphHints hints,
AF_Dimension dim )
{
AF_AxisHints axis = & hints->axis[dim];
AF_Edge edges = axis->edges;
AF_AxisHints axis = &hints->axis[dim];
AF_Edge edges = axis->edges;
AF_Edge edge_limit = edges + axis->num_edges;
FT_Int n_edges;
AF_Edge edge;
AF_Edge anchor = 0;
AF_Edge anchor = 0;
FT_Int has_serifs = 0;
/* we begin by aligning all stems relative to the blue zone */
/* if needed -- that's only for horizontal edges */
if ( dim == AF_DIMENSION_VERT )
{
for ( edge = edges; edge < edge_limit; edge++ )
@ -1694,16 +1727,16 @@
org_len = edge2->opos - edge->opos;
org_center = org_pos + ( org_len >> 1 );
cur_len = af_latin_compute_stem_width( hints, dim, org_len,
edge->flags, edge2->flags );
cur_len = af_latin_compute_stem_width(
hints, dim, org_len, edge->flags, edge2->flags );
cur_pos1 = FT_PIX_ROUND( org_pos );
delta1 = ( cur_pos1 + ( cur_len >> 1 ) - org_center );
delta1 = cur_pos1 + ( cur_len >> 1 ) - org_center;
if ( delta1 < 0 )
delta1 = -delta1;
cur_pos2 = FT_PIX_ROUND( org_pos + org_len ) - cur_len;
delta2 = ( cur_pos2 + ( cur_len >> 1 ) - org_center );
delta2 = cur_pos2 + ( cur_len >> 1 ) - org_center;
if ( delta2 < 0 )
delta2 = -delta2;
@ -1722,7 +1755,7 @@
/* make sure that lowercase m's maintain their symmetry */
/* In general, lowercase m's have six vertical edges if they are sans */
/* serif, or twelve if they are avec serif. This implementation is */
/* serif, or twelve if they are with serifs. This implementation is */
/* based on that assumption, and seems to work very well with most */
/* faces. However, if for a certain face this assumption is not */
/* true, the m is just rendered like before. In addition, any stem */
@ -1783,9 +1816,10 @@
if ( has_serifs || !anchor )
{
/* now hint the remaining edges (serifs and single) in order
* to complete our processing
*/
/*
* now hint the remaining edges (serifs and single) in order
* to complete our processing
*/
for ( edge = edges; edge < edge_limit; edge++ )
{
if ( edge->flags & AF_EDGE_DONE )
@ -1824,34 +1858,33 @@
FT_Error error;
AF_Dimension dim;
error = af_glyph_hints_reload( hints, outline );
if ( error )
goto Exit;
/* analyze glyph outline
*/
if ( AF_HINTS_DO_HORIZONTAL(hints) )
/* analyze glyph outline */
if ( AF_HINTS_DO_HORIZONTAL( hints ) )
{
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 ) )
{
error = 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 );
}
/* grid-fit the outline
*/
/* grid-fit the outline */
for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
{
if ( (dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL(hints)) ||
(dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL(hints)) )
if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) ||
( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) )
{
af_latin_hint_edges( hints, dim );
af_glyph_hints_align_edge_points( hints, dim );
@ -1865,33 +1898,39 @@
return error;
}
/***************************************************************************/
/***************************************************************************/
/***** *****/
/***** L A T I N S C R I P T C L A S S *****/
/***** *****/
/***************************************************************************/
/***************************************************************************/
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** L A T I N S C R I P T C L A S S *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
static const AF_Script_UniRangeRec af_latin_uniranges[] =
{
{ 32, 127 }, /* XXX: TODO: Add new Unicode ranges here !! */
{ 32, 127 }, /* XXX: TODO: Add new Unicode ranges here! */
{ 160, 255 },
{ 0, 0 }
};
FT_LOCAL_DEF( const AF_ScriptClassRec ) af_latin_script_class =
FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec
af_latin_script_class =
{
AF_SCRIPT_LATIN,
af_latin_uniranges,
sizeof( AF_LatinMetricsRec ),
(AF_Script_InitMetricsFunc) af_latin_metrics_init,
(AF_Script_ScaleMetricsFunc) af_latin_metrics_scale,
(AF_Script_DoneMetricsFunc) NULL,
(AF_Script_InitHintsFunc) af_latin_hints_init,
(AF_Script_ApplyHintsFunc) af_latin_hints_apply
(AF_Script_InitMetricsFunc) af_latin_metrics_init,
(AF_Script_ScaleMetricsFunc)af_latin_metrics_scale,
(AF_Script_DoneMetricsFunc) NULL,
(AF_Script_InitHintsFunc) af_latin_hints_init,
(AF_Script_ApplyHintsFunc) af_latin_hints_apply
};
/* END */

View File

@ -3,32 +3,33 @@
#include "afhints.h"
FT_BEGIN_HEADER
/*
* the latin-specific script class
*
*/
FT_LOCAL( const AF_ScriptClassRec ) af_latin_script_class;
/***************************************************************************/
/***************************************************************************/
/***** *****/
/***** L A T I N G L O B A L M E T R I C S *****/
/***** *****/
/***************************************************************************/
/***************************************************************************/
/* the latin-specific script class */
/*
* the following declarations could be embedded in the file "aflatin.c"
* they've been made semi-public to allow alternate script hinters to
* re-use some of them
*/
FT_CALLBACK_TABLE const AF_ScriptClassRec
af_latin_script_class;
/*
* Latin (global) metrics management
*
*/
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** 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 have been made semi-public to allow alternate script hinters to
* re-use some of them.
*/
/* Latin (global) metrics management */
enum
{
@ -42,45 +43,47 @@ FT_BEGIN_HEADER
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 AF_LATIN_BLUE_MAX
#define AF_LATIN_MAX_WIDTHS 16
#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_ADJUSTMENT = (1 << 2), /* used for scale adjustment */
/* optimization */
AF_LATIN_BLUE_ACTIVE = ( 1 << 0 ),
AF_LATIN_BLUE_TOP = ( 1 << 1 ),
AF_LATIN_BLUE_ADJUSTMENT = ( 1 << 2 ), /* used for scale adjustment */
/* optimization */
AF_LATIN_BLUE_FLAG_MAX
};
typedef struct AF_LatinBlueRec_
typedef struct AF_LatinBlueRec_
{
AF_WidthRec ref;
AF_WidthRec shoot;
FT_UInt flags;
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_Pos delta;
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_UInt blue_count;
AF_LatinBlueRec blues[ AF_LATIN_BLUE_MAX ];
AF_LatinBlueRec blues[AF_LATIN_BLUE_MAX];
FT_Fixed org_scale;
FT_Pos org_delta;
@ -88,16 +91,15 @@ FT_BEGIN_HEADER
} AF_LatinAxisRec, *AF_LatinAxis;
typedef struct AF_LatinMetricsRec_
typedef struct AF_LatinMetricsRec_
{
AF_ScriptMetricsRec root;
FT_UInt units_per_em;
AF_LatinAxisRec axis[ AF_DIMENSION_MAX ];
AF_ScriptMetricsRec root;
FT_UInt units_per_em;
AF_LatinAxisRec axis[AF_DIMENSION_MAX];
} AF_LatinMetricsRec, *AF_LatinMetrics;
FT_LOCAL( FT_Error )
af_latin_metrics_init( AF_LatinMetrics metrics,
FT_Face face );
@ -108,52 +110,58 @@ FT_BEGIN_HEADER
/***************************************************************************/
/***************************************************************************/
/***** *****/
/***** L A T I N G L Y P H A N A L Y S I S *****/
/***** *****/
/***************************************************************************/
/***************************************************************************/
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** L A T I N G L Y P H A N A L Y S I S *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
enum
{
AF_LATIN_HINTS_HORZ_SNAP = (1 << 0), /* enable stem width snapping */
AF_LATIN_HINTS_VERT_SNAP = (1 << 1), /* enable stem height snapping */
AF_LATIN_HINTS_STEM_ADJUST = (1 << 2), /* enable stem width/height adjustment */
AF_LATIN_HINTS_MONO = (1 << 3) /* indicate monochrome rendering */
AF_LATIN_HINTS_HORZ_SNAP = ( 1 << 0 ), /* enable stem width snapping */
AF_LATIN_HINTS_VERT_SNAP = ( 1 << 1 ), /* enable stem height snapping */
AF_LATIN_HINTS_STEM_ADJUST = ( 1 << 2 ), /* enable stem width/height
adjustment */
AF_LATIN_HINTS_MONO = ( 1 << 3 ) /* indicate monochrome
rendering */
};
#define AF_LATIN_HINTS_DO_HORZ_SNAP(h) \
AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_HORZ_SNAP)
#define AF_LATIN_HINTS_DO_VERT_SNAP(h) \
AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_VERT_SNAP)
#define AF_LATIN_HINTS_DO_HORZ_SNAP( h ) \
AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_HORZ_SNAP )
#define AF_LATIN_HINTS_DO_STEM_ADJUST(h) \
AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_STEM_ADJUST)
#define AF_LATIN_HINTS_DO_VERT_SNAP( h ) \
AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_VERT_SNAP )
#define AF_LATIN_HINTS_DO_MONO(h) \
AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_MONO)
#define AF_LATIN_HINTS_DO_STEM_ADJUST( h ) \
AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_STEM_ADJUST )
#define AF_LATIN_HINTS_DO_MONO( h ) \
AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_MONO )
/* this shouldn't normally be exported. However, other scripts might
* like to use this function as-is
*/
/*
* This shouldn't normally be exported. However, other scripts might
* like to use this function as-is.
*/
FT_LOCAL( FT_Error )
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
*/
/*
* 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
*/
/*
* This shouldn't normally be exported. However, other scripts might
* want to use this function as-is.
*/
FT_LOCAL( FT_Error )
af_latin_hints_compute_edges( AF_GlyphHints hints,
AF_Dimension dim );
@ -167,3 +175,6 @@ FT_BEGIN_HEADER
FT_END_HEADER
#endif /* __AFLATIN_H__ */
/* END */

View File

@ -3,12 +3,14 @@
#include "afglobal.h"
#include "aflatin.h"
FT_LOCAL_DEF( FT_Error )
af_loader_init( AF_Loader loader,
FT_Memory memory )
{
FT_Error error;
FT_ZERO( loader );
af_glyph_hints_init( &loader->hints, memory );
@ -28,13 +30,14 @@
FT_LOCAL_DEF( FT_Error )
af_loader_reset( AF_Loader loader,
FT_Face face )
af_loader_reset( AF_Loader loader,
FT_Face face )
{
FT_Error error = 0;
FT_Error error = FT_Err_Ok;
loader->face = face;
loader->globals = (AF_FaceGlobals) face->autohint.data;
loader->globals = (AF_FaceGlobals)face->autohint.data;
FT_GlyphLoader_Rewind( loader->gloader );
@ -43,16 +46,19 @@
error = af_face_globals_new( face, &loader->globals );
if ( !error )
{
face->autohint.data = (FT_Pointer) loader->globals;
face->autohint.finalizer = (FT_Generic_Finalizer) af_face_globals_free;
face->autohint.data =
(FT_Pointer)loader->globals;
face->autohint.finalizer =
(FT_Generic_Finalizer)af_face_globals_free;
}
}
return error;
}
FT_LOCAL_DEF( void )
af_loader_done( AF_Loader loader )
af_loader_done( AF_Loader loader )
{
af_glyph_hints_done( &loader->hints );
@ -71,7 +77,7 @@
FT_Int32 load_flags,
FT_UInt depth )
{
FT_Error error = 0;
FT_Error error;
FT_Face face = loader->face;
FT_GlyphLoader gloader = loader->gloader;
AF_ScriptMetrics metrics = loader->metrics;
@ -79,6 +85,7 @@
FT_GlyphSlot slot = face->glyph;
FT_Slot_Internal internal = slot->internal;
error = FT_Load_Glyph( face, glyph_index, load_flags );
if ( error )
goto Exit;
@ -88,6 +95,7 @@
{
FT_Matrix inverse;
loader->trans_matrix = internal->glyph_matrix;
loader->trans_delta = internal->glyph_delta;
@ -102,115 +110,114 @@
switch ( slot->format )
{
case FT_GLYPH_FORMAT_OUTLINE:
/* translate the loaded glyph when an internal transform
* is needed
*/
if ( loader->transformed )
FT_Outline_Translate( &slot->outline,
loader->trans_delta.x,
loader->trans_delta.y );
case FT_GLYPH_FORMAT_OUTLINE:
/* translate the loaded glyph when an internal transform is needed */
if ( loader->transformed )
FT_Outline_Translate( &slot->outline,
loader->trans_delta.x,
loader->trans_delta.y );
/* copy the outline points in the loader's current */
/* extra points which is used to keep original glyph coordinates */
error = FT_GlyphLoader_CheckPoints( gloader,
slot->outline.n_points + 4,
slot->outline.n_contours );
if ( error )
goto Exit;
/* copy the outline points in the loader's current */
/* extra points which is used to keep original glyph coordinates */
error = FT_GlyphLoader_CheckPoints( gloader,
slot->outline.n_points + 4,
slot->outline.n_contours );
if ( error )
goto Exit;
FT_ARRAY_COPY( gloader->current.outline.points,
slot->outline.points,
slot->outline.n_points );
FT_ARRAY_COPY( gloader->current.outline.points,
slot->outline.points,
slot->outline.n_points );
FT_ARRAY_COPY( gloader->current.extra_points,
slot->outline.points,
slot->outline.n_points );
FT_ARRAY_COPY( gloader->current.extra_points,
slot->outline.points,
slot->outline.n_points );
FT_ARRAY_COPY( gloader->current.outline.contours,
slot->outline.contours,
slot->outline.n_contours );
FT_ARRAY_COPY( gloader->current.outline.contours,
slot->outline.contours,
slot->outline.n_contours );
FT_ARRAY_COPY( gloader->current.outline.tags,
slot->outline.tags,
slot->outline.n_points );
FT_ARRAY_COPY( gloader->current.outline.tags,
slot->outline.tags,
slot->outline.n_points );
gloader->current.outline.n_points = slot->outline.n_points;
gloader->current.outline.n_contours = slot->outline.n_contours;
gloader->current.outline.n_points = slot->outline.n_points;
gloader->current.outline.n_contours = slot->outline.n_contours;
/* compute original horizontal phantom points (and ignore */
/* vertical ones) */
loader->pp1.x = hints->x_delta;
loader->pp1.y = hints->y_delta;
loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance,
hints->x_scale ) + hints->x_delta;
loader->pp2.y = hints->y_delta;
/* compute original horizontal phantom points (and ignore */
/* vertical ones) */
loader->pp1.x = hints->x_delta;
loader->pp1.y = hints->y_delta;
loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance,
hints->x_scale ) + hints->x_delta;
loader->pp2.y = hints->y_delta;
/* be sure to check for spacing glyphs */
if ( slot->outline.n_points == 0 )
goto Hint_Metrics;
/* be sure to check for spacing glyphs */
if ( slot->outline.n_points == 0 )
goto Hint_Metrics;
/* now load the slot image into the auto-outline and run the */
/* automatic hinting process */
metrics->clazz->script_hints_apply( hints,
&gloader->current.outline,
metrics );
/* now load the slot image into the auto-outline and run the */
/* automatic hinting process */
metrics->clazz->script_hints_apply( hints,
&gloader->current.outline,
metrics );
/* we now need to hint the metrics according to the change in */
/* width/positioning that occured during the hinting process */
/* we now need to hint the metrics according to the change in */
/* width/positioning that occured during the hinting process */
{
FT_Pos old_advance, old_rsb, old_lsb, new_lsb;
FT_Pos pp1x_uh, pp2x_uh;
AF_AxisHints axis = &hints->axis[ AF_DIMENSION_HORZ ];
AF_Edge edge1 = axis->edges; /* leftmost edge */
AF_Edge edge2 = edge1 +
axis->num_edges - 1; /* rightmost edge */
if ( axis->num_edges > 1 )
{
FT_Pos old_advance, old_rsb, old_lsb, new_lsb;
FT_Pos pp1x_uh, pp2x_uh;
AF_AxisHints axis = &hints->axis[ AF_DIMENSION_HORZ ];
AF_Edge edge1 = axis->edges; /* leftmost edge */
AF_Edge edge2 = edge1 +
axis->num_edges - 1; /* rightmost edge */
old_advance = loader->pp2.x;
old_rsb = old_advance - edge2->opos;
old_lsb = edge1->opos;
new_lsb = edge1->pos;
/* remember unhinted values to later account */
/* for rounding errors */
if ( axis->num_edges > 1 )
{
old_advance = loader->pp2.x;
old_rsb = old_advance - edge2->opos;
old_lsb = edge1->opos;
new_lsb = edge1->pos;
pp1x_uh = new_lsb - old_lsb;
pp2x_uh = edge2->pos + old_rsb;
/* remember unhinted values to later account */
/* for rounding errors */
/* prefer too much space over too little space */
/* for very small sizes */
pp1x_uh = new_lsb - old_lsb;
pp2x_uh = edge2->pos + old_rsb;
if ( old_lsb < 24 )
pp1x_uh -= 5;
/* prefer too much space over too little space */
/* for very small sizes */
if ( old_rsb < 24 )
pp2x_uh += 5;
if ( old_lsb < 24 )
pp1x_uh -= 5;
loader->pp1.x = FT_PIX_ROUND( pp1x_uh );
loader->pp2.x = FT_PIX_ROUND( pp2x_uh );
if ( old_rsb < 24 )
pp2x_uh += 5;
loader->pp1.x = FT_PIX_ROUND( pp1x_uh );
loader->pp2.x = FT_PIX_ROUND( pp2x_uh );
slot->lsb_delta = loader->pp1.x - pp1x_uh;
slot->rsb_delta = loader->pp2.x - pp2x_uh;
slot->lsb_delta = loader->pp1.x - pp1x_uh;
slot->rsb_delta = loader->pp2.x - pp2x_uh;
#if 0
/* try to fix certain bad advance computations */
if ( loader->pp2.x + loader->pp1.x == edge2->pos && old_rsb > 4 )
loader->pp2.x += 64;
/* try to fix certain bad advance computations */
if ( loader->pp2.x + loader->pp1.x == edge2->pos && old_rsb > 4 )
loader->pp2.x += 64;
#endif
}
else
{
loader->pp1.x = FT_PIX_ROUND( loader->pp1.x );
loader->pp2.x = FT_PIX_ROUND( loader->pp2.x );
}
}
/* good, we simply add the glyph to our loader's base */
FT_GlyphLoader_Add( gloader );
break;
}
else
{
loader->pp1.x = FT_PIX_ROUND( loader->pp1.x );
loader->pp2.x = FT_PIX_ROUND( loader->pp2.x );
}
}
/* good, we simply add the glyph to our loader's base */
FT_GlyphLoader_Add( gloader );
break;
case FT_GLYPH_FORMAT_COMPOSITE:
{
@ -231,7 +238,7 @@
num_subglyphs );
gloader->current.num_subglyphs = num_subglyphs;
num_base_subgs = gloader->base.num_subglyphs;
num_base_subgs = gloader->base.num_subglyphs;
/* now, read each subglyph independently */
for ( nn = 0; nn < num_subglyphs; nn++ )
@ -325,8 +332,8 @@
x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta;
y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta;
x = FT_PIX_ROUND(x);
y = FT_PIX_ROUND(y);
x = FT_PIX_ROUND( x );
y = FT_PIX_ROUND( y );
}
{
@ -364,10 +371,10 @@
FT_Outline_Get_CBox( &gloader->base.outline, &bbox );
bbox.xMin = FT_PIX_FLOOR( bbox.xMin );
bbox.yMin = FT_PIX_FLOOR( bbox.yMin );
bbox.xMax = FT_PIX_CEIL( bbox.xMax );
bbox.yMax = FT_PIX_CEIL( bbox.yMax );
bbox.xMin = FT_PIX_FLOOR( bbox.xMin );
bbox.yMin = FT_PIX_FLOOR( bbox.yMin );
bbox.xMax = FT_PIX_CEIL( bbox.xMax );
bbox.yMax = FT_PIX_CEIL( bbox.yMax );
slot->metrics.width = bbox.xMax - bbox.xMin;
slot->metrics.height = bbox.yMax - bbox.yMin;
@ -383,8 +390,6 @@
slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
x_scale );
#else
/* for mono-width fonts (like Andale, Courier, etc.) we need */
/* to keep the original rounded advance width */
if ( !FT_IS_FIXED_WIDTH( slot->face ) )
slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
else
@ -413,8 +418,6 @@
}
FT_LOCAL_DEF( FT_Error )
af_loader_load_glyph( AF_Loader loader,
FT_Face face,
@ -425,6 +428,7 @@
FT_Size size = face->size;
AF_ScalerRec scaler;
if ( !size )
return FT_Err_Invalid_Argument;
@ -444,7 +448,9 @@
{
AF_ScriptMetrics metrics;
error = af_face_globals_get_metrics( loader->globals, gindex, &metrics );
error = af_face_globals_get_metrics( loader->globals, gindex,
&metrics );
if ( !error )
{
loader->metrics = metrics;
@ -467,3 +473,6 @@
Exit:
return error;
}
/* END */

View File

@ -3,7 +3,7 @@
#
# AUTO driver directory
# AUTOF driver directory
#
AUTOF_DIR := $(SRC_DIR)/autofit
@ -13,23 +13,23 @@ AUTOF_DIR := $(SRC_DIR)/autofit
AUTOF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(AUTOF_DIR))
# AUTO driver sources (i.e., C files)
# AUTOF driver sources (i.e., C files)
#
AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \
$(AUTOF_DIR)/afdummy.c \
$(AUTOF_DIR)/afglobal.c \
$(AUTOF_DIR)/afhints.c \
$(AUTOF_DIR)/afhints.c \
$(AUTOF_DIR)/afloader.c \
AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \
$(AUTOF_DIR)/afdummy.c \
$(AUTOF_DIR)/afglobal.c \
$(AUTOF_DIR)/afhints.c \
$(AUTOF_DIR)/aflatin.c \
$(AUTOF_DIR)/afloader.c \
$(AUTOF_DIR)/afmodule.c
# AUTO driver headers
# AUTOF driver headers
#
AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h) \
AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h) \
$(AUTOF_DIR)/aftypes.h
# AUTO driver object(s)
# AUTOF driver object(s)
#
# AUTOF_DRV_OBJ_M is used during `multi' builds.
# AUTOF_DRV_OBJ_S is used during `single' builds.
@ -37,19 +37,19 @@ AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h) \
AUTOF_DRV_OBJ_M := $(AUTOF_DRV_SRC:$(AUTOF_DIR)/%.c=$(OBJ_DIR)/%.$O)
AUTOF_DRV_OBJ_S := $(OBJ_DIR)/autofit.$O
# AUTO driver source file for single build
# AUTOF driver source file for single build
#
AUTOF_DRV_SRC_S := $(AUTOF_DIR)/autofit.c
# AUTO driver - single object
# AUTOF driver - single object
#
$(AUTOF_DRV_OBJ_S): $(AUTOF_DRV_SRC_S) $(AUTOF_DRV_SRC) \
$(FREETYPE_H) $(AUTOF_DRV_H)
$(AUTOF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(AUTOF_DRV_SRC_S))
# AUTO driver - multiple objects
# AUTOF driver - multiple objects
#
$(OBJ_DIR)/%.$O: $(AUTOF_DIR)/%.c $(FREETYPE_H) $(AUTOF_DRV_H)
$(AUTOF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)

View File

@ -197,7 +197,8 @@
FT_UInt coverage = FT_NEXT_USHORT( p );
FT_Int value = 0;
FT_UNUSED(version);
FT_UNUSED( version );
next = base + length;

View File

@ -4,7 +4,7 @@
/* */
/* TrueType and OpenType embedded bitmap support (specification). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */

View File

@ -535,11 +535,11 @@
static FT_Error
tt_sbit_decoder_load_bit_aligned ( TT_SBitDecoder decoder,
FT_Byte* p,
FT_Byte* limit,
FT_Int x_pos,
FT_Int y_pos )
tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder,
FT_Byte* p,
FT_Byte* limit,
FT_Int x_pos,
FT_Int y_pos )
{
FT_Error error = SFNT_Err_Ok;
FT_Byte* line;
@ -629,7 +629,7 @@
FT_Int x_pos,
FT_Int y_pos )
{
FT_Error error = 0;
FT_Error error = SFNT_Err_Ok;
FT_UInt num_components, nn;