ref: c3dd151b0f5401a603e66c13ec5a11655754b385
parent: d082cd680122af0f5ab7381b921462d2587adb83
author: Werner Lemberg <[email protected]>
date: Wed Jul 26 10:11:15 EDT 2000
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
--- a/src/autohint/ahglobal.c
+++ b/src/autohint/ahglobal.c
@@ -102,7 +102,7 @@
AH_LOG(( "blue zones computation\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* limit = p + MAX_TEST_CHARACTERS;
@@ -109,7 +109,7 @@
FT_Pos *blue_ref, *blue_shoot;
- AH_LOG(( "blue %3d: ", (int)blue ));
+ AH_LOG(( "blue %3d: ", blue ));
num_flats = 0;
num_rounds = 0;
--- a/src/autohint/ahglyph.c
+++ b/src/autohint/ahglyph.c
@@ -11,7 +11,7 @@
/* This file is part of the Catharon Typography Project and shall only */
/* be used, modified, and distributed under the terms of the Catharon */
/* 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 */
/* understand and accept it fully. */
/* */
@@ -547,7 +547,7 @@
/* a segment is round if either its first or last point */
/* is a control point */
if ( ( segment->first->flags | point->flags ) &
- ah_flah_control )
+ ah_flah_control )
segment->flags |= ah_edge_round;
/* compute segment size */
@@ -1150,7 +1150,7 @@
if ( 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 */
/* zone, check for left edges */
@@ -1213,41 +1213,38 @@
}
- /************************************************************************
- *
- * <Function>
- * ah_outline_scale_blue_edges
- *
- * <Description>
- * This functions must be called before hinting in order to re-adjust
- * the content of the detected edges (basically change the "blue edge"
- * pointer from 'design units' to 'scaled ones'
- *
- ************************************************************************/
-
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* ah_outline_scale_blue_edges */
+ /* */
+ /* <Description> */
+ /* This functions must be called before hinting in order to re-adjust */
+ /* the contents of the detected edges (basically change the `blue */
+ /* edge' pointer from `design units' to `scaled ones'). */
+ /* */
LOCAL_FUNC
void ah_outline_scale_blue_edges( AH_Outline* outline,
AH_Face_Globals* globals )
{
- AH_Edge* edge = outline->horz_edges;
- AH_Edge* limit = edge + outline->num_hedges;
- FT_Int delta;
+ AH_Edge* edge = outline->horz_edges;
+ AH_Edge* limit = edge + outline->num_hedges;
+ FT_Int delta;
+
delta = globals->scaled.blue_refs - globals->design.blue_refs;
+
for ( ; edge < limit; edge++ )
{
- if (edge->blue_edge)
+ if ( edge->blue_edge )
edge->blue_edge += delta;
}
}
-
-
-
#ifdef AH_DEBUG_GLYPH
- extern
- void ah_dump_edges( AH_Outline* outline )
+
+ void ah_dump_edges( AH_Outline* outline )
{
AH_Edge* edges;
AH_Edge* limit;
@@ -1254,38 +1251,49 @@
AH_Segment* segments;
FT_Int dimension;
+
edges = outline->horz_edges;
limit = edges + outline->num_hedges;
segments = outline->horz_segments;
+
for ( dimension = 1; dimension >= 0; dimension-- )
{
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++ )
{
printf ( " [ %5d | %4d | %5s | %4d | %5d | %c | %5.2f | %5.2f ]\n",
edge - edges,
(int)edge->fpos,
- edge->dir == ah_dir_up ? "up" :
- (edge->dir == ah_dir_down ? "down" :
- (edge->dir == ah_dir_left ? "left" :
- (edge->dir == ah_dir_right ? "right" : "none")
- )
- ),
- edge->link ? (edge->link-edges) : -1,
- edge->serif ? (edge->serif-edges) : -1,
+ edge->dir == ah_dir_up
+ ? "up"
+ : ( edge->dir == ah_dir_down
+ ? "down"
+ : ( edge->dir == ah_dir_left
+ ? "left"
+ : ( edge->dir == ah_dir_right
+ ? "right"
+ : "none" ) ) ),
+ edge->link ? ( edge->link - edges ) : -1,
+ edge->serif ? ( edge->serif - edges ) : -1,
edge->blue_edge ? 'y' : 'n',
- edge->opos/64.0,
- edge->pos/64.0 );
+ edge->opos / 64.0,
+ edge->pos / 64.0 );
}
-
edges = outline->vert_edges;
limit = edges + outline->num_vedges;
segments = outline->vert_segments;
}
}
-#endif
+
+#endif /* AH_DEBUG_GLYPH */
+
+
+/* END */
--- a/src/autohint/ahhint.c
+++ b/src/autohint/ahhint.c
@@ -2,70 +2,81 @@
/* */
/* ahhint.c */
/* */
-/* Glyph hinter */
+/* Glyph hinter (body). */
/* */
-/* Copyright 2000: Catharon Productions Inc. */
+/* Copyright 2000 Catharon Productions Inc. */
/* Author: David Turner */
/* */
/* This file is part of the Catharon Typography Project and shall only */
/* be used, modified, and distributed under the terms of the Catharon */
/* 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 */
/* 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
+
#include "ahhint.h"
#include "ahglyph.h"
#include "ahangles.h"
+
#else
+
#include <autohint/ahhint.h>
#include <autohint/ahglyph.h>
#include <autohint/ahangles.h>
+
#endif
#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
- /*******************************************************************/
- /*******************************************************************/
- /**** ****/
- /**** Hinting routines ****/
- /**** ****/
- /*******************************************************************/
- /*******************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** Hinting routines ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+
static int disable_horz_edges = 0;
static int disable_vert_edges = 0;
+
/* snap a given width in scaled coordinates to one of the */
- /* current standard widths.. */
+ /* current standard widths */
static
- FT_Pos ah_snap_width( FT_Pos* widths,
- FT_Int count,
- FT_Pos width )
+ FT_Pos ah_snap_width( FT_Pos* widths,
+ FT_Int count,
+ FT_Pos width )
{
int n;
- FT_Pos best = 64+32+2;
+ FT_Pos best = 64 + 32 + 2;
FT_Pos reference = width;
+
for ( n = 0; n < count; n++ )
{
FT_Pos w;
FT_Pos dist;
+
w = widths[n];
dist = width - w;
- if (dist < 0) dist = -dist;
- if (dist < best)
+ if ( dist < 0 )
+ dist = -dist;
+ if ( dist < best )
{
best = dist;
reference = w;
@@ -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
void ah_align_linked_edge( AH_Hinter* hinter,
AH_Edge* base_edge,
@@ -101,20 +111,21 @@
AH_Globals* globals = &hinter->globals->scaled;
FT_Pos sign = 1;
- if (dist < 0)
+
+ if ( dist < 0 )
{
dist = -dist;
sign = -1;
}
- if (vertical)
+ if ( vertical )
{
dist = ah_snap_width( globals->heights, globals->num_heights, dist );
/* in the case of vertical hinting, always round */
- /* the stem heights to integer pixels.. */
- if (dist >= 64)
- dist = (dist+16) & -64;
+ /* the stem heights to integer pixels */
+ if ( dist >= 64 )
+ dist = ( dist + 16 ) & -64;
else
dist = 64;
}
@@ -122,33 +133,32 @@
{
dist = ah_snap_width( globals->widths, globals->num_widths, dist );
- if (hinter->flags & ah_hinter_monochrome)
+ if ( hinter->flags & ah_hinter_monochrome )
{
/* monochrome horizontal hinting: snap widths to integer pixels */
- /* with a different threshold.. */
- if (dist < 64)
+ /* with a different threshold */
+ if ( dist < 64 )
dist = 64;
else
- dist = (dist+32) & -64;
+ dist = ( dist + 32 ) & -64;
}
else
{
/* 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 */
- if (dist < 48)
- dist = (dist+64) >> 1;
+ if ( dist < 48 )
+ dist = ( dist + 64 ) >> 1;
- else if (dist < 128)
- dist = (dist+42) & -64;
-
+ else if ( dist < 128 )
+ dist = ( dist + 42 ) & -64;
}
}
- stem_edge->pos = base_edge->pos + sign*dist;
+
+ stem_edge->pos = base_edge->pos + sign * dist;
}
-
static
void ah_align_serif_edge( AH_Hinter* hinter,
AH_Edge* base,
@@ -157,47 +167,51 @@
FT_Pos dist;
FT_Pos sign = 1;
- UNUSED(hinter);
+ UNUSED( hinter );
+
+
dist = serif->opos - base->opos;
- if (dist < 0)
+ if ( dist < 0 )
{
dist = -dist;
sign = -1;
}
- if (base->flags & ah_edge_done)
/* do not strengthen serifs */
+ if ( base->flags & ah_edge_done )
{
- if (dist > 64)
- dist = (dist+16) & -64;
+ if ( dist > 64 )
+ dist = ( dist + 16 ) & -64;
- else if (dist <= 32)
- dist = (dist+33) >> 1;
+ else if ( dist <= 32 )
+ 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 */
static
void ah_hint_edges_3( AH_Hinter* hinter )
{
- AH_Edge* edges;
- AH_Edge* edge_limit;
- AH_Outline* outline = hinter->glyph;
- FT_Int dimension;
+ AH_Edge* edges;
+ AH_Edge* edge_limit;
+ AH_Outline* outline = hinter->glyph;
+ FT_Int dimension;
+
edges = outline->horz_edges;
edge_limit = edges + outline->num_hedges;
@@ -209,22 +223,24 @@
AH_Edge* anchor = 0;
int has_serifs = 0;
- if (disable_vert_edges && !dimension)
+
+ if ( disable_vert_edges && !dimension )
goto Next_Dimension;
- if (disable_horz_edges && dimension)
+ if ( disable_horz_edges && dimension )
goto Next_Dimension;
/* we begin by aligning all stems relative to the blue zone */
- /* if needed.. that's only for horizontal edges.. */
- if (dimension)
+ /* if needed -- that's only for horizontal edges */
+ if ( dimension )
{
for ( edge = edges; edge < edge_limit; edge++ )
{
FT_Pos* blue;
- AH_Edge *edge1, *edge2;
+ AH_Edge *edge1, *edge2;
- if (edge->flags & ah_edge_done)
+
+ if ( edge->flags & ah_edge_done )
continue;
blue = edge->blue_edge;
@@ -231,7 +247,7 @@
edge1 = 0;
edge2 = edge->link;
- if (blue)
+ if ( blue )
{
edge1 = edge;
}
@@ -242,19 +258,19 @@
edge2 = edge;
}
- if (!edge1)
+ if ( !edge1 )
continue;
edge1->pos = blue[0];
edge1->flags |= ah_edge_done;
- if (edge2 && !edge2->blue_edge)
+ if ( edge2 && !edge2->blue_edge )
{
ah_align_linked_edge( hinter, edge1, edge2, dimension );
edge2->flags |= ah_edge_done;
}
- if (!anchor)
+ if ( !anchor )
anchor = edge;
}
}
@@ -267,12 +283,13 @@
{
AH_Edge *edge2;
- if (edge->flags & ah_edge_done)
+
+ if ( edge->flags & ah_edge_done )
continue;
/* skip all non-stem edges */
edge2 = edge->link;
- if (!edge2)
+ if ( !edge2 )
{
has_serifs++;
continue;
@@ -281,12 +298,14 @@
/* now, align the stem */
/* 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
printf( "strange blue alignement, edge %d to %d\n",
- edge - edges, edge2 - edges );
+ edge - edges, edge2 - edges );
#endif
+
ah_align_linked_edge( hinter, edge2, edge, dimension );
edge->flags |= ah_edge_done;
continue;
@@ -296,32 +315,33 @@
FT_Bool min = 0;
FT_Pos delta;
- if (!anchor)
+ if ( !anchor )
{
- edge->pos = (edge->opos+32) & -64;
+ edge->pos = ( edge->opos + 32 ) & -64;
anchor = edge;
}
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;
- if (edge > edges && edge->pos < edge[-1].pos)
+ if ( edge > edges && edge->pos < edge[-1].pos )
{
edge->pos = edge[-1].pos;
- min = 1;
+ min = 1;
}
ah_align_linked_edge( hinter, edge, edge2, dimension );
delta = 0;
- if ( edge2+1 < edge_limit &&
+ if ( edge2 + 1 < edge_limit &&
edge2[1].flags & ah_edge_done )
delta = edge2[1].pos - edge2->pos;
- if (delta < 0)
+ if ( delta < 0 )
{
edge2->pos += delta;
- if (!min)
+ if ( !min )
edge->pos += delta;
}
edge2->flags |= ah_edge_done;
@@ -328,35 +348,37 @@
}
}
- if (!has_serifs)
+ if ( !has_serifs )
goto Next_Dimension;
/* 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++ )
{
- if (edge->flags & ah_edge_done)
+ if ( edge->flags & ah_edge_done )
continue;
- if (edge->serif)
+ if ( edge->serif )
{
ah_align_serif_edge( hinter, edge->serif, edge );
}
- else if (!anchor)
+ else if ( !anchor )
{
- edge->pos = (edge->opos+32) & -64;
+ edge->pos = ( edge->opos + 32 ) & -64;
anchor = edge;
}
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;
- if (edge > edges && edge->pos < edge[-1].pos)
+ if ( edge > edges && edge->pos < edge[-1].pos )
edge->pos = edge[-1].pos;
- if ( edge+1 < edge_limit && edge[1].flags & ah_edge_done &&
- edge->pos > edge[1].pos)
+ if ( edge + 1 < edge_limit &&
+ edge[1].flags & ah_edge_done &&
+ edge->pos > edge[1].pos )
edge->pos = edge[1].pos;
}
@@ -364,15 +386,9 @@
edges = outline->vert_edges;
edge_limit = edges + outline->num_vedges;
}
-
}
-
-
-
-
-
LOCAL_FUNC
void ah_hinter_hint_edges( AH_Hinter* hinter,
int no_horz_edges,
@@ -381,19 +397,20 @@
disable_horz_edges = no_horz_edges;
disable_vert_edges = no_vert_edges;
- /* AH_Interpolate_Blue_Edges( hinter ); -- doesn't seem to help */
- /* reduce the problem of the disappearing eye in the "e" of Times */
- /* also, creates some artifacts near the blue zones ?? */
+ /* AH_Interpolate_Blue_Edges( hinter ); -- doesn't seem to help */
+ /* reduce the problem of the disappearing eye in the `e' of Times... */
+ /* also, creates some artifacts near the blue zones? */
{
ah_hint_edges_3( hinter );
- /* outline optimiser removed temporarily */
#if 0
- if (hinter->flags & ah_hinter_optimize)
+ /* outline optimizer removed temporarily */
+ if ( hinter->flags & ah_hinter_optimize )
{
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_Done( &opt );
@@ -400,22 +417,21 @@
}
}
#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
void ah_hinter_align_edge_points( AH_Hinter* hinter )
{
@@ -424,9 +440,10 @@
AH_Edge* edge_limit;
FT_Int dimension;
- edges = outline->horz_edges;
- edge_limit = edges + outline->num_hedges;
+ edges = outline->horz_edges;
+ edge_limit = edges + outline->num_hedges;
+
for ( dimension = 1; dimension >= 0; dimension-- )
{
AH_Edge* edge;
@@ -433,6 +450,7 @@
AH_Edge* before;
AH_Edge* after;
+
before = 0;
after = 0;
@@ -439,14 +457,19 @@
edge = edges;
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;
+
+
do
{
AH_Point* point = seg->first;
+
+
for (;;)
{
- if (dimension)
+ if ( dimension )
{
point->y = edge->pos;
point->flags |= ah_flah_touch_y;
@@ -456,7 +479,8 @@
point->x = edge->pos;
point->flags |= ah_flah_touch_x;
}
- if (point == seg->last)
+
+ if ( point == seg->last )
break;
point = point->next;
@@ -463,9 +487,10 @@
}
seg = seg->edge_next;
- }
- while (seg != edge->first);
+
+ } while ( seg != edge->first );
}
+
edges = outline->vert_edges;
edge_limit = edges + outline->num_vedges;
}
@@ -472,7 +497,7 @@
}
- /* hint the strong points - this is equivalent to the TrueType "IP" */
+ /* hint the strong points -- this is equivalent to the TrueType `IP' */
static
void ah_hinter_align_strong_points( AH_Hinter* hinter )
{
@@ -484,6 +509,7 @@
AH_Point* point_limit;
AH_Flags touch_flag;
+
points = outline->points;
point_limit = points + outline->num_points;
@@ -498,6 +524,7 @@
AH_Edge* before;
AH_Edge* after;
+
before = 0;
after = 0;
@@ -507,36 +534,45 @@
FT_Pos u, ou, fu; /* point position */
FT_Pos delta;
+
if ( point->flags & touch_flag )
continue;
#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 */
if ( point->flags & ah_flah_weak_interpolation )
continue;
#endif
- if (dimension) { u = point->fy; ou = point->oy; }
- else { u = point->fx; ou = point->ox; }
+ if ( dimension )
+ {
+ u = point->fy;
+ ou = point->oy;
+ }
+ else
+ {
+ u = point->fx;
+ ou = point->ox;
+ }
fu = u;
- /* is the point before the first edge ? */
+ /* is the point before the first edge? */
edge = edges;
delta = edge->fpos - u;
- if (delta >= 0)
+ if ( delta >= 0 )
{
- u = edge->pos - (edge->opos - ou);
+ u = edge->pos - ( edge->opos - ou );
goto Store_Point;
}
/* is the point after the last edge ? */
- edge = edge_limit-1;
+ edge = edge_limit - 1;
delta = u - edge->fpos;
if ( delta >= 0 )
{
- u = edge->pos + (ou - edge->opos);
+ u = edge->pos + ( ou - edge->opos );
goto Store_Point;
}
@@ -545,6 +581,7 @@
AH_Edge* before = 0;
AH_Edge* after = 0;
+
for ( edge = edges; edge < edge_limit; edge++ )
{
if ( u == edge->fpos )
@@ -557,7 +594,7 @@
before = edge;
}
- for ( edge = edge_limit-1; edge >= edges; edge-- )
+ for ( edge = edge_limit - 1; edge >= edges; edge-- )
{
if ( u == edge->fpos )
{
@@ -574,11 +611,14 @@
after->pos - before->pos,
after->fpos - before->fpos );
}
+
Store_Point:
/* save the point position */
- if (dimension) point->y = u;
- else point->x = u;
+ if ( dimension )
+ point->y = u;
+ else
+ point->x = u;
point->flags |= touch_flag;
}
@@ -591,6 +631,7 @@
#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
+
static
void ah_iup_shift( AH_Point* p1,
AH_Point* p2,
@@ -599,10 +640,11 @@
AH_Point* p;
FT_Pos delta = ref->u - ref->v;
+
for ( p = p1; p < ref; p++ )
p->u = p->v + delta;
- for ( p = ref+1; p <= p2; p++ )
+ for ( p = ref + 1; p <= p2; p++ )
p->u = p->v + delta;
}
@@ -620,16 +662,22 @@
FT_Pos d1 = ref1->u - v1;
FT_Pos d2 = ref2->u - v2;
- if (p1 > p2) return;
- if (v1 == v2)
+ if ( p1 > p2 )
+ return;
+
+ if ( v1 == v2 )
{
for ( p = p1; p <= p2; p++ )
{
FT_Pos u = p->v;
- if (u <= v1) u += d1;
- else u += d2;
+
+ if ( u <= v1 )
+ u += d1;
+ else
+ u += d2;
+
p->u = u;
}
return;
@@ -641,9 +689,12 @@
{
u = p->v;
- if (u <= v1) u += d1;
- else if (u >= v2) u += d2;
- else u = ref1->u+FT_MulDiv( u-v1, ref2->u-ref1->u, v2-v1 );
+ if ( u <= v1 )
+ u += d1;
+ else if ( u >= v2 )
+ u += d2;
+ else
+ u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
p->u = u;
}
@@ -653,16 +704,21 @@
for ( p = p1; p <= p2; p++ )
{
u = p->v;
- if (u <= v2) u += d2;
- else if (u >= v1) u += d1;
- else u = ref1->u+FT_MulDiv( u-v1, ref2->u-ref1->u, v2-v1 );
+ if ( u <= v2 )
+ u += d2;
+ else if ( u >= v1 )
+ u += d1;
+ else
+ u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
+
p->u = u;
}
}
}
- /* interpolate weak points - this is equivalent to the TrueType "IUP" */
+
+ /* interpolate weak points -- this is equivalent to the TrueType `IUP' */
static
void ah_hinter_align_weak_points( AH_Hinter* hinter )
{
@@ -675,10 +731,11 @@
AH_Point** contour_limit;
AH_Flags touch_flag;
+
points = outline->points;
point_limit = points + outline->num_points;
- /* PASS 1 : Move segment points to edge positions */
+ /* PASS 1: Move segment points to edge positions */
edges = outline->horz_edges;
edge_limit = edges + outline->num_hedges;
@@ -690,11 +747,12 @@
for ( dimension = 1; dimension >= 0; dimension-- )
{
- AH_Point* point;
- AH_Point* end_point;
- AH_Point* first_point;
- AH_Point** contour;
+ AH_Point* point;
+ AH_Point* end_point;
+ AH_Point* first_point;
+ AH_Point** contour;
+
point = points;
contour = outline->contours;
@@ -704,22 +762,23 @@
end_point = point->prev;
first_point = point;
- while (point <= end_point && !(point->flags & touch_flag))
+ while ( point <= end_point && !( point->flags & touch_flag ) )
point++;
- if (point <= end_point)
+ if ( point <= end_point )
{
AH_Point* first_touched = point;
AH_Point* cur_touched = point;
+
point++;
while ( point <= end_point )
{
- if (point->flags & touch_flag)
+ if ( point->flags & touch_flag )
{
- /* we found two succesive touched points, we interpolate */
- /* all contour points between them.. */
- ah_iup_interp( cur_touched+1, point-1,
+ /* we found two successive touched points; we interpolate */
+ /* all contour points between them */
+ ah_iup_interp( cur_touched + 1, point - 1,
cur_touched, point );
cur_touched = point;
}
@@ -726,23 +785,23 @@
point++;
}
- if (cur_touched == first_touched)
+ if ( cur_touched == first_touched )
{
/* this is a special case: only one point was touched in the */
- /* contour.. we thus simply shift the whole contour.. */
+ /* contour; we thus simply shift the whole contour */
ah_iup_shift( first_point, end_point, cur_touched );
}
else
{
/* now interpolate after the last touched point to the end */
- /* of the contour.. */
- ah_iup_interp( cur_touched+1, end_point,
+ /* of the contour */
+ ah_iup_interp( cur_touched + 1, end_point,
cur_touched, first_touched );
- /* if the first contour point isn't touched, interpolate */
- /* from the contour start to the first touched point */
- if (first_touched > points)
- ah_iup_interp( first_point, first_touched-1,
+ /* if the first contour point isn't touched, interpolate */
+ /* from the contour start to the first touched point */
+ if ( first_touched > points )
+ ah_iup_interp( first_point, first_touched - 1,
cur_touched, first_touched );
}
}
@@ -749,7 +808,7 @@
}
/* now save the interpolated values back to x/y */
- if (dimension)
+ if ( dimension )
{
for ( point = points; point < point_limit; point++ )
point->y = point->u;
@@ -766,8 +825,10 @@
}
}
}
-#endif
+#endif /* !AH_OPTION_NO_WEAK_INTERPOLATION */
+
+
LOCAL_FUNC
void ah_hinter_align_points( AH_Hinter* hinter )
{
@@ -783,17 +844,17 @@
}
- /**************************************************************************/
- /**************************************************************************/
- /**************************************************************************/
- /**** ****/
- /**** 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 */
static
void ah_hinter_scale_globals( AH_Hinter* hinter,
@@ -805,6 +866,7 @@
AH_Globals* design = &globals->design;
AH_Globals* scaled = &globals->scaled;
+
/* copy content */
*scaled = *design;
@@ -820,22 +882,28 @@
{
FT_Pos delta, delta2;
+
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 );
- if (delta2 < 32)
+ if ( delta2 < 32 )
delta2 = 0;
- else if (delta2 < 64)
- delta2 = 32 + (((delta2-32)+16) & -32);
+ else if ( delta2 < 64 )
+ delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & -32 );
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;
}
+
globals->x_scale = x_scale;
globals->y_scale = y_scale;
}
@@ -849,38 +917,42 @@
}
- /* finalise a hinter object */
+ /* finalize a hinter object */
void ah_hinter_done( AH_Hinter* hinter )
{
- if (hinter)
+ if ( hinter )
{
FT_Memory memory = hinter->memory;
+
ah_loader_done( hinter->loader );
ah_outline_done( hinter->glyph );
- /* note: the globals pointer is _not_ owned by the hinter */
- /* but by the current face object, we don't need to */
- /* release it.. */
+ /* note: the `globals' pointer is _not_ owned by the hinter */
+ /* but by the current face object, we don't need to */
+ /* release it */
hinter->globals = 0;
hinter->face = 0;
- FREE(hinter);
+ FREE( hinter );
}
}
- /* create a new empty hinter object */
- FT_Error ah_hinter_new( FT_Library library, AH_Hinter* *ahinter )
+ /* create a new empty hinter object */
+ FT_Error ah_hinter_new( FT_Library library,
+ AH_Hinter** ahinter )
{
AH_Hinter* hinter = 0;
FT_Memory memory = library->memory;
FT_Error error;
+
*ahinter = 0;
/* allocate object */
- if (ALLOC( hinter, sizeof(*hinter) )) goto Exit;
+ if ( ALLOC( hinter, sizeof ( *hinter ) ) )
+ goto Exit;
hinter->memory = memory;
hinter->flags = 0;
@@ -889,12 +961,13 @@
error = ah_outline_new( memory, &hinter->glyph ) ||
ah_loader_new ( memory, &hinter->loader ) ||
ah_loader_create_extra( hinter->loader );
- if (error) goto Exit;
+ if ( error )
+ goto Exit;
*ahinter = hinter;
Exit:
- if (error)
+ if ( error )
ah_hinter_done( hinter );
return error;
@@ -901,27 +974,30 @@
}
- /* create a face's autohint globals */
- FT_Error ah_hinter_new_face_globals( AH_Hinter* hinter,
- FT_Face face,
- AH_Globals* globals )
+ /* create a face's autohint globals */
+ FT_Error ah_hinter_new_face_globals( AH_Hinter* hinter,
+ FT_Face face,
+ AH_Globals* globals )
{
FT_Error error;
FT_Memory memory = hinter->memory;
AH_Face_Globals* face_globals;
- if ( ALLOC( face_globals, sizeof(*face_globals) ) )
+
+ if ( ALLOC( face_globals, sizeof ( *face_globals ) ) )
goto Exit;
hinter->face = face;
hinter->globals = face_globals;
- if (globals)
+
+ if ( globals )
face_globals->design = *globals;
else
ah_hinter_compute_globals( hinter );
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;
Exit:
@@ -929,357 +1005,381 @@
}
-
- /* discard a face's autohint globals */
+ /* discard a face's autohint globals */
void ah_hinter_done_face_globals( AH_Face_Globals* globals )
{
- FT_Face face = globals->face;
- FT_Memory memory = face->memory;
+ FT_Face face = globals->face;
+ FT_Memory memory = face->memory;
+
FREE( globals );
}
+ static
+ FT_Error ah_hinter_load( AH_Hinter* hinter,
+ FT_UInt glyph_index,
+ FT_UInt load_flags,
+ FT_UInt depth )
+ {
+ FT_Face face = hinter->face;
+ FT_GlyphSlot slot = face->glyph;
+ FT_Fixed x_scale = face->size->metrics.x_scale;
+ FT_Fixed y_scale = face->size->metrics.y_scale;
+ FT_Glyph_Metrics metrics; /* temporary metrics */
+ FT_Error error;
+ AH_Outline* outline = hinter->glyph;
+ AH_Loader* gloader = hinter->loader;
+ FT_Bool no_horz_hints =
+ ( load_flags & AH_HINT_NO_HORZ_EDGES ) != 0;
+ FT_Bool no_vert_hints =
+ ( load_flags & AH_HINT_NO_VERT_EDGES ) != 0;
- static
- FT_Error ah_hinter_load( AH_Hinter* hinter,
- FT_UInt glyph_index,
- FT_UInt load_flags,
- FT_UInt depth )
- {
- FT_Face face = hinter->face;
- FT_GlyphSlot slot = face->glyph;
- FT_Fixed x_scale = face->size->metrics.x_scale;
- FT_Fixed y_scale = face->size->metrics.y_scale;
- FT_Glyph_Metrics metrics; /* temporary metrics */
- FT_Error error;
- AH_Outline* outline = hinter->glyph;
- AH_Loader* gloader = hinter->loader;
- FT_Bool no_horz_hints = (load_flags & AH_HINT_NO_HORZ_EDGES) != 0;
- FT_Bool no_vert_hints = (load_flags & AH_HINT_NO_VERT_EDGES) != 0;
- /* load the glyph */
- error = FT_Load_Glyph( face, glyph_index, load_flags );
- if (error) goto Exit;
+ /* load the glyph */
+ error = FT_Load_Glyph( face, glyph_index, load_flags );
+ if ( error )
+ goto Exit;
- /* save current glyph metrics */
- metrics = slot->metrics;
+ /* save current glyph metrics */
+ metrics = slot->metrics;
- switch (slot->format)
- {
- case ft_glyph_format_outline:
- {
- /* first of all, copy the outline points in the loader's current */
- /* extra points, which is used to keep original glyph coordinates */
- error = ah_loader_check_points( gloader, slot->outline.n_points+2,
- slot->outline.n_contours );
- if (error) goto Exit;
+ switch ( slot->format )
+ {
+ case ft_glyph_format_outline:
+ /* first of all, copy the outline points in the loader's current */
+ /* extra points, which is used to keep original glyph coordinates */
+ error = ah_loader_check_points( gloader, slot->outline.n_points + 2,
+ slot->outline.n_contours );
+ if ( error )
+ goto Exit;
- MEM_Copy( gloader->current.extra_points, slot->outline.points,
- slot->outline.n_points * sizeof(FT_Vector) );
+ MEM_Copy( gloader->current.extra_points, slot->outline.points,
+ slot->outline.n_points * sizeof ( FT_Vector ) );
- MEM_Copy( gloader->current.outline.contours, slot->outline.contours,
- slot->outline.n_contours*sizeof(short) );
+ MEM_Copy( gloader->current.outline.contours, slot->outline.contours,
+ slot->outline.n_contours * sizeof ( short ) );
- MEM_Copy( gloader->current.outline.tags, slot->outline.tags,
- slot->outline.n_points * sizeof(char) );
+ MEM_Copy( gloader->current.outline.tags, slot->outline.tags,
+ slot->outline.n_points * sizeof ( char ) );
- gloader->current.outline.n_points = slot->outline.n_points;
- gloader->current.outline.n_contours = slot->outline.n_contours;
+ gloader->current.outline.n_points = slot->outline.n_points;
+ gloader->current.outline.n_contours = slot->outline.n_contours;
- /* compute original phantom points */
- hinter->pp1.x = 0;
- hinter->pp1.y = 0;
- hinter->pp2.x = FT_MulFix( slot->metrics.horiAdvance, x_scale );
- hinter->pp2.y = 0;
+ /* compute original phantom points */
+ hinter->pp1.x = 0;
+ hinter->pp1.y = 0;
+ hinter->pp2.x = FT_MulFix( slot->metrics.horiAdvance, x_scale );
+ hinter->pp2.y = 0;
- /* be sure to check for spacing glyphs */
- if (slot->outline.n_points == 0)
- goto Hint_Metrics;
+ /* be sure to check for spacing glyphs */
+ if ( slot->outline.n_points == 0 )
+ goto Hint_Metrics;
- /* now, load the slot image into the auto-outline, and run the */
- /* automatic hinting process.. */
- error = ah_outline_load( outline, face ); /* XXXX: change to slot */
- if (error) goto Exit;
+ /* now, load the slot image into the auto-outline, and run the */
+ /* automatic hinting process */
+ error = ah_outline_load( outline, face ); /* XXX: change to slot */
+ if ( error )
+ goto Exit;
- /* perform feature detection */
- ah_outline_detect_features( outline );
+ /* perform feature detection */
+ ah_outline_detect_features( outline );
- if ( !no_horz_hints )
- {
- ah_outline_compute_blue_edges( outline, hinter->globals );
- ah_outline_scale_blue_edges( outline, hinter->globals );
- }
+ if ( !no_horz_hints )
+ {
+ ah_outline_compute_blue_edges( outline, hinter->globals );
+ ah_outline_scale_blue_edges( outline, hinter->globals );
+ }
- /* perform alignment control */
- ah_hinter_hint_edges( hinter, no_horz_hints, no_vert_hints );
- ah_hinter_align( hinter );
+ /* perform alignment control */
+ ah_hinter_hint_edges( hinter, no_horz_hints, no_vert_hints );
+ ah_hinter_align( hinter );
- /* now save the current outline into the loader's current table */
- ah_outline_save( outline, gloader );
+ /* now save the current outline into the loader's current table */
+ ah_outline_save( outline, gloader );
- /* we now need to hint the metrics according to the change in */
- /* width/positioning that occured during the hinting process */
- {
- FT_Pos old_width, new_width;
- FT_Pos old_advance, new_advance;
- FT_Pos old_lsb, new_lsb;
- AH_Edge* edge1 = outline->vert_edges; /* left-most edge */
- AH_Edge* edge2 = edge1 + outline->num_vedges-1; /* right-mode edge */
+ /* we now need to hint the metrics according to the change in */
+ /* width/positioning that occured during the hinting process */
+ {
+ FT_Pos old_width, new_width;
+ FT_Pos old_advance, new_advance;
+ FT_Pos old_lsb, new_lsb;
+ AH_Edge* edge1 = outline->vert_edges; /* leftmost edge */
+ AH_Edge* edge2 = edge1 +
+ outline->num_vedges - 1; /* rightmost edge */
- old_width = edge2->opos - edge1->opos;
- new_width = edge2->pos - edge1->pos;
- old_advance = hinter->pp2.x;
- old_lsb = edge1->opos;
- new_lsb = edge1->pos;
+ old_width = edge2->opos - edge1->opos;
+ new_width = edge2->pos - edge1->pos;
- new_advance = old_advance + (new_width+new_lsb-old_width-old_lsb);
+ old_advance = hinter->pp2.x;
+ old_lsb = edge1->opos;
+ new_lsb = edge1->pos;
- hinter->pp1.x = ((new_lsb - old_lsb)+32) & -64;
- hinter->pp2.x = ((edge2->pos + (old_advance - edge2->opos))+32) & -64;
- }
+ new_advance = old_advance +
+ ( new_width + new_lsb - old_width - old_lsb );
- /* good, we simply add the glyph to our loader's base */
- ah_loader_add( gloader );
- }
- break;
+ hinter->pp1.x = ( ( new_lsb - old_lsb ) + 32 ) & -64;
+ hinter->pp2.x = ( ( edge2->pos +
+ ( old_advance - edge2->opos ) ) + 32 ) & -64;
+ }
- case ft_glyph_format_composite:
- {
- FT_UInt nn, num_subglyphs = slot->num_subglyphs;
- FT_UInt num_base_subgs, start_point, start_contour;
- FT_SubGlyph* subglyph;
+ /* good, we simply add the glyph to our loader's base */
+ ah_loader_add( gloader );
+ break;
- start_point = gloader->base.outline.n_points;
- start_contour = gloader->base.outline.n_contours;
+ case ft_glyph_format_composite:
+ {
+ FT_UInt nn, num_subglyphs = slot->num_subglyphs;
+ FT_UInt num_base_subgs, start_point, start_contour;
+ FT_SubGlyph* subglyph;
- /* first of all, copy the subglyph descriptors in the glyph loader */
- error = ah_loader_check_subglyphs( gloader, num_subglyphs );
- if (error) goto Exit;
- MEM_Copy( gloader->current.subglyphs, slot->subglyphs,
- num_subglyphs*sizeof(FT_SubGlyph) );
+ start_point = gloader->base.outline.n_points;
+ start_contour = gloader->base.outline.n_contours;
- gloader->current.num_subglyphs = num_subglyphs;
- num_base_subgs = gloader->base.num_subglyphs;
+ /* first of all, copy the subglyph descriptors in the glyph loader */
+ error = ah_loader_check_subglyphs( gloader, num_subglyphs );
+ if ( error )
+ goto Exit;
- /* now, read each subglyph independently */
- for ( nn = 0; nn < num_subglyphs; nn++ )
- {
- FT_Vector pp1, pp2;
- FT_Pos x, y;
- FT_UInt num_points, num_new_points, num_base_points;
+ MEM_Copy( gloader->current.subglyphs, slot->subglyphs,
+ num_subglyphs * sizeof ( FT_SubGlyph ) );
- /* gloader.current.subglyphs can change during glyph loading due */
- /* to re-allocation. We must recompute the current subglyph on */
- /* each iteration.. */
- subglyph = gloader->base.subglyphs + num_base_subgs + nn;
+ gloader->current.num_subglyphs = num_subglyphs;
+ num_base_subgs = gloader->base.num_subglyphs;
- pp1 = hinter->pp1;
- pp2 = hinter->pp2;
+ /* now, read each subglyph independently */
+ for ( nn = 0; nn < num_subglyphs; nn++ )
+ {
+ FT_Vector pp1, pp2;
+ FT_Pos x, y;
+ FT_UInt num_points, num_new_points, num_base_points;
- num_base_points = gloader->base.outline.n_points;
- error = ah_hinter_load( hinter, subglyph->index, load_flags, depth+1 );
- if ( error ) goto Exit;
+ /* gloader.current.subglyphs can change during glyph loading due */
+ /* to re-allocation -- we must recompute the current subglyph on */
+ /* each iteration */
+ subglyph = gloader->base.subglyphs + num_base_subgs + nn;
- /* recompute subglyph pointer */
- subglyph = gloader->base.subglyphs + num_base_subgs + nn;
+ pp1 = hinter->pp1;
+ pp2 = hinter->pp2;
- if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS )
- {
- pp1 = hinter->pp1;
- pp2 = hinter->pp2;
- }
- else
- {
- hinter->pp1 = pp1;
- hinter->pp2 = pp2;
- }
+ num_base_points = gloader->base.outline.n_points;
- num_points = gloader->base.outline.n_points;
- num_new_points = num_points - num_base_points;
+ error = ah_hinter_load( hinter, subglyph->index,
+ load_flags, depth + 1 );
+ if ( error )
+ goto Exit;
- /* now perform the transform required for this subglyph */
+ /* recompute subglyph pointer */
+ subglyph = gloader->base.subglyphs + num_base_subgs + nn;
- if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE |
- FT_SUBGLYPH_FLAG_XY_SCALE |
- FT_SUBGLYPH_FLAG_2X2 ) )
- {
- FT_Vector* cur = gloader->base.outline.points + num_base_points;
- FT_Vector* org = gloader->base.extra_points + num_base_points;
- FT_Vector* limit = cur + num_new_points;
+ if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS )
+ {
+ pp1 = hinter->pp1;
+ pp2 = hinter->pp2;
+ }
+ else
+ {
+ hinter->pp1 = pp1;
+ hinter->pp2 = pp2;
+ }
- for ( ; cur < limit; cur++, org++ )
- {
- FT_Vector_Transform( cur, &subglyph->transform );
- FT_Vector_Transform( org, &subglyph->transform );
- }
- }
+ num_points = gloader->base.outline.n_points;
+ num_new_points = num_points - num_base_points;
- /* apply offset */
+ /* now perform the transform required for this subglyph */
- if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) )
- {
- FT_Int k = subglyph->arg1;
- FT_UInt l = subglyph->arg2;
- FT_Vector* p1;
- FT_Vector* p2;
+ if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE |
+ FT_SUBGLYPH_FLAG_XY_SCALE |
+ FT_SUBGLYPH_FLAG_2X2 ) )
+ {
+ FT_Vector* cur = gloader->base.outline.points +
+ num_base_points;
+ FT_Vector* org = gloader->base.extra_points +
+ num_base_points;
+ FT_Vector* limit = cur + num_new_points;
- if ( start_point + k >= num_base_points ||
- l >= (FT_UInt)num_new_points )
- {
- error = FT_Err_Invalid_Composite;
- goto Exit;
- }
- l += num_base_points;
+ for ( ; cur < limit; cur++, org++ )
+ {
+ FT_Vector_Transform( cur, &subglyph->transform );
+ FT_Vector_Transform( org, &subglyph->transform );
+ }
+ }
- /* for now, only use the current point coordinates */
- /* we may consider another approach in the near future */
- p1 = gloader->base.outline.points + start_point + k;
- p2 = gloader->base.outline.points + start_point + l;
+ /* apply offset */
- x = p1->x - p2->x;
- y = p1->y - p2->y;
- }
- else
- {
- x = FT_MulFix( subglyph->arg1, x_scale );
- y = FT_MulFix( subglyph->arg2, y_scale );
+ if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) )
+ {
+ FT_Int k = subglyph->arg1;
+ FT_UInt l = subglyph->arg2;
+ FT_Vector* p1;
+ FT_Vector* p2;
- x = ( x + 32 ) & -64;
- y = ( y + 32 ) & -64;
- }
- {
- FT_Outline dummy = gloader->base.outline;
- dummy.points += num_base_points;
- dummy.n_points = num_new_points;
+ if ( start_point + k >= num_base_points ||
+ l >= (FT_UInt)num_new_points )
+ {
+ error = FT_Err_Invalid_Composite;
+ goto Exit;
+ }
- FT_Outline_Translate( &dummy, x, y );
- }
- }
- }
- break;
+ l += num_base_points;
- default:
- /* we don't support other formats (yet ?) */
- error = FT_Err_Unimplemented_Feature;
- }
+ /* for now, only use the current point coordinates */
+ /* we may consider another approach in the near future */
+ p1 = gloader->base.outline.points + start_point + k;
+ p2 = gloader->base.outline.points + start_point + l;
- Hint_Metrics:
- if (depth == 0)
- {
- FT_BBox bbox;
+ x = p1->x - p2->x;
+ y = p1->y - p2->y;
+ }
+ else
+ {
+ x = FT_MulFix( subglyph->arg1, x_scale );
+ y = FT_MulFix( subglyph->arg2, y_scale );
- /* we must translate our final outline by -pp1.x, and compute */
- /* the new metrics.. */
- if (hinter->pp1.x)
- FT_Outline_Translate( &gloader->base.outline, -hinter->pp1.x, 0 );
+ x = ( x + 32 ) & -64;
+ y = ( y + 32 ) & -64;
+ }
- FT_Outline_Get_CBox( &gloader->base.outline, &bbox );
- bbox.xMin &= -64;
- bbox.yMin &= -64;
- bbox.xMax = (bbox.xMax+63) & -64;
- bbox.yMax = (bbox.yMax+63) & -64;
+ {
+ FT_Outline dummy = gloader->base.outline;
- slot->metrics.width = (bbox.xMax - bbox.xMin);
- slot->metrics.height = (bbox.yMax - bbox.yMin);
- slot->metrics.horiBearingX = bbox.xMin;
- slot->metrics.horiBearingY = bbox.yMax;
- slot->metrics.horiAdvance = hinter->pp2.x - hinter->pp1.x;
- /* XXXX: TO DO - slot->linearHoriAdvance */
- /* now copy outline into glyph slot */
- ah_loader_rewind( slot->loader );
- error = ah_loader_copy_points( slot->loader, gloader );
- if (error) goto Exit;
+ dummy.points += num_base_points;
+ dummy.n_points = num_new_points;
- slot->outline = slot->loader->base.outline;
- slot->format = ft_glyph_format_outline;
- }
+ FT_Outline_Translate( &dummy, x, y );
+ }
+ }
+ }
+ break;
- Exit:
- return error;
- }
+ default:
+ /* we don't support other formats (yet?) */
+ error = FT_Err_Unimplemented_Feature;
+ }
+ Hint_Metrics:
+ if ( depth == 0 )
+ {
+ FT_BBox bbox;
- /* load and hint a given glyph */
- FT_Error ah_hinter_load_glyph( AH_Hinter* hinter,
- FT_GlyphSlot slot,
- FT_Size size,
- FT_UInt glyph_index,
- FT_Int load_flags )
- {
- FT_Face face = slot->face;
- FT_Error error;
- FT_Fixed x_scale = size->metrics.x_scale;
- FT_Fixed y_scale = size->metrics.y_scale;
- AH_Face_Globals* face_globals = FACE_GLOBALS(face);
- /* first of all, we need to check that we're using the correct face and */
- /* global hints to load the glyph */
- if ( hinter->face != face || hinter->globals != face_globals )
- {
- hinter->face = face;
- if (!face_globals)
- {
- error = ah_hinter_new_face_globals( hinter, face, 0 );
- if (error) goto Exit;
- }
- hinter->globals = FACE_GLOBALS(face);
- face_globals = FACE_GLOBALS(face);
- }
+ /* we must translate our final outline by -pp1.x, and compute */
+ /* the new metrics */
+ if ( hinter->pp1.x )
+ FT_Outline_Translate( &gloader->base.outline, -hinter->pp1.x, 0 );
- /* now, we must check the current character pixel size to see if we need */
- /* to rescale the global metrics.. */
- if ( face_globals->x_scale != x_scale ||
- face_globals->y_scale != y_scale )
- {
- ah_hinter_scale_globals( hinter, x_scale, y_scale );
- }
+ FT_Outline_Get_CBox( &gloader->base.outline, &bbox );
+ bbox.xMin &= -64;
+ bbox.yMin &= -64;
+ bbox.xMax = ( bbox.xMax + 63 ) & -64;
+ bbox.yMax = ( bbox.yMax + 63 ) & -64;
- load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE;
+ slot->metrics.width = bbox.xMax - bbox.xMin;
+ slot->metrics.height = bbox.yMax - bbox.yMin;
+ slot->metrics.horiBearingX = bbox.xMin;
+ slot->metrics.horiBearingY = bbox.yMax;
+ slot->metrics.horiAdvance = hinter->pp2.x - hinter->pp1.x;
+ /* XXX: TO DO - slot->linearHoriAdvance */
- ah_loader_rewind( hinter->loader );
+ /* now copy outline into glyph slot */
+ ah_loader_rewind( slot->loader );
+ error = ah_loader_copy_points( slot->loader, gloader );
+ if ( error )
+ goto Exit;
- error = ah_hinter_load( hinter, glyph_index, load_flags, 0 );
+ slot->outline = slot->loader->base.outline;
+ slot->format = ft_glyph_format_outline;
+ }
- Exit:
- return error;
- }
+ Exit:
+ return error;
+ }
- /* retrieve a face's autohint globals for client applications */
+ /* load and hint a given glyph */
+ FT_Error ah_hinter_load_glyph( AH_Hinter* hinter,
+ FT_GlyphSlot slot,
+ FT_Size size,
+ FT_UInt glyph_index,
+ FT_Int load_flags )
+ {
+ FT_Face face = slot->face;
+ FT_Error error;
+ FT_Fixed x_scale = size->metrics.x_scale;
+ FT_Fixed y_scale = size->metrics.y_scale;
+ AH_Face_Globals* face_globals = FACE_GLOBALS( face );
+
+
+ /* first of all, we need to check that we're using the correct face and */
+ /* global hints to load the glyph */
+ if ( hinter->face != face || hinter->globals != face_globals )
+ {
+ hinter->face = face;
+ if ( !face_globals )
+ {
+ error = ah_hinter_new_face_globals( hinter, face, 0 );
+ if ( error )
+ goto Exit;
+ }
+ hinter->globals = FACE_GLOBALS( face );
+ face_globals = FACE_GLOBALS( face );
+ }
+
+ /* now, we must check the current character pixel size to see if we */
+ /* need to rescale the global metrics */
+ if ( face_globals->x_scale != x_scale ||
+ face_globals->y_scale != y_scale )
+ ah_hinter_scale_globals( hinter, x_scale, y_scale );
+
+ load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE;
+
+ ah_loader_rewind( hinter->loader );
+
+ error = ah_hinter_load( hinter, glyph_index, load_flags, 0 );
+
+ Exit:
+ return error;
+ }
+
+
+ /* retrieve a face's autohint globals for client applications */
void ah_hinter_get_global_hints( AH_Hinter* hinter,
FT_Face face,
- void* *global_hints,
- long *global_len )
+ void** global_hints,
+ long* global_len )
{
AH_Globals* globals = 0;
FT_Memory memory = hinter->memory;
FT_Error error;
+
/* allocate new master globals */
- if (ALLOC( globals, sizeof(*globals)))
+ if ( ALLOC( globals, sizeof ( *globals ) ) )
goto Fail;
/* compute face globals if needed */
- if (!FACE_GLOBALS(face))
+ if ( !FACE_GLOBALS( face ) )
{
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_len = sizeof(*globals);
+ *global_len = sizeof( *globals );
+
return;
Fail:
FREE( globals );
+
*global_hints = 0;
*global_len = 0;
}
@@ -1288,8 +1388,11 @@
void ah_hinter_done_global_hints( AH_Hinter* hinter,
void* global_hints )
{
- FT_Memory memory = hinter->memory;
+ FT_Memory memory = hinter->memory;
+
+
FREE( global_hints );
}
+/* END */
--- a/src/autohint/ahhint.h
+++ b/src/autohint/ahhint.h
@@ -2,43 +2,49 @@
/* */
/* ahhint.h */
/* */
-/* Glyph hinter declarations */
+/* Glyph hinter (declaration). */
/* */
-/* Copyright 2000: Catharon Productions Inc. */
+/* Copyright 2000 Catharon Productions Inc. */
/* Author: David Turner */
/* */
/* This file is part of the Catharon Typography Project and shall only */
/* be used, modified, and distributed under the terms of the Catharon */
/* 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 */
/* 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
+
#include "ahglobal.h"
+
#else
+
#include <autohint/ahglobal.h>
+
#endif
-#define AH_HINT_DEFAULT 0
-#define AH_HINT_NO_ALIGNMENT 1
-#define AH_HINT_NO_HORZ_EDGES 0x20000
-#define AH_HINT_NO_VERT_EDGES 0x40000
+#define AH_HINT_DEFAULT 0
+#define AH_HINT_NO_ALIGNMENT 1
+#define AH_HINT_NO_HORZ_EDGES 0x20000L
+#define AH_HINT_NO_VERT_EDGES 0x40000L
- /* create a new empty hinter object */
- extern
- FT_Error ah_hinter_new( FT_Library library, AH_Hinter* *ahinter );
+ /* create a new empty hinter object */
+ FT_Error ah_hinter_new( FT_Library library,
+ AH_Hinter** ahinter );
- /* Load a hinted glyph in the hinter */
- extern
+ /* Load a hinted glyph in the hinter */
FT_Error ah_hinter_load_glyph( AH_Hinter* hinter,
FT_GlyphSlot slot,
FT_Size size,
@@ -45,21 +51,22 @@
FT_UInt glyph_index,
FT_Int load_flags );
- /* finalise a hinter object */
- extern
- void ah_hinter_done( AH_Hinter* hinter );
+ /* finalize a hinter object */
+ void ah_hinter_done( AH_Hinter* hinter );
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,
- FT_Face face,
- void* *global_hints,
- long *global_len );
+ void ah_hinter_get_global_hints( AH_Hinter* hinter,
+ FT_Face face,
+ void** global_hints,
+ long* global_len );
- extern
- void ah_hinter_done_global_hints( AH_Hinter* hinter,
- void* global_hints );
+ void ah_hinter_done_global_hints( AH_Hinter* hinter,
+ void* global_hints );
-#endif /* AGHINT_H */
+
+#endif /* AHHINT_H */
+
+
+/* END */
--- a/src/autohint/ahloader.h
+++ b/src/autohint/ahloader.h
@@ -2,44 +2,53 @@
/* */
/* ahloader.h */
/* */
-/* Glyph loader implementation for the auto-hinting module */
-/* This defines the AG_GlyphLoader type in two different ways: */
+/* Glyph loader for the auto-hinting module (declaration only). */
/* */
-/* - when the module is compiled within FreeType 2, the type */
-/* 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. */
+/* Copyright 2000 Catharon Productions Inc. */
/* Author: David Turner */
/* */
/* This file is part of the Catharon Typography Project and shall only */
/* be used, modified, and distributed under the terms of the Catharon */
/* 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 */
/* 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_
- typedef struct AH_GlyphLoad_
+ typedef struct AH_GlyphLoad_
{
- FT_Outline outline; /* outline */
- FT_UInt num_subglyphs; /* number of subglyphs */
- FT_SubGlyph* subglyphs; /* subglyphs */
- FT_Vector* extra_points; /* extra points table.. */
+ FT_Outline outline; /* outline */
+ FT_UInt num_subglyphs; /* number of subglyphs */
+ FT_SubGlyph* subglyphs; /* subglyphs */
+ FT_Vector* extra_points; /* extra points table */
} AH_GlyphLoad;
- struct AH_GlyphLoader_
+ struct AH_GlyphLoader_
{
FT_Memory memory;
FT_UInt max_points;
@@ -50,38 +59,47 @@
AH_GlyphLoad base;
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,
- AH_GlyphLoader* *aloader );
+ LOCAL_DEF
+ FT_Error AH_GlyphLoader_New( FT_Memory memory,
+ 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,
- FT_UInt n_points,
- FT_UInt n_contours );
+ LOCAL_DEF
+ FT_Error AH_GlyphLoader_Check_Points( AH_GlyphLoader* loader,
+ FT_UInt n_points,
+ FT_UInt n_contours );
- LOCAL_DEF FT_Error AH_GlyphLoader_Check_Subglyphs( AH_GlyphLoader* loader,
- FT_UInt n_subs );
+ LOCAL_DEF
+ FT_Error AH_GlyphLoader_Check_Subglyphs( AH_GlyphLoader* loader,
+ 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,
+ FT_GlyphLoader* source );
- LOCAL_DEF FT_Error AH_GlyphLoader_Copy_Points( AH_GlyphLoader* target,
- FT_GlyphLoader* source );
+#else /* _STANDALONE */
-#else
#include <freetype/internal/ftobjs.h>
#define AH_Load FT_GlyphLoad
@@ -98,6 +116,9 @@
#define ah_loader_add FT_GlyphLoader_Add
#define ah_loader_copy_points FT_GlyphLoader_Copy_Points
-#endif
+#endif /* _STANDALONE_ */
-#endif /* AGLOADER_H */
+#endif /* AHLOADER_H */
+
+
+/* END */
--- a/src/autohint/ahmodule.c
+++ b/src/autohint/ahmodule.c
@@ -2,34 +2,41 @@
/* */
/* ahmodule.c */
/* */
-/* Auto-hinting module implementation */
+/* Auto-hinting module implementation (declaration). */
/* */
-/* Copyright 2000: Catharon Productions Inc. */
+/* Copyright 2000 Catharon Productions Inc. */
/* Author: David Turner */
/* */
/* This file is part of the Catharon Typography Project and shall only */
/* be used, modified, and distributed under the terms of the Catharon */
/* 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 */
/* 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>
+
#ifdef FT_FLAT_COMPILE
+
#include "ahhint.h"
+
#else
+
#include <autohint/ahhint.h>
+
#endif
- typedef struct FT_AutoHinterRec_
+ typedef struct FT_AutoHinterRec_
{
- FT_ModuleRec root;
- AH_Hinter* hinter;
+ FT_ModuleRec root;
+ AH_Hinter* hinter;
} FT_AutoHinterRec;
@@ -40,37 +47,42 @@
return ah_hinter_new( module->root.library, &module->hinter );
}
+
static
- void ft_autohinter_done( FT_AutoHinter module )
+ void ft_autohinter_done( FT_AutoHinter module )
{
ah_hinter_done( module->hinter );
}
+
static
FT_Error ft_autohinter_load( FT_AutoHinter module,
FT_GlyphSlot slot,
- FT_Size size,
- FT_UInt glyph_index,
- FT_ULong load_flags )
+ FT_Size size,
+ FT_UInt glyph_index,
+ FT_ULong load_flags )
{
return ah_hinter_load_glyph( module->hinter,
slot, size, glyph_index, load_flags );
}
+
static
void ft_autohinter_reset( FT_AutoHinter module,
FT_Face face )
{
- UNUSED(module);
- if (face->autohint.data)
- ah_hinter_done_face_globals( face->autohint.data );
+ UNUSED( module );
+
+ if ( face->autohint.data )
+ ah_hinter_done_face_globals( (AH_Face_Globals*)(face->autohint.data) );
}
+
static
void ft_autohinter_get_globals( FT_AutoHinter module,
FT_Face face,
- void* *global_hints,
- long *global_len )
+ void** global_hints,
+ long* global_len )
{
ah_hinter_get_global_hints( module->hinter, face,
global_hints, global_len );
@@ -94,18 +106,22 @@
ft_autohinter_done_globals
};
+
const FT_Module_Class autohint_module_class =
{
ft_module_hinter,
- sizeof( FT_AutoHinterRec ),
+ sizeof ( FT_AutoHinterRec ),
"autohinter",
- 0x10000, /* version 1.0 of the autohinter */
- 0x20000, /* requires FreeType 2.0 or above */
+ 0x10000L, /* version 1.0 of the autohinter */
+ 0x20000L, /* requires FreeType 2.0 or above */
(const void*)&autohinter_interface,
- (FT_Module_Constructor) ft_autohinter_init,
- (FT_Module_Destructor) ft_autohinter_done,
- (FT_Module_Requester) 0
+ (FT_Module_Constructor)ft_autohinter_init,
+ (FT_Module_Destructor) ft_autohinter_done,
+ (FT_Module_Requester) 0
};
+
+
+/* END */
--- a/src/autohint/ahmodule.h
+++ b/src/autohint/ahmodule.h
@@ -2,26 +2,31 @@
/* */
/* ahmodule.h */
/* */
-/* Auto-hinting module declaration */
+/* Auto-hinting module (declaration). */
/* */
-/* Copyright 2000: Catharon Productions Inc. */
+/* Copyright 2000 Catharon Productions Inc. */
/* Author: David Turner */
/* */
/* This file is part of the Catharon Typography Project and shall only */
/* be used, modified, and distributed under the terms of the Catharon */
/* 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 */
/* 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
#define AHMODULE_H
#include <freetype/ftmodule.h>
- FT_EXPORT_VAR(const FT_Module_Class) autohint_module_class;
+ FT_EXPORT_VAR( const FT_Module_Class ) autohint_module_class;
#endif /* AHMODULE_H */
+
+
+/* END */
--- a/src/autohint/ahoptim.c
+++ b/src/autohint/ahoptim.c
@@ -1,71 +1,91 @@
/***************************************************************************/
/* */
-/* FreeType Auto-Gridder Outline Optimisation */
+/* ahoptim.c */
/* */
-/* 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.. */
+/* FreeType auto hinting outline optimization (body). */
/* */
-/* The technique used in this module is a simplified simulated annealing. */
-/* */
-/* */
-/* Copyright 2000: Catharon Productions Inc. */
+/* Copyright 2000 Catharon Productions Inc. */
/* Author: David Turner */
/* */
/* This file is part of the Catharon Typography Project and shall only */
/* be used, modified, and distributed under the terms of the Catharon */
/* 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 */
/* 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
+
#include "ahoptim.h"
+
#else
+
#include <autohint/ahoptim.h>
+
#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
-#ifdef DEBUG_OPTIM
-#define LOG(x) optim_log##x
+#ifdef AH_DEBUG_OPTIM
+
+#define LOG( x ) optim_log##x
+
#else
-#define LOG(x)
-#endif
-#ifdef DEBUG_OPTIM
+#define LOG( x )
+
+#endif /* AH_DEBUG_OPTIM */
+
+
+#ifdef AH_DEBUG_OPTIM
+
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
-#define FLOAT(x) ((float)((x)/64.0))
+#define FLOAT( x ) ( (float)( (x) / 64.0 ) )
-static
-void optim_log( const char* fmt, ... )
-{
- va_list ap;
+ static
+ void optim_log( const char* fmt, ... )
+ {
+ va_list ap;
- va_start( ap, fmt );
- vprintf( fmt, ap );
- va_end( ap );
-}
-#endif
+ va_start( ap, fmt );
+ vprintf( fmt, ap );
+ va_end( ap );
+ }
-#ifdef DEBUG_OPTIM
static
void AH_Dump_Stems( AH_Optimizer* optimizer )
{
@@ -72,18 +92,21 @@
int n;
AH_Stem* stem;
+
stem = optimizer->stems;
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,
- FLOAT(stem->edge1->opos), FLOAT(stem->edge2->opos),
- FLOAT(stem->edge1->pos), FLOAT(stem->edge2->pos),
- FLOAT(stem->min_pos), FLOAT(stem->max_pos),
- FLOAT(stem->force), FLOAT(stem->velocity) ));
+ FLOAT( stem->edge1->opos ), FLOAT( stem->edge2->opos ),
+ FLOAT( stem->edge1->pos ), FLOAT( stem->edge2->pos ),
+ FLOAT( stem->min_pos ), FLOAT( stem->max_pos ),
+ FLOAT( stem->force ), FLOAT( stem->velocity ) ));
}
}
+
static
void AH_Dump_Stems2( AH_Optimizer* optimizer )
{
@@ -90,17 +113,19 @@
int n;
AH_Stem* stem;
+
stem = optimizer->stems;
for ( n = 0; n < optimizer->num_stems; n++, stem++ )
{
LOG(( " %c%2d [%.1f]=<%1.f..%1.f> force=%.1f speed=%.1f\n",
optimizer->vertical ? 'V' : 'H', n,
- FLOAT(stem->pos),
- FLOAT(stem->min_pos), FLOAT(stem->max_pos),
- FLOAT(stem->force), FLOAT(stem->velocity) ));
+ FLOAT( stem->pos ),
+ FLOAT( stem->min_pos ), FLOAT( stem->max_pos ),
+ FLOAT( stem->force ), FLOAT( stem->velocity ) ));
}
}
+
static
void AH_Dump_Springs( AH_Optimizer* optimizer )
{
@@ -108,22 +133,27 @@
AH_Spring* spring;
AH_Stem* stems;
+
spring = optimizer->springs;
stems = optimizer->stems;
LOG(( "%cSprings ", optimizer->vertical ? 'V' : 'H' ));
+
for ( n = 0; n < optimizer->num_springs; n++, spring++ )
{
- LOG(( " [%d-%d:%.1f:%1.f:%.1f]", spring->stem1 - stems, spring->stem2 - stems,
- FLOAT(spring->owidth),
- FLOAT(spring->stem2->pos-(spring->stem1->pos+spring->stem1->width)),
- FLOAT(spring->tension) ));
+ LOG(( " [%d-%d:%.1f:%1.f:%.1f]",
+ spring->stem1 - stems, spring->stem2 - stems,
+ FLOAT( spring->owidth ),
+ FLOAT( spring->stem2->pos -
+ ( spring->stem1->pos + spring->stem1->width ) ),
+ FLOAT( spring->tension ) ));
}
LOG(( "\n" ));
}
-#endif
+#endif /* AH_DEBUG_OPTIM */
+
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
@@ -130,23 +160,27 @@
/**** ****/
/**** COMPUTE STEMS AND SPRINGS IN AN OUTLINE ****/
/**** ****/
- /**** ****/
- /**** ****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
+
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 &&
seg2->min_coord <= seg1->max_coord;
}
+
/* compute all stems in an outline */
static
- int optim_compute_stems( AH_Optimizer* optimizer )
+ int optim_compute_stems( AH_Optimizer* optimizer )
{
AH_Outline* outline = optimizer->outline;
FT_Fixed scale;
@@ -158,6 +192,7 @@
AH_Stem** p_stems;
FT_Int* p_num_stems;
+
edges = outline->horz_edges;
edge_limit = edges + outline->num_hedges;
scale = outline->y_scale;
@@ -171,25 +206,29 @@
FT_Int num_stems = 0;
AH_Edge* edge;
+
/* first of all, count the number of stems in this direction */
for ( edge = edges; edge < edge_limit; edge++ )
{
AH_Segment* seg = edge->first;
+
+
do
{
- if (valid_stem_segments( seg, seg->link ))
+ if (valid_stem_segments( seg, seg->link ) )
num_stems++;
seg = seg->edge_next;
- } while (seg != edge->first);
+ } while ( seg != edge->first );
}
/* now allocate the stems and build their table */
- if (num_stems > 0)
+ if ( num_stems > 0 )
{
AH_Stem* stem;
+
if ( ALLOC_ARRAY( stems, num_stems, AH_Stem ) )
goto Exit;
@@ -198,14 +237,17 @@
{
AH_Segment* seg = edge->first;
AH_Segment* seg2;
+
+
do
{
seg2 = seg->link;
- if (valid_stem_segments(seg,seg2))
+ if ( valid_stem_segments( seg, seg2 ) )
{
AH_Edge* edge1 = seg->edge;
AH_Edge* edge2 = seg2->edge;
+
stem->edge1 = edge1;
stem->edge2 = edge2;
stem->opos = edge1->opos;
@@ -218,10 +260,11 @@
FT_Pos min_coord = seg->min_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;
- if (seg2->max_coord < max_coord)
+ if ( seg2->max_coord < max_coord )
max_coord = seg2->max_coord;
stem->min_coord = min_coord;
@@ -228,39 +271,40 @@
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 */
- /* a fixed position.. */
- if (stem == stems || edge1->blue_edge || edge2->blue_edge)
+ /* a fixed position */
+ 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->max_pos = stem->pos;
}
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 pos2 = pos1 + stem->owidth - stem->width;
- FT_Pos min1 = (pos1 & -64);
- FT_Pos min2 = (pos2 & -64);
+ FT_Pos min1 = pos1 & -64;
+ FT_Pos min2 = pos2 & -64;
+
stem->min_pos = min1;
- stem->max_pos = min1+64;
- if (min2 < min1)
+ stem->max_pos = min1 + 64;
+ if ( min2 < min1 )
stem->min_pos = min2;
else
- stem->max_pos = min2+64;
+ stem->max_pos = min2 + 64;
- /* XXX : just to see what it does */
+ /* XXX: just to see what it does */
stem->max_pos += 64;
- /* just for the case where direct hinting did some incredible */
- /* things (e.g. blue edge shifts..) */
- if (stem->min_pos > stem->pos)
+ /* just for the case where direct hinting did some */
+ /* incredible things (e.g. blue edge shifts) */
+ if ( stem->min_pos > stem->pos )
stem->min_pos = stem->pos;
- if (stem->max_pos < stem->pos)
+ if ( stem->max_pos < stem->pos )
stem->max_pos = stem->pos;
}
@@ -270,8 +314,8 @@
stem++;
}
seg = seg->edge_next;
- }
- while (seg != edge->first);
+
+ } while ( seg != edge->first );
}
}
@@ -285,10 +329,13 @@
p_stems = &optimizer->vert_stems;
p_num_stems = &optimizer->num_vstems;
}
+
Exit:
- #ifdef DEBUG_OPTIM
- AH_Dump_Stems(optimizer);
- #endif
+
+#ifdef AH_DEBUG_OPTIM
+ AH_Dump_Stems( optimizer );
+#endif
+
return error;
}
@@ -295,7 +342,8 @@
/* returns the spring area between two stems, 0 if none */
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 area2 = stem2->max_coord - stem2->min_coord;
@@ -303,18 +351,19 @@
FT_Pos max = stem1->max_coord;
FT_Pos area;
+
/* order stems */
- if (stem2->opos <= stem1->opos + stem1->owidth)
+ if ( stem2->opos <= stem1->opos + stem1->owidth )
return 0;
- if (min < stem2->min_coord)
+ if ( min < stem2->min_coord )
min = stem2->min_coord;
- if (max < stem2->max_coord)
+ if ( max < stem2->max_coord )
max = stem2->max_coord;
- area = (max-min);
- if ( 2*area < area1 && 2*area < area2 )
+ area = ( max-min );
+ if ( 2 * area < area1 && 2 * area < area2 )
area = 0;
return area;
@@ -326,7 +375,7 @@
int optim_compute_springs( AH_Optimizer* optimizer )
{
/* basically, a spring exists between two stems if most of their */
- /* surface is aligned.. */
+ /* surface is aligned */
FT_Memory memory = optimizer->memory;
AH_Stem* stems;
@@ -338,6 +387,7 @@
FT_Int* p_num_springs;
AH_Spring** p_springs;
+
stems = optimizer->horz_stems;
stem_limit = stems + optimizer->num_hstems;
@@ -349,20 +399,24 @@
FT_Int num_springs = 0;
AH_Spring* springs = 0;
+
/* 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;
+
+
for ( stem2 = stem+1; stem2 < stem_limit; stem2++ )
- if (stem_spring_area(stem,stem2))
+ if ( stem_spring_area( stem, stem2 ) )
num_springs++;
}
/* then allocate and build the springs table */
- if (num_springs > 0)
+ if ( num_springs > 0 )
{
AH_Spring* spring;
+
/* allocate table of springs */
if ( ALLOC_ARRAY( springs, num_springs, AH_Spring ) )
goto Exit;
@@ -374,15 +428,16 @@
AH_Stem* stem2;
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);
- if (area)
+ area = stem_spring_area( stem, stem2 );
+ if ( area )
{
/* add a new spring here */
spring->stem1 = stem;
spring->stem2 = stem2;
- spring->owidth = stem2->opos - (stem->opos + stem->owidth);
+ spring->owidth = stem2->opos - ( stem->opos + stem->owidth );
spring->tension = 0;
spring++;
@@ -401,25 +456,27 @@
}
Exit:
- #ifdef DEBUG_OPTIM
- AH_Dump_Springs(optimizer);
- #endif
+
+#ifdef AH_DEBUG_OPTIM
+ AH_Dump_Springs( optimizer );
+#endif
+
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 */
static
void optim_compute_tensions( AH_Optimizer* optimizer )
@@ -426,6 +483,8 @@
{
AH_Spring* spring = optimizer->springs;
AH_Spring* limit = spring + optimizer->num_springs;
+
+
for ( ; spring < limit; spring++ )
{
AH_Stem* stem1 = spring->stem1;
@@ -436,49 +495,49 @@
FT_Pos tension;
FT_Pos sign;
- /* compute the tension, it simply is -K*(new_width-old_width) */
- width = stem2->pos - (stem1->pos + stem1->width);
- tension = width - spring->owidth;
+ /* compute the tension; it simply is -K*(new_width-old_width) */
+ width = stem2->pos - ( stem1->pos + stem1->width );
+ tension = width - spring->owidth;
+
sign = 1;
- if (tension < 0)
+ if ( tension < 0 )
{
sign = -1;
tension = -tension;
}
- if (width <= 0)
+ if ( width <= 0 )
tension = 32000;
else
- tension = (tension << 10)/width;
+ tension = ( tension << 10 ) / width;
- tension = -sign*FT_MulFix( tension, optimizer->tension_scale );
+ tension = -sign * FT_MulFix( tension, optimizer->tension_scale );
spring->tension = tension;
/* now, distribute tension among the englobing stems, if they */
- /* are able to move.. */
+ /* are able to move */
status = 0;
- if (stem1->pos <= stem1->min_pos)
+ if ( stem1->pos <= stem1->min_pos )
status |= 1;
- if (stem2->pos >= stem2->max_pos)
+ if ( stem2->pos >= stem2->max_pos )
status |= 2;
- if (!status)
+ if ( !status )
tension /= 2;
- if ((status & 1)== 0)
+ if ( ( status & 1 ) == 0 )
stem1->force -= tension;
- if ((status & 2)== 0)
+ if ( ( status & 2 ) == 0 )
stem2->force += tension;
}
}
-
- /* compute all stem movements - returns 0 if nothing moved */
+ /* compute all stem movements -- returns 0 if nothing moved */
static
- int optim_compute_stem_movements( AH_Optimizer* optimizer )
+ int optim_compute_stem_movements( AH_Optimizer* optimizer )
{
AH_Stem* stems = optimizer->stems;
AH_Stem* limit = stems + optimizer->num_stems;
@@ -485,63 +544,67 @@
AH_Stem* stem = stems;
int moved = 0;
+
/* set initial forces to velocity */
for ( stem = stems; stem < limit; stem++ )
{
stem->force = stem->velocity;
- stem->velocity /= 2; /* XXXX: Heuristics */
+ stem->velocity /= 2; /* XXX: Heuristics */
}
/* compute the sum of forces applied on each stem */
optim_compute_tensions( optimizer );
- #ifdef DEBUG_OPTIM
+
+#ifdef AH_DEBUG_OPTIM
AH_Dump_Springs( 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++ )
{
- if (stem->force > optimizer->tension_threshold)
+ if ( stem->force > optimizer->tension_threshold )
{
/* there is enough tension to move the stem to the right */
- if (stem->pos < stem->max_pos)
+ if ( stem->pos < stem->max_pos )
{
- stem->pos += 64;
- stem->velocity = stem->force/2;
- moved = 1;
+ stem->pos += 64;
+ stem->velocity = stem->force / 2;
+ moved = 1;
}
else
stem->velocity = 0;
}
- else if (stem->force < optimizer->tension_threshold)
+ else if ( stem->force < optimizer->tension_threshold )
{
/* there is enough tension to move the stem to the left */
- if (stem->pos > stem->min_pos)
+ if ( stem->pos > stem->min_pos )
{
- stem->pos -= 64;
- stem->velocity = stem->force/2;
- moved = 1;
+ stem->pos -= 64;
+ stem->velocity = stem->force / 2;
+ moved = 1;
}
else
stem->velocity = 0;
}
}
+
/* return 0 if nothing moved */
return moved;
}
-#endif /* BRUTE_FORCE */
+#endif /* AH_BRUTE_FORCE */
/* compute current global distortion from springs */
static
- FT_Pos optim_compute_distorsion( AH_Optimizer* optimizer )
+ FT_Pos optim_compute_distortion( AH_Optimizer* optimizer )
{
AH_Spring* spring = optimizer->springs;
AH_Spring* limit = spring + optimizer->num_springs;
- FT_Pos distorsion = 0;
+ FT_Pos distortion = 0;
+
for ( ; spring < limit; spring++ )
{
AH_Stem* stem1 = spring->stem1;
@@ -548,32 +611,34 @@
AH_Stem* stem2 = spring->stem2;
FT_Pos width;
- width = stem2->pos - (stem1->pos + stem1->width);
- width -= spring->owidth;
- if (width < 0)
+ width = stem2->pos - ( stem1->pos + stem1->width );
+ width -= spring->owidth;
+ if ( width < 0 )
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
void optim_record_configuration( AH_Optimizer* optimizer )
{
- FT_Pos distorsion;
+ FT_Pos distortion;
AH_Configuration* configs = optimizer->configs;
AH_Configuration* limit = configs + optimizer->num_configs;
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 */
- /* sorted history.. */
- if ( limit > configs && limit[-1].distorsion < distorsion )
+ /* sorted history */
+ if ( limit > configs && limit[-1].distortion < distortion )
{
LOG(( "ejected\n" ));
return;
@@ -583,13 +648,14 @@
{
int n;
+
config = limit;
- if (optimizer->num_configs < AH_MAX_CONFIGS)
+ if ( optimizer->num_configs < AH_MAX_CONFIGS )
optimizer->num_configs++;
else
config--;
- config->distorsion = distorsion;
+ config->distortion = distortion;
for ( n = 0; n < optimizer->num_stems; n++ )
config->positions[n] = optimizer->stems[n].pos;
@@ -596,33 +662,36 @@
}
/* move the current configuration towards the front of the list */
- /* when necessary, yes this is slow bubble sort ;-) */
- while ( config > configs && config[0].distorsion < config[-1].distorsion )
+ /* when necessary -- yes this is slow bubble sort ;-) */
+ while ( config > configs && config[0].distortion < config[-1].distortion )
{
AH_Configuration temp;
+
+
config--;
temp = config[0];
config[0] = config[1];
config[1] = temp;
}
- LOG(( "recorded !!\n" ));
+ LOG(( "recorded!\n" ));
}
-#ifdef BRUTE_FORCE
+#ifdef AH_BRUTE_FORCE
+
/* optimize outline in a single direction */
static
void optim_compute( AH_Optimizer* optimizer )
{
- int n;
- FT_Bool moved;
+ int n;
+ FT_Bool moved;
-
AH_Stem* stem = optimizer->stems;
AH_Stem* limit = stem + optimizer->num_stems;
+
/* empty, exit */
- if (stem >= limit)
+ if ( stem >= limit )
return;
optimizer->num_configs = 0;
@@ -634,13 +703,13 @@
do
{
/* record current configuration */
- optim_record_configuration(optimizer);
+ optim_record_configuration( optimizer );
/* now change configuration */
moved = 0;
for ( stem = optimizer->stems; stem < limit; stem++ )
{
- if (stem->pos < stem->max_pos)
+ if ( stem->pos < stem->max_pos )
{
stem->pos += 64;
moved = 1;
@@ -649,8 +718,7 @@
stem->pos = stem->min_pos;
}
- }
- while (moved);
+ } while ( moved );
/* now, set the best stem positions */
for ( n = 0; n < optimizer->num_stems; n++ )
@@ -658,6 +726,7 @@
AH_Stem* stem = optimizer->stems + n;
FT_Pos pos = optimizer->configs[0].positions[n];
+
stem->edge1->pos = pos;
stem->edge2->pos = pos + stem->width;
@@ -665,7 +734,9 @@
stem->edge2->flags |= ah_edge_done;
}
}
-#else
+
+#else /* AH_BRUTE_FORCE */
+
/* optimize outline in a single direction */
static
void optim_compute( AH_Optimizer* optimizer )
@@ -672,24 +743,27 @@
{
int n, counter, counter2;
+
optimizer->num_configs = 0;
optimizer->tension_scale = 0x80000L;
optimizer->tension_threshold = 64;
/* record initial configuration threshold */
- optim_record_configuration(optimizer);
+ optim_record_configuration( optimizer );
+
counter = 0;
for ( counter2 = optimizer->num_stems*8; counter2 >= 0; counter2-- )
{
- if (counter == 0)
- counter = 2*optimizer->num_stems;
+ if ( counter == 0 )
+ counter = 2 * optimizer->num_stems;
- if (!optim_compute_stem_movements( optimizer ))
+ if ( !optim_compute_stem_movements( optimizer ) )
break;
- optim_record_configuration(optimizer);
+ optim_record_configuration( optimizer );
+
counter--;
- if (counter == 0)
+ if ( counter == 0 )
optimizer->tension_scale /= 2;
}
@@ -699,6 +773,7 @@
AH_Stem* stem = optimizer->stems + n;
FT_Pos pos = optimizer->configs[0].positions[n];
+
stem->edge1->pos = pos;
stem->edge2->pos = pos + stem->width;
@@ -706,8 +781,10 @@
stem->edge2->flags |= ah_edge_done;
}
}
-#endif
+#endif /* AH_BRUTE_FORCE */
+
+
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
@@ -714,19 +791,19 @@
/**** ****/
/**** HIGH-LEVEL OPTIMIZER API ****/
/**** ****/
- /**** ****/
- /**** ****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
- /* releases the optimisation data */
+ /* releases the optimization data */
void AH_Optimizer_Done( AH_Optimizer* optimizer )
{
- if (optimizer)
+ if ( optimizer )
{
FT_Memory memory = optimizer->memory;
+
+
FREE( optimizer->horz_stems );
FREE( optimizer->vert_stems );
FREE( optimizer->horz_springs );
@@ -735,6 +812,7 @@
}
}
+
/* loads the outline into the optimizer */
int AH_Optimizer_Init( AH_Optimizer* optimizer,
AH_Outline* outline,
@@ -742,7 +820,8 @@
{
FT_Error error;
- MEM_Set( optimizer, 0, sizeof(*optimizer));
+
+ MEM_Set( optimizer, 0, sizeof ( *optimizer ) );
optimizer->outline = outline;
optimizer->memory = memory;
@@ -750,22 +829,26 @@
/* compute stems and springs */
error = optim_compute_stems ( optimizer ) ||
optim_compute_springs( optimizer );
- if (error) goto Fail;
+ if ( error )
+ goto Fail;
/* allocate stem positions history and configurations */
{
int n, max_stems;
+
max_stems = optimizer->num_hstems;
- if (max_stems < optimizer->num_vstems)
+ if ( 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;
optimizer->num_configs = 0;
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;
@@ -784,9 +867,9 @@
optimizer->num_springs = optimizer->num_hsprings;
optimizer->springs = optimizer->horz_springs;
- if (optimizer->num_springs > 0)
+ if ( optimizer->num_springs > 0 )
{
- LOG(( "horizontal optimisation ------------------------\n" ));
+ LOG(( "horizontal optimization ------------------------\n" ));
optim_compute( optimizer );
}
@@ -795,14 +878,12 @@
optimizer->num_springs = optimizer->num_vsprings;
optimizer->springs = optimizer->vert_springs;
- if (optimizer->num_springs)
+ if ( optimizer->num_springs )
{
- LOG(( "vertical optimisation --------------------------\n" ));
+ LOG(( "vertical optimization --------------------------\n" ));
optim_compute( optimizer );
}
}
-
-
-
+/* END */
--- a/src/autohint/ahoptim.h
+++ b/src/autohint/ahoptim.h
@@ -1,64 +1,68 @@
/***************************************************************************/
/* */
-/* FreeType Auto-Gridder Outline Optimisation */
+/* ahoptim.h */
/* */
-/* 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.. */
+/* FreeType auto hinting outline optimization (declaration). */
/* */
-/* The technique used in this module is a simplified simulated annealing. */
-/* */
-/* Copyright 2000: Catharon Productions Inc. */
+/* Copyright 2000 Catharon Productions Inc. */
/* Author: David Turner */
/* */
/* This file is part of the Catharon Typography Project and shall only */
/* be used, modified, and distributed under the terms of the Catharon */
/* 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 */
/* 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
+
#include "ahtypes.h"
+
#else
+
#include <autohint/ahtypes.h>
+
#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
- typedef struct AH_Stem_
+ typedef struct AH_Stem_
{
- FT_Pos pos; /* current position */
- FT_Pos velocity; /* current velocity */
- FT_Pos force; /* sum of current forces */
- FT_Pos width; /* normalized width */
+ FT_Pos pos; /* current position */
+ FT_Pos velocity; /* current velocity */
+ FT_Pos force; /* sum of current forces */
+ FT_Pos width; /* normalized width */
- FT_Pos min_pos; /* minimum grid position */
- FT_Pos max_pos; /* maximum grid position */
+ FT_Pos min_pos; /* minimum grid position */
+ FT_Pos max_pos; /* maximum grid position */
- AH_Edge* edge1; /* left/bottom edge */
- AH_Edge* edge2; /* right/top edge */
+ AH_Edge* edge1; /* left/bottom edge */
+ AH_Edge* edge2; /* right/top edge */
- FT_Pos opos; /* original position */
- FT_Pos owidth; /* original width */
+ FT_Pos opos; /* original position */
+ FT_Pos owidth; /* original width */
- FT_Pos min_coord; /* minimum coordinate */
- FT_Pos max_coord; /* maximum coordinate */
+ FT_Pos min_coord; /* minimum coordinate */
+ FT_Pos max_coord; /* maximum coordinate */
} AH_Stem;
/* A spring between two stems */
- typedef struct AH_Spring_
+ typedef struct AH_Spring_
{
AH_Stem* stem1;
AH_Stem* stem2;
@@ -69,69 +73,64 @@
/* 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_
{
FT_Pos* positions;
- FT_Long distorsion;
+ FT_Long distortion;
} AH_Configuration;
-
-
- typedef struct AH_Optimizer_
+ typedef struct AH_Optimizer_
{
- FT_Memory memory;
- AH_Outline* outline;
+ FT_Memory memory;
+ AH_Outline* outline;
- FT_Int num_hstems;
- AH_Stem* horz_stems;
+ FT_Int num_hstems;
+ AH_Stem* horz_stems;
- FT_Int num_vstems;
- AH_Stem* vert_stems;
+ FT_Int num_vstems;
+ AH_Stem* vert_stems;
- FT_Int num_hsprings;
- FT_Int num_vsprings;
- AH_Spring* horz_springs;
- AH_Spring* vert_springs;
+ FT_Int num_hsprings;
+ FT_Int num_vsprings;
+ AH_Spring* horz_springs;
+ AH_Spring* vert_springs;
FT_Int num_configs;
- AH_Configuration configs[ AH_MAX_CONFIGS ];
+ AH_Configuration configs[AH_MAX_CONFIGS];
FT_Pos* positions;
/* during each pass, use these instead */
- FT_Int num_stems;
- AH_Stem* stems;
+ FT_Int num_stems;
+ AH_Stem* stems;
- FT_Int num_springs;
- AH_Spring* springs;
- FT_Bool vertical;
+ FT_Int num_springs;
+ AH_Spring* springs;
+ FT_Bool vertical;
- FT_Fixed tension_scale;
- FT_Pos tension_threshold;
+ FT_Fixed tension_scale;
+ FT_Pos tension_threshold;
} AH_Optimizer;
/* loads the outline into the optimizer */
- extern
int AH_Optimizer_Init( AH_Optimizer* optimizer,
AH_Outline* outline,
FT_Memory memory );
-
/* compute optimal outline */
- extern
void AH_Optimizer_Compute( AH_Optimizer* optimizer );
+ /* release the optimization data */
+ void AH_Optimizer_Done( AH_Optimizer* optimizer );
- /* releases the optimisation data */
- extern
- void AH_Optimizer_Done( AH_Optimizer* optimizer );
+#endif /* AHOPTIM_H */
-#endif /* AGOPTIM_H */
+/* END */
--- a/src/autohint/ahtypes.h
+++ b/src/autohint/ahtypes.h
@@ -2,181 +2,216 @@
/* */
/* 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 */
/* */
/* This file is part of the Catharon Typography Project and shall only */
/* be used, modified, and distributed under the terms of the Catharon */
/* 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 */
/* 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
-#include "ahloader.h" /* glyph loader types & declarations */
+
+#include "ahloader.h"
+
#else
-#include <autohint/ahloader.h> /* glyph loader types & declarations */
+
+#include <autohint/ahloader.h>
+
#endif
-#define xxDEBUG_AG
-#ifdef DEBUG_AG
+#define xxAH_DEBUG
+
+
+#ifdef AH_DEBUG
+
#include <stdio.h>
-#define AH_LOG(x) printf##x
+
+#define AH_LOG( x ) printf##x
+
#else
-#define AH_LOG(x) /* nothing */
+
+#define AH_LOG( x ) do ; while ( 0 ) /* nothing */
+
#endif
-/***************************************************************************/
-/***************************************************************************/
-/***************************************************************************/
-/**** ****/
-/**** COMPILE-TIME BUILD OPTIONS ****/
-/**** ****/
-/**** Toggle these configuration macros to experiment with ****/
-/**** "features" of the auto-hinter.. ****/
-/**** ****/
-/***************************************************************************/
-/***************************************************************************/
-/***************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** COMPILE-TIME BUILD OPTIONS ****/
+ /**** ****/
+ /**** Toggle these configuration macros to experiment with `features' ****/
+ /**** 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.. */
-/* */
-#undef AH_OPTION_NO_WEAK_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 */
+ /*************************************************************************/
+ /* */
+ /* 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
+
+
+ /*************************************************************************/
+ /* */
+ /* 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
+
+
+ /*************************************************************************/
+ /* */
+ /* 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 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.. */
-/* */
-#undef AH_OPTION_NO_EXTREMUM_EDGES
-/* don't touch for now.. */
+ /*************************************************************************/
+ /* */
+ /* 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
+
+
+ /* don't touch for now */
#define AH_MAX_WIDTHS 12
#define AH_MAX_HEIGHTS 12
-/***************************************************************************/
-/***************************************************************************/
-/***************************************************************************/
-/**** ****/
-/**** TYPES DEFINITIONS ****/
-/**** ****/
-/***************************************************************************/
-/***************************************************************************/
-/***************************************************************************/
- /* see agangles.h */
- typedef FT_Int AH_Angle;
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** TYPE DEFINITIONS ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
- /* hint flags */
- typedef enum AH_Flags_
- {
- ah_flah_none = 0,
+ /* see agangles.h */
+ typedef FT_Int AH_Angle;
- /* bezier control points flags */
- ah_flah_conic = 1,
- ah_flah_cubic = 2,
- ah_flah_control = ah_flah_conic | ah_flah_cubic,
- /* extrema flags */
- ah_flah_extrema_x = 4,
- ah_flah_extrema_y = 8,
+ /* hint flags */
+#define ah_flah_none 0
- /* roundness */
- ah_flah_round_x = 16,
- ah_flah_round_y = 32,
+ /* bezier control points flags */
+#define ah_flah_conic 1
+#define ah_flah_cubic 2
+#define ah_flah_control ( ah_flah_conic | ah_flah_cubic )
- /* touched */
- ah_flah_touch_x = 64,
- ah_flah_touch_y = 128,
+ /* extrema flags */
+#define ah_flah_extrema_x 4
+#define ah_flah_extrema_y 8
- /* weak interpolation */
- ah_flah_weak_interpolation = 256,
+ /* roundness */
+#define ah_flah_round_x 16
+#define ah_flah_round_y 32
- /* never remove this one !! */
- ah_flah_max
+ /* touched */
+#define ah_flah_touch_x 64
+#define ah_flah_touch_y 128
- } AH_Flags;
+ /* weak interpolation */
+#define ah_flah_weak_interpolation 256
+ typedef FT_Int AH_Flags;
- /* edge hint flags */
- typedef enum AH_Edge_Flags_
- {
- ah_edge_normal = 0,
- ah_edge_round = 1,
- ah_edge_serif = 2,
- ah_edge_done = 4
- } AH_Edge_Flags;
+ /* edge hint flags */
+#define ah_edge_normal 0
+#define ah_edge_round 1
+#define ah_edge_serif 2
+#define ah_edge_done 4
+ typedef FT_Int AH_Edge_Flags;
- /* hint directions - the values are computed so that two vectors are */
- /* in opposite directions iff "dir1+dir2 == 0" */
- typedef enum AH_Direction_
- {
- ah_dir_none = 4,
- ah_dir_right = 1,
- ah_dir_left = -1,
- ah_dir_up_and_down = 0,
- ah_dir_left_and_right = 0,
- ah_dir_up = 2,
- ah_dir_down = -2
- } AH_Direction;
+ /* hint directions -- the values are computed so that two vectors are */
+ /* in opposite directions iff `dir1+dir2 == 0' */
+#define ah_dir_none 4
+#define ah_dir_right 1
+#define ah_dir_left -1
+#define ah_dir_up 2
+#define ah_dir_down -2
+ typedef FT_Int AH_Direction;
+
typedef struct AH_Point AH_Point;
typedef struct AH_Segment AH_Segment;
typedef struct AH_Edge AH_Edge;
- /***************************************************************************
- *
- * <Struct>
- * AH_Point
- *
- * <Description>
- * A structure used to model an outline point to the AH_Outline type
- *
- * <Fields>
- * flags :: current point hint flags
- * ox, oy :: current original scaled coordinates
- * fx, fy :: current coordinates in font units
- * x, y :: current hinter coordinates
- * u, v :: point coordinates - meaning varies with context
- *
- * in_dir :: direction of inwards vector (prev->point)
- * out_dir :: direction of outwards vector (point->next)
- *
- * in_angle :: angle of inwards vector
- * out_angle :: angle of outwards vector
- *
- * next :: next point in same contour
- * prev :: previous point in same contour
- *
- */
+
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* AH_Point */
+ /* */
+ /* <Description> */
+ /* A structure used to model an outline point to the AH_Outline type. */
+ /* */
+ /* <Fields> */
+ /* flags :: The current point hint flags. */
+ /* */
+ /* ox, oy :: The current original scaled coordinates. */
+ /* */
+ /* fx, fy :: The current coordinates in font units. */
+ /* */
+ /* x, y :: The current hinter coordinates. */
+ /* */
+ /* u, v :: Point coordinates -- meaning varies with context. */
+ /* */
+ /* in_dir :: The direction of the inwards vector (prev->point). */
+ /* */
+ /* 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
{
- AH_Flags flags; /* point flags used by hinter */
+ AH_Flags flags; /* point flags used by hinter */
FT_Pos ox, oy;
FT_Pos fx, fy;
FT_Pos x, y;
@@ -188,226 +223,239 @@
AH_Angle in_angle;
AH_Angle out_angle;
- AH_Point* next; /* next point in contour */
- AH_Point* prev; /* previous point in contour */
+ AH_Point* next; /* next point in contour */
+ AH_Point* prev; /* previous point in contour */
};
- /***************************************************************************
- *
- * <Struct>
- * AH_Segment
- *
- * <Description>
- * a structure used to describe an edge segment to the auto-hinter. A
- * segment is simply a sequence of successive points located on the same
- * horizontal or vertical "position", in a given direction.
- *
- * <Fields>
- * flags :: segment edge flags ( straight, rounded.. )
- * dir :: segment direction
- *
- * first :: first point in segment
- * last :: last point in segment
- * contour :: ptr to first point of segment's contour
- *
- * pos :: segment position in font units
- * size :: segment size
- *
- * edge :: edge of current segment
- * edge_next :: next segment on 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 */
+ /* */
+ /* <Description> */
+ /* A structure used to describe an edge segment to the auto-hinter. */
+ /* A segment is simply a sequence of successive points located on the */
+ /* same horizontal or vertical `position', in a given direction. */
+ /* */
+ /* <Fields> */
+ /* flags :: The segment edge flags (straight, rounded, etc.). */
+ /* */
+ /* dir :: The segment direction. */
+ /* */
+ /* first :: The first point in the segment. */
+ /* */
+ /* last :: The last point in the segment. */
+ /* */
+ /* contour :: A pointer to the first point of the segment's */
+ /* contour. */
+ /* */
+ /* pos :: The segment position in font units. */
+ /* */
+ /* size :: The segment size. */
+ /* */
+ /* edge :: The edge of the current segment. */
+ /* */
+ /* 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
{
AH_Edge_Flags flags;
AH_Direction dir;
- AH_Point* first; /* first point in edge segment */
- AH_Point* last; /* last point in edge segment */
- AH_Point** contour; /* ptr to first point of segment's contour */
+ AH_Point* first; /* first point in edge segment */
+ AH_Point* last; /* last point in edge segment */
+ AH_Point** contour; /* ptr to first point of segment's contour */
- FT_Pos pos; /* position of segment */
- FT_Pos min_coord; /* minimum coordinate of segment */
- FT_Pos max_coord; /* maximum coordinate of segment */
+ FT_Pos pos; /* position of segment */
+ FT_Pos min_coord; /* minimum coordinate of segment */
+ FT_Pos max_coord; /* maximum coordinate of segment */
AH_Edge* edge;
AH_Segment* edge_next;
- AH_Segment* link; /* link segment */
- AH_Segment* serif; /* primary segment for serifs */
- FT_Pos num_linked; /* number of linked segments */
+ AH_Segment* link; /* link segment */
+ AH_Segment* serif; /* primary segment for serifs */
+ FT_Pos num_linked; /* number of linked segments */
FT_Int score;
};
- /***************************************************************************
- *
- * <Struct>
- * AH_Edge
- *
- * <Description>
- * a structure used to describe an edge, which really is a horizontal
- * or vertical coordinate which will be hinted depending on the segments
- * located on it..
- *
- * <Fields>
- * flags :: segment edge flags ( straight, rounded.. )
- * dir :: main segment direction on this edge
- *
- * first :: first edge segment
- * last :: last edge segment
- *
- * fpos :: original edge position in font units
- * opos :: original scaled edge position
- * pos :: hinted edge position
- *
- * link :: the linked edge
- * serif :: the serif edge
- * 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 */
+ /* */
+ /* <Description> */
+ /* A structure used to describe an edge, which really is a horizontal */
+ /* or vertical coordinate to be hinted depending on the segments */
+ /* located on it. */
+ /* */
+ /* <Fields> */
+ /* flags :: The segment edge flags (straight, rounded, etc.). */
+ /* */
+ /* dir :: The main segment direction on this edge. */
+ /* */
+ /* first :: The first edge segment. */
+ /* */
+ /* last :: The last edge segment. */
+ /* */
+ /* fpos :: The original edge position in font units. */
+ /* */
+ /* opos :: The original scaled edge position. */
+ /* */
+ /* pos :: The hinted edge position. */
+ /* */
+ /* link :: The linked edge. */
+ /* */
+ /* serif :: The serif edge. */
+ /* */
+ /* 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
{
- AH_Edge_Flags flags;
- AH_Direction dir;
+ AH_Edge_Flags flags;
+ AH_Direction dir;
- AH_Segment* first;
- AH_Segment* last;
+ AH_Segment* first;
+ AH_Segment* last;
- FT_Pos fpos;
- FT_Pos opos;
- FT_Pos pos;
+ FT_Pos fpos;
+ FT_Pos opos;
+ FT_Pos pos;
- AH_Edge* link;
- AH_Edge* serif;
- FT_Int num_linked;
+ AH_Edge* link;
+ AH_Edge* serif;
+ FT_Int num_linked;
- FT_Int score;
- FT_Pos* blue_edge;
+ FT_Int score;
+ FT_Pos* blue_edge;
};
- /* an outline as seen by the hinter */
- typedef struct AH_Outline_
+ /* an outline as seen by the hinter */
+ typedef struct AH_Outline_
{
- FT_Memory memory;
+ FT_Memory memory;
- AH_Direction vert_major_dir; /* vertical major direction */
- AH_Direction horz_major_dir; /* horizontal major direction */
+ AH_Direction vert_major_dir; /* vertical major direction */
+ AH_Direction horz_major_dir; /* horizontal major direction */
- FT_Fixed x_scale;
- FT_Fixed y_scale;
- FT_Pos edge_distance_threshold;
+ FT_Fixed x_scale;
+ FT_Fixed y_scale;
+ FT_Pos edge_distance_threshold;
- FT_Int max_points;
- FT_Int num_points;
- AH_Point* points;
+ FT_Int max_points;
+ FT_Int num_points;
+ AH_Point* points;
- FT_Int max_contours;
- FT_Int num_contours;
- AH_Point** contours;
+ FT_Int max_contours;
+ FT_Int num_contours;
+ AH_Point** contours;
- FT_Int num_hedges;
- AH_Edge* horz_edges;
+ FT_Int num_hedges;
+ AH_Edge* horz_edges;
- FT_Int num_vedges;
- AH_Edge* vert_edges;
+ FT_Int num_vedges;
+ AH_Edge* vert_edges;
- FT_Int num_hsegments;
- AH_Segment* horz_segments;
+ FT_Int num_hsegments;
+ AH_Segment* horz_segments;
- FT_Int num_vsegments;
- AH_Segment* vert_segments;
+ FT_Int num_vsegments;
+ AH_Segment* vert_segments;
} 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_
- {
- 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 */
+ typedef FT_Int AH_Blue;
- ah_blue_max
- } AH_Blue;
+#define ah_hinter_monochrome 1
+#define ah_hinter_optimize 2
- typedef enum
- {
- ah_hinter_monochrome = 1,
- ah_hinter_optimize = 2
+ typedef FT_Int AH_Hinter_Flags;
- } 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 :: 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
- *
- ************************************************************************/
-
+ /*************************************************************************/
+ /* */
+ /* <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_
{
FT_Int num_widths;
FT_Int num_heights;
- FT_Pos widths [ AH_MAX_WIDTHS ];
- FT_Pos heights[ AH_MAX_HEIGHTS ];
+ FT_Pos widths [AH_MAX_WIDTHS];
+ FT_Pos heights[AH_MAX_HEIGHTS];
- FT_Pos blue_refs [ ah_blue_max ];
- FT_Pos blue_shoots[ ah_blue_max ];
+ FT_Pos blue_refs [ah_blue_max];
+ FT_Pos blue_shoots[ah_blue_max];
} AH_Globals;
- /************************************************************************
- *
- * <Struct>
- * AH_Face_Globals
- *
- * <Description>
- * Holds the complete global metrics for a given font face (i.e. the
- * design units version + a scaled version + the current scales used)
- *
- * <Fields>
- * face :: handle to source face object
- * design :: globals in font design units
- * scaled :: scaled globals in sub-pixel values
- * x_scale :: current horizontal scale
- * y_scale :: current vertical scale
- *
- ************************************************************************/
-
- typedef struct AH_Face_Globals_
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+ /* AH_Face_Globals */
+ /* */
+ /* <Description> */
+ /* Holds the complete global metrics for a given font face (i.e., the */
+ /* design units version + a scaled version + the current scales */
+ /* used). */
+ /* */
+ /* <Fields> */
+ /* face :: A handle to the source face object */
+ /* */
+ /* design :: The globals in font design units. */
+ /* */
+ /* scaled :: Scaled globals in sub-pixel values. */
+ /* */
+ /* x_scale :: The current horizontal scale. */
+ /* */
+ /* y_scale :: The current vertical scale. */
+ /* */
+ typedef struct AH_Face_Globals_
{
FT_Face face;
AH_Globals design;
@@ -419,12 +467,10 @@
} AH_Face_Globals;
-
-
- typedef struct AH_Hinter
+ typedef struct AH_Hinter
{
FT_Memory memory;
- FT_Long flags;
+ AH_Hinter_Flags flags;
FT_Int algorithm;
FT_Face face;
@@ -439,4 +485,8 @@
} AH_Hinter;
-#endif /* AGTYPES_H */
+
+#endif /* AHTYPES_H */
+
+
+/* END */
--- a/src/autohint/autohint.c
+++ b/src/autohint/autohint.c
@@ -2,22 +2,23 @@
/* */
/* autohint.c */
/* */
-/* Automatic Hinting wrapper. */
+/* Automatic Hinting wrapper (body only). */
/* */
-/* Copyright 2000: Catharon Productions Inc. */
+/* Copyright 2000 Catharon Productions Inc. */
/* Author: David Turner */
/* */
/* This file is part of the Catharon Typography Project and shall only */
/* be used, modified, and distributed under the terms of the Catharon */
/* 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 */
/* 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
#ifdef FT_FLAT_COMPILE
@@ -38,3 +39,5 @@
#endif
+
+/* END */
--- a/src/autohint/mather.py
+++ b/src/autohint/mather.py
@@ -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
ag_pi = 256
@@ -5,50 +23,56 @@
def print_arctan( atan_bits ):
atan_base = 1 << atan_bits
- print "static AH_Angle ag_arctan[ 1L << AG_ATAN_BITS ] ="
- print "{"
+ print " static AH_Angle ag_arctan[1L << AG_ATAN_BITS] ="
+ print " {"
count = 0
- line = ""
+ line = " "
- for n in range(atan_base):
+ for n in range( atan_base ):
comma = ","
- if (n == atan_base-1):
+ if ( n == atan_base - 1 ):
comma = ""
- angle = math.atan(n*1.0/atan_base)/math.pi*ag_pi
- line = line + " " + repr(int(angle+0.5)) + comma
- count = count+1;
- if (count == 8):
+ angle = math.atan( n * 1.0 / atan_base ) / math.pi * ag_pi
+ line = line + " " + repr( int( angle + 0.5 ) ) + comma
+ count = count + 1;
+ if ( count == 8 ):
count = 0
print line
- line = ""
+ line = " "
- if (count >0):
+ if ( count > 0 ):
print line
- print "};"
+ print " };"
+# This routine is not used currently.
+#
def print_sines():
- print "static FT_Fixed ah_sines[ AG_HALF_PI+1 ] ="
- print "{"
+ print " static FT_Fixed ah_sines[AG_HALF_PI + 1] ="
+ print " {"
+
count = 0
- line = ""
+ line = " "
- for n in range(ag_pi/2):
- sinus = math.sin(n*math.pi/ag_pi)
- line = line + " " + repr(int(65536.0*sinus)) + ","
- count = count+1
- if (count == 8):
+ for n in range( ag_pi / 2 ):
+ sinus = math.sin( n * math.pi / ag_pi )
+ line = line + " " + repr( int( 65536.0 * sinus ) ) + ","
+ count = count + 1
+ if ( count == 8 ):
count = 0
print line
- line = ""
+ line = " "
- if (count > 0):
+ if ( count > 0 ):
print line
- print " 65536"
- print "};"
+ print " 65536"
+ print " };"
-print_arctan(8)
+
+print_arctan( 8 )
+
+# END
--- a/src/autohint/rules.mk
+++ b/src/autohint/rules.mk
@@ -3,28 +3,17 @@
#
+# Copyright 2000 Catharon Productions Inc.
+# Author: David Turner
#
-# Copyright 2000: Catharon Productions Inc.
-# Author: David Turner
+# This file is part of the Catharon Typography Project and shall only
+# be used, modified, and distributed under the terms of the Catharon
+# Open Source License that should come with this file under the name
+# `CatharonLicense.txt'. By continuing to use, modify, or distribute
+# this file you indicate that you have read the license and
+# understand and accept it fully.
#
-# This file is part of the Catharon Typography Project and shall only
-# be used, modified, and distributed under the terms of the Catharon
-# Open Source License that should come with this file under the name
-# "CatharonLicense.txt". By continuing to use, modify, or distribute
-# this file you indicate that you have read the license and
-# understand and accept it fully.
-#
-# 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.
+# Note that this license is compatible with the FreeType license.
# AUTO driver directory
@@ -48,7 +37,9 @@
# 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)
--- a/src/type1/rules.mk
+++ b/src/type1/rules.mk
@@ -70,4 +70,5 @@
DRV_OBJS_S += $(T1_DRV_OBJ_S)
DRV_OBJS_M += $(T1_DRV_OBJ_M)
+
# EOF