2005-03-03 18:09:08 +01:00
|
|
|
/***************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* afhints.c */
|
|
|
|
/* */
|
|
|
|
/* Auto-fitter hinting routines (body). */
|
|
|
|
/* */
|
2007-01-13 09:45:00 +01:00
|
|
|
/* Copyright 2003, 2004, 2005, 2006, 2007 by */
|
2005-03-03 18:09:08 +01:00
|
|
|
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
|
|
|
/* */
|
|
|
|
/* This file is part of the FreeType project, and may only be used, */
|
|
|
|
/* modified, and distributed under the terms of the FreeType project */
|
|
|
|
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
|
|
|
/* this file you indicate that you have read the license and */
|
|
|
|
/* understand and accept it fully. */
|
|
|
|
/* */
|
|
|
|
/***************************************************************************/
|
|
|
|
|
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
#include "afhints.h"
|
2005-03-23 17:45:24 +01:00
|
|
|
#include "aferrors.h"
|
2006-11-02 18:21:02 +01:00
|
|
|
#include FT_INTERNAL_CALC_H
|
2005-03-01 16:48:29 +01:00
|
|
|
|
2006-11-03 10:40:12 +01:00
|
|
|
|
2005-03-01 16:48:29 +01:00
|
|
|
FT_LOCAL_DEF( FT_Error )
|
|
|
|
af_axis_hints_new_segment( AF_AxisHints axis,
|
|
|
|
FT_Memory memory,
|
|
|
|
AF_Segment *asegment )
|
|
|
|
{
|
2005-03-23 17:45:24 +01:00
|
|
|
FT_Error error = AF_Err_Ok;
|
2005-03-01 16:48:29 +01:00
|
|
|
AF_Segment segment = NULL;
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
|
2005-03-01 16:48:29 +01:00
|
|
|
if ( axis->num_segments >= axis->max_segments )
|
|
|
|
{
|
|
|
|
FT_Int old_max = axis->max_segments;
|
|
|
|
FT_Int new_max = old_max;
|
2005-03-02 12:24:23 +01:00
|
|
|
FT_Int big_max = FT_INT_MAX / sizeof ( *segment );
|
|
|
|
|
2005-03-01 16:48:29 +01:00
|
|
|
|
|
|
|
if ( old_max >= big_max )
|
|
|
|
{
|
2005-03-23 17:45:24 +01:00
|
|
|
error = AF_Err_Out_Of_Memory;
|
2005-03-01 16:48:29 +01:00
|
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
|
2005-04-04 00:09:41 +02:00
|
|
|
new_max += ( new_max >> 2 ) + 4;
|
2005-03-01 16:48:29 +01:00
|
|
|
if ( new_max < old_max || new_max > big_max )
|
|
|
|
new_max = big_max;
|
|
|
|
|
|
|
|
if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) )
|
|
|
|
goto Exit;
|
|
|
|
|
|
|
|
axis->max_segments = new_max;
|
|
|
|
}
|
|
|
|
|
|
|
|
segment = axis->segments + axis->num_segments++;
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
#if 0
|
2005-03-01 16:48:29 +01:00
|
|
|
FT_ZERO( segment );
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
#endif
|
2005-03-01 16:48:29 +01:00
|
|
|
|
|
|
|
Exit:
|
|
|
|
*asegment = segment;
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
|
2005-03-03 18:09:08 +01:00
|
|
|
FT_LOCAL( FT_Error )
|
2005-03-01 16:48:29 +01:00
|
|
|
af_axis_hints_new_edge( AF_AxisHints axis,
|
|
|
|
FT_Int fpos,
|
|
|
|
FT_Memory memory,
|
|
|
|
AF_Edge *aedge )
|
|
|
|
{
|
2005-03-23 17:45:24 +01:00
|
|
|
FT_Error error = AF_Err_Ok;
|
2005-03-02 12:24:23 +01:00
|
|
|
AF_Edge edge = NULL;
|
|
|
|
AF_Edge edges;
|
|
|
|
|
2005-03-01 16:48:29 +01:00
|
|
|
|
|
|
|
if ( axis->num_edges >= axis->max_edges )
|
|
|
|
{
|
|
|
|
FT_Int old_max = axis->max_edges;
|
|
|
|
FT_Int new_max = old_max;
|
2005-03-02 12:24:23 +01:00
|
|
|
FT_Int big_max = FT_INT_MAX / sizeof ( *edge );
|
|
|
|
|
2005-03-01 16:48:29 +01:00
|
|
|
|
|
|
|
if ( old_max >= big_max )
|
|
|
|
{
|
2005-03-23 17:45:24 +01:00
|
|
|
error = AF_Err_Out_Of_Memory;
|
2005-03-01 16:48:29 +01:00
|
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
|
2005-04-04 00:09:41 +02:00
|
|
|
new_max += ( new_max >> 2 ) + 4;
|
2005-03-01 16:48:29 +01:00
|
|
|
if ( new_max < old_max || new_max > big_max )
|
|
|
|
new_max = big_max;
|
|
|
|
|
|
|
|
if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) )
|
|
|
|
goto Exit;
|
|
|
|
|
|
|
|
axis->max_edges = new_max;
|
|
|
|
}
|
|
|
|
|
|
|
|
edges = axis->edges;
|
|
|
|
edge = edges + axis->num_edges;
|
|
|
|
|
|
|
|
while ( edge > edges && edge[-1].fpos > fpos )
|
|
|
|
{
|
|
|
|
edge[0] = edge[-1];
|
|
|
|
edge--;
|
|
|
|
}
|
|
|
|
|
|
|
|
axis->num_edges++;
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
FT_ZERO( edge );
|
|
|
|
edge->fpos = (FT_Short)fpos;
|
2005-03-01 16:48:29 +01:00
|
|
|
|
|
|
|
Exit:
|
|
|
|
*aedge = edge;
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
#ifdef AF_DEBUG
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
static const char*
|
|
|
|
af_dir_str( AF_Direction dir )
|
2004-03-27 09:43:17 +01:00
|
|
|
{
|
|
|
|
const char* result;
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
|
|
|
|
switch ( dir )
|
2004-03-27 09:43:17 +01:00
|
|
|
{
|
2005-03-02 12:24:23 +01:00
|
|
|
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";
|
2004-03-27 09:43:17 +01:00
|
|
|
}
|
2005-03-02 12:24:23 +01:00
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
|
|
|
|
#define AF_INDEX_NUM( ptr, base ) ( (ptr) ? ( (ptr) - (base) ) : -1 )
|
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
void
|
|
|
|
af_glyph_hints_dump_points( AF_GlyphHints hints )
|
|
|
|
{
|
|
|
|
AF_Point points = hints->points;
|
|
|
|
AF_Point limit = points + hints->num_points;
|
|
|
|
AF_Point point;
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
printf( "Table of points:\n" );
|
2005-03-02 12:24:23 +01:00
|
|
|
printf( " [ index | xorg | yorg | xscale | yscale "
|
|
|
|
"| xfit | yfit | flags ]\n" );
|
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
for ( point = points; point < limit; point++ )
|
|
|
|
{
|
2005-03-02 12:24:23 +01:00
|
|
|
printf( " [ %5d | %5d | %5d | %-5.2f | %-5.2f "
|
|
|
|
"| %-5.2f | %-5.2f | %c%c%c%c%c%c ]\n",
|
2004-03-27 09:43:17 +01:00
|
|
|
point - points,
|
|
|
|
point->fx,
|
|
|
|
point->fy,
|
|
|
|
point->ox/64.0,
|
|
|
|
point->oy/64.0,
|
|
|
|
point->x/64.0,
|
|
|
|
point->y/64.0,
|
2005-03-02 12:24:23 +01:00
|
|
|
( 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' : ' ');
|
2004-03-27 09:43:17 +01:00
|
|
|
}
|
|
|
|
printf( "\n" );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
/* A function to dump the array of linked segments. */
|
2004-03-27 09:43:17 +01:00
|
|
|
void
|
|
|
|
af_glyph_hints_dump_segments( AF_GlyphHints hints )
|
|
|
|
{
|
2007-01-13 09:45:00 +01:00
|
|
|
FT_Int dimension;
|
2005-03-02 12:24:23 +01:00
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
for ( dimension = 1; dimension >= 0; dimension-- )
|
|
|
|
{
|
2005-03-02 12:24:23 +01:00
|
|
|
AF_AxisHints axis = &hints->axis[dimension];
|
2004-03-27 09:43:17 +01:00
|
|
|
AF_Segment segments = axis->segments;
|
|
|
|
AF_Segment limit = segments + axis->num_segments;
|
|
|
|
AF_Segment seg;
|
|
|
|
|
|
|
|
|
|
|
|
printf ( "Table of %s segments:\n",
|
|
|
|
dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );
|
|
|
|
printf ( " [ index | pos | dir | link | serif |"
|
2006-11-23 15:49:48 +01:00
|
|
|
" height | extra ]\n" );
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
for ( seg = segments; seg < limit; seg++ )
|
|
|
|
{
|
2006-11-23 15:49:48 +01:00
|
|
|
printf ( " [ %5d | %4d | %5s | %4d | %5d | %5d | %5d ]\n",
|
2004-03-27 09:43:17 +01:00
|
|
|
seg - segments,
|
|
|
|
(int)seg->pos,
|
2007-01-13 09:45:00 +01:00
|
|
|
af_dir_str( (AF_Direction)seg->dir ),
|
2004-03-27 09:43:17 +01:00
|
|
|
AF_INDEX_NUM( seg->link, segments ),
|
|
|
|
AF_INDEX_NUM( seg->serif, segments ),
|
2006-11-23 15:49:48 +01:00
|
|
|
seg->height,
|
2006-12-01 09:20:47 +01:00
|
|
|
seg->height - ( seg->max_coord - seg->min_coord ) );
|
2004-03-27 09:43:17 +01:00
|
|
|
}
|
|
|
|
printf( "\n" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
af_glyph_hints_dump_edges( AF_GlyphHints hints )
|
|
|
|
{
|
2005-03-02 12:24:23 +01:00
|
|
|
FT_Int dimension;
|
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
for ( dimension = 1; dimension >= 0; dimension-- )
|
|
|
|
{
|
2005-03-02 12:24:23 +01:00
|
|
|
AF_AxisHints axis = &hints->axis[dimension];
|
2004-03-27 09:43:17 +01:00
|
|
|
AF_Edge edges = axis->edges;
|
|
|
|
AF_Edge limit = edges + axis->num_edges;
|
|
|
|
AF_Edge edge;
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* note: AF_DIMENSION_HORZ corresponds to _vertical_ edges
|
|
|
|
* since they have constant a X coordinate.
|
|
|
|
*/
|
2004-03-27 09:43:17 +01:00
|
|
|
printf ( "Table of %s edges:\n",
|
|
|
|
dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );
|
|
|
|
printf ( " [ index | pos | dir | link |"
|
|
|
|
" serif | blue | opos | pos ]\n" );
|
|
|
|
|
|
|
|
for ( edge = edges; edge < limit; edge++ )
|
|
|
|
{
|
2005-03-02 12:24:23 +01:00
|
|
|
printf ( " [ %5d | %4d | %5s | %4d |"
|
|
|
|
" %5d | %c | %5.2f | %5.2f ]\n",
|
2004-03-27 09:43:17 +01:00
|
|
|
edge - edges,
|
|
|
|
(int)edge->fpos,
|
2007-01-13 09:45:00 +01:00
|
|
|
af_dir_str( (AF_Direction)edge->dir ),
|
2004-03-27 09:43:17 +01:00
|
|
|
AF_INDEX_NUM( edge->link, edges ),
|
|
|
|
AF_INDEX_NUM( edge->serif, edges ),
|
|
|
|
edge->blue_edge ? 'y' : 'n',
|
|
|
|
edge->opos / 64.0,
|
|
|
|
edge->pos / 64.0 );
|
|
|
|
}
|
|
|
|
printf( "\n" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-12-01 09:20:47 +01:00
|
|
|
#else /* !AF_DEBUG */
|
|
|
|
|
|
|
|
/* these empty stubs are only used to link the `ftgrid' test program */
|
|
|
|
/* when debugging is disabled */
|
|
|
|
|
2006-11-25 02:30:40 +01:00
|
|
|
void
|
|
|
|
af_glyph_hints_dump_points( AF_GlyphHints hints )
|
|
|
|
{
|
2006-12-01 09:20:47 +01:00
|
|
|
FT_UNUSED( hints );
|
2006-11-25 02:30:40 +01:00
|
|
|
}
|
|
|
|
|
2006-12-01 09:20:47 +01:00
|
|
|
|
2006-11-25 02:30:40 +01:00
|
|
|
void
|
|
|
|
af_glyph_hints_dump_segments( AF_GlyphHints hints )
|
|
|
|
{
|
2006-12-01 09:20:47 +01:00
|
|
|
FT_UNUSED( hints );
|
2006-11-25 02:30:40 +01:00
|
|
|
}
|
|
|
|
|
2006-12-01 09:20:47 +01:00
|
|
|
|
2006-11-25 02:30:40 +01:00
|
|
|
void
|
|
|
|
af_glyph_hints_dump_edges( AF_GlyphHints hints )
|
|
|
|
{
|
2006-12-01 09:20:47 +01:00
|
|
|
FT_UNUSED( hints );
|
2006-11-25 02:30:40 +01:00
|
|
|
}
|
|
|
|
|
2006-12-01 09:20:47 +01:00
|
|
|
#endif /* !AF_DEBUG */
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* compute the direction value of a given vector */
|
|
|
|
FT_LOCAL_DEF( AF_Direction )
|
|
|
|
af_direction_compute( FT_Pos dx,
|
|
|
|
FT_Pos dy )
|
|
|
|
{
|
2006-05-18 00:55:04 +02:00
|
|
|
|
2005-10-28 18:14:14 +02:00
|
|
|
#if 1
|
2006-05-18 00:55:04 +02:00
|
|
|
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
FT_Pos ll, ss; /* long and short arm lengths */
|
|
|
|
AF_Direction dir; /* candidate direction */
|
2005-10-28 18:14:14 +02:00
|
|
|
|
2006-05-18 00:55:04 +02:00
|
|
|
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
if ( dy >= dx )
|
2005-10-28 18:14:14 +02:00
|
|
|
{
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
if ( dy >= -dx )
|
2005-10-28 18:14:14 +02:00
|
|
|
{
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
dir = AF_DIR_UP;
|
|
|
|
ll = dy;
|
|
|
|
ss = dx;
|
2005-10-28 18:14:14 +02:00
|
|
|
}
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
else
|
2005-10-28 18:14:14 +02:00
|
|
|
{
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
dir = AF_DIR_LEFT;
|
|
|
|
ll = -dx;
|
|
|
|
ss = dy;
|
2005-10-28 18:14:14 +02:00
|
|
|
}
|
|
|
|
}
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
else /* dy < dx */
|
2005-10-28 18:14:14 +02:00
|
|
|
{
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
if ( dy >= -dx )
|
2005-10-28 18:14:14 +02:00
|
|
|
{
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
dir = AF_DIR_RIGHT;
|
|
|
|
ll = dx;
|
|
|
|
ss = dy;
|
2005-10-28 18:14:14 +02:00
|
|
|
}
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
else
|
2005-10-28 18:14:14 +02:00
|
|
|
{
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
dir = AF_DIR_DOWN;
|
|
|
|
ll = dy;
|
|
|
|
ss = dx;
|
2005-10-28 18:14:14 +02:00
|
|
|
}
|
|
|
|
}
|
2005-11-12 08:34:40 +01:00
|
|
|
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
ss *= 12;
|
2006-11-02 17:37:35 +01:00
|
|
|
if ( FT_ABS(ll) <= FT_ABS(ss) )
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
dir = AF_DIR_NONE;
|
2005-11-12 08:34:40 +01:00
|
|
|
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
return dir;
|
2006-05-18 00:55:04 +02:00
|
|
|
|
2005-11-12 08:34:40 +01:00
|
|
|
#else /* 0 */
|
2006-05-18 00:55:04 +02:00
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
AF_Direction dir;
|
|
|
|
FT_Pos ax = FT_ABS( dx );
|
|
|
|
FT_Pos ay = FT_ABS( dy );
|
|
|
|
|
|
|
|
|
|
|
|
dir = AF_DIR_NONE;
|
|
|
|
|
|
|
|
/* atan(1/12) == 4.7 degrees */
|
|
|
|
|
|
|
|
/* test for vertical direction */
|
|
|
|
if ( ax * 12 < ay )
|
|
|
|
{
|
|
|
|
dir = dy > 0 ? AF_DIR_UP : AF_DIR_DOWN;
|
|
|
|
}
|
|
|
|
/* test for horizontal direction */
|
|
|
|
else if ( ay * 12 < ax )
|
|
|
|
{
|
|
|
|
dir = dx > 0 ? AF_DIR_RIGHT : AF_DIR_LEFT;
|
|
|
|
}
|
|
|
|
|
|
|
|
return dir;
|
2006-05-18 00:55:04 +02:00
|
|
|
|
2005-11-12 08:34:40 +01:00
|
|
|
#endif /* 0 */
|
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* compute all inflex points in a given glyph */
|
2006-05-18 00:55:04 +02:00
|
|
|
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
#if 1
|
2006-05-18 00:55:04 +02:00
|
|
|
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
static void
|
|
|
|
af_glyph_hints_compute_inflections( AF_GlyphHints hints )
|
|
|
|
{
|
|
|
|
AF_Point* contour = hints->contours;
|
|
|
|
AF_Point* contour_limit = contour + hints->num_contours;
|
|
|
|
|
|
|
|
|
|
|
|
/* do each contour separately */
|
|
|
|
for ( ; contour < contour_limit; contour++ )
|
|
|
|
{
|
|
|
|
AF_Point point = contour[0];
|
|
|
|
AF_Point first = point;
|
|
|
|
AF_Point start = point;
|
|
|
|
AF_Point end = point;
|
|
|
|
AF_Point before;
|
|
|
|
AF_Point after;
|
|
|
|
FT_Pos in_x, in_y, out_x, out_y;
|
|
|
|
AF_Angle orient_prev, orient_cur;
|
|
|
|
FT_Int finished = 0;
|
|
|
|
|
|
|
|
|
|
|
|
/* compute first segment in contour */
|
|
|
|
first = point;
|
|
|
|
|
|
|
|
start = end = first;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
end = end->next;
|
|
|
|
if ( end == first )
|
|
|
|
goto Skip;
|
|
|
|
|
|
|
|
in_x = end->fx - start->fx;
|
|
|
|
in_y = end->fy - start->fy;
|
|
|
|
|
|
|
|
} while ( in_x == 0 && in_y == 0 );
|
|
|
|
|
|
|
|
/* extend the segment start whenever possible */
|
|
|
|
before = start;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
start = before;
|
|
|
|
before = before->prev;
|
|
|
|
if ( before == first )
|
|
|
|
goto Skip;
|
|
|
|
|
|
|
|
out_x = start->fx - before->fx;
|
|
|
|
out_y = start->fy - before->fy;
|
|
|
|
|
|
|
|
} while ( out_x == 0 && out_y == 0 );
|
|
|
|
|
2006-11-02 18:21:02 +01:00
|
|
|
orient_prev = ft_corner_orientation( in_x, in_y, out_x, out_y );
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
|
|
|
|
} while ( orient_prev == 0 );
|
|
|
|
|
|
|
|
first = start;
|
|
|
|
|
|
|
|
in_x = out_x;
|
|
|
|
in_y = out_y;
|
|
|
|
|
2006-05-18 00:55:04 +02:00
|
|
|
/* now process all segments in the contour */
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
do
|
|
|
|
{
|
|
|
|
/* first, extend current segment's end whenever possible */
|
|
|
|
after = end;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
end = after;
|
|
|
|
after = after->next;
|
|
|
|
if ( after == first )
|
|
|
|
finished = 1;
|
|
|
|
|
|
|
|
out_x = after->fx - end->fx;
|
|
|
|
out_y = after->fy - end->fy;
|
|
|
|
|
|
|
|
} while ( out_x == 0 && out_y == 0 );
|
|
|
|
|
2006-11-02 18:21:02 +01:00
|
|
|
orient_cur = ft_corner_orientation( in_x, in_y, out_x, out_y );
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
|
|
|
|
} while ( orient_cur == 0 );
|
|
|
|
|
|
|
|
if ( ( orient_prev + orient_cur ) == 0 )
|
|
|
|
{
|
|
|
|
/* we have an inflection point here */
|
|
|
|
do
|
|
|
|
{
|
|
|
|
start->flags |= AF_FLAG_INFLECTION;
|
|
|
|
start = start->next;
|
|
|
|
|
|
|
|
} while ( start != end );
|
|
|
|
|
|
|
|
start->flags |= AF_FLAG_INFLECTION;
|
|
|
|
}
|
|
|
|
|
2006-05-18 00:55:04 +02:00
|
|
|
start = end;
|
|
|
|
end = after;
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
|
|
|
|
orient_prev = orient_cur;
|
|
|
|
in_x = out_x;
|
|
|
|
in_y = out_y;
|
|
|
|
|
|
|
|
} while ( !finished );
|
|
|
|
|
|
|
|
Skip:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#else /* old code */
|
2006-05-18 00:55:04 +02:00
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
static void
|
|
|
|
af_glyph_hints_compute_inflections( AF_GlyphHints hints )
|
|
|
|
{
|
|
|
|
AF_Point* contour = hints->contours;
|
|
|
|
AF_Point* contour_limit = contour + hints->num_contours;
|
|
|
|
|
|
|
|
|
|
|
|
/* do each contour separately */
|
|
|
|
for ( ; contour < contour_limit; contour++ )
|
|
|
|
{
|
2005-03-03 18:09:08 +01:00
|
|
|
AF_Point point = contour[0];
|
|
|
|
AF_Point first = point;
|
|
|
|
AF_Point start = point;
|
|
|
|
AF_Point end = point;
|
|
|
|
AF_Point before;
|
|
|
|
AF_Point after;
|
|
|
|
AF_Angle angle_in, angle_seg, angle_out;
|
|
|
|
AF_Angle diff_in, diff_out;
|
|
|
|
FT_Int finished = 0;
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* compute first segment in contour */
|
|
|
|
first = point;
|
|
|
|
|
|
|
|
start = end = first;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
end = end->next;
|
|
|
|
if ( end == first )
|
|
|
|
goto Skip;
|
|
|
|
|
|
|
|
} while ( end->fx == first->fx && end->fy == first->fy );
|
|
|
|
|
|
|
|
angle_seg = af_angle_atan( end->fx - start->fx,
|
|
|
|
end->fy - start->fy );
|
|
|
|
|
|
|
|
/* extend the segment start whenever possible */
|
|
|
|
before = start;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
start = before;
|
|
|
|
before = before->prev;
|
|
|
|
if ( before == first )
|
|
|
|
goto Skip;
|
|
|
|
|
|
|
|
} while ( before->fx == start->fx && before->fy == start->fy );
|
|
|
|
|
|
|
|
angle_in = af_angle_atan( start->fx - before->fx,
|
|
|
|
start->fy - before->fy );
|
|
|
|
|
|
|
|
} while ( angle_in == angle_seg );
|
|
|
|
|
2005-11-12 08:34:40 +01:00
|
|
|
first = start;
|
2005-10-28 18:14:14 +02:00
|
|
|
|
|
|
|
AF_ANGLE_DIFF( diff_in, angle_in, angle_seg );
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
/* now, process all segments in the contour */
|
|
|
|
do
|
|
|
|
{
|
|
|
|
/* first, extend current segment's end whenever possible */
|
|
|
|
after = end;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
end = after;
|
|
|
|
after = after->next;
|
|
|
|
if ( after == first )
|
|
|
|
finished = 1;
|
|
|
|
|
|
|
|
} while ( end->fx == after->fx && end->fy == after->fy );
|
|
|
|
|
|
|
|
angle_out = af_angle_atan( after->fx - end->fx,
|
|
|
|
after->fy - end->fy );
|
|
|
|
|
|
|
|
} while ( angle_out == angle_seg );
|
|
|
|
|
2005-10-28 18:14:14 +02:00
|
|
|
AF_ANGLE_DIFF( diff_out, angle_seg, angle_out );
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
if ( ( diff_in ^ diff_out ) < 0 )
|
|
|
|
{
|
|
|
|
/* diff_in and diff_out have different signs, we have */
|
|
|
|
/* inflection points here... */
|
|
|
|
do
|
|
|
|
{
|
|
|
|
start->flags |= AF_FLAG_INFLECTION;
|
|
|
|
start = start->next;
|
|
|
|
|
|
|
|
} while ( start != end );
|
|
|
|
|
|
|
|
start->flags |= AF_FLAG_INFLECTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
start = end;
|
|
|
|
end = after;
|
|
|
|
angle_seg = angle_out;
|
|
|
|
diff_in = diff_out;
|
|
|
|
|
|
|
|
} while ( !finished );
|
|
|
|
|
|
|
|
Skip:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
}
|
2006-05-18 00:55:04 +02:00
|
|
|
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
#endif /* old code */
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
FT_LOCAL_DEF( void )
|
|
|
|
af_glyph_hints_init( AF_GlyphHints hints,
|
|
|
|
FT_Memory memory )
|
|
|
|
{
|
|
|
|
FT_ZERO( hints );
|
|
|
|
hints->memory = memory;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FT_LOCAL_DEF( void )
|
|
|
|
af_glyph_hints_done( AF_GlyphHints hints )
|
|
|
|
{
|
|
|
|
if ( hints && hints->memory )
|
|
|
|
{
|
2005-03-03 18:09:08 +01:00
|
|
|
FT_Memory memory = hints->memory;
|
|
|
|
int dim;
|
2004-03-27 09:43:17 +01:00
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* note that we don't need to free the segment and edge
|
|
|
|
* buffers, since they are really within the hints->points array
|
|
|
|
*/
|
2005-03-03 18:09:08 +01:00
|
|
|
for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
|
2004-03-27 09:43:17 +01:00
|
|
|
{
|
2005-03-02 12:24:23 +01:00
|
|
|
AF_AxisHints axis = &hints->axis[dim];
|
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
axis->num_segments = 0;
|
2005-03-01 16:48:29 +01:00
|
|
|
axis->max_segments = 0;
|
|
|
|
FT_FREE( axis->segments );
|
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
axis->num_edges = 0;
|
2005-03-01 16:48:29 +01:00
|
|
|
axis->max_edges = 0;
|
|
|
|
FT_FREE( axis->edges );
|
2004-03-27 09:43:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
FT_FREE( hints->contours );
|
|
|
|
hints->max_contours = 0;
|
|
|
|
hints->num_contours = 0;
|
|
|
|
|
|
|
|
FT_FREE( hints->points );
|
|
|
|
hints->num_points = 0;
|
|
|
|
hints->max_points = 0;
|
|
|
|
|
|
|
|
hints->memory = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-04 19:41:59 +02:00
|
|
|
FT_LOCAL_DEF( void )
|
|
|
|
af_glyph_hints_rescale( AF_GlyphHints hints,
|
|
|
|
AF_ScriptMetrics metrics )
|
|
|
|
{
|
2005-12-14 17:37:15 +01:00
|
|
|
hints->metrics = metrics;
|
|
|
|
hints->scaler_flags = metrics->scaler.flags;
|
2004-06-04 19:41:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
FT_LOCAL_DEF( FT_Error )
|
2005-03-02 12:24:23 +01:00
|
|
|
af_glyph_hints_reload( AF_GlyphHints hints,
|
|
|
|
FT_Outline* outline )
|
2004-03-27 09:43:17 +01:00
|
|
|
{
|
2005-03-23 17:45:24 +01:00
|
|
|
FT_Error error = AF_Err_Ok;
|
2005-03-02 12:24:23 +01:00
|
|
|
AF_Point points;
|
|
|
|
FT_UInt old_max, new_max;
|
|
|
|
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;
|
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
|
2005-03-03 18:09:08 +01:00
|
|
|
hints->num_points = 0;
|
|
|
|
hints->num_contours = 0;
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
hints->axis[0].num_segments = 0;
|
|
|
|
hints->axis[0].num_edges = 0;
|
|
|
|
hints->axis[1].num_segments = 0;
|
|
|
|
hints->axis[1].num_edges = 0;
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
/* first of all, reallocate the contours array when necessary */
|
|
|
|
new_max = (FT_UInt)outline->n_contours;
|
2004-03-27 09:43:17 +01:00
|
|
|
old_max = hints->max_contours;
|
|
|
|
if ( new_max > old_max )
|
|
|
|
{
|
2005-03-02 12:24:23 +01:00
|
|
|
new_max = ( new_max + 3 ) & ~3;
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
|
|
|
|
goto Exit;
|
|
|
|
|
|
|
|
hints->max_contours = new_max;
|
|
|
|
}
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
/*
|
2005-03-03 18:09:08 +01:00
|
|
|
* then reallocate the points arrays if necessary --
|
2005-03-02 12:24:23 +01:00
|
|
|
* note that we reserve two additional point positions, used to
|
|
|
|
* hint metrics appropriately
|
|
|
|
*/
|
2004-03-27 09:43:17 +01:00
|
|
|
new_max = (FT_UInt)( outline->n_points + 2 );
|
|
|
|
old_max = hints->max_points;
|
|
|
|
if ( new_max > old_max )
|
|
|
|
{
|
|
|
|
new_max = ( new_max + 2 + 7 ) & ~7;
|
|
|
|
|
2005-03-01 16:48:29 +01:00
|
|
|
if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) )
|
2004-03-27 09:43:17 +01:00
|
|
|
goto Exit;
|
|
|
|
|
2005-03-01 16:48:29 +01:00
|
|
|
hints->max_points = new_max;
|
2004-03-27 09:43:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
hints->num_points = outline->n_points;
|
|
|
|
hints->num_contours = outline->n_contours;
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
/* 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;
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT )
|
|
|
|
{
|
2005-03-02 12:24:23 +01:00
|
|
|
hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_DOWN;
|
|
|
|
hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_RIGHT;
|
2004-03-27 09:43:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
hints->x_scale = x_scale;
|
|
|
|
hints->y_scale = y_scale;
|
|
|
|
hints->x_delta = x_delta;
|
|
|
|
hints->y_delta = y_delta;
|
|
|
|
|
|
|
|
points = hints->points;
|
|
|
|
if ( hints->num_points == 0 )
|
|
|
|
goto Exit;
|
|
|
|
|
|
|
|
{
|
|
|
|
AF_Point point;
|
|
|
|
AF_Point point_limit = points + hints->num_points;
|
|
|
|
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
/* compute coordinates & Bezier flags */
|
2004-03-27 09:43:17 +01:00
|
|
|
{
|
|
|
|
FT_Vector* vec = outline->points;
|
|
|
|
char* tag = outline->tags;
|
|
|
|
|
|
|
|
|
|
|
|
for ( point = points; point < point_limit; point++, vec++, tag++ )
|
|
|
|
{
|
* Jamfile: removing otvalid from the list of compiled modules
* include/freetype/internal/ftserv.h: added compiler pragmas to get rid
of annoying warnings with Visual C++ compiler in maximum warning mode
* src/autofit/afhints.c, src/autofit/aflatin.c, src/base/ftstroke.c,
src/bdf/bdfdrivr.c, src/cache/ftcbasic.c, src/cache/ftccmap.c,
src/cache/ftcmanag.c, src/cff/cffload.c, src/cid/cidload.c,
src/lzw/zopen.c, src/otvalid/otvgdef.c, src/pcf/pcfread.c,
src/sfnt/sfobjs.c, src/truetype/ttgxvar.c: removing compiler warnings
2005-05-01 12:11:32 +02:00
|
|
|
point->fx = (FT_Short)vec->x;
|
|
|
|
point->fy = (FT_Short)vec->y;
|
2004-03-27 09:43:17 +01:00
|
|
|
point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;
|
|
|
|
point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta;
|
|
|
|
|
|
|
|
switch ( FT_CURVE_TAG( *tag ) )
|
|
|
|
{
|
|
|
|
case FT_CURVE_TAG_CONIC:
|
|
|
|
point->flags = AF_FLAG_CONIC;
|
|
|
|
break;
|
|
|
|
case FT_CURVE_TAG_CUBIC:
|
|
|
|
point->flags = AF_FLAG_CUBIC;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
point->flags = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* compute `next' and `prev' */
|
|
|
|
{
|
|
|
|
FT_Int contour_index;
|
|
|
|
AF_Point prev;
|
|
|
|
AF_Point first;
|
|
|
|
AF_Point end;
|
|
|
|
|
|
|
|
|
|
|
|
contour_index = 0;
|
|
|
|
|
|
|
|
first = points;
|
|
|
|
end = points + outline->contours[0];
|
|
|
|
prev = end;
|
|
|
|
|
|
|
|
for ( point = points; point < point_limit; point++ )
|
|
|
|
{
|
|
|
|
point->prev = prev;
|
|
|
|
if ( point < end )
|
|
|
|
{
|
|
|
|
point->next = point + 1;
|
|
|
|
prev = point;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
point->next = first;
|
|
|
|
contour_index++;
|
|
|
|
if ( point + 1 < point_limit )
|
|
|
|
{
|
|
|
|
end = points + outline->contours[contour_index];
|
|
|
|
first = point + 1;
|
|
|
|
prev = end;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set-up the contours array */
|
|
|
|
{
|
|
|
|
AF_Point* contour = hints->contours;
|
|
|
|
AF_Point* contour_limit = contour + hints->num_contours;
|
|
|
|
short* end = outline->contours;
|
|
|
|
short idx = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for ( ; contour < contour_limit; contour++, end++ )
|
|
|
|
{
|
|
|
|
contour[0] = points + idx;
|
|
|
|
idx = (short)( end[0] + 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* compute directions of in & out vectors */
|
|
|
|
{
|
|
|
|
for ( point = points; point < point_limit; point++ )
|
|
|
|
{
|
2005-03-02 12:24:23 +01:00
|
|
|
AF_Point prev;
|
|
|
|
AF_Point next;
|
|
|
|
FT_Pos in_x, in_y, out_x, out_y;
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
prev = point->prev;
|
|
|
|
in_x = point->fx - prev->fx;
|
|
|
|
in_y = point->fy - prev->fy;
|
|
|
|
|
* Jamfile: removing otvalid from the list of compiled modules
* include/freetype/internal/ftserv.h: added compiler pragmas to get rid
of annoying warnings with Visual C++ compiler in maximum warning mode
* src/autofit/afhints.c, src/autofit/aflatin.c, src/base/ftstroke.c,
src/bdf/bdfdrivr.c, src/cache/ftcbasic.c, src/cache/ftccmap.c,
src/cache/ftcmanag.c, src/cff/cffload.c, src/cid/cidload.c,
src/lzw/zopen.c, src/otvalid/otvgdef.c, src/pcf/pcfread.c,
src/sfnt/sfobjs.c, src/truetype/ttgxvar.c: removing compiler warnings
2005-05-01 12:11:32 +02:00
|
|
|
point->in_dir = (FT_Char)af_direction_compute( in_x, in_y );
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
next = point->next;
|
|
|
|
out_x = next->fx - point->fx;
|
|
|
|
out_y = next->fy - point->fy;
|
|
|
|
|
* Jamfile: removing otvalid from the list of compiled modules
* include/freetype/internal/ftserv.h: added compiler pragmas to get rid
of annoying warnings with Visual C++ compiler in maximum warning mode
* src/autofit/afhints.c, src/autofit/aflatin.c, src/base/ftstroke.c,
src/bdf/bdfdrivr.c, src/cache/ftcbasic.c, src/cache/ftccmap.c,
src/cache/ftcmanag.c, src/cff/cffload.c, src/cid/cidload.c,
src/lzw/zopen.c, src/otvalid/otvgdef.c, src/pcf/pcfread.c,
src/sfnt/sfobjs.c, src/truetype/ttgxvar.c: removing compiler warnings
2005-05-01 12:11:32 +02:00
|
|
|
point->out_dir = (FT_Char)af_direction_compute( out_x, out_y );
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
if ( point->flags & ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) )
|
|
|
|
{
|
|
|
|
Is_Weak_Point:
|
|
|
|
point->flags |= AF_FLAG_WEAK_INTERPOLATION;
|
|
|
|
}
|
|
|
|
else if ( point->out_dir == point->in_dir )
|
|
|
|
{
|
2006-05-18 00:55:04 +02:00
|
|
|
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
#if 1
|
2006-05-18 00:55:04 +02:00
|
|
|
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
if ( point->out_dir != AF_DIR_NONE )
|
|
|
|
goto Is_Weak_Point;
|
|
|
|
|
2006-11-02 18:21:02 +01:00
|
|
|
if ( ft_corner_is_flat( in_x, in_y, out_x, out_y ) )
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
goto Is_Weak_Point;
|
|
|
|
|
|
|
|
#else /* old code */
|
2006-05-18 00:55:04 +02:00
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
AF_Angle angle_in, angle_out, delta;
|
|
|
|
|
|
|
|
|
|
|
|
if ( point->out_dir != AF_DIR_NONE )
|
|
|
|
goto Is_Weak_Point;
|
|
|
|
|
|
|
|
angle_in = af_angle_atan( in_x, in_y );
|
|
|
|
angle_out = af_angle_atan( out_x, out_y );
|
2005-10-28 18:14:14 +02:00
|
|
|
|
|
|
|
AF_ANGLE_DIFF( delta, angle_in, angle_out );
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
if ( delta < 2 && delta > -2 )
|
|
|
|
goto Is_Weak_Point;
|
2006-05-18 00:55:04 +02:00
|
|
|
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
#endif /* old code */
|
2006-05-18 00:55:04 +02:00
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
}
|
|
|
|
else if ( point->in_dir == -point->out_dir )
|
|
|
|
goto Is_Weak_Point;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
/* compute inflection points */
|
2004-03-27 09:43:17 +01:00
|
|
|
af_glyph_hints_compute_inflections( hints );
|
|
|
|
|
|
|
|
Exit:
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FT_LOCAL_DEF( void )
|
2005-03-02 12:24:23 +01:00
|
|
|
af_glyph_hints_save( AF_GlyphHints hints,
|
|
|
|
FT_Outline* outline )
|
2004-03-27 09:43:17 +01:00
|
|
|
{
|
|
|
|
AF_Point point = hints->points;
|
|
|
|
AF_Point limit = point + hints->num_points;
|
|
|
|
FT_Vector* vec = outline->points;
|
|
|
|
char* tag = outline->tags;
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
for ( ; point < limit; point++, vec++, tag++ )
|
|
|
|
{
|
* Jamfile: removing otvalid from the list of compiled modules
* include/freetype/internal/ftserv.h: added compiler pragmas to get rid
of annoying warnings with Visual C++ compiler in maximum warning mode
* src/autofit/afhints.c, src/autofit/aflatin.c, src/base/ftstroke.c,
src/bdf/bdfdrivr.c, src/cache/ftcbasic.c, src/cache/ftccmap.c,
src/cache/ftcmanag.c, src/cff/cffload.c, src/cid/cidload.c,
src/lzw/zopen.c, src/otvalid/otvgdef.c, src/pcf/pcfread.c,
src/sfnt/sfobjs.c, src/truetype/ttgxvar.c: removing compiler warnings
2005-05-01 12:11:32 +02:00
|
|
|
vec->x = point->x;
|
|
|
|
vec->y = point->y;
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
if ( point->flags & AF_FLAG_CONIC )
|
|
|
|
tag[0] = FT_CURVE_TAG_CONIC;
|
|
|
|
else if ( point->flags & AF_FLAG_CUBIC )
|
|
|
|
tag[0] = FT_CURVE_TAG_CUBIC;
|
|
|
|
else
|
|
|
|
tag[0] = FT_CURVE_TAG_ON;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
/****************************************************************
|
|
|
|
*
|
|
|
|
* EDGE POINT GRID-FITTING
|
|
|
|
*
|
|
|
|
****************************************************************/
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
FT_LOCAL_DEF( void )
|
|
|
|
af_glyph_hints_align_edge_points( AF_GlyphHints hints,
|
|
|
|
AF_Dimension dim )
|
|
|
|
{
|
2005-03-02 12:24:23 +01:00
|
|
|
AF_AxisHints axis = & hints->axis[dim];
|
2004-03-27 09:43:17 +01:00
|
|
|
AF_Edge edges = axis->edges;
|
|
|
|
AF_Edge edge_limit = edges + axis->num_edges;
|
|
|
|
AF_Edge edge;
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
for ( edge = edges; edge < edge_limit; edge++ )
|
|
|
|
{
|
|
|
|
/* move the points of each segment */
|
|
|
|
/* in each edge to the edge's position */
|
|
|
|
AF_Segment seg = edge->first;
|
|
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
AF_Point point = seg->first;
|
|
|
|
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
if ( dim == AF_DIMENSION_HORZ )
|
|
|
|
{
|
|
|
|
point->x = edge->pos;
|
|
|
|
point->flags |= AF_FLAG_TOUCH_X;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
point->y = edge->pos;
|
|
|
|
point->flags |= AF_FLAG_TOUCH_Y;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( point == seg->last )
|
|
|
|
break;
|
|
|
|
|
|
|
|
point = point->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
seg = seg->edge_next;
|
|
|
|
|
|
|
|
} while ( seg != edge->first );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
/****************************************************************
|
|
|
|
*
|
|
|
|
* STRONG POINT INTERPOLATION
|
|
|
|
*
|
|
|
|
****************************************************************/
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* hint the strong points -- this is equivalent to the TrueType `IP' */
|
|
|
|
/* hinting instruction */
|
2005-03-02 12:24:23 +01:00
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
FT_LOCAL_DEF( void )
|
|
|
|
af_glyph_hints_align_strong_points( AF_GlyphHints hints,
|
|
|
|
AF_Dimension dim )
|
|
|
|
{
|
|
|
|
AF_Point points = hints->points;
|
|
|
|
AF_Point point_limit = points + hints->num_points;
|
|
|
|
AF_AxisHints axis = &hints->axis[dim];
|
|
|
|
AF_Edge edges = axis->edges;
|
|
|
|
AF_Edge edge_limit = edges + axis->num_edges;
|
|
|
|
AF_Flags touch_flag;
|
|
|
|
|
|
|
|
|
|
|
|
if ( dim == AF_DIMENSION_HORZ )
|
|
|
|
touch_flag = AF_FLAG_TOUCH_X;
|
|
|
|
else
|
|
|
|
touch_flag = AF_FLAG_TOUCH_Y;
|
|
|
|
|
|
|
|
if ( edges < edge_limit )
|
|
|
|
{
|
|
|
|
AF_Point point;
|
|
|
|
AF_Edge edge;
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
for ( point = points; point < point_limit; point++ )
|
|
|
|
{
|
|
|
|
FT_Pos u, ou, fu; /* point position */
|
|
|
|
FT_Pos delta;
|
|
|
|
|
|
|
|
|
|
|
|
if ( point->flags & touch_flag )
|
|
|
|
continue;
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
/* if this point is candidate to weak interpolation, we */
|
2004-03-27 09:43:17 +01:00
|
|
|
/* interpolate it after all strong points have been processed */
|
2005-03-02 12:24:23 +01:00
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) &&
|
|
|
|
!( point->flags & AF_FLAG_INFLECTION ) )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if ( dim == AF_DIMENSION_VERT )
|
|
|
|
{
|
|
|
|
u = point->fy;
|
|
|
|
ou = point->oy;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
u = point->fx;
|
|
|
|
ou = point->ox;
|
|
|
|
}
|
|
|
|
|
|
|
|
fu = u;
|
|
|
|
|
|
|
|
/* is the point before the first edge? */
|
|
|
|
edge = edges;
|
|
|
|
delta = edge->fpos - u;
|
|
|
|
if ( delta >= 0 )
|
|
|
|
{
|
|
|
|
u = edge->pos - ( edge->opos - ou );
|
|
|
|
goto Store_Point;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* is the point after the last edge? */
|
|
|
|
edge = edge_limit - 1;
|
|
|
|
delta = u - edge->fpos;
|
|
|
|
if ( delta >= 0 )
|
|
|
|
{
|
|
|
|
u = edge->pos + ( ou - edge->opos );
|
|
|
|
goto Store_Point;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
FT_UInt min, max, mid;
|
|
|
|
FT_Pos fpos;
|
|
|
|
|
|
|
|
|
|
|
|
/* find enclosing edges */
|
|
|
|
min = 0;
|
|
|
|
max = edge_limit - edges;
|
|
|
|
|
|
|
|
while ( min < max )
|
|
|
|
{
|
|
|
|
mid = ( max + min ) >> 1;
|
|
|
|
edge = edges + mid;
|
|
|
|
fpos = edge->fpos;
|
|
|
|
|
|
|
|
if ( u < fpos )
|
|
|
|
max = mid;
|
|
|
|
else if ( u > fpos )
|
|
|
|
min = mid + 1;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* we are on the edge */
|
|
|
|
u = edge->pos;
|
|
|
|
goto Store_Point;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
AF_Edge before = edges + min - 1;
|
|
|
|
AF_Edge after = edges + min + 0;
|
|
|
|
|
|
|
|
|
|
|
|
/* assert( before && after && before != after ) */
|
|
|
|
if ( before->scale == 0 )
|
|
|
|
before->scale = FT_DivFix( after->pos - before->pos,
|
|
|
|
after->fpos - before->fpos );
|
|
|
|
|
|
|
|
u = before->pos + FT_MulFix( fu - before->fpos,
|
|
|
|
before->scale );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Store_Point:
|
|
|
|
/* save the point position */
|
|
|
|
if ( dim == AF_DIMENSION_HORZ )
|
|
|
|
point->x = u;
|
|
|
|
else
|
|
|
|
point->y = u;
|
|
|
|
|
|
|
|
point->flags |= touch_flag;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
/****************************************************************
|
|
|
|
*
|
|
|
|
* WEAK POINT INTERPOLATION
|
|
|
|
*
|
|
|
|
****************************************************************/
|
|
|
|
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
static void
|
|
|
|
af_iup_shift( AF_Point p1,
|
|
|
|
AF_Point p2,
|
|
|
|
AF_Point ref )
|
|
|
|
{
|
|
|
|
AF_Point p;
|
|
|
|
FT_Pos delta = ref->u - ref->v;
|
|
|
|
|
|
|
|
|
|
|
|
for ( p = p1; p < ref; p++ )
|
|
|
|
p->u = p->v + delta;
|
|
|
|
|
|
|
|
for ( p = ref + 1; p <= p2; p++ )
|
|
|
|
p->u = p->v + delta;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
af_iup_interp( AF_Point p1,
|
|
|
|
AF_Point p2,
|
|
|
|
AF_Point ref1,
|
|
|
|
AF_Point ref2 )
|
|
|
|
{
|
|
|
|
AF_Point p;
|
|
|
|
FT_Pos u;
|
|
|
|
FT_Pos v1 = ref1->v;
|
|
|
|
FT_Pos v2 = ref2->v;
|
|
|
|
FT_Pos d1 = ref1->u - v1;
|
|
|
|
FT_Pos d2 = ref2->u - v2;
|
|
|
|
|
|
|
|
|
|
|
|
if ( p1 > p2 )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( v1 == v2 )
|
|
|
|
{
|
|
|
|
for ( p = p1; p <= p2; p++ )
|
|
|
|
{
|
|
|
|
u = p->v;
|
|
|
|
|
|
|
|
if ( u <= v1 )
|
|
|
|
u += d1;
|
|
|
|
else
|
|
|
|
u += d2;
|
|
|
|
|
|
|
|
p->u = u;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( v1 < v2 )
|
|
|
|
{
|
|
|
|
for ( p = p1; p <= p2; p++ )
|
|
|
|
{
|
|
|
|
u = p->v;
|
|
|
|
|
|
|
|
if ( u <= v1 )
|
|
|
|
u += d1;
|
|
|
|
else if ( u >= v2 )
|
|
|
|
u += d2;
|
|
|
|
else
|
|
|
|
u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
|
|
|
|
|
|
|
|
p->u = u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for ( p = p1; p <= p2; p++ )
|
|
|
|
{
|
|
|
|
u = p->v;
|
|
|
|
|
|
|
|
if ( u <= v2 )
|
|
|
|
u += d2;
|
|
|
|
else if ( u >= v1 )
|
|
|
|
u += d1;
|
|
|
|
else
|
|
|
|
u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
|
|
|
|
|
|
|
|
p->u = u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FT_LOCAL_DEF( void )
|
|
|
|
af_glyph_hints_align_weak_points( AF_GlyphHints hints,
|
|
|
|
AF_Dimension dim )
|
|
|
|
{
|
2005-03-03 18:09:08 +01:00
|
|
|
AF_Point points = hints->points;
|
|
|
|
AF_Point point_limit = points + hints->num_points;
|
|
|
|
AF_Point* contour = hints->contours;
|
|
|
|
AF_Point* contour_limit = contour + hints->num_contours;
|
|
|
|
AF_Flags touch_flag;
|
|
|
|
AF_Point point;
|
|
|
|
AF_Point end_point;
|
|
|
|
AF_Point first_point;
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* PASS 1: Move segment points to edge positions */
|
|
|
|
|
|
|
|
if ( dim == AF_DIMENSION_HORZ )
|
|
|
|
{
|
|
|
|
touch_flag = AF_FLAG_TOUCH_X;
|
|
|
|
|
|
|
|
for ( point = points; point < point_limit; point++ )
|
|
|
|
{
|
|
|
|
point->u = point->x;
|
|
|
|
point->v = point->ox;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
touch_flag = AF_FLAG_TOUCH_Y;
|
|
|
|
|
|
|
|
for ( point = points; point < point_limit; point++ )
|
|
|
|
{
|
|
|
|
point->u = point->y;
|
|
|
|
point->v = point->oy;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-03-02 12:24:23 +01:00
|
|
|
point = points;
|
2004-03-27 09:43:17 +01:00
|
|
|
|
|
|
|
for ( ; contour < contour_limit; contour++ )
|
|
|
|
{
|
|
|
|
point = *contour;
|
|
|
|
end_point = point->prev;
|
|
|
|
first_point = point;
|
|
|
|
|
|
|
|
while ( point <= end_point && !( point->flags & touch_flag ) )
|
|
|
|
point++;
|
|
|
|
|
|
|
|
if ( point <= end_point )
|
|
|
|
{
|
|
|
|
AF_Point first_touched = point;
|
|
|
|
AF_Point cur_touched = point;
|
|
|
|
|
|
|
|
|
|
|
|
point++;
|
|
|
|
while ( point <= end_point )
|
|
|
|
{
|
|
|
|
if ( point->flags & touch_flag )
|
|
|
|
{
|
|
|
|
/* we found two successive touched points; we interpolate */
|
|
|
|
/* all contour points between them */
|
|
|
|
af_iup_interp( cur_touched + 1, point - 1,
|
|
|
|
cur_touched, point );
|
|
|
|
cur_touched = point;
|
|
|
|
}
|
|
|
|
point++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( cur_touched == first_touched )
|
|
|
|
{
|
|
|
|
/* this is a special case: only one point was touched in the */
|
|
|
|
/* contour; we thus simply shift the whole contour */
|
|
|
|
af_iup_shift( first_point, end_point, cur_touched );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* now interpolate after the last touched point to the end */
|
|
|
|
/* of the contour */
|
|
|
|
af_iup_interp( cur_touched + 1, end_point,
|
|
|
|
cur_touched, first_touched );
|
|
|
|
|
|
|
|
/* if the first contour point isn't touched, interpolate */
|
|
|
|
/* from the contour start to the first touched point */
|
|
|
|
if ( first_touched > points )
|
|
|
|
af_iup_interp( first_point, first_touched - 1,
|
|
|
|
cur_touched, first_touched );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* now save the interpolated values back to x/y */
|
|
|
|
if ( dim == AF_DIMENSION_HORZ )
|
|
|
|
{
|
|
|
|
for ( point = points; point < point_limit; point++ )
|
|
|
|
point->x = point->u;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for ( point = points; point < point_limit; point++ )
|
|
|
|
point->y = point->u;
|
|
|
|
}
|
|
|
|
}
|
2005-03-02 12:24:23 +01:00
|
|
|
|
2006-01-22 07:58:16 +01:00
|
|
|
|
2006-01-21 15:31:45 +01:00
|
|
|
#ifdef AF_USE_WARPER
|
2006-01-22 07:58:16 +01:00
|
|
|
|
2006-01-21 15:31:45 +01:00
|
|
|
FT_LOCAL_DEF( void )
|
|
|
|
af_glyph_hints_scale_dim( AF_GlyphHints hints,
|
|
|
|
AF_Dimension dim,
|
|
|
|
FT_Fixed scale,
|
|
|
|
FT_Pos delta )
|
|
|
|
{
|
|
|
|
AF_Point points = hints->points;
|
|
|
|
AF_Point points_limit = points + hints->num_points;
|
|
|
|
AF_Point point;
|
* include/freetype/internal/tttypes.h, src/autofit/afangles.c,
src/autofit/afcjk.c, src/autofit/afhints.c, src/autofit/aflatin.c,
src/autofit/aftypes.h, src/base/ftcalc.c, src/base/ftoutln.c,
src/gzip/ftgzip.c, src/psaux/psconv.c, src/truetype/ttgload.c,
src/type1/t1gload.c:
this is a major patch used to drastically improve the performance
of loading glyphs. This both speeds up loading the glypn vector
themselves and the auto-fitter.
note that we've started using inline assembler with GCC to
implement FT_MulFix, given that this function is so damn
important for the engine's performance.
the resulting speed-up is about 25%.
2006-05-17 15:34:21 +02:00
|
|
|
|
2006-01-22 07:58:16 +01:00
|
|
|
|
2006-01-21 15:31:45 +01:00
|
|
|
if ( dim == AF_DIMENSION_HORZ )
|
|
|
|
{
|
|
|
|
for ( point = points; point < points_limit; point++ )
|
|
|
|
point->x = FT_MulFix( point->fx, scale ) + delta;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for ( point = points; point < points_limit; point++ )
|
|
|
|
point->y = FT_MulFix( point->fy, scale ) + delta;
|
|
|
|
}
|
|
|
|
}
|
2006-01-22 07:58:16 +01:00
|
|
|
|
2006-01-21 15:31:45 +01:00
|
|
|
#endif /* AF_USE_WARPER */
|
2005-03-02 12:24:23 +01:00
|
|
|
|
|
|
|
/* END */
|