|
|
|
@ -4,7 +4,7 @@ |
|
|
|
|
/* */ |
|
|
|
|
/* A new `perfect' anti-aliasing renderer (body). */ |
|
|
|
|
/* */ |
|
|
|
|
/* Copyright 2000-2001, 2002, 2003, 2005, 2006, 2007 by */ |
|
|
|
|
/* Copyright 2000-2001, 2002, 2003, 2005, 2006, 2007, 2008 by */ |
|
|
|
|
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
|
|
|
|
/* */ |
|
|
|
|
/* This file is part of the FreeType project, and may only be used, */ |
|
|
|
@ -91,11 +91,19 @@ |
|
|
|
|
#define FT_COMPONENT trace_smooth |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _STANDALONE_ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _STANDALONE_ |
|
|
|
|
/* define this to dump debugging information */ |
|
|
|
|
/* #define FT_DEBUG_LEVEL_TRACE */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <string.h> /* for ft_memcpy() */ |
|
|
|
|
#ifdef FT_DEBUG_LEVEL_TRACE |
|
|
|
|
#include <stdio.h> |
|
|
|
|
#include <stdarg.h> |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#include <string.h> |
|
|
|
|
#include <setjmp.h> |
|
|
|
|
#include <limits.h> |
|
|
|
|
#define FT_UINT_MAX UINT_MAX |
|
|
|
@ -118,24 +126,53 @@ |
|
|
|
|
#include "ftimage.h" |
|
|
|
|
#include "ftgrays.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* This macro is used to indicate that a function parameter is unused. */ |
|
|
|
|
/* Its purpose is simply to reduce compiler warnings. Note also that */ |
|
|
|
|
/* simply defining it as `(void)x' doesn't avoid warnings with certain */ |
|
|
|
|
/* ANSI compilers (e.g. LCC). */ |
|
|
|
|
#define FT_UNUSED( x ) (x) = (x) |
|
|
|
|
|
|
|
|
|
/* Disable the tracing mechanism for simplicity -- developers can */ |
|
|
|
|
/* activate it easily by redefining these two macros. */ |
|
|
|
|
|
|
|
|
|
/* we only use level 5 & 7 tracing messages; cf. ftdebug.h */ |
|
|
|
|
|
|
|
|
|
#ifdef FT_DEBUG_LEVEL_TRACE |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
FT_Message( const char* fmt, |
|
|
|
|
... ) |
|
|
|
|
{ |
|
|
|
|
va_list ap; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
va_start( ap, fmt ); |
|
|
|
|
vfprintf( stderr, fmt, ap ); |
|
|
|
|
va_end( ap ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* we don't handle tracing levels in stand-alone mode; */ |
|
|
|
|
#ifndef FT_TRACE5 |
|
|
|
|
#define FT_TRACE5( varformat ) FT_Message varformat |
|
|
|
|
#endif |
|
|
|
|
#ifndef FT_TRACE7 |
|
|
|
|
#define FT_TRACE7( varformat ) FT_Message varformat |
|
|
|
|
#endif |
|
|
|
|
#ifndef FT_ERROR |
|
|
|
|
#define FT_ERROR( x ) do ; while ( 0 ) /* nothing */ |
|
|
|
|
#define FT_ERROR( varformat ) FT_Message varformat |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifndef FT_TRACE |
|
|
|
|
#define FT_TRACE( x ) do ; while ( 0 ) /* nothing */ |
|
|
|
|
#endif |
|
|
|
|
#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 */ |
|
|
|
|
|
|
|
|
|
#endif /* !FT_DEBUG_LEVEL_TRACE */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#else /* !_STANDALONE_ */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <ft2build.h> |
|
|
|
|
#include "ftgrays.h" |
|
|
|
|
#include FT_INTERNAL_OBJECTS_H |
|
|
|
@ -160,10 +197,6 @@ |
|
|
|
|
#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/* define this to dump debugging information */ |
|
|
|
|
#define xxxDEBUG_GRAYS |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* as usual, for the speed hungry :-) */ |
|
|
|
|
|
|
|
|
|
#ifndef FT_STATIC_RASTER |
|
|
|
@ -1229,24 +1262,23 @@ |
|
|
|
|
if ( ras.render_span && count > 0 ) |
|
|
|
|
ras.render_span( ras.span_y, count, ras.gray_spans, |
|
|
|
|
ras.render_span_data ); |
|
|
|
|
/* ras.render_span( span->y, ras.gray_spans, count ); */ |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_GRAYS |
|
|
|
|
#ifdef FT_DEBUG_LEVEL_TRACE |
|
|
|
|
|
|
|
|
|
if ( ras.span_y >= 0 ) |
|
|
|
|
if ( count > 0 ) |
|
|
|
|
{ |
|
|
|
|
int n; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fprintf( stderr, "y=%3d ", ras.span_y ); |
|
|
|
|
FT_TRACE7(( "y = %3d ", ras.span_y )); |
|
|
|
|
span = ras.gray_spans; |
|
|
|
|
for ( n = 0; n < count; n++, span++ ) |
|
|
|
|
fprintf( stderr, "[%d..%d]:%02x ", |
|
|
|
|
span->x, span->x + span->len - 1, span->coverage ); |
|
|
|
|
fprintf( stderr, "\n" ); |
|
|
|
|
FT_TRACE7(( "[%d..%d]:%02x ", |
|
|
|
|
span->x, span->x + span->len - 1, span->coverage )); |
|
|
|
|
FT_TRACE7(( "\n" )); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif /* DEBUG_GRAYS */ |
|
|
|
|
#endif /* FT_DEBUG_LEVEL_TRACE */ |
|
|
|
|
|
|
|
|
|
ras.num_gray_spans = 0; |
|
|
|
|
ras.span_y = y; |
|
|
|
@ -1267,9 +1299,11 @@ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_GRAYS |
|
|
|
|
#ifdef FT_DEBUG_LEVEL_TRACE |
|
|
|
|
|
|
|
|
|
/* to be called while in the debugger */ |
|
|
|
|
/* to be called while in the debugger -- */ |
|
|
|
|
/* this function causes a compiler warning since it is unused otherwise */ |
|
|
|
|
static void |
|
|
|
|
gray_dump_cells( RAS_ARG ) |
|
|
|
|
{ |
|
|
|
|
int yindex; |
|
|
|
@ -1288,7 +1322,7 @@ |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif /* DEBUG_GRAYS */ |
|
|
|
|
#endif /* FT_DEBUG_LEVEL_TRACE */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
@ -1344,7 +1378,7 @@ |
|
|
|
|
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/* */ |
|
|
|
|
/* The following function should only compile in stand_alone mode, */ |
|
|
|
|
/* The following function should only compile in stand-alone mode, */ |
|
|
|
|
/* i.e., when building this component without the rest of FreeType. */ |
|
|
|
|
/* */ |
|
|
|
|
/*************************************************************************/ |
|
|
|
@ -1355,18 +1389,19 @@ |
|
|
|
|
/* FT_Outline_Decompose */ |
|
|
|
|
/* */ |
|
|
|
|
/* <Description> */ |
|
|
|
|
/* Walks over an outline's structure to decompose it into individual */ |
|
|
|
|
/* segments and Bezier arcs. This function is also able to emit */ |
|
|
|
|
/* Walk over an outline's structure to decompose it into individual */ |
|
|
|
|
/* segments and Bézier arcs. This function is also able to emit */ |
|
|
|
|
/* `move to' and `close to' operations to indicate the start and end */ |
|
|
|
|
/* of new contours in the outline. */ |
|
|
|
|
/* */ |
|
|
|
|
/* <Input> */ |
|
|
|
|
/* outline :: A pointer to the source target. */ |
|
|
|
|
/* */ |
|
|
|
|
/* func_interface :: A table of `emitters', i.e,. function pointers */ |
|
|
|
|
/* func_interface :: A table of `emitters', i.e., function pointers */ |
|
|
|
|
/* called during decomposition to indicate path */ |
|
|
|
|
/* operations. */ |
|
|
|
|
/* */ |
|
|
|
|
/* <InOut> */ |
|
|
|
|
/* user :: A typeless pointer which is passed to each */ |
|
|
|
|
/* emitter during the decomposition. It can be */ |
|
|
|
|
/* used to store the state during the */ |
|
|
|
@ -1375,17 +1410,13 @@ |
|
|
|
|
/* <Return> */ |
|
|
|
|
/* Error code. 0 means success. */ |
|
|
|
|
/* */ |
|
|
|
|
static |
|
|
|
|
int FT_Outline_Decompose( const FT_Outline* outline, |
|
|
|
|
const FT_Outline_Funcs* func_interface, |
|
|
|
|
void* user ) |
|
|
|
|
static int |
|
|
|
|
FT_Outline_Decompose( const FT_Outline* outline, |
|
|
|
|
const FT_Outline_Funcs* func_interface, |
|
|
|
|
void* user ) |
|
|
|
|
{ |
|
|
|
|
#undef SCALED |
|
|
|
|
#if 0 |
|
|
|
|
#define SCALED( x ) ( ( (x) << shift ) - delta ) |
|
|
|
|
#else |
|
|
|
|
#define SCALED( x ) (x) |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
FT_Vector v_last; |
|
|
|
|
FT_Vector v_control; |
|
|
|
@ -1395,17 +1426,21 @@ |
|
|
|
|
FT_Vector* limit; |
|
|
|
|
char* tags; |
|
|
|
|
|
|
|
|
|
int error; |
|
|
|
|
|
|
|
|
|
int n; /* index of contour in outline */ |
|
|
|
|
int first; /* index of first point in contour */ |
|
|
|
|
int error; |
|
|
|
|
char tag; /* current point's state */ |
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
int shift = func_interface->shift; |
|
|
|
|
TPos delta = func_interface->delta; |
|
|
|
|
#endif |
|
|
|
|
int shift; |
|
|
|
|
TPos delta; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( !outline || !func_interface ) |
|
|
|
|
return ErrRaster_Invalid_Argument; |
|
|
|
|
|
|
|
|
|
shift = func_interface->shift; |
|
|
|
|
delta = func_interface->delta; |
|
|
|
|
first = 0; |
|
|
|
|
|
|
|
|
|
for ( n = 0; n < outline->n_contours; n++ ) |
|
|
|
@ -1413,22 +1448,25 @@ |
|
|
|
|
int last; /* index of last point in contour */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n )); |
|
|
|
|
|
|
|
|
|
last = outline->contours[n]; |
|
|
|
|
if ( last < 0 ) |
|
|
|
|
goto Invalid_Outline; |
|
|
|
|
limit = outline->points + last; |
|
|
|
|
|
|
|
|
|
v_start = outline->points[first]; |
|
|
|
|
v_last = outline->points[last]; |
|
|
|
|
|
|
|
|
|
v_start = outline->points[first]; |
|
|
|
|
v_start.x = SCALED( v_start.x ); |
|
|
|
|
v_start.y = SCALED( v_start.y ); |
|
|
|
|
|
|
|
|
|
v_last.x = SCALED( v_last.x ); |
|
|
|
|
v_last.y = SCALED( v_last.y ); |
|
|
|
|
v_last = outline->points[last]; |
|
|
|
|
v_last.x = SCALED( v_last.x ); |
|
|
|
|
v_last.y = SCALED( v_last.y ); |
|
|
|
|
|
|
|
|
|
v_control = v_start; |
|
|
|
|
|
|
|
|
|
point = outline->points + first; |
|
|
|
|
tags = outline->tags + first; |
|
|
|
|
tags = outline->tags + first; |
|
|
|
|
tag = FT_CURVE_TAG( tags[0] ); |
|
|
|
|
|
|
|
|
|
/* A contour cannot start with a cubic control point! */ |
|
|
|
@ -1459,6 +1497,8 @@ |
|
|
|
|
tags--; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
FT_TRACE5(( " move to (%.2f, %.2f)\n", |
|
|
|
|
v_start.x / 64.0, v_start.y / 64.0 )); |
|
|
|
|
error = func_interface->move_to( &v_start, user ); |
|
|
|
|
if ( error ) |
|
|
|
|
goto Exit; |
|
|
|
@ -1479,6 +1519,8 @@ |
|
|
|
|
vec.x = SCALED( point->x ); |
|
|
|
|
vec.y = SCALED( point->y ); |
|
|
|
|
|
|
|
|
|
FT_TRACE5(( " line to (%.2f, %.2f)\n", |
|
|
|
|
vec.x / 64.0, vec.y / 64.0 )); |
|
|
|
|
error = func_interface->line_to( &vec, user ); |
|
|
|
|
if ( error ) |
|
|
|
|
goto Exit; |
|
|
|
@ -1486,53 +1528,60 @@ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case FT_CURVE_TAG_CONIC: /* consume conic arcs */ |
|
|
|
|
{ |
|
|
|
|
v_control.x = SCALED( point->x ); |
|
|
|
|
v_control.y = SCALED( point->y ); |
|
|
|
|
v_control.x = SCALED( point->x ); |
|
|
|
|
v_control.y = SCALED( point->y ); |
|
|
|
|
|
|
|
|
|
Do_Conic: |
|
|
|
|
if ( point < limit ) |
|
|
|
|
{ |
|
|
|
|
FT_Vector vec; |
|
|
|
|
FT_Vector v_middle; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
point++; |
|
|
|
|
tags++; |
|
|
|
|
tag = FT_CURVE_TAG( tags[0] ); |
|
|
|
|
|
|
|
|
|
vec.x = SCALED( point->x ); |
|
|
|
|
vec.y = SCALED( point->y ); |
|
|
|
|
Do_Conic: |
|
|
|
|
if ( point < limit ) |
|
|
|
|
{ |
|
|
|
|
FT_Vector vec; |
|
|
|
|
FT_Vector v_middle; |
|
|
|
|
|
|
|
|
|
if ( tag == FT_CURVE_TAG_ON ) |
|
|
|
|
{ |
|
|
|
|
error = func_interface->conic_to( &v_control, &vec, |
|
|
|
|
user ); |
|
|
|
|
if ( error ) |
|
|
|
|
goto Exit; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ( tag != FT_CURVE_TAG_CONIC ) |
|
|
|
|
goto Invalid_Outline; |
|
|
|
|
point++; |
|
|
|
|
tags++; |
|
|
|
|
tag = FT_CURVE_TAG( tags[0] ); |
|
|
|
|
|
|
|
|
|
v_middle.x = ( v_control.x + vec.x ) / 2; |
|
|
|
|
v_middle.y = ( v_control.y + vec.y ) / 2; |
|
|
|
|
vec.x = SCALED( point->x ); |
|
|
|
|
vec.y = SCALED( point->y ); |
|
|
|
|
|
|
|
|
|
error = func_interface->conic_to( &v_control, &v_middle, |
|
|
|
|
user ); |
|
|
|
|
if ( tag == FT_CURVE_TAG_ON ) |
|
|
|
|
{ |
|
|
|
|
FT_TRACE5(( " conic to (%.2f, %.2f)" |
|
|
|
|
" with control (%.2f, %.2f)\n", |
|
|
|
|
vec.x / 64.0, vec.y / 64.0, |
|
|
|
|
v_control.x / 64.0, v_control.y / 64.0 )); |
|
|
|
|
error = func_interface->conic_to( &v_control, &vec, user ); |
|
|
|
|
if ( error ) |
|
|
|
|
goto Exit; |
|
|
|
|
|
|
|
|
|
v_control = vec; |
|
|
|
|
goto Do_Conic; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
error = func_interface->conic_to( &v_control, &v_start, |
|
|
|
|
user ); |
|
|
|
|
goto Close; |
|
|
|
|
if ( tag != FT_CURVE_TAG_CONIC ) |
|
|
|
|
goto Invalid_Outline; |
|
|
|
|
|
|
|
|
|
v_middle.x = ( v_control.x + vec.x ) / 2; |
|
|
|
|
v_middle.y = ( v_control.y + vec.y ) / 2; |
|
|
|
|
|
|
|
|
|
FT_TRACE5(( " conic to (%.2f, %.2f)" |
|
|
|
|
" with control (%.2f, %.2f)\n", |
|
|
|
|
v_middle.x / 64.0, v_middle.y / 64.0, |
|
|
|
|
v_control.x / 64.0, v_control.y / 64.0 )); |
|
|
|
|
error = func_interface->conic_to( &v_control, &v_middle, user ); |
|
|
|
|
if ( error ) |
|
|
|
|
goto Exit; |
|
|
|
|
|
|
|
|
|
v_control = vec; |
|
|
|
|
goto Do_Conic; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
FT_TRACE5(( " conic to (%.2f, %.2f)" |
|
|
|
|
" with control (%.2f, %.2f)\n", |
|
|
|
|
v_start.x / 64.0, v_start.y / 64.0, |
|
|
|
|
v_control.x / 64.0, v_control.y / 64.0 )); |
|
|
|
|
error = func_interface->conic_to( &v_control, &v_start, user ); |
|
|
|
|
goto Close; |
|
|
|
|
|
|
|
|
|
default: /* FT_CURVE_TAG_CUBIC */ |
|
|
|
|
{ |
|
|
|
|
FT_Vector vec1, vec2; |
|
|
|
@ -1559,12 +1608,22 @@ |
|
|
|
|
vec.x = SCALED( point->x ); |
|
|
|
|
vec.y = SCALED( point->y ); |
|
|
|
|
|
|
|
|
|
FT_TRACE5(( " cubic to (%.2f, %.2f)" |
|
|
|
|
" with controls (%.2f, %.2f) and (%.2f, %.2f)\n", |
|
|
|
|
vec.x / 64.0, vec.y / 64.0, |
|
|
|
|
vec1.x / 64.0, vec1.y / 64.0, |
|
|
|
|
vec2.x / 64.0, vec2.y / 64.0 )); |
|
|
|
|
error = func_interface->cubic_to( &vec1, &vec2, &vec, user ); |
|
|
|
|
if ( error ) |
|
|
|
|
goto Exit; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
FT_TRACE5(( " cubic to (%.2f, %.2f)" |
|
|
|
|
" with controls (%.2f, %.2f) and (%.2f, %.2f)\n", |
|
|
|
|
v_start.x / 64.0, v_start.y / 64.0, |
|
|
|
|
vec1.x / 64.0, vec1.y / 64.0, |
|
|
|
|
vec2.x / 64.0, vec2.y / 64.0 )); |
|
|
|
|
error = func_interface->cubic_to( &vec1, &vec2, &v_start, user ); |
|
|
|
|
goto Close; |
|
|
|
|
} |
|
|
|
@ -1572,6 +1631,8 @@ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* close the contour with a line segment */ |
|
|
|
|
FT_TRACE5(( " line to (%.2f, %.2f)\n", |
|
|
|
|
v_start.x / 64.0, v_start.y / 64.0 )); |
|
|
|
|
error = func_interface->line_to( &v_start, user ); |
|
|
|
|
|
|
|
|
|
Close: |
|
|
|
@ -1581,9 +1642,11 @@ |
|
|
|
|
first = last + 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
Exit: |
|
|
|
|
FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); |
|
|
|
|
return error; |
|
|
|
|
|
|
|
|
|
Invalid_Outline: |
|
|
|
@ -1665,7 +1728,7 @@ |
|
|
|
|
ras.cubic_level = 16; |
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
int level = 0; |
|
|
|
|
int level = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( ras.count_ex > 24 || ras.count_ey > 24 ) |
|
|
|
@ -1761,8 +1824,8 @@ |
|
|
|
|
/* be some problems. */ |
|
|
|
|
if ( middle == bottom ) |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG_GRAYS |
|
|
|
|
fprintf( stderr, "Rotten glyph!\n" ); |
|
|
|
|
#ifdef FT_DEBUG_LEVEL_TRACE |
|
|
|
|
FT_TRACE7(( "gray_convert_glyph: Rotten glyph!\n" )); |
|
|
|
|
#endif |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
@ -1876,8 +1939,8 @@ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ |
|
|
|
|
/**** a static object. *****/ |
|
|
|
|
/**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/ |
|
|
|
|
/**** a static object. *****/ |
|
|
|
|
|
|
|
|
|
#ifdef _STANDALONE_ |
|
|
|
|
|
|
|
|
@ -1985,3 +2048,8 @@ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* END */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Local Variables: */ |
|
|
|
|
/* coding: utf-8 */ |
|
|
|
|
/* End: */ |
|
|
|
|