[smooth] Slightly optimize conic and cubic flatterners. * src/smooth/ftgrays.c (gray_render_conic, gray_render_cubic): Move out some code from the main loop to speed it up.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
diff --git a/ChangeLog b/ChangeLog
index 5b37e68..6187645 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2011-09-17 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [smooth] Slightly optimize conic and cubic flatterners.
+
+ * src/smooth/ftgrays.c (gray_render_conic, gray_render_cubic): Move
+ out some code from the main loop to speed it up.
+
2011-09-11 Tomas Hoger <thoger@redhat.com>
Slightly improve LZW_CLEAR handling.
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 40de269..895e748 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -872,6 +872,7 @@ typedef ptrdiff_t FT_PtrDist;
const FT_Vector* to )
{
TPos dx, dy;
+ TPos min, max, y;
int top, level;
int* levels;
FT_Vector* arc;
@@ -884,45 +885,45 @@ typedef ptrdiff_t FT_PtrDist;
arc[1].y = UPSCALE( control->y );
arc[2].x = ras.x;
arc[2].y = ras.y;
+ top = 0;
dx = FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x );
dy = FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y );
if ( dx < dy )
dx = dy;
+ if ( dx < ONE_PIXEL / 4 )
+ goto Draw;
+
+ /* short-cut the arc that crosses the current band */
+ min = max = arc[0].y;
+
+ y = arc[1].y;
+ if ( y < min ) min = y;
+ if ( y > max ) max = y;
+
+ y = arc[2].y;
+ if ( y < min ) min = y;
+ if ( y > max ) max = y;
+
+ if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )
+ goto Draw;
+
level = 0;
- while ( dx > ONE_PIXEL / 6 )
+ do
{
dx >>= 2;
level++;
- }
+ } while ( dx > ONE_PIXEL / 4 );
levels = ras.lev_stack;
levels[0] = level;
- top = 0;
do
{
level = levels[top];
- if ( level > 1 )
+ if ( level > 0 )
{
- /* check that the arc crosses the current band */
- TPos min, max, y;
-
-
- min = max = arc[0].y;
-
- y = arc[1].y;
- if ( y < min ) min = y;
- if ( y > max ) max = y;
-
- y = arc[2].y;
- if ( y < min ) min = y;
- if ( y > max ) max = y;
-
- if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )
- goto Draw;
-
gray_split_conic( arc );
arc += 2;
top++;
@@ -973,6 +974,7 @@ typedef ptrdiff_t FT_PtrDist;
const FT_Vector* to )
{
FT_Vector* arc;
+ TPos min, max, y;
arc = ras.bez_stack;
@@ -985,35 +987,32 @@ typedef ptrdiff_t FT_PtrDist;
arc[3].x = ras.x;
arc[3].y = ras.y;
- for (;;)
- {
- /* Check that the arc crosses the current band. */
- TPos min, max, y;
-
-
- min = max = arc[0].y;
+ /* Short-cut the arc that crosses the current band. */
+ min = max = arc[0].y;
- y = arc[1].y;
- if ( y < min )
- min = y;
- if ( y > max )
- max = y;
+ y = arc[1].y;
+ if ( y < min )
+ min = y;
+ if ( y > max )
+ max = y;
- y = arc[2].y;
- if ( y < min )
- min = y;
- if ( y > max )
- max = y;
+ y = arc[2].y;
+ if ( y < min )
+ min = y;
+ if ( y > max )
+ max = y;
- y = arc[3].y;
- if ( y < min )
- min = y;
- if ( y > max )
- max = y;
+ y = arc[3].y;
+ if ( y < min )
+ min = y;
+ if ( y > max )
+ max = y;
- if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )
- goto Draw;
+ if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )
+ goto Draw;
+ for (;;)
+ {
/* Decide whether to split or draw. See `Rapid Termination */
/* Evaluation for Recursive Subdivision of Bezier Curves' by Thomas */
/* F. Hain, at */