summaryrefslogtreecommitdiffstats
path: root/src/smooth/ftgrays.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/smooth/ftgrays.c')
-rw-r--r--src/smooth/ftgrays.c180
1 files changed, 85 insertions, 95 deletions
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 27be966..77b58f2 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -4,7 +4,7 @@
/* */
/* A new `perfect' anti-aliasing renderer (body). */
/* */
-/* Copyright 2000-2003, 2005-2014 by */
+/* Copyright 2000-2015 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -94,6 +94,11 @@
#ifdef _STANDALONE_
+ /* The size in bytes of the render pool used by the scan-line converter */
+ /* to do all of its work. */
+#define FT_RENDER_POOL_SIZE 16384L
+
+
/* Auxiliary macros for token concatenation. */
#define FT_ERR_XCAT( x, y ) x ## y
#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y )
@@ -101,6 +106,21 @@
#define FT_BEGIN_STMNT do {
#define FT_END_STMNT } while ( 0 )
+#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) )
+#define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) )
+
+
+ /*
+ * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min'
+ * algorithm. We use alpha = 1, beta = 3/8, giving us results with a
+ * largest error less than 7% compared to the exact value.
+ */
+#define FT_HYPOT( x, y ) \
+ ( x = FT_ABS( x ), \
+ y = FT_ABS( y ), \
+ x > y ? x + ( 3 * y >> 3 ) \
+ : y + ( 3 * x >> 3 ) )
+
/* define this to dump debugging information */
/* #define FT_DEBUG_LEVEL_TRACE */
@@ -405,6 +425,8 @@ typedef ptrdiff_t FT_PtrDist;
typedef struct gray_TWorker_
{
+ ft_jmp_buf jump_buffer;
+
TCoord ex, ey;
TPos min_ex, max_ex;
TPos min_ey, max_ey;
@@ -440,8 +462,6 @@ typedef ptrdiff_t FT_PtrDist;
int band_size;
int band_shoot;
- ft_jmp_buf jump_buffer;
-
void* buffer;
long buffer_size;
@@ -464,11 +484,7 @@ typedef ptrdiff_t FT_PtrDist;
typedef struct gray_TRaster_
{
- void* buffer;
- long buffer_size;
- int band_size;
void* memory;
- gray_PWorker worker;
} gray_TRaster, *gray_PRaster;
@@ -480,7 +496,7 @@ typedef ptrdiff_t FT_PtrDist;
/* */
static void
gray_init_cells( RAS_ARG_ void* buffer,
- long byte_size )
+ long byte_size )
{
ras.buffer = buffer;
ras.buffer_size = byte_size;
@@ -638,8 +654,8 @@ typedef ptrdiff_t FT_PtrDist;
ras.ey = ey;
}
- ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey ||
- ex >= ras.count_ex );
+ ras.invalid = ( (unsigned int)ey >= (unsigned int)ras.count_ey ||
+ ex >= ras.count_ex );
}
@@ -1091,37 +1107,10 @@ typedef ptrdiff_t FT_PtrDist;
/* dx and dy are x and y components of the P0-P3 chord vector. */
- dx = arc[3].x - arc[0].x;
- dy = arc[3].y - arc[0].y;
-
- /* L is an (under)estimate of the Euclidean distance P0-P3. */
- /* */
- /* If dx >= dy, then r = sqrt(dx^2 + dy^2) can be overestimated */
- /* with least maximum error by */
- /* */
- /* r_upperbound = dx + (sqrt(2) - 1) * dy , */
- /* */
- /* where sqrt(2) - 1 can be (over)estimated by 107/256, giving an */
- /* error of no more than 8.4%. */
- /* */
- /* Similarly, some elementary calculus shows that r can be */
- /* underestimated with least maximum error by */
- /* */
- /* r_lowerbound = sqrt(2 + sqrt(2)) / 2 * dx */
- /* + sqrt(2 - sqrt(2)) / 2 * dy . */
- /* */
- /* 236/256 and 97/256 are (under)estimates of the two algebraic */
- /* numbers, giving an error of no more than 8.1%. */
-
- dx_ = FT_ABS( dx );
- dy_ = FT_ABS( dy );
-
- /* This is the same as */
- /* */
- /* L = ( 236 * FT_MAX( dx_, dy_ ) */
- /* + 97 * FT_MIN( dx_, dy_ ) ) >> 8; */
- L = ( dx_ > dy_ ? 236 * dx_ + 97 * dy_
- : 97 * dx_ + 236 * dy_ ) >> 8;
+ dx = dx_ = arc[3].x - arc[0].x;
+ dy = dy_ = arc[3].y - arc[0].y;
+
+ L = FT_HYPOT( dx_, dy_ );
/* Avoid possible arithmetic overflow below by splitting. */
if ( L > 32767 )
@@ -1239,7 +1228,7 @@ typedef ptrdiff_t FT_PtrDist;
/* first of all, compute the scanline offset */
p = (unsigned char*)map->buffer - y * map->pitch;
if ( map->pitch >= 0 )
- p += (unsigned)( ( map->rows - 1 ) * map->pitch );
+ p += ( map->rows - 1 ) * (unsigned int)map->pitch;
for ( ; count > 0; count--, spans++ )
{
@@ -1542,7 +1531,10 @@ typedef ptrdiff_t FT_PtrDist;
TPos delta;
- if ( !outline || !func_interface )
+ if ( !outline )
+ return FT_THROW( Invalid_Outline );
+
+ if ( !func_interface )
return FT_THROW( Invalid_Argument );
shift = func_interface->shift;
@@ -1768,14 +1760,17 @@ typedef ptrdiff_t FT_PtrDist;
} gray_TBand;
- FT_DEFINE_OUTLINE_FUNCS(func_interface,
- (FT_Outline_MoveTo_Func) gray_move_to,
- (FT_Outline_LineTo_Func) gray_line_to,
- (FT_Outline_ConicTo_Func)gray_conic_to,
- (FT_Outline_CubicTo_Func)gray_cubic_to,
- 0,
- 0
- )
+
+ FT_DEFINE_OUTLINE_FUNCS(
+ func_interface,
+
+ (FT_Outline_MoveTo_Func) gray_move_to,
+ (FT_Outline_LineTo_Func) gray_line_to,
+ (FT_Outline_ConicTo_Func)gray_conic_to,
+ (FT_Outline_CubicTo_Func)gray_cubic_to,
+ 0,
+ 0 )
+
static int
gray_convert_glyph_inner( RAS_ARG )
@@ -1866,13 +1861,13 @@ typedef ptrdiff_t FT_PtrDist;
ras.ycells = (PCell*)ras.buffer;
ras.ycount = band->max - band->min;
- cell_start = sizeof ( PCell ) * ras.ycount;
- cell_mod = cell_start % sizeof ( TCell );
+ cell_start = (long)sizeof ( PCell ) * ras.ycount;
+ cell_mod = cell_start % (long)sizeof ( TCell );
if ( cell_mod > 0 )
- cell_start += sizeof ( TCell ) - cell_mod;
+ cell_start += (long)sizeof ( TCell ) - cell_mod;
cell_end = ras.buffer_size;
- cell_end -= cell_end % sizeof ( TCell );
+ cell_end -= cell_end % (long)sizeof ( TCell );
cells_max = (PCell)( (char*)ras.buffer + cell_end );
ras.cells = (PCell)( (char*)ras.buffer + cell_start );
@@ -1942,12 +1937,18 @@ typedef ptrdiff_t FT_PtrDist;
gray_raster_render( gray_PRaster raster,
const FT_Raster_Params* params )
{
- const FT_Outline* outline = (const FT_Outline*)params->source;
- const FT_Bitmap* target_map = params->target;
- gray_PWorker worker;
+ const FT_Outline* outline = (const FT_Outline*)params->source;
+ const FT_Bitmap* target_map = params->target;
+
+ gray_TWorker worker[1];
+ TCell buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( TCell )];
+ long buffer_size = sizeof ( buffer );
+ int band_size = (int)( buffer_size /
+ (long)( sizeof ( TCell ) * 8 ) );
- if ( !raster || !raster->buffer || !raster->buffer_size )
+
+ if ( !raster )
return FT_THROW( Invalid_Argument );
if ( !outline )
@@ -1964,8 +1965,6 @@ typedef ptrdiff_t FT_PtrDist;
outline->contours[outline->n_contours - 1] + 1 )
return FT_THROW( Invalid_Outline );
- worker = raster->worker;
-
/* if direct mode is not set, we must have a target bitmap */
if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
{
@@ -1990,8 +1989,8 @@ typedef ptrdiff_t FT_PtrDist;
/* compute clip box from target pixmap */
ras.clip_box.xMin = 0;
ras.clip_box.yMin = 0;
- ras.clip_box.xMax = target_map->width;
- ras.clip_box.yMax = target_map->rows;
+ ras.clip_box.xMax = (FT_Pos)target_map->width;
+ ras.clip_box.yMax = (FT_Pos)target_map->rows;
}
else if ( params->flags & FT_RASTER_FLAG_CLIP )
ras.clip_box = params->clip_box;
@@ -2003,13 +2002,14 @@ typedef ptrdiff_t FT_PtrDist;
ras.clip_box.yMax = 32767L;
}
- gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size );
+ gray_init_cells( RAS_VAR_ buffer, buffer_size );
ras.outline = *outline;
ras.num_cells = 0;
ras.invalid = 1;
- ras.band_size = raster->band_size;
+ ras.band_size = band_size;
ras.num_gray_spans = 0;
+ ras.span_y = 0;
if ( params->flags & FT_RASTER_FLAG_DIRECT )
{
@@ -2093,46 +2093,36 @@ typedef ptrdiff_t FT_PtrDist;
char* pool_base,
long pool_size )
{
- gray_PRaster rast = (gray_PRaster)raster;
+ FT_UNUSED( raster );
+ FT_UNUSED( pool_base );
+ FT_UNUSED( pool_size );
+ }
- if ( raster )
- {
- if ( pool_base && pool_size >= (long)sizeof ( gray_TWorker ) + 2048 )
- {
- gray_PWorker worker = (gray_PWorker)pool_base;
-
-
- rast->worker = worker;
- rast->buffer = pool_base +
- ( ( sizeof ( gray_TWorker ) +
- sizeof ( TCell ) - 1 ) &
- ~( sizeof ( TCell ) - 1 ) );
- rast->buffer_size = (long)( ( pool_base + pool_size ) -
- (char*)rast->buffer ) &
- ~( sizeof ( TCell ) - 1 );
- rast->band_size = (int)( rast->buffer_size /
- ( sizeof ( TCell ) * 8 ) );
- }
- else
- {
- rast->buffer = NULL;
- rast->buffer_size = 0;
- rast->worker = NULL;
- }
- }
+ static int
+ gray_raster_set_mode( FT_Raster raster,
+ unsigned long mode,
+ void* args )
+ {
+ FT_UNUSED( raster );
+ FT_UNUSED( mode );
+ FT_UNUSED( args );
+
+
+ return 0; /* nothing to do */
}
- FT_DEFINE_RASTER_FUNCS(ft_grays_raster,
+ FT_DEFINE_RASTER_FUNCS(
+ ft_grays_raster,
+
FT_GLYPH_FORMAT_OUTLINE,
(FT_Raster_New_Func) gray_raster_new,
(FT_Raster_Reset_Func) gray_raster_reset,
- (FT_Raster_Set_Mode_Func)0,
+ (FT_Raster_Set_Mode_Func)gray_raster_set_mode,
(FT_Raster_Render_Func) gray_raster_render,
- (FT_Raster_Done_Func) gray_raster_done
- )
+ (FT_Raster_Done_Func) gray_raster_done )
/* END */