forked from minhngoc25a/freetype2
autohint:
Formatting. Replacing many enums with #defines since we do arithmetics (especially ORing which would produce undefined enum values). The ideal thing instead of #defines is `const int' as provided in C++... Adding header files to rules.mk
This commit is contained in:
parent
d082cd6801
commit
c3dd151b0f
|
@ -102,14 +102,14 @@
|
||||||
AH_LOG(( "blue zones computation\n" ));
|
AH_LOG(( "blue zones computation\n" ));
|
||||||
AH_LOG(( "------------------------------------------------\n" ));
|
AH_LOG(( "------------------------------------------------\n" ));
|
||||||
|
|
||||||
for ( blue = (AH_Blue)0; blue < ah_blue_max; blue++ )
|
for ( blue = ah_blue_capital_top; blue < ah_blue_max; blue++ )
|
||||||
{
|
{
|
||||||
const char* p = blue_chars[blue];
|
const char* p = blue_chars[blue];
|
||||||
const char* limit = p + MAX_TEST_CHARACTERS;
|
const char* limit = p + MAX_TEST_CHARACTERS;
|
||||||
FT_Pos *blue_ref, *blue_shoot;
|
FT_Pos *blue_ref, *blue_shoot;
|
||||||
|
|
||||||
|
|
||||||
AH_LOG(( "blue %3d: ", (int)blue ));
|
AH_LOG(( "blue %3d: ", blue ));
|
||||||
|
|
||||||
num_flats = 0;
|
num_flats = 0;
|
||||||
num_rounds = 0;
|
num_rounds = 0;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
/* This file is part of the Catharon Typography Project and shall only */
|
/* This file is part of the Catharon Typography Project and shall only */
|
||||||
/* be used, modified, and distributed under the terms of the Catharon */
|
/* be used, modified, and distributed under the terms of the Catharon */
|
||||||
/* Open Source License that should come with this file under the name */
|
/* Open Source License that should come with this file under the name */
|
||||||
/* "CatharonLicense.txt". By continuing to use, modify, or distribute */
|
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||||
/* this file you indicate that you have read the license and */
|
/* this file you indicate that you have read the license and */
|
||||||
/* understand and accept it fully. */
|
/* understand and accept it fully. */
|
||||||
/* */
|
/* */
|
||||||
|
@ -1150,7 +1150,7 @@
|
||||||
if ( best_dist > 64 / 4 )
|
if ( best_dist > 64 / 4 )
|
||||||
best_dist = 64 / 4;
|
best_dist = 64 / 4;
|
||||||
|
|
||||||
for ( blue = (AH_Blue)0; blue < ah_blue_max; blue++ )
|
for ( blue = ah_blue_capital_top; blue < ah_blue_max; blue++ )
|
||||||
{
|
{
|
||||||
/* if it is a top zone, check for right edges -- if it is a bottom */
|
/* if it is a top zone, check for right edges -- if it is a bottom */
|
||||||
/* zone, check for left edges */
|
/* zone, check for left edges */
|
||||||
|
@ -1213,18 +1213,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/*************************************************************************/
|
||||||
*
|
/* */
|
||||||
* <Function>
|
/* <Function> */
|
||||||
* ah_outline_scale_blue_edges
|
/* ah_outline_scale_blue_edges */
|
||||||
*
|
/* */
|
||||||
* <Description>
|
/* <Description> */
|
||||||
* This functions must be called before hinting in order to re-adjust
|
/* This functions must be called before hinting in order to re-adjust */
|
||||||
* the content of the detected edges (basically change the "blue edge"
|
/* the contents of the detected edges (basically change the `blue */
|
||||||
* pointer from 'design units' to 'scaled ones'
|
/* edge' pointer from `design units' to `scaled ones'). */
|
||||||
*
|
/* */
|
||||||
************************************************************************/
|
|
||||||
|
|
||||||
LOCAL_FUNC
|
LOCAL_FUNC
|
||||||
void ah_outline_scale_blue_edges( AH_Outline* outline,
|
void ah_outline_scale_blue_edges( AH_Outline* outline,
|
||||||
AH_Face_Globals* globals )
|
AH_Face_Globals* globals )
|
||||||
|
@ -1233,7 +1231,9 @@
|
||||||
AH_Edge* limit = edge + outline->num_hedges;
|
AH_Edge* limit = edge + outline->num_hedges;
|
||||||
FT_Int delta;
|
FT_Int delta;
|
||||||
|
|
||||||
|
|
||||||
delta = globals->scaled.blue_refs - globals->design.blue_refs;
|
delta = globals->scaled.blue_refs - globals->design.blue_refs;
|
||||||
|
|
||||||
for ( ; edge < limit; edge++ )
|
for ( ; edge < limit; edge++ )
|
||||||
{
|
{
|
||||||
if ( edge->blue_edge )
|
if ( edge->blue_edge )
|
||||||
|
@ -1242,11 +1242,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef AH_DEBUG_GLYPH
|
#ifdef AH_DEBUG_GLYPH
|
||||||
extern
|
|
||||||
void ah_dump_edges( AH_Outline* outline )
|
void ah_dump_edges( AH_Outline* outline )
|
||||||
{
|
{
|
||||||
AH_Edge* edges;
|
AH_Edge* edges;
|
||||||
|
@ -1254,27 +1251,35 @@
|
||||||
AH_Segment* segments;
|
AH_Segment* segments;
|
||||||
FT_Int dimension;
|
FT_Int dimension;
|
||||||
|
|
||||||
|
|
||||||
edges = outline->horz_edges;
|
edges = outline->horz_edges;
|
||||||
limit = edges + outline->num_hedges;
|
limit = edges + outline->num_hedges;
|
||||||
segments = outline->horz_segments;
|
segments = outline->horz_segments;
|
||||||
|
|
||||||
for ( dimension = 1; dimension >= 0; dimension-- )
|
for ( dimension = 1; dimension >= 0; dimension-- )
|
||||||
{
|
{
|
||||||
AH_Edge* edge;
|
AH_Edge* edge;
|
||||||
|
|
||||||
printf ( "Table of %s edges:\n", !dimension ? "vertical" : "horizontal" );
|
|
||||||
printf ( " [ index | pos | dir | link | serif | blue | opos | pos ]\n" );
|
printf ( "Table of %s edges:\n",
|
||||||
|
!dimension ? "vertical" : "horizontal" );
|
||||||
|
printf ( " [ index | pos | dir | link |"
|
||||||
|
" serif | blue | opos | pos ]\n" );
|
||||||
|
|
||||||
for ( edge = edges; edge < limit; edge++ )
|
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,
|
edge - edges,
|
||||||
(int)edge->fpos,
|
(int)edge->fpos,
|
||||||
edge->dir == ah_dir_up ? "up" :
|
edge->dir == ah_dir_up
|
||||||
(edge->dir == ah_dir_down ? "down" :
|
? "up"
|
||||||
(edge->dir == ah_dir_left ? "left" :
|
: ( edge->dir == ah_dir_down
|
||||||
(edge->dir == ah_dir_right ? "right" : "none")
|
? "down"
|
||||||
)
|
: ( edge->dir == ah_dir_left
|
||||||
),
|
? "left"
|
||||||
|
: ( edge->dir == ah_dir_right
|
||||||
|
? "right"
|
||||||
|
: "none" ) ) ),
|
||||||
edge->link ? ( edge->link - edges ) : -1,
|
edge->link ? ( edge->link - edges ) : -1,
|
||||||
edge->serif ? ( edge->serif - edges ) : -1,
|
edge->serif ? ( edge->serif - edges ) : -1,
|
||||||
edge->blue_edge ? 'y' : 'n',
|
edge->blue_edge ? 'y' : 'n',
|
||||||
|
@ -1282,10 +1287,13 @@
|
||||||
edge->pos / 64.0 );
|
edge->pos / 64.0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
edges = outline->vert_edges;
|
edges = outline->vert_edges;
|
||||||
limit = edges + outline->num_vedges;
|
limit = edges + outline->num_vedges;
|
||||||
segments = outline->vert_segments;
|
segments = outline->vert_segments;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
#endif /* AH_DEBUG_GLYPH */
|
||||||
|
|
||||||
|
|
||||||
|
/* END */
|
||||||
|
|
|
@ -2,52 +2,60 @@
|
||||||
/* */
|
/* */
|
||||||
/* ahhint.c */
|
/* ahhint.c */
|
||||||
/* */
|
/* */
|
||||||
/* Glyph hinter */
|
/* Glyph hinter (body). */
|
||||||
/* */
|
/* */
|
||||||
/* Copyright 2000: Catharon Productions Inc. */
|
/* Copyright 2000 Catharon Productions Inc. */
|
||||||
/* Author: David Turner */
|
/* Author: David Turner */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of the Catharon Typography Project and shall only */
|
/* This file is part of the Catharon Typography Project and shall only */
|
||||||
/* be used, modified, and distributed under the terms of the Catharon */
|
/* be used, modified, and distributed under the terms of the Catharon */
|
||||||
/* Open Source License that should come with this file under the name */
|
/* Open Source License that should come with this file under the name */
|
||||||
/* "CatharonLicense.txt". By continuing to use, modify, or distribute */
|
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||||
/* this file you indicate that you have read the license and */
|
/* this file you indicate that you have read the license and */
|
||||||
/* understand and accept it fully. */
|
/* understand and accept it fully. */
|
||||||
/* */
|
/* */
|
||||||
/* Note that this license is compatible with the FreeType license */
|
/* Note that this license is compatible with the FreeType license. */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifdef FT_FLAT_COMPILE
|
#ifdef FT_FLAT_COMPILE
|
||||||
|
|
||||||
#include "ahhint.h"
|
#include "ahhint.h"
|
||||||
#include "ahglyph.h"
|
#include "ahglyph.h"
|
||||||
#include "ahangles.h"
|
#include "ahangles.h"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <autohint/ahhint.h>
|
#include <autohint/ahhint.h>
|
||||||
#include <autohint/ahglyph.h>
|
#include <autohint/ahglyph.h>
|
||||||
#include <autohint/ahangles.h>
|
#include <autohint/ahangles.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <freetype/ftoutln.h>
|
#include <freetype/ftoutln.h>
|
||||||
|
|
||||||
|
|
||||||
#define FACE_GLOBALS( face ) ((AH_Face_Globals*)(face)->autohint.data)
|
#define FACE_GLOBALS( face ) ((AH_Face_Globals*)(face)->autohint.data)
|
||||||
|
|
||||||
#define AH_USE_IUP
|
#define AH_USE_IUP
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************/
|
/*************************************************************************/
|
||||||
/*******************************************************************/
|
/*************************************************************************/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/**** Hinting routines ****/
|
/**** Hinting routines ****/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/*******************************************************************/
|
/*************************************************************************/
|
||||||
/*******************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
static int disable_horz_edges = 0;
|
static int disable_horz_edges = 0;
|
||||||
static int disable_vert_edges = 0;
|
static int disable_vert_edges = 0;
|
||||||
|
|
||||||
|
|
||||||
/* snap a given width in scaled coordinates to one of the */
|
/* snap a given width in scaled coordinates to one of the */
|
||||||
/* current standard widths.. */
|
/* current standard widths */
|
||||||
static
|
static
|
||||||
FT_Pos ah_snap_width( FT_Pos* widths,
|
FT_Pos ah_snap_width( FT_Pos* widths,
|
||||||
FT_Int count,
|
FT_Int count,
|
||||||
|
@ -57,14 +65,17 @@
|
||||||
FT_Pos best = 64 + 32 + 2;
|
FT_Pos best = 64 + 32 + 2;
|
||||||
FT_Pos reference = width;
|
FT_Pos reference = width;
|
||||||
|
|
||||||
|
|
||||||
for ( n = 0; n < count; n++ )
|
for ( n = 0; n < count; n++ )
|
||||||
{
|
{
|
||||||
FT_Pos w;
|
FT_Pos w;
|
||||||
FT_Pos dist;
|
FT_Pos dist;
|
||||||
|
|
||||||
|
|
||||||
w = widths[n];
|
w = widths[n];
|
||||||
dist = width - w;
|
dist = width - w;
|
||||||
if (dist < 0) dist = -dist;
|
if ( dist < 0 )
|
||||||
|
dist = -dist;
|
||||||
if ( dist < best )
|
if ( dist < best )
|
||||||
{
|
{
|
||||||
best = dist;
|
best = dist;
|
||||||
|
@ -89,8 +100,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* align one stem edge relative to the previous stem edge */
|
||||||
/* Align one stem edge relative to the previous stem edge */
|
|
||||||
static
|
static
|
||||||
void ah_align_linked_edge( AH_Hinter* hinter,
|
void ah_align_linked_edge( AH_Hinter* hinter,
|
||||||
AH_Edge* base_edge,
|
AH_Edge* base_edge,
|
||||||
|
@ -101,6 +111,7 @@
|
||||||
AH_Globals* globals = &hinter->globals->scaled;
|
AH_Globals* globals = &hinter->globals->scaled;
|
||||||
FT_Pos sign = 1;
|
FT_Pos sign = 1;
|
||||||
|
|
||||||
|
|
||||||
if ( dist < 0 )
|
if ( dist < 0 )
|
||||||
{
|
{
|
||||||
dist = -dist;
|
dist = -dist;
|
||||||
|
@ -112,7 +123,7 @@
|
||||||
dist = ah_snap_width( globals->heights, globals->num_heights, dist );
|
dist = ah_snap_width( globals->heights, globals->num_heights, dist );
|
||||||
|
|
||||||
/* in the case of vertical hinting, always round */
|
/* in the case of vertical hinting, always round */
|
||||||
/* the stem heights to integer pixels.. */
|
/* the stem heights to integer pixels */
|
||||||
if ( dist >= 64 )
|
if ( dist >= 64 )
|
||||||
dist = ( dist + 16 ) & -64;
|
dist = ( dist + 16 ) & -64;
|
||||||
else
|
else
|
||||||
|
@ -125,7 +136,7 @@
|
||||||
if ( hinter->flags & ah_hinter_monochrome )
|
if ( hinter->flags & ah_hinter_monochrome )
|
||||||
{
|
{
|
||||||
/* monochrome horizontal hinting: snap widths to integer pixels */
|
/* monochrome horizontal hinting: snap widths to integer pixels */
|
||||||
/* with a different threshold.. */
|
/* with a different threshold */
|
||||||
if ( dist < 64 )
|
if ( dist < 64 )
|
||||||
dist = 64;
|
dist = 64;
|
||||||
else
|
else
|
||||||
|
@ -134,21 +145,20 @@
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* for horizontal anti-aliased hinting, we adopt a more subtle */
|
/* for horizontal anti-aliased hinting, we adopt a more subtle */
|
||||||
/* approach, we strengthen small stems, round stems whose size */
|
/* approach: we strengthen small stems, round stems whose size */
|
||||||
/* is between 1 and 2 pixels to an integer, otherwise nothing */
|
/* is between 1 and 2 pixels to an integer, otherwise nothing */
|
||||||
if ( dist < 48 )
|
if ( dist < 48 )
|
||||||
dist = ( dist + 64 ) >> 1;
|
dist = ( dist + 64 ) >> 1;
|
||||||
|
|
||||||
else if ( dist < 128 )
|
else if ( dist < 128 )
|
||||||
dist = ( dist + 42 ) & -64;
|
dist = ( dist + 42 ) & -64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stem_edge->pos = base_edge->pos + sign * dist;
|
stem_edge->pos = base_edge->pos + sign * dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void ah_align_serif_edge( AH_Hinter* hinter,
|
void ah_align_serif_edge( AH_Hinter* hinter,
|
||||||
AH_Edge* base,
|
AH_Edge* base,
|
||||||
|
@ -158,6 +168,8 @@
|
||||||
FT_Pos sign = 1;
|
FT_Pos sign = 1;
|
||||||
|
|
||||||
UNUSED( hinter );
|
UNUSED( hinter );
|
||||||
|
|
||||||
|
|
||||||
dist = serif->opos - base->opos;
|
dist = serif->opos - base->opos;
|
||||||
if ( dist < 0 )
|
if ( dist < 0 )
|
||||||
{
|
{
|
||||||
|
@ -165,8 +177,8 @@
|
||||||
sign = -1;
|
sign = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base->flags & ah_edge_done)
|
|
||||||
/* do not strengthen serifs */
|
/* do not strengthen serifs */
|
||||||
|
if ( base->flags & ah_edge_done )
|
||||||
{
|
{
|
||||||
if ( dist > 64 )
|
if ( dist > 64 )
|
||||||
dist = ( dist + 16 ) & -64;
|
dist = ( dist + 16 ) & -64;
|
||||||
|
@ -174,20 +186,21 @@
|
||||||
else if ( dist <= 32 )
|
else if ( dist <= 32 )
|
||||||
dist = ( dist + 33 ) >> 1;
|
dist = ( dist + 33 ) >> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
serif->pos = base->pos + sign * dist;
|
serif->pos = base->pos + sign * dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************/
|
/*************************************************************************/
|
||||||
/**************************************************************************/
|
/*************************************************************************/
|
||||||
/**************************************************************************/
|
/*************************************************************************/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/**** E D G E H I N T I N G ****/
|
/**** E D G E H I N T I N G ****/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/**** ****/
|
/*************************************************************************/
|
||||||
/**************************************************************************/
|
/*************************************************************************/
|
||||||
/**************************************************************************/
|
/*************************************************************************/
|
||||||
/**************************************************************************/
|
|
||||||
|
|
||||||
/* Another alternative edge hinting algorithm */
|
/* Another alternative edge hinting algorithm */
|
||||||
static
|
static
|
||||||
|
@ -198,6 +211,7 @@
|
||||||
AH_Outline* outline = hinter->glyph;
|
AH_Outline* outline = hinter->glyph;
|
||||||
FT_Int dimension;
|
FT_Int dimension;
|
||||||
|
|
||||||
|
|
||||||
edges = outline->horz_edges;
|
edges = outline->horz_edges;
|
||||||
edge_limit = edges + outline->num_hedges;
|
edge_limit = edges + outline->num_hedges;
|
||||||
|
|
||||||
|
@ -209,6 +223,7 @@
|
||||||
AH_Edge* anchor = 0;
|
AH_Edge* anchor = 0;
|
||||||
int has_serifs = 0;
|
int has_serifs = 0;
|
||||||
|
|
||||||
|
|
||||||
if ( disable_vert_edges && !dimension )
|
if ( disable_vert_edges && !dimension )
|
||||||
goto Next_Dimension;
|
goto Next_Dimension;
|
||||||
|
|
||||||
|
@ -216,7 +231,7 @@
|
||||||
goto Next_Dimension;
|
goto Next_Dimension;
|
||||||
|
|
||||||
/* we begin by aligning all stems relative to the blue zone */
|
/* we begin by aligning all stems relative to the blue zone */
|
||||||
/* if needed.. that's only for horizontal edges.. */
|
/* if needed -- that's only for horizontal edges */
|
||||||
if ( dimension )
|
if ( dimension )
|
||||||
{
|
{
|
||||||
for ( edge = edges; edge < edge_limit; edge++ )
|
for ( edge = edges; edge < edge_limit; edge++ )
|
||||||
|
@ -224,6 +239,7 @@
|
||||||
FT_Pos* blue;
|
FT_Pos* blue;
|
||||||
AH_Edge *edge1, *edge2;
|
AH_Edge *edge1, *edge2;
|
||||||
|
|
||||||
|
|
||||||
if ( edge->flags & ah_edge_done )
|
if ( edge->flags & ah_edge_done )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -267,6 +283,7 @@
|
||||||
{
|
{
|
||||||
AH_Edge *edge2;
|
AH_Edge *edge2;
|
||||||
|
|
||||||
|
|
||||||
if ( edge->flags & ah_edge_done )
|
if ( edge->flags & ah_edge_done )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -283,10 +300,12 @@
|
||||||
/* this should not happen, but it's better to be safe.. */
|
/* this should not happen, but it's better to be safe.. */
|
||||||
if ( edge2->blue_edge || edge2 < edge )
|
if ( edge2->blue_edge || edge2 < edge )
|
||||||
{
|
{
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf( "strange blue alignement, edge %d to %d\n",
|
printf( "strange blue alignement, edge %d to %d\n",
|
||||||
edge - edges, edge2 - edges );
|
edge - edges, edge2 - edges );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ah_align_linked_edge( hinter, edge2, edge, dimension );
|
ah_align_linked_edge( hinter, edge2, edge, dimension );
|
||||||
edge->flags |= ah_edge_done;
|
edge->flags |= ah_edge_done;
|
||||||
continue;
|
continue;
|
||||||
|
@ -302,7 +321,8 @@
|
||||||
anchor = edge;
|
anchor = edge;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
edge->pos = anchor->pos + ((edge->opos - anchor->opos + 32) & -64);
|
edge->pos = anchor->pos +
|
||||||
|
( ( edge->opos - anchor->opos + 32 ) & -64 );
|
||||||
|
|
||||||
edge->flags |= ah_edge_done;
|
edge->flags |= ah_edge_done;
|
||||||
|
|
||||||
|
@ -332,7 +352,7 @@
|
||||||
goto Next_Dimension;
|
goto Next_Dimension;
|
||||||
|
|
||||||
/* now, hint the remaining edges (serifs and single) in order */
|
/* now, hint the remaining edges (serifs and single) in order */
|
||||||
/* to complete our processing.. */
|
/* to complete our processing */
|
||||||
for ( edge = edges; edge < edge_limit; edge++ )
|
for ( edge = edges; edge < edge_limit; edge++ )
|
||||||
{
|
{
|
||||||
if ( edge->flags & ah_edge_done )
|
if ( edge->flags & ah_edge_done )
|
||||||
|
@ -348,14 +368,16 @@
|
||||||
anchor = edge;
|
anchor = edge;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
edge->pos = anchor->pos + ((edge->opos-anchor->opos+32) & -64);
|
edge->pos = anchor->pos +
|
||||||
|
( ( edge->opos-anchor->opos + 32 ) & -64 );
|
||||||
|
|
||||||
edge->flags |= ah_edge_done;
|
edge->flags |= ah_edge_done;
|
||||||
|
|
||||||
if ( edge > edges && edge->pos < edge[-1].pos )
|
if ( edge > edges && edge->pos < edge[-1].pos )
|
||||||
edge->pos = edge[-1].pos;
|
edge->pos = edge[-1].pos;
|
||||||
|
|
||||||
if ( edge+1 < edge_limit && edge[1].flags & ah_edge_done &&
|
if ( edge + 1 < edge_limit &&
|
||||||
|
edge[1].flags & ah_edge_done &&
|
||||||
edge->pos > edge[1].pos )
|
edge->pos > edge[1].pos )
|
||||||
edge->pos = edge[1].pos;
|
edge->pos = edge[1].pos;
|
||||||
}
|
}
|
||||||
|
@ -364,15 +386,9 @@
|
||||||
edges = outline->vert_edges;
|
edges = outline->vert_edges;
|
||||||
edge_limit = edges + outline->num_vedges;
|
edge_limit = edges + outline->num_vedges;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LOCAL_FUNC
|
LOCAL_FUNC
|
||||||
void ah_hinter_hint_edges( AH_Hinter* hinter,
|
void ah_hinter_hint_edges( AH_Hinter* hinter,
|
||||||
int no_horz_edges,
|
int no_horz_edges,
|
||||||
|
@ -382,17 +398,18 @@
|
||||||
disable_vert_edges = no_vert_edges;
|
disable_vert_edges = no_vert_edges;
|
||||||
|
|
||||||
/* AH_Interpolate_Blue_Edges( hinter ); -- doesn't seem to help */
|
/* AH_Interpolate_Blue_Edges( hinter ); -- doesn't seem to help */
|
||||||
/* reduce the problem of the disappearing eye in the "e" of Times */
|
/* reduce the problem of the disappearing eye in the `e' of Times... */
|
||||||
/* also, creates some artifacts near the blue zones ?? */
|
/* also, creates some artifacts near the blue zones? */
|
||||||
{
|
{
|
||||||
ah_hint_edges_3( hinter );
|
ah_hint_edges_3( hinter );
|
||||||
|
|
||||||
/* outline optimiser removed temporarily */
|
|
||||||
#if 0
|
#if 0
|
||||||
|
/* outline optimizer removed temporarily */
|
||||||
if ( hinter->flags & ah_hinter_optimize )
|
if ( hinter->flags & ah_hinter_optimize )
|
||||||
{
|
{
|
||||||
AH_Optimizer opt;
|
AH_Optimizer opt;
|
||||||
|
|
||||||
|
|
||||||
if ( !AH_Optimizer_Init( &opt, hinter->glyph, hinter->memory ) )
|
if ( !AH_Optimizer_Init( &opt, hinter->glyph, hinter->memory ) )
|
||||||
{
|
{
|
||||||
AH_Optimizer_Compute( &opt );
|
AH_Optimizer_Compute( &opt );
|
||||||
|
@ -400,21 +417,20 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
/**************************************************************************/
|
/*************************************************************************/
|
||||||
/**************************************************************************/
|
/*************************************************************************/
|
||||||
/**************************************************************************/
|
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/**** P O I N T H I N T I N G ****/
|
/**** P O I N T H I N T I N G ****/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/**** ****/
|
/*************************************************************************/
|
||||||
/**************************************************************************/
|
/*************************************************************************/
|
||||||
/**************************************************************************/
|
/*************************************************************************/
|
||||||
/**************************************************************************/
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void ah_hinter_align_edge_points( AH_Hinter* hinter )
|
void ah_hinter_align_edge_points( AH_Hinter* hinter )
|
||||||
|
@ -424,6 +440,7 @@
|
||||||
AH_Edge* edge_limit;
|
AH_Edge* edge_limit;
|
||||||
FT_Int dimension;
|
FT_Int dimension;
|
||||||
|
|
||||||
|
|
||||||
edges = outline->horz_edges;
|
edges = outline->horz_edges;
|
||||||
edge_limit = edges + outline->num_hedges;
|
edge_limit = edges + outline->num_hedges;
|
||||||
|
|
||||||
|
@ -433,17 +450,23 @@
|
||||||
AH_Edge* before;
|
AH_Edge* before;
|
||||||
AH_Edge* after;
|
AH_Edge* after;
|
||||||
|
|
||||||
|
|
||||||
before = 0;
|
before = 0;
|
||||||
after = 0;
|
after = 0;
|
||||||
|
|
||||||
edge = edges;
|
edge = edges;
|
||||||
for ( ; edge < edge_limit; edge++ )
|
for ( ; edge < edge_limit; edge++ )
|
||||||
{
|
{
|
||||||
/* move the points of each segment in each edge to the edge's position */
|
/* move the points of each segment */
|
||||||
|
/* in each edge to the edge's position */
|
||||||
AH_Segment* seg = edge->first;
|
AH_Segment* seg = edge->first;
|
||||||
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
AH_Point* point = seg->first;
|
AH_Point* point = seg->first;
|
||||||
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if ( dimension )
|
if ( dimension )
|
||||||
|
@ -456,6 +479,7 @@
|
||||||
point->x = edge->pos;
|
point->x = edge->pos;
|
||||||
point->flags |= ah_flah_touch_x;
|
point->flags |= ah_flah_touch_x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( point == seg->last )
|
if ( point == seg->last )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -463,16 +487,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
seg = seg->edge_next;
|
seg = seg->edge_next;
|
||||||
|
|
||||||
|
} while ( seg != edge->first );
|
||||||
}
|
}
|
||||||
while (seg != edge->first);
|
|
||||||
}
|
|
||||||
edges = outline->vert_edges;
|
edges = outline->vert_edges;
|
||||||
edge_limit = edges + outline->num_vedges;
|
edge_limit = edges + outline->num_vedges;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* hint the strong points - this is equivalent to the TrueType "IP" */
|
/* hint the strong points -- this is equivalent to the TrueType `IP' */
|
||||||
static
|
static
|
||||||
void ah_hinter_align_strong_points( AH_Hinter* hinter )
|
void ah_hinter_align_strong_points( AH_Hinter* hinter )
|
||||||
{
|
{
|
||||||
|
@ -484,6 +509,7 @@
|
||||||
AH_Point* point_limit;
|
AH_Point* point_limit;
|
||||||
AH_Flags touch_flag;
|
AH_Flags touch_flag;
|
||||||
|
|
||||||
|
|
||||||
points = outline->points;
|
points = outline->points;
|
||||||
point_limit = points + outline->num_points;
|
point_limit = points + outline->num_points;
|
||||||
|
|
||||||
|
@ -498,6 +524,7 @@
|
||||||
AH_Edge* before;
|
AH_Edge* before;
|
||||||
AH_Edge* after;
|
AH_Edge* after;
|
||||||
|
|
||||||
|
|
||||||
before = 0;
|
before = 0;
|
||||||
after = 0;
|
after = 0;
|
||||||
|
|
||||||
|
@ -507,18 +534,27 @@
|
||||||
FT_Pos u, ou, fu; /* point position */
|
FT_Pos u, ou, fu; /* point position */
|
||||||
FT_Pos delta;
|
FT_Pos delta;
|
||||||
|
|
||||||
|
|
||||||
if ( point->flags & touch_flag )
|
if ( point->flags & touch_flag )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
|
#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
|
||||||
/* if this point is candidate to weak interpolation, we'll */
|
/* if this point is candidate to weak interpolation, we will */
|
||||||
/* interpolate it after all strong points have been processed */
|
/* interpolate it after all strong points have been processed */
|
||||||
if ( point->flags & ah_flah_weak_interpolation )
|
if ( point->flags & ah_flah_weak_interpolation )
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dimension) { u = point->fy; ou = point->oy; }
|
if ( dimension )
|
||||||
else { u = point->fx; ou = point->ox; }
|
{
|
||||||
|
u = point->fy;
|
||||||
|
ou = point->oy;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u = point->fx;
|
||||||
|
ou = point->ox;
|
||||||
|
}
|
||||||
|
|
||||||
fu = u;
|
fu = u;
|
||||||
|
|
||||||
|
@ -545,6 +581,7 @@
|
||||||
AH_Edge* before = 0;
|
AH_Edge* before = 0;
|
||||||
AH_Edge* after = 0;
|
AH_Edge* after = 0;
|
||||||
|
|
||||||
|
|
||||||
for ( edge = edges; edge < edge_limit; edge++ )
|
for ( edge = edges; edge < edge_limit; edge++ )
|
||||||
{
|
{
|
||||||
if ( u == edge->fpos )
|
if ( u == edge->fpos )
|
||||||
|
@ -574,11 +611,14 @@
|
||||||
after->pos - before->pos,
|
after->pos - before->pos,
|
||||||
after->fpos - before->fpos );
|
after->fpos - before->fpos );
|
||||||
}
|
}
|
||||||
|
|
||||||
Store_Point:
|
Store_Point:
|
||||||
|
|
||||||
/* save the point position */
|
/* save the point position */
|
||||||
if (dimension) point->y = u;
|
if ( dimension )
|
||||||
else point->x = u;
|
point->y = u;
|
||||||
|
else
|
||||||
|
point->x = u;
|
||||||
|
|
||||||
point->flags |= touch_flag;
|
point->flags |= touch_flag;
|
||||||
}
|
}
|
||||||
|
@ -591,6 +631,7 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
|
#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
|
||||||
|
|
||||||
static
|
static
|
||||||
void ah_iup_shift( AH_Point* p1,
|
void ah_iup_shift( AH_Point* p1,
|
||||||
AH_Point* p2,
|
AH_Point* p2,
|
||||||
|
@ -599,6 +640,7 @@
|
||||||
AH_Point* p;
|
AH_Point* p;
|
||||||
FT_Pos delta = ref->u - ref->v;
|
FT_Pos delta = ref->u - ref->v;
|
||||||
|
|
||||||
|
|
||||||
for ( p = p1; p < ref; p++ )
|
for ( p = p1; p < ref; p++ )
|
||||||
p->u = p->v + delta;
|
p->u = p->v + delta;
|
||||||
|
|
||||||
|
@ -620,7 +662,9 @@
|
||||||
FT_Pos d1 = ref1->u - v1;
|
FT_Pos d1 = ref1->u - v1;
|
||||||
FT_Pos d2 = ref2->u - v2;
|
FT_Pos d2 = ref2->u - v2;
|
||||||
|
|
||||||
if (p1 > p2) return;
|
|
||||||
|
if ( p1 > p2 )
|
||||||
|
return;
|
||||||
|
|
||||||
if ( v1 == v2 )
|
if ( v1 == v2 )
|
||||||
{
|
{
|
||||||
|
@ -628,8 +672,12 @@
|
||||||
{
|
{
|
||||||
FT_Pos u = p->v;
|
FT_Pos u = p->v;
|
||||||
|
|
||||||
if (u <= v1) u += d1;
|
|
||||||
else u += d2;
|
if ( u <= v1 )
|
||||||
|
u += d1;
|
||||||
|
else
|
||||||
|
u += d2;
|
||||||
|
|
||||||
p->u = u;
|
p->u = u;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -641,9 +689,12 @@
|
||||||
{
|
{
|
||||||
u = p->v;
|
u = p->v;
|
||||||
|
|
||||||
if (u <= v1) u += d1;
|
if ( u <= v1 )
|
||||||
else if (u >= v2) u += d2;
|
u += d1;
|
||||||
else u = ref1->u+FT_MulDiv( u-v1, ref2->u-ref1->u, v2-v1 );
|
else if ( u >= v2 )
|
||||||
|
u += d2;
|
||||||
|
else
|
||||||
|
u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
|
||||||
|
|
||||||
p->u = u;
|
p->u = u;
|
||||||
}
|
}
|
||||||
|
@ -653,16 +704,21 @@
|
||||||
for ( p = p1; p <= p2; p++ )
|
for ( p = p1; p <= p2; p++ )
|
||||||
{
|
{
|
||||||
u = p->v;
|
u = p->v;
|
||||||
if (u <= v2) u += d2;
|
|
||||||
else if (u >= v1) u += d1;
|
if ( u <= v2 )
|
||||||
else u = ref1->u+FT_MulDiv( u-v1, ref2->u-ref1->u, v2-v1 );
|
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;
|
p->u = u;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* interpolate weak points - this is equivalent to the TrueType "IUP" */
|
|
||||||
|
/* interpolate weak points -- this is equivalent to the TrueType `IUP' */
|
||||||
static
|
static
|
||||||
void ah_hinter_align_weak_points( AH_Hinter* hinter )
|
void ah_hinter_align_weak_points( AH_Hinter* hinter )
|
||||||
{
|
{
|
||||||
|
@ -675,6 +731,7 @@
|
||||||
AH_Point** contour_limit;
|
AH_Point** contour_limit;
|
||||||
AH_Flags touch_flag;
|
AH_Flags touch_flag;
|
||||||
|
|
||||||
|
|
||||||
points = outline->points;
|
points = outline->points;
|
||||||
point_limit = points + outline->num_points;
|
point_limit = points + outline->num_points;
|
||||||
|
|
||||||
|
@ -695,6 +752,7 @@
|
||||||
AH_Point* first_point;
|
AH_Point* first_point;
|
||||||
AH_Point** contour;
|
AH_Point** contour;
|
||||||
|
|
||||||
|
|
||||||
point = points;
|
point = points;
|
||||||
contour = outline->contours;
|
contour = outline->contours;
|
||||||
|
|
||||||
|
@ -712,13 +770,14 @@
|
||||||
AH_Point* first_touched = point;
|
AH_Point* first_touched = point;
|
||||||
AH_Point* cur_touched = point;
|
AH_Point* cur_touched = point;
|
||||||
|
|
||||||
|
|
||||||
point++;
|
point++;
|
||||||
while ( point <= end_point )
|
while ( point <= end_point )
|
||||||
{
|
{
|
||||||
if ( point->flags & touch_flag )
|
if ( point->flags & touch_flag )
|
||||||
{
|
{
|
||||||
/* we found two succesive touched points, we interpolate */
|
/* we found two successive touched points; we interpolate */
|
||||||
/* all contour points between them.. */
|
/* all contour points between them */
|
||||||
ah_iup_interp( cur_touched + 1, point - 1,
|
ah_iup_interp( cur_touched + 1, point - 1,
|
||||||
cur_touched, point );
|
cur_touched, point );
|
||||||
cur_touched = point;
|
cur_touched = point;
|
||||||
|
@ -729,13 +788,13 @@
|
||||||
if ( cur_touched == first_touched )
|
if ( cur_touched == first_touched )
|
||||||
{
|
{
|
||||||
/* this is a special case: only one point was touched in the */
|
/* this is a special case: only one point was touched in the */
|
||||||
/* contour.. we thus simply shift the whole contour.. */
|
/* contour; we thus simply shift the whole contour */
|
||||||
ah_iup_shift( first_point, end_point, cur_touched );
|
ah_iup_shift( first_point, end_point, cur_touched );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* now interpolate after the last touched point to the end */
|
/* now interpolate after the last touched point to the end */
|
||||||
/* of the contour.. */
|
/* of the contour */
|
||||||
ah_iup_interp( cur_touched + 1, end_point,
|
ah_iup_interp( cur_touched + 1, end_point,
|
||||||
cur_touched, first_touched );
|
cur_touched, first_touched );
|
||||||
|
|
||||||
|
@ -766,7 +825,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
#endif /* !AH_OPTION_NO_WEAK_INTERPOLATION */
|
||||||
|
|
||||||
|
|
||||||
LOCAL_FUNC
|
LOCAL_FUNC
|
||||||
void ah_hinter_align_points( AH_Hinter* hinter )
|
void ah_hinter_align_points( AH_Hinter* hinter )
|
||||||
|
@ -783,16 +844,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************/
|
/*************************************************************************/
|
||||||
/**************************************************************************/
|
/*************************************************************************/
|
||||||
/**************************************************************************/
|
/*************************************************************************/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/**** H I N T E R O B J E C T M E T H O D S ****/
|
/**** H I N T E R O B J E C T M E T H O D S ****/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/**** ****/
|
/*************************************************************************/
|
||||||
/**************************************************************************/
|
/*************************************************************************/
|
||||||
/**************************************************************************/
|
/*************************************************************************/
|
||||||
/**************************************************************************/
|
|
||||||
|
|
||||||
/* scale and fit the global metrics */
|
/* scale and fit the global metrics */
|
||||||
static
|
static
|
||||||
|
@ -805,6 +866,7 @@
|
||||||
AH_Globals* design = &globals->design;
|
AH_Globals* design = &globals->design;
|
||||||
AH_Globals* scaled = &globals->scaled;
|
AH_Globals* scaled = &globals->scaled;
|
||||||
|
|
||||||
|
|
||||||
/* copy content */
|
/* copy content */
|
||||||
*scaled = *design;
|
*scaled = *design;
|
||||||
|
|
||||||
|
@ -820,8 +882,11 @@
|
||||||
{
|
{
|
||||||
FT_Pos delta, delta2;
|
FT_Pos delta, delta2;
|
||||||
|
|
||||||
|
|
||||||
delta = design->blue_shoots[n] - design->blue_refs[n];
|
delta = design->blue_shoots[n] - design->blue_refs[n];
|
||||||
delta2 = delta; if (delta < 0) delta2 = -delta2;
|
delta2 = delta;
|
||||||
|
if ( delta < 0 )
|
||||||
|
delta2 = -delta2;
|
||||||
delta2 = FT_MulFix( delta2, y_scale );
|
delta2 = FT_MulFix( delta2, y_scale );
|
||||||
|
|
||||||
if ( delta2 < 32 )
|
if ( delta2 < 32 )
|
||||||
|
@ -831,11 +896,14 @@
|
||||||
else
|
else
|
||||||
delta2 = ( delta2 + 32 ) & -64;
|
delta2 = ( delta2 + 32 ) & -64;
|
||||||
|
|
||||||
if (delta < 0) delta2 = -delta2;
|
if ( delta < 0 )
|
||||||
|
delta2 = -delta2;
|
||||||
|
|
||||||
scaled->blue_refs [n] = (FT_MulFix(design->blue_refs[n],y_scale)+32) & -64;
|
scaled->blue_refs[n] =
|
||||||
|
( FT_MulFix( design->blue_refs[n], y_scale ) + 32 ) & -64;
|
||||||
scaled->blue_shoots[n] = scaled->blue_refs[n] + delta2;
|
scaled->blue_shoots[n] = scaled->blue_refs[n] + delta2;
|
||||||
}
|
}
|
||||||
|
|
||||||
globals->x_scale = x_scale;
|
globals->x_scale = x_scale;
|
||||||
globals->y_scale = y_scale;
|
globals->y_scale = y_scale;
|
||||||
}
|
}
|
||||||
|
@ -849,19 +917,20 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* finalise a hinter object */
|
/* finalize a hinter object */
|
||||||
void ah_hinter_done( AH_Hinter* hinter )
|
void ah_hinter_done( AH_Hinter* hinter )
|
||||||
{
|
{
|
||||||
if ( hinter )
|
if ( hinter )
|
||||||
{
|
{
|
||||||
FT_Memory memory = hinter->memory;
|
FT_Memory memory = hinter->memory;
|
||||||
|
|
||||||
|
|
||||||
ah_loader_done( hinter->loader );
|
ah_loader_done( hinter->loader );
|
||||||
ah_outline_done( hinter->glyph );
|
ah_outline_done( hinter->glyph );
|
||||||
|
|
||||||
/* note: the globals pointer is _not_ owned by the hinter */
|
/* note: the `globals' pointer is _not_ owned by the hinter */
|
||||||
/* but by the current face object, we don't need to */
|
/* but by the current face object, we don't need to */
|
||||||
/* release it.. */
|
/* release it */
|
||||||
hinter->globals = 0;
|
hinter->globals = 0;
|
||||||
hinter->face = 0;
|
hinter->face = 0;
|
||||||
|
|
||||||
|
@ -871,16 +940,19 @@
|
||||||
|
|
||||||
|
|
||||||
/* create a new empty hinter object */
|
/* create a new empty hinter object */
|
||||||
FT_Error ah_hinter_new( FT_Library library, AH_Hinter* *ahinter )
|
FT_Error ah_hinter_new( FT_Library library,
|
||||||
|
AH_Hinter** ahinter )
|
||||||
{
|
{
|
||||||
AH_Hinter* hinter = 0;
|
AH_Hinter* hinter = 0;
|
||||||
FT_Memory memory = library->memory;
|
FT_Memory memory = library->memory;
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
|
|
||||||
|
|
||||||
*ahinter = 0;
|
*ahinter = 0;
|
||||||
|
|
||||||
/* allocate object */
|
/* allocate object */
|
||||||
if (ALLOC( hinter, sizeof(*hinter) )) goto Exit;
|
if ( ALLOC( hinter, sizeof ( *hinter ) ) )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
hinter->memory = memory;
|
hinter->memory = memory;
|
||||||
hinter->flags = 0;
|
hinter->flags = 0;
|
||||||
|
@ -889,7 +961,8 @@
|
||||||
error = ah_outline_new( memory, &hinter->glyph ) ||
|
error = ah_outline_new( memory, &hinter->glyph ) ||
|
||||||
ah_loader_new ( memory, &hinter->loader ) ||
|
ah_loader_new ( memory, &hinter->loader ) ||
|
||||||
ah_loader_create_extra( hinter->loader );
|
ah_loader_create_extra( hinter->loader );
|
||||||
if (error) goto Exit;
|
if ( error )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
*ahinter = hinter;
|
*ahinter = hinter;
|
||||||
|
|
||||||
|
@ -910,18 +983,21 @@
|
||||||
FT_Memory memory = hinter->memory;
|
FT_Memory memory = hinter->memory;
|
||||||
AH_Face_Globals* face_globals;
|
AH_Face_Globals* face_globals;
|
||||||
|
|
||||||
|
|
||||||
if ( ALLOC( face_globals, sizeof ( *face_globals ) ) )
|
if ( ALLOC( face_globals, sizeof ( *face_globals ) ) )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
hinter->face = face;
|
hinter->face = face;
|
||||||
hinter->globals = face_globals;
|
hinter->globals = face_globals;
|
||||||
|
|
||||||
if ( globals )
|
if ( globals )
|
||||||
face_globals->design = *globals;
|
face_globals->design = *globals;
|
||||||
else
|
else
|
||||||
ah_hinter_compute_globals( hinter );
|
ah_hinter_compute_globals( hinter );
|
||||||
|
|
||||||
face->autohint.data = face_globals;
|
face->autohint.data = face_globals;
|
||||||
face->autohint.finalizer = (FT_Generic_Finalizer)ah_hinter_done_face_globals;
|
face->autohint.finalizer = (FT_Generic_Finalizer)
|
||||||
|
ah_hinter_done_face_globals;
|
||||||
face_globals->face = face;
|
face_globals->face = face;
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
|
@ -929,18 +1005,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* discard a face's autohint globals */
|
/* discard a face's autohint globals */
|
||||||
void ah_hinter_done_face_globals( AH_Face_Globals* globals )
|
void ah_hinter_done_face_globals( AH_Face_Globals* globals )
|
||||||
{
|
{
|
||||||
FT_Face face = globals->face;
|
FT_Face face = globals->face;
|
||||||
FT_Memory memory = face->memory;
|
FT_Memory memory = face->memory;
|
||||||
|
|
||||||
|
|
||||||
FREE( globals );
|
FREE( globals );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
FT_Error ah_hinter_load( AH_Hinter* hinter,
|
FT_Error ah_hinter_load( AH_Hinter* hinter,
|
||||||
FT_UInt glyph_index,
|
FT_UInt glyph_index,
|
||||||
|
@ -955,12 +1030,16 @@
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
AH_Outline* outline = hinter->glyph;
|
AH_Outline* outline = hinter->glyph;
|
||||||
AH_Loader* gloader = hinter->loader;
|
AH_Loader* gloader = hinter->loader;
|
||||||
FT_Bool no_horz_hints = (load_flags & AH_HINT_NO_HORZ_EDGES) != 0;
|
FT_Bool no_horz_hints =
|
||||||
FT_Bool no_vert_hints = (load_flags & AH_HINT_NO_VERT_EDGES) != 0;
|
( load_flags & AH_HINT_NO_HORZ_EDGES ) != 0;
|
||||||
|
FT_Bool no_vert_hints =
|
||||||
|
( load_flags & AH_HINT_NO_VERT_EDGES ) != 0;
|
||||||
|
|
||||||
|
|
||||||
/* load the glyph */
|
/* load the glyph */
|
||||||
error = FT_Load_Glyph( face, glyph_index, load_flags );
|
error = FT_Load_Glyph( face, glyph_index, load_flags );
|
||||||
if (error) goto Exit;
|
if ( error )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
/* save current glyph metrics */
|
/* save current glyph metrics */
|
||||||
metrics = slot->metrics;
|
metrics = slot->metrics;
|
||||||
|
@ -968,12 +1047,12 @@
|
||||||
switch ( slot->format )
|
switch ( slot->format )
|
||||||
{
|
{
|
||||||
case ft_glyph_format_outline:
|
case ft_glyph_format_outline:
|
||||||
{
|
|
||||||
/* first of all, copy the outline points in the loader's current */
|
/* first of all, copy the outline points in the loader's current */
|
||||||
/* extra points, which is used to keep original glyph coordinates */
|
/* extra points, which is used to keep original glyph coordinates */
|
||||||
error = ah_loader_check_points( gloader, slot->outline.n_points + 2,
|
error = ah_loader_check_points( gloader, slot->outline.n_points + 2,
|
||||||
slot->outline.n_contours );
|
slot->outline.n_contours );
|
||||||
if (error) goto Exit;
|
if ( error )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
MEM_Copy( gloader->current.extra_points, slot->outline.points,
|
MEM_Copy( gloader->current.extra_points, slot->outline.points,
|
||||||
slot->outline.n_points * sizeof ( FT_Vector ) );
|
slot->outline.n_points * sizeof ( FT_Vector ) );
|
||||||
|
@ -998,9 +1077,10 @@
|
||||||
goto Hint_Metrics;
|
goto Hint_Metrics;
|
||||||
|
|
||||||
/* now, load the slot image into the auto-outline, and run the */
|
/* now, load the slot image into the auto-outline, and run the */
|
||||||
/* automatic hinting process.. */
|
/* automatic hinting process */
|
||||||
error = ah_outline_load( outline, face ); /* XXXX: change to slot */
|
error = ah_outline_load( outline, face ); /* XXX: change to slot */
|
||||||
if (error) goto Exit;
|
if ( error )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
/* perform feature detection */
|
/* perform feature detection */
|
||||||
ah_outline_detect_features( outline );
|
ah_outline_detect_features( outline );
|
||||||
|
@ -1024,8 +1104,10 @@
|
||||||
FT_Pos old_width, new_width;
|
FT_Pos old_width, new_width;
|
||||||
FT_Pos old_advance, new_advance;
|
FT_Pos old_advance, new_advance;
|
||||||
FT_Pos old_lsb, new_lsb;
|
FT_Pos old_lsb, new_lsb;
|
||||||
AH_Edge* edge1 = outline->vert_edges; /* left-most edge */
|
AH_Edge* edge1 = outline->vert_edges; /* leftmost edge */
|
||||||
AH_Edge* edge2 = edge1 + outline->num_vedges-1; /* right-mode edge */
|
AH_Edge* edge2 = edge1 +
|
||||||
|
outline->num_vedges - 1; /* rightmost edge */
|
||||||
|
|
||||||
|
|
||||||
old_width = edge2->opos - edge1->opos;
|
old_width = edge2->opos - edge1->opos;
|
||||||
new_width = edge2->pos - edge1->pos;
|
new_width = edge2->pos - edge1->pos;
|
||||||
|
@ -1034,15 +1116,16 @@
|
||||||
old_lsb = edge1->opos;
|
old_lsb = edge1->opos;
|
||||||
new_lsb = edge1->pos;
|
new_lsb = edge1->pos;
|
||||||
|
|
||||||
new_advance = old_advance + (new_width+new_lsb-old_width-old_lsb);
|
new_advance = old_advance +
|
||||||
|
( new_width + new_lsb - old_width - old_lsb );
|
||||||
|
|
||||||
hinter->pp1.x = ( ( new_lsb - old_lsb ) + 32 ) & -64;
|
hinter->pp1.x = ( ( new_lsb - old_lsb ) + 32 ) & -64;
|
||||||
hinter->pp2.x = ((edge2->pos + (old_advance - edge2->opos))+32) & -64;
|
hinter->pp2.x = ( ( edge2->pos +
|
||||||
|
( old_advance - edge2->opos ) ) + 32 ) & -64;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* good, we simply add the glyph to our loader's base */
|
/* good, we simply add the glyph to our loader's base */
|
||||||
ah_loader_add( gloader );
|
ah_loader_add( gloader );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ft_glyph_format_composite:
|
case ft_glyph_format_composite:
|
||||||
|
@ -1051,12 +1134,14 @@
|
||||||
FT_UInt num_base_subgs, start_point, start_contour;
|
FT_UInt num_base_subgs, start_point, start_contour;
|
||||||
FT_SubGlyph* subglyph;
|
FT_SubGlyph* subglyph;
|
||||||
|
|
||||||
|
|
||||||
start_point = gloader->base.outline.n_points;
|
start_point = gloader->base.outline.n_points;
|
||||||
start_contour = gloader->base.outline.n_contours;
|
start_contour = gloader->base.outline.n_contours;
|
||||||
|
|
||||||
/* first of all, copy the subglyph descriptors in the glyph loader */
|
/* first of all, copy the subglyph descriptors in the glyph loader */
|
||||||
error = ah_loader_check_subglyphs( gloader, num_subglyphs );
|
error = ah_loader_check_subglyphs( gloader, num_subglyphs );
|
||||||
if (error) goto Exit;
|
if ( error )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
MEM_Copy( gloader->current.subglyphs, slot->subglyphs,
|
MEM_Copy( gloader->current.subglyphs, slot->subglyphs,
|
||||||
num_subglyphs * sizeof ( FT_SubGlyph ) );
|
num_subglyphs * sizeof ( FT_SubGlyph ) );
|
||||||
|
@ -1071,9 +1156,10 @@
|
||||||
FT_Pos x, y;
|
FT_Pos x, y;
|
||||||
FT_UInt num_points, num_new_points, num_base_points;
|
FT_UInt num_points, num_new_points, num_base_points;
|
||||||
|
|
||||||
|
|
||||||
/* gloader.current.subglyphs can change during glyph loading due */
|
/* gloader.current.subglyphs can change during glyph loading due */
|
||||||
/* to re-allocation. We must recompute the current subglyph on */
|
/* to re-allocation -- we must recompute the current subglyph on */
|
||||||
/* each iteration.. */
|
/* each iteration */
|
||||||
subglyph = gloader->base.subglyphs + num_base_subgs + nn;
|
subglyph = gloader->base.subglyphs + num_base_subgs + nn;
|
||||||
|
|
||||||
pp1 = hinter->pp1;
|
pp1 = hinter->pp1;
|
||||||
|
@ -1081,8 +1167,10 @@
|
||||||
|
|
||||||
num_base_points = gloader->base.outline.n_points;
|
num_base_points = gloader->base.outline.n_points;
|
||||||
|
|
||||||
error = ah_hinter_load( hinter, subglyph->index, load_flags, depth+1 );
|
error = ah_hinter_load( hinter, subglyph->index,
|
||||||
if ( error ) goto Exit;
|
load_flags, depth + 1 );
|
||||||
|
if ( error )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
/* recompute subglyph pointer */
|
/* recompute subglyph pointer */
|
||||||
subglyph = gloader->base.subglyphs + num_base_subgs + nn;
|
subglyph = gloader->base.subglyphs + num_base_subgs + nn;
|
||||||
|
@ -1107,10 +1195,13 @@
|
||||||
FT_SUBGLYPH_FLAG_XY_SCALE |
|
FT_SUBGLYPH_FLAG_XY_SCALE |
|
||||||
FT_SUBGLYPH_FLAG_2X2 ) )
|
FT_SUBGLYPH_FLAG_2X2 ) )
|
||||||
{
|
{
|
||||||
FT_Vector* cur = gloader->base.outline.points + num_base_points;
|
FT_Vector* cur = gloader->base.outline.points +
|
||||||
FT_Vector* org = gloader->base.extra_points + num_base_points;
|
num_base_points;
|
||||||
|
FT_Vector* org = gloader->base.extra_points +
|
||||||
|
num_base_points;
|
||||||
FT_Vector* limit = cur + num_new_points;
|
FT_Vector* limit = cur + num_new_points;
|
||||||
|
|
||||||
|
|
||||||
for ( ; cur < limit; cur++, org++ )
|
for ( ; cur < limit; cur++, org++ )
|
||||||
{
|
{
|
||||||
FT_Vector_Transform( cur, &subglyph->transform );
|
FT_Vector_Transform( cur, &subglyph->transform );
|
||||||
|
@ -1127,6 +1218,7 @@
|
||||||
FT_Vector* p1;
|
FT_Vector* p1;
|
||||||
FT_Vector* p2;
|
FT_Vector* p2;
|
||||||
|
|
||||||
|
|
||||||
if ( start_point + k >= num_base_points ||
|
if ( start_point + k >= num_base_points ||
|
||||||
l >= (FT_UInt)num_new_points )
|
l >= (FT_UInt)num_new_points )
|
||||||
{
|
{
|
||||||
|
@ -1155,6 +1247,8 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
FT_Outline dummy = gloader->base.outline;
|
FT_Outline dummy = gloader->base.outline;
|
||||||
|
|
||||||
|
|
||||||
dummy.points += num_base_points;
|
dummy.points += num_base_points;
|
||||||
dummy.n_points = num_new_points;
|
dummy.n_points = num_new_points;
|
||||||
|
|
||||||
|
@ -1174,8 +1268,9 @@
|
||||||
{
|
{
|
||||||
FT_BBox bbox;
|
FT_BBox bbox;
|
||||||
|
|
||||||
|
|
||||||
/* we must translate our final outline by -pp1.x, and compute */
|
/* we must translate our final outline by -pp1.x, and compute */
|
||||||
/* the new metrics.. */
|
/* the new metrics */
|
||||||
if ( hinter->pp1.x )
|
if ( hinter->pp1.x )
|
||||||
FT_Outline_Translate( &gloader->base.outline, -hinter->pp1.x, 0 );
|
FT_Outline_Translate( &gloader->base.outline, -hinter->pp1.x, 0 );
|
||||||
|
|
||||||
|
@ -1185,17 +1280,18 @@
|
||||||
bbox.xMax = ( bbox.xMax + 63 ) & -64;
|
bbox.xMax = ( bbox.xMax + 63 ) & -64;
|
||||||
bbox.yMax = ( bbox.yMax + 63 ) & -64;
|
bbox.yMax = ( bbox.yMax + 63 ) & -64;
|
||||||
|
|
||||||
slot->metrics.width = (bbox.xMax - bbox.xMin);
|
slot->metrics.width = bbox.xMax - bbox.xMin;
|
||||||
slot->metrics.height = (bbox.yMax - bbox.yMin);
|
slot->metrics.height = bbox.yMax - bbox.yMin;
|
||||||
slot->metrics.horiBearingX = bbox.xMin;
|
slot->metrics.horiBearingX = bbox.xMin;
|
||||||
slot->metrics.horiBearingY = bbox.yMax;
|
slot->metrics.horiBearingY = bbox.yMax;
|
||||||
slot->metrics.horiAdvance = hinter->pp2.x - hinter->pp1.x;
|
slot->metrics.horiAdvance = hinter->pp2.x - hinter->pp1.x;
|
||||||
/* XXXX: TO DO - slot->linearHoriAdvance */
|
/* XXX: TO DO - slot->linearHoriAdvance */
|
||||||
|
|
||||||
/* now copy outline into glyph slot */
|
/* now copy outline into glyph slot */
|
||||||
ah_loader_rewind( slot->loader );
|
ah_loader_rewind( slot->loader );
|
||||||
error = ah_loader_copy_points( slot->loader, gloader );
|
error = ah_loader_copy_points( slot->loader, gloader );
|
||||||
if (error) goto Exit;
|
if ( error )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
slot->outline = slot->loader->base.outline;
|
slot->outline = slot->loader->base.outline;
|
||||||
slot->format = ft_glyph_format_outline;
|
slot->format = ft_glyph_format_outline;
|
||||||
|
@ -1219,6 +1315,7 @@
|
||||||
FT_Fixed y_scale = size->metrics.y_scale;
|
FT_Fixed y_scale = size->metrics.y_scale;
|
||||||
AH_Face_Globals* face_globals = FACE_GLOBALS( face );
|
AH_Face_Globals* face_globals = FACE_GLOBALS( face );
|
||||||
|
|
||||||
|
|
||||||
/* first of all, we need to check that we're using the correct face and */
|
/* first of all, we need to check that we're using the correct face and */
|
||||||
/* global hints to load the glyph */
|
/* global hints to load the glyph */
|
||||||
if ( hinter->face != face || hinter->globals != face_globals )
|
if ( hinter->face != face || hinter->globals != face_globals )
|
||||||
|
@ -1227,19 +1324,18 @@
|
||||||
if ( !face_globals )
|
if ( !face_globals )
|
||||||
{
|
{
|
||||||
error = ah_hinter_new_face_globals( hinter, face, 0 );
|
error = ah_hinter_new_face_globals( hinter, face, 0 );
|
||||||
if (error) goto Exit;
|
if ( error )
|
||||||
|
goto Exit;
|
||||||
}
|
}
|
||||||
hinter->globals = FACE_GLOBALS( face );
|
hinter->globals = FACE_GLOBALS( face );
|
||||||
face_globals = FACE_GLOBALS( face );
|
face_globals = FACE_GLOBALS( face );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now, we must check the current character pixel size to see if we need */
|
/* now, we must check the current character pixel size to see if we */
|
||||||
/* to rescale the global metrics.. */
|
/* need to rescale the global metrics */
|
||||||
if ( face_globals->x_scale != x_scale ||
|
if ( face_globals->x_scale != x_scale ||
|
||||||
face_globals->y_scale != y_scale )
|
face_globals->y_scale != y_scale )
|
||||||
{
|
|
||||||
ah_hinter_scale_globals( hinter, x_scale, y_scale );
|
ah_hinter_scale_globals( hinter, x_scale, y_scale );
|
||||||
}
|
|
||||||
|
|
||||||
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE;
|
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE;
|
||||||
|
|
||||||
|
@ -1262,6 +1358,7 @@
|
||||||
FT_Memory memory = hinter->memory;
|
FT_Memory memory = hinter->memory;
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
|
|
||||||
|
|
||||||
/* allocate new master globals */
|
/* allocate new master globals */
|
||||||
if ( ALLOC( globals, sizeof ( *globals ) ) )
|
if ( ALLOC( globals, sizeof ( *globals ) ) )
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
@ -1270,16 +1367,19 @@
|
||||||
if ( !FACE_GLOBALS( face ) )
|
if ( !FACE_GLOBALS( face ) )
|
||||||
{
|
{
|
||||||
error = ah_hinter_new_face_globals( hinter, face, 0 );
|
error = ah_hinter_new_face_globals( hinter, face, 0 );
|
||||||
if (error) goto Fail;
|
if ( error )
|
||||||
|
goto Fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
*globals = FACE_GLOBALS( face )->design;
|
*globals = FACE_GLOBALS( face )->design;
|
||||||
*global_hints = globals;
|
*global_hints = globals;
|
||||||
*global_len = sizeof( *globals );
|
*global_len = sizeof( *globals );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Fail:
|
Fail:
|
||||||
FREE( globals );
|
FREE( globals );
|
||||||
|
|
||||||
*global_hints = 0;
|
*global_hints = 0;
|
||||||
*global_len = 0;
|
*global_len = 0;
|
||||||
}
|
}
|
||||||
|
@ -1289,7 +1389,10 @@
|
||||||
void* global_hints )
|
void* global_hints )
|
||||||
{
|
{
|
||||||
FT_Memory memory = hinter->memory;
|
FT_Memory memory = hinter->memory;
|
||||||
|
|
||||||
|
|
||||||
FREE( global_hints );
|
FREE( global_hints );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* END */
|
||||||
|
|
|
@ -2,64 +2,71 @@
|
||||||
/* */
|
/* */
|
||||||
/* ahhint.h */
|
/* ahhint.h */
|
||||||
/* */
|
/* */
|
||||||
/* Glyph hinter declarations */
|
/* Glyph hinter (declaration). */
|
||||||
/* */
|
/* */
|
||||||
/* Copyright 2000: Catharon Productions Inc. */
|
/* Copyright 2000 Catharon Productions Inc. */
|
||||||
/* Author: David Turner */
|
/* Author: David Turner */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of the Catharon Typography Project and shall only */
|
/* This file is part of the Catharon Typography Project and shall only */
|
||||||
/* be used, modified, and distributed under the terms of the Catharon */
|
/* be used, modified, and distributed under the terms of the Catharon */
|
||||||
/* Open Source License that should come with this file under the name */
|
/* Open Source License that should come with this file under the name */
|
||||||
/* "CatharonLicense.txt". By continuing to use, modify, or distribute */
|
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||||
/* this file you indicate that you have read the license and */
|
/* this file you indicate that you have read the license and */
|
||||||
/* understand and accept it fully. */
|
/* understand and accept it fully. */
|
||||||
/* */
|
/* */
|
||||||
/* Note that this license is compatible with the FreeType license */
|
/* Note that this license is compatible with the FreeType license. */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
#ifndef AGHINT_H
|
|
||||||
#define AGHINT_H
|
|
||||||
|
#ifndef AHHINT_H
|
||||||
|
#define AHHINT_H
|
||||||
|
|
||||||
|
|
||||||
#ifdef FT_FLAT_COMPILE
|
#ifdef FT_FLAT_COMPILE
|
||||||
|
|
||||||
#include "ahglobal.h"
|
#include "ahglobal.h"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <autohint/ahglobal.h>
|
#include <autohint/ahglobal.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define AH_HINT_DEFAULT 0
|
#define AH_HINT_DEFAULT 0
|
||||||
#define AH_HINT_NO_ALIGNMENT 1
|
#define AH_HINT_NO_ALIGNMENT 1
|
||||||
#define AH_HINT_NO_HORZ_EDGES 0x20000
|
#define AH_HINT_NO_HORZ_EDGES 0x20000L
|
||||||
#define AH_HINT_NO_VERT_EDGES 0x40000
|
#define AH_HINT_NO_VERT_EDGES 0x40000L
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* create a new empty hinter object */
|
/* create a new empty hinter object */
|
||||||
extern
|
FT_Error ah_hinter_new( FT_Library library,
|
||||||
FT_Error ah_hinter_new( FT_Library library, AH_Hinter* *ahinter );
|
AH_Hinter** ahinter );
|
||||||
|
|
||||||
/* Load a hinted glyph in the hinter */
|
/* Load a hinted glyph in the hinter */
|
||||||
extern
|
|
||||||
FT_Error ah_hinter_load_glyph( AH_Hinter* hinter,
|
FT_Error ah_hinter_load_glyph( AH_Hinter* hinter,
|
||||||
FT_GlyphSlot slot,
|
FT_GlyphSlot slot,
|
||||||
FT_Size size,
|
FT_Size size,
|
||||||
FT_UInt glyph_index,
|
FT_UInt glyph_index,
|
||||||
FT_Int load_flags );
|
FT_Int load_flags );
|
||||||
|
|
||||||
/* finalise a hinter object */
|
/* finalize a hinter object */
|
||||||
extern
|
|
||||||
void ah_hinter_done( AH_Hinter* hinter );
|
void ah_hinter_done( AH_Hinter* hinter );
|
||||||
|
|
||||||
LOCAL_DEF
|
LOCAL_DEF
|
||||||
void ah_hinter_done_face_globals( AH_Face_Globals* globals );
|
void ah_hinter_done_face_globals( AH_Face_Globals* globals );
|
||||||
|
|
||||||
extern
|
|
||||||
void ah_hinter_get_global_hints( AH_Hinter* hinter,
|
void ah_hinter_get_global_hints( AH_Hinter* hinter,
|
||||||
FT_Face face,
|
FT_Face face,
|
||||||
void** global_hints,
|
void** global_hints,
|
||||||
long* global_len );
|
long* global_len );
|
||||||
|
|
||||||
extern
|
|
||||||
void ah_hinter_done_global_hints( AH_Hinter* hinter,
|
void ah_hinter_done_global_hints( AH_Hinter* hinter,
|
||||||
void* global_hints );
|
void* global_hints );
|
||||||
|
|
||||||
#endif /* AGHINT_H */
|
|
||||||
|
#endif /* AHHINT_H */
|
||||||
|
|
||||||
|
|
||||||
|
/* END */
|
||||||
|
|
|
@ -2,30 +2,39 @@
|
||||||
/* */
|
/* */
|
||||||
/* ahloader.h */
|
/* ahloader.h */
|
||||||
/* */
|
/* */
|
||||||
/* Glyph loader implementation for the auto-hinting module */
|
/* Glyph loader for the auto-hinting module (declaration only). */
|
||||||
/* This defines the AG_GlyphLoader type in two different ways: */
|
|
||||||
/* */
|
/* */
|
||||||
/* - when the module is compiled within FreeType 2, the type */
|
/* Copyright 2000 Catharon Productions Inc. */
|
||||||
/* is simply a typedef to FT_GlyphLoader */
|
|
||||||
/* */
|
|
||||||
/* - when the module is compiled as a standalone object, */
|
|
||||||
/* AG_GlyphLoader has its own implementation.. */
|
|
||||||
/* */
|
|
||||||
/* Copyright 2000: Catharon Productions Inc. */
|
|
||||||
/* Author: David Turner */
|
/* Author: David Turner */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of the Catharon Typography Project and shall only */
|
/* This file is part of the Catharon Typography Project and shall only */
|
||||||
/* be used, modified, and distributed under the terms of the Catharon */
|
/* be used, modified, and distributed under the terms of the Catharon */
|
||||||
/* Open Source License that should come with this file under the name */
|
/* Open Source License that should come with this file under the name */
|
||||||
/* "CatharonLicense.txt". By continuing to use, modify, or distribute */
|
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||||
/* this file you indicate that you have read the license and */
|
/* this file you indicate that you have read the license and */
|
||||||
/* understand and accept it fully. */
|
/* understand and accept it fully. */
|
||||||
/* */
|
/* */
|
||||||
/* Note that this license is compatible with the FreeType license */
|
/* Note that this license is compatible with the FreeType license. */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
#ifndef AGLOADER_H
|
|
||||||
#define AGLOADER_H
|
|
||||||
|
/*************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* This defines the AH_GlyphLoader type in two different ways: */
|
||||||
|
/* */
|
||||||
|
/* - If the module is compiled within FreeType 2, the type is simply a */
|
||||||
|
/* typedef to FT_GlyphLoader. */
|
||||||
|
/* */
|
||||||
|
/* - If the module is compiled as a standalone object, AH_GlyphLoader */
|
||||||
|
/* has its own implementation. */
|
||||||
|
/* */
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef AHLOADER_H
|
||||||
|
#define AHLOADER_H
|
||||||
|
|
||||||
|
|
||||||
#ifdef _STANDALONE_
|
#ifdef _STANDALONE_
|
||||||
|
|
||||||
|
@ -34,7 +43,7 @@
|
||||||
FT_Outline outline; /* outline */
|
FT_Outline outline; /* outline */
|
||||||
FT_UInt num_subglyphs; /* number of subglyphs */
|
FT_UInt num_subglyphs; /* number of subglyphs */
|
||||||
FT_SubGlyph* subglyphs; /* subglyphs */
|
FT_SubGlyph* subglyphs; /* subglyphs */
|
||||||
FT_Vector* extra_points; /* extra points table.. */
|
FT_Vector* extra_points; /* extra points table */
|
||||||
|
|
||||||
} AH_GlyphLoad;
|
} AH_GlyphLoad;
|
||||||
|
|
||||||
|
@ -50,38 +59,47 @@
|
||||||
AH_GlyphLoad base;
|
AH_GlyphLoad base;
|
||||||
AH_GlyphLoad current;
|
AH_GlyphLoad current;
|
||||||
|
|
||||||
void* other; /* for possible future extension ? */
|
void* other; /* for possible future extensions */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
LOCAL_DEF FT_Error AH_GlyphLoader_New( FT_Memory memory,
|
LOCAL_DEF
|
||||||
|
FT_Error AH_GlyphLoader_New( FT_Memory memory,
|
||||||
AH_GlyphLoader** aloader );
|
AH_GlyphLoader** aloader );
|
||||||
|
|
||||||
LOCAL_DEF FT_Error AH_GlyphLoader_Create_Extra( AH_GlyphLoader* loader );
|
LOCAL_DEF
|
||||||
|
FT_Error AH_GlyphLoader_Create_Extra( AH_GlyphLoader* loader );
|
||||||
|
|
||||||
LOCAL_DEF void AH_GlyphLoader_Done( AH_GlyphLoader* loader );
|
LOCAL_DEF
|
||||||
|
void AH_GlyphLoader_Done( AH_GlyphLoader* loader );
|
||||||
|
|
||||||
LOCAL_DEF void AH_GlyphLoader_Reset( AH_GlyphLoader* loader );
|
LOCAL_DEF
|
||||||
|
void AH_GlyphLoader_Reset( AH_GlyphLoader* loader );
|
||||||
|
|
||||||
LOCAL_DEF void AH_GlyphLoader_Rewind( AH_GlyphLoader* loader );
|
LOCAL_DEF
|
||||||
|
void AH_GlyphLoader_Rewind( AH_GlyphLoader* loader );
|
||||||
|
|
||||||
LOCAL_DEF FT_Error AH_GlyphLoader_Check_Points( AH_GlyphLoader* loader,
|
LOCAL_DEF
|
||||||
|
FT_Error AH_GlyphLoader_Check_Points( AH_GlyphLoader* loader,
|
||||||
FT_UInt n_points,
|
FT_UInt n_points,
|
||||||
FT_UInt n_contours );
|
FT_UInt n_contours );
|
||||||
|
|
||||||
LOCAL_DEF FT_Error AH_GlyphLoader_Check_Subglyphs( AH_GlyphLoader* loader,
|
LOCAL_DEF
|
||||||
|
FT_Error AH_GlyphLoader_Check_Subglyphs( AH_GlyphLoader* loader,
|
||||||
FT_UInt n_subs );
|
FT_UInt n_subs );
|
||||||
|
|
||||||
LOCAL_DEF void AH_GlyphLoader_Prepare( AH_GlyphLoader* loader );
|
LOCAL_DEF
|
||||||
|
void AH_GlyphLoader_Prepare( AH_GlyphLoader* loader );
|
||||||
|
|
||||||
|
LOCAL_DEF
|
||||||
|
void AH_GlyphLoader_Add( AH_GlyphLoader* loader );
|
||||||
|
|
||||||
LOCAL_DEF void AH_GlyphLoader_Add( AH_GlyphLoader* loader );
|
LOCAL_DEF
|
||||||
|
FT_Error AH_GlyphLoader_Copy_Points( AH_GlyphLoader* target,
|
||||||
LOCAL_DEF FT_Error AH_GlyphLoader_Copy_Points( AH_GlyphLoader* target,
|
|
||||||
FT_GlyphLoader* source );
|
FT_GlyphLoader* source );
|
||||||
|
|
||||||
#else
|
#else /* _STANDALONE */
|
||||||
|
|
||||||
#include <freetype/internal/ftobjs.h>
|
#include <freetype/internal/ftobjs.h>
|
||||||
|
|
||||||
#define AH_Load FT_GlyphLoad
|
#define AH_Load FT_GlyphLoad
|
||||||
|
@ -98,6 +116,9 @@
|
||||||
#define ah_loader_add FT_GlyphLoader_Add
|
#define ah_loader_add FT_GlyphLoader_Add
|
||||||
#define ah_loader_copy_points FT_GlyphLoader_Copy_Points
|
#define ah_loader_copy_points FT_GlyphLoader_Copy_Points
|
||||||
|
|
||||||
#endif
|
#endif /* _STANDALONE_ */
|
||||||
|
|
||||||
#endif /* AGLOADER_H */
|
#endif /* AHLOADER_H */
|
||||||
|
|
||||||
|
|
||||||
|
/* END */
|
||||||
|
|
|
@ -2,27 +2,34 @@
|
||||||
/* */
|
/* */
|
||||||
/* ahmodule.c */
|
/* ahmodule.c */
|
||||||
/* */
|
/* */
|
||||||
/* Auto-hinting module implementation */
|
/* Auto-hinting module implementation (declaration). */
|
||||||
/* */
|
/* */
|
||||||
/* Copyright 2000: Catharon Productions Inc. */
|
/* Copyright 2000 Catharon Productions Inc. */
|
||||||
/* Author: David Turner */
|
/* Author: David Turner */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of the Catharon Typography Project and shall only */
|
/* This file is part of the Catharon Typography Project and shall only */
|
||||||
/* be used, modified, and distributed under the terms of the Catharon */
|
/* be used, modified, and distributed under the terms of the Catharon */
|
||||||
/* Open Source License that should come with this file under the name */
|
/* Open Source License that should come with this file under the name */
|
||||||
/* "CatharonLicense.txt". By continuing to use, modify, or distribute */
|
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||||
/* this file you indicate that you have read the license and */
|
/* this file you indicate that you have read the license and */
|
||||||
/* understand and accept it fully. */
|
/* understand and accept it fully. */
|
||||||
/* */
|
/* */
|
||||||
/* Note that this license is compatible with the FreeType license */
|
/* Note that this license is compatible with the FreeType license. */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include <freetype/ftmodule.h>
|
#include <freetype/ftmodule.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef FT_FLAT_COMPILE
|
#ifdef FT_FLAT_COMPILE
|
||||||
|
|
||||||
#include "ahhint.h"
|
#include "ahhint.h"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <autohint/ahhint.h>
|
#include <autohint/ahhint.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,12 +47,14 @@
|
||||||
return ah_hinter_new( module->root.library, &module->hinter );
|
return ah_hinter_new( module->root.library, &module->hinter );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void ft_autohinter_done( FT_AutoHinter module )
|
void ft_autohinter_done( FT_AutoHinter module )
|
||||||
{
|
{
|
||||||
ah_hinter_done( module->hinter );
|
ah_hinter_done( module->hinter );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
FT_Error ft_autohinter_load( FT_AutoHinter module,
|
FT_Error ft_autohinter_load( FT_AutoHinter module,
|
||||||
FT_GlyphSlot slot,
|
FT_GlyphSlot slot,
|
||||||
|
@ -57,15 +66,18 @@
|
||||||
slot, size, glyph_index, load_flags );
|
slot, size, glyph_index, load_flags );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void ft_autohinter_reset( FT_AutoHinter module,
|
void ft_autohinter_reset( FT_AutoHinter module,
|
||||||
FT_Face face )
|
FT_Face face )
|
||||||
{
|
{
|
||||||
UNUSED( module );
|
UNUSED( module );
|
||||||
|
|
||||||
if ( face->autohint.data )
|
if ( face->autohint.data )
|
||||||
ah_hinter_done_face_globals( face->autohint.data );
|
ah_hinter_done_face_globals( (AH_Face_Globals*)(face->autohint.data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void ft_autohinter_get_globals( FT_AutoHinter module,
|
void ft_autohinter_get_globals( FT_AutoHinter module,
|
||||||
FT_Face face,
|
FT_Face face,
|
||||||
|
@ -94,14 +106,15 @@
|
||||||
ft_autohinter_done_globals
|
ft_autohinter_done_globals
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const FT_Module_Class autohint_module_class =
|
const FT_Module_Class autohint_module_class =
|
||||||
{
|
{
|
||||||
ft_module_hinter,
|
ft_module_hinter,
|
||||||
sizeof ( FT_AutoHinterRec ),
|
sizeof ( FT_AutoHinterRec ),
|
||||||
|
|
||||||
"autohinter",
|
"autohinter",
|
||||||
0x10000, /* version 1.0 of the autohinter */
|
0x10000L, /* version 1.0 of the autohinter */
|
||||||
0x20000, /* requires FreeType 2.0 or above */
|
0x20000L, /* requires FreeType 2.0 or above */
|
||||||
|
|
||||||
(const void*)&autohinter_interface,
|
(const void*)&autohinter_interface,
|
||||||
|
|
||||||
|
@ -109,3 +122,6 @@
|
||||||
(FT_Module_Destructor) ft_autohinter_done,
|
(FT_Module_Destructor) ft_autohinter_done,
|
||||||
(FT_Module_Requester) 0
|
(FT_Module_Requester) 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* END */
|
||||||
|
|
|
@ -2,21 +2,23 @@
|
||||||
/* */
|
/* */
|
||||||
/* ahmodule.h */
|
/* ahmodule.h */
|
||||||
/* */
|
/* */
|
||||||
/* Auto-hinting module declaration */
|
/* Auto-hinting module (declaration). */
|
||||||
/* */
|
/* */
|
||||||
/* Copyright 2000: Catharon Productions Inc. */
|
/* Copyright 2000 Catharon Productions Inc. */
|
||||||
/* Author: David Turner */
|
/* Author: David Turner */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of the Catharon Typography Project and shall only */
|
/* This file is part of the Catharon Typography Project and shall only */
|
||||||
/* be used, modified, and distributed under the terms of the Catharon */
|
/* be used, modified, and distributed under the terms of the Catharon */
|
||||||
/* Open Source License that should come with this file under the name */
|
/* Open Source License that should come with this file under the name */
|
||||||
/* "CatharonLicense.txt". By continuing to use, modify, or distribute */
|
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||||
/* this file you indicate that you have read the license and */
|
/* this file you indicate that you have read the license and */
|
||||||
/* understand and accept it fully. */
|
/* understand and accept it fully. */
|
||||||
/* */
|
/* */
|
||||||
/* Note that this license is compatible with the FreeType license */
|
/* Note that this license is compatible with the FreeType license. */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef AHMODULE_H
|
#ifndef AHMODULE_H
|
||||||
#define AHMODULE_H
|
#define AHMODULE_H
|
||||||
|
|
||||||
|
@ -25,3 +27,6 @@
|
||||||
FT_EXPORT_VAR( const FT_Module_Class ) autohint_module_class;
|
FT_EXPORT_VAR( const FT_Module_Class ) autohint_module_class;
|
||||||
|
|
||||||
#endif /* AHMODULE_H */
|
#endif /* AHMODULE_H */
|
||||||
|
|
||||||
|
|
||||||
|
/* END */
|
||||||
|
|
|
@ -1,51 +1,73 @@
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* FreeType Auto-Gridder Outline Optimisation */
|
/* ahoptim.c */
|
||||||
/* */
|
/* */
|
||||||
/* This module is in charge of optimising the outlines produced by the */
|
/* FreeType auto hinting outline optimization (body). */
|
||||||
/* auto-hinter in direct mode. This is required at small pixel sizes in */
|
|
||||||
/* order to ensure coherent spacing, among other things.. */
|
|
||||||
/* */
|
/* */
|
||||||
/* The technique used in this module is a simplified simulated annealing. */
|
/* Copyright 2000 Catharon Productions Inc. */
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* Copyright 2000: Catharon Productions Inc. */
|
|
||||||
/* Author: David Turner */
|
/* Author: David Turner */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of the Catharon Typography Project and shall only */
|
/* This file is part of the Catharon Typography Project and shall only */
|
||||||
/* be used, modified, and distributed under the terms of the Catharon */
|
/* be used, modified, and distributed under the terms of the Catharon */
|
||||||
/* Open Source License that should come with this file under the name */
|
/* Open Source License that should come with this file under the name */
|
||||||
/* "CatharonLicense.txt". By continuing to use, modify, or distribute */
|
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||||
/* this file you indicate that you have read the license and */
|
/* this file you indicate that you have read the license and */
|
||||||
/* understand and accept it fully. */
|
/* understand and accept it fully. */
|
||||||
/* */
|
/* */
|
||||||
/* Note that this license is compatible with the FreeType license */
|
/* Note that this license is compatible with the FreeType license. */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
#include <freetype/internal/ftobjs.h> /* for ALLOC_ARRAY and FREE */
|
|
||||||
|
/*************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* This module is in charge of optimising the outlines produced by the */
|
||||||
|
/* auto-hinter in direct mode. This is required at small pixel sizes in */
|
||||||
|
/* order to ensure coherent spacing, among other things.. */
|
||||||
|
/* */
|
||||||
|
/* The technique used in this module is a simplified simulated */
|
||||||
|
/* annealing. */
|
||||||
|
/* */
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <freetype/internal/ftobjs.h> /* for ALLOC_ARRAY() and FREE() */
|
||||||
|
|
||||||
|
|
||||||
#ifdef FT_FLAT_COMPILE
|
#ifdef FT_FLAT_COMPILE
|
||||||
|
|
||||||
#include "ahoptim.h"
|
#include "ahoptim.h"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <autohint/ahoptim.h>
|
#include <autohint/ahoptim.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* define this macro to use brute force optimisation, this is slow, but */
|
|
||||||
/* a good way to perfect the distortion function "by hand" through */
|
|
||||||
/* tweaking.. */
|
|
||||||
#define BRUTE_FORCE
|
|
||||||
|
|
||||||
#define xxxDEBUG_OPTIM
|
/* define this macro to use brute force optimisation -- this is slow, */
|
||||||
|
/* but a good way to perfect the distortion function `by hand' through */
|
||||||
|
/* tweaking */
|
||||||
|
#define AH_BRUTE_FORCE
|
||||||
|
|
||||||
|
|
||||||
|
#define xxxAH_DEBUG_OPTIM
|
||||||
|
|
||||||
|
|
||||||
#undef LOG
|
#undef LOG
|
||||||
#ifdef DEBUG_OPTIM
|
#ifdef AH_DEBUG_OPTIM
|
||||||
#define LOG(x) optim_log##x
|
|
||||||
#else
|
#define LOG( x ) optim_log##x
|
||||||
#define LOG(x)
|
|
||||||
#endif
|
#else
|
||||||
|
|
||||||
|
#define LOG( x )
|
||||||
|
|
||||||
|
#endif /* AH_DEBUG_OPTIM */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef AH_DEBUG_OPTIM
|
||||||
|
|
||||||
#ifdef DEBUG_OPTIM
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -62,20 +84,20 @@ void optim_log( const char* fmt, ... )
|
||||||
vprintf( fmt, ap );
|
vprintf( fmt, ap );
|
||||||
va_end( ap );
|
va_end( ap );
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_OPTIM
|
|
||||||
static
|
static
|
||||||
void AH_Dump_Stems( AH_Optimizer* optimizer )
|
void AH_Dump_Stems( AH_Optimizer* optimizer )
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
AH_Stem* stem;
|
AH_Stem* stem;
|
||||||
|
|
||||||
|
|
||||||
stem = optimizer->stems;
|
stem = optimizer->stems;
|
||||||
for ( n = 0; n < optimizer->num_stems; n++, stem++ )
|
for ( n = 0; n < optimizer->num_stems; n++, stem++ )
|
||||||
{
|
{
|
||||||
LOG(( " %c%2d [%.1f:%.1f]={%.1f:%.1f}=<%1.f..%1.f> force=%.1f speed=%.1f\n",
|
LOG(( " %c%2d [%.1f:%.1f]={%.1f:%.1f}="
|
||||||
|
"<%1.f..%1.f> force=%.1f speed=%.1f\n",
|
||||||
optimizer->vertical ? 'V' : 'H', n,
|
optimizer->vertical ? 'V' : 'H', n,
|
||||||
FLOAT( stem->edge1->opos ), FLOAT( stem->edge2->opos ),
|
FLOAT( stem->edge1->opos ), FLOAT( stem->edge2->opos ),
|
||||||
FLOAT( stem->edge1->pos ), FLOAT( stem->edge2->pos ),
|
FLOAT( stem->edge1->pos ), FLOAT( stem->edge2->pos ),
|
||||||
|
@ -84,12 +106,14 @@ void optim_log( const char* fmt, ... )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void AH_Dump_Stems2( AH_Optimizer* optimizer )
|
void AH_Dump_Stems2( AH_Optimizer* optimizer )
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
AH_Stem* stem;
|
AH_Stem* stem;
|
||||||
|
|
||||||
|
|
||||||
stem = optimizer->stems;
|
stem = optimizer->stems;
|
||||||
for ( n = 0; n < optimizer->num_stems; n++, stem++ )
|
for ( n = 0; n < optimizer->num_stems; n++, stem++ )
|
||||||
{
|
{
|
||||||
|
@ -101,6 +125,7 @@ void optim_log( const char* fmt, ... )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void AH_Dump_Springs( AH_Optimizer* optimizer )
|
void AH_Dump_Springs( AH_Optimizer* optimizer )
|
||||||
{
|
{
|
||||||
|
@ -108,20 +133,25 @@ void optim_log( const char* fmt, ... )
|
||||||
AH_Spring* spring;
|
AH_Spring* spring;
|
||||||
AH_Stem* stems;
|
AH_Stem* stems;
|
||||||
|
|
||||||
|
|
||||||
spring = optimizer->springs;
|
spring = optimizer->springs;
|
||||||
stems = optimizer->stems;
|
stems = optimizer->stems;
|
||||||
LOG(( "%cSprings ", optimizer->vertical ? 'V' : 'H' ));
|
LOG(( "%cSprings ", optimizer->vertical ? 'V' : 'H' ));
|
||||||
|
|
||||||
for ( n = 0; n < optimizer->num_springs; n++, spring++ )
|
for ( n = 0; n < optimizer->num_springs; n++, spring++ )
|
||||||
{
|
{
|
||||||
LOG(( " [%d-%d:%.1f:%1.f:%.1f]", spring->stem1 - stems, spring->stem2 - stems,
|
LOG(( " [%d-%d:%.1f:%1.f:%.1f]",
|
||||||
|
spring->stem1 - stems, spring->stem2 - stems,
|
||||||
FLOAT( spring->owidth ),
|
FLOAT( spring->owidth ),
|
||||||
FLOAT(spring->stem2->pos-(spring->stem1->pos+spring->stem1->width)),
|
FLOAT( spring->stem2->pos -
|
||||||
|
( spring->stem1->pos + spring->stem1->width ) ),
|
||||||
FLOAT( spring->tension ) ));
|
FLOAT( spring->tension ) ));
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(( "\n" ));
|
LOG(( "\n" ));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
#endif /* AH_DEBUG_OPTIM */
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
@ -130,20 +160,24 @@ void optim_log( const char* fmt, ... )
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/**** COMPUTE STEMS AND SPRINGS IN AN OUTLINE ****/
|
/**** COMPUTE STEMS AND SPRINGS IN AN OUTLINE ****/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/**** ****/
|
|
||||||
/**** ****/
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int valid_stem_segments( AH_Segment* seg1, AH_Segment* seg2 )
|
int valid_stem_segments( AH_Segment* seg1,
|
||||||
|
AH_Segment* seg2 )
|
||||||
{
|
{
|
||||||
return seg1->serif == 0 && seg2 && seg2->link == seg1 && seg1->pos < seg2->pos &&
|
return seg1->serif == 0 &&
|
||||||
|
seg2 &&
|
||||||
|
seg2->link == seg1 &&
|
||||||
|
seg1->pos < seg2->pos &&
|
||||||
seg1->min_coord <= seg2->max_coord &&
|
seg1->min_coord <= seg2->max_coord &&
|
||||||
seg2->min_coord <= seg1->max_coord;
|
seg2->min_coord <= seg1->max_coord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* compute all stems in an outline */
|
/* compute all stems in an outline */
|
||||||
static
|
static
|
||||||
int optim_compute_stems( AH_Optimizer* optimizer )
|
int optim_compute_stems( AH_Optimizer* optimizer )
|
||||||
|
@ -158,6 +192,7 @@ void optim_log( const char* fmt, ... )
|
||||||
AH_Stem** p_stems;
|
AH_Stem** p_stems;
|
||||||
FT_Int* p_num_stems;
|
FT_Int* p_num_stems;
|
||||||
|
|
||||||
|
|
||||||
edges = outline->horz_edges;
|
edges = outline->horz_edges;
|
||||||
edge_limit = edges + outline->num_hedges;
|
edge_limit = edges + outline->num_hedges;
|
||||||
scale = outline->y_scale;
|
scale = outline->y_scale;
|
||||||
|
@ -171,10 +206,13 @@ void optim_log( const char* fmt, ... )
|
||||||
FT_Int num_stems = 0;
|
FT_Int num_stems = 0;
|
||||||
AH_Edge* edge;
|
AH_Edge* edge;
|
||||||
|
|
||||||
|
|
||||||
/* first of all, count the number of stems in this direction */
|
/* first of all, count the number of stems in this direction */
|
||||||
for ( edge = edges; edge < edge_limit; edge++ )
|
for ( edge = edges; edge < edge_limit; edge++ )
|
||||||
{
|
{
|
||||||
AH_Segment* seg = edge->first;
|
AH_Segment* seg = edge->first;
|
||||||
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (valid_stem_segments( seg, seg->link ) )
|
if (valid_stem_segments( seg, seg->link ) )
|
||||||
|
@ -190,6 +228,7 @@ void optim_log( const char* fmt, ... )
|
||||||
{
|
{
|
||||||
AH_Stem* stem;
|
AH_Stem* stem;
|
||||||
|
|
||||||
|
|
||||||
if ( ALLOC_ARRAY( stems, num_stems, AH_Stem ) )
|
if ( ALLOC_ARRAY( stems, num_stems, AH_Stem ) )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
|
@ -198,6 +237,8 @@ void optim_log( const char* fmt, ... )
|
||||||
{
|
{
|
||||||
AH_Segment* seg = edge->first;
|
AH_Segment* seg = edge->first;
|
||||||
AH_Segment* seg2;
|
AH_Segment* seg2;
|
||||||
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
seg2 = seg->link;
|
seg2 = seg->link;
|
||||||
|
@ -206,6 +247,7 @@ void optim_log( const char* fmt, ... )
|
||||||
AH_Edge* edge1 = seg->edge;
|
AH_Edge* edge1 = seg->edge;
|
||||||
AH_Edge* edge2 = seg2->edge;
|
AH_Edge* edge2 = seg2->edge;
|
||||||
|
|
||||||
|
|
||||||
stem->edge1 = edge1;
|
stem->edge1 = edge1;
|
||||||
stem->edge2 = edge2;
|
stem->edge2 = edge2;
|
||||||
stem->opos = edge1->opos;
|
stem->opos = edge1->opos;
|
||||||
|
@ -218,6 +260,7 @@ void optim_log( const char* fmt, ... )
|
||||||
FT_Pos min_coord = seg->min_coord;
|
FT_Pos min_coord = seg->min_coord;
|
||||||
FT_Pos max_coord = seg->max_coord;
|
FT_Pos max_coord = seg->max_coord;
|
||||||
|
|
||||||
|
|
||||||
if ( seg2->min_coord > min_coord )
|
if ( seg2->min_coord > min_coord )
|
||||||
min_coord = seg2->min_coord;
|
min_coord = seg2->min_coord;
|
||||||
|
|
||||||
|
@ -228,22 +271,23 @@ void optim_log( const char* fmt, ... )
|
||||||
stem->max_coord = max_coord;
|
stem->max_coord = max_coord;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compute minimum and maximum positions for stem */
|
/* compute minimum and maximum positions for stem -- */
|
||||||
/* note that the left-most/bottom-most stem has always */
|
/* note that the left-most/bottom-most stem has always */
|
||||||
/* a fixed position.. */
|
/* a fixed position */
|
||||||
if ( stem == stems || edge1->blue_edge || edge2->blue_edge )
|
if ( stem == stems || edge1->blue_edge || edge2->blue_edge )
|
||||||
{
|
{
|
||||||
/* this stem cannot move, it is snapped to a blue edge */
|
/* this stem cannot move; it is snapped to a blue edge */
|
||||||
stem->min_pos = stem->pos;
|
stem->min_pos = stem->pos;
|
||||||
stem->max_pos = stem->pos;
|
stem->max_pos = stem->pos;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* this edge can move, compute its min and max positions */
|
/* this edge can move; compute its min and max positions */
|
||||||
FT_Pos pos1 = stem->opos;
|
FT_Pos pos1 = stem->opos;
|
||||||
FT_Pos pos2 = pos1 + stem->owidth - stem->width;
|
FT_Pos pos2 = pos1 + stem->owidth - stem->width;
|
||||||
FT_Pos min1 = (pos1 & -64);
|
FT_Pos min1 = pos1 & -64;
|
||||||
FT_Pos min2 = (pos2 & -64);
|
FT_Pos min2 = pos2 & -64;
|
||||||
|
|
||||||
|
|
||||||
stem->min_pos = min1;
|
stem->min_pos = min1;
|
||||||
stem->max_pos = min1 + 64;
|
stem->max_pos = min1 + 64;
|
||||||
|
@ -255,8 +299,8 @@ void optim_log( const char* fmt, ... )
|
||||||
/* XXX: just to see what it does */
|
/* XXX: just to see what it does */
|
||||||
stem->max_pos += 64;
|
stem->max_pos += 64;
|
||||||
|
|
||||||
/* just for the case where direct hinting did some incredible */
|
/* just for the case where direct hinting did some */
|
||||||
/* things (e.g. blue edge shifts..) */
|
/* incredible things (e.g. blue edge shifts) */
|
||||||
if ( stem->min_pos > stem->pos )
|
if ( stem->min_pos > stem->pos )
|
||||||
stem->min_pos = stem->pos;
|
stem->min_pos = stem->pos;
|
||||||
|
|
||||||
|
@ -270,8 +314,8 @@ void optim_log( const char* fmt, ... )
|
||||||
stem++;
|
stem++;
|
||||||
}
|
}
|
||||||
seg = seg->edge_next;
|
seg = seg->edge_next;
|
||||||
}
|
|
||||||
while (seg != edge->first);
|
} while ( seg != edge->first );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,17 +329,21 @@ void optim_log( const char* fmt, ... )
|
||||||
p_stems = &optimizer->vert_stems;
|
p_stems = &optimizer->vert_stems;
|
||||||
p_num_stems = &optimizer->num_vstems;
|
p_num_stems = &optimizer->num_vstems;
|
||||||
}
|
}
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
#ifdef DEBUG_OPTIM
|
|
||||||
|
#ifdef AH_DEBUG_OPTIM
|
||||||
AH_Dump_Stems( optimizer );
|
AH_Dump_Stems( optimizer );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* returns the spring area between two stems, 0 if none */
|
/* returns the spring area between two stems, 0 if none */
|
||||||
static
|
static
|
||||||
FT_Pos stem_spring_area( AH_Stem* stem1, AH_Stem* stem2 )
|
FT_Pos stem_spring_area( AH_Stem* stem1,
|
||||||
|
AH_Stem* stem2 )
|
||||||
{
|
{
|
||||||
FT_Pos area1 = stem1->max_coord - stem1->min_coord;
|
FT_Pos area1 = stem1->max_coord - stem1->min_coord;
|
||||||
FT_Pos area2 = stem2->max_coord - stem2->min_coord;
|
FT_Pos area2 = stem2->max_coord - stem2->min_coord;
|
||||||
|
@ -303,6 +351,7 @@ void optim_log( const char* fmt, ... )
|
||||||
FT_Pos max = stem1->max_coord;
|
FT_Pos max = stem1->max_coord;
|
||||||
FT_Pos area;
|
FT_Pos area;
|
||||||
|
|
||||||
|
|
||||||
/* order stems */
|
/* order stems */
|
||||||
if ( stem2->opos <= stem1->opos + stem1->owidth )
|
if ( stem2->opos <= stem1->opos + stem1->owidth )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -326,7 +375,7 @@ void optim_log( const char* fmt, ... )
|
||||||
int optim_compute_springs( AH_Optimizer* optimizer )
|
int optim_compute_springs( AH_Optimizer* optimizer )
|
||||||
{
|
{
|
||||||
/* basically, a spring exists between two stems if most of their */
|
/* basically, a spring exists between two stems if most of their */
|
||||||
/* surface is aligned.. */
|
/* surface is aligned */
|
||||||
FT_Memory memory = optimizer->memory;
|
FT_Memory memory = optimizer->memory;
|
||||||
|
|
||||||
AH_Stem* stems;
|
AH_Stem* stems;
|
||||||
|
@ -338,6 +387,7 @@ void optim_log( const char* fmt, ... )
|
||||||
FT_Int* p_num_springs;
|
FT_Int* p_num_springs;
|
||||||
AH_Spring** p_springs;
|
AH_Spring** p_springs;
|
||||||
|
|
||||||
|
|
||||||
stems = optimizer->horz_stems;
|
stems = optimizer->horz_stems;
|
||||||
stem_limit = stems + optimizer->num_hstems;
|
stem_limit = stems + optimizer->num_hstems;
|
||||||
|
|
||||||
|
@ -349,10 +399,13 @@ void optim_log( const char* fmt, ... )
|
||||||
FT_Int num_springs = 0;
|
FT_Int num_springs = 0;
|
||||||
AH_Spring* springs = 0;
|
AH_Spring* springs = 0;
|
||||||
|
|
||||||
|
|
||||||
/* first of all, count stem springs */
|
/* first of all, count stem springs */
|
||||||
for ( stem = stems; stem + 1 < stem_limit; stem++ )
|
for ( stem = stems; stem + 1 < stem_limit; stem++ )
|
||||||
{
|
{
|
||||||
AH_Stem* stem2;
|
AH_Stem* stem2;
|
||||||
|
|
||||||
|
|
||||||
for ( stem2 = stem+1; stem2 < stem_limit; stem2++ )
|
for ( stem2 = stem+1; stem2 < stem_limit; stem2++ )
|
||||||
if ( stem_spring_area( stem, stem2 ) )
|
if ( stem_spring_area( stem, stem2 ) )
|
||||||
num_springs++;
|
num_springs++;
|
||||||
|
@ -363,6 +416,7 @@ void optim_log( const char* fmt, ... )
|
||||||
{
|
{
|
||||||
AH_Spring* spring;
|
AH_Spring* spring;
|
||||||
|
|
||||||
|
|
||||||
/* allocate table of springs */
|
/* allocate table of springs */
|
||||||
if ( ALLOC_ARRAY( springs, num_springs, AH_Spring ) )
|
if ( ALLOC_ARRAY( springs, num_springs, AH_Spring ) )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
@ -374,6 +428,7 @@ void optim_log( const char* fmt, ... )
|
||||||
AH_Stem* stem2;
|
AH_Stem* stem2;
|
||||||
FT_Pos area;
|
FT_Pos area;
|
||||||
|
|
||||||
|
|
||||||
for ( stem2 = stem + 1; stem2 < stem_limit; stem2++ )
|
for ( stem2 = stem + 1; stem2 < stem_limit; stem2++ )
|
||||||
{
|
{
|
||||||
area = stem_spring_area( stem, stem2 );
|
area = stem_spring_area( stem, stem2 );
|
||||||
|
@ -401,31 +456,35 @@ void optim_log( const char* fmt, ... )
|
||||||
}
|
}
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
#ifdef DEBUG_OPTIM
|
|
||||||
|
#ifdef AH_DEBUG_OPTIM
|
||||||
AH_Dump_Springs( optimizer );
|
AH_Dump_Springs( optimizer );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/**** OPTIMISE THROUGH MY STRANGE SIMULATED ANNEALING ALGO ;-) ****/
|
/**** OPTIMIZE THROUGH MY STRANGE SIMULATED ANNEALING ALGO ;-) ****/
|
||||||
/**** ****/
|
|
||||||
/**** ****/
|
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
#ifndef BRUTE_FORCE
|
#ifndef AH_BRUTE_FORCE
|
||||||
|
|
||||||
/* compute all spring tensions */
|
/* compute all spring tensions */
|
||||||
static
|
static
|
||||||
void optim_compute_tensions( AH_Optimizer* optimizer )
|
void optim_compute_tensions( AH_Optimizer* optimizer )
|
||||||
{
|
{
|
||||||
AH_Spring* spring = optimizer->springs;
|
AH_Spring* spring = optimizer->springs;
|
||||||
AH_Spring* limit = spring + optimizer->num_springs;
|
AH_Spring* limit = spring + optimizer->num_springs;
|
||||||
|
|
||||||
|
|
||||||
for ( ; spring < limit; spring++ )
|
for ( ; spring < limit; spring++ )
|
||||||
{
|
{
|
||||||
AH_Stem* stem1 = spring->stem1;
|
AH_Stem* stem1 = spring->stem1;
|
||||||
|
@ -436,7 +495,8 @@ void optim_log( const char* fmt, ... )
|
||||||
FT_Pos tension;
|
FT_Pos tension;
|
||||||
FT_Pos sign;
|
FT_Pos sign;
|
||||||
|
|
||||||
/* compute the tension, it simply is -K*(new_width-old_width) */
|
|
||||||
|
/* compute the tension; it simply is -K*(new_width-old_width) */
|
||||||
width = stem2->pos - ( stem1->pos + stem1->width );
|
width = stem2->pos - ( stem1->pos + stem1->width );
|
||||||
tension = width - spring->owidth;
|
tension = width - spring->owidth;
|
||||||
|
|
||||||
|
@ -456,7 +516,7 @@ void optim_log( const char* fmt, ... )
|
||||||
spring->tension = tension;
|
spring->tension = tension;
|
||||||
|
|
||||||
/* now, distribute tension among the englobing stems, if they */
|
/* now, distribute tension among the englobing stems, if they */
|
||||||
/* are able to move.. */
|
/* are able to move */
|
||||||
status = 0;
|
status = 0;
|
||||||
if ( stem1->pos <= stem1->min_pos )
|
if ( stem1->pos <= stem1->min_pos )
|
||||||
status |= 1;
|
status |= 1;
|
||||||
|
@ -475,8 +535,7 @@ void optim_log( const char* fmt, ... )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* compute all stem movements -- returns 0 if nothing moved */
|
||||||
/* compute all stem movements - returns 0 if nothing moved */
|
|
||||||
static
|
static
|
||||||
int optim_compute_stem_movements( AH_Optimizer* optimizer )
|
int optim_compute_stem_movements( AH_Optimizer* optimizer )
|
||||||
{
|
{
|
||||||
|
@ -485,21 +544,23 @@ void optim_log( const char* fmt, ... )
|
||||||
AH_Stem* stem = stems;
|
AH_Stem* stem = stems;
|
||||||
int moved = 0;
|
int moved = 0;
|
||||||
|
|
||||||
|
|
||||||
/* set initial forces to velocity */
|
/* set initial forces to velocity */
|
||||||
for ( stem = stems; stem < limit; stem++ )
|
for ( stem = stems; stem < limit; stem++ )
|
||||||
{
|
{
|
||||||
stem->force = stem->velocity;
|
stem->force = stem->velocity;
|
||||||
stem->velocity /= 2; /* XXXX: Heuristics */
|
stem->velocity /= 2; /* XXX: Heuristics */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compute the sum of forces applied on each stem */
|
/* compute the sum of forces applied on each stem */
|
||||||
optim_compute_tensions( optimizer );
|
optim_compute_tensions( optimizer );
|
||||||
#ifdef DEBUG_OPTIM
|
|
||||||
|
#ifdef AH_DEBUG_OPTIM
|
||||||
AH_Dump_Springs( optimizer );
|
AH_Dump_Springs( optimizer );
|
||||||
AH_Dump_Stems2( optimizer );
|
AH_Dump_Stems2( optimizer );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* now, see if something can move ? */
|
/* now, see whether something can move */
|
||||||
for ( stem = stems; stem < limit; stem++ )
|
for ( stem = stems; stem < limit; stem++ )
|
||||||
{
|
{
|
||||||
if ( stem->force > optimizer->tension_threshold )
|
if ( stem->force > optimizer->tension_threshold )
|
||||||
|
@ -527,20 +588,22 @@ void optim_log( const char* fmt, ... )
|
||||||
stem->velocity = 0;
|
stem->velocity = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return 0 if nothing moved */
|
/* return 0 if nothing moved */
|
||||||
return moved;
|
return moved;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* BRUTE_FORCE */
|
#endif /* AH_BRUTE_FORCE */
|
||||||
|
|
||||||
|
|
||||||
/* compute current global distortion from springs */
|
/* compute current global distortion from springs */
|
||||||
static
|
static
|
||||||
FT_Pos optim_compute_distorsion( AH_Optimizer* optimizer )
|
FT_Pos optim_compute_distortion( AH_Optimizer* optimizer )
|
||||||
{
|
{
|
||||||
AH_Spring* spring = optimizer->springs;
|
AH_Spring* spring = optimizer->springs;
|
||||||
AH_Spring* limit = spring + optimizer->num_springs;
|
AH_Spring* limit = spring + optimizer->num_springs;
|
||||||
FT_Pos distorsion = 0;
|
FT_Pos distortion = 0;
|
||||||
|
|
||||||
|
|
||||||
for ( ; spring < limit; spring++ )
|
for ( ; spring < limit; spring++ )
|
||||||
{
|
{
|
||||||
|
@ -553,27 +616,29 @@ void optim_log( const char* fmt, ... )
|
||||||
if ( width < 0 )
|
if ( width < 0 )
|
||||||
width = -width;
|
width = -width;
|
||||||
|
|
||||||
distorsion += width;
|
distortion += width;
|
||||||
}
|
}
|
||||||
return distorsion;
|
|
||||||
|
return distortion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* record stems configuration in "best of" history */
|
/* record stems configuration in `best of' history */
|
||||||
static
|
static
|
||||||
void optim_record_configuration( AH_Optimizer* optimizer )
|
void optim_record_configuration( AH_Optimizer* optimizer )
|
||||||
{
|
{
|
||||||
FT_Pos distorsion;
|
FT_Pos distortion;
|
||||||
AH_Configuration* configs = optimizer->configs;
|
AH_Configuration* configs = optimizer->configs;
|
||||||
AH_Configuration* limit = configs + optimizer->num_configs;
|
AH_Configuration* limit = configs + optimizer->num_configs;
|
||||||
AH_Configuration* config;
|
AH_Configuration* config;
|
||||||
|
|
||||||
distorsion = optim_compute_distorsion( optimizer );
|
|
||||||
LOG(( "config distorsion = %.1f ", FLOAT(distorsion*64) ));
|
distortion = optim_compute_distortion( optimizer );
|
||||||
|
LOG(( "config distortion = %.1f ", FLOAT( distortion * 64 ) ));
|
||||||
|
|
||||||
/* check that we really need to add this configuration to our */
|
/* check that we really need to add this configuration to our */
|
||||||
/* sorted history.. */
|
/* sorted history */
|
||||||
if ( limit > configs && limit[-1].distorsion < distorsion )
|
if ( limit > configs && limit[-1].distortion < distortion )
|
||||||
{
|
{
|
||||||
LOG(( "ejected\n" ));
|
LOG(( "ejected\n" ));
|
||||||
return;
|
return;
|
||||||
|
@ -583,33 +648,37 @@ void optim_log( const char* fmt, ... )
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
|
||||||
config = limit;
|
config = limit;
|
||||||
if ( optimizer->num_configs < AH_MAX_CONFIGS )
|
if ( optimizer->num_configs < AH_MAX_CONFIGS )
|
||||||
optimizer->num_configs++;
|
optimizer->num_configs++;
|
||||||
else
|
else
|
||||||
config--;
|
config--;
|
||||||
|
|
||||||
config->distorsion = distorsion;
|
config->distortion = distortion;
|
||||||
|
|
||||||
for ( n = 0; n < optimizer->num_stems; n++ )
|
for ( n = 0; n < optimizer->num_stems; n++ )
|
||||||
config->positions[n] = optimizer->stems[n].pos;
|
config->positions[n] = optimizer->stems[n].pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* move the current configuration towards the front of the list */
|
/* move the current configuration towards the front of the list */
|
||||||
/* when necessary, yes this is slow bubble sort ;-) */
|
/* when necessary -- yes this is slow bubble sort ;-) */
|
||||||
while ( config > configs && config[0].distorsion < config[-1].distorsion )
|
while ( config > configs && config[0].distortion < config[-1].distortion )
|
||||||
{
|
{
|
||||||
AH_Configuration temp;
|
AH_Configuration temp;
|
||||||
|
|
||||||
|
|
||||||
config--;
|
config--;
|
||||||
temp = config[0];
|
temp = config[0];
|
||||||
config[0] = config[1];
|
config[0] = config[1];
|
||||||
config[1] = temp;
|
config[1] = temp;
|
||||||
}
|
}
|
||||||
LOG(( "recorded !!\n" ));
|
LOG(( "recorded!\n" ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef BRUTE_FORCE
|
#ifdef AH_BRUTE_FORCE
|
||||||
|
|
||||||
/* optimize outline in a single direction */
|
/* optimize outline in a single direction */
|
||||||
static
|
static
|
||||||
void optim_compute( AH_Optimizer* optimizer )
|
void optim_compute( AH_Optimizer* optimizer )
|
||||||
|
@ -617,10 +686,10 @@ void optim_log( const char* fmt, ... )
|
||||||
int n;
|
int n;
|
||||||
FT_Bool moved;
|
FT_Bool moved;
|
||||||
|
|
||||||
|
|
||||||
AH_Stem* stem = optimizer->stems;
|
AH_Stem* stem = optimizer->stems;
|
||||||
AH_Stem* limit = stem + optimizer->num_stems;
|
AH_Stem* limit = stem + optimizer->num_stems;
|
||||||
|
|
||||||
|
|
||||||
/* empty, exit */
|
/* empty, exit */
|
||||||
if ( stem >= limit )
|
if ( stem >= limit )
|
||||||
return;
|
return;
|
||||||
|
@ -649,8 +718,7 @@ void optim_log( const char* fmt, ... )
|
||||||
|
|
||||||
stem->pos = stem->min_pos;
|
stem->pos = stem->min_pos;
|
||||||
}
|
}
|
||||||
}
|
} while ( moved );
|
||||||
while (moved);
|
|
||||||
|
|
||||||
/* now, set the best stem positions */
|
/* now, set the best stem positions */
|
||||||
for ( n = 0; n < optimizer->num_stems; n++ )
|
for ( n = 0; n < optimizer->num_stems; n++ )
|
||||||
|
@ -658,6 +726,7 @@ void optim_log( const char* fmt, ... )
|
||||||
AH_Stem* stem = optimizer->stems + n;
|
AH_Stem* stem = optimizer->stems + n;
|
||||||
FT_Pos pos = optimizer->configs[0].positions[n];
|
FT_Pos pos = optimizer->configs[0].positions[n];
|
||||||
|
|
||||||
|
|
||||||
stem->edge1->pos = pos;
|
stem->edge1->pos = pos;
|
||||||
stem->edge2->pos = pos + stem->width;
|
stem->edge2->pos = pos + stem->width;
|
||||||
|
|
||||||
|
@ -665,19 +734,23 @@ void optim_log( const char* fmt, ... )
|
||||||
stem->edge2->flags |= ah_edge_done;
|
stem->edge2->flags |= ah_edge_done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
|
#else /* AH_BRUTE_FORCE */
|
||||||
|
|
||||||
/* optimize outline in a single direction */
|
/* optimize outline in a single direction */
|
||||||
static
|
static
|
||||||
void optim_compute( AH_Optimizer* optimizer )
|
void optim_compute( AH_Optimizer* optimizer )
|
||||||
{
|
{
|
||||||
int n, counter, counter2;
|
int n, counter, counter2;
|
||||||
|
|
||||||
|
|
||||||
optimizer->num_configs = 0;
|
optimizer->num_configs = 0;
|
||||||
optimizer->tension_scale = 0x80000L;
|
optimizer->tension_scale = 0x80000L;
|
||||||
optimizer->tension_threshold = 64;
|
optimizer->tension_threshold = 64;
|
||||||
|
|
||||||
/* record initial configuration threshold */
|
/* record initial configuration threshold */
|
||||||
optim_record_configuration( optimizer );
|
optim_record_configuration( optimizer );
|
||||||
|
|
||||||
counter = 0;
|
counter = 0;
|
||||||
for ( counter2 = optimizer->num_stems*8; counter2 >= 0; counter2-- )
|
for ( counter2 = optimizer->num_stems*8; counter2 >= 0; counter2-- )
|
||||||
{
|
{
|
||||||
|
@ -688,6 +761,7 @@ void optim_log( const char* fmt, ... )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
optim_record_configuration( optimizer );
|
optim_record_configuration( optimizer );
|
||||||
|
|
||||||
counter--;
|
counter--;
|
||||||
if ( counter == 0 )
|
if ( counter == 0 )
|
||||||
optimizer->tension_scale /= 2;
|
optimizer->tension_scale /= 2;
|
||||||
|
@ -699,6 +773,7 @@ void optim_log( const char* fmt, ... )
|
||||||
AH_Stem* stem = optimizer->stems + n;
|
AH_Stem* stem = optimizer->stems + n;
|
||||||
FT_Pos pos = optimizer->configs[0].positions[n];
|
FT_Pos pos = optimizer->configs[0].positions[n];
|
||||||
|
|
||||||
|
|
||||||
stem->edge1->pos = pos;
|
stem->edge1->pos = pos;
|
||||||
stem->edge2->pos = pos + stem->width;
|
stem->edge2->pos = pos + stem->width;
|
||||||
|
|
||||||
|
@ -706,7 +781,9 @@ void optim_log( const char* fmt, ... )
|
||||||
stem->edge2->flags |= ah_edge_done;
|
stem->edge2->flags |= ah_edge_done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
#endif /* AH_BRUTE_FORCE */
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
@ -714,19 +791,19 @@ void optim_log( const char* fmt, ... )
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/**** HIGH-LEVEL OPTIMIZER API ****/
|
/**** HIGH-LEVEL OPTIMIZER API ****/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/**** ****/
|
|
||||||
/**** ****/
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/* releases the optimisation data */
|
/* releases the optimization data */
|
||||||
void AH_Optimizer_Done( AH_Optimizer* optimizer )
|
void AH_Optimizer_Done( AH_Optimizer* optimizer )
|
||||||
{
|
{
|
||||||
if ( optimizer )
|
if ( optimizer )
|
||||||
{
|
{
|
||||||
FT_Memory memory = optimizer->memory;
|
FT_Memory memory = optimizer->memory;
|
||||||
|
|
||||||
|
|
||||||
FREE( optimizer->horz_stems );
|
FREE( optimizer->horz_stems );
|
||||||
FREE( optimizer->vert_stems );
|
FREE( optimizer->vert_stems );
|
||||||
FREE( optimizer->horz_springs );
|
FREE( optimizer->horz_springs );
|
||||||
|
@ -735,6 +812,7 @@ void optim_log( const char* fmt, ... )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* loads the outline into the optimizer */
|
/* loads the outline into the optimizer */
|
||||||
int AH_Optimizer_Init( AH_Optimizer* optimizer,
|
int AH_Optimizer_Init( AH_Optimizer* optimizer,
|
||||||
AH_Outline* outline,
|
AH_Outline* outline,
|
||||||
|
@ -742,6 +820,7 @@ void optim_log( const char* fmt, ... )
|
||||||
{
|
{
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
|
|
||||||
|
|
||||||
MEM_Set( optimizer, 0, sizeof ( *optimizer ) );
|
MEM_Set( optimizer, 0, sizeof ( *optimizer ) );
|
||||||
optimizer->outline = outline;
|
optimizer->outline = outline;
|
||||||
optimizer->memory = memory;
|
optimizer->memory = memory;
|
||||||
|
@ -750,22 +829,26 @@ void optim_log( const char* fmt, ... )
|
||||||
/* compute stems and springs */
|
/* compute stems and springs */
|
||||||
error = optim_compute_stems ( optimizer ) ||
|
error = optim_compute_stems ( optimizer ) ||
|
||||||
optim_compute_springs( optimizer );
|
optim_compute_springs( optimizer );
|
||||||
if (error) goto Fail;
|
if ( error )
|
||||||
|
goto Fail;
|
||||||
|
|
||||||
/* allocate stem positions history and configurations */
|
/* allocate stem positions history and configurations */
|
||||||
{
|
{
|
||||||
int n, max_stems;
|
int n, max_stems;
|
||||||
|
|
||||||
|
|
||||||
max_stems = optimizer->num_hstems;
|
max_stems = optimizer->num_hstems;
|
||||||
if ( max_stems < optimizer->num_vstems )
|
if ( max_stems < optimizer->num_vstems )
|
||||||
max_stems = optimizer->num_vstems;
|
max_stems = optimizer->num_vstems;
|
||||||
|
|
||||||
if ( ALLOC_ARRAY( optimizer->positions, max_stems*AH_MAX_CONFIGS, FT_Pos ) )
|
if ( ALLOC_ARRAY( optimizer->positions,
|
||||||
|
max_stems * AH_MAX_CONFIGS, FT_Pos ) )
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
optimizer->num_configs = 0;
|
optimizer->num_configs = 0;
|
||||||
for ( n = 0; n < AH_MAX_CONFIGS; n++ )
|
for ( n = 0; n < AH_MAX_CONFIGS; n++ )
|
||||||
optimizer->configs[n].positions = optimizer->positions + n*max_stems;
|
optimizer->configs[n].positions = optimizer->positions +
|
||||||
|
n * max_stems;
|
||||||
}
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
@ -786,7 +869,7 @@ void optim_log( const char* fmt, ... )
|
||||||
|
|
||||||
if ( optimizer->num_springs > 0 )
|
if ( optimizer->num_springs > 0 )
|
||||||
{
|
{
|
||||||
LOG(( "horizontal optimisation ------------------------\n" ));
|
LOG(( "horizontal optimization ------------------------\n" ));
|
||||||
optim_compute( optimizer );
|
optim_compute( optimizer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -797,12 +880,10 @@ void optim_log( const char* fmt, ... )
|
||||||
|
|
||||||
if ( optimizer->num_springs )
|
if ( optimizer->num_springs )
|
||||||
{
|
{
|
||||||
LOG(( "vertical optimisation --------------------------\n" ));
|
LOG(( "vertical optimization --------------------------\n" ));
|
||||||
optim_compute( optimizer );
|
optim_compute( optimizer );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* END */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,37 +1,41 @@
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* FreeType Auto-Gridder Outline Optimisation */
|
/* ahoptim.h */
|
||||||
/* */
|
/* */
|
||||||
/* This module is in charge of optimising the outlines produced by the */
|
/* FreeType auto hinting outline optimization (declaration). */
|
||||||
/* auto-hinter in direct mode. This is required at small pixel sizes in */
|
|
||||||
/* order to ensure coherent spacing, among other things.. */
|
|
||||||
/* */
|
/* */
|
||||||
/* The technique used in this module is a simplified simulated annealing. */
|
/* Copyright 2000 Catharon Productions Inc. */
|
||||||
/* */
|
|
||||||
/* Copyright 2000: Catharon Productions Inc. */
|
|
||||||
/* Author: David Turner */
|
/* Author: David Turner */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of the Catharon Typography Project and shall only */
|
/* This file is part of the Catharon Typography Project and shall only */
|
||||||
/* be used, modified, and distributed under the terms of the Catharon */
|
/* be used, modified, and distributed under the terms of the Catharon */
|
||||||
/* Open Source License that should come with this file under the name */
|
/* Open Source License that should come with this file under the name */
|
||||||
/* "CatharonLicense.txt". By continuing to use, modify, or distribute */
|
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||||
/* this file you indicate that you have read the license and */
|
/* this file you indicate that you have read the license and */
|
||||||
/* understand and accept it fully. */
|
/* understand and accept it fully. */
|
||||||
/* */
|
/* */
|
||||||
/* Note that this license is compatible with the FreeType license */
|
/* Note that this license is compatible with the FreeType license. */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
#ifndef AGOPTIM_H
|
|
||||||
#define AGOPTIM_H
|
#ifndef AHOPTIM_H
|
||||||
|
#define AHOPTIM_H
|
||||||
|
|
||||||
|
|
||||||
#ifdef FT_FLAT_COMPILE
|
#ifdef FT_FLAT_COMPILE
|
||||||
|
|
||||||
#include "ahtypes.h"
|
#include "ahtypes.h"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <autohint/ahtypes.h>
|
#include <autohint/ahtypes.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* the maximal number of stem configurations to record during optimisation */
|
|
||||||
|
/* the maximal number of stem configurations to record */
|
||||||
|
/* during optimization */
|
||||||
#define AH_MAX_CONFIGS 8
|
#define AH_MAX_CONFIGS 8
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,17 +73,15 @@
|
||||||
|
|
||||||
|
|
||||||
/* A configuration records the position of each stem at a given time */
|
/* A configuration records the position of each stem at a given time */
|
||||||
/* as well as the associated distortion.. */
|
/* as well as the associated distortion */
|
||||||
typedef struct AH_Configuration_
|
typedef struct AH_Configuration_
|
||||||
{
|
{
|
||||||
FT_Pos* positions;
|
FT_Pos* positions;
|
||||||
FT_Long distorsion;
|
FT_Long distortion;
|
||||||
|
|
||||||
} AH_Configuration;
|
} AH_Configuration;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AH_Optimizer_
|
typedef struct AH_Optimizer_
|
||||||
{
|
{
|
||||||
FT_Memory memory;
|
FT_Memory memory;
|
||||||
|
@ -115,23 +117,20 @@
|
||||||
|
|
||||||
|
|
||||||
/* loads the outline into the optimizer */
|
/* loads the outline into the optimizer */
|
||||||
extern
|
|
||||||
int AH_Optimizer_Init( AH_Optimizer* optimizer,
|
int AH_Optimizer_Init( AH_Optimizer* optimizer,
|
||||||
AH_Outline* outline,
|
AH_Outline* outline,
|
||||||
FT_Memory memory );
|
FT_Memory memory );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* compute optimal outline */
|
/* compute optimal outline */
|
||||||
extern
|
|
||||||
void AH_Optimizer_Compute( AH_Optimizer* optimizer );
|
void AH_Optimizer_Compute( AH_Optimizer* optimizer );
|
||||||
|
|
||||||
|
|
||||||
|
/* release the optimization data */
|
||||||
|
|
||||||
/* releases the optimisation data */
|
|
||||||
extern
|
|
||||||
void AH_Optimizer_Done( AH_Optimizer* optimizer );
|
void AH_Optimizer_Done( AH_Optimizer* optimizer );
|
||||||
|
|
||||||
|
|
||||||
#endif /* AGOPTIM_H */
|
#endif /* AHOPTIM_H */
|
||||||
|
|
||||||
|
|
||||||
|
/* END */
|
||||||
|
|
|
@ -3,177 +3,212 @@
|
||||||
/* ahtypes.h */
|
/* ahtypes.h */
|
||||||
/* */
|
/* */
|
||||||
/* General types and definitions for the auto-hint module */
|
/* General types and definitions for the auto-hint module */
|
||||||
|
/* (specification only). */
|
||||||
/* */
|
/* */
|
||||||
/* Copyright 2000: Catharon Productions Inc. */
|
/* Copyright 2000 Catharon Productions Inc. */
|
||||||
/* Author: David Turner */
|
/* Author: David Turner */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of the Catharon Typography Project and shall only */
|
/* This file is part of the Catharon Typography Project and shall only */
|
||||||
/* be used, modified, and distributed under the terms of the Catharon */
|
/* be used, modified, and distributed under the terms of the Catharon */
|
||||||
/* Open Source License that should come with this file under the name */
|
/* Open Source License that should come with this file under the name */
|
||||||
/* "CatharonLicense.txt". By continuing to use, modify, or distribute */
|
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||||
/* this file you indicate that you have read the license and */
|
/* this file you indicate that you have read the license and */
|
||||||
/* understand and accept it fully. */
|
/* understand and accept it fully. */
|
||||||
/* */
|
/* */
|
||||||
/* Note that this license is compatible with the FreeType license */
|
/* Note that this license is compatible with the FreeType license. */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
#ifndef AGTYPES_H
|
|
||||||
#define AGTYPES_H
|
|
||||||
|
|
||||||
#include <freetype/internal/ftobjs.h> /* for freetype.h + LOCAL_DEF etc.. */
|
#ifndef AHTYPES_H
|
||||||
|
#define AHTYPES_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <freetype/internal/ftobjs.h> /* for freetype.h + LOCAL_DEF etc. */
|
||||||
|
|
||||||
|
|
||||||
#ifdef FT_FLAT_COMPILE
|
#ifdef FT_FLAT_COMPILE
|
||||||
#include "ahloader.h" /* glyph loader types & declarations */
|
|
||||||
|
#include "ahloader.h"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#include <autohint/ahloader.h> /* glyph loader types & declarations */
|
|
||||||
|
#include <autohint/ahloader.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define xxDEBUG_AG
|
|
||||||
|
|
||||||
#ifdef DEBUG_AG
|
#define xxAH_DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef AH_DEBUG
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define AH_LOG( x ) printf##x
|
#define AH_LOG( x ) printf##x
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define AH_LOG(x) /* nothing */
|
|
||||||
|
#define AH_LOG( x ) do ; while ( 0 ) /* nothing */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/*************************************************************************/
|
||||||
/***************************************************************************/
|
/*************************************************************************/
|
||||||
/***************************************************************************/
|
/*************************************************************************/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/**** COMPILE-TIME BUILD OPTIONS ****/
|
/**** COMPILE-TIME BUILD OPTIONS ****/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/**** Toggle these configuration macros to experiment with ****/
|
/**** Toggle these configuration macros to experiment with `features' ****/
|
||||||
/**** "features" of the auto-hinter.. ****/
|
/**** of the auto-hinter. ****/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/***************************************************************************/
|
/*************************************************************************/
|
||||||
/***************************************************************************/
|
/*************************************************************************/
|
||||||
/***************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
/* if this option is defined, only strong interpolation will be used to */
|
|
||||||
/* place the points between edges. Otherwise, "smooth" points are detected */
|
/*************************************************************************/
|
||||||
/* and later hinted through weak interpolation to correct some unpleasant */
|
/* */
|
||||||
/* artefacts.. */
|
/* If this option is defined, only strong interpolation will be used to */
|
||||||
|
/* place the points between edges. Otherwise, `smooth' points are */
|
||||||
|
/* detected and later hinted through weak interpolation to correct some */
|
||||||
|
/* unpleasant artefacts. */
|
||||||
/* */
|
/* */
|
||||||
#undef AH_OPTION_NO_WEAK_INTERPOLATION
|
#undef AH_OPTION_NO_WEAK_INTERPOLATION
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* If this option is defined, only weak interpolation will be used to */
|
||||||
|
/* place the points between edges. Otherwise, `strong' points are */
|
||||||
|
/* detected and later hinted through strong interpolation to correct */
|
||||||
|
/* some unpleasant artefacts. */
|
||||||
|
/* */
|
||||||
#undef AH_OPTION_NO_STRONG_INTERPOLATION
|
#undef AH_OPTION_NO_STRONG_INTERPOLATION
|
||||||
|
|
||||||
/* undefine this macro if you don't want to hint the metrics */
|
|
||||||
/* there is no reason to do this, except for experimentation */
|
/*************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* Undefine this macro if you don't want to hint the metrics. There is */
|
||||||
|
/* no reason to do this (at least for non-CJK scripts), except for */
|
||||||
|
/* experimentation. */
|
||||||
|
/* */
|
||||||
#define AH_HINT_METRICS
|
#define AH_HINT_METRICS
|
||||||
|
|
||||||
/* define this macro if you do not want to insert extra edges at a glyph's */
|
|
||||||
/* x and y extrema (when there isn't one already available). This help */
|
/*************************************************************************/
|
||||||
/* reduce a number of artefacts and allow hinting of metrics.. */
|
/* */
|
||||||
|
/* Define this macro if you do not want to insert extra edges at a */
|
||||||
|
/* glyph's x and y extremum (if there isn't one already available). */
|
||||||
|
/* This helps to reduce a number of artefacts and allows hinting of */
|
||||||
|
/* metrics. */
|
||||||
/* */
|
/* */
|
||||||
#undef AH_OPTION_NO_EXTREMUM_EDGES
|
#undef AH_OPTION_NO_EXTREMUM_EDGES
|
||||||
|
|
||||||
/* don't touch for now.. */
|
|
||||||
|
/* don't touch for now */
|
||||||
#define AH_MAX_WIDTHS 12
|
#define AH_MAX_WIDTHS 12
|
||||||
#define AH_MAX_HEIGHTS 12
|
#define AH_MAX_HEIGHTS 12
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/***************************************************************************/
|
/*************************************************************************/
|
||||||
/***************************************************************************/
|
/*************************************************************************/
|
||||||
|
/*************************************************************************/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/**** TYPES DEFINITIONS ****/
|
/**** TYPE DEFINITIONS ****/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/***************************************************************************/
|
/*************************************************************************/
|
||||||
/***************************************************************************/
|
/*************************************************************************/
|
||||||
/***************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/* see agangles.h */
|
/* see agangles.h */
|
||||||
typedef FT_Int AH_Angle;
|
typedef FT_Int AH_Angle;
|
||||||
|
|
||||||
|
|
||||||
/* hint flags */
|
/* hint flags */
|
||||||
typedef enum AH_Flags_
|
#define ah_flah_none 0
|
||||||
{
|
|
||||||
ah_flah_none = 0,
|
|
||||||
|
|
||||||
/* bezier control points flags */
|
/* bezier control points flags */
|
||||||
ah_flah_conic = 1,
|
#define ah_flah_conic 1
|
||||||
ah_flah_cubic = 2,
|
#define ah_flah_cubic 2
|
||||||
ah_flah_control = ah_flah_conic | ah_flah_cubic,
|
#define ah_flah_control ( ah_flah_conic | ah_flah_cubic )
|
||||||
|
|
||||||
/* extrema flags */
|
/* extrema flags */
|
||||||
ah_flah_extrema_x = 4,
|
#define ah_flah_extrema_x 4
|
||||||
ah_flah_extrema_y = 8,
|
#define ah_flah_extrema_y 8
|
||||||
|
|
||||||
/* roundness */
|
/* roundness */
|
||||||
ah_flah_round_x = 16,
|
#define ah_flah_round_x 16
|
||||||
ah_flah_round_y = 32,
|
#define ah_flah_round_y 32
|
||||||
|
|
||||||
/* touched */
|
/* touched */
|
||||||
ah_flah_touch_x = 64,
|
#define ah_flah_touch_x 64
|
||||||
ah_flah_touch_y = 128,
|
#define ah_flah_touch_y 128
|
||||||
|
|
||||||
/* weak interpolation */
|
/* weak interpolation */
|
||||||
ah_flah_weak_interpolation = 256,
|
#define ah_flah_weak_interpolation 256
|
||||||
|
|
||||||
/* never remove this one !! */
|
typedef FT_Int AH_Flags;
|
||||||
ah_flah_max
|
|
||||||
|
|
||||||
} AH_Flags;
|
|
||||||
|
|
||||||
|
|
||||||
/* edge hint flags */
|
/* edge hint flags */
|
||||||
typedef enum AH_Edge_Flags_
|
#define ah_edge_normal 0
|
||||||
{
|
#define ah_edge_round 1
|
||||||
ah_edge_normal = 0,
|
#define ah_edge_serif 2
|
||||||
ah_edge_round = 1,
|
#define ah_edge_done 4
|
||||||
ah_edge_serif = 2,
|
|
||||||
ah_edge_done = 4
|
|
||||||
|
|
||||||
} AH_Edge_Flags;
|
typedef FT_Int AH_Edge_Flags;
|
||||||
|
|
||||||
|
|
||||||
/* hint directions - the values are computed so that two vectors are */
|
/* hint directions -- the values are computed so that two vectors are */
|
||||||
/* in opposite directions iff "dir1+dir2 == 0" */
|
/* in opposite directions iff `dir1+dir2 == 0' */
|
||||||
typedef enum AH_Direction_
|
#define ah_dir_none 4
|
||||||
{
|
#define ah_dir_right 1
|
||||||
ah_dir_none = 4,
|
#define ah_dir_left -1
|
||||||
ah_dir_right = 1,
|
#define ah_dir_up 2
|
||||||
ah_dir_left = -1,
|
#define ah_dir_down -2
|
||||||
ah_dir_up_and_down = 0,
|
|
||||||
ah_dir_left_and_right = 0,
|
|
||||||
ah_dir_up = 2,
|
|
||||||
ah_dir_down = -2
|
|
||||||
|
|
||||||
} AH_Direction;
|
typedef FT_Int AH_Direction;
|
||||||
|
|
||||||
|
|
||||||
typedef struct AH_Point AH_Point;
|
typedef struct AH_Point AH_Point;
|
||||||
typedef struct AH_Segment AH_Segment;
|
typedef struct AH_Segment AH_Segment;
|
||||||
typedef struct AH_Edge AH_Edge;
|
typedef struct AH_Edge AH_Edge;
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
*
|
/*************************************************************************/
|
||||||
* <Struct>
|
/* */
|
||||||
* AH_Point
|
/* <Struct> */
|
||||||
*
|
/* AH_Point */
|
||||||
* <Description>
|
/* */
|
||||||
* A structure used to model an outline point to the AH_Outline type
|
/* <Description> */
|
||||||
*
|
/* A structure used to model an outline point to the AH_Outline type. */
|
||||||
* <Fields>
|
/* */
|
||||||
* flags :: current point hint flags
|
/* <Fields> */
|
||||||
* ox, oy :: current original scaled coordinates
|
/* flags :: The current point hint flags. */
|
||||||
* fx, fy :: current coordinates in font units
|
/* */
|
||||||
* x, y :: current hinter coordinates
|
/* ox, oy :: The current original scaled coordinates. */
|
||||||
* u, v :: point coordinates - meaning varies with context
|
/* */
|
||||||
*
|
/* fx, fy :: The current coordinates in font units. */
|
||||||
* in_dir :: direction of inwards vector (prev->point)
|
/* */
|
||||||
* out_dir :: direction of outwards vector (point->next)
|
/* x, y :: The current hinter coordinates. */
|
||||||
*
|
/* */
|
||||||
* in_angle :: angle of inwards vector
|
/* u, v :: Point coordinates -- meaning varies with context. */
|
||||||
* out_angle :: angle of outwards vector
|
/* */
|
||||||
*
|
/* in_dir :: The direction of the inwards vector (prev->point). */
|
||||||
* next :: next point in same contour
|
/* */
|
||||||
* prev :: previous point in same contour
|
/* out_dir :: The direction of the outwards vector (point->next). */
|
||||||
*
|
/* */
|
||||||
*/
|
/* in_angle :: The angle of the inwards vector. */
|
||||||
|
/* */
|
||||||
|
/* out_angle :: The angle of the outwards vector. */
|
||||||
|
/* */
|
||||||
|
/* next :: The next point in same contour. */
|
||||||
|
/* */
|
||||||
|
/* prev :: The previous point in same contour. */
|
||||||
|
/* */
|
||||||
struct AH_Point
|
struct AH_Point
|
||||||
{
|
{
|
||||||
AH_Flags flags; /* point flags used by hinter */
|
AH_Flags flags; /* point flags used by hinter */
|
||||||
|
@ -193,37 +228,44 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/*************************************************************************/
|
||||||
*
|
/* */
|
||||||
* <Struct>
|
/* <Struct> */
|
||||||
* AH_Segment
|
/* AH_Segment */
|
||||||
*
|
/* */
|
||||||
* <Description>
|
/* <Description> */
|
||||||
* a structure used to describe an edge segment to the auto-hinter. A
|
/* A structure used to describe an edge segment to the auto-hinter. */
|
||||||
* segment is simply a sequence of successive points located on the same
|
/* A segment is simply a sequence of successive points located on the */
|
||||||
* horizontal or vertical "position", in a given direction.
|
/* same horizontal or vertical `position', in a given direction. */
|
||||||
*
|
/* */
|
||||||
* <Fields>
|
/* <Fields> */
|
||||||
* flags :: segment edge flags ( straight, rounded.. )
|
/* flags :: The segment edge flags (straight, rounded, etc.). */
|
||||||
* dir :: segment direction
|
/* */
|
||||||
*
|
/* dir :: The segment direction. */
|
||||||
* first :: first point in segment
|
/* */
|
||||||
* last :: last point in segment
|
/* first :: The first point in the segment. */
|
||||||
* contour :: ptr to first point of segment's contour
|
/* */
|
||||||
*
|
/* last :: The last point in the segment. */
|
||||||
* pos :: segment position in font units
|
/* */
|
||||||
* size :: segment size
|
/* contour :: A pointer to the first point of the segment's */
|
||||||
*
|
/* contour. */
|
||||||
* edge :: edge of current segment
|
/* */
|
||||||
* edge_next :: next segment on same edge
|
/* pos :: The segment position in font units. */
|
||||||
*
|
/* */
|
||||||
* link :: the pairing segment for this edge
|
/* size :: The segment size. */
|
||||||
* serif :: the primary segment for serifs
|
/* */
|
||||||
* num_linked :: the number of other segments that link to this one
|
/* edge :: The edge of the current segment. */
|
||||||
*
|
/* */
|
||||||
* score :: used to score the segment when selecting them..
|
/* edge_next :: The next segment on the same edge. */
|
||||||
*
|
/* */
|
||||||
*/
|
/* link :: The pairing segment for this edge. */
|
||||||
|
/* */
|
||||||
|
/* serif :: The primary segment for serifs. */
|
||||||
|
/* */
|
||||||
|
/* num_linked :: The number of other segments that link to this one. */
|
||||||
|
/* */
|
||||||
|
/* score :: Used to score the segment when selecting them. */
|
||||||
|
/* */
|
||||||
struct AH_Segment
|
struct AH_Segment
|
||||||
{
|
{
|
||||||
AH_Edge_Flags flags;
|
AH_Edge_Flags flags;
|
||||||
|
@ -247,38 +289,43 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/*************************************************************************/
|
||||||
*
|
/* */
|
||||||
* <Struct>
|
/* <Struct> */
|
||||||
* AH_Edge
|
/* AH_Edge */
|
||||||
*
|
/* */
|
||||||
* <Description>
|
/* <Description> */
|
||||||
* a structure used to describe an edge, which really is a horizontal
|
/* A structure used to describe an edge, which really is a horizontal */
|
||||||
* or vertical coordinate which will be hinted depending on the segments
|
/* or vertical coordinate to be hinted depending on the segments */
|
||||||
* located on it..
|
/* located on it. */
|
||||||
*
|
/* */
|
||||||
* <Fields>
|
/* <Fields> */
|
||||||
* flags :: segment edge flags ( straight, rounded.. )
|
/* flags :: The segment edge flags (straight, rounded, etc.). */
|
||||||
* dir :: main segment direction on this edge
|
/* */
|
||||||
*
|
/* dir :: The main segment direction on this edge. */
|
||||||
* first :: first edge segment
|
/* */
|
||||||
* last :: last edge segment
|
/* first :: The first edge segment. */
|
||||||
*
|
/* */
|
||||||
* fpos :: original edge position in font units
|
/* last :: The last edge segment. */
|
||||||
* opos :: original scaled edge position
|
/* */
|
||||||
* pos :: hinted edge position
|
/* fpos :: The original edge position in font units. */
|
||||||
*
|
/* */
|
||||||
* link :: the linked edge
|
/* opos :: The original scaled edge position. */
|
||||||
* serif :: the serif edge
|
/* */
|
||||||
* num_paired :: the number of other edges that pair to this one
|
/* pos :: The hinted edge position. */
|
||||||
*
|
/* */
|
||||||
* score :: used to score the edge when selecting them..
|
/* link :: The linked edge. */
|
||||||
*
|
/* */
|
||||||
* blue_edge :: indicate the blue zone edge this edge is related to
|
/* serif :: The serif edge. */
|
||||||
* only set for some of the horizontal edges in a Latin
|
/* */
|
||||||
* font..
|
/* num_paired :: The number of other edges that pair to this one. */
|
||||||
*
|
/* */
|
||||||
***************************************************************************/
|
/* score :: Used to score the edge when selecting them. */
|
||||||
|
/* */
|
||||||
|
/* blue_edge :: Indicate the blue zone edge this edge is related to. */
|
||||||
|
/* Only set for some of the horizontal edges in a Latin */
|
||||||
|
/* font. */
|
||||||
|
/* */
|
||||||
struct AH_Edge
|
struct AH_Edge
|
||||||
{
|
{
|
||||||
AH_Edge_Flags flags;
|
AH_Edge_Flags flags;
|
||||||
|
@ -335,46 +382,44 @@
|
||||||
} AH_Outline;
|
} AH_Outline;
|
||||||
|
|
||||||
|
|
||||||
|
#define ah_blue_capital_top 0 /* THEZOCQS */
|
||||||
|
#define ah_blue_capital_bottom ( ah_blue_capital_top + 1 ) /* HEZLOCUS */
|
||||||
|
#define ah_blue_small_top ( ah_blue_capital_bottom + 1 ) /* xzroesc */
|
||||||
|
#define ah_blue_small_bottom ( ah_blue_small_top + 1 ) /* xzroesc */
|
||||||
|
#define ah_blue_small_minor ( ah_blue_small_bottom + 1 ) /* pqgjy */
|
||||||
|
#define ah_blue_max ( ah_blue_small_minor + 1 )
|
||||||
|
|
||||||
typedef enum AH_Blue_
|
typedef FT_Int AH_Blue;
|
||||||
{
|
|
||||||
ah_blue_capital_top, /* THEZOCQS */
|
|
||||||
ah_blue_capital_bottom, /* HEZLOCUS */
|
|
||||||
ah_blue_small_top, /* xzroesc */
|
|
||||||
ah_blue_small_bottom, /* xzroesc */
|
|
||||||
ah_blue_small_minor, /* pqgjy */
|
|
||||||
|
|
||||||
ah_blue_max
|
|
||||||
|
|
||||||
} AH_Blue;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
ah_hinter_monochrome = 1,
|
|
||||||
ah_hinter_optimize = 2
|
|
||||||
|
|
||||||
} AH_Hinter_Flags;
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
#define ah_hinter_monochrome 1
|
||||||
*
|
#define ah_hinter_optimize 2
|
||||||
* <Struct>
|
|
||||||
* AH_Globals
|
|
||||||
*
|
|
||||||
* <Description>
|
|
||||||
* Holds the global metrics for a given font face (be it in design
|
|
||||||
* units, or scaled pixel values)..
|
|
||||||
*
|
|
||||||
* <Fields>
|
|
||||||
* num_widths :: number of widths
|
|
||||||
* num_heights :: number of heights
|
|
||||||
* widths :: snap widths, including standard one
|
|
||||||
* heights :: snap height, including standard one
|
|
||||||
* blue_refs :: reference position of blue zones
|
|
||||||
* blue_shoots :: overshoot position of blue zones
|
|
||||||
*
|
|
||||||
************************************************************************/
|
|
||||||
|
|
||||||
|
typedef FT_Int AH_Hinter_Flags;
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* <Struct> */
|
||||||
|
/* AH_Globals */
|
||||||
|
/* */
|
||||||
|
/* <Description> */
|
||||||
|
/* Holds the global metrics for a given font face (be it in design */
|
||||||
|
/* units or scaled pixel values). */
|
||||||
|
/* */
|
||||||
|
/* <Fields> */
|
||||||
|
/* num_widths :: The number of widths. */
|
||||||
|
/* */
|
||||||
|
/* num_heights :: The number of heights. */
|
||||||
|
/* */
|
||||||
|
/* widths :: Snap widths, including standard one. */
|
||||||
|
/* */
|
||||||
|
/* heights :: Snap height, including standard one. */
|
||||||
|
/* */
|
||||||
|
/* blue_refs :: The reference positions of blue zones. */
|
||||||
|
/* */
|
||||||
|
/* blue_shoots :: The overshoot positions of blue zones. */
|
||||||
|
/* */
|
||||||
typedef struct AH_Globals_
|
typedef struct AH_Globals_
|
||||||
{
|
{
|
||||||
FT_Int num_widths;
|
FT_Int num_widths;
|
||||||
|
@ -389,24 +434,27 @@
|
||||||
} AH_Globals;
|
} AH_Globals;
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/*************************************************************************/
|
||||||
*
|
/* */
|
||||||
* <Struct>
|
/* <Struct> */
|
||||||
* AH_Face_Globals
|
/* AH_Face_Globals */
|
||||||
*
|
/* */
|
||||||
* <Description>
|
/* <Description> */
|
||||||
* Holds the complete global metrics for a given font face (i.e. the
|
/* Holds the complete global metrics for a given font face (i.e., the */
|
||||||
* design units version + a scaled version + the current scales used)
|
/* design units version + a scaled version + the current scales */
|
||||||
*
|
/* used). */
|
||||||
* <Fields>
|
/* */
|
||||||
* face :: handle to source face object
|
/* <Fields> */
|
||||||
* design :: globals in font design units
|
/* face :: A handle to the source face object */
|
||||||
* scaled :: scaled globals in sub-pixel values
|
/* */
|
||||||
* x_scale :: current horizontal scale
|
/* design :: The globals in font design units. */
|
||||||
* y_scale :: current vertical scale
|
/* */
|
||||||
*
|
/* scaled :: Scaled globals in sub-pixel values. */
|
||||||
************************************************************************/
|
/* */
|
||||||
|
/* x_scale :: The current horizontal scale. */
|
||||||
|
/* */
|
||||||
|
/* y_scale :: The current vertical scale. */
|
||||||
|
/* */
|
||||||
typedef struct AH_Face_Globals_
|
typedef struct AH_Face_Globals_
|
||||||
{
|
{
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
|
@ -419,12 +467,10 @@
|
||||||
} AH_Face_Globals;
|
} AH_Face_Globals;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AH_Hinter
|
typedef struct AH_Hinter
|
||||||
{
|
{
|
||||||
FT_Memory memory;
|
FT_Memory memory;
|
||||||
FT_Long flags;
|
AH_Hinter_Flags flags;
|
||||||
|
|
||||||
FT_Int algorithm;
|
FT_Int algorithm;
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
|
@ -439,4 +485,8 @@
|
||||||
|
|
||||||
} AH_Hinter;
|
} AH_Hinter;
|
||||||
|
|
||||||
#endif /* AGTYPES_H */
|
|
||||||
|
#endif /* AHTYPES_H */
|
||||||
|
|
||||||
|
|
||||||
|
/* END */
|
||||||
|
|
|
@ -2,22 +2,23 @@
|
||||||
/* */
|
/* */
|
||||||
/* autohint.c */
|
/* autohint.c */
|
||||||
/* */
|
/* */
|
||||||
/* Automatic Hinting wrapper. */
|
/* Automatic Hinting wrapper (body only). */
|
||||||
/* */
|
/* */
|
||||||
/* Copyright 2000: Catharon Productions Inc. */
|
/* Copyright 2000 Catharon Productions Inc. */
|
||||||
/* Author: David Turner */
|
/* Author: David Turner */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of the Catharon Typography Project and shall only */
|
/* This file is part of the Catharon Typography Project and shall only */
|
||||||
/* be used, modified, and distributed under the terms of the Catharon */
|
/* be used, modified, and distributed under the terms of the Catharon */
|
||||||
/* Open Source License that should come with this file under the name */
|
/* Open Source License that should come with this file under the name */
|
||||||
/* "CatharonLicense.txt". By continuing to use, modify, or distribute */
|
/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */
|
||||||
/* this file you indicate that you have read the license and */
|
/* this file you indicate that you have read the license and */
|
||||||
/* understand and accept it fully. */
|
/* understand and accept it fully. */
|
||||||
/* */
|
/* */
|
||||||
/* Note that this license is compatible with the FreeType license */
|
/* Note that this license is compatible with the FreeType license. */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#define FT_MAKE_OPTION_SINGLE_OBJECT
|
#define FT_MAKE_OPTION_SINGLE_OBJECT
|
||||||
|
|
||||||
#ifdef FT_FLAT_COMPILE
|
#ifdef FT_FLAT_COMPILE
|
||||||
|
@ -38,3 +39,5 @@
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* END */
|
||||||
|
|
|
@ -1,3 +1,21 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# autohint math table builder
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
# Copyright 1996-2000 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.
|
||||||
|
|
||||||
|
|
||||||
import math
|
import math
|
||||||
|
|
||||||
ag_pi = 256
|
ag_pi = 256
|
||||||
|
@ -29,9 +47,12 @@ def print_arctan( atan_bits ):
|
||||||
print " };"
|
print " };"
|
||||||
|
|
||||||
|
|
||||||
|
# This routine is not used currently.
|
||||||
|
#
|
||||||
def print_sines():
|
def print_sines():
|
||||||
print " static FT_Fixed ah_sines[AG_HALF_PI + 1] ="
|
print " static FT_Fixed ah_sines[AG_HALF_PI + 1] ="
|
||||||
print " {"
|
print " {"
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
line = " "
|
line = " "
|
||||||
|
|
||||||
|
@ -49,6 +70,9 @@ def print_sines():
|
||||||
print " 65536"
|
print " 65536"
|
||||||
print " };"
|
print " };"
|
||||||
|
|
||||||
|
|
||||||
print_arctan( 8 )
|
print_arctan( 8 )
|
||||||
print
|
print
|
||||||
|
|
||||||
|
|
||||||
|
# END
|
||||||
|
|
|
@ -3,28 +3,17 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
#
|
# Copyright 2000 Catharon Productions Inc.
|
||||||
# Copyright 2000: Catharon Productions Inc.
|
|
||||||
# Author: David Turner
|
# Author: David Turner
|
||||||
#
|
#
|
||||||
# This file is part of the Catharon Typography Project and shall only
|
# This file is part of the Catharon Typography Project and shall only
|
||||||
# be used, modified, and distributed under the terms of the Catharon
|
# be used, modified, and distributed under the terms of the Catharon
|
||||||
# Open Source License that should come with this file under the name
|
# Open Source License that should come with this file under the name
|
||||||
# "CatharonLicense.txt". By continuing to use, modify, or distribute
|
# `CatharonLicense.txt'. By continuing to use, modify, or distribute
|
||||||
# this file you indicate that you have read the license and
|
# this file you indicate that you have read the license and
|
||||||
# understand and accept it fully.
|
# understand and accept it fully.
|
||||||
#
|
#
|
||||||
# Note that this license is compatible with the FreeType license
|
# Note that this license is compatible with the FreeType license.
|
||||||
#
|
|
||||||
#
|
|
||||||
# Copyright 1996-2000 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.
|
|
||||||
|
|
||||||
|
|
||||||
# AUTO driver directory
|
# AUTO driver directory
|
||||||
|
@ -48,7 +37,9 @@ AUTO_DRV_SRC := $(AUTO_DIR_)ahangles.c \
|
||||||
|
|
||||||
# AUTO driver headers
|
# AUTO driver headers
|
||||||
#
|
#
|
||||||
AUTO_DRV_H := $(AUTO_DRV_SRC:%c=%h)
|
AUTO_DRV_H := $(AUTO_DRV_SRC:%c=%h) \
|
||||||
|
$(AUTO_DIR_)ahloader.h \
|
||||||
|
$(AUTO_DIR_)ahtypes.h
|
||||||
|
|
||||||
|
|
||||||
# AUTO driver object(s)
|
# AUTO driver object(s)
|
||||||
|
|
|
@ -70,4 +70,5 @@ $(OBJ_)%.$O: $(T1_DIR_)%.c $(FREETYPE_H) $(T1_DRV_H)
|
||||||
DRV_OBJS_S += $(T1_DRV_OBJ_S)
|
DRV_OBJS_S += $(T1_DRV_OBJ_S)
|
||||||
DRV_OBJS_M += $(T1_DRV_OBJ_M)
|
DRV_OBJS_M += $(T1_DRV_OBJ_M)
|
||||||
|
|
||||||
|
|
||||||
# EOF
|
# EOF
|
||||||
|
|
Loading…
Reference in New Issue