* 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:
parent
1e03fff62b
commit
b19b0810cd
59
ChangeLog
59
ChangeLog
@ -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>
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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),$@ $<)
|
||||
|
@ -197,7 +197,8 @@
|
||||
FT_UInt coverage = FT_NEXT_USHORT( p );
|
||||
FT_Int value = 0;
|
||||
|
||||
FT_UNUSED(version);
|
||||
FT_UNUSED( version );
|
||||
|
||||
|
||||
next = base + length;
|
||||
|
||||
|
@ -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, */
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user