ref: 3cd6cc24f234cfc9b936aed5c136393448eeb631
parent: 2c4500e981aa4fae26af045e259d34e55a3aa7e5
author: Werner Lemberg <[email protected]>
date: Fri Feb 16 03:10:17 EST 2007
formatting
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,14 @@
2007-02-14 David Turner <[email protected]>
- * src/truetype/ttinterp.c: improved the FIX_BYTECODE code which is now
- the default, it seems to get rid of most known problems with my fonts,
- but more testing is needed though.
+ It seems that the following changes fix most of the known
+ interpreter problems with my fonts, but more testing is needed,
+ though.
+ * src/truetype/ttinterp.c (FIX_BYTECODE): Activate.
+ (TT_MulFix14): Rewrite.
+ (Ins_MD, Ins_MDRP, Ins_IP) [FIX_BYTECODE]: Improved and updated.
+ (Ins_MIRP): Ditto.
+
2007-02-12 Werner Lemberg <[email protected]>
* src/truetype/ttinterp.c (Project_x, Project_y): Remove compiler
@@ -14,6 +19,8 @@
2007-02-12 David Turner <[email protected]>
+ Simplify projection and dual-projection code interface.
+
* src/truetype/ttinterp.h (TT_Project_Func): Use `FT_Pos', not
FT_Vector' as argument type.
* src/truetype/ttinterp.c (CUR_Func_project, CUR_Func_dualproj):
@@ -28,9 +35,10 @@
adjustments for the non-light auto-hinted modes. Gets rid of
`inter-letter spacing is too wide' problems.
- * src/autofit/aflatin.c: Slight optimization of the segment linker
- and better handling of serif segments to get rid of broken `9' in
- Arial at 9pt (96dpi).
+ * src/autofit/aflatin.c (af_latin_hints_link_segments,
+ af_latin_hints_compute_edges): Slight optimization of the segment
+ linker and better handling of serif segments to get rid of broken
+ `9' in Arial at 9pt (96dpi).
Introduce new string functions and the corresponding macros to get
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -926,7 +926,7 @@
if ( seg1->first == seg1->last )
continue;
- for ( seg2 = seg1+1; seg2 < segment_limit; seg2++ )
+ for ( seg2 = seg1 + 1; seg2 < segment_limit; seg2++ )
if ( seg1->dir + seg2->dir == 0 )
{
FT_Pos pos1 = seg1->pos;
@@ -1057,10 +1057,10 @@
if ( seg->height < segment_length_threshold )
continue;
- /* a special case for serif edges, if they're smaller than 1.5
- * pixels, we ignore them
- */
- if ( seg->serif && 2*seg->height < 3*segment_length_threshold )
+ /* A special case for serif edges: If they are smaller than */
+ /* 1.5 pixels we ignore them. */
+ if ( seg->serif &&
+ 2 * seg->height < 3 * segment_length_threshold )
continue;
/* look for an edge corresponding to the segment */
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -1144,34 +1144,40 @@
#if 1
+
static FT_Int32
TT_MulFix14( FT_Int32 a,
FT_Int b )
-{
- FT_Int32 sign;
- FT_UInt32 ah, al, mid, lo, hi;
+ {
+ FT_Int32 sign;
+ FT_UInt32 ah, al, mid, lo, hi;
- sign = a^b;
- if (a < 0) a = -a;
- if (b < 0) b = -b;
+ sign = a ^ b;
- ah = (FT_UInt32)((a >> 16) & 0xFFFFU);
- al = (FT_UInt32)( a & 0xFFFFU );
+ if ( a < 0 )
+ a = -a;
+ if ( b < 0 )
+ b = -b;
- lo = al*b;
- mid = ah*b;
- hi = (mid >> 16);
- mid = (mid << 16) + (1 << 13); /* rounding */
- lo += mid;
- if (lo < mid)
- hi += 1;
+ ah = (FT_UInt32)( ( a >> 16 ) & 0xFFFFU );
+ al = (FT_UInt32)( a & 0xFFFFU );
- mid = (lo >> 14) | (hi << 18);
+ lo = al * b;
+ mid = ah * b;
+ hi = mid >> 16;
+ mid = ( mid << 16 ) + ( 1 << 13 ); /* rounding */
+ lo += mid;
+ if ( lo < mid )
+ hi += 1;
- return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid;
-}
+ mid = ( lo >> 14 ) | ( hi << 18 );
+
+ return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid;
+ }
+
#else
+
/* compute (a*b)/2^14 with maximal accuracy and rounding */
static FT_Int32
TT_MulFix14( FT_Int32 a,
@@ -4838,8 +4844,10 @@
CUR.twilight.n_points );
/* get scaled orus coordinates */
- vec1.x = TT_MULFIX( CUR.zp0.orus[L].x - CUR.zp1.orus[K].x, CUR.metrics.x_scale );
- vec1.y = TT_MULFIX( CUR.zp0.orus[L].y - CUR.zp1.orus[L].y, CUR.metrics.y_scale );
+ vec1.x = TT_MULFIX( CUR.zp0.orus[L].x - CUR.zp1.orus[K].x,
+ CUR.metrics.x_scale );
+ vec1.y = TT_MULFIX( CUR.zp0.orus[L].y - CUR.zp1.orus[L].y,
+ CUR.metrics.y_scale );
D = CUR_fast_dualproj( &vec1 );
@@ -5920,8 +5928,10 @@
CUR.zp1.cur[point] = CUR.zp0.cur[point];
}
- org_dist = CUR_Func_dualproj( &CUR.zp1.org[point], &CUR.zp0.org[CUR.GS.rp0] );
- cur_dist = CUR_Func_project ( &CUR.zp1.cur[point], &CUR.zp0.cur[CUR.GS.rp0] );
+ org_dist = CUR_Func_dualproj( &CUR.zp1.org[point],
+ &CUR.zp0.org[CUR.GS.rp0] );
+ cur_dist = CUR_Func_project ( &CUR.zp1.cur[point],
+ &CUR.zp0.cur[CUR.GS.rp0] );
/* auto-flip test */
@@ -6154,7 +6164,9 @@
/* */
/* SOMETIMES, DUMBER CODE IS BETTER CODE */
+
#ifdef FIX_BYTECODE
+
static void
Ins_IP( INS_ARG )
{
@@ -6171,20 +6183,19 @@
return;
}
- /* We need to deal in a special way with the twilight zone. The easiest
- * solution is simply to copy the coordinates from `org' to `orus'
- * whenever someone tries to perform intersections based on some of its
- * points.
- *
- * Otherwise, by definition, value of CUR.twilight.orus[n] is (0,0),
- * whatever value of `n'.
- */
+ /*
+ * We need to deal in a special way with the twilight zone. The easiest
+ * solution is simply to copy the coordinates from `org' to `orus'
+ * whenever a font tries to perform intersections based on some of its
+ * points.
+ *
+ * Otherwise, by definition, the value of CUR.twilight.orus[n] is (0,0),
+ * whatever value of `n'.
+ */
if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0 )
- {
- FT_ARRAY_COPY( CUR.twilight.orus,
- CUR.twilight.org,
- CUR.twilight.n_points );
- }
+ FT_ARRAY_COPY( CUR.twilight.orus,
+ CUR.twilight.org,
+ CUR.twilight.n_points );
orus_base = &CUR.zp0.orus[CUR.GS.rp1];
cur_base = &CUR.zp0.cur[CUR.GS.rp1];
@@ -6207,9 +6218,10 @@
for ( ; CUR.GS.loop > 0; --CUR.GS.loop )
{
- FT_UInt point = (FT_UInt) CUR.stack[--CUR.args];
+ FT_UInt point = (FT_UInt)CUR.stack[--CUR.args];
FT_F26Dot6 org_dist, cur_dist, new_dist;
+
/* check point bounds */
if ( BOUNDS( point, CUR.zp2.n_points ) )
{
@@ -6223,8 +6235,9 @@
org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base );
cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base );
- new_dist = (old_range != 0) ? TT_MULDIV( org_dist, cur_range, old_range )
- : cur_dist;
+ new_dist = (old_range != 0)
+ ? TT_MULDIV( org_dist, cur_range, old_range )
+ : cur_dist;
CUR_Func_move( &CUR.zp2, point, new_dist - cur_dist );
}
@@ -6231,7 +6244,9 @@
CUR.GS.loop = 1;
CUR.new_top = CUR.args;
}
-#else /* OLD CODE */
+
+#else /* !FIX_BYTECODE */
+
static void
Ins_IP( INS_ARG )
{
@@ -6314,7 +6329,9 @@
CUR.GS.loop = 1;
CUR.new_top = CUR.args;
}
-#endif
+
+#endif /* !FIX_BYTECODE */
+
/*************************************************************************/
/* */