diff options
Diffstat (limited to 'src/base')
33 files changed, 1530 insertions, 1515 deletions
diff --git a/src/base/basepic.c b/src/base/basepic.c index aeb6fd5..9850ed9 100644 --- a/src/base/basepic.c +++ b/src/base/basepic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for base. */ /* */ -/* Copyright 2009, 2012, 2013 by */ +/* Copyright 2009-2015 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/base/basepic.h b/src/base/basepic.h index 329d7c8..51ecf9e 100644 --- a/src/base/basepic.h +++ b/src/base/basepic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for base. */ /* */ -/* Copyright 2009 by */ +/* Copyright 2009-2015 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/base/ftadvanc.c b/src/base/ftadvanc.c index 5207847..f12908f 100644 --- a/src/base/ftadvanc.c +++ b/src/base/ftadvanc.c @@ -4,7 +4,7 @@ /* */ /* Quick computation of advance widths (body). */ /* */ -/* Copyright 2008, 2009, 2011, 2013 by */ +/* Copyright 2008-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -80,6 +80,9 @@ if ( !face ) return FT_THROW( Invalid_Face_Handle ); + if ( !padvance ) + return FT_THROW( Invalid_Argument ); + if ( gindex >= (FT_UInt)face->num_glyphs ) return FT_THROW( Invalid_Glyph_Index ); @@ -118,6 +121,9 @@ if ( !face ) return FT_THROW( Invalid_Face_Handle ); + if ( !padvances ) + return FT_THROW( Invalid_Argument ); + num = (FT_UInt)face->num_glyphs; end = start + count; if ( start >= num || end < start || end > num ) diff --git a/src/base/ftapi.c b/src/base/ftapi.c index 8914d1f..f22a181 100644 --- a/src/base/ftapi.c +++ b/src/base/ftapi.c @@ -4,7 +4,7 @@ /* */ /* The FreeType compatibility functions (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/base/ftbase.c b/src/base/ftbase.c index 5e5d70e..253dfb7 100644 --- a/src/base/ftbase.c +++ b/src/base/ftbase.c @@ -4,7 +4,7 @@ /* */ /* Single object library component (body only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/base/ftbase.h b/src/base/ftbase.h index 51a1db1..cb57f96 100644 --- a/src/base/ftbase.h +++ b/src/base/ftbase.h @@ -4,7 +4,7 @@ /* */ /* The FreeType private functions used in base module (specification). */ /* */ -/* Copyright 2008, 2010 by */ +/* Copyright 2008-2015 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/base/ftbbox.c b/src/base/ftbbox.c index 8d3f383..10df98d 100644 --- a/src/base/ftbbox.c +++ b/src/base/ftbbox.c @@ -4,7 +4,7 @@ /* */ /* FreeType bbox computation (body). */ /* */ -/* Copyright 1996-2002, 2004, 2006, 2010, 2013 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -42,16 +42,35 @@ } TBBox_Rec; +#define FT_UPDATE_BBOX( p, bbox ) \ + FT_BEGIN_STMNT \ + if ( p->x < bbox.xMin ) \ + bbox.xMin = p->x; \ + if ( p->x > bbox.xMax ) \ + bbox.xMax = p->x; \ + if ( p->y < bbox.yMin ) \ + bbox.yMin = p->y; \ + if ( p->y > bbox.yMax ) \ + bbox.yMax = p->y; \ + FT_END_STMNT + +#define CHECK_X( p, bbox ) \ + ( p->x < bbox.xMin || p->x > bbox.xMax ) + +#define CHECK_Y( p, bbox ) \ + ( p->y < bbox.yMin || p->y > bbox.yMax ) + + /*************************************************************************/ /* */ /* <Function> */ /* BBox_Move_To */ /* */ /* <Description> */ - /* This function is used as a `move_to' and `line_to' emitter during */ + /* This function is used as a `move_to' emitter during */ /* FT_Outline_Decompose(). It simply records the destination point */ - /* in `user->last'; no further computations are necessary since we */ - /* use the cbox as the starting bbox which must be refined. */ + /* in `user->last'. We also update bbox in case contour starts with */ + /* an implicit `on' point. */ /* */ /* <Input> */ /* to :: A pointer to the destination vector. */ @@ -66,17 +85,42 @@ BBox_Move_To( FT_Vector* to, TBBox_Rec* user ) { + FT_UPDATE_BBOX( to, user->bbox ); + user->last = *to; return 0; } -#define CHECK_X( p, bbox ) \ - ( p->x < bbox.xMin || p->x > bbox.xMax ) + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Line_To */ + /* */ + /* <Description> */ + /* This function is used as a `line_to' emitter during */ + /* FT_Outline_Decompose(). It simply records the destination point */ + /* in `user->last'; no further computations are necessary because */ + /* bbox already contains both explicit ends of the line segment. */ + /* */ + /* <Input> */ + /* to :: A pointer to the destination vector. */ + /* */ + /* <InOut> */ + /* user :: A pointer to the current walk context. */ + /* */ + /* <Return> */ + /* Always 0. Needed for the interface only. */ + /* */ + static int + BBox_Line_To( FT_Vector* to, + TBBox_Rec* user ) + { + user->last = *to; -#define CHECK_Y( p, bbox ) \ - ( p->y < bbox.yMin || p->y > bbox.yMax ) + return 0; + } /*************************************************************************/ @@ -155,8 +199,8 @@ FT_Vector* to, TBBox_Rec* user ) { - /* we don't need to check `to' since it is always an `on' point, thus */ - /* within the bbox */ + /* in case `to' is implicit and not included in bbox yet */ + FT_UPDATE_BBOX( to, user->bbox ); if ( CHECK_X( control, user->bbox ) ) BBox_Conic_Check( user->last.x, @@ -203,15 +247,51 @@ /* max :: The address of the current maximum. */ /* */ static FT_Pos - update_cubic_max( FT_Pos q1, - FT_Pos q2, - FT_Pos q3, - FT_Pos q4, - FT_Pos max ) + cubic_peak( FT_Pos q1, + FT_Pos q2, + FT_Pos q3, + FT_Pos q4 ) { - /* for a cubic segment to possibly reach new maximum, at least */ - /* one of its off-points must stay above the current value */ - while ( q2 > max || q3 > max ) + FT_Pos peak = 0; + FT_Int shift; + + + /* This function finds a peak of a cubic segment if it is above 0 */ + /* using iterative bisection of the segment, or returns 0. */ + /* The fixed-point arithmetic of bisection is inherently stable */ + /* but may loose accuracy in the two lowest bits. To compensate, */ + /* we upscale the segment if there is room. Large values may need */ + /* to be downscaled to avoid overflows during bisection. */ + /* It is called with either q2 or q3 positive, which is necessary */ + /* for the peak to exist and avoids undefined FT_MSB. */ + + shift = 27 - FT_MSB( (FT_UInt32)( FT_ABS( q1 ) | + FT_ABS( q2 ) | + FT_ABS( q3 ) | + FT_ABS( q4 ) ) ); + + if ( shift > 0 ) + { + /* upscaling too much just wastes time */ + if ( shift > 2 ) + shift = 2; + + q1 <<= shift; + q2 <<= shift; + q3 <<= shift; + q4 <<= shift; + } + else + { + q1 >>= -shift; + q2 >>= -shift; + q3 >>= -shift; + q4 >>= -shift; + } + + /* for a peak to exist above 0, the cubic segment must have */ + /* at least one of its control off-points above 0. */ + while ( q2 > 0 || q3 > 0 ) { /* determine which half contains the maximum and split */ if ( q1 + q2 > q3 + q4 ) /* first half */ @@ -240,17 +320,22 @@ /* check whether either end reached the maximum */ if ( q1 == q2 && q1 >= q3 ) { - max = q1; + peak = q1; break; } if ( q3 == q4 && q2 <= q4 ) { - max = q4; + peak = q4; break; } } - return max; + if ( shift > 0 ) + peak >>= shift; + else + peak <<= -shift; + + return peak; } @@ -262,65 +347,17 @@ FT_Pos* min, FT_Pos* max ) { - FT_Pos nmin, nmax; - FT_Int shift; - - /* This function is only called when a control off-point is outside */ - /* the bbox that contains all on-points. It finds a local extremum */ - /* within the segment using iterative bisection of the segment. */ - /* The fixed-point arithmetic of bisection is inherently stable */ - /* but may loose accuracy in the two lowest bits. To compensate, */ - /* we upscale the segment if there is room. Large values may need */ - /* to be downscaled to avoid overflows during bisection. */ - /* The control off-point outside the bbox is likely to have the top */ - /* absolute value among arguments. */ - - shift = 27 - FT_MSB( FT_ABS( p2 ) | FT_ABS( p3 ) ); - - if ( shift > 0 ) - { - /* upscaling too much just wastes time */ - if ( shift > 2 ) - shift = 2; - - p1 <<= shift; - p2 <<= shift; - p3 <<= shift; - p4 <<= shift; - nmin = *min << shift; - nmax = *max << shift; - } - else - { - p1 >>= -shift; - p2 >>= -shift; - p3 >>= -shift; - p4 >>= -shift; - nmin = *min >> -shift; - nmax = *max >> -shift; - } + /* the bbox that contains all on-points. So at least one of the */ + /* conditions below holds and cubic_peak is called with at least one */ + /* non-zero argument. */ - nmax = update_cubic_max( p1, p2, p3, p4, nmax ); + if ( p2 > *max || p3 > *max ) + *max += cubic_peak( p1 - *max, p2 - *max, p3 - *max, p4 - *max ); /* now flip the signs to update the minimum */ - nmin = -update_cubic_max( -p1, -p2, -p3, -p4, -nmin ); - - if ( shift > 0 ) - { - nmin >>= shift; - nmax >>= shift; - } - else - { - nmin <<= -shift; - nmax <<= -shift; - } - - if ( nmin < *min ) - *min = nmin; - if ( nmax > *max ) - *max = nmax; + if ( p2 < *min || p3 < *min ) + *min -= cubic_peak( *min - p1, *min - p2, *min - p3, *min - p4 ); } @@ -385,22 +422,26 @@ return 0; } -FT_DEFINE_OUTLINE_FUNCS(bbox_interface, + + FT_DEFINE_OUTLINE_FUNCS(bbox_interface, (FT_Outline_MoveTo_Func) BBox_Move_To, - (FT_Outline_LineTo_Func) BBox_Move_To, + (FT_Outline_LineTo_Func) BBox_Line_To, (FT_Outline_ConicTo_Func)BBox_Conic_To, (FT_Outline_CubicTo_Func)BBox_Cubic_To, 0, 0 ) + /* documentation is in ftbbox.h */ FT_EXPORT_DEF( FT_Error ) FT_Outline_Get_BBox( FT_Outline* outline, FT_BBox *abbox ) { - FT_BBox cbox; - FT_BBox bbox; + FT_BBox cbox = { 0x7FFFFFFFL, 0x7FFFFFFFL, + -0x7FFFFFFFL, -0x7FFFFFFFL }; + FT_BBox bbox = { 0x7FFFFFFFL, 0x7FFFFFFFL, + -0x7FFFFFFFL, -0x7FFFFFFFL }; FT_Vector* vec; FT_UShort n; @@ -424,32 +465,13 @@ FT_DEFINE_OUTLINE_FUNCS(bbox_interface, /* coincide, we exit immediately. */ vec = outline->points; - bbox.xMin = bbox.xMax = cbox.xMin = cbox.xMax = vec->x; - bbox.yMin = bbox.yMax = cbox.yMin = cbox.yMax = vec->y; - vec++; - for ( n = 1; n < outline->n_points; n++ ) + for ( n = 0; n < outline->n_points; n++ ) { - FT_Pos x = vec->x; - FT_Pos y = vec->y; - - - /* update control box */ - if ( x < cbox.xMin ) cbox.xMin = x; - if ( x > cbox.xMax ) cbox.xMax = x; - - if ( y < cbox.yMin ) cbox.yMin = y; - if ( y > cbox.yMax ) cbox.yMax = y; + FT_UPDATE_BBOX( vec, cbox); if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON ) - { - /* update bbox for `on' points only */ - if ( x < bbox.xMin ) bbox.xMin = x; - if ( x > bbox.xMax ) bbox.xMax = x; - - if ( y < bbox.yMin ) bbox.yMin = y; - if ( y > bbox.yMax ) bbox.yMax = y; - } + FT_UPDATE_BBOX( vec, bbox); vec++; } diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c index 6542c79..a54572a 100644 --- a/src/base/ftbitmap.c +++ b/src/base/ftbitmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility functions for bitmaps (body). */ /* */ -/* Copyright 2004-2009, 2011, 2013, 2014 by */ +/* Copyright 2004-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,9 +31,20 @@ /* documentation is in ftbitmap.h */ FT_EXPORT_DEF( void ) + FT_Bitmap_Init( FT_Bitmap *abitmap ) + { + if ( abitmap ) + *abitmap = null_bitmap; + } + + + /* deprecated function name; retained for ABI compatibility */ + + FT_EXPORT_DEF( void ) FT_Bitmap_New( FT_Bitmap *abitmap ) { - *abitmap = null_bitmap; + if ( abitmap ) + *abitmap = null_bitmap; } @@ -44,25 +55,42 @@ const FT_Bitmap *source, FT_Bitmap *target) { - FT_Memory memory = library->memory; + FT_Memory memory; FT_Error error = FT_Err_Ok; - FT_Int pitch = source->pitch; - FT_ULong size; + FT_Int pitch; + FT_ULong size; + + FT_Int source_pitch_sign, target_pitch_sign; + + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !source || !target ) + return FT_THROW( Invalid_Argument ); if ( source == target ) return FT_Err_Ok; + source_pitch_sign = source->pitch < 0 ? -1 : 1; + target_pitch_sign = target->pitch < 0 ? -1 : 1; + if ( source->buffer == NULL ) { *target = *source; + if ( source_pitch_sign != target_pitch_sign ) + target->pitch = -target->pitch; return FT_Err_Ok; } + memory = library->memory; + pitch = source->pitch; + if ( pitch < 0 ) pitch = -pitch; - size = (FT_ULong)( pitch * source->rows ); + size = (FT_ULong)pitch * source->rows; if ( target->buffer ) { @@ -70,9 +98,9 @@ FT_ULong target_size; - if ( target_pitch < 0 ) + if ( target_pitch < 0 ) target_pitch = -target_pitch; - target_size = (FT_ULong)( target_pitch * target->rows ); + target_size = (FT_ULong)target_pitch * target->rows; if ( target_size != size ) (void)FT_QREALLOC( target->buffer, target_size, size ); @@ -89,13 +117,35 @@ *target = *source; target->buffer = p; - FT_MEM_COPY( target->buffer, source->buffer, size ); + if ( source_pitch_sign == target_pitch_sign ) + FT_MEM_COPY( target->buffer, source->buffer, size ); + else + { + /* take care of bitmap flow */ + FT_UInt i; + FT_Byte* s = source->buffer; + FT_Byte* t = target->buffer; + + + t += (FT_ULong)pitch * ( target->rows - 1 ); + + for ( i = target->rows; i > 0; i-- ) + { + FT_ARRAY_COPY( t, s, pitch ); + + s += pitch; + t -= pitch; + } + } } return error; } + /* Enlarge `bitmap' horizontally and vertically by `xpixels' */ + /* and `ypixels', respectively. */ + static FT_Error ft_bitmap_assure_buffer( FT_Memory memory, FT_Bitmap* bitmap, @@ -106,7 +156,7 @@ int pitch; int new_pitch; FT_UInt bpp; - FT_Int i, width, height; + FT_UInt i, width, height; unsigned char* buffer = NULL; @@ -120,21 +170,21 @@ { case FT_PIXEL_MODE_MONO: bpp = 1; - new_pitch = ( width + xpixels + 7 ) >> 3; + new_pitch = (int)( ( width + xpixels + 7 ) >> 3 ); break; case FT_PIXEL_MODE_GRAY2: bpp = 2; - new_pitch = ( width + xpixels + 3 ) >> 2; + new_pitch = (int)( ( width + xpixels + 3 ) >> 2 ); break; case FT_PIXEL_MODE_GRAY4: bpp = 4; - new_pitch = ( width + xpixels + 1 ) >> 1; + new_pitch = (int)( ( width + xpixels + 1 ) >> 1 ); break; case FT_PIXEL_MODE_GRAY: case FT_PIXEL_MODE_LCD: case FT_PIXEL_MODE_LCD_V: bpp = 8; - new_pitch = ( width + xpixels ); + new_pitch = (int)( width + xpixels ); break; default: return FT_THROW( Invalid_Glyph_Format ); @@ -144,17 +194,17 @@ if ( ypixels == 0 && new_pitch <= pitch ) { /* zero the padding */ - FT_Int bit_width = pitch * 8; - FT_Int bit_last = ( width + xpixels ) * bpp; + FT_UInt bit_width = (FT_UInt)pitch * 8; + FT_UInt bit_last = ( width + xpixels ) * bpp; if ( bit_last < bit_width ) { FT_Byte* line = bitmap->buffer + ( bit_last >> 3 ); FT_Byte* end = bitmap->buffer + pitch; - FT_Int shift = bit_last & 7; + FT_UInt shift = bit_last & 7; FT_UInt mask = 0xFF00U >> shift; - FT_Int count = height; + FT_UInt count = height; for ( ; count > 0; count--, line += pitch, end += pitch ) @@ -168,33 +218,38 @@ write++; } if ( write < end ) - FT_MEM_ZERO( write, end-write ); + FT_MEM_ZERO( write, end - write ); } } return FT_Err_Ok; } + /* otherwise allocate new buffer */ if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) ) return error; + /* new rows get added at the top of the bitmap, */ + /* thus take care of the flow direction */ if ( bitmap->pitch > 0 ) { - FT_Int len = ( width * bpp + 7 ) >> 3; + FT_UInt len = ( width * bpp + 7 ) >> 3; for ( i = 0; i < bitmap->rows; i++ ) - FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ), - bitmap->buffer + pitch * i, len ); + FT_MEM_COPY( buffer + (FT_UInt)new_pitch * ( ypixels + i ), + bitmap->buffer + (FT_UInt)pitch * i, + len ); } else { - FT_Int len = ( width * bpp + 7 ) >> 3; + FT_UInt len = ( width * bpp + 7 ) >> 3; for ( i = 0; i < bitmap->rows; i++ ) - FT_MEM_COPY( buffer + new_pitch * i, - bitmap->buffer + pitch * i, len ); + FT_MEM_COPY( buffer + (FT_UInt)new_pitch * i, + bitmap->buffer + (FT_UInt)pitch * i, + len ); } FT_FREE( bitmap->buffer ); @@ -220,7 +275,8 @@ { FT_Error error; unsigned char* p; - FT_Int i, x, y, pitch; + FT_Int i, x, pitch; + FT_UInt y; FT_Int xstr, ystr; @@ -248,17 +304,11 @@ case FT_PIXEL_MODE_GRAY4: { FT_Bitmap tmp; - FT_Int align; - - - if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 ) - align = ( bitmap->width + xstr + 3 ) / 4; - else - align = ( bitmap->width + xstr + 1 ) / 2; - FT_Bitmap_New( &tmp ); - error = FT_Bitmap_Convert( library, bitmap, &tmp, align ); + /* convert to 8bpp */ + FT_Bitmap_Init( &tmp ); + error = FT_Bitmap_Convert( library, bitmap, &tmp, 1 ); if ( error ) return error; @@ -285,17 +335,19 @@ return FT_Err_Ok; } - error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr ); + error = ft_bitmap_assure_buffer( library->memory, bitmap, + (FT_UInt)xstr, (FT_UInt)ystr ); if ( error ) return error; + /* take care of bitmap flow */ pitch = bitmap->pitch; if ( pitch > 0 ) p = bitmap->buffer + pitch * ystr; else { pitch = -pitch; - p = bitmap->buffer + pitch * ( bitmap->rows - 1 ); + p = bitmap->buffer + (FT_UInt)pitch * ( bitmap->rows - 1 ); } /* for each row */ @@ -309,7 +361,7 @@ */ for ( x = pitch - 1; x >= 0; x-- ) { - unsigned char tmp; + unsigned char tmp; tmp = p[x]; @@ -324,7 +376,7 @@ p[x] |= p[x - 1] << ( 8 - i ); #if 0 - if ( p[x] == 0xff ) + if ( p[x] == 0xFF ) break; #endif } @@ -334,12 +386,12 @@ { if ( p[x] + p[x - i] > bitmap->num_grays - 1 ) { - p[x] = (unsigned char)(bitmap->num_grays - 1); + p[x] = (unsigned char)( bitmap->num_grays - 1 ); break; } else { - p[x] = (unsigned char)(p[x] + p[x-i]); + p[x] = (unsigned char)( p[x] + p[x - i] ); if ( p[x] == bitmap->num_grays - 1 ) break; } @@ -368,8 +420,8 @@ p += bitmap->pitch; } - bitmap->width += xstr; - bitmap->rows += ystr; + bitmap->width += (FT_UInt)xstr; + bitmap->rows += (FT_UInt)ystr; return FT_Err_Ok; } @@ -378,11 +430,11 @@ static FT_Byte ft_gray_for_premultiplied_srgb_bgra( const FT_Byte* bgra ) { - FT_Byte a = bgra[3]; - FT_ULong l; + FT_UInt a = bgra[3]; + FT_UInt l; - /* Short-circuit transparent color to avoid div-by-zero. */ + /* Short-circuit transparent color to avoid division by zero. */ if ( !a ) return 0; @@ -392,17 +444,17 @@ * A gamma of 2.2 is fair to assume. And then, we need to * undo the premultiplication too. * - * http://accessibility.kde.org/hsl-adjusted.php + * http://accessibility.kde.org/hsl-adjusted.php * * We do the computation with integers only, applying a gamma of 2.0. - * The following will never overflow 32 bits; it is a scaled-up - * luminosity with premultiplication not yet undone. + * We guarantee 32-bit arithmetic to avoid overflow but the resulting + * luminosity fits into 16 bits. * */ - l = 4731UL /* 0.0722 * 65536 */ * bgra[0] * bgra[0] + - 46871UL /* 0.7152 * 65536 */ * bgra[1] * bgra[1] + - 13933UL /* 0.2126 * 65536 */ * bgra[2] * bgra[2]; + l = ( 4732UL /* 0.0722 * 65536 */ * bgra[0] * bgra[0] + + 46871UL /* 0.7152 * 65536 */ * bgra[1] * bgra[1] + + 13933UL /* 0.2126 * 65536 */ * bgra[2] * bgra[2] ) >> 16; /* * Final transparency can be determined as follows. @@ -413,11 +465,11 @@ * * So the formula is a * (1 - l) = a - l * a. * - * In the actual code, we undo premultiplication and scale down again. + * We still need to undo premultiplication by dividing l by a*a. * */ - return a - (FT_Byte)( ( l / a ) >> 16 ); + return (FT_Byte)( a - l / a ); } @@ -432,10 +484,16 @@ FT_Error error = FT_Err_Ok; FT_Memory memory; + FT_Byte* s; + FT_Byte* t; + if ( !library ) return FT_THROW( Invalid_Library_Handle ); + if ( !source || !target ) + return FT_THROW( Invalid_Argument ); + memory = library->memory; switch ( source->pixel_mode ) @@ -448,13 +506,15 @@ case FT_PIXEL_MODE_LCD_V: case FT_PIXEL_MODE_BGRA: { - FT_Int pad; - FT_Long old_size; + FT_Int pad, old_target_pitch, target_pitch; + FT_ULong old_size; - old_size = target->rows * target->pitch; - if ( old_size < 0 ) - old_size = -old_size; + old_target_pitch = target->pitch; + if ( old_target_pitch < 0 ) + old_target_pitch = -old_target_pitch; + + old_size = target->rows * (FT_UInt)old_target_pitch; target->pixel_mode = FT_PIXEL_MODE_GRAY; target->rows = source->rows; @@ -463,21 +523,23 @@ pad = 0; if ( alignment > 0 ) { - pad = source->width % alignment; + pad = (FT_Int)source->width % alignment; if ( pad != 0 ) pad = alignment - pad; } - target->pitch = source->width + pad; + target_pitch = (FT_Int)source->width + pad; - if ( target->pitch > 0 && - (FT_ULong)target->rows > FT_ULONG_MAX / target->pitch ) + if ( target_pitch > 0 && + (FT_ULong)target->rows > FT_ULONG_MAX / (FT_ULong)target_pitch ) return FT_THROW( Invalid_Argument ); - if ( target->rows * target->pitch > old_size && + if ( target->rows * (FT_ULong)target_pitch > old_size && FT_QREALLOC( target->buffer, - old_size, target->rows * target->pitch ) ) + old_size, target->rows * (FT_UInt)target_pitch ) ) return error; + + target->pitch = target->pitch < 0 ? -target_pitch : target_pitch; } break; @@ -485,13 +547,20 @@ error = FT_THROW( Invalid_Argument ); } + s = source->buffer; + t = target->buffer; + + /* take care of bitmap flow */ + if ( source->pitch < 0 ) + s -= source->pitch * (FT_Int)( source->rows - 1 ); + if ( target->pitch < 0 ) + t -= target->pitch * (FT_Int)( target->rows - 1 ); + switch ( source->pixel_mode ) { case FT_PIXEL_MODE_MONO: { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int i; + FT_UInt i; target->num_grays = 2; @@ -500,7 +569,7 @@ { FT_Byte* ss = s; FT_Byte* tt = t; - FT_Int j; + FT_UInt j; /* get the full bytes */ @@ -548,12 +617,8 @@ case FT_PIXEL_MODE_LCD: case FT_PIXEL_MODE_LCD_V: { - FT_Int width = source->width; - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int s_pitch = source->pitch; - FT_Int t_pitch = target->pitch; - FT_Int i; + FT_UInt width = source->width; + FT_UInt i; target->num_grays = 256; @@ -562,8 +627,8 @@ { FT_ARRAY_COPY( t, s, width ); - s += s_pitch; - t += t_pitch; + s += source->pitch; + t += target->pitch; } } break; @@ -571,9 +636,7 @@ case FT_PIXEL_MODE_GRAY2: { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int i; + FT_UInt i; target->num_grays = 4; @@ -582,7 +645,7 @@ { FT_Byte* ss = s; FT_Byte* tt = t; - FT_Int j; + FT_UInt j; /* get the full bytes */ @@ -623,9 +686,7 @@ case FT_PIXEL_MODE_GRAY4: { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int i; + FT_UInt i; target->num_grays = 16; @@ -634,7 +695,7 @@ { FT_Byte* ss = s; FT_Byte* tt = t; - FT_Int j; + FT_UInt j; /* get the full bytes */ @@ -659,13 +720,10 @@ } break; + case FT_PIXEL_MODE_BGRA: { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int s_pitch = source->pitch; - FT_Int t_pitch = target->pitch; - FT_Int i; + FT_UInt i; target->num_grays = 256; @@ -674,7 +732,7 @@ { FT_Byte* ss = s; FT_Byte* tt = t; - FT_Int j; + FT_UInt j; for ( j = source->width; j > 0; j-- ) @@ -685,8 +743,8 @@ tt += 1; } - s += s_pitch; - t += t_pitch; + s += source->pitch; + t += target->pitch; } } break; @@ -711,7 +769,7 @@ FT_Error error; - FT_Bitmap_New( &bitmap ); + FT_Bitmap_Init( &bitmap ); error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap ); if ( error ) return error; diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c index 4db43e0..dca0e1d 100644 --- a/src/base/ftcalc.c +++ b/src/base/ftcalc.c @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (body). */ /* */ -/* Copyright 1996-2006, 2008, 2012-2014 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -40,235 +40,7 @@ #include FT_INTERNAL_OBJECTS_H -#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER - /* Provide assembler fragments for performance-critical functions. */ - /* These must be defined `static __inline__' with GCC. */ - -#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */ - -#define FT_MULFIX_ASSEMBLER FT_MulFix_arm - - /* documentation is in freetype.h */ - - static __inline FT_Int32 - FT_MulFix_arm( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 t, t2; - - - __asm - { - smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ - mov a, t, asr #31 /* a = (hi >> 31) */ - add a, a, #0x8000 /* a += 0x8000 */ - adds t2, t2, a /* t2 += a */ - adc t, t, #0 /* t += carry */ - mov a, t2, lsr #16 /* a = t2 >> 16 */ - orr a, a, t, lsl #16 /* a |= t << 16 */ - } - return a; - } - -#endif /* __CC_ARM || __ARMCC__ */ - - -#ifdef __GNUC__ - -#if defined( __arm__ ) && \ - ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \ - !( defined( __CC_ARM ) || defined( __ARMCC__ ) ) - -#define FT_MULFIX_ASSEMBLER FT_MulFix_arm - - /* documentation is in freetype.h */ - - static __inline__ FT_Int32 - FT_MulFix_arm( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 t, t2; - - - __asm__ __volatile__ ( - "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ - "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ -#if defined( __clang__ ) && defined( __thumb2__ ) - "add.w %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ -#else - "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ -#endif - "adds %1, %1, %0\n\t" /* %1 += %0 */ - "adc %2, %2, #0\n\t" /* %2 += carry */ - "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */ - "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */ - : "=r"(a), "=&r"(t2), "=&r"(t) - : "r"(a), "r"(b) - : "cc" ); - return a; - } - -#endif /* __arm__ && */ - /* ( __thumb2__ || !__thumb__ ) && */ - /* !( __CC_ARM || __ARMCC__ ) */ - - -#if defined( __i386__ ) - -#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 - - /* documentation is in freetype.h */ - - static __inline__ FT_Int32 - FT_MulFix_i386( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 result; - - - __asm__ __volatile__ ( - "imul %%edx\n" - "movl %%edx, %%ecx\n" - "sarl $31, %%ecx\n" - "addl $0x8000, %%ecx\n" - "addl %%ecx, %%eax\n" - "adcl $0, %%edx\n" - "shrl $16, %%eax\n" - "shll $16, %%edx\n" - "addl %%edx, %%eax\n" - : "=a"(result), "=d"(b) - : "a"(a), "d"(b) - : "%ecx", "cc" ); - return result; - } - -#endif /* i386 */ - -#endif /* __GNUC__ */ - - -#ifdef _MSC_VER /* Visual C++ */ - -#ifdef _M_IX86 - -#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 - - /* documentation is in freetype.h */ - - static __inline FT_Int32 - FT_MulFix_i386( FT_Int32 a, - FT_Int32 b ) - { - register FT_Int32 result; - - __asm - { - mov eax, a - mov edx, b - imul edx - mov ecx, edx - sar ecx, 31 - add ecx, 8000h - add eax, ecx - adc edx, 0 - shr eax, 16 - shl edx, 16 - add eax, edx - mov result, eax - } - return result; - } - -#endif /* _M_IX86 */ - -#endif /* _MSC_VER */ - - -#if defined( __GNUC__ ) && defined( __x86_64__ ) - -#define FT_MULFIX_ASSEMBLER FT_MulFix_x86_64 - - static __inline__ FT_Int32 - FT_MulFix_x86_64( FT_Int32 a, - FT_Int32 b ) - { - /* Temporarily disable the warning that C90 doesn't support */ - /* `long long'. */ -#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) ) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wlong-long" -#endif - -#if 1 - /* Technically not an assembly fragment, but GCC does a really good */ - /* job at inlining it and generating good machine code for it. */ - long long ret, tmp; - - - ret = (long long)a * b; - tmp = ret >> 63; - ret += 0x8000 + tmp; - - return (FT_Int32)( ret >> 16 ); -#else - - /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine */ - /* code from the lines below. The main issue is that `wide_a' is not */ - /* properly initialized by sign-extending `a'. Instead, the generated */ - /* machine code assumes that the register that contains `a' on input */ - /* can be used directly as a 64-bit value, which is wrong most of the */ - /* time. */ - long long wide_a = (long long)a; - long long wide_b = (long long)b; - long long result; - - - __asm__ __volatile__ ( - "imul %2, %1\n" - "mov %1, %0\n" - "sar $63, %0\n" - "lea 0x8000(%1, %0), %0\n" - "sar $16, %0\n" - : "=&r"(result), "=&r"(wide_a) - : "r"(wide_b) - : "cc" ); - - return (FT_Int32)result; -#endif - -#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) ) -#pragma GCC diagnostic pop -#endif - } - -#endif /* __GNUC__ && __x86_64__ */ - -#if defined( __GNUC__ ) -#if ( __GNUC__ > 3 ) || ( ( __GNUC__ == 3 ) && ( __GNUC_MINOR__ >= 4 ) ) - -#if FT_SIZEOF_INT == 4 - -#define FT_MSB_BUILTIN( x ) ( 31 - __builtin_clz( x ) ) - -#elif FT_SIZEOF_LONG == 4 - -#define FT_MSB_BUILTIN( x ) ( 31 - __builtin_clzl( x ) ) - -#endif - -#endif -#endif /* __GNUC__ */ - -#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ - - -#ifdef FT_CONFIG_OPTION_INLINE_MULFIX #ifdef FT_MULFIX_ASSEMBLER -#define FT_MULFIX_INLINED FT_MULFIX_ASSEMBLER -#endif -#endif - -#ifdef FT_MULFIX_INLINED #undef FT_MulFix #endif @@ -296,6 +68,16 @@ #define FT_COMPONENT trace_calc + /* transfer sign leaving a positive number */ +#define FT_MOVE_SIGN( x, s ) \ + FT_BEGIN_STMNT \ + if ( x < 0 ) \ + { \ + x = -x; \ + s = -s; \ + } \ + FT_END_STMNT + /* The following three functions are available regardless of whether */ /* FT_LONG64 is defined. */ @@ -304,8 +86,8 @@ FT_EXPORT_DEF( FT_Fixed ) FT_RoundFix( FT_Fixed a ) { - return ( a >= 0 ) ? ( a + 0x8000L ) & ~0xFFFFL - : -((-a + 0x8000L ) & ~0xFFFFL ); + return a >= 0 ? ( a + 0x8000L ) & ~0xFFFFL + : -((-a + 0x8000L ) & ~0xFFFFL ); } @@ -314,8 +96,8 @@ FT_EXPORT_DEF( FT_Fixed ) FT_CeilFix( FT_Fixed a ) { - return ( a >= 0 ) ? ( a + 0xFFFFL ) & ~0xFFFFL - : -((-a + 0xFFFFL ) & ~0xFFFFL ); + return a >= 0 ? ( a + 0xFFFFL ) & ~0xFFFFL + : -((-a + 0xFFFFL ) & ~0xFFFFL ); } @@ -324,54 +106,50 @@ FT_EXPORT_DEF( FT_Fixed ) FT_FloorFix( FT_Fixed a ) { - return ( a >= 0 ) ? a & ~0xFFFFL - : -((-a) & ~0xFFFFL ); + return a >= 0 ? a & ~0xFFFFL + : -((-a) & ~0xFFFFL ); } +#ifndef FT_MSB FT_BASE_DEF ( FT_Int ) FT_MSB( FT_UInt32 z ) { -#ifdef FT_MSB_BUILTIN - - return FT_MSB_BUILTIN( z ); + FT_Int shift = 0; -#else - - FT_Int shift = 0; /* determine msb bit index in `shift' */ - if ( z >= ( 1L << 16 ) ) + if ( z & 0xFFFF0000UL ) { z >>= 16; shift += 16; } - if ( z >= ( 1L << 8 ) ) + if ( z & 0x0000FF00UL ) { z >>= 8; shift += 8; } - if ( z >= ( 1L << 4 ) ) + if ( z & 0x000000F0UL ) { z >>= 4; shift += 4; } - if ( z >= ( 1L << 2 ) ) + if ( z & 0x0000000CUL ) { z >>= 2; shift += 2; } - if ( z >= ( 1L << 1 ) ) + if ( z & 0x00000002UL ) { /* z >>= 1; */ shift += 1; } return shift; - -#endif /* FT_MSB_BUILTIN */ } +#endif /* !FT_MSB */ + /* documentation is in ftcalc.h */ @@ -395,80 +173,89 @@ /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) - FT_MulDiv( FT_Long a, - FT_Long b, - FT_Long c ) + FT_MulDiv( FT_Long a_, + FT_Long b_, + FT_Long c_ ) { - FT_Int s; - FT_Long d; + FT_Int s = 1; + FT_UInt64 a, b, c, d; + FT_Long d_; - s = 1; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - if ( c < 0 ) { c = -c; s = -s; } + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + FT_MOVE_SIGN( c_, s ); - d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c - : 0x7FFFFFFFL ); + a = (FT_UInt64)a_; + b = (FT_UInt64)b_; + c = (FT_UInt64)c_; - return ( s > 0 ) ? d : -d; + d = c > 0 ? ( a * b + ( c >> 1 ) ) / c + : 0x7FFFFFFFUL; + + d_ = (FT_Long)d; + + return s < 0 ? -d_ : d_; } /* documentation is in ftcalc.h */ FT_BASE_DEF( FT_Long ) - FT_MulDiv_No_Round( FT_Long a, - FT_Long b, - FT_Long c ) + FT_MulDiv_No_Round( FT_Long a_, + FT_Long b_, + FT_Long c_ ) { - FT_Int s; - FT_Long d; + FT_Int s = 1; + FT_UInt64 a, b, c, d; + FT_Long d_; + + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + FT_MOVE_SIGN( c_, s ); - s = 1; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - if ( c < 0 ) { c = -c; s = -s; } + a = (FT_UInt64)a_; + b = (FT_UInt64)b_; + c = (FT_UInt64)c_; - d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c - : 0x7FFFFFFFL ); + d = c > 0 ? a * b / c + : 0x7FFFFFFFUL; - return ( s > 0 ) ? d : -d; + d_ = (FT_Long)d; + + return s < 0 ? -d_ : d_; } /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ) + FT_MulFix( FT_Long a_, + FT_Long b_ ) { #ifdef FT_MULFIX_ASSEMBLER - return FT_MULFIX_ASSEMBLER( a, b ); + return FT_MULFIX_ASSEMBLER( a_, b_ ); #else - FT_Int s = 1; - FT_Long c; + FT_Int s = 1; + FT_UInt64 a, b, c; + FT_Long c_; - if ( a < 0 ) - { - a = -a; - s = -1; - } + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); - if ( b < 0 ) - { - b = -b; - s = -s; - } + a = (FT_UInt64)a_; + b = (FT_UInt64)b_; + + c = ( a * b + 0x8000UL ) >> 16; - c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 ); + c_ = (FT_Long)c; - return ( s > 0 ) ? c : -c; + return s < 0 ? -c_ : c_; #endif /* FT_MULFIX_ASSEMBLER */ } @@ -477,33 +264,26 @@ /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) - FT_DivFix( FT_Long a, - FT_Long b ) + FT_DivFix( FT_Long a_, + FT_Long b_ ) { - FT_Int32 s; - FT_UInt32 q; + FT_Int s = 1; + FT_UInt64 a, b, q; + FT_Long q_; - s = 1; - if ( a < 0 ) - { - a = -a; - s = -1; - } - if ( b < 0 ) - { - b = -b; - s = -s; - } + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); - if ( b == 0 ) - /* check for division by 0 */ - q = 0x7FFFFFFFL; - else - /* compute result directly */ - q = (FT_UInt32)( ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b ); + a = (FT_UInt64)a_; + b = (FT_UInt64)b_; + + q = b > 0 ? ( ( a << 16 ) + ( b >> 1 ) ) / b + : 0x7FFFFFFFUL; - return ( s < 0 ? -(FT_Long)q : (FT_Long)q ); + q_ = (FT_Long)q; + + return s < 0 ? -q_ : q_; } @@ -551,25 +331,30 @@ FT_Int i; - q = 0; - r = hi; - - if ( r >= y ) + if ( hi >= y ) return (FT_UInt32)0x7FFFFFFFL; - i = 32; + /* We shift as many bits as we can into the high register, perform */ + /* 32-bit division with modulo there, then work through the remaining */ + /* bits with long division. This optimization is especially noticeable */ + /* for smaller dividends that barely use the high register. */ + + i = 31 - FT_MSB( hi ); + r = ( hi << i ) | ( lo >> ( 32 - i ) ); lo <<= i; /* left 64-bit shift */ + q = r / y; + r -= q * y; /* remainder */ + + i = 32 - i; /* bits remaining in low register */ do { - r <<= 1; q <<= 1; - r |= lo >> 31; + r = ( r << 1 ) | ( lo >> 31 ); lo <<= 1; if ( r >= y ) { r -= y; q |= 1; } - lo <<= 1; } while ( --i ); return q; @@ -581,7 +366,7 @@ FT_Int64* y, FT_Int64 *z ) { - register FT_UInt32 lo, hi; + FT_UInt32 lo, hi; lo = x->lo + y->lo; @@ -592,111 +377,161 @@ } - /* documentation is in freetype.h */ - - /* The FT_MulDiv function has been optimized thanks to ideas from */ - /* Graham Asher and Alexei Podtelezhnikov. The trick is to optimize */ - /* a rather common case when everything fits within 32-bits. */ + /* The FT_MulDiv function has been optimized thanks to ideas from */ + /* Graham Asher and Alexei Podtelezhnikov. The trick is to optimize */ + /* a rather common case when everything fits within 32-bits. */ /* */ - /* We compute 'a*b+c/2', then divide it by 'c'. (positive values) */ + /* We compute 'a*b+c/2', then divide it by 'c' (all positive values). */ /* */ /* The product of two positive numbers never exceeds the square of */ - /* their mean. Therefore, we always avoid the overflow by imposing */ + /* its mean values. Therefore, we always avoid the overflow by */ + /* imposing */ + /* */ + /* (a + b) / 2 <= sqrt(X - c/2) , */ + /* */ + /* where X = 2^32 - 1, the maximum unsigned 32-bit value, and using */ + /* unsigned arithmetic. Now we replace `sqrt' with a linear function */ + /* that is smaller or equal for all values of c in the interval */ + /* [0;X/2]; it should be equal to sqrt(X) and sqrt(3X/4) at the */ + /* endpoints. Substituting the linear solution and explicit numbers */ + /* we get */ + /* */ + /* a + b <= 131071.99 - c / 122291.84 . */ + /* */ + /* In practice, we should use a faster and even stronger inequality */ + /* */ + /* a + b <= 131071 - (c >> 16) */ /* */ - /* ( a + b ) / 2 <= sqrt( X - c/2 ) */ + /* or, alternatively, */ /* */ - /* where X = 2^31 - 1. Now we replace sqrt with a linear function */ - /* that is smaller or equal in the entire range of c from 0 to X; */ - /* it should be equal to sqrt(X) and sqrt(X/2) at the range termini. */ - /* Substituting the linear solution and explicit numbers we get */ + /* a + b <= 129894 - (c >> 17) . */ /* */ - /* a + b <= 92681.9 - c / 79108.95 */ + /* FT_MulFix, on the other hand, is optimized for a small value of */ + /* the first argument, when the second argument can be much larger. */ + /* This can be achieved by scaling the second argument and the limit */ + /* in the above inequalities. For example, */ /* */ - /* In practice we use a faster and even stronger inequality */ + /* a + (b >> 8) <= (131071 >> 4) */ /* */ - /* a + b <= 92681 - (c >> 16) */ + /* covers the practical range of use. The actual test below is a bit */ + /* tighter to avoid the border case overflows. */ /* */ + /* In the case of FT_DivFix, the exact overflow check */ + /* */ + /* a << 16 <= X - c/2 */ + /* */ + /* is scaled down by 2^16 and we use */ + /* */ + /* a <= 65535 - (c >> 17) . */ + + /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) - FT_MulDiv( FT_Long a, - FT_Long b, - FT_Long c ) + FT_MulDiv( FT_Long a_, + FT_Long b_, + FT_Long c_ ) { - long s; + FT_Int s = 1; + FT_UInt32 a, b, c; /* XXX: this function does not allow 64-bit arguments */ - if ( a == 0 || b == c ) - return a; - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); - s ^= c; c = FT_ABS( c ); + if ( a_ == 0 || b_ == c_ ) + return a_; + + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + FT_MOVE_SIGN( c_, s ); + + a = (FT_UInt32)a_; + b = (FT_UInt32)b_; + c = (FT_UInt32)c_; - if ( (FT_ULong)a + (FT_ULong)b <= 92681UL - ( c >> 16 ) && c > 0 ) + if ( c == 0 ) + a = 0x7FFFFFFFUL; + + else if ( a + b <= 129894UL - ( c >> 17 ) ) a = ( a * b + ( c >> 1 ) ) / c; - else if ( (FT_Int32)c > 0 ) + else { FT_Int64 temp, temp2; - ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); + ft_multo64( a, b, &temp ); temp2.hi = 0; - temp2.lo = (FT_UInt32)(c >> 1); + temp2.lo = c >> 1; + FT_Add64( &temp, &temp2, &temp ); - a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); + + /* last attempt to ditch long division */ + a = temp.hi == 0 ? temp.lo / c + : ft_div64by32( temp.hi, temp.lo, c ); } - else - a = 0x7FFFFFFFL; - return ( s < 0 ? -a : a ); + a_ = (FT_Long)a; + + return s < 0 ? -a_ : a_; } FT_BASE_DEF( FT_Long ) - FT_MulDiv_No_Round( FT_Long a, - FT_Long b, - FT_Long c ) + FT_MulDiv_No_Round( FT_Long a_, + FT_Long b_, + FT_Long c_ ) { - long s; + FT_Int s = 1; + FT_UInt32 a, b, c; - if ( a == 0 || b == c ) - return a; + /* XXX: this function does not allow 64-bit arguments */ + + if ( a_ == 0 || b_ == c_ ) + return a_; + + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + FT_MOVE_SIGN( c_, s ); + + a = (FT_UInt32)a_; + b = (FT_UInt32)b_; + c = (FT_UInt32)c_; - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); - s ^= c; c = FT_ABS( c ); + if ( c == 0 ) + a = 0x7FFFFFFFUL; - if ( (FT_ULong)a + (FT_ULong)b <= 92681UL && c > 0 ) + else if ( a + b <= 131071UL ) a = a * b / c; - else if ( (FT_Int32)c > 0 ) + else { FT_Int64 temp; - ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); - a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); + ft_multo64( a, b, &temp ); + + /* last attempt to ditch long division */ + a = temp.hi == 0 ? temp.lo / c + : ft_div64by32( temp.hi, temp.lo, c ); } - else - a = 0x7FFFFFFFL; - return ( s < 0 ? -a : a ); + a_ = (FT_Long)a; + + return s < 0 ? -a_ : a_; } /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ) + FT_MulFix( FT_Long a_, + FT_Long b_ ) { #ifdef FT_MULFIX_ASSEMBLER - return FT_MULFIX_ASSEMBLER( a, b ); + return FT_MULFIX_ASSEMBLER( a_, b_ ); #elif 0 @@ -707,12 +542,12 @@ * the leftmost bits by copying the sign bit, it might be faster. */ - FT_Long sa, sb; - FT_ULong ua, ub; + FT_Long sa, sb; + FT_UInt32 a, b; - if ( a == 0 || b == 0x10000L ) - return a; + if ( a_ == 0 || b_ == 0x10000L ) + return a_; /* * This is a clever way of converting a signed number `a' into its @@ -732,57 +567,61 @@ * with the value 1 rather than -1. After that, everything else goes * wrong. */ - sa = ( a >> ( sizeof ( a ) * 8 - 1 ) ); - a = ( a ^ sa ) - sa; - sb = ( b >> ( sizeof ( b ) * 8 - 1 ) ); - b = ( b ^ sb ) - sb; + sa = ( a_ >> ( sizeof ( a_ ) * 8 - 1 ) ); + a = ( a_ ^ sa ) - sa; + sb = ( b_ >> ( sizeof ( b_ ) * 8 - 1 ) ); + b = ( b_ ^ sb ) - sb; - ua = (FT_ULong)a; - ub = (FT_ULong)b; + a = (FT_UInt32)a_; + b = (FT_UInt32)b_; - if ( ua <= 2048 && ub <= 1048576L ) - ua = ( ua * ub + 0x8000U ) >> 16; + if ( a + ( b >> 8 ) <= 8190UL ) + a = ( a * b + 0x8000U ) >> 16; else { - FT_ULong al = ua & 0xFFFFU; + FT_UInt32 al = a & 0xFFFFUL; - ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + - ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 ); + a = ( a >> 16 ) * b + al * ( b >> 16 ) + + ( ( al * ( b & 0xFFFFUL ) + 0x8000UL ) >> 16 ); } - sa ^= sb, - ua = (FT_ULong)(( ua ^ sa ) - sa); + sa ^= sb; + a = ( a ^ sa ) - sa; - return (FT_Long)ua; + return (FT_Long)a; #else /* 0 */ - FT_Long s; - FT_ULong ua, ub; + FT_Int s = 1; + FT_UInt32 a, b; + + /* XXX: this function does not allow 64-bit arguments */ - if ( a == 0 || b == 0x10000L ) - return a; + if ( a_ == 0 || b_ == 0x10000L ) + return a_; - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); - ua = (FT_ULong)a; - ub = (FT_ULong)b; + a = (FT_UInt32)a_; + b = (FT_UInt32)b_; - if ( ua <= 2048 && ub <= 1048576L ) - ua = ( ua * ub + 0x8000UL ) >> 16; + if ( a + ( b >> 8 ) <= 8190UL ) + a = ( a * b + 0x8000UL ) >> 16; else { - FT_ULong al = ua & 0xFFFFUL; + FT_UInt32 al = a & 0xFFFFUL; - ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + - ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 ); + a = ( a >> 16 ) * b + al * ( b >> 16 ) + + ( ( al * ( b & 0xFFFFUL ) + 0x8000UL ) >> 16 ); } - return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua ); + a_ = (FT_Long)a; + + return s < 0 ? -a_ : a_; #endif /* 0 */ @@ -792,26 +631,31 @@ /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) - FT_DivFix( FT_Long a, - FT_Long b ) + FT_DivFix( FT_Long a_, + FT_Long b_ ) { - FT_Int32 s; - FT_UInt32 q; + FT_Int s = 1; + FT_UInt32 a, b, q; + FT_Long q_; /* XXX: this function does not allow 64-bit arguments */ - s = (FT_Int32)a; a = FT_ABS( a ); - s ^= (FT_Int32)b; b = FT_ABS( b ); - if ( (FT_UInt32)b == 0 ) + FT_MOVE_SIGN( a_, s ); + FT_MOVE_SIGN( b_, s ); + + a = (FT_UInt32)a_; + b = (FT_UInt32)b_; + + if ( b == 0 ) { /* check for division by 0 */ - q = (FT_UInt32)0x7FFFFFFFL; + q = 0x7FFFFFFFUL; } - else if ( ( a >> 16 ) == 0 ) + else if ( a <= 65535UL - ( b >> 17 ) ) { /* compute result directly */ - q = (FT_UInt32)( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b; + q = ( ( a << 16 ) + ( b >> 1 ) ) / b; } else { @@ -819,140 +663,22 @@ FT_Int64 temp, temp2; - temp.hi = (FT_Int32)( a >> 16 ); - temp.lo = (FT_UInt32)a << 16; + temp.hi = a >> 16; + temp.lo = a << 16; temp2.hi = 0; - temp2.lo = (FT_UInt32)( b >> 1 ); - FT_Add64( &temp, &temp2, &temp ); - q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b ); - } + temp2.lo = b >> 1; - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - -#if 0 - - /* documentation is in ftcalc.h */ - - FT_EXPORT_DEF( void ) - FT_MulTo64( FT_Int32 x, - FT_Int32 y, - FT_Int64 *z ) - { - FT_Int32 s; - - - s = x; x = FT_ABS( x ); - s ^= y; y = FT_ABS( y ); - - ft_multo64( x, y, z ); - - if ( s < 0 ) - { - z->lo = (FT_UInt32)-(FT_Int32)z->lo; - z->hi = ~z->hi + !( z->lo ); - } - } - - - /* apparently, the second version of this code is not compiled correctly */ - /* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */ - -#if 1 - - FT_EXPORT_DEF( FT_Int32 ) - FT_Div64by32( FT_Int64* x, - FT_Int32 y ) - { - FT_Int32 s; - FT_UInt32 q, r, i, lo; - - - s = x->hi; - if ( s < 0 ) - { - x->lo = (FT_UInt32)-(FT_Int32)x->lo; - x->hi = ~x->hi + !x->lo; - } - s ^= y; y = FT_ABS( y ); - - /* Shortcut */ - if ( x->hi == 0 ) - { - if ( y > 0 ) - q = x->lo / y; - else - q = 0x7FFFFFFFL; - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - r = x->hi; - lo = x->lo; - - if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */ - return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL ); - /* Return Max/Min Int32 if division overflow. */ - /* This includes division by zero! */ - q = 0; - for ( i = 0; i < 32; i++ ) - { - r <<= 1; - q <<= 1; - r |= lo >> 31; - - if ( r >= (FT_UInt32)y ) - { - r -= y; - q |= 1; - } - lo <<= 1; - } - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - -#else /* 0 */ - - FT_EXPORT_DEF( FT_Int32 ) - FT_Div64by32( FT_Int64* x, - FT_Int32 y ) - { - FT_Int32 s; - FT_UInt32 q; - - - s = x->hi; - if ( s < 0 ) - { - x->lo = (FT_UInt32)-(FT_Int32)x->lo; - x->hi = ~x->hi + !x->lo; - } - s ^= y; y = FT_ABS( y ); - - /* Shortcut */ - if ( x->hi == 0 ) - { - if ( y > 0 ) - q = ( x->lo + ( y >> 1 ) ) / y; - else - q = 0x7FFFFFFFL; - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + FT_Add64( &temp, &temp2, &temp ); + q = ft_div64by32( temp.hi, temp.lo, b ); } - q = ft_div64by32( x->hi, x->lo, y ); + q_ = (FT_Long)q; - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + return s < 0 ? -q_ : q_; } -#endif /* 0 */ - -#endif /* 0 */ - -#endif /* FT_LONG64 */ +#endif /* !FT_LONG64 */ /* documentation is in ftglyph.h */ @@ -1075,7 +801,7 @@ if ( x > 0 ) { rem_hi = 0; - rem_lo = x; + rem_lo = (FT_UInt32)x; count = 24; do { @@ -1156,8 +882,8 @@ /* XXX: this function does not allow 64-bit arguments */ - ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 ); - ft_multo64( (FT_Int32)in_y, (FT_Int32)out_x, &z2 ); + ft_multo64( (FT_UInt32)in_x, (FT_UInt32)out_y, &z1 ); + ft_multo64( (FT_UInt32)in_y, (FT_UInt32)out_x, &z2 ); if ( z1.hi > z2.hi ) result = +1; @@ -1186,55 +912,40 @@ FT_Pos out_x, FT_Pos out_y ) { - FT_Pos ax = in_x; - FT_Pos ay = in_y; - - FT_Pos d_in, d_out, d_corner; - - - /* We approximate the Euclidean metric (sqrt(x^2 + y^2)) with */ - /* the Taxicab metric (|x| + |y|), which can be computed much */ - /* faster. If one of the two vectors is much longer than the */ - /* other one, the direction of the shorter vector doesn't */ - /* influence the result any more. */ - /* */ - /* corner */ - /* x---------------------------x */ - /* \ / */ - /* \ / */ - /* in \ / out */ - /* \ / */ - /* o */ - /* Point */ - /* */ - - if ( ax < 0 ) - ax = -ax; - if ( ay < 0 ) - ay = -ay; - d_in = ax + ay; /* d_in = || in || */ - - ax = out_x; - if ( ax < 0 ) - ax = -ax; - ay = out_y; - if ( ay < 0 ) - ay = -ay; - d_out = ax + ay; /* d_out = || out || */ - - ax = out_x + in_x; - if ( ax < 0 ) - ax = -ax; - ay = out_y + in_y; - if ( ay < 0 ) - ay = -ay; - d_corner = ax + ay; /* d_corner = || in + out || */ + FT_Pos ax = in_x + out_x; + FT_Pos ay = in_y + out_y; + + FT_Pos d_in, d_out, d_hypot; + + + /* The idea of this function is to compare the length of the */ + /* hypotenuse with the `in' and `out' length. The `corner' */ + /* represented by `in' and `out' is flat if the hypotenuse's */ + /* length isn't too large. */ + /* */ + /* This approach has the advantage that the angle between */ + /* `in' and `out' is not checked. In case one of the two */ + /* vectors is `dominant', this is, much larger than the */ + /* other vector, we thus always have a flat corner. */ + /* */ + /* hypotenuse */ + /* x---------------------------x */ + /* \ / */ + /* \ / */ + /* in \ / out */ + /* \ / */ + /* o */ + /* Point */ + + d_in = FT_HYPOT( in_x, in_y ); + d_out = FT_HYPOT( out_x, out_y ); + d_hypot = FT_HYPOT( ax, ay ); /* now do a simple length comparison: */ /* */ - /* d_in + d_out < 17/16 d_corner */ + /* d_in + d_out < 17/16 d_hypot */ - return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); + return ( d_in + d_out - d_hypot ) < ( d_hypot >> 4 ); } diff --git a/src/base/ftdbgmem.c b/src/base/ftdbgmem.c index 6fb86fe..6f20313 100644 --- a/src/base/ftdbgmem.c +++ b/src/base/ftdbgmem.c @@ -4,7 +4,7 @@ /* */ /* Memory debugger (body). */ /* */ -/* Copyright 2001-2006, 2009, 2013 by */ +/* Copyright 2001-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,7 +35,7 @@ #include FT_CONFIG_STANDARD_LIBRARY_H - FT_BASE_DEF( const char* ) _ft_debug_file = 0; + FT_BASE_DEF( const char* ) _ft_debug_file = NULL; FT_BASE_DEF( long ) _ft_debug_lineno = 0; extern void @@ -47,7 +47,7 @@ typedef struct FT_MemTableRec_* FT_MemTable; -#define FT_MEM_VAL( addr ) ((FT_PtrDist)(FT_Pointer)( addr )) +#define FT_MEM_VAL( addr ) ( (FT_PtrDist)(FT_Pointer)( addr ) ) /* * This structure holds statistics for a single allocation/release @@ -76,7 +76,7 @@ /* - * We don't need a resizable array for the memory sources, because + * We don't need a resizable array for the memory sources because * their number is pretty limited within FreeType. */ #define FT_MEM_SOURCE_BUCKETS 128 @@ -85,8 +85,8 @@ * This structure holds information related to a single allocated * memory block. If KEEPALIVE is defined, blocks that are freed by * FreeType are never released to the system. Instead, their `size' - * field is set to -size. This is mainly useful to detect double frees, - * at the price of large memory footprint during execution. + * field is set to `-size'. This is mainly useful to detect double + * frees, at the price of a large memory footprint during execution. */ typedef struct FT_MemNodeRec_ { @@ -111,20 +111,20 @@ */ typedef struct FT_MemTableRec_ { - FT_ULong size; - FT_ULong nodes; + FT_Long size; + FT_Long nodes; FT_MemNode* buckets; - FT_ULong alloc_total; - FT_ULong alloc_current; - FT_ULong alloc_max; - FT_ULong alloc_count; + FT_Long alloc_total; + FT_Long alloc_current; + FT_Long alloc_max; + FT_Long alloc_count; FT_Bool bound_total; - FT_ULong alloc_total_max; + FT_Long alloc_total_max; FT_Bool bound_count; - FT_ULong alloc_count_max; + FT_Long alloc_count_max; FT_MemSource sources[FT_MEM_SOURCE_BUCKETS]; @@ -142,14 +142,14 @@ #define FT_MEM_SIZE_MIN 7 #define FT_MEM_SIZE_MAX 13845163 -#define FT_FILENAME( x ) ((x) ? (x) : "unknown file") +#define FT_FILENAME( x ) ( (x) ? (x) : "unknown file" ) /* * Prime numbers are ugly to handle. It would be better to implement * L-Hashing, which is 10% faster and doesn't require divisions. */ - static const FT_UInt ft_mem_primes[] = + static const FT_Int ft_mem_primes[] = { 7, 11, @@ -189,10 +189,10 @@ }; - static FT_ULong - ft_mem_closest_prime( FT_ULong num ) + static FT_Long + ft_mem_closest_prime( FT_Long num ) { - FT_UInt i; + size_t i; for ( i = 0; @@ -204,7 +204,7 @@ } - extern void + static void ft_mem_debug_panic( const char* fmt, ... ) { @@ -254,19 +254,20 @@ static void ft_mem_table_resize( FT_MemTable table ) { - FT_ULong new_size; + FT_Long new_size; new_size = ft_mem_closest_prime( table->nodes ); if ( new_size != table->size ) { FT_MemNode* new_buckets; - FT_ULong i; + FT_Long i; new_buckets = (FT_MemNode *) - ft_mem_table_alloc( table, - new_size * sizeof ( FT_MemNode ) ); + ft_mem_table_alloc( + table, + new_size * (FT_Long)sizeof ( FT_MemNode ) ); if ( new_buckets == NULL ) return; @@ -282,7 +283,7 @@ while ( node ) { next = node->link; - hash = FT_MEM_VAL( node->address ) % new_size; + hash = FT_MEM_VAL( node->address ) % (FT_PtrDist)new_size; pnode = new_buckets + hash; node->link = pnode[0]; @@ -325,8 +326,9 @@ table->free = memory->free; table->buckets = (FT_MemNode *) - memory->alloc( memory, - table->size * sizeof ( FT_MemNode ) ); + memory->alloc( + memory, + table->size * (FT_Long)sizeof ( FT_MemNode ) ); if ( table->buckets ) FT_ARRAY_ZERO( table->buckets, table->size ); else @@ -343,9 +345,9 @@ static void ft_mem_table_destroy( FT_MemTable table ) { - FT_ULong i; - FT_Long leak_count = 0; - FT_ULong leaks = 0; + FT_Long i; + FT_Long leak_count = 0; + FT_Long leaks = 0; FT_DumpMemory( table->memory ); @@ -359,7 +361,7 @@ while ( node ) { next = node->link; - node->link = 0; + node->link = NULL; if ( node->size > 0 ) { @@ -381,7 +383,7 @@ ft_mem_table_free( table, node ); node = next; } - table->buckets[i] = 0; + table->buckets[i] = NULL; } ft_mem_table_free( table, table->buckets ); @@ -430,7 +432,7 @@ hash = FT_MEM_VAL( address ); - pnode = table->buckets + ( hash % table->size ); + pnode = table->buckets + ( hash % (FT_PtrDist)table->size ); for (;;) { @@ -466,8 +468,8 @@ if ( node == NULL ) break; - if ( node->file_name == _ft_debug_file && - node->line_no == _ft_debug_lineno ) + if ( node->file_name == _ft_debug_file && + node->line_no == _ft_debug_lineno ) goto Exit; pnode = &node->link; @@ -485,11 +487,11 @@ node->max_blocks = 0; node->all_blocks = 0; - node->cur_size = 0; - node->max_size = 0; - node->all_size = 0; + node->cur_size = 0; + node->max_size = 0; + node->all_size = 0; - node->cur_max = 0; + node->cur_max = 0; node->link = NULL; node->hash = hash; @@ -503,7 +505,7 @@ static void ft_mem_table_set( FT_MemTable table, FT_Byte* address, - FT_ULong size, + FT_Long size, FT_Long delta ) { FT_MemNode *pnode, node; @@ -558,7 +560,7 @@ source->max_blocks = source->cur_blocks; } - if ( size > (FT_ULong)source->cur_max ) + if ( size > source->cur_max ) source->cur_max = size; if ( delta != 0 ) @@ -671,7 +673,7 @@ } - extern FT_Pointer + static FT_Pointer ft_mem_debug_alloc( FT_Memory memory, FT_Long size ) { @@ -688,14 +690,14 @@ return NULL; /* return NULL if this allocation would overflow the maximum heap size */ - if ( table->bound_total && - table->alloc_total_max - table->alloc_current > (FT_ULong)size ) + if ( table->bound_total && + table->alloc_total_max - table->alloc_current > size ) return NULL; block = (FT_Byte *)ft_mem_table_alloc( table, size ); if ( block ) { - ft_mem_table_set( table, block, (FT_ULong)size, 0 ); + ft_mem_table_set( table, block, size, 0 ); table->alloc_count++; } @@ -707,7 +709,7 @@ } - extern void + static void ft_mem_debug_free( FT_Memory memory, FT_Pointer block ) { @@ -731,7 +733,7 @@ } - extern FT_Pointer + static FT_Pointer ft_mem_debug_realloc( FT_Memory memory, FT_Long cur_size, FT_Long new_size, @@ -787,21 +789,22 @@ table->alloc_count >= table->alloc_count_max ) return NULL; - delta = (FT_Long)( new_size - cur_size ); + delta = new_size - cur_size; /* return NULL if this allocation would overflow the maximum heap size */ - if ( delta > 0 && - table->bound_total && - table->alloc_current + (FT_ULong)delta > table->alloc_total_max ) + if ( delta > 0 && + table->bound_total && + table->alloc_current + delta > table->alloc_total_max ) return NULL; - new_block = (FT_Byte *)ft_mem_table_alloc( table, new_size ); + new_block = (FT_Pointer)ft_mem_table_alloc( table, new_size ); if ( new_block == NULL ) return NULL; ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta ); - ft_memcpy( new_block, block, cur_size < new_size ? cur_size : new_size ); + ft_memcpy( new_block, block, cur_size < new_size ? (size_t)cur_size + : (size_t)new_size ); ft_mem_table_remove( table, (FT_Byte*)block, delta ); @@ -844,7 +847,7 @@ if ( total_max > 0 ) { table->bound_total = 1; - table->alloc_total_max = (FT_ULong)total_max; + table->alloc_total_max = total_max; } } @@ -857,7 +860,7 @@ if ( total_count > 0 ) { table->bound_count = 1; - table->alloc_count_max = (FT_ULong)total_count; + table->alloc_count_max = total_count; } } @@ -896,7 +899,6 @@ } - static int ft_mem_source_compare( const void* p1, const void* p2 ) @@ -925,7 +927,7 @@ FT_MemSource* bucket = table->sources; FT_MemSource* limit = bucket + FT_MEM_SOURCE_BUCKETS; FT_MemSource* sources; - FT_UInt nn, count; + FT_Int nn, count; const char* fmt; @@ -939,8 +941,9 @@ count++; } - sources = (FT_MemSource*)ft_mem_table_alloc( - table, sizeof ( *sources ) * count ); + sources = (FT_MemSource*) + ft_mem_table_alloc( + table, count * (FT_Long)sizeof ( *sources ) ); count = 0; for ( bucket = table->sources; bucket < limit; bucket++ ) @@ -952,7 +955,10 @@ sources[count++] = source; } - ft_qsort( sources, count, sizeof ( *sources ), ft_mem_source_compare ); + ft_qsort( sources, + (size_t)count, + sizeof ( *sources ), + ft_mem_source_compare ); printf( "FreeType Memory Dump: " "current=%ld max=%ld total=%ld count=%ld\n", diff --git a/src/base/ftdebug.c b/src/base/ftdebug.c index 39ac6ad..2cdb7c2 100644 --- a/src/base/ftdebug.c +++ b/src/base/ftdebug.c @@ -4,7 +4,7 @@ /* */ /* Debugging and logging component (body). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2008, 2013 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/base/ftxf86.c b/src/base/ftfntfmt.c index a4bf767..98e7431 100644 --- a/src/base/ftxf86.c +++ b/src/base/ftfntfmt.c @@ -1,10 +1,10 @@ /***************************************************************************/ /* */ -/* ftxf86.c */ +/* ftfntfmt.c */ /* */ -/* FreeType utility file for X11 support (body). */ +/* FreeType utility file for font formats (body). */ /* */ -/* Copyright 2002, 2003, 2004 by */ +/* Copyright 2002-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,12 +17,27 @@ #include <ft2build.h> -#include FT_XFREE86_H +#include FT_FONT_FORMATS_H #include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_FONT_FORMAT_H - /* documentation is in ftxf86.h */ + /* documentation is in ftfntfmt.h */ + + FT_EXPORT_DEF( const char* ) + FT_Get_Font_Format( FT_Face face ) + { + const char* result = NULL; + + + if ( face ) + FT_FACE_FIND_SERVICE( face, result, FONT_FORMAT ); + + return result; + } + + + /* deprecated function name; retained for ABI compatibility */ FT_EXPORT_DEF( const char* ) FT_Get_X11_Font_Format( FT_Face face ) @@ -31,7 +46,7 @@ if ( face ) - FT_FACE_FIND_SERVICE( face, result, XF86_NAME ); + FT_FACE_FIND_SERVICE( face, result, FONT_FORMAT ); return result; } diff --git a/src/base/ftfstype.c b/src/base/ftfstype.c index 0bf29c7..cd3458f 100644 --- a/src/base/ftfstype.c +++ b/src/base/ftfstype.c @@ -1,62 +1,62 @@ -/***************************************************************************/
-/* */
-/* ftfstype.c */
-/* */
-/* FreeType utility file to access FSType data (body). */
-/* */
-/* Copyright 2008, 2009 by */
-/* David Turner, Robert Wilhelm, and Werner Lemberg. */
-/* */
-/* This file is part of the FreeType project, and may only be used, */
-/* modified, and distributed under the terms of the FreeType project */
-/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
-/* this file you indicate that you have read the license and */
-/* understand and accept it fully. */
-/* */
-/***************************************************************************/
-
-#include <ft2build.h>
-#include FT_TYPE1_TABLES_H
-#include FT_TRUETYPE_TABLES_H
-#include FT_INTERNAL_SERVICE_H
-#include FT_SERVICE_POSTSCRIPT_INFO_H
-
-
- /* documentation is in freetype.h */
-
- FT_EXPORT_DEF( FT_UShort )
- FT_Get_FSType_Flags( FT_Face face )
- {
- TT_OS2* os2;
-
-
- /* first, try to get the fs_type directly from the font */
- if ( face )
- {
- FT_Service_PsInfo service = NULL;
-
-
- FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
-
- if ( service && service->ps_get_font_extra )
- {
- PS_FontExtraRec extra;
-
-
- if ( !service->ps_get_font_extra( face, &extra ) &&
- extra.fs_type != 0 )
- return extra.fs_type;
- }
- }
-
- /* look at FSType before fsType for Type42 */
-
- if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, ft_sfnt_os2 ) ) != NULL &&
- os2->version != 0xFFFFU )
- return os2->fsType;
-
- return 0;
- }
-
-
-/* END */
+/***************************************************************************/ +/* */ +/* ftfstype.c */ +/* */ +/* FreeType utility file to access FSType data (body). */ +/* */ +/* Copyright 2008-2015 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include <ft2build.h> +#include FT_TYPE1_TABLES_H +#include FT_TRUETYPE_TABLES_H +#include FT_INTERNAL_SERVICE_H +#include FT_SERVICE_POSTSCRIPT_INFO_H + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UShort ) + FT_Get_FSType_Flags( FT_Face face ) + { + TT_OS2* os2; + + + /* first, try to get the fs_type directly from the font */ + if ( face ) + { + FT_Service_PsInfo service = NULL; + + + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_get_font_extra ) + { + PS_FontExtraRec extra; + + + if ( !service->ps_get_font_extra( face, &extra ) && + extra.fs_type != 0 ) + return extra.fs_type; + } + } + + /* look at FSType before fsType for Type42 */ + + if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, FT_SFNT_OS2 ) ) != NULL && + os2->version != 0xFFFFU ) + return os2->fsType; + + return 0; + } + + +/* END */ diff --git a/src/base/ftgasp.c b/src/base/ftgasp.c index 8485d29..bbd257c 100644 --- a/src/base/ftgasp.c +++ b/src/base/ftgasp.c @@ -4,7 +4,7 @@ /* */ /* Access of TrueType's `gasp' table (body). */ /* */ -/* Copyright 2007 by */ +/* Copyright 2007-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/base/ftgloadr.c b/src/base/ftgloadr.c index 3cc5c7a..7e28638 100644 --- a/src/base/ftgloadr.c +++ b/src/base/ftgloadr.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph loader (body). */ /* */ -/* Copyright 2002-2006, 2010, 2013 by */ +/* Copyright 2002-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -212,7 +212,8 @@ /* check points & tags */ - new_max = base->n_points + current->n_points + n_points; + new_max = (FT_UInt)base->n_points + (FT_UInt)current->n_points + + n_points; old_max = loader->max_points; if ( new_max > old_max ) @@ -245,7 +246,7 @@ /* check contours */ old_max = loader->max_contours; - new_max = base->n_contours + current->n_contours + + new_max = (FT_UInt)base->n_contours + (FT_UInt)current->n_contours + n_contours; if ( new_max > old_max ) { @@ -329,9 +330,9 @@ FT_GlyphLoad base; FT_GlyphLoad current; - FT_UInt n_curr_contours; - FT_UInt n_base_points; - FT_UInt n; + FT_Int n_curr_contours; + FT_Int n_base_points; + FT_Int n; if ( !loader ) @@ -365,8 +366,8 @@ FT_GlyphLoader source ) { FT_Error error; - FT_UInt num_points = source->base.outline.n_points; - FT_UInt num_contours = source->base.outline.n_contours; + FT_UInt num_points = (FT_UInt)source->base.outline.n_points; + FT_UInt num_contours = (FT_UInt)source->base.outline.n_contours; error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours ); diff --git a/src/base/ftglyph.c b/src/base/ftglyph.c index c62b3db..cb7fc37 100644 --- a/src/base/ftglyph.c +++ b/src/base/ftglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (body). */ /* */ -/* Copyright 1996-2005, 2007, 2008, 2010, 2012, 2013 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -82,7 +82,7 @@ } else { - FT_Bitmap_New( &glyph->bitmap ); + FT_Bitmap_Init( &glyph->bitmap ); error = FT_Bitmap_Copy( library, &slot->bitmap, &glyph->bitmap ); } @@ -126,9 +126,9 @@ cbox->xMin = glyph->left << 6; - cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 ); + cbox->xMax = cbox->xMin + (FT_Pos)( glyph->bitmap.width << 6 ); cbox->yMax = glyph->top << 6; - cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 ); + cbox->yMin = cbox->yMax - (FT_Pos)( glyph->bitmap.rows << 6 ); } @@ -173,7 +173,9 @@ } /* allocate new outline */ - error = FT_Outline_New( library, source->n_points, source->n_contours, + error = FT_Outline_New( library, + (FT_UInt)source->n_points, + source->n_contours, &glyph->outline ); if ( error ) goto Exit; @@ -205,8 +207,10 @@ FT_Library library = FT_GLYPH( source )->library; - error = FT_Outline_New( library, source->outline.n_points, - source->outline.n_contours, &target->outline ); + error = FT_Outline_New( library, + (FT_UInt)source->outline.n_points, + source->outline.n_contours, + &target->outline ); if ( !error ) FT_Outline_Copy( &source->outline, &target->outline ); @@ -287,7 +291,7 @@ FT_Glyph glyph = NULL; - *aglyph = 0; + *aglyph = NULL; if ( !FT_ALLOC( glyph, clazz->glyph_size ) ) { @@ -314,13 +318,13 @@ /* check arguments */ - if ( !target ) + if ( !target || !source || !source->clazz ) { error = FT_THROW( Invalid_Argument ); goto Exit; } - *target = 0; + *target = NULL; if ( !source || !source->clazz ) { @@ -359,7 +363,7 @@ FT_Error error; FT_Glyph glyph; - const FT_Glyph_Class* clazz = 0; + const FT_Glyph_Class* clazz = NULL; if ( !slot ) @@ -512,7 +516,7 @@ FT_BitmapGlyph bitmap = NULL; const FT_Glyph_Class* clazz; - /* FT_BITMAP_GLYPH_CLASS_GET derefers `library' in PIC mode */ + /* FT_BITMAP_GLYPH_CLASS_GET dereferences `library' in PIC mode */ FT_Library library; diff --git a/src/base/ftinit.c b/src/base/ftinit.c index 6176273..cc95e6a 100644 --- a/src/base/ftinit.c +++ b/src/base/ftinit.c @@ -4,7 +4,7 @@ /* */ /* FreeType initialization layer (body). */ /* */ -/* Copyright 1996-2002, 2005, 2007, 2009, 2012, 2013 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -138,7 +138,7 @@ #include FT_CONFIG_MODULES_H FT_FREE( classes ); - pic_container->default_module_classes = 0; + pic_container->default_module_classes = NULL; } @@ -164,7 +164,7 @@ memory = library->memory; - pic_container->default_module_classes = 0; + pic_container->default_module_classes = NULL; if ( FT_ALLOC( classes, sizeof ( FT_Module_Class* ) * ( FT_NUM_MODULE_CLASSES + 1 ) ) ) @@ -172,8 +172,8 @@ /* initialize all pointers to 0, especially the last one */ for ( i = 0; i < FT_NUM_MODULE_CLASSES; i++ ) - classes[i] = 0; - classes[FT_NUM_MODULE_CLASSES] = 0; + classes[i] = NULL; + classes[FT_NUM_MODULE_CLASSES] = NULL; i = 0; @@ -235,6 +235,8 @@ FT_Memory memory; + /* check of `alibrary' delayed to `FT_New_Library' */ + /* First of all, allocate a new system object -- this function is part */ /* of the system-specific component, i.e. `ftsystem.c'. */ @@ -263,17 +265,19 @@ FT_EXPORT_DEF( FT_Error ) FT_Done_FreeType( FT_Library library ) { - if ( library ) - { - FT_Memory memory = library->memory; + FT_Memory memory; - /* Discard the library object */ - FT_Done_Library( library ); + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); - /* discard memory manager */ - FT_Done_Memory( memory ); - } + memory = library->memory; + + /* Discard the library object */ + FT_Done_Library( library ); + + /* discard memory manager */ + FT_Done_Memory( memory ); return FT_Err_Ok; } diff --git a/src/base/ftlcdfil.c b/src/base/ftlcdfil.c index 4aefb68..ff6f7e9 100644 --- a/src/base/ftlcdfil.c +++ b/src/base/ftlcdfil.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for color filtering of subpixel bitmap glyphs (body). */ /* */ -/* Copyright 2006, 2008-2010, 2013, 2014 by */ +/* Copyright 2006-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -46,6 +46,10 @@ FT_Byte* line = bitmap->buffer; + /* take care of bitmap flow */ + if ( bitmap->pitch < 0 ) + line -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); + /* `fir' and `pix' must be at least 32 bit wide, since the sum of */ /* the values in `weights' can exceed 0xFF */ @@ -106,6 +110,10 @@ FT_Int pitch = bitmap->pitch; + /* take care of bitmap flow */ + if ( bitmap->pitch < 0 ) + column -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); + for ( ; width > 0; width--, column++ ) { FT_Byte* col = column; @@ -174,7 +182,7 @@ FT_UInt height = (FT_UInt)bitmap->rows; FT_Int pitch = bitmap->pitch; - static const int filters[3][3] = + static const unsigned int filters[3][3] = { { 65538 * 9/13, 65538 * 1/6, 65538 * 1/13 }, { 65538 * 3/13, 65538 * 4/6, 65538 * 3/13 }, @@ -190,6 +198,10 @@ FT_Byte* line = bitmap->buffer; + /* take care of bitmap flow */ + if ( bitmap->pitch < 0 ) + line -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); + for ( ; height > 0; height--, line += pitch ) { FT_UInt xx; @@ -229,10 +241,14 @@ FT_Byte* column = bitmap->buffer; + /* take care of bitmap flow */ + if ( bitmap->pitch < 0 ) + column -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); + for ( ; width > 0; width--, column++ ) { FT_Byte* col = column; - FT_Byte* col_end = col + height * pitch; + FT_Byte* col_end = col + (FT_Int)height * pitch; for ( ; col < col_end; col += 3 * pitch ) @@ -273,7 +289,10 @@ FT_Library_SetLcdFilterWeights( FT_Library library, unsigned char *weights ) { - if ( !library || !weights ) + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !weights ) return FT_THROW( Invalid_Argument ); ft_memcpy( library->lcd_weights, weights, 5 ); @@ -295,7 +314,7 @@ if ( !library ) - return FT_THROW( Invalid_Argument ); + return FT_THROW( Invalid_Library_Handle ); switch ( filter ) { diff --git a/src/base/ftmm.c b/src/base/ftmm.c index 18ff879..7c012aa 100644 --- a/src/base/ftmm.c +++ b/src/base/ftmm.c @@ -4,7 +4,7 @@ /* */ /* Multiple Master font support (body). */ /* */ -/* Copyright 1996-2001, 2003, 2004, 2009, 2013 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -72,6 +72,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !amaster ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { @@ -94,6 +99,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !amaster ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { @@ -117,6 +127,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { @@ -140,6 +155,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { @@ -163,6 +183,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { @@ -189,6 +214,11 @@ FT_Service_MultiMasters service; + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + error = ft_face_get_mm_service( face, &service ); if ( !error ) { diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index cc56105..9c3332c 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (body). */ /* */ -/* Copyright 1996-2014 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -158,7 +158,7 @@ FT_Stream stream = NULL; - *astream = 0; + *astream = NULL; if ( !library ) return FT_THROW( Invalid_Library_Handle ); @@ -178,7 +178,7 @@ /* create a memory-based stream */ FT_Stream_OpenMemory( stream, (const FT_Byte*)args->memory_base, - args->memory_size ); + (FT_ULong)args->memory_size ); } #ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT @@ -353,10 +353,10 @@ slot->bitmap_left = 0; slot->bitmap_top = 0; slot->num_subglyphs = 0; - slot->subglyphs = 0; - slot->control_data = 0; + slot->subglyphs = NULL; + slot->control_data = NULL; slot->control_len = 0; - slot->other = 0; + slot->other = NULL; slot->format = FT_GLYPH_FORMAT_NONE; slot->linearHoriAdvance = 0; @@ -387,7 +387,7 @@ if ( FT_DRIVER_USES_OUTLINES( driver ) ) { FT_GlyphLoader_Done( slot->internal->loader ); - slot->internal->loader = 0; + slot->internal->loader = NULL; } FT_FREE( slot->internal ); @@ -408,7 +408,10 @@ FT_GlyphSlot slot = NULL; - if ( !face || !face->driver ) + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( !face->driver ) return FT_THROW( Invalid_Argument ); driver = face->driver; @@ -435,7 +438,7 @@ *aslot = slot; } else if ( aslot ) - *aslot = 0; + *aslot = NULL; Exit: @@ -508,6 +511,7 @@ internal->transform_matrix.xy = 0; internal->transform_matrix.yx = 0; internal->transform_matrix.yy = 0x10000L; + matrix = &internal->transform_matrix; } else @@ -523,6 +527,7 @@ { internal->transform_delta.x = 0; internal->transform_delta.y = 0; + delta = &internal->transform_delta; } else @@ -927,7 +932,7 @@ (FT_List_Destructor)destroy_size, memory, driver ); - face->size = 0; + face->size = NULL; /* now discard client data */ if ( face->generic.finalizer ) @@ -945,7 +950,7 @@ face->stream, ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); - face->stream = 0; + face->stream = NULL; /* get rid of it */ if ( face->internal ) @@ -963,10 +968,6 @@ (FT_List_Destructor)destroy_face, driver->root.memory, driver ); - - /* check whether we need to drop the driver's glyph loader */ - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - FT_GlyphLoader_Done( driver->glyph_loader ); } @@ -1040,14 +1041,6 @@ ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "find_unicode_charmap: UCS-4 cmap is found " - "at too late position (%d)\n", cur - first )); - continue; - } -#endif face->charmap = cur[0]; return FT_Err_Ok; } @@ -1062,14 +1055,6 @@ { if ( cur[0]->encoding == FT_ENCODING_UNICODE ) { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "find_unicode_charmap: UCS-2 cmap is found " - "at too late position (%d)\n", cur - first )); - continue; - } -#endif face->charmap = cur[0]; return FT_Err_Ok; } @@ -1111,17 +1096,7 @@ if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR && FT_Get_CMap_Format( cur[0] ) == 14 ) - { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "find_unicode_charmap: UVS cmap is found " - "at too late position (%d)\n", cur - first )); - continue; - } -#endif return cur[0]; - } } return NULL; @@ -1178,7 +1153,7 @@ int i; - face->internal->incremental_interface = 0; + face->internal->incremental_interface = NULL; for ( i = 0; i < num_params && !face->internal->incremental_interface; i++ ) if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL ) @@ -1220,7 +1195,7 @@ clazz->done_face( face ); FT_FREE( internal ); FT_FREE( face ); - *aface = 0; + *aface = NULL; } return error; @@ -1243,7 +1218,7 @@ FT_Open_Args args; - /* test for valid `library' and `aface' delayed to FT_Open_Face() */ + /* test for valid `library' and `aface' delayed to `FT_Open_Face' */ if ( !pathname ) return FT_THROW( Invalid_Argument ); @@ -1269,7 +1244,7 @@ FT_Open_Args args; - /* test for valid `library' and `face' delayed to FT_Open_Face() */ + /* test for valid `library' and `face' delayed to `FT_Open_Face' */ if ( !file_base ) return FT_THROW( Invalid_Argument ); @@ -1323,8 +1298,8 @@ FT_FREE( stream->base ); stream->size = 0; - stream->base = 0; - stream->close = 0; + stream->base = NULL; + stream->close = NULL; } @@ -1348,7 +1323,7 @@ if ( !base ) return FT_THROW( Invalid_Argument ); - *astream = 0; + *astream = NULL; memory = library->memory; if ( FT_NEW( stream ) ) goto Exit; @@ -1512,7 +1487,7 @@ FT_Error error; FT_Memory memory = library->memory; FT_ULong offset, length; - FT_Long pos; + FT_ULong pos; FT_Bool is_sfnt_cid; FT_Byte* sfnt_ps = NULL; @@ -1520,7 +1495,7 @@ FT_UNUSED( params ); - pos = FT_Stream_Pos( stream ); + pos = FT_STREAM_POS(); error = ft_lookup_PS_in_sfnt_stream( stream, face_index, @@ -1583,9 +1558,9 @@ FT_Memory memory = library->memory; FT_Byte* pfb_data = NULL; int i, type, flags; - FT_Long len; - FT_Long pfb_len, pfb_pos, pfb_lenpos; - FT_Long rlen, temp; + FT_ULong len; + FT_ULong pfb_len, pfb_pos, pfb_lenpos; + FT_ULong rlen, temp; if ( face_index == -1 ) @@ -1598,14 +1573,37 @@ pfb_len = 0; for ( i = 0; i < resource_cnt; ++i ) { - error = FT_Stream_Seek( stream, offsets[i] ); + error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] ); if ( error ) goto Exit; - if ( FT_READ_LONG( temp ) ) + if ( FT_READ_ULONG( temp ) ) goto Exit; + + /* FT2 allocator takes signed long buffer length, + * too large value causing overflow should be checked + */ + FT_TRACE4(( " POST fragment #%d: length=0x%08x\n", + i, temp)); + if ( 0x7FFFFFFFUL < temp || pfb_len + temp + 6 < pfb_len ) + { + FT_TRACE2(( " too long fragment length makes" + " pfb_len confused: temp=0x%08x\n", temp )); + error = FT_THROW( Invalid_Offset ); + goto Exit; + } + pfb_len += temp + 6; } + FT_TRACE2(( " total buffer size to concatenate %d" + " POST fragments: 0x%08x\n", + resource_cnt, pfb_len + 2)); + if ( pfb_len + 2 < 6 ) { + FT_TRACE2(( " too long fragment length makes" + " pfb_len confused: pfb_len=0x%08x\n", pfb_len )); + error = FT_THROW( Array_Too_Large ); + goto Exit; + } if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) goto Exit; @@ -1622,19 +1620,33 @@ type = 1; for ( i = 0; i < resource_cnt; ++i ) { - error = FT_Stream_Seek( stream, offsets[i] ); + error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] ); if ( error ) goto Exit2; - if ( FT_READ_LONG( rlen ) ) - goto Exit; + if ( FT_READ_ULONG( rlen ) ) + goto Exit2; + + /* FT2 allocator takes signed long buffer length, + * too large fragment length causing overflow should be checked + */ + if ( 0x7FFFFFFFUL < rlen ) + { + error = FT_THROW( Invalid_Offset ); + goto Exit2; + } + if ( FT_READ_USHORT( flags ) ) - goto Exit; + goto Exit2; FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", i, offsets[i], rlen, flags )); + error = FT_ERR( Array_Too_Large ); /* postpone the check of rlen longer than buffer until FT_Stream_Read() */ if ( ( flags >> 8 ) == 0 ) /* Comment, should not be loaded */ + { + FT_TRACE3(( " Skip POST fragment #%d because it is a comment\n", i )); continue; + } /* the flags are part of the resource, so rlen >= 2. */ /* but some fonts declare rlen = 0 for empty fragment */ @@ -1647,6 +1659,8 @@ len += rlen; else { + FT_TRACE3(( " Write POST fragment #%d header (4-byte) to buffer" + " 0x%p + 0x%08x\n", i, pfb_data, pfb_lenpos )); if ( pfb_lenpos + 3 > pfb_len + 2 ) goto Exit2; pfb_data[pfb_lenpos ] = (FT_Byte)( len ); @@ -1657,6 +1671,8 @@ if ( ( flags >> 8 ) == 5 ) /* End of font mark */ break; + FT_TRACE3(( " Write POST fragment #%d header (6-byte) to buffer" + " 0x%p + 0x%08x\n", i, pfb_data, pfb_pos )); if ( pfb_pos + 6 > pfb_len + 2 ) goto Exit2; pfb_data[pfb_pos++] = 0x80; @@ -1672,16 +1688,18 @@ pfb_data[pfb_pos++] = 0; } - error = FT_ERR( Cannot_Open_Resource ); if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len ) goto Exit2; + FT_TRACE3(( " Load POST fragment #%d (%d byte) to buffer" + " 0x%p + 0x%08x\n", i, rlen, pfb_data, pfb_pos )); error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); if ( error ) goto Exit2; pfb_pos += rlen; } + error = FT_ERR( Array_Too_Large ); if ( pfb_pos + 2 > pfb_len + 2 ) goto Exit2; pfb_data[pfb_pos++] = 0x80; @@ -1702,6 +1720,13 @@ aface ); Exit2: + if ( error == FT_ERR( Array_Too_Large ) ) + FT_TRACE2(( " Abort due to too-short buffer to store" + " all POST fragments\n" )); + else if ( error == FT_ERR( Invalid_Offset ) ) + FT_TRACE2(( " Abort due to invalid offset in a POST fragment\n" )); + if ( error ) + error = FT_ERR( Cannot_Open_Resource ); FT_FREE( pfb_data ); Exit: @@ -1725,7 +1750,7 @@ FT_Memory memory = library->memory; FT_Byte* sfnt_data = NULL; FT_Error error; - FT_Long flag_offset; + FT_ULong flag_offset; FT_Long rlen; int is_cff; FT_Long face_index_in_resource = 0; @@ -1736,7 +1761,7 @@ if ( face_index >= resource_cnt ) return FT_THROW( Cannot_Open_Resource ); - flag_offset = offsets[face_index]; + flag_offset = (FT_ULong)offsets[face_index]; error = FT_Stream_Seek( stream, flag_offset ); if ( error ) goto Exit; @@ -1758,16 +1783,16 @@ if ( FT_Stream_Seek( stream, flag_offset + 4 ) ) goto Exit; - if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) ) + if ( FT_ALLOC( sfnt_data, rlen ) ) return error; - error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen ); + error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, (FT_ULong)rlen ); if ( error ) goto Exit; is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 ); error = open_face_from_buffer( library, sfnt_data, - rlen, + (FT_ULong)rlen, face_index_in_resource, is_cff ? "cff" : "truetype", aface ); @@ -1881,7 +1906,7 @@ rlen = ( header[0x57] << 24 ) | ( header[0x58] << 16 ) | ( header[0x59] << 8 ) | - header[0x5a]; + header[0x5A]; #endif /* 0 */ offset = 128 + ( ( dlen + 127 ) & ~127 ); @@ -1905,7 +1930,7 @@ FT_Memory memory = library->memory; FT_Error error = FT_ERR( Unknown_File_Format ); - int i; + FT_UInt i; char * file_names[FT_RACCESS_N_RULES]; FT_Long offsets[FT_RACCESS_N_RULES]; @@ -1913,7 +1938,7 @@ FT_Bool is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */ FT_Open_Args args2; - FT_Stream stream2 = 0; + FT_Stream stream2 = NULL; FT_Raccess_Guess( library, stream, @@ -2049,8 +2074,7 @@ FT_Module* limit; - /* test for valid `library' delayed to */ - /* FT_Stream_New() */ + /* test for valid `library' delayed to `FT_Stream_New' */ if ( ( !aface && face_index >= 0 ) || !args ) return FT_THROW( Invalid_Argument ); @@ -2075,7 +2099,7 @@ if ( FT_MODULE_IS_DRIVER( driver ) ) { FT_Int num_params = 0; - FT_Parameter* params = 0; + FT_Parameter* params = NULL; if ( args->flags & FT_OPEN_PARAMS ) @@ -2109,7 +2133,7 @@ if ( FT_MODULE_IS_DRIVER( cur[0] ) ) { FT_Int num_params = 0; - FT_Parameter* params = 0; + FT_Parameter* params = NULL; driver = FT_DRIVER( cur[0] ); @@ -2297,7 +2321,7 @@ FT_Open_Args open; - /* test for valid `face' delayed to FT_Attach_Stream() */ + /* test for valid `face' delayed to `FT_Attach_Stream' */ if ( !filepathname ) return FT_THROW( Invalid_Argument ); @@ -2323,7 +2347,7 @@ FT_Driver_Class clazz; - /* test for valid `parameters' delayed to FT_Stream_New() */ + /* test for valid `parameters' delayed to `FT_Stream_New' */ if ( !face ) return FT_THROW( Invalid_Face_Handle ); @@ -2359,6 +2383,9 @@ FT_EXPORT_DEF( FT_Error ) FT_Reference_Face( FT_Face face ) { + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + face->internal->refcount++; return FT_Err_Ok; @@ -2417,20 +2444,20 @@ FT_Driver driver; FT_Driver_Class clazz; - FT_Size size = 0; - FT_ListNode node = 0; + FT_Size size = NULL; + FT_ListNode node = NULL; if ( !face ) return FT_THROW( Invalid_Face_Handle ); if ( !asize ) - return FT_THROW( Invalid_Size_Handle ); + return FT_THROW( Invalid_Argument ); if ( !face->driver ) return FT_THROW( Invalid_Driver_Handle ); - *asize = 0; + *asize = NULL; driver = face->driver; clazz = driver->clazz; @@ -2443,7 +2470,7 @@ size->face = face; /* for now, do not use any internal fields in size objects */ - size->internal = 0; + size->internal = NULL; if ( clazz->init_size ) error = clazz->init_size( size ); @@ -2501,7 +2528,7 @@ if ( face->size == size ) { - face->size = 0; + face->size = NULL; if ( face->sizes_list.head ) face->size = (FT_Size)(face->sizes_list.head->data); } @@ -2934,6 +2961,8 @@ FT_Size_RequestRec req; + /* check of `face' delayed to `FT_Request_Size' */ + if ( !char_width ) char_width = char_height; else if ( !char_height ) @@ -2972,6 +3001,8 @@ FT_Size_RequestRec req; + /* check of `face' delayed to `FT_Request_Size' */ + if ( pixel_width == 0 ) pixel_width = pixel_height; else if ( pixel_height == 0 ) @@ -2983,14 +3014,14 @@ pixel_height = 1; /* use `>=' to avoid potential compiler warning on 16bit platforms */ - if ( pixel_width >= 0xFFFFU ) - pixel_width = 0xFFFFU; + if ( pixel_width >= 0xFFFFU ) + pixel_width = 0xFFFFU; if ( pixel_height >= 0xFFFFU ) pixel_height = 0xFFFFU; req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; - req.width = pixel_width << 6; - req.height = pixel_height << 6; + req.width = (FT_Long)( pixel_width << 6 ); + req.height = (FT_Long)( pixel_height << 6 ); req.horiResolution = 0; req.vertResolution = 0; @@ -3122,15 +3153,6 @@ { if ( cur[0]->encoding == encoding ) { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "FT_Select_Charmap: requested charmap is found (%d), " - "but in too late position to cache\n", - cur - face->charmaps )); - continue; - } -#endif face->charmap = cur[0]; return 0; } @@ -3154,8 +3176,9 @@ return FT_THROW( Invalid_Face_Handle ); cur = face->charmaps; - if ( !cur ) + if ( !cur || !charmap ) return FT_THROW( Invalid_CharMap_Handle ); + if ( FT_Get_CMap_Format( charmap ) == 14 ) return FT_THROW( Invalid_Argument ); @@ -3165,19 +3188,11 @@ { if ( cur[0] == charmap ) { -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "FT_Set_Charmap: requested charmap is found (%d), " - "but in too late position to cache\n", - cur - face->charmaps )); - continue; - } -#endif face->charmap = cur[0]; - return 0; + return FT_Err_Ok; } } + return FT_THROW( Invalid_Argument ); } @@ -3199,15 +3214,6 @@ FT_ASSERT( i < charmap->face->num_charmaps ); -#ifdef FT_MAX_CHARMAP_CACHEABLE - if ( i > FT_MAX_CHARMAP_CACHEABLE ) - { - FT_ERROR(( "FT_Get_Charmap_Index: requested charmap is found (%d), " - "but in too late position to cache\n", - i )); - return -i; - } -#endif return i; } @@ -3418,8 +3424,9 @@ FT_UInt result = 0; - if ( face && face->charmap && - face->charmap->encoding == FT_ENCODING_UNICODE ) + if ( face && + face->charmap && + face->charmap->encoding == FT_ENCODING_UNICODE ) { FT_CharMap charmap = find_variant_selector_charmap( face ); FT_CMap ucmap = FT_CMAP( face->charmap ); @@ -3597,7 +3604,9 @@ FT_UInt result = 0; - if ( face && FT_HAS_GLYPH_NAMES( face ) ) + if ( face && + FT_HAS_GLYPH_NAMES( face ) && + glyph_name ) { FT_Service_GlyphDict service; @@ -3622,27 +3631,30 @@ FT_Pointer buffer, FT_UInt buffer_max ) { - FT_Error error = FT_ERR( Invalid_Argument ); + FT_Error error; + FT_Service_GlyphDict service; - /* clean up buffer */ - if ( buffer && buffer_max > 0 ) - ((FT_Byte*)buffer)[0] = 0; + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); - if ( face && - (FT_Long)glyph_index <= face->num_glyphs && - FT_HAS_GLYPH_NAMES( face ) ) - { - FT_Service_GlyphDict service; + if ( !buffer || buffer_max == 0 ) + return FT_THROW( Invalid_Argument ); + /* clean up buffer */ + ((FT_Byte*)buffer)[0] = '\0'; - FT_FACE_LOOKUP_SERVICE( face, - service, - GLYPH_DICT ); + if ( (FT_Long)glyph_index >= face->num_glyphs ) + return FT_THROW( Invalid_Glyph_Index ); - if ( service && service->get_name ) - error = service->get_name( face, glyph_index, buffer, buffer_max ); - } + if ( !FT_HAS_GLYPH_NAMES( face ) ) + return FT_THROW( Invalid_Argument ); + + FT_FACE_LOOKUP_SERVICE( face, service, GLYPH_DICT ); + if ( service && service->get_name ) + error = service->get_name( face, glyph_index, buffer, buffer_max ); + else + error = FT_THROW( Invalid_Argument ); return error; } @@ -3683,7 +3695,7 @@ FT_Get_Sfnt_Table( FT_Face face, FT_Sfnt_Tag tag ) { - void* table = 0; + void* table = NULL; FT_Service_SFNT_Table service; @@ -3733,6 +3745,8 @@ FT_ULong offset; + /* test for valid `length' delayed to `service->table_info' */ + if ( !face || !FT_IS_SFNT( face ) ) return FT_THROW( Invalid_Face_Handle ); @@ -3800,12 +3814,12 @@ FT_Face face; - if ( size == NULL ) - return FT_THROW( Invalid_Argument ); + if ( !size ) + return FT_THROW( Invalid_Size_Handle ); face = size->face; - if ( face == NULL || face->driver == NULL ) - return FT_THROW( Invalid_Argument ); + if ( !face || !face->driver ) + return FT_THROW( Invalid_Face_Handle ); /* we don't need anything more complex than that; all size objects */ /* are already listed by the face */ @@ -3834,7 +3848,7 @@ FT_ListNode* node ) { FT_ListNode cur; - FT_Renderer result = 0; + FT_Renderer result = NULL; if ( !library ) @@ -3846,7 +3860,7 @@ { if ( *node ) cur = (*node)->next; - *node = 0; + *node = NULL; } while ( cur ) @@ -3984,7 +3998,7 @@ FT_Get_Renderer( FT_Library library, FT_Glyph_Format format ) { - /* test for valid `library' delayed to FT_Lookup_Renderer() */ + /* test for valid `library' delayed to `FT_Lookup_Renderer' */ return FT_Lookup_Renderer( library, format, 0 ); } @@ -4001,12 +4015,26 @@ FT_ListNode node; FT_Error error = FT_Err_Ok; + FT_Renderer_SetModeFunc set_mode; + if ( !library ) - return FT_THROW( Invalid_Library_Handle ); + { + error = FT_THROW( Invalid_Library_Handle ); + goto Exit; + } if ( !renderer ) - return FT_THROW( Invalid_Argument ); + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( num_params > 0 && !parameters ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } node = FT_List_Find( &library->renderers, renderer ); if ( !node ) @@ -4020,18 +4048,14 @@ if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE ) library->cur_renderer = renderer; - if ( num_params > 0 ) - { - FT_Renderer_SetModeFunc set_mode = renderer->clazz->set_mode; - + set_mode = renderer->clazz->set_mode; - for ( ; num_params > 0; num_params-- ) - { - error = set_mode( renderer, parameters->tag, parameters->data ); - if ( error ) - break; - parameters++; - } + for ( ; num_params > 0; num_params-- ) + { + error = set_mode( renderer, parameters->tag, parameters->data ); + if ( error ) + break; + parameters++; } Exit: @@ -4056,8 +4080,7 @@ default: { - FT_ListNode node = 0; - FT_Bool update = 0; + FT_ListNode node = NULL; /* small shortcut for the very common case */ @@ -4084,13 +4107,7 @@ /* now, look for another renderer that supports the same */ /* format. */ renderer = FT_Lookup_Renderer( library, slot->format, &node ); - update = 1; } - - /* if we changed the current renderer for the glyph image format */ - /* we need to select it as the next current one */ - if ( !error && update && renderer ) - FT_Set_Renderer( library, renderer, 0, 0 ); } } @@ -4100,28 +4117,32 @@ #define FT_COMPONENT trace_bitmap /* we convert to a single bitmap format for computing the checksum */ + if ( !error ) { FT_Bitmap bitmap; FT_Error err; - FT_Bitmap_New( &bitmap ); + FT_Bitmap_Init( &bitmap ); + /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */ err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 ); if ( !err ) { MD5_CTX ctx; unsigned char md5[16]; int i; + unsigned int rows = bitmap.rows; + unsigned int pitch = (unsigned int)bitmap.pitch; - MD5_Init( &ctx); - MD5_Update( &ctx, bitmap.buffer, bitmap.rows * bitmap.pitch ); + MD5_Init( &ctx ); + MD5_Update( &ctx, bitmap.buffer, rows * pitch ); MD5_Final( md5, &ctx ); FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n" " ", - bitmap.rows, bitmap.pitch )); + rows, pitch )); for ( i = 0; i < 16; i++ ) FT_TRACE3(( "%02X", md5[i] )); FT_TRACE3(( "\n" )); @@ -4194,7 +4215,7 @@ if ( library && library->auto_hinter == module ) - library->auto_hinter = 0; + library->auto_hinter = NULL; /* if the module is a renderer */ if ( FT_MODULE_IS_RENDERER( module ) ) @@ -4290,17 +4311,10 @@ /* if the module is a font driver */ if ( FT_MODULE_IS_DRIVER( module ) ) { - /* allocate glyph loader if needed */ FT_Driver driver = FT_DRIVER( module ); driver->clazz = (FT_Driver_Class)module->clazz; - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - { - error = FT_GlyphLoader_New( memory, &driver->glyph_loader ); - if ( error ) - goto Fail; - } } if ( clazz->module_init ) @@ -4317,15 +4331,6 @@ return error; Fail: - if ( FT_MODULE_IS_DRIVER( module ) ) - { - FT_Driver driver = FT_DRIVER( module ); - - - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - FT_GlyphLoader_Done( driver->glyph_loader ); - } - if ( FT_MODULE_IS_RENDERER( module ) ) { FT_Renderer renderer = FT_RENDERER( module ); @@ -4348,7 +4353,7 @@ FT_Get_Module( FT_Library library, const char* module_name ) { - FT_Module result = 0; + FT_Module result = NULL; FT_Module* cur; FT_Module* limit; @@ -4460,7 +4465,7 @@ cur[0] = cur[1]; cur++; } - limit[0] = 0; + limit[0] = NULL; /* destroy the module */ Destroy_Module( module ); @@ -4603,6 +4608,9 @@ FT_EXPORT_DEF( FT_Error ) FT_Reference_Library( FT_Library library ) { + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + library->refcount++; return FT_Err_Ok; @@ -4619,7 +4627,7 @@ FT_Error error; - if ( !memory ) + if ( !memory || !alibrary ) return FT_THROW( Invalid_Argument ); #ifdef FT_DEBUG_LEVEL_ERROR @@ -4640,12 +4648,9 @@ goto Fail; #endif - /* allocate the render pool */ - library->raster_pool_size = FT_RENDER_POOL_SIZE; -#if FT_RENDER_POOL_SIZE > 0 - if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) - goto Fail; -#endif + /* we don't use raster_pool anymore. */ + library->raster_pool_size = 0; + library->raster_pool = NULL; library->version_major = FREETYPE_MAJOR; library->version_minor = FREETYPE_MINOR; @@ -4658,8 +4663,8 @@ return FT_Err_Ok; - Fail: #ifdef FT_CONFIG_OPTION_PIC + Fail: ft_pic_container_destroy( library ); #endif FT_FREE( library ); @@ -4788,16 +4793,12 @@ if ( module ) { Destroy_Module( module ); - library->modules[n] = 0; + library->modules[n] = NULL; } } } #endif - /* Destroy raster objects */ - FT_FREE( library->raster_pool ); - library->raster_pool_size = 0; - #ifdef FT_CONFIG_OPTION_PIC /* Destroy pic container contents */ ft_pic_container_destroy( library ); diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c index 4a39dcd..d821c49 100644 --- a/src/base/ftoutln.c +++ b/src/base/ftoutln.c @@ -4,7 +4,7 @@ /* */ /* FreeType outline management (body). */ /* */ -/* Copyright 1996-2008, 2010, 2012-2014 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -73,7 +73,10 @@ FT_Pos delta; - if ( !outline || !func_interface ) + if ( !outline ) + return FT_THROW( Invalid_Outline ); + + if ( !func_interface ) return FT_THROW( Invalid_Argument ); shift = func_interface->shift; @@ -276,7 +279,7 @@ if ( error ) goto Exit; - first = last + 1; + first = (FT_UInt)last + 1; } FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); @@ -317,7 +320,7 @@ FT_NEW_ARRAY( anoutline->contours, numContours ) ) goto Fail; - anoutline->n_points = (FT_UShort)numPoints; + anoutline->n_points = (FT_Short)numPoints; anoutline->n_contours = (FT_Short)numContours; anoutline->flags |= FT_OUTLINE_OWNER; @@ -362,7 +365,7 @@ /* empty glyph? */ if ( n_points == 0 && n_contours == 0 ) - return 0; + return FT_Err_Ok; /* check point and contour counts */ if ( n_points <= 0 || n_contours <= 0 ) @@ -384,7 +387,7 @@ goto Bad; /* XXX: check the tags array */ - return 0; + return FT_Err_Ok; } Bad: @@ -401,8 +404,10 @@ FT_Int is_owner; - if ( !source || !target || - source->n_points != target->n_points || + if ( !source || !target ) + return FT_THROW( Invalid_Outline ); + + if ( source->n_points != target->n_points || source->n_contours != target->n_contours ) return FT_THROW( Invalid_Argument ); @@ -430,20 +435,21 @@ FT_Outline_Done_Internal( FT_Memory memory, FT_Outline* outline ) { - if ( memory && outline ) - { - if ( outline->flags & FT_OUTLINE_OWNER ) - { - FT_FREE( outline->points ); - FT_FREE( outline->tags ); - FT_FREE( outline->contours ); - } - *outline = null_outline; + if ( !outline ) + return FT_THROW( Invalid_Outline ); - return FT_Err_Ok; - } - else + if ( !memory ) return FT_THROW( Invalid_Argument ); + + if ( outline->flags & FT_OUTLINE_OWNER ) + { + FT_FREE( outline->points ); + FT_FREE( outline->tags ); + FT_FREE( outline->contours ); + } + *outline = null_outline; + + return FT_Err_Ok; } @@ -606,7 +612,6 @@ FT_Raster_Params* params ) { FT_Error error; - FT_Bool update = FALSE; FT_Renderer renderer; FT_ListNode node; @@ -614,7 +619,10 @@ if ( !library ) return FT_THROW( Invalid_Library_Handle ); - if ( !outline || !params ) + if ( !outline ) + return FT_THROW( Invalid_Outline ); + + if ( !params ) return FT_THROW( Invalid_Argument ); renderer = library->cur_renderer; @@ -637,14 +645,8 @@ /* format */ renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, &node ); - update = TRUE; } - /* if we changed the current renderer for the glyph image format */ - /* we need to select it as the next current one */ - if ( !error && update && renderer ) - FT_Set_Renderer( library, renderer, 0, 0 ); - return error; } @@ -662,7 +664,7 @@ if ( !abitmap ) return FT_THROW( Invalid_Argument ); - /* other checks are delayed to FT_Outline_Render() */ + /* other checks are delayed to `FT_Outline_Render' */ params.target = abitmap; params.flags = 0; @@ -911,7 +913,7 @@ if ( !outline ) - return FT_THROW( Invalid_Argument ); + return FT_THROW( Invalid_Outline ); xstrength /= 2; ystrength /= 2; @@ -993,13 +995,13 @@ l = FT_MIN( l_in, l_out ); /* non-strict inequalities avoid divide-by-zero when q == l == 0 */ - if ( FT_MulFix( xstrength, q ) <= FT_MulFix( d, l ) ) + if ( FT_MulFix( xstrength, q ) <= FT_MulFix( l, d ) ) shift.x = FT_MulDiv( shift.x, xstrength, d ); else shift.x = FT_MulDiv( shift.x, l, q ); - if ( FT_MulFix( ystrength, q ) <= FT_MulFix( d, l ) ) + if ( FT_MulFix( ystrength, q ) <= FT_MulFix( l, d ) ) shift.y = FT_MulDiv( shift.y, ystrength, d ); else shift.y = FT_MulDiv( shift.y, l, q ); @@ -1041,14 +1043,19 @@ /* We use the nonzero winding rule to find the orientation. */ /* Since glyph outlines behave much more `regular' than arbitrary */ /* cubic or quadratic curves, this test deals with the polygon */ - /* only which is spanned up by the control points. */ + /* only that is spanned up by the control points. */ FT_Outline_Get_CBox( outline, &cbox ); - xshift = FT_MSB( FT_ABS( cbox.xMax ) | FT_ABS( cbox.xMin ) ) - 14; + /* Handle collapsed outlines to avoid undefined FT_MSB. */ + if ( cbox.xMin == cbox.xMax || cbox.yMin == cbox.yMax ) + return FT_ORIENTATION_NONE; + + xshift = FT_MSB( (FT_UInt32)( FT_ABS( cbox.xMax ) | + FT_ABS( cbox.xMin ) ) ) - 14; xshift = FT_MAX( xshift, 0 ); - yshift = FT_MSB( cbox.yMax - cbox.yMin ) - 14; + yshift = FT_MSB( (FT_UInt32)( cbox.yMax - cbox.yMin ) ) - 14; yshift = FT_MAX( yshift, 0 ); points = outline->points; diff --git a/src/base/ftpatent.c b/src/base/ftpatent.c index 82b42f0..bf2b085 100644 --- a/src/base/ftpatent.c +++ b/src/base/ftpatent.c @@ -5,7 +5,8 @@ /* FreeType API for checking patented TrueType bytecode instructions */ /* (body). */ /* */ -/* Copyright 2007, 2008, 2010 by David Turner. */ +/* Copyright 2007-2015 by */ +/* David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ diff --git a/src/base/ftpic.c b/src/base/ftpic.c index 9bd92f7..6c4b1cd 100644 --- a/src/base/ftpic.c +++ b/src/base/ftpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services (body). */ /* */ -/* Copyright 2009, 2013 by */ +/* Copyright 2009-2015 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/base/ftrfork.c b/src/base/ftrfork.c index 5352970..82d54f8 100644 --- a/src/base/ftrfork.c +++ b/src/base/ftrfork.c @@ -4,7 +4,7 @@ /* */ /* Embedded resource forks accessor (body). */ /* */ -/* Copyright 2004-2010, 2013, 2014 by */ +/* Copyright 2004-2015 by */ /* Masatake YAMATO and Redhat K.K. */ /* */ /* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ @@ -63,7 +63,7 @@ FT_UNUSED( library ); - error = FT_Stream_Seek( stream, rfork_offset ); + error = FT_Stream_Seek( stream, (FT_ULong)rfork_offset ); if ( error ) return error; @@ -89,7 +89,7 @@ if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset ) return FT_THROW( Unknown_File_Format ); - error = FT_Stream_Seek( stream, map_pos ); + error = FT_Stream_Seek( stream, (FT_ULong)map_pos ); if ( error ) return error; @@ -124,7 +124,7 @@ if ( type_list == -1 ) return FT_THROW( Unknown_File_Format ); - error = FT_Stream_Seek( stream, map_pos + type_list ); + error = FT_Stream_Seek( stream, (FT_ULong)( map_pos + type_list ) ); if ( error ) return error; @@ -166,7 +166,7 @@ FT_TRACE3(( "\n" )); - error = FT_Stream_Seek( stream, map_offset ); + error = FT_Stream_Seek( stream, (FT_ULong)map_offset ); if ( error ) return error; @@ -182,10 +182,10 @@ return error; FT_TRACE2(( "Resource tags: %c%c%c%c\n", - (char)( 0xff & ( tag_internal >> 24 ) ), - (char)( 0xff & ( tag_internal >> 16 ) ), - (char)( 0xff & ( tag_internal >> 8 ) ), - (char)( 0xff & ( tag_internal >> 0 ) ) )); + (char)( 0xFF & ( tag_internal >> 24 ) ), + (char)( 0xFF & ( tag_internal >> 16 ) ), + (char)( 0xFF & ( tag_internal >> 8 ) ), + (char)( 0xFF & ( tag_internal >> 0 ) ) )); FT_TRACE3(( " : subcount=%d, suboffset=0x%04x\n", subcnt, rpos )); @@ -194,7 +194,7 @@ *count = subcnt + 1; rpos += map_offset; - error = FT_Stream_Seek( stream, rpos ); + error = FT_Stream_Seek( stream, (FT_ULong)rpos ); if ( error ) return error; @@ -220,7 +220,7 @@ if (sort_by_res_id) { - ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ), + ft_qsort( ref, (size_t)*count, sizeof ( FT_RFork_Ref ), ( int(*)(const void*, const void*) ) ft_raccess_sort_ref_by_id ); @@ -713,9 +713,9 @@ FT_UShort n_of_entries; int i; - FT_UInt32 entry_id, entry_offset, entry_length = 0; + FT_Int32 entry_id, entry_offset, entry_length = 0; - const FT_UInt32 resource_fork_entry_id = 0x2; + const FT_Int32 resource_fork_entry_id = 0x2; FT_UNUSED( library ); FT_UNUSED( base_file_name ); @@ -813,7 +813,9 @@ tmp = ft_strrchr( original_name, '/' ); if ( tmp ) { - ft_strncpy( new_name, original_name, tmp - original_name + 1 ); + ft_strncpy( new_name, + original_name, + (size_t)( tmp - original_name + 1 ) ); new_name[tmp - original_name + 1] = '\0'; slash = tmp + 1; } diff --git a/src/base/ftsnames.c b/src/base/ftsnames.c index 260e91c..80304e5 100644 --- a/src/base/ftsnames.c +++ b/src/base/ftsnames.c @@ -7,7 +7,7 @@ /* */ /* This is _not_ used to retrieve glyph names! */ /* */ -/* Copyright 1996-2001, 2002, 2009 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/base/ftstream.c b/src/base/ftstream.c index d965333..b68f3f8 100644 --- a/src/base/ftstream.c +++ b/src/base/ftstream.c @@ -4,7 +4,7 @@ /* */ /* I/O stream support (body). */ /* */ -/* Copyright 2000-2002, 2004-2006, 2008-2011, 2013 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, */ @@ -39,9 +39,9 @@ stream->base = (FT_Byte*) base; stream->size = size; stream->pos = 0; - stream->cursor = 0; - stream->read = 0; - stream->close = 0; + stream->cursor = NULL; + stream->read = NULL; + stream->close = NULL; } @@ -95,11 +95,11 @@ if ( distance < 0 ) return FT_THROW( Invalid_Stream_Operation ); - return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) ); + return FT_Stream_Seek( stream, stream->pos + (FT_ULong)distance ); } - FT_BASE_DEF( FT_Long ) + FT_BASE_DEF( FT_ULong ) FT_Stream_Pos( FT_Stream stream ) { return stream->pos; @@ -203,8 +203,8 @@ *pbytes = (FT_Byte*)stream->cursor; /* equivalent to FT_Stream_ExitFrame(), with no memory block release */ - stream->cursor = 0; - stream->limit = 0; + stream->cursor = NULL; + stream->limit = NULL; } return error; @@ -226,7 +226,7 @@ FT_FREE( *pbytes ); #endif } - *pbytes = 0; + *pbytes = NULL; } @@ -260,7 +260,9 @@ #ifdef FT_DEBUG_MEMORY /* assume _ft_debug_file and _ft_debug_lineno are already set */ - stream->base = (unsigned char*)ft_mem_qalloc( memory, count, &error ); + stream->base = (unsigned char*)ft_mem_qalloc( memory, + (FT_Long)count, + &error ); if ( error ) goto Exit; #else @@ -333,8 +335,8 @@ FT_FREE( stream->base ); #endif } - stream->cursor = 0; - stream->limit = 0; + stream->cursor = NULL; + stream->limit = NULL; } @@ -348,7 +350,7 @@ result = 0; if ( stream->cursor < stream->limit ) - result = *stream->cursor++; + result = (FT_Char)*stream->cursor++; return result; } @@ -357,8 +359,8 @@ FT_BASE_DEF( FT_UShort ) FT_Stream_GetUShort( FT_Stream stream ) { - FT_Byte* p; - FT_Short result; + FT_Byte* p; + FT_UShort result; FT_ASSERT( stream && stream->cursor ); @@ -376,8 +378,8 @@ FT_BASE_DEF( FT_UShort ) FT_Stream_GetUShortLE( FT_Stream stream ) { - FT_Byte* p; - FT_Short result; + FT_Byte* p; + FT_UShort result; FT_ASSERT( stream && stream->cursor ); @@ -396,7 +398,7 @@ FT_Stream_GetUOffset( FT_Stream stream ) { FT_Byte* p; - FT_Long result; + FT_ULong result; FT_ASSERT( stream && stream->cursor ); @@ -414,7 +416,7 @@ FT_Stream_GetULong( FT_Stream stream ) { FT_Byte* p; - FT_Long result; + FT_ULong result; FT_ASSERT( stream && stream->cursor ); @@ -432,7 +434,7 @@ FT_Stream_GetULongLE( FT_Stream stream ) { FT_Byte* p; - FT_Long result; + FT_ULong result; FT_ASSERT( stream && stream->cursor ); @@ -471,7 +473,7 @@ } stream->pos++; - return result; + return (FT_Char)result; Fail: *error = FT_THROW( Invalid_Stream_Operation ); @@ -485,11 +487,11 @@ FT_BASE_DEF( FT_UShort ) FT_Stream_ReadUShort( FT_Stream stream, - FT_Error* error ) + FT_Error* error ) { - FT_Byte reads[2]; - FT_Byte* p = 0; - FT_Short result = 0; + FT_Byte reads[2]; + FT_Byte* p = 0; + FT_UShort result = 0; FT_ASSERT( stream ); @@ -506,9 +508,7 @@ p = reads; } else - { p = stream->base + stream->pos; - } if ( p ) result = FT_NEXT_USHORT( p ); @@ -532,11 +532,11 @@ FT_BASE_DEF( FT_UShort ) FT_Stream_ReadUShortLE( FT_Stream stream, - FT_Error* error ) + FT_Error* error ) { - FT_Byte reads[2]; - FT_Byte* p = 0; - FT_Short result = 0; + FT_Byte reads[2]; + FT_Byte* p = 0; + FT_UShort result = 0; FT_ASSERT( stream ); @@ -553,9 +553,7 @@ p = reads; } else - { p = stream->base + stream->pos; - } if ( p ) result = FT_NEXT_USHORT_LE( p ); @@ -579,11 +577,11 @@ FT_BASE_DEF( FT_ULong ) FT_Stream_ReadUOffset( FT_Stream stream, - FT_Error* error ) + FT_Error* error ) { FT_Byte reads[3]; - FT_Byte* p = 0; - FT_Long result = 0; + FT_Byte* p = 0; + FT_ULong result = 0; FT_ASSERT( stream ); @@ -600,9 +598,7 @@ p = reads; } else - { p = stream->base + stream->pos; - } if ( p ) result = FT_NEXT_UOFF3( p ); @@ -626,11 +622,11 @@ FT_BASE_DEF( FT_ULong ) FT_Stream_ReadULong( FT_Stream stream, - FT_Error* error ) + FT_Error* error ) { FT_Byte reads[4]; - FT_Byte* p = 0; - FT_Long result = 0; + FT_Byte* p = 0; + FT_ULong result = 0; FT_ASSERT( stream ); @@ -647,9 +643,7 @@ p = reads; } else - { p = stream->base + stream->pos; - } if ( p ) result = FT_NEXT_ULONG( p ); @@ -673,11 +667,11 @@ FT_BASE_DEF( FT_ULong ) FT_Stream_ReadULongLE( FT_Stream stream, - FT_Error* error ) + FT_Error* error ) { FT_Byte reads[4]; - FT_Byte* p = 0; - FT_Long result = 0; + FT_Byte* p = 0; + FT_ULong result = 0; FT_ASSERT( stream ); @@ -694,9 +688,7 @@ p = reads; } else - { p = stream->base + stream->pos; - } if ( p ) result = FT_NEXT_ULONG_LE( p ); @@ -728,9 +720,12 @@ FT_Byte* cursor; - if ( !fields || !stream ) + if ( !fields ) return FT_THROW( Invalid_Argument ); + if ( !stream ) + return FT_THROW( Invalid_Stream_Handle ); + cursor = stream->cursor; error = FT_Err_Ok; diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c index ee61cec..842ee30 100644 --- a/src/base/ftstroke.c +++ b/src/base/ftstroke.c @@ -4,7 +4,7 @@ /* */ /* FreeType path stroker (body). */ /* */ -/* Copyright 2002-2006, 2008-2011, 2013 by */ +/* Copyright 2002-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -347,7 +347,7 @@ ft_stroke_border_close( FT_StrokeBorder border, FT_Bool reverse ) { - FT_UInt start = border->start; + FT_UInt start = (FT_UInt)border->start; FT_UInt count = border->num_points; @@ -599,7 +599,7 @@ if ( border->start >= 0 ) ft_stroke_border_close( border, FALSE ); - border->start = border->num_points; + border->start = (FT_Int)border->num_points; border->movable = FALSE; return ft_stroke_border_lineto( border, to, FALSE ); @@ -742,7 +742,7 @@ } } - outline->n_points = (short)( outline->n_points + border->num_points ); + outline->n_points += (short)border->num_points; FT_ASSERT( FT_Outline_Check( outline ) == 0 ); } @@ -795,6 +795,9 @@ if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + if ( !astroker ) return FT_THROW( Invalid_Argument ); memory = library->memory; @@ -822,14 +825,17 @@ FT_Stroker_LineJoin line_join, FT_Fixed miter_limit ) { + if ( !stroker ) + return; + stroker->radius = radius; stroker->line_cap = line_cap; stroker->line_join = line_join; stroker->miter_limit = miter_limit; /* ensure miter limit has sensible value */ - if ( stroker->miter_limit < 0x10000 ) - stroker->miter_limit = 0x10000; + if ( stroker->miter_limit < 0x10000L ) + stroker->miter_limit = 0x10000L; /* save line join style: */ /* line join style can be temporarily changed when stroking curves */ @@ -993,7 +999,9 @@ /* Only intersect borders if between two lineto's and both */ /* lines are long enough (line_length is zero for curves). */ - if ( !border->movable || line_length == 0 ) + /* Also avoid U-turns of nearly 180 degree. */ + if ( !border->movable || line_length == 0 || + theta > 0x59C000 || theta < -0x59C000 ) intersect = FALSE; else { @@ -1002,7 +1010,8 @@ FT_Tan( theta ) ) ); - intersect = FT_BOOL( stroker->line_length >= min_length && + intersect = FT_BOOL( min_length && + stroker->line_length >= min_length && line_length >= min_length ); } @@ -1213,11 +1222,8 @@ goto Exit; /* when we turn to the right, the inside side is 0 */ - inside_side = 0; - /* otherwise, the inside side is 1 */ - if ( turn < 0 ) - inside_side = 1; + inside_side = ( turn < 0 ); /* process the inside side */ error = ft_stroker_inside( stroker, inside_side, line_length ); @@ -1225,7 +1231,7 @@ goto Exit; /* process the outside side */ - error = ft_stroker_outside( stroker, 1 - inside_side, line_length ); + error = ft_stroker_outside( stroker, !inside_side, line_length ); Exit: return error; @@ -1287,6 +1293,9 @@ FT_Fixed line_length; + if ( !stroker || !to ) + return FT_THROW( Invalid_Argument ); + delta.x = to->x - stroker->center.x; delta.y = to->y - stroker->center.y; @@ -1360,6 +1369,12 @@ FT_Bool first_arc = TRUE; + if ( !stroker || !control || !to ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + /* if all control points are coincident, this is a no-op; */ /* avoid creating a spurious corner */ if ( FT_IS_SMALL( stroker->center.x - control->x ) && @@ -1556,6 +1571,12 @@ FT_Bool first_arc = TRUE; + if ( !stroker || !control1 || !control2 || !to ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + /* if all control points are coincident, this is a no-op; */ /* avoid creating a spurious corner */ if ( FT_IS_SMALL( stroker->center.x - control1->x ) && @@ -1758,6 +1779,9 @@ FT_Vector* to, FT_Bool open ) { + if ( !stroker || !to ) + return FT_THROW( Invalid_Argument ); + /* We cannot process the first point, because there is not enough */ /* information regarding its corner/cap. The latter will be processed */ /* in the `FT_Stroker_EndSubPath' routine. */ @@ -1797,7 +1821,7 @@ FT_ASSERT( left->start >= 0 ); - new_points = left->num_points - left->start; + new_points = (FT_Int)left->num_points - left->start; if ( new_points > 0 ) { error = ft_stroke_border_grow( right, (FT_UInt)new_points ); @@ -1837,8 +1861,8 @@ } } - left->num_points = left->start; - right->num_points += new_points; + left->num_points = (FT_UInt)left->start; + right->num_points += (FT_UInt)new_points; right->movable = FALSE; left->movable = FALSE; @@ -1858,6 +1882,12 @@ FT_Error error = FT_Err_Ok; + if ( !stroker ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + if ( stroker->subpath_open ) { FT_StrokeBorder right = stroker->borders; @@ -1910,11 +1940,8 @@ if ( turn != 0 ) { /* when we turn to the right, the inside side is 0 */ - inside_side = 0; - /* otherwise, the inside side is 1 */ - if ( turn < 0 ) - inside_side = 1; + inside_side = ( turn < 0 ); error = ft_stroker_inside( stroker, inside_side, @@ -1924,7 +1951,7 @@ /* process the outside side */ error = ft_stroker_outside( stroker, - 1 - inside_side, + !inside_side, stroker->subpath_line_length ); if ( error ) goto Exit; @@ -1983,6 +2010,12 @@ FT_Error error; + if ( !stroker ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + error = ft_stroke_border_get_counts( stroker->borders + 0, &count1, &count2 ); if ( error ) @@ -1997,8 +2030,12 @@ num_contours = count2 + count4; Exit: - *anum_points = num_points; - *anum_contours = num_contours; + if ( anum_points ) + *anum_points = num_points; + + if ( anum_contours ) + *anum_contours = num_contours; + return error; } @@ -2010,6 +2047,9 @@ FT_StrokerBorder border, FT_Outline* outline ) { + if ( !stroker || !outline ) + return; + if ( border == FT_STROKER_BORDER_LEFT || border == FT_STROKER_BORDER_RIGHT ) { @@ -2059,7 +2099,10 @@ FT_Int tag; /* current point's state */ - if ( !outline || !stroker ) + if ( !outline ) + return FT_THROW( Invalid_Outline ); + + if ( !stroker ) return FT_THROW( Invalid_Argument ); FT_Stroker_Rewind( stroker ); @@ -2071,7 +2114,7 @@ FT_UInt last; /* index of last point in contour */ - last = outline->contours[n]; + last = (FT_UInt)outline->contours[n]; limit = outline->points + last; /* skip empty points; we don't stroke these */ @@ -2258,18 +2301,20 @@ FT_Stroker stroker, FT_Bool destroy ) { - FT_Error error = FT_ERR( Invalid_Argument ); - FT_Glyph glyph = NULL; + FT_Error error = FT_ERR( Invalid_Argument ); + FT_Glyph glyph = NULL; + + /* for FT_OUTLINE_GLYPH_CLASS_GET (in PIC mode) */ FT_Library library = stroker->library; FT_UNUSED( library ); - if ( pglyph == NULL ) + if ( !pglyph ) goto Exit; glyph = *pglyph; - if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) + if ( !glyph || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) goto Exit; { @@ -2293,12 +2338,14 @@ if ( error ) goto Fail; - (void)FT_Stroker_GetCounts( stroker, &num_points, &num_contours ); + FT_Stroker_GetCounts( stroker, &num_points, &num_contours ); FT_Outline_Done( glyph->library, outline ); error = FT_Outline_New( glyph->library, - num_points, num_contours, outline ); + num_points, + (FT_Int)num_contours, + outline ); if ( error ) goto Fail; @@ -2334,18 +2381,20 @@ FT_Bool inside, FT_Bool destroy ) { - FT_Error error = FT_ERR( Invalid_Argument ); - FT_Glyph glyph = NULL; + FT_Error error = FT_ERR( Invalid_Argument ); + FT_Glyph glyph = NULL; + + /* for FT_OUTLINE_GLYPH_CLASS_GET (in PIC mode) */ FT_Library library = stroker->library; FT_UNUSED( library ); - if ( pglyph == NULL ) + if ( !pglyph ) goto Exit; glyph = *pglyph; - if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) + if ( !glyph || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) goto Exit; { @@ -2379,14 +2428,14 @@ if ( error ) goto Fail; - (void)FT_Stroker_GetBorderCounts( stroker, border, - &num_points, &num_contours ); + FT_Stroker_GetBorderCounts( stroker, border, + &num_points, &num_contours ); FT_Outline_Done( glyph->library, outline ); error = FT_Outline_New( glyph->library, num_points, - num_contours, + (FT_Int)num_contours, outline ); if ( error ) goto Fail; diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c index 3098a60..cd68533 100644 --- a/src/base/ftsynth.c +++ b/src/base/ftsynth.c @@ -4,7 +4,7 @@ /* */ /* FreeType synthesizing code for emboldening and slanting (body). */ /* */ -/* Copyright 2000-2006, 2010, 2012, 2013 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, */ @@ -48,9 +48,14 @@ FT_GlyphSlot_Oblique( FT_GlyphSlot slot ) { FT_Matrix transform; - FT_Outline* outline = &slot->outline; + FT_Outline* outline; + if ( !slot ) + return; + + outline = &slot->outline; + /* only oblique outline glyphs */ if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) return; @@ -84,12 +89,18 @@ FT_EXPORT_DEF( void ) FT_GlyphSlot_Embolden( FT_GlyphSlot slot ) { - FT_Library library = slot->library; - FT_Face face = slot->face; + FT_Library library; + FT_Face face; FT_Error error; FT_Pos xstr, ystr; + if ( !slot ) + return; + + library = slot->library; + face = slot->face; + if ( slot->format != FT_GLYPH_FORMAT_OUTLINE && slot->format != FT_GLYPH_FORMAT_BITMAP ) return; @@ -100,10 +111,8 @@ ystr = xstr; if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - { - /* ignore error */ - (void)FT_Outline_EmboldenXY( &slot->outline, xstr, ystr ); - } + FT_Outline_EmboldenXY( &slot->outline, xstr, ystr ); + else /* slot->format == FT_GLYPH_FORMAT_BITMAP */ { /* round to full pixels */ diff --git a/src/base/ftsystem.c b/src/base/ftsystem.c index 2c6ddac..1938fd8 100644 --- a/src/base/ftsystem.c +++ b/src/base/ftsystem.c @@ -4,7 +4,7 @@ /* */ /* ANSI-specific FreeType low-level system interface (body). */ /* */ -/* Copyright 1996-2002, 2006, 2008-2011, 2013 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -71,7 +71,7 @@ { FT_UNUSED( memory ); - return ft_smalloc( size ); + return ft_smalloc( (size_t)size ); } @@ -104,7 +104,7 @@ FT_UNUSED( memory ); FT_UNUSED( cur_size ); - return ft_srealloc( block, new_size ); + return ft_srealloc( block, (size_t)new_size ); } @@ -171,7 +171,7 @@ stream->descriptor.pointer = NULL; stream->size = 0; - stream->base = 0; + stream->base = NULL; } @@ -212,7 +212,7 @@ file = STREAM_FILE( stream ); if ( stream->pos != offset ) - ft_fseek( file, offset, SEEK_SET ); + ft_fseek( file, (long)offset, SEEK_SET ); return (unsigned long)ft_fread( buffer, 1, count, file ); } @@ -232,7 +232,7 @@ stream->descriptor.pointer = NULL; stream->pathname.pointer = (char*)filepathname; - stream->base = 0; + stream->base = NULL; stream->pos = 0; stream->read = NULL; stream->close = NULL; @@ -247,7 +247,7 @@ } ft_fseek( file, 0, SEEK_END ); - stream->size = ft_ftell( file ); + stream->size = (unsigned long)ft_ftell( file ); if ( !stream->size ) { FT_ERROR(( "FT_Stream_Open:" )); @@ -292,7 +292,7 @@ memory = (FT_Memory)ft_smalloc( sizeof ( *memory ) ); if ( memory ) { - memory->user = 0; + memory->user = NULL; memory->alloc = ft_alloc; memory->realloc = ft_realloc; memory->free = ft_free; diff --git a/src/base/fttrigon.c b/src/base/fttrigon.c index 4ffdcb7..5b24304 100644 --- a/src/base/fttrigon.c +++ b/src/base/fttrigon.c @@ -4,7 +4,7 @@ /* */ /* FreeType trigonometric functions (body). */ /* */ -/* Copyright 2001-2005, 2012-2013 by */ +/* Copyright 2001-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -45,7 +45,7 @@ /* this table was generated for FT_PI = 180L << 16, i.e. degrees */ #define FT_TRIG_MAX_ITERS 23 - static const FT_Fixed + static const FT_Angle ft_trig_arctan_table[] = { 1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 29335L, @@ -60,17 +60,20 @@ static FT_Fixed ft_trig_downscale( FT_Fixed val ) { - FT_Fixed s; - FT_Int64 v; + FT_Int s = 1; - s = val; - val = FT_ABS( val ); + if ( val < 0 ) + { + val = -val; + s = -1; + } - v = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL; - val = (FT_Fixed)( v >> 32 ); + /* 0x40000000 comes from regression analysis between true */ + /* and CORDIC hypotenuse, so it minimizes the error */ + val = (FT_Fixed)( ( (FT_Int64)val * FT_TRIG_SCALE + 0x40000000UL ) >> 32 ); - return ( s >= 0 ) ? val : -val; + return s < 0 ? -val : val; } #else /* !FT_LONG64 */ @@ -79,38 +82,53 @@ static FT_Fixed ft_trig_downscale( FT_Fixed val ) { - FT_Fixed s; - FT_UInt32 v1, v2, k1, k2, hi, lo1, lo2, lo3; + FT_Int s = 1; + FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; + + + if ( val < 0 ) + { + val = -val; + s = -1; + } + lo1 = (FT_UInt32)val & 0x0000FFFFU; + hi1 = (FT_UInt32)val >> 16; + lo2 = FT_TRIG_SCALE & 0x0000FFFFU; + hi2 = FT_TRIG_SCALE >> 16; - s = val; - val = FT_ABS( val ); + lo = lo1 * lo2; + i1 = lo1 * hi2; + i2 = lo2 * hi1; + hi = hi1 * hi2; - v1 = (FT_UInt32)val >> 16; - v2 = (FT_UInt32)( val & 0xFFFFL ); + /* Check carry overflow of i1 + i2 */ + i1 += i2; + hi += (FT_UInt32)( i1 < i2 ) << 16; - k1 = (FT_UInt32)FT_TRIG_SCALE >> 16; /* constant */ - k2 = (FT_UInt32)( FT_TRIG_SCALE & 0xFFFFL ); /* constant */ + hi += i1 >> 16; + i1 = i1 << 16; - hi = k1 * v1; - lo1 = k1 * v2 + k2 * v1; /* can't overflow */ + /* Check carry overflow of i1 + lo */ + lo += i1; + hi += ( lo < i1 ); - lo2 = ( k2 * v2 ) >> 16; - lo3 = FT_MAX( lo1, lo2 ); - lo1 += lo2; + /* 0x40000000 comes from regression analysis between true */ + /* and CORDIC hypotenuse, so it minimizes the error */ - hi += lo1 >> 16; - if ( lo1 < lo3 ) - hi += (FT_UInt32)0x10000UL; + /* Check carry overflow of lo + 0x40000000 */ + lo += 0x40000000UL; + hi += ( lo < 0x40000000UL ); - val = (FT_Fixed)hi; + val = (FT_Fixed)hi; - return ( s >= 0 ) ? val : -val; + return s < 0 ? -val : val; } #endif /* !FT_LONG64 */ + /* undefined and never called for zero vector */ static FT_Int ft_trig_prenorm( FT_Vector* vec ) { @@ -121,7 +139,7 @@ x = vec->x; y = vec->y; - shift = FT_MSB( FT_ABS( x ) | FT_ABS( y ) ); + shift = FT_MSB( (FT_UInt32)( FT_ABS( x ) | FT_ABS( y ) ) ); if ( shift <= FT_TRIG_SAFE_MSB ) { @@ -147,7 +165,7 @@ { FT_Int i; FT_Fixed x, y, xtemp, b; - const FT_Fixed *arctanptr; + const FT_Angle *arctanptr; x = vec->x; @@ -202,7 +220,7 @@ FT_Angle theta; FT_Int i; FT_Fixed x, y, xtemp, b; - const FT_Fixed *arctanptr; + const FT_Angle *arctanptr; x = vec->x; @@ -261,11 +279,12 @@ } } - /* round theta */ + /* round theta to acknowledge its error that mostly comes */ + /* from accumulated rounding errors in the arctan table */ if ( theta >= 0 ) - theta = FT_PAD_ROUND( theta, 32 ); + theta = FT_PAD_ROUND( theta, 16 ); else - theta = -FT_PAD_ROUND( -theta, 32 ); + theta = -FT_PAD_ROUND( -theta, 16 ); vec->x = x; vec->y = theta; @@ -280,11 +299,9 @@ FT_Vector v; - v.x = FT_TRIG_SCALE >> 8; - v.y = 0; - ft_trig_pseudo_rotate( &v, angle ); + FT_Vector_Unit( &v, angle ); - return ( v.x + 0x80L ) >> 8; + return v.x; } @@ -293,7 +310,12 @@ FT_EXPORT_DEF( FT_Fixed ) FT_Sin( FT_Angle angle ) { - return FT_Cos( FT_ANGLE_PI2 - angle ); + FT_Vector v; + + + FT_Vector_Unit( &v, angle ); + + return v.y; } @@ -305,9 +327,7 @@ FT_Vector v; - v.x = FT_TRIG_SCALE >> 8; - v.y = 0; - ft_trig_pseudo_rotate( &v, angle ); + FT_Vector_Unit( &v, angle ); return FT_DivFix( v.y, v.x ); } @@ -340,6 +360,9 @@ FT_Vector_Unit( FT_Vector* vec, FT_Angle angle ) { + if ( !vec ) + return; + vec->x = FT_TRIG_SCALE >> 8; vec->y = 0; ft_trig_pseudo_rotate( vec, angle ); @@ -366,30 +389,32 @@ FT_Vector v; - v.x = vec->x; - v.y = vec->y; + if ( !vec || !angle ) + return; - if ( angle && ( v.x != 0 || v.y != 0 ) ) - { - shift = ft_trig_prenorm( &v ); - ft_trig_pseudo_rotate( &v, angle ); - v.x = ft_trig_downscale( v.x ); - v.y = ft_trig_downscale( v.y ); + v = *vec; - if ( shift > 0 ) - { - FT_Int32 half = (FT_Int32)1L << ( shift - 1 ); + if ( v.x == 0 && v.y == 0 ) + return; + shift = ft_trig_prenorm( &v ); + ft_trig_pseudo_rotate( &v, angle ); + v.x = ft_trig_downscale( v.x ); + v.y = ft_trig_downscale( v.y ); - vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift; - vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift; - } - else - { - shift = -shift; - vec->x = (FT_Pos)( (FT_ULong)v.x << shift ); - vec->y = (FT_Pos)( (FT_ULong)v.y << shift ); - } + if ( shift > 0 ) + { + FT_Int32 half = (FT_Int32)1L << ( shift - 1 ); + + + vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift; + vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift; + } + else + { + shift = -shift; + vec->x = (FT_Pos)( (FT_ULong)v.x << shift ); + vec->y = (FT_Pos)( (FT_ULong)v.y << shift ); } } @@ -403,6 +428,9 @@ FT_Vector v; + if ( !vec ) + return 0; + v = *vec; /* handle trivial cases */ @@ -422,7 +450,7 @@ v.x = ft_trig_downscale( v.x ); if ( shift > 0 ) - return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift; + return ( v.x + ( 1L << ( shift - 1 ) ) ) >> shift; return (FT_Fixed)( (FT_UInt32)v.x << -shift ); } @@ -439,6 +467,9 @@ FT_Vector v; + if ( !vec || !length || !angle ) + return; + v = *vec; if ( v.x == 0 && v.y == 0 ) @@ -449,8 +480,8 @@ v.x = ft_trig_downscale( v.x ); - *length = ( shift >= 0 ) ? ( v.x >> shift ) - : (FT_Fixed)( (FT_UInt32)v.x << -shift ); + *length = shift >= 0 ? ( v.x >> shift ) + : (FT_Fixed)( (FT_UInt32)v.x << -shift ); *angle = v.y; } @@ -462,6 +493,9 @@ FT_Fixed length, FT_Angle angle ) { + if ( !vec ) + return; + vec->x = length; vec->y = 0; @@ -478,11 +512,10 @@ FT_Angle delta = angle2 - angle1; - delta %= FT_ANGLE_2PI; - if ( delta < 0 ) + while ( delta <= -FT_ANGLE_PI ) delta += FT_ANGLE_2PI; - if ( delta > FT_ANGLE_PI ) + while ( delta > FT_ANGLE_PI ) delta -= FT_ANGLE_2PI; return delta; diff --git a/src/base/fttype1.c b/src/base/fttype1.c index 1d17402..c549382 100644 --- a/src/base/fttype1.c +++ b/src/base/fttype1.c @@ -1,114 +1,127 @@ -/***************************************************************************/
-/* */
-/* fttype1.c */
-/* */
-/* FreeType utility file for PS names support (body). */
-/* */
-/* Copyright 2002-2004, 2011 by */
-/* David Turner, Robert Wilhelm, and Werner Lemberg. */
-/* */
-/* This file is part of the FreeType project, and may only be used, */
-/* modified, and distributed under the terms of the FreeType project */
-/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
-/* this file you indicate that you have read the license and */
-/* understand and accept it fully. */
-/* */
-/***************************************************************************/
-
-
-#include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_SERVICE_H
-#include FT_SERVICE_POSTSCRIPT_INFO_H
-
-
- /* documentation is in t1tables.h */
-
- FT_EXPORT_DEF( FT_Error )
- FT_Get_PS_Font_Info( FT_Face face,
- PS_FontInfoRec* afont_info )
- {
- FT_Error error = FT_ERR( Invalid_Argument );
-
-
- if ( face )
- {
- FT_Service_PsInfo service = NULL;
-
-
- FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
-
- if ( service && service->ps_get_font_info )
- error = service->ps_get_font_info( face, afont_info );
- }
-
- return error;
- }
-
-
- /* documentation is in t1tables.h */
-
- FT_EXPORT_DEF( FT_Int )
- FT_Has_PS_Glyph_Names( FT_Face face )
- {
- FT_Int result = 0;
- FT_Service_PsInfo service = NULL;
-
-
- if ( face )
- {
- FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
-
- if ( service && service->ps_has_glyph_names )
- result = service->ps_has_glyph_names( face );
- }
-
- return result;
- }
-
-
- /* documentation is in t1tables.h */
-
- FT_EXPORT_DEF( FT_Error )
- FT_Get_PS_Font_Private( FT_Face face,
- PS_PrivateRec* afont_private )
- {
- FT_Error error = FT_ERR( Invalid_Argument );
-
-
- if ( face )
- {
- FT_Service_PsInfo service = NULL;
-
-
- FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
-
- if ( service && service->ps_get_font_private )
- error = service->ps_get_font_private( face, afont_private );
- }
-
- return error;
- }
-
-/* documentation is in t1tables.h */
-FT_EXPORT_DEF( FT_Long )
-FT_Get_PS_Font_Value( FT_Face face,
- PS_Dict_Keys key,
- FT_UInt idx,
- void *value,
- FT_Long value_len )
-{
- FT_Int result = 0;
- FT_Service_PsInfo service = NULL;
-
- if ( face )
- {
- FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
- if ( service && service->ps_get_font_value )
- result = service->ps_get_font_value( face, key, idx,
- value, value_len );
- }
- return result;
-}
-
-/* END */
+/***************************************************************************/ +/* */ +/* fttype1.c */ +/* */ +/* FreeType utility file for PS names support (body). */ +/* */ +/* Copyright 2002-2015 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_SERVICE_H +#include FT_SERVICE_POSTSCRIPT_INFO_H + + + /* documentation is in t1tables.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PS_Font_Info( FT_Face face, + PS_FontInfoRec* afont_info ) + { + FT_Error error; + FT_Service_PsInfo service; + + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( !afont_info ) + return FT_THROW( Invalid_Argument ); + + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_get_font_info ) + error = service->ps_get_font_info( face, afont_info ); + else + error = FT_THROW( Invalid_Argument ); + + return error; + } + + + /* documentation is in t1tables.h */ + + FT_EXPORT_DEF( FT_Int ) + FT_Has_PS_Glyph_Names( FT_Face face ) + { + FT_Int result = 0; + FT_Service_PsInfo service; + + + if ( face ) + { + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_has_glyph_names ) + result = service->ps_has_glyph_names( face ); + } + + return result; + } + + + /* documentation is in t1tables.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PS_Font_Private( FT_Face face, + PS_PrivateRec* afont_private ) + { + FT_Error error; + FT_Service_PsInfo service; + + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + if ( !afont_private ) + return FT_THROW( Invalid_Argument ); + + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_get_font_private ) + error = service->ps_get_font_private( face, afont_private ); + else + error = FT_THROW( Invalid_Argument ); + + return error; + } + + + /* documentation is in t1tables.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_Get_PS_Font_Value( FT_Face face, + PS_Dict_Keys key, + FT_UInt idx, + void *value, + FT_Long value_len ) + { + FT_Int result = 0; + FT_Service_PsInfo service = NULL; + + + if ( face ) + { + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_get_font_value ) + result = service->ps_get_font_value( face, key, idx, + value, value_len ); + } + + return result; + } + + +/* END */ diff --git a/src/base/ftutil.c b/src/base/ftutil.c index 9f37189..f5b72db 100644 --- a/src/base/ftutil.c +++ b/src/base/ftutil.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file for memory and list management (body). */ /* */ -/* Copyright 2002, 2004-2007, 2013 by */ +/* Copyright 2002-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -180,7 +180,7 @@ FT_Error *p_error ) { FT_Error error; - FT_Pointer p = ft_mem_qalloc( memory, size, &error ); + FT_Pointer p = ft_mem_qalloc( memory, (FT_Long)size, &error ); if ( !error && address ) @@ -245,6 +245,9 @@ FT_ListNode cur; + if ( !list ) + return NULL; + cur = list->head; while ( cur ) { @@ -254,7 +257,7 @@ cur = cur->next; } - return (FT_ListNode)0; + return NULL; } @@ -264,10 +267,15 @@ FT_List_Add( FT_List list, FT_ListNode node ) { - FT_ListNode before = list->tail; + FT_ListNode before; + + if ( !list || !node ) + return; - node->next = 0; + before = list->tail; + + node->next = NULL; node->prev = before; if ( before ) @@ -285,11 +293,16 @@ FT_List_Insert( FT_List list, FT_ListNode node ) { - FT_ListNode after = list->head; + FT_ListNode after; + if ( !list || !node ) + return; + + after = list->head; + node->next = after; - node->prev = 0; + node->prev = NULL; if ( !after ) list->tail = node; @@ -309,6 +322,9 @@ FT_ListNode before, after; + if ( !list || !node ) + return; + before = node->prev; after = node->next; @@ -333,6 +349,9 @@ FT_ListNode before, after; + if ( !list || !node ) + return; + before = node->prev; after = node->next; @@ -347,7 +366,7 @@ else list->tail = before; - node->prev = 0; + node->prev = NULL; node->next = list->head; list->head->prev = node; list->head = node; @@ -357,14 +376,19 @@ /* documentation is in ftlist.h */ FT_EXPORT_DEF( FT_Error ) - FT_List_Iterate( FT_List list, - FT_List_Iterator iterator, - void* user ) + FT_List_Iterate( FT_List list, + FT_List_Iterator iterator, + void* user ) { - FT_ListNode cur = list->head; + FT_ListNode cur; FT_Error error = FT_Err_Ok; + if ( !list || !iterator ) + return FT_THROW( Invalid_Argument ); + + cur = list->head; + while ( cur ) { FT_ListNode next = cur->next; @@ -392,6 +416,9 @@ FT_ListNode cur; + if ( !list || !memory ) + return; + cur = list->head; while ( cur ) { @@ -406,8 +433,8 @@ cur = next; } - list->head = 0; - list->tail = 0; + list->head = NULL; + list->tail = NULL; } diff --git a/src/base/ftwinfnt.c b/src/base/ftwinfnt.c index 463ae76..76a19af 100644 --- a/src/base/ftwinfnt.c +++ b/src/base/ftwinfnt.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing Windows FNT specific info (body). */ /* */ -/* Copyright 2003, 2004 by */ +/* Copyright 2003-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,6 +17,7 @@ #include <ft2build.h> +#include FT_INTERNAL_DEBUG_H #include FT_WINFONTS_H #include FT_INTERNAL_OBJECTS_H #include FT_SERVICE_WINFNT_H @@ -32,17 +33,18 @@ FT_Error error; - error = FT_ERR( Invalid_Argument ); + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); - if ( face != NULL ) - { - FT_FACE_LOOKUP_SERVICE( face, service, WINFNT ); + if ( !header ) + return FT_THROW( Invalid_Argument ); - if ( service != NULL ) - { - error = service->get_header( face, header ); - } - } + FT_FACE_LOOKUP_SERVICE( face, service, WINFNT ); + + if ( service ) + error = service->get_header( face, header ); + else + error = FT_THROW( Invalid_Argument ); return error; } |