summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/freetype/src/smooth/ftgrays.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/freetype/src/smooth/ftgrays.c')
-rw-r--r--src/3rdparty/freetype/src/smooth/ftgrays.c633
1 files changed, 338 insertions, 295 deletions
diff --git a/src/3rdparty/freetype/src/smooth/ftgrays.c b/src/3rdparty/freetype/src/smooth/ftgrays.c
index 846e454e66..131ad27a0c 100644
--- a/src/3rdparty/freetype/src/smooth/ftgrays.c
+++ b/src/3rdparty/freetype/src/smooth/ftgrays.c
@@ -4,7 +4,7 @@
/* */
/* A new `perfect' anti-aliasing renderer (body). */
/* */
-/* Copyright 2000-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009 by */
+/* Copyright 2000-2003, 2005-2014 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -24,8 +24,8 @@
/* */
/* - copy `src/smooth/ftgrays.c' (this file) to your current directory */
/* */
- /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */
- /* same directory */
+ /* - copy `include/ftimage.h' and `src/smooth/ftgrays.h' to the same */
+ /* directory */
/* */
/* - compile `ftgrays' with the _STANDALONE_ macro defined, as in */
/* */
@@ -94,6 +94,14 @@
#ifdef _STANDALONE_
+ /* Auxiliary macros for token concatenation. */
+#define FT_ERR_XCAT( x, y ) x ## y
+#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y )
+
+#define FT_BEGIN_STMNT do {
+#define FT_END_STMNT } while ( 0 )
+
+
/* define this to dump debugging information */
/* #define FT_DEBUG_LEVEL_TRACE */
@@ -103,10 +111,12 @@
#include <stdarg.h>
#endif
+#include <stddef.h>
#include <string.h>
#include <setjmp.h>
#include <limits.h>
#define FT_UINT_MAX UINT_MAX
+#define FT_INT_MAX INT_MAX
#define ft_memset memset
@@ -114,6 +124,8 @@
#define ft_longjmp longjmp
#define ft_jmp_buf jmp_buf
+typedef ptrdiff_t FT_PtrDist;
+
#define ErrRaster_Invalid_Mode -2
#define ErrRaster_Invalid_Outline -1
@@ -150,6 +162,21 @@
va_end( ap );
}
+
+ /* empty function useful for setting a breakpoint to catch errors */
+ int
+ FT_Throw( int error,
+ int line,
+ const char* file )
+ {
+ FT_UNUSED( error );
+ FT_UNUSED( line );
+ FT_UNUSED( file );
+
+ return 0;
+ }
+
+
/* we don't handle tracing levels in stand-alone mode; */
#ifndef FT_TRACE5
#define FT_TRACE5( varformat ) FT_Message varformat
@@ -161,11 +188,19 @@
#define FT_ERROR( varformat ) FT_Message varformat
#endif
+#define FT_THROW( e ) \
+ ( FT_Throw( FT_ERR_CAT( ErrRaster, e ), \
+ __LINE__, \
+ __FILE__ ) | \
+ FT_ERR_CAT( ErrRaster, e ) )
+
#else /* !FT_DEBUG_LEVEL_TRACE */
#define FT_TRACE5( x ) do { } while ( 0 ) /* nothing */
#define FT_TRACE7( x ) do { } while ( 0 ) /* nothing */
#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */
+#define FT_THROW( e ) FT_ERR_CAT( ErrRaster_, e )
+
#endif /* !FT_DEBUG_LEVEL_TRACE */
@@ -183,7 +218,7 @@
shift_, \
delta_ \
};
-
+
#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, \
raster_new_, raster_reset_, \
raster_set_mode_, raster_render_, \
@@ -198,6 +233,7 @@
raster_done_ \
};
+
#else /* !_STANDALONE_ */
@@ -211,13 +247,14 @@
#include "ftspic.h"
-#define ErrRaster_Invalid_Mode Smooth_Err_Cannot_Render_Glyph
-#define ErrRaster_Invalid_Outline Smooth_Err_Invalid_Outline
+#define Smooth_Err_Invalid_Mode Smooth_Err_Cannot_Render_Glyph
+#define Smooth_Err_Memory_Overflow Smooth_Err_Out_Of_Memory
#define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory
-#define ErrRaster_Invalid_Argument Smooth_Err_Invalid_Argument
+
#endif /* !_STANDALONE_ */
+
#ifndef FT_MEM_SET
#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c )
#endif
@@ -228,10 +265,15 @@
/* as usual, for the speed hungry :-) */
+#undef RAS_ARG
+#undef RAS_ARG_
+#undef RAS_VAR
+#undef RAS_VAR_
+
#ifndef FT_STATIC_RASTER
-#define RAS_ARG PWorker worker
-#define RAS_ARG_ PWorker worker,
+#define RAS_ARG gray_PWorker worker
+#define RAS_ARG_ gray_PWorker worker,
#define RAS_VAR worker
#define RAS_VAR_ worker,
@@ -249,6 +291,11 @@
/* must be at least 6 bits! */
#define PIXEL_BITS 8
+#undef FLOOR
+#undef CEILING
+#undef TRUNC
+#undef SCALED
+
#define ONE_PIXEL ( 1L << PIXEL_BITS )
#define PIXEL_MASK ( -1L << PIXEL_BITS )
#define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) )
@@ -266,6 +313,40 @@
#endif
+ /* Compute `dividend / divisor' and return both its quotient and */
+ /* remainder, cast to a specific type. This macro also ensures that */
+ /* the remainder is always positive. */
+#define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \
+ FT_BEGIN_STMNT \
+ (quotient) = (type)( (dividend) / (divisor) ); \
+ (remainder) = (type)( (dividend) % (divisor) ); \
+ if ( (remainder) < 0 ) \
+ { \
+ (quotient)--; \
+ (remainder) += (type)(divisor); \
+ } \
+ FT_END_STMNT
+
+#ifdef __arm__
+ /* Work around a bug specific to GCC which make the compiler fail to */
+ /* optimize a division and modulo operation on the same parameters */
+ /* into a single call to `__aeabi_idivmod'. See */
+ /* */
+ /* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721 */
+#undef FT_DIV_MOD
+#define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \
+ FT_BEGIN_STMNT \
+ (quotient) = (type)( (dividend) / (divisor) ); \
+ (remainder) = (type)( (dividend) - (quotient) * (divisor) ); \
+ if ( (remainder) < 0 ) \
+ { \
+ (quotient)--; \
+ (remainder) += (type)(divisor); \
+ } \
+ FT_END_STMNT
+#endif /* __arm__ */
+
+
/*************************************************************************/
/* */
/* TYPE DEFINITIONS */
@@ -298,7 +379,7 @@
#endif /* PIXEL_BITS >= 8 */
- /* maximal number of gray spans in a call to the span callback */
+ /* maximum number of gray spans in a call to the span callback */
#define FT_MAX_GRAY_SPANS 32
@@ -306,16 +387,26 @@
typedef struct TCell_
{
- TPos x; /* same with TWorker.ex */
- TCoord cover; /* same with TWorker.cover */
- TArea area;
- PCell next;
+ TPos x; /* same with gray_TWorker.ex */
+ TCoord cover; /* same with gray_TWorker.cover */
+ TArea area;
+ PCell next;
} TCell;
- typedef struct TWorker_
+#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
+ /* We disable the warning `structure was padded due to */
+ /* __declspec(align())' in order to compile cleanly with */
+ /* the maximum level of warnings. */
+#pragma warning( push )
+#pragma warning( disable : 4324 )
+#endif /* _MSC_VER */
+
+ typedef struct gray_TWorker_
{
+ ft_jmp_buf jump_buffer;
+
TCoord ex, ey;
TPos min_ex, max_ex;
TPos min_ey, max_ey;
@@ -325,7 +416,7 @@
TCoord cover;
int invalid;
- PCell cells;
+ PCell cells;
FT_PtrDist max_cells;
FT_PtrDist num_cells;
@@ -350,10 +441,6 @@
int band_size;
int band_shoot;
- int conic_level;
- int cubic_level;
-
- ft_jmp_buf jump_buffer;
void* buffer;
long buffer_size;
@@ -361,25 +448,29 @@
PCell* ycells;
TPos ycount;
- } TWorker, *PWorker;
+ } gray_TWorker, *gray_PWorker;
+
+#if defined( _MSC_VER )
+#pragma warning( pop )
+#endif
#ifndef FT_STATIC_RASTER
#define ras (*worker)
#else
- static TWorker ras;
+ static gray_TWorker ras;
#endif
- typedef struct TRaster_
+ typedef struct gray_TRaster_
{
- void* buffer;
- long buffer_size;
- int band_size;
- void* memory;
- PWorker worker;
+ void* buffer;
+ long buffer_size;
+ int band_size;
+ void* memory;
+ gray_PWorker worker;
- } TRaster, *PRaster;
+ } gray_TRaster, *gray_PRaster;
@@ -494,7 +585,7 @@
static void
gray_record_cell( RAS_ARG )
{
- if ( !ras.invalid && ( ras.area | ras.cover ) )
+ if ( ras.area | ras.cover )
{
PCell cell = gray_find_cell( RAS_VAR );
@@ -543,10 +634,10 @@
ras.area = 0;
ras.cover = 0;
+ ras.ex = ex;
+ ras.ey = ey;
}
- ras.ex = ex;
- ras.ey = ey;
ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey ||
ex >= ras.count_ex );
}
@@ -588,7 +679,7 @@
TPos x2,
TCoord y2 )
{
- TCoord ex1, ex2, fx1, fx2, delta, mod, lift, rem;
+ TCoord ex1, ex2, fx1, fx2, delta, mod;
long p, first, dx;
int incr;
@@ -632,13 +723,7 @@
dx = -dx;
}
- delta = (TCoord)( p / dx );
- mod = (TCoord)( p % dx );
- if ( mod < 0 )
- {
- delta--;
- mod += (TCoord)dx;
- }
+ FT_DIV_MOD( TCoord, p, dx, delta, mod );
ras.area += (TArea)(( fx1 + first ) * delta);
ras.cover += delta;
@@ -649,14 +734,11 @@
if ( ex1 != ex2 )
{
- p = ONE_PIXEL * ( y2 - y1 + delta );
- lift = (TCoord)( p / dx );
- rem = (TCoord)( p % dx );
- if ( rem < 0 )
- {
- lift--;
- rem += (TCoord)dx;
- }
+ TCoord lift, rem;
+
+
+ p = ONE_PIXEL * ( y2 - y1 + delta );
+ FT_DIV_MOD( TCoord, p, dx, lift, rem );
mod -= (int)dx;
@@ -706,9 +788,6 @@
dx = to_x - ras.x;
dy = to_y - ras.y;
- /* XXX: we should do something about the trivial case where dx == 0, */
- /* as it happens very often! */
-
/* perform vertical clipping */
{
TCoord min, max;
@@ -787,13 +866,7 @@
dy = -dy;
}
- delta = (int)( p / dy );
- mod = (int)( p % dy );
- if ( mod < 0 )
- {
- delta--;
- mod += (TCoord)dy;
- }
+ FT_DIV_MOD( int, p, dy, delta, mod );
x = ras.x + delta;
gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, (TCoord)first );
@@ -804,13 +877,7 @@
if ( ey1 != ey2 )
{
p = ONE_PIXEL * dx;
- lift = (int)( p / dy );
- rem = (int)( p % dy );
- if ( rem < 0 )
- {
- lift--;
- rem += (int)dy;
- }
+ FT_DIV_MOD( int, p, dy, lift, rem );
mod -= (int)dy;
while ( ey1 != ey2 )
@@ -870,81 +937,59 @@
const FT_Vector* to )
{
TPos dx, dy;
+ TPos min, max, y;
int top, level;
int* levels;
FT_Vector* arc;
- dx = DOWNSCALE( ras.x ) + to->x - ( control->x << 1 );
- if ( dx < 0 )
- dx = -dx;
- dy = DOWNSCALE( ras.y ) + to->y - ( control->y << 1 );
- if ( dy < 0 )
- dy = -dy;
- if ( dx < dy )
- dx = dy;
-
- level = 1;
- dx = dx / ras.conic_level;
- while ( dx > 0 )
- {
- dx >>= 2;
- level++;
- }
-
- /* a shortcut to speed things up */
- if ( level <= 1 )
- {
- /* we compute the mid-point directly in order to avoid */
- /* calling gray_split_conic() */
- TPos to_x, to_y, mid_x, mid_y;
-
-
- to_x = UPSCALE( to->x );
- to_y = UPSCALE( to->y );
- mid_x = ( ras.x + to_x + 2 * UPSCALE( control->x ) ) / 4;
- mid_y = ( ras.y + to_y + 2 * UPSCALE( control->y ) ) / 4;
-
- gray_render_line( RAS_VAR_ mid_x, mid_y );
- gray_render_line( RAS_VAR_ to_x, to_y );
-
- return;
- }
-
- arc = ras.bez_stack;
- levels = ras.lev_stack;
- top = 0;
- levels[0] = level;
+ levels = ras.lev_stack;
+ arc = ras.bez_stack;
arc[0].x = UPSCALE( to->x );
arc[0].y = UPSCALE( to->y );
arc[1].x = UPSCALE( control->x );
arc[1].y = UPSCALE( control->y );
arc[2].x = ras.x;
arc[2].y = ras.y;
+ top = 0;
- while ( top >= 0 )
- {
- level = levels[top];
- if ( level > 1 )
- {
- /* check that the arc crosses the current band */
- TPos min, max, y;
+ 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;
- 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;
+ 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;
+ level = 0;
+ do
+ {
+ dx >>= 2;
+ level++;
+ } while ( dx > ONE_PIXEL / 4 );
+ levels[0] = level;
+
+ do
+ {
+ level = levels[top];
+ if ( level > 0 )
+ {
gray_split_conic( arc );
arc += 2;
top++;
@@ -953,24 +998,11 @@
}
Draw:
- {
- TPos to_x, to_y, mid_x, mid_y;
-
-
- to_x = arc[0].x;
- to_y = arc[0].y;
- mid_x = ( ras.x + to_x + 2 * arc[1].x ) / 4;
- mid_y = ( ras.y + to_y + 2 * arc[1].y ) / 4;
-
- gray_render_line( RAS_VAR_ mid_x, mid_y );
- gray_render_line( RAS_VAR_ to_x, to_y );
-
- top--;
- arc -= 2;
- }
- }
+ gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
+ top--;
+ arc -= 2;
- return;
+ } while ( top >= 0 );
}
@@ -1007,59 +1039,10 @@
const FT_Vector* control2,
const FT_Vector* to )
{
- TPos dx, dy, da, db;
- int top, level;
- int* levels;
FT_Vector* arc;
+ TPos min, max, y;
- dx = DOWNSCALE( ras.x ) + to->x - ( control1->x << 1 );
- if ( dx < 0 )
- dx = -dx;
- dy = DOWNSCALE( ras.y ) + to->y - ( control1->y << 1 );
- if ( dy < 0 )
- dy = -dy;
- if ( dx < dy )
- dx = dy;
- da = dx;
-
- dx = DOWNSCALE( ras.x ) + to->x - 3 * ( control1->x + control2->x );
- if ( dx < 0 )
- dx = -dx;
- dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->x + control2->y );
- if ( dy < 0 )
- dy = -dy;
- if ( dx < dy )
- dx = dy;
- db = dx;
-
- level = 1;
- da = da / ras.cubic_level;
- db = db / ras.conic_level;
- while ( da > 0 || db > 0 )
- {
- da >>= 2;
- db >>= 3;
- level++;
- }
-
- if ( level <= 1 )
- {
- TPos to_x, to_y, mid_x, mid_y;
-
-
- to_x = UPSCALE( to->x );
- to_y = UPSCALE( to->y );
- mid_x = ( ras.x + to_x +
- 3 * UPSCALE( control1->x + control2->x ) ) / 8;
- mid_y = ( ras.y + to_y +
- 3 * UPSCALE( control1->y + control2->y ) ) / 8;
-
- gray_render_line( RAS_VAR_ mid_x, mid_y );
- gray_render_line( RAS_VAR_ to_x, to_y );
- return;
- }
-
arc = ras.bez_stack;
arc[0].x = UPSCALE( to->x );
arc[0].y = UPSCALE( to->y );
@@ -1070,69 +1053,109 @@
arc[3].x = ras.x;
arc[3].y = ras.y;
- levels = ras.lev_stack;
- top = 0;
- levels[0] = level;
+ /* Short-cut the arc that crosses the current band. */
+ min = max = arc[0].y;
- while ( top >= 0 )
+ 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[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;
+
+ for (;;)
{
- level = levels[top];
- if ( level > 1 )
- {
- /* 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;
- y = arc[3].y;
- if ( y < min ) min = y;
- if ( y > max ) max = y;
- if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 )
- goto Draw;
- gray_split_cubic( arc );
- arc += 3;
- top ++;
- levels[top] = levels[top - 1] = level - 1;
- continue;
- }
+ /* Decide whether to split or draw. See `Rapid Termination */
+ /* Evaluation for Recursive Subdivision of Bezier Curves' by Thomas */
+ /* F. Hain, at */
+ /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */
- Draw:
{
- TPos to_x, to_y, mid_x, mid_y;
+ TPos dx, dy, dx_, dy_;
+ TPos dx1, dy1, dx2, dy2;
+ TPos L, s, s_limit;
- to_x = arc[0].x;
- to_y = arc[0].y;
- mid_x = ( ras.x + to_x + 3 * ( arc[1].x + arc[2].x ) ) / 8;
- mid_y = ( ras.y + to_y + 3 * ( arc[1].y + arc[2].y ) ) / 8;
+ /* dx and dy are x and y components of the P0-P3 chord vector. */
+ dx = dx_ = arc[3].x - arc[0].x;
+ dy = dy_ = arc[3].y - arc[0].y;
- gray_render_line( RAS_VAR_ mid_x, mid_y );
- gray_render_line( RAS_VAR_ to_x, to_y );
- top --;
- arc -= 3;
+ L = FT_HYPOT( dx_, dy_ );
+
+ /* Avoid possible arithmetic overflow below by splitting. */
+ if ( L > 32767 )
+ goto Split;
+
+ /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */
+ s_limit = L * (TPos)( ONE_PIXEL / 6 );
+
+ /* s is L * the perpendicular distance from P1 to the line P0-P3. */
+ dx1 = arc[1].x - arc[0].x;
+ dy1 = arc[1].y - arc[0].y;
+ s = FT_ABS( dy * dx1 - dx * dy1 );
+
+ if ( s > s_limit )
+ goto Split;
+
+ /* s is L * the perpendicular distance from P2 to the line P0-P3. */
+ dx2 = arc[2].x - arc[0].x;
+ dy2 = arc[2].y - arc[0].y;
+ s = FT_ABS( dy * dx2 - dx * dy2 );
+
+ if ( s > s_limit )
+ goto Split;
+
+ /* Split super curvy segments where the off points are so far
+ from the chord that the angles P0-P1-P3 or P0-P2-P3 become
+ acute as detected by appropriate dot products. */
+ if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 ||
+ dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 )
+ goto Split;
+
+ /* No reason to split. */
+ goto Draw;
}
- }
- return;
- }
+ Split:
+ gray_split_cubic( arc );
+ arc += 3;
+ continue;
+ Draw:
+ gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
+
+ if ( arc == ras.bez_stack )
+ return;
+
+ arc -= 3;
+ }
+ }
static int
gray_move_to( const FT_Vector* to,
- PWorker worker )
+ gray_PWorker worker )
{
TPos x, y;
/* record current cell, if any */
- gray_record_cell( RAS_VAR );
+ if ( !ras.invalid )
+ gray_record_cell( RAS_VAR );
/* start to a new position */
x = UPSCALE( to->x );
@@ -1148,7 +1171,7 @@
static int
gray_line_to( const FT_Vector* to,
- PWorker worker )
+ gray_PWorker worker )
{
gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) );
return 0;
@@ -1158,7 +1181,7 @@
static int
gray_conic_to( const FT_Vector* control,
const FT_Vector* to,
- PWorker worker )
+ gray_PWorker worker )
{
gray_render_conic( RAS_VAR_ control, to );
return 0;
@@ -1169,7 +1192,7 @@
gray_cubic_to( const FT_Vector* control1,
const FT_Vector* control2,
const FT_Vector* to,
- PWorker worker )
+ gray_PWorker worker )
{
gray_render_cubic( RAS_VAR_ control1, control2, to );
return 0;
@@ -1180,7 +1203,7 @@
gray_render_span( int y,
int count,
const FT_Span* spans,
- PWorker worker )
+ gray_PWorker worker )
{
unsigned char* p;
FT_Bitmap* map = &worker->target;
@@ -1189,7 +1212,7 @@
/* first of all, compute the scanline offset */
p = (unsigned char*)map->buffer - y * map->pitch;
if ( map->pitch >= 0 )
- p += ( map->rows - 1 ) * map->pitch;
+ p += (unsigned)( ( map->rows - 1 ) * map->pitch );
for ( ; count > 0; count--, spans++ )
{
@@ -1233,9 +1256,7 @@
TPos area,
TCoord acount )
{
- FT_Span* span;
- int count;
- int coverage;
+ int coverage;
/* compute the coverage line's coverage, depending on the */
@@ -1277,6 +1298,10 @@
if ( coverage )
{
+ FT_Span* span;
+ int count;
+
+
/* see whether we can add this span to the current list */
count = ras.num_gray_spans;
span = ras.gray_spans + count - 1;
@@ -1315,7 +1340,6 @@
ras.num_gray_spans = 0;
ras.span_y = (int)y;
- count = 0;
span = ras.gray_spans;
}
else
@@ -1406,7 +1430,26 @@
ras.render_span( ras.span_y, ras.num_gray_spans,
ras.gray_spans, ras.render_span_data );
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+ if ( ras.num_gray_spans > 0 )
+ {
+ FT_Span* span;
+ int n;
+
+
+ FT_TRACE7(( "y = %3d ", ras.span_y ));
+ span = ras.gray_spans;
+ for ( n = 0; n < ras.num_gray_spans; n++, span++ )
+ FT_TRACE7(( "[%d..%d]:%02x ",
+ span->x, span->x + span->len - 1, span->coverage ));
+ FT_TRACE7(( "\n" ));
+ }
+
FT_TRACE7(( "gray_sweep: end\n" ));
+
+#endif /* FT_DEBUG_LEVEL_TRACE */
+
}
@@ -1472,8 +1515,11 @@
TPos delta;
- if ( !outline || !func_interface )
- return ErrRaster_Invalid_Argument;
+ if ( !outline )
+ return FT_THROW( Invalid_Outline );
+
+ if ( !func_interface )
+ return FT_THROW( Invalid_Argument );
shift = func_interface->shift;
delta = func_interface->delta;
@@ -1686,17 +1732,17 @@
return error;
Invalid_Outline:
- return ErrRaster_Invalid_Outline;
+ return FT_THROW( Invalid_Outline );
}
#endif /* _STANDALONE_ */
- typedef struct TBand_
+ typedef struct gray_TBand_
{
TPos min, max;
- } TBand;
+ } gray_TBand;
FT_DEFINE_OUTLINE_FUNCS(func_interface,
(FT_Outline_MoveTo_Func) gray_move_to,
@@ -1721,10 +1767,11 @@
if ( ft_setjmp( ras.jump_buffer ) == 0 )
{
error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras );
- gray_record_cell( RAS_VAR );
+ if ( !ras.invalid )
+ gray_record_cell( RAS_VAR );
}
else
- error = ErrRaster_Memory_Overflow;
+ error = FT_THROW( Memory_Overflow );
return error;
}
@@ -1733,11 +1780,11 @@
static int
gray_convert_glyph( RAS_ARG )
{
- TBand bands[40];
- TBand* volatile band;
- int volatile n, num_bands;
- TPos volatile min, max, max_y;
- FT_BBox* clip;
+ gray_TBand bands[40];
+ gray_TBand* volatile band;
+ int volatile n, num_bands;
+ TPos volatile min, max, max_y;
+ FT_BBox* clip;
/* Set up state in the raster object */
@@ -1759,25 +1806,6 @@
ras.count_ex = ras.max_ex - ras.min_ex;
ras.count_ey = ras.max_ey - ras.min_ey;
- /* simple heuristic used to speed up the bezier decomposition -- see */
- /* the code in gray_render_conic() and gray_render_cubic() for more */
- /* details */
- ras.conic_level = 32;
- ras.cubic_level = 16;
-
- {
- int level = 0;
-
-
- if ( ras.count_ex > 24 || ras.count_ey > 24 )
- level++;
- if ( ras.count_ex > 120 || ras.count_ey > 120 )
- level++;
-
- ras.conic_level <<= level;
- ras.cubic_level <<= level;
- }
-
/* set up vertical bands */
num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size );
if ( num_bands == 0 )
@@ -1820,7 +1848,7 @@
cell_start += sizeof ( TCell ) - cell_mod;
cell_end = ras.buffer_size;
- cell_end -= cell_end % sizeof( TCell );
+ cell_end -= cell_end % sizeof ( TCell );
cells_max = (PCell)( (char*)ras.buffer + cell_end );
ras.cells = (PCell)( (char*)ras.buffer + cell_start );
@@ -1887,30 +1915,30 @@
static int
- gray_raster_render( PRaster raster,
+ 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;
- PWorker worker;
+ gray_PWorker worker;
if ( !raster || !raster->buffer || !raster->buffer_size )
- return ErrRaster_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
if ( !outline )
- return ErrRaster_Invalid_Outline;
+ return FT_THROW( Invalid_Outline );
/* return immediately if the outline is empty */
if ( outline->n_points == 0 || outline->n_contours <= 0 )
return 0;
if ( !outline->contours || !outline->points )
- return ErrRaster_Invalid_Outline;
+ return FT_THROW( Invalid_Outline );
if ( outline->n_points !=
outline->contours[outline->n_contours - 1] + 1 )
- return ErrRaster_Invalid_Outline;
+ return FT_THROW( Invalid_Outline );
worker = raster->worker;
@@ -1918,19 +1946,19 @@
if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
{
if ( !target_map )
- return ErrRaster_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
/* nothing to do */
if ( !target_map->width || !target_map->rows )
return 0;
if ( !target_map->buffer )
- return ErrRaster_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
}
/* this version does not support monochrome rendering */
if ( !( params->flags & FT_RASTER_FLAG_AA ) )
- return ErrRaster_Invalid_Mode;
+ return FT_THROW( Invalid_Mode );
/* compute clipping box */
if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
@@ -1984,7 +2012,7 @@
gray_raster_new( void* memory,
FT_Raster* araster )
{
- static TRaster the_raster;
+ static gray_TRaster the_raster;
FT_UNUSED( memory );
@@ -2003,21 +2031,21 @@
FT_UNUSED( raster );
}
-#else /* _STANDALONE_ */
+#else /* !_STANDALONE_ */
static int
gray_raster_new( FT_Memory memory,
FT_Raster* araster )
{
- FT_Error error;
- PRaster raster;
+ FT_Error error;
+ gray_PRaster raster = NULL;
*araster = 0;
- if ( !FT_ALLOC( raster, sizeof ( TRaster ) ) )
+ if ( !FT_ALLOC( raster, sizeof ( gray_TRaster ) ) )
{
raster->memory = memory;
- *araster = (FT_Raster)raster;
+ *araster = (FT_Raster)raster;
}
return error;
@@ -2027,13 +2055,13 @@
static void
gray_raster_done( FT_Raster raster )
{
- FT_Memory memory = (FT_Memory)((PRaster)raster)->memory;
+ FT_Memory memory = (FT_Memory)((gray_PRaster)raster)->memory;
FT_FREE( raster );
}
-#endif /* _STANDALONE_ */
+#endif /* !_STANDALONE_ */
static void
@@ -2041,19 +2069,20 @@
char* pool_base,
long pool_size )
{
- PRaster rast = (PRaster)raster;
+ gray_PRaster rast = (gray_PRaster)raster;
if ( raster )
{
- if ( pool_base && pool_size >= (long)sizeof ( TWorker ) + 2048 )
+ if ( pool_base && pool_size >= (long)sizeof ( gray_TWorker ) + 2048 )
{
- PWorker worker = (PWorker)pool_base;
+ gray_PWorker worker = (gray_PWorker)pool_base;
rast->worker = worker;
rast->buffer = pool_base +
- ( ( sizeof ( TWorker ) + sizeof ( TCell ) - 1 ) &
+ ( ( sizeof ( gray_TWorker ) +
+ sizeof ( TCell ) - 1 ) &
~( sizeof ( TCell ) - 1 ) );
rast->buffer_size = (long)( ( pool_base + pool_size ) -
(char*)rast->buffer ) &
@@ -2071,12 +2100,26 @@
}
+ 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_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
)