diff options
Diffstat (limited to 'src/smooth')
-rw-r--r-- | src/smooth/ftgrays.c | 102 | ||||
-rw-r--r-- | src/smooth/ftsmooth.c | 80 | ||||
-rw-r--r-- | src/smooth/ftspic.c | 37 | ||||
-rw-r--r-- | src/smooth/ftspic.h | 17 |
4 files changed, 168 insertions, 68 deletions
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c index 4c0eea5..d2158e7 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-2012 by */ +/* Copyright 2000-2003, 2005-2013 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_ + /* 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 this to dump debugging information */ /* #define FT_DEBUG_LEVEL_TRACE */ @@ -154,6 +159,21 @@ typedef ptrdiff_t FT_PtrDist; 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 @@ -165,11 +185,19 @@ typedef ptrdiff_t FT_PtrDist; #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 */ @@ -202,6 +230,7 @@ typedef ptrdiff_t FT_PtrDist; raster_done_ \ }; + #else /* !_STANDALONE_ */ @@ -215,13 +244,14 @@ typedef ptrdiff_t FT_PtrDist; #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 @@ -312,7 +342,7 @@ typedef ptrdiff_t FT_PtrDist; #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 @@ -600,7 +630,7 @@ typedef ptrdiff_t FT_PtrDist; 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; @@ -661,6 +691,9 @@ typedef ptrdiff_t FT_PtrDist; if ( ex1 != ex2 ) { + TCoord lift, rem; + + p = ONE_PIXEL * ( y2 - y1 + delta ); lift = (TCoord)( p / dx ); rem = (TCoord)( p % dx ); @@ -1091,11 +1124,11 @@ typedef ptrdiff_t FT_PtrDist; if ( s > s_limit ) goto Split; - /* If P1 or P2 is outside P0-P3, split the curve. */ - if ( dy * dy1 + dx * dx1 < 0 || - dy * dy2 + dx * dx2 < 0 || - dy * (arc[3].y - arc[1].y) + dx * (arc[3].x - arc[1].x) < 0 || - dy * (arc[3].y - arc[2].y) + dx * (arc[3].x - arc[2].x) < 0 ) + /* 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. */ @@ -1227,9 +1260,7 @@ typedef ptrdiff_t FT_PtrDist; TPos area, TCoord acount ) { - FT_Span* span; - int count; - int coverage; + int coverage; /* compute the coverage line's coverage, depending on the */ @@ -1271,6 +1302,10 @@ typedef ptrdiff_t FT_PtrDist; 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; @@ -1400,7 +1435,26 @@ typedef ptrdiff_t FT_PtrDist; 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 */ + } @@ -1467,7 +1521,7 @@ typedef ptrdiff_t FT_PtrDist; if ( !outline || !func_interface ) - return ErrRaster_Invalid_Argument; + return FT_THROW( Invalid_Argument ); shift = func_interface->shift; delta = func_interface->delta; @@ -1680,7 +1734,7 @@ typedef ptrdiff_t FT_PtrDist; return error; Invalid_Outline: - return ErrRaster_Invalid_Outline; + return FT_THROW( Invalid_Outline ); } #endif /* _STANDALONE_ */ @@ -1718,7 +1772,7 @@ typedef ptrdiff_t FT_PtrDist; gray_record_cell( RAS_VAR ); } else - error = ErrRaster_Memory_Overflow; + error = FT_THROW( Memory_Overflow ); return error; } @@ -1871,21 +1925,21 @@ typedef ptrdiff_t FT_PtrDist; 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; @@ -1893,19 +1947,19 @@ typedef ptrdiff_t FT_PtrDist; 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 ) ) diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c index 00499cc..89088cd 100644 --- a/src/smooth/ftsmooth.c +++ b/src/smooth/ftsmooth.c @@ -4,7 +4,7 @@ /* */ /* Anti-aliasing renderer interface (body). */ /* */ -/* Copyright 2000-2006, 2009-2012 by */ +/* Copyright 2000-2006, 2009-2013 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -61,12 +61,12 @@ const FT_Matrix* matrix, const FT_Vector* delta ) { - FT_Error error = Smooth_Err_Ok; + FT_Error error = FT_Err_Ok; if ( slot->format != render->glyph_format ) { - error = Smooth_Err_Invalid_Argument; + error = FT_THROW( Invalid_Argument ); goto Exit; } @@ -109,31 +109,43 @@ #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING FT_Pos height_org, width_org; #endif - FT_Bitmap* bitmap; - FT_Memory memory; - FT_Int hmul = mode == FT_RENDER_MODE_LCD; - FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; - FT_Pos x_shift, y_shift, x_left, y_top; + FT_Bitmap* bitmap = &slot->bitmap; + FT_Memory memory = render->root.memory; + FT_Int hmul = mode == FT_RENDER_MODE_LCD; + FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; + FT_Pos x_shift = 0; + FT_Pos y_shift = 0; + FT_Pos x_left, y_top; FT_Raster_Params params; + FT_Bool have_translated_origin = FALSE; + FT_Bool have_outline_shifted = FALSE; + FT_Bool have_buffer = FALSE; + /* check glyph image format */ if ( slot->format != render->glyph_format ) { - error = Smooth_Err_Invalid_Argument; + error = FT_THROW( Invalid_Argument ); goto Exit; } /* check mode */ if ( mode != required_mode ) - return Smooth_Err_Cannot_Render_Glyph; + { + error = FT_THROW( Cannot_Render_Glyph ); + goto Exit; + } outline = &slot->outline; /* translate the outline to the new origin if needed */ if ( origin ) + { FT_Outline_Translate( outline, origin->x, origin->y ); + have_translated_origin = TRUE; + } /* compute the control box, and grid fit it */ FT_Outline_Get_CBox( outline, &cbox ); @@ -148,24 +160,23 @@ FT_ERROR(( "ft_smooth_render_generic: glyph too large:" " xMin = %d, xMax = %d\n", cbox.xMin >> 6, cbox.xMax >> 6 )); - return Smooth_Err_Raster_Overflow; + error = FT_THROW( Raster_Overflow ); + goto Exit; } else - width = ( cbox.xMax - cbox.xMin ) >> 6; + width = ( cbox.xMax - cbox.xMin ) >> 6; if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin ) { FT_ERROR(( "ft_smooth_render_generic: glyph too large:" " yMin = %d, yMax = %d\n", cbox.yMin >> 6, cbox.yMax >> 6 )); - return Smooth_Err_Raster_Overflow; + error = FT_THROW( Raster_Overflow ); + goto Exit; } else height = ( cbox.yMax - cbox.yMin ) >> 6; - bitmap = &slot->bitmap; - memory = render->root.memory; - #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING width_org = width; height_org = height; @@ -221,13 +232,14 @@ #if FT_UINT_MAX > 0xFFFFU - /* Required check is ( pitch * height < FT_ULONG_MAX ), */ - /* but we care realistic cases only. Always pitch <= width. */ + /* Required check is (pitch * height < FT_ULONG_MAX), */ + /* but we care realistic cases only. Always pitch <= width. */ if ( width > 0x7FFF || height > 0x7FFF ) { FT_ERROR(( "ft_smooth_render_generic: glyph too large: %u x %u\n", width, height )); - return Smooth_Err_Raster_Overflow; + error = FT_THROW( Raster_Overflow ); + goto Exit; } #endif @@ -240,9 +252,12 @@ /* translate outline to render it into the bitmap */ FT_Outline_Translate( outline, -x_shift, -y_shift ); + have_outline_shifted = TRUE; if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) goto Exit; + else + have_buffer = TRUE; slot->internal->flags |= FT_GLYPH_OWN_BITMAP; @@ -288,6 +303,9 @@ vec->y /= 3; } + if ( error ) + goto Exit; + if ( slot->library->lcd_filter_func ) slot->library->lcd_filter_func( bitmap, mode, slot->library ); @@ -295,6 +313,8 @@ /* render outline into bitmap */ error = render->raster_render( render->raster, ¶ms ); + if ( error ) + goto Exit; /* expand it horizontally */ if ( hmul ) @@ -346,25 +366,35 @@ #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - FT_Outline_Translate( outline, x_shift, y_shift ); - /* * XXX: on 16bit system, we return an error for huge bitmap * to prevent an overflow. */ if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX ) - return Smooth_Err_Invalid_Pixel_Size; - - if ( error ) + { + error = FT_THROW( Invalid_Pixel_Size ); goto Exit; + } slot->format = FT_GLYPH_FORMAT_BITMAP; slot->bitmap_left = (FT_Int)x_left; slot->bitmap_top = (FT_Int)y_top; + /* everything is fine; don't deallocate buffer */ + have_buffer = FALSE; + + error = FT_Err_Ok; + Exit: - if ( outline && origin ) + if ( have_outline_shifted ) + FT_Outline_Translate( outline, x_shift, y_shift ); + if ( have_translated_origin ) FT_Outline_Translate( outline, -origin->x, -origin->y ); + if ( have_buffer ) + { + FT_FREE( bitmap->buffer ); + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } return error; } diff --git a/src/smooth/ftspic.c b/src/smooth/ftspic.c index 601bcf9..67a2b83 100644 --- a/src/smooth/ftspic.c +++ b/src/smooth/ftspic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for smooth module. */ /* */ -/* Copyright 2009, 2010 by */ +/* Copyright 2009, 2010, 2012, 2013 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,17 +22,19 @@ #include "ftspic.h" #include "ftsmerrs.h" + #ifdef FT_CONFIG_OPTION_PIC /* forward declaration of PIC init functions from ftgrays.c */ void FT_Init_Class_ft_grays_raster( FT_Raster_Funcs* funcs ); + void ft_smooth_renderer_class_pic_free( FT_Library library ) { FT_PIC_Container* pic_container = &library->pic_container; - FT_Memory memory = library->memory; + FT_Memory memory = library->memory; if ( pic_container->smooth ) @@ -42,6 +44,7 @@ if ( --container->ref_count ) return; + FT_FREE( container ); pic_container->smooth = NULL; } @@ -52,8 +55,8 @@ ft_smooth_renderer_class_pic_init( FT_Library library ) { FT_PIC_Container* pic_container = &library->pic_container; - FT_Error error = Smooth_Err_Ok; - SmoothPIC* container; + FT_Error error = FT_Err_Ok; + SmoothPIC* container = NULL; FT_Memory memory = library->memory; @@ -66,37 +69,45 @@ } /* allocate pointer, clear and set global container pointer */ - if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + if ( FT_ALLOC( container, sizeof ( *container ) ) ) return error; FT_MEM_SET( container, 0, sizeof ( *container ) ); pic_container->smooth = container; + container->ref_count = 1; - /* initialize pointer table - this is how the module usually expects this data */ + /* initialize pointer table - */ + /* this is how the module usually expects this data */ FT_Init_Class_ft_grays_raster( &container->ft_grays_raster ); -/*Exit:*/ - if ( error ) - ft_smooth_renderer_class_pic_free( library ); + return error; } + /* re-route these init and free functions to the above functions */ - FT_Error ft_smooth_lcd_renderer_class_pic_init( FT_Library library ) + FT_Error + ft_smooth_lcd_renderer_class_pic_init( FT_Library library ) { return ft_smooth_renderer_class_pic_init( library ); } - void ft_smooth_lcd_renderer_class_pic_free( FT_Library library ) + + void + ft_smooth_lcd_renderer_class_pic_free( FT_Library library ) { ft_smooth_renderer_class_pic_free( library ); } - FT_Error ft_smooth_lcdv_renderer_class_pic_init( FT_Library library ) + + FT_Error + ft_smooth_lcdv_renderer_class_pic_init( FT_Library library ) { return ft_smooth_renderer_class_pic_init( library ); } - void ft_smooth_lcdv_renderer_class_pic_free( FT_Library library ) + + void + ft_smooth_lcdv_renderer_class_pic_free( FT_Library library ) { ft_smooth_renderer_class_pic_free( library ); } diff --git a/src/smooth/ftspic.h b/src/smooth/ftspic.h index 4686f5e..334b51c 100644 --- a/src/smooth/ftspic.h +++ b/src/smooth/ftspic.h @@ -25,18 +25,23 @@ FT_BEGIN_HEADER #include FT_INTERNAL_PIC_H #ifndef FT_CONFIG_OPTION_PIC -#define FT_GRAYS_RASTER_GET ft_grays_raster + +#define FT_GRAYS_RASTER_GET ft_grays_raster #else /* FT_CONFIG_OPTION_PIC */ - typedef struct SmoothPIC_ + typedef struct SmoothPIC_ { - int ref_count; - FT_Raster_Funcs ft_grays_raster; + int ref_count; + FT_Raster_Funcs ft_grays_raster; + } SmoothPIC; -#define GET_PIC(lib) ((SmoothPIC*)((lib)->pic_container.smooth)) -#define FT_GRAYS_RASTER_GET (GET_PIC(library)->ft_grays_raster) + +#define GET_PIC( lib ) \ + ( (SmoothPIC*)( (lib)->pic_container.smooth ) ) +#define FT_GRAYS_RASTER_GET ( GET_PIC( library )->ft_grays_raster ) + /* see ftspic.c for the implementation */ void |