[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[freetype2] bytecode_tweaks 041a339b6 6/7: [truetype] Optimize bytecode
From: |
Werner Lemberg |
Subject: |
[freetype2] bytecode_tweaks 041a339b6 6/7: [truetype] Optimize bytecode movements. |
Date: |
Fri, 9 May 2025 18:29:47 -0400 (EDT) |
branch: bytecode_tweaks
commit 041a339b6a2048d041446f9cc250a7e2bc8a3d15
Author: Alexei Podtelezhnikov <apodtele@gmail.com>
Commit: Alexei Podtelezhnikov <apodtele@gmail.com>
[truetype] Optimize bytecode movements.
Replacing FT_MulDiv with FT_MulFix gives large performance gains.
* src/truetype/ttinterp.h (TT_ExecContextRec): Store "projected"
freedom vector.
* src/truetype/ttinterp.c (Compute_Funcs): Compute "projected"
freedom vector.
(Direct_Move, Direct_Move_Orig, Compute_Point_displacement): Use it.
---
src/truetype/ttinterp.c | 106 +++++++++++++++++++++++-------------------------
src/truetype/ttinterp.h | 6 +--
2 files changed, 54 insertions(+), 58 deletions(-)
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index abff39095..182ba3d3c 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -1638,11 +1638,10 @@
FT_UShort point,
FT_F26Dot6 distance )
{
- FT_F26Dot6 v;
+ FT_Fixed v;
- v = exc->GS.freeVector.x;
-
+ v = exc->moveVector.x;
if ( v != 0 )
{
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
@@ -1651,23 +1650,18 @@
/* diagonal stems like on `Z' and `z' post-IUP. */
if ( SUBPIXEL_HINTING_MINIMAL && !exc->backward_compatibility )
zone->cur[point].x = ADD_LONG( zone->cur[point].x,
- FT_MulDiv( distance,
- v,
- exc->F_dot_P ) );
+ FT_MulFix( distance, v ) );
else
#endif
if ( NO_SUBPIXEL_HINTING )
zone->cur[point].x = ADD_LONG( zone->cur[point].x,
- FT_MulDiv( distance,
- v,
- exc->F_dot_P ) );
+ FT_MulFix( distance, v ) );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
}
- v = exc->GS.freeVector.y;
-
+ v = exc->moveVector.y;
if ( v != 0 )
{
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
@@ -1677,9 +1671,7 @@
exc->iupy_called ) )
#endif
zone->cur[point].y = ADD_LONG( zone->cur[point].y,
- FT_MulDiv( distance,
- v,
- exc->F_dot_P ) );
+ FT_MulFix( distance, v ) );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
@@ -1712,24 +1704,20 @@
FT_UShort point,
FT_F26Dot6 distance )
{
- FT_F26Dot6 v;
+ FT_Fixed v;
- v = exc->GS.freeVector.x;
+ v = exc->moveVector.x;
if ( v != 0 )
zone->org[point].x = ADD_LONG( zone->org[point].x,
- FT_MulDiv( distance,
- v,
- exc->F_dot_P ) );
+ FT_MulFix( distance, v ) );
- v = exc->GS.freeVector.y;
+ v = exc->moveVector.y;
if ( v != 0 )
zone->org[point].y = ADD_LONG( zone->org[point].y,
- FT_MulDiv( distance,
- v,
- exc->F_dot_P ) );
+ FT_MulFix( distance, v ) );
}
@@ -2448,14 +2436,45 @@
static void
Compute_Funcs( TT_ExecContext exc )
{
- if ( exc->GS.freeVector.x == 0x4000 )
- exc->F_dot_P = exc->GS.projVector.x;
- else if ( exc->GS.freeVector.y == 0x4000 )
- exc->F_dot_P = exc->GS.projVector.y;
+ FT_Long F_dot_P =
+ ( (FT_Long)exc->GS.projVector.x * exc->GS.freeVector.x +
+ (FT_Long)exc->GS.projVector.y * exc->GS.freeVector.y +
+ 0x2000L ) >> 14;
+
+
+ if ( F_dot_P >= 0x3FFEL )
+ {
+ /* commonly collinear */
+ exc->moveVector.x = exc->GS.freeVector.x << 2;
+ exc->moveVector.y = exc->GS.freeVector.y << 2;
+ }
+ else if ( -0x400L < F_dot_P && F_dot_P < 0x400L )
+ {
+ /* prohibitively orthogonal */
+ exc->moveVector.x = 0;
+ exc->moveVector.y = 0;
+ }
+ else
+ {
+ exc->moveVector.x = ( exc->GS.freeVector.x << 16 ) / F_dot_P;
+ exc->moveVector.y = ( exc->GS.freeVector.y << 16 ) / F_dot_P;
+ }
+
+ if ( F_dot_P >= 0x3FFEL && exc->GS.freeVector.x == 0x4000 )
+ {
+ exc->func_move = (TT_Move_Func)Direct_Move_X;
+ exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
+ }
+ else if ( F_dot_P >= 0x3FFEL && exc->GS.freeVector.y == 0x4000 )
+ {
+ exc->func_move = (TT_Move_Func)Direct_Move_Y;
+ exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
+ }
else
- exc->F_dot_P =
- ( (FT_Long)exc->GS.projVector.x * exc->GS.freeVector.x +
- (FT_Long)exc->GS.projVector.y * exc->GS.freeVector.y ) >> 14;
+ {
+ exc->func_move = (TT_Move_Func)Direct_Move;
+ exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig;
+ }
if ( exc->GS.projVector.x == 0x4000 )
exc->func_project = (TT_Project_Func)Project_x;
@@ -2471,29 +2490,6 @@
else
exc->func_dualproj = (TT_Project_Func)Dual_Project;
- exc->func_move = (TT_Move_Func)Direct_Move;
- exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig;
-
- if ( exc->F_dot_P == 0x4000L )
- {
- if ( exc->GS.freeVector.x == 0x4000 )
- {
- exc->func_move = (TT_Move_Func)Direct_Move_X;
- exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
- }
- else if ( exc->GS.freeVector.y == 0x4000 )
- {
- exc->func_move = (TT_Move_Func)Direct_Move_Y;
- exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
- }
- }
-
- /* at small sizes, F_dot_P can become too small, resulting */
- /* in overflows and `spikes' in a number of glyphs like `w'. */
-
- if ( FT_ABS( exc->F_dot_P ) < 0x400L )
- exc->F_dot_P = 0x4000L;
-
/* Disable cached aspect ratio */
exc->tt_metrics.ratio = 0;
}
@@ -5157,8 +5153,8 @@
d = PROJECT( zp.cur + p, zp.org + p );
- *x = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.x, exc->F_dot_P );
- *y = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.y, exc->F_dot_P );
+ *x = FT_MulFix( d, exc->moveVector.x );
+ *y = FT_MulFix( d, exc->moveVector.y );
return SUCCESS;
}
diff --git a/src/truetype/ttinterp.h b/src/truetype/ttinterp.h
index 09923f563..4e6acd3b4 100644
--- a/src/truetype/ttinterp.h
+++ b/src/truetype/ttinterp.h
@@ -192,9 +192,9 @@ FT_BEGIN_HEADER
/* latest interpreter additions */
- FT_Long F_dot_P; /* dot product of freedom and projection */
- /* vectors */
- TT_Round_Func func_round; /* current rounding function */
+ TT_Round_Func func_round; /* current rounding function */
+
+ FT_Vector moveVector; /* "projected" freedom vector */
TT_Project_Func func_project, /* current projection function */
func_dualproj, /* current dual proj. function */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [freetype2] bytecode_tweaks 041a339b6 6/7: [truetype] Optimize bytecode movements.,
Werner Lemberg <=