summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Turner <david@freetype.org>2001-05-14 14:04:23 +0000
committerDavid Turner <david@freetype.org>2001-05-14 14:04:23 +0000
commit8e86015f3955e3acc038b3f24a764da7fe76a394 (patch)
tree727c07cf713e665e8d0f2b687d8fe2d56bd899cc
parentfdab085e253c2bfcad235d192cdb2d7b8f3f4cb2 (diff)
downloadfreetype2-8e86015f3955e3acc038b3f24a764da7fe76a394.tar.gz
* src/base/ftcalc.c (FT_DivFix): fixed a bug in the 64-bit code that
created incorrect scale factors !! * src/autohint/ahglobal.c, src/autohint/ahglyph.c, src/autohint/ahhint.c: fixed the incorrect blue zone computations, and improved the composite support. Note that these changes result in improved rendering, while sometimes introducing their own artefacts. That's probably the last big change to the autohinter before the introduction of its complete replacement..
-rw-r--r--ChangeLog12
-rw-r--r--src/autohint/ahglobal.c2
-rw-r--r--src/autohint/ahglyph.c264
-rw-r--r--src/autohint/ahhint.c10
-rw-r--r--src/base/ftcalc.c17
5 files changed, 168 insertions, 137 deletions
diff --git a/ChangeLog b/ChangeLog
index e7abe8b62..e499c511c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2001-05-14 David Turner <david@freetype.org>
+
+ * src/base/ftcalc.c (FT_DivFix): fixed a bug in the 64-bit code that
+ created incorrect scale factors !!
+
+ * src/autohint/ahglobal.c, src/autohint/ahglyph.c, src/autohint/ahhint.c:
+ fixed the incorrect blue zone computations, and improved the composite
+ support. Note that these changes result in improved rendering, while
+ sometimes introducing their own artefacts. That's probably the last
+ big change to the autohinter before the introduction of its complete
+ replacement..
+
2001-05-12 Werner Lemberg <wl@gnu.org>
* include/freetype/ftbbox.h: FTBBOX_H -> __FTBBOX_H__.
diff --git a/src/autohint/ahglobal.c b/src/autohint/ahglobal.c
index 68f68c40a..f2ebc6edb 100644
--- a/src/autohint/ahglobal.c
+++ b/src/autohint/ahglobal.c
@@ -47,7 +47,7 @@
for ( i = 1; i < count; i++ )
{
- for ( j = i; j > 1; j-- )
+ for ( j = i; j > 0; j-- )
{
if ( table[j] > table[j - 1] )
break;
diff --git a/src/autohint/ahglyph.c b/src/autohint/ahglyph.c
index 252572dfc..6656ba48b 100644
--- a/src/autohint/ahglyph.c
+++ b/src/autohint/ahglyph.c
@@ -28,7 +28,109 @@
#include <stdio.h>
-#define xxxAH_DEBUG_GLYPH
+
+#ifdef AH_DEBUG
+
+ void ah_dump_edges( AH_Outline* outline )
+ {
+ AH_Edge* edges;
+ AH_Edge* edge_limit;
+ AH_Segment* segments;
+ FT_Int dimension;
+
+
+ edges = outline->horz_edges;
+ edge_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" );
+
+ for ( edge = edges; edge < 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->blue_edge ? 'y' : 'n',
+ edge->opos / 64.0,
+ edge->pos / 64.0 );
+ }
+
+ edges = outline->vert_edges;
+ edge_limit = edges + outline->num_vedges;
+ segments = outline->vert_segments;
+ }
+ }
+
+
+ /* A function used to dump the array of linked segments */
+ void ah_dump_segments( AH_Outline* outline )
+ {
+ AH_Segment* segments;
+ AH_Segment* segment_limit;
+ AH_Point* points;
+ FT_Int dimension;
+
+
+ points = outline->points;
+ segments = outline->horz_segments;
+ segment_limit = segments + outline->num_hsegments;
+
+ for ( dimension = 1; dimension >= 0; dimension-- )
+ {
+ AH_Segment* seg;
+
+
+ printf ( "Table of %s segments:\n",
+ !dimension ? "vertical" : "horizontal" );
+ printf ( " [ index | pos | dir | link | serif |"
+ " numl | first | start ]\n" );
+
+ for ( seg = segments; seg < segment_limit; seg++ )
+ {
+ printf ( " [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n",
+ seg - segments,
+ (int)seg->pos,
+ seg->dir == ah_dir_up
+ ? "up"
+ : ( seg->dir == ah_dir_down
+ ? "down"
+ : ( seg->dir == ah_dir_left
+ ? "left"
+ : ( seg->dir == ah_dir_right
+ ? "right"
+ : "none" ) ) ),
+ seg->link ? (seg->link-segments) : -1,
+ seg->serif ? (seg->serif-segments) : -1,
+ (int)seg->num_linked,
+ seg->first - points,
+ seg->last - points );
+ }
+
+ segments = outline->vert_segments;
+ segment_limit = segments + outline->num_vsegments;
+ }
+ }
+
+#endif /* AH_DEBUG */
/* compute the direction value of a given vector.. */
@@ -344,8 +446,6 @@
outline->num_hsegments = 0;
outline->num_vsegments = 0;
-#if 1
-
/* We can't rely on the value of `FT_Outline.flags' to know the fill */
/* direction used for a glyph, given that some fonts are broken (e.g. */
/* the Arphic ones). We thus recompute it each time we need to. */
@@ -359,23 +459,6 @@
outline->horz_major_dir = ah_dir_right;
}
-#else /* !1 */
-
- /* Compute the vertical and horizontal major directions; this is */
- /* currently done by inspecting the `ft_outline_reverse_fill' flag. */
- /* However, some fonts have improper glyphs, and it'd be a good idea */
- /* to be able to re-compute these values on the fly. */
- outline->vert_major_dir = ah_dir_up;
- outline->horz_major_dir = ah_dir_left;
-
- if ( source->flags & ft_outline_reverse_fill )
- {
- outline->vert_major_dir = ah_dir_down;
- outline->horz_major_dir = ah_dir_right;
- }
-
-#endif /* !1 */
-
outline->x_scale = face->size->metrics.x_scale;
outline->y_scale = face->size->metrics.y_scale;
@@ -952,59 +1035,6 @@
}
-#ifdef AH_DEBUG_GLYPH
-
- /* A function used to dump the array of linked segments */
- void ah_dump_segments( AH_Outline* outline )
- {
- AH_Segment* segments;
- AH_Segment* segment_limit;
- AH_Point* points;
- FT_Int dimension;
-
-
- points = outline->points;
- segments = outline->horz_segments;
- segment_limit = segments + outline->num_hsegments;
-
- for ( dimension = 1; dimension >= 0; dimension-- )
- {
- AH_Segment* seg;
-
-
- printf ( "Table of %s segments:\n",
- !dimension ? "vertical" : "horizontal" );
- printf ( " [ index | pos | dir | link | serif |"
- " numl | first | start ]\n" );
-
- for ( seg = segments; seg < segment_limit; seg++ )
- {
- printf ( " [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n",
- seg - segments,
- (int)seg->pos,
- seg->dir == ah_dir_up
- ? "up"
- : ( seg->dir == ah_dir_down
- ? "down"
- : ( seg->dir == ah_dir_left
- ? "left"
- : ( seg->dir == ah_dir_right
- ? "right"
- : "none" ) ) ),
- seg->link ? (seg->link-segments) : -1,
- seg->serif ? (seg->serif-segments) : -1,
- (int)seg->num_linked,
- seg->first - points,
- seg->last - points );
- }
-
- segments = outline->vert_segments;
- segment_limit = segments + outline->num_vsegments;
- }
- }
-
-#endif /* AH_DEBUG_GLYPH */
-
static
void ah_outline_compute_edges( AH_Outline* outline )
@@ -1218,7 +1248,7 @@
/* set the round/straight flags */
edge->flags = ah_edge_normal;
- if ( is_straight == 0 && is_round )
+ if ( is_round > 0 && is_round >= is_straight )
edge->flags |= ah_edge_round;
/* set the edge's main direction */
@@ -1286,6 +1316,38 @@
AH_Globals* globals = &face_globals->design;
FT_Fixed y_scale = outline->y_scale;
+ FT_Bool blue_active[ ah_blue_max ];
+
+
+ /* compute which blue zones are active, i.e. have their scaled */
+ /* size < 3/4 pixels */
+ {
+ AH_Blue blue;
+ FT_Bool check = 0;
+
+ for ( blue = ah_blue_capital_top; blue < ah_blue_max; blue++ )
+ {
+ FT_Pos ref, shoot, dist;
+
+ ref = globals->blue_refs[blue];
+ shoot = globals->blue_shoots[blue];
+ dist = ref-shoot;
+ if (dist < 0)
+ dist = -dist;
+
+ blue_active[blue] = 0;
+
+ if ( FT_MulFix( dist, y_scale ) < 48 )
+ {
+ blue_active[blue] = 1;
+ check = 1;
+ }
+ }
+
+ /* return immediately if no blue zone is active */
+ if (!check)
+ return;
+ }
/* compute for each horizontal edge, which blue zone is closer */
for ( ; edge < edge_limit; edge++ )
@@ -1309,6 +1371,8 @@
FT_Bool is_top_blue = AH_IS_TOP_BLUE( blue );
FT_Bool is_major_dir = edge->dir == outline->horz_major_dir;
+ if ( !blue_active[blue] )
+ continue;
/* if it is a top zone, the edge must be against the major */
/* direction; if it is a bottom zone, it must be in the major */
@@ -1392,58 +1456,6 @@
}
-#ifdef AH_DEBUG_GLYPH
-
- void ah_dump_edges( AH_Outline* outline )
- {
- AH_Edge* edges;
- AH_Edge* edge_limit;
- AH_Segment* segments;
- FT_Int dimension;
-
-
- edges = outline->horz_edges;
- edge_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" );
-
- for ( edge = edges; edge < 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->blue_edge ? 'y' : 'n',
- edge->opos / 64.0,
- edge->pos / 64.0 );
- }
-
- edges = outline->vert_edges;
- edge_limit = edges + outline->num_vedges;
- segments = outline->vert_segments;
- }
- }
-
-#endif /* AH_DEBUG_GLYPH */
/* END */
diff --git a/src/autohint/ahhint.c b/src/autohint/ahhint.c
index 754687c3a..ead32fde5 100644
--- a/src/autohint/ahhint.c
+++ b/src/autohint/ahhint.c
@@ -1051,13 +1051,13 @@
switch ( slot->format )
{
case ft_glyph_format_outline:
-
+
/* translate glyph outline if we need to */
if ( hinter->transformed )
{
FT_UInt n = slot->outline.n_points;
FT_Vector* point = slot->outline.points;
-
+
for ( ; n > 0; point++, n-- )
{
@@ -1065,7 +1065,7 @@
point->y += hinter->trans_delta.y;
}
}
-
+
/* 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,
@@ -1365,7 +1365,11 @@
ah_loader_rewind( hinter->loader );
+#if 1
+ load_flags = FT_LOAD_NO_SCALE;
+#else
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE;
+#endif
error = ah_hinter_load( hinter, glyph_index, load_flags, 0 );
diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c
index dfcecc1c5..327b31800 100644
--- a/src/base/ftcalc.c
+++ b/src/base/ftcalc.c
@@ -55,7 +55,8 @@
FT_EXPORT_DEF( FT_Fixed ) FT_RoundFix( FT_Fixed a )
{
- return( ( a + 0x8000L ) & -0x10000L );
+ return ( a >= 0 ) ? ( a + 0x8000L ) & -0x10000L
+ : -((-a + 0x8000L ) & -0x10000L );
}
@@ -63,7 +64,8 @@
FT_EXPORT_DEF( FT_Fixed ) FT_CeilFix( FT_Fixed a )
{
- return( ( a + 0x10000L - 1 ) & -0x10000L );
+ return ( a >= 0 ) ? ( a + 0xFFFFL ) & -0x10000L
+ : -((-a + 0xFFFFL ) & -0x10000L );
}
@@ -71,7 +73,8 @@
FT_EXPORT_DEF( FT_Fixed ) FT_FloorFix( FT_Fixed a )
{
- return( a & -0x10000L );
+ return ( a >= 0 ) ? a & -0x10000L
+ : -((-a) & -0x10000L );
}
@@ -176,16 +179,16 @@
FT_Int32 s;
FT_UInt32 q;
-
- s = a; a = ABS(a);
- s ^= b; b = ABS(b);
+ s = 1;
+ if ( a < 0 ) { a = -a; s = -1; }
+ if ( b < 0 ) { b = -b; s = -s; }
if ( b == 0 )
/* check for division by 0 */
q = 0x7FFFFFFFL;
else
/* compute result directly */
- q = ( ((FT_Int64)a + (b >> 1)) << 16 ) / b;
+ q = ( ((FT_Int64)a << 16) + (b >> 1)) / b;
return (FT_Long)( s < 0 ? -q : q );
}