/***************************************************************************/
/* */
/* afhints.c */
/* */
/* Auto-fitter hinting routines (body). */
/* */
/* Copyright 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */
/* 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. */
/* */
/***************************************************************************/
#include "afhints.h"
#include "aferrors.h"
#include FT_INTERNAL_CALC_H
FT_LOCAL_DEF( FT_Error )
af_axis_hints_new_segment( AF_AxisHints axis,
FT_Memory memory,
AF_Segment *asegment )
{
FT_Error error = AF_Err_Ok;
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)( FT_INT_MAX / sizeof ( *segment ) );
if ( old_max >= big_max )
{
error = AF_Err_Out_Of_Memory;
goto Exit;
}
new_max += ( new_max >> 2 ) + 4;
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++;
Exit:
*asegment = segment;
return error;
}
FT_LOCAL( FT_Error )
af_axis_hints_new_edge( AF_AxisHints axis,
FT_Int fpos,
AF_Direction dir,
FT_Memory memory,
AF_Edge *aedge )
{
FT_Error error = AF_Err_Ok;
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)( FT_INT_MAX / sizeof ( *edge ) );
if ( old_max >= big_max )
{
error = AF_Err_Out_Of_Memory;
goto Exit;
}
new_max += ( new_max >> 2 ) + 4;
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 )
{
if ( edge[-1].fpos < fpos )
break;
/* we want the edge with same position and minor direction */
/* to appear before those in the major one in the list */
if ( edge[-1].fpos == fpos && dir == axis->major_dir )
break;
edge[0] = edge[-1];
edge--;
}
axis->num_edges++;
FT_ZERO( edge );
edge->fpos =