aboutsummaryrefslogtreecommitdiff
path: root/freetype/src/base
diff options
context:
space:
mode:
Diffstat (limited to 'freetype/src/base')
-rw-r--r--freetype/src/base/ftadvanc.c8
-rw-r--r--freetype/src/base/ftbbox.c223
-rw-r--r--freetype/src/base/ftbdf.c45
-rw-r--r--freetype/src/base/ftbitmap.c224
-rw-r--r--freetype/src/base/ftcalc.c475
-rw-r--r--freetype/src/base/ftfstype.c4
-rw-r--r--freetype/src/base/ftglyph.c10
-rw-r--r--freetype/src/base/ftgxval.c6
-rw-r--r--freetype/src/base/ftinit.c22
-rw-r--r--freetype/src/base/ftlcdfil.c46
-rw-r--r--freetype/src/base/ftmac.c25
-rw-r--r--freetype/src/base/ftmm.c32
-rw-r--r--freetype/src/base/ftobjs.c263
-rw-r--r--freetype/src/base/ftoutln.c55
-rw-r--r--freetype/src/base/ftpfr.c15
-rw-r--r--freetype/src/base/ftrfork.c8
-rw-r--r--freetype/src/base/ftstream.c5
-rw-r--r--freetype/src/base/ftstroke.c87
-rw-r--r--freetype/src/base/ftsynth.c25
-rw-r--r--freetype/src/base/fttrigon.c100
-rw-r--r--freetype/src/base/fttype1.c51
-rw-r--r--freetype/src/base/ftutil.c63
-rw-r--r--freetype/src/base/ftwinfnt.c22
23 files changed, 1008 insertions, 806 deletions
diff --git a/freetype/src/base/ftadvanc.c b/freetype/src/base/ftadvanc.c
index 24da83dbb..797057b65 100644
--- a/freetype/src/base/ftadvanc.c
+++ b/freetype/src/base/ftadvanc.c
@@ -4,7 +4,7 @@
/* */
/* Quick computation of advance widths (body). */
/* */
-/* Copyright 2008, 2009, 2011, 2013 by */
+/* Copyright 2008, 2009, 2011, 2013, 2014 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/freetype/src/base/ftbbox.c b/freetype/src/base/ftbbox.c
index 36048c296..c703e50cd 100644
--- a/freetype/src/base/ftbbox.c
+++ b/freetype/src/base/ftbbox.c
@@ -4,7 +4,7 @@
/* */
/* FreeType bbox computation (body). */
/* */
-/* Copyright 1996-2002, 2004, 2006, 2010, 2013 by */
+/* Copyright 1996-2002, 2004, 2006, 2010, 2013, 2014 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,48 @@
/* 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_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 +317,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 +344,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 +419,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 +462,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/freetype/src/base/ftbdf.c b/freetype/src/base/ftbdf.c
index fccbfedde..d9dcbad5e 100644
--- a/freetype/src/base/ftbdf.c
+++ b/freetype/src/base/ftbdf.c
@@ -4,7 +4,7 @@
/* */
/* FreeType API for accessing BDF-specific strings (body). */
/* */
-/* Copyright 2002-2004, 2013 by */
+/* Copyright 2002-2004, 2013, 2014 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -17,7 +17,9 @@
#include <ft2build.h>
-#include <internal/ftobjs.h>
+#include FT_INTERNAL_DEBUG_H
+
+#include FT_INTERNAL_OBJECTS_H
#include FT_SERVICE_BDF_H
@@ -32,19 +34,18 @@
const char* encoding = NULL;
const char* registry = NULL;
+ FT_Service_BDF service;
- error = FT_ERR( Invalid_Argument );
-
- if ( face )
- {
- FT_Service_BDF service;
+ if ( !face )
+ return FT_THROW( Invalid_Face_Handle );
- FT_FACE_FIND_SERVICE( face, service, BDF );
+ FT_FACE_FIND_SERVICE( face, service, BDF );
- if ( service && service->get_charset_id )
- error = service->get_charset_id( face, &encoding, &registry );
- }
+ if ( service && service->get_charset_id )
+ error = service->get_charset_id( face, &encoding, &registry );
+ else
+ error = FT_THROW( Invalid_Argument );
if ( acharset_encoding )
*acharset_encoding = encoding;
@@ -65,23 +66,25 @@
{
FT_Error error;
+ FT_Service_BDF service;
- error = FT_ERR( Invalid_Argument );
- aproperty->type = BDF_PROPERTY_TYPE_NONE;
+ if ( !face )
+ return FT_THROW( Invalid_Face_Handle );
- if ( face )
- {
- FT_Service_BDF service;
+ if ( !aproperty )
+ return FT_THROW( Invalid_Argument );
+ aproperty->type = BDF_PROPERTY_TYPE_NONE;
- FT_FACE_FIND_SERVICE( face, service, BDF );
+ FT_FACE_FIND_SERVICE( face, service, BDF );
- if ( service && service->get_property )
- error = service->get_property( face, prop_name, aproperty );
- }
+ if ( service && service->get_property )
+ error = service->get_property( face, prop_name, aproperty );
+ else
+ error = FT_THROW( Invalid_Argument );
- return error;
+ return error;
}
diff --git a/freetype/src/base/ftbitmap.c b/freetype/src/base/ftbitmap.c
index 887722a93..2f26b2f28 100644
--- a/freetype/src/base/ftbitmap.c
+++ b/freetype/src/base/ftbitmap.c
@@ -33,7 +33,8 @@
FT_EXPORT_DEF( void )
FT_Bitmap_New( FT_Bitmap *abitmap )
{
- *abitmap = null_bitmap;
+ if ( abitmap )
+ *abitmap = null_bitmap;
}
@@ -44,25 +45,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 +88,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 +107,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 += 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 +146,7 @@
int pitch;
int new_pitch;
FT_UInt bpp;
- FT_Int i, width, height;
+ FT_UInt i, width, height;
unsigned char* buffer = NULL;
@@ -144,17 +184,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 = 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,19 +208,22 @@
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++ )
@@ -189,7 +232,7 @@
}
else
{
- FT_Int len = ( width * bpp + 7 ) >> 3;
+ FT_UInt len = ( width * bpp + 7 ) >> 3;
for ( i = 0; i < bitmap->rows; i++ )
@@ -220,7 +263,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 +292,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;
+ /* convert to 8bpp */
FT_Bitmap_New( &tmp );
-
- error = FT_Bitmap_Convert( library, bitmap, &tmp, align );
+ error = FT_Bitmap_Convert( library, bitmap, &tmp, 1 );
if ( error )
return error;
@@ -289,6 +327,7 @@
if ( error )
return error;
+ /* take care of bitmap flow */
pitch = bitmap->pitch;
if ( pitch > 0 )
p = bitmap->buffer + pitch * ystr;
@@ -309,7 +348,7 @@
*/
for ( x = pitch - 1; x >= 0; x-- )
{
- unsigned char tmp;
+ unsigned char tmp;
tmp = p[x];
@@ -324,7 +363,7 @@
p[x] |= p[x - 1] << ( 8 - i );
#if 0
- if ( p[x] == 0xff )
+ if ( p[x] == 0xFF )
break;
#endif
}
@@ -334,12 +373,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;
}
@@ -378,14 +417,11 @@
static FT_Byte
ft_gray_for_premultiplied_srgb_bgra( const FT_Byte* bgra )
{
- FT_Long a = bgra[3];
- FT_Long b = bgra[0];
- FT_Long g = bgra[1];
- FT_Long r = bgra[2];
- FT_Long 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;
@@ -395,40 +431,32 @@
* 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.
+ * We guarantee 32-bit arithmetic to avoid overflow but the resulting
+ * luminosity fits into 16 bits.
*
- * We do the computation with integers only.
*/
- /* Undo premultification, get the number in a 16.16 form. */
- b = FT_MulDiv( b, 65536, a );
- g = FT_MulDiv( g, 65536, a );
- r = FT_MulDiv( r, 65536, a );
- a = a * 256;
-
- /* Apply gamma of 2.0 instead of 2.2. */
- b = FT_MulFix( b, b );
- g = FT_MulFix( g, g );
- r = FT_MulFix( r, r );
-
- /* Apply coefficients. */
- b = FT_MulFix( b, 4731 /* 0.0722 * 65536 */ );
- g = FT_MulFix( g, 46871 /* 0.7152 * 65536 */ );
- r = FT_MulFix( r, 13933 /* 0.2126 * 65536 */ );
-
- l = r + g + b;
+ 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 this way:
+ * Final transparency can be determined as follows.
*
* - If alpha is zero, we want 0.
* - If alpha is zero and luminosity is zero, we want 255.
* - If alpha is zero and luminosity is one, we want 0.
*
- * So the formula is a * (1 - l).
+ * So the formula is a * (1 - l) = a - l * a.
+ *
+ * We still need to undo premultiplication by dividing l by a*a.
+ *
*/
- return (FT_Byte)( FT_MulFix( 65535 - l, a ) >> 8 );
+ return (FT_Byte)( a - l / a );
}
@@ -443,10 +471,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 )
@@ -459,13 +493,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 * old_target_pitch;
target->pixel_mode = FT_PIXEL_MODE_GRAY;
target->rows = source->rows;
@@ -479,16 +515,18 @@
pad = alignment - pad;
}
- target->pitch = source->width + pad;
+ target_pitch = 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 / target_pitch )
return FT_THROW( Invalid_Argument );
- if ( target->rows * target->pitch > old_size &&
+ if ( target->rows * target_pitch > old_size &&
FT_QREALLOC( target->buffer,
- old_size, target->rows * target->pitch ) )
+ old_size, target->rows * target_pitch ) )
return error;
+
+ target->pitch = target->pitch < 0 ? -target_pitch : target_pitch;
}
break;
@@ -496,13 +534,20 @@
error = FT_THROW( Invalid_Argument );
}
+ s = source->buffer;
+ t = target->buffer;
+
+ /* take care of bitmap flow */
+ if ( source->pitch < 0 )
+ s -= source->pitch * ( source->rows - 1 );
+ if ( target->pitch < 0 )
+ t -= target->pitch * ( 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;
@@ -511,7 +556,7 @@
{
FT_Byte* ss = s;
FT_Byte* tt = t;
- FT_Int j;
+ FT_UInt j;
/* get the full bytes */
@@ -559,12 +604,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_Int width = source->width;
+ FT_UInt i;
target->num_grays = 256;
@@ -573,8 +614,8 @@
{
FT_ARRAY_COPY( t, s, width );
- s += s_pitch;
- t += t_pitch;
+ s += source->pitch;
+ t += target->pitch;
}
}
break;
@@ -582,9 +623,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;
@@ -593,7 +632,7 @@
{
FT_Byte* ss = s;
FT_Byte* tt = t;
- FT_Int j;
+ FT_UInt j;
/* get the full bytes */
@@ -634,9 +673,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;
@@ -645,7 +682,7 @@
{
FT_Byte* ss = s;
FT_Byte* tt = t;
- FT_Int j;
+ FT_UInt j;
/* get the full bytes */
@@ -670,13 +707,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;
@@ -685,7 +719,7 @@
{
FT_Byte* ss = s;
FT_Byte* tt = t;
- FT_Int j;
+ FT_UInt j;
for ( j = source->width; j > 0; j-- )
@@ -696,8 +730,8 @@
tt += 1;
}
- s += s_pitch;
- t += t_pitch;
+ s += source->pitch;
+ t += target->pitch;
}
}
break;
diff --git a/freetype/src/base/ftcalc.c b/freetype/src/base/ftcalc.c
index fb0492721..7b6425056 100644
--- a/freetype/src/base/ftcalc.c
+++ b/freetype/src/base/ftcalc.c
@@ -39,7 +39,8 @@
#include <internal/ftdebug.h>
#include <internal/ftobjs.h>
-#ifdef FT_MULFIX_INLINED
+
+#ifdef FT_MULFIX_ASSEMBLER
#undef FT_MulFix
#endif
@@ -67,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. */
@@ -75,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 );
}
@@ -85,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 );
}
@@ -95,38 +106,40 @@
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 )
{
- FT_Int shift = 0;
+ 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;
@@ -135,6 +148,8 @@
return shift;
}
+#endif /* !FT_MSB */
+
/* documentation is in ftcalc.h */
@@ -162,19 +177,18 @@
FT_Long b,
FT_Long c )
{
- FT_Int s;
+ FT_Int s = 1;
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 );
- return ( s > 0 ) ? d : -d;
+ return s < 0 ? -d : d;
}
@@ -185,19 +199,18 @@
FT_Long b,
FT_Long c )
{
- FT_Int s;
+ FT_Int s = 1;
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
: 0x7FFFFFFFL );
- return ( s > 0 ) ? d : -d;
+ return s < 0 ? -d : d;
}
@@ -217,21 +230,12 @@
FT_Long c;
- if ( a < 0 )
- {
- a = -a;
- s = -1;
- }
-
- if ( b < 0 )
- {
- b = -b;
- s = -s;
- }
+ FT_MOVE_SIGN( a, s );
+ FT_MOVE_SIGN( b, s );
c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 );
- return ( s > 0 ) ? c : -c;
+ return s < 0 ? -c : c;
#endif /* FT_MULFIX_ASSEMBLER */
}
@@ -243,30 +247,17 @@
FT_DivFix( FT_Long a,
FT_Long b )
{
- FT_Int32 s;
- FT_UInt32 q;
+ FT_Int s = 1;
+ 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 );
+ q = (FT_Long)( b > 0 ? ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b
+ : 0x7FFFFFFFL );
- return ( s < 0 ? -(FT_Long)q : (FT_Long)q );
+ return s < 0 ? -q : q;
}
@@ -314,25 +305,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;
@@ -344,7 +340,7 @@
FT_Int64* y,
FT_Int64 *z )
{
- register FT_UInt32 lo, hi;
+ FT_UInt32 lo, hi;
lo = x->lo + y->lo;
@@ -355,60 +351,95 @@
}
- /* documentation is in freetype.h */
-
- /* The FT_MulDiv function has been optimized thanks to ideas from */
- /* Graham Asher. The trick is to optimize computation when everything */
- /* fits within 32-bits (a rather common case). */
+ /* 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' (all positive values). */
+ /* */
+ /* The product of two positive numbers never exceeds the square of */
+ /* its mean values. Therefore, we always avoid the overflow by */
+ /* imposing */
/* */
- /* we compute 'a*b+c/2', then divide it by 'c'. (positive values) */
+ /* (a + b) / 2 <= sqrt(X - c/2) , */
/* */
- /* 46340 is FLOOR(SQRT(2^31-1)). */
+ /* 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 */
/* */
- /* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */
+ /* a + b <= 131071.99 - c / 122291.84 . */
/* */
- /* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */
+ /* In practice, we should use a faster and even stronger inequality */
/* */
- /* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */
+ /* a + b <= 131071 - (c >> 16) */
/* */
- /* and 2*0x157F0 = 176096 */
+ /* or, alternatively, */
/* */
+ /* a + b <= 129894 - (c >> 17) . */
+ /* */
+ /* 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, */
+ /* */
+ /* a + (b >> 8) <= (131071 >> 4) */
+ /* */
+ /* 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 )
{
- long s;
+ FT_Int s = 1;
/* 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 );
+ FT_MOVE_SIGN( a, s );
+ FT_MOVE_SIGN( b, s );
+ FT_MOVE_SIGN( c, s );
+
+ if ( c == 0 )
+ a = 0x7FFFFFFFL;
- if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 )
- a = ( a * b + ( c >> 1 ) ) / c;
+ else if ( (FT_ULong)a + b <= 129894UL - ( c >> 17 ) )
+ a = ( (FT_ULong)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 );
+ return s < 0 ? -a : a;
}
@@ -417,31 +448,35 @@
FT_Long b,
FT_Long c )
{
- long s;
+ FT_Int s = 1;
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 );
+ FT_MOVE_SIGN( a, s );
+ FT_MOVE_SIGN( b, s );
+ FT_MOVE_SIGN( c, s );
+
+ if ( c == 0 )
+ a = 0x7FFFFFFFL;
- if ( a <= 46340L && b <= 46340L && c > 0 )
- a = a * b / c;
+ else if ( (FT_ULong)a + b <= 131071UL )
+ a = (FT_ULong)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 );
+ return s < 0 ? -a : a;
}
@@ -497,7 +532,7 @@
ua = (FT_ULong)a;
ub = (FT_ULong)b;
- if ( ua <= 2048 && ub <= 1048576L )
+ if ( ua + ( ub >> 8 ) <= 8190UL )
ua = ( ua * ub + 0x8000U ) >> 16;
else
{
@@ -515,20 +550,20 @@
#else /* 0 */
- FT_Long s;
+ FT_Int s = 1;
FT_ULong ua, ub;
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;
- if ( ua <= 2048 && ub <= 1048576L )
+ if ( ua + ( ub >> 8 ) <= 8190UL )
ua = ( ua * ub + 0x8000UL ) >> 16;
else
{
@@ -539,7 +574,7 @@
( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 );
}
- return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua );
+ return s < 0 ? -(FT_Long)ua : (FT_Long)ua;
#endif /* 0 */
@@ -552,23 +587,24 @@
FT_DivFix( FT_Long a,
FT_Long b )
{
- FT_Int32 s;
- FT_UInt32 q;
+ FT_Int s = 1;
+ 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 );
+
+ if ( b == 0 )
{
/* check for division by 0 */
- q = (FT_UInt32)0x7FFFFFFFL;
+ q = 0x7FFFFFFFL;
}
- else if ( ( a >> 16 ) == 0 )
+ else if ( a <= 65535L - ( b >> 17 ) )
{
/* compute result directly */
- q = (FT_UInt32)( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b;
+ q = (FT_Long)( ( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / b );
}
else
{
@@ -576,138 +612,18 @@
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 );
- }
-
- return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
- }
+ temp2.lo = b >> 1;
-
-#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_Long)ft_div64by32( temp.hi, temp.lo, b );
}
- q = ft_div64by32( x->hi, x->lo, y );
-
- return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
+ return s < 0 ? -q : q;
}
-#endif /* 0 */
-
-#endif /* 0 */
-
#endif /* FT_LONG64 */
@@ -943,55 +859,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/freetype/src/base/ftfstype.c b/freetype/src/base/ftfstype.c
index d0ef7b7c1..6b49ef837 100644
--- a/freetype/src/base/ftfstype.c
+++ b/freetype/src/base/ftfstype.c
@@ -4,7 +4,7 @@
/* */
/* FreeType utility file to access FSType data (body). */
/* */
-/* Copyright 2008, 2009 by */
+/* Copyright 2008, 2009, 2014 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -51,7 +51,7 @@
/* look at FSType before fsType for Type42 */
- if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, ft_sfnt_os2 ) ) != NULL &&
+ if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, FT_SFNT_OS2 ) ) != NULL &&
os2->version != 0xFFFFU )
return os2->fsType;
diff --git a/freetype/src/base/ftglyph.c b/freetype/src/base/ftglyph.c
index 76d8d6156..194857ad9 100644
--- a/freetype/src/base/ftglyph.c
+++ b/freetype/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-2005, 2007, 2008, 2010, 2012-2014 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -314,13 +314,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 +359,7 @@
FT_Error error;
FT_Glyph glyph;
- const FT_Glyph_Class* clazz = 0;
+ const FT_Glyph_Class* clazz = NULL;
if ( !slot )
@@ -512,7 +512,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/freetype/src/base/ftgxval.c b/freetype/src/base/ftgxval.c
index e301917d0..d3b44029e 100644
--- a/freetype/src/base/ftgxval.c
+++ b/freetype/src/base/ftgxval.c
@@ -4,7 +4,7 @@
/* */
/* FreeType API for validating TrueTyepGX/AAT tables (body). */
/* */
-/* Copyright 2004-2006, 2010, 2013 by */
+/* Copyright 2004-2006, 2010, 2013, 2014 by */
/* Masatake YAMATO, Redhat K.K, */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
@@ -49,7 +49,7 @@
goto Exit;
}
- if ( tables == NULL )
+ if ( !tables )
{
error = FT_THROW( Invalid_Argument );
goto Exit;
@@ -101,7 +101,7 @@
goto Exit;
}
- if ( ckern_table == NULL )
+ if ( !ckern_table )
{
error = FT_THROW( Invalid_Argument );
goto Exit;
diff --git a/freetype/src/base/ftinit.c b/freetype/src/base/ftinit.c
index 224b7ce37..b23f2394d 100644
--- a/freetype/src/base/ftinit.c
+++ b/freetype/src/base/ftinit.c
@@ -4,7 +4,7 @@
/* */
/* FreeType initialization layer (body). */
/* */
-/* Copyright 1996-2002, 2005, 2007, 2009, 2012, 2013 by */
+/* Copyright 1996-2002, 2005, 2007, 2009, 2012-2014 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -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/freetype/src/base/ftlcdfil.c b/freetype/src/base/ftlcdfil.c
index e6d7fca3b..c1ec75239 100644
--- a/freetype/src/base/ftlcdfil.c
+++ b/freetype/src/base/ftlcdfil.c
@@ -4,7 +4,7 @@
/* */
/* FreeType API for color filtering of subpixel bitmap glyphs (body). */
/* */
-/* Copyright 2006, 2008-2010, 2013 by */
+/* Copyright 2006, 2008-2010, 2013, 2014 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -46,9 +46,16 @@
FT_Byte* line = bitmap->buffer;
+ /* take care of bitmap flow */
+ if ( bitmap->pitch < 0 )
+ line -= bitmap->pitch * ( bitmap->rows - 1 );
+
+ /* `fir' and `pix' must be at least 32 bit wide, since the sum of */
+ /* the values in `weights' can exceed 0xFF */
+
for ( ; height > 0; height--, line += bitmap->pitch )
{
- FT_UInt fir[5];
+ FT_UInt fir[4]; /* below, `pix' is used as the 5th element */
FT_UInt val1, xx;
@@ -57,7 +64,6 @@
fir[1] = weights[3] * val1;
fir[2] = weights[4] * val1;
fir[3] = 0;
- fir[4] = 0;
val1 = line[1];
fir[0] += weights[1] * val1;
@@ -78,7 +84,7 @@
fir[3] = weights[4] * val;
pix >>= 8;
- pix |= -( pix >> 8 );
+ pix |= (FT_UInt)-(FT_Int)( pix >> 8 );
line[xx - 2] = (FT_Byte)pix;
}
@@ -87,11 +93,11 @@
pix = fir[0] >> 8;
- pix |= -( pix >> 8 );
+ pix |= (FT_UInt)-(FT_Int)( pix >> 8 );
line[xx - 2] = (FT_Byte)pix;
pix = fir[1] >> 8;
- pix |= -( pix >> 8 );
+ pix |= (FT_UInt)-(FT_Int)( pix >> 8 );
line[xx - 1] = (FT_Byte)pix;
}
}
@@ -104,10 +110,14 @@
FT_Int pitch = bitmap->pitch;
+ /* take care of bitmap flow */
+ if ( bitmap->pitch < 0 )
+ column -= bitmap->pitch * ( bitmap->rows - 1 );
+
for ( ; width > 0; width--, column++ )
{
FT_Byte* col = column;
- FT_UInt fir[5];
+ FT_UInt fir[4]; /* below, `pix' is used as the 5th element */
FT_UInt val1, yy;
@@ -116,7 +126,6 @@
fir[1] = weights[3] * val1;
fir[2] = weights[4] * val1;
fir[3] = 0;
- fir[4] = 0;
col += pitch;
val1 = col[0];
@@ -139,7 +148,7 @@
fir[3] = weights[4] * val;
pix >>= 8;
- pix |= -( pix >> 8 );
+ pix |= (FT_UInt)-(FT_Int)( pix >> 8 );
col[-2 * pitch] = (FT_Byte)pix;
col += pitch;
}
@@ -149,11 +158,11 @@
pix = fir[0] >> 8;
- pix |= -( pix >> 8 );
+ pix |= (FT_UInt)-(FT_Int)( pix >> 8 );
col[-2 * pitch] = (FT_Byte)pix;
pix = fir[1] >> 8;
- pix |= -( pix >> 8 );
+ pix |= (FT_UInt)-(FT_Int)( pix >> 8 );
col[-pitch] = (FT_Byte)pix;
}
}
@@ -189,6 +198,10 @@
FT_Byte* line = bitmap->buffer;
+ /* take care of bitmap flow */
+ if ( bitmap->pitch < 0 )
+ line -= bitmap->pitch * ( bitmap->rows - 1 );
+
for ( ; height > 0; height--, line += pitch )
{
FT_UInt xx;
@@ -228,6 +241,10 @@
FT_Byte* column = bitmap->buffer;
+ /* take care of bitmap flow */
+ if ( bitmap->pitch < 0 )
+ column -= bitmap->pitch * ( bitmap->rows - 1 );
+
for ( ; width > 0; width--, column++ )
{
FT_Byte* col = column;
@@ -272,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 );
@@ -294,7 +314,7 @@
if ( !library )
- return FT_THROW( Invalid_Argument );
+ return FT_THROW( Invalid_Library_Handle );
switch ( filter )
{
diff --git a/freetype/src/base/ftmac.c b/freetype/src/base/ftmac.c
index 6607b3d29..459f004b5 100644
--- a/freetype/src/base/ftmac.c
+++ b/freetype/src/base/ftmac.c
@@ -8,7 +8,7 @@
/* This file is for Mac OS X only; see builds/mac/ftoldmac.c for */
/* classic platforms built by MPW. */
/* */
-/* Copyright 1996-2009, 2013 by */
+/* Copyright 1996-2009, 2013, 2014 by */
/* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -227,6 +227,9 @@
FT_Error err;
+ if ( !fontName || !face_index )
+ return FT_THROW( Invalid_Argument) ;
+
err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index );
if ( err )
return err;
@@ -256,6 +259,9 @@
FT_Error err;
+ if ( !fontName || !face_index )
+ return FT_THROW( Invalid_Argument );
+
err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index );
if ( err )
return err;
@@ -440,9 +446,10 @@
style = (StyleTable*)p;
p += sizeof ( StyleTable );
string_count = EndianS16_BtoN( *(short*)(p) );
+ string_count = FT_MIN( 64, string_count );
p += sizeof ( short );
- for ( i = 0; i < string_count && i < 64; i++ )
+ for ( i = 0; i < string_count; i++ )
{
names[i] = p;
p += names[i][0];
@@ -459,7 +466,7 @@
ps_name[ps_name_len] = 0;
}
if ( style->indexes[face_index] > 1 &&
- style->indexes[face_index] <= FT_MIN( string_count, 64 ) )
+ style->indexes[face_index] <= string_count )
{
unsigned char* suffixes = names[style->indexes[face_index] - 1];
@@ -852,6 +859,8 @@
FT_Error error = FT_Err_Ok;
+ /* check of `library' and `aface' delayed to `FT_New_Face_From_XXX' */
+
GetResInfo( fond, &fond_id, &fond_type, fond_name );
if ( ResError() != noErr || fond_type != TTAG_FOND )
return FT_THROW( Invalid_File_Format );
@@ -997,10 +1006,14 @@
{
FT_Error error;
FT_Open_Args args;
- OSErr err;
- UInt8 pathname[PATH_MAX];
+
+ OSErr err;
+ UInt8 pathname[PATH_MAX];
+ /* check of `library' and `aface' delayed to */
+ /* `FT_New_Face_From_Resource' */
+
if ( !ref )
return FT_THROW( Invalid_Argument );
@@ -1047,6 +1060,8 @@
FSRef ref;
+ /* check of `library' and `aface' delayed to `FT_New_Face_From_FSRef' */
+
if ( !spec || FSpMakeFSRef( spec, &ref ) != noErr )
return FT_THROW( Invalid_Argument );
else
diff --git a/freetype/src/base/ftmm.c b/freetype/src/base/ftmm.c
index 178f97abf..af7bd691d 100644
--- a/freetype/src/base/ftmm.c
+++ b/freetype/src/base/ftmm.c
@@ -4,7 +4,7 @@
/* */
/* Multiple Master font support (body). */
/* */
-/* Copyright 1996-2001, 2003, 2004, 2009, 2013 by */
+/* Copyright 1996-2001, 2003, 2004, 2009, 2013, 2014 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/freetype/src/base/ftobjs.c b/freetype/src/base/ftobjs.c
index 4cbadfee6..7ffb0c9e5 100644
--- a/freetype/src/base/ftobjs.c
+++ b/freetype/src/base/ftobjs.c
@@ -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;
@@ -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
@@ -1040,14 +1045,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 +1059,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 +1100,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;
@@ -1243,7 +1222,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 +1248,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 );
@@ -1583,9 +1562,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 )
@@ -1601,11 +1580,34 @@
error = FT_Stream_Seek( stream, 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;
@@ -1625,16 +1627,30 @@
error = FT_Stream_Seek( stream, 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 +1663,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 +1675,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 +1692,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 +1724,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:
@@ -1881,7 +1910,7 @@
rlen = ( header[0x57] << 24 ) |
( header[0x58] << 16 ) |
( header[0x59] << 8 ) |
- header[0x5a];
+ header[0x5A];
#endif /* 0 */
offset = 128 + ( ( dlen + 127 ) & ~127 );
@@ -2049,8 +2078,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 );
@@ -2297,7 +2325,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 +2351,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 +2387,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;
@@ -2425,7 +2456,7 @@
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 );
@@ -2934,6 +2965,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 +3005,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 )
@@ -3122,15 +3157,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 +3180,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 +3192,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 +3218,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 +3428,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 +3608,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 +3635,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 +3699,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 +3749,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 +3818,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 */
@@ -3984,7 +4002,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 +4019,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 +4052,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:
@@ -4090,7 +4118,11 @@
/* 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 );
+ {
+ error = FT_Set_Renderer( library, renderer, 0, 0 );
+ if ( error )
+ break;
+ }
}
}
@@ -4100,6 +4132,7 @@
#define FT_COMPONENT trace_bitmap
/* we convert to a single bitmap format for computing the checksum */
+ if ( !error )
{
FT_Bitmap bitmap;
FT_Error err;
@@ -4107,6 +4140,7 @@
FT_Bitmap_New( &bitmap );
+ /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */
err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 );
if ( !err )
{
@@ -4348,7 +4382,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;
@@ -4603,6 +4637,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 +4656,7 @@
FT_Error error;
- if ( !memory )
+ if ( !memory || !alibrary )
return FT_THROW( Invalid_Argument );
#ifdef FT_DEBUG_LEVEL_ERROR
@@ -4881,6 +4918,8 @@
*p_arg1 = subg->arg1;
*p_arg2 = subg->arg2;
*p_transform = subg->transform;
+
+ error = FT_Err_Ok;
}
return error;
diff --git a/freetype/src/base/ftoutln.c b/freetype/src/base/ftoutln.c
index 5f0e61c1c..b214f5446 100644
--- a/freetype/src/base/ftoutln.c
+++ b/freetype/src/base/ftoutln.c
@@ -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;
@@ -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;
}
@@ -614,7 +620,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;
@@ -643,7 +652,7 @@
/* 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 );
+ error = FT_Set_Renderer( library, renderer, 0, 0 );
return error;
}
@@ -662,7 +671,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 +920,7 @@
if ( !outline )
- return FT_THROW( Invalid_Argument );
+ return FT_THROW( Invalid_Outline );
xstrength /= 2;
ystrength /= 2;
@@ -1045,6 +1054,10 @@
FT_Outline_Get_CBox( outline, &cbox );
+ /* 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_ABS( cbox.xMax ) | FT_ABS( cbox.xMin ) ) - 14;
xshift = FT_MAX( xshift, 0 );
diff --git a/freetype/src/base/ftpfr.c b/freetype/src/base/ftpfr.c
index 7387e08c6..be5a4c0f5 100644
--- a/freetype/src/base/ftpfr.c
+++ b/freetype/src/base/ftpfr.c
@@ -4,7 +4,7 @@
/* */
/* FreeType API for accessing PFR-specific data (body). */
/* */
-/* Copyright 2002-2004, 2008, 2010, 2013 by */
+/* Copyright 2002-2004, 2008, 2010, 2013, 2014 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -49,7 +49,7 @@
if ( !face )
- return FT_THROW( Invalid_Argument );
+ return FT_THROW( Invalid_Face_Handle );
service = ft_pfr_check( face );
if ( service )
@@ -105,6 +105,9 @@
if ( !face )
+ return FT_THROW( Invalid_Face_Handle );
+
+ if ( !avector )
return FT_THROW( Invalid_Argument );
service = ft_pfr_check( face );
@@ -129,11 +132,15 @@
FT_Service_PfrMetrics service;
+ if ( !face )
+ return FT_THROW( Invalid_Face_Handle );
+
+ if ( !aadvance )
+ return FT_THROW( Invalid_Argument );
+
service = ft_pfr_check( face );
if ( service )
- {
error = service->get_advance( face, gindex, aadvance );
- }
else
/* XXX: TODO: PROVIDE ADVANCE-LOADING METHOD TO ALL FONT DRIVERS */
error = FT_THROW( Invalid_Argument );
diff --git a/freetype/src/base/ftrfork.c b/freetype/src/base/ftrfork.c
index 0e44d33a8..110b00f64 100644
--- a/freetype/src/base/ftrfork.c
+++ b/freetype/src/base/ftrfork.c
@@ -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 ));
diff --git a/freetype/src/base/ftstream.c b/freetype/src/base/ftstream.c
index 8cb1b88b2..1d5bd39c8 100644
--- a/freetype/src/base/ftstream.c
+++ b/freetype/src/base/ftstream.c
@@ -728,9 +728,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/freetype/src/base/ftstroke.c b/freetype/src/base/ftstroke.c
index 2f7db791a..aa8da15b4 100644
--- a/freetype/src/base/ftstroke.c
+++ b/freetype/src/base/ftstroke.c
@@ -4,7 +4,7 @@
/* */
/* FreeType path stroker (body). */
/* */
-/* Copyright 2002-2006, 2008-2011, 2013 by */
+/* Copyright 2002-2006, 2008-2011, 2013, 2014 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -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 */
@@ -1002,7 +1008,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 );
}
@@ -1287,6 +1294,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 +1370,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 +1572,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 +1780,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. */
@@ -1858,6 +1883,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;
@@ -1983,6 +2014,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 +2034,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 +2051,9 @@
FT_StrokerBorder border,
FT_Outline* outline )
{
+ if ( !stroker || !outline )
+ return;
+
if ( border == FT_STROKER_BORDER_LEFT ||
border == FT_STROKER_BORDER_RIGHT )
{
@@ -2059,7 +2103,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 );
@@ -2258,18 +2305,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,7 +2342,7 @@
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 );
@@ -2334,18 +2383,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,8 +2430,8 @@
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 );
diff --git a/freetype/src/base/ftsynth.c b/freetype/src/base/ftsynth.c
index 4fc8254c7..2e6dce16e 100644
--- a/freetype/src/base/ftsynth.c
+++ b/freetype/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-2006, 2010, 2012-2014 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/freetype/src/base/fttrigon.c b/freetype/src/base/fttrigon.c
index 9e0af81b0..aa191fd2f 100644
--- a/freetype/src/base/fttrigon.c
+++ b/freetype/src/base/fttrigon.c
@@ -4,7 +4,7 @@
/* */
/* FreeType trigonometric functions (body). */
/* */
-/* Copyright 2001-2005, 2012-2013 by */
+/* Copyright 2001-2005, 2012-2014 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 = val & 0x0000FFFFU;
+ hi1 = 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;
- 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 )
{
@@ -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;
@@ -340,6 +359,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,6 +388,9 @@
FT_Vector v;
+ if ( !vec )
+ return;
+
v.x = vec->x;
v.y = vec->y;
@@ -403,6 +428,9 @@
FT_Vector v;
+ if ( !vec )
+ return 0;
+
v = *vec;
/* handle trivial cases */
@@ -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;
diff --git a/freetype/src/base/fttype1.c b/freetype/src/base/fttype1.c
index 54ccbbd30..47af19afb 100644
--- a/freetype/src/base/fttype1.c
+++ b/freetype/src/base/fttype1.c
@@ -4,7 +4,7 @@
/* */
/* FreeType utility file for PS names support (body). */
/* */
-/* Copyright 2002-2004, 2011 by */
+/* Copyright 2002-2004, 2011, 2014 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -17,9 +17,10 @@
#include <ft2build.h>
-#include <internal/ftobjs.h>
-#include <internal/ftserv.h>
-#include <internal/services/svpsinfo.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 */
@@ -28,19 +29,22 @@
FT_Get_PS_Font_Info( FT_Face face,
PS_FontInfoRec* afont_info )
{
- FT_Error error = FT_ERR( Invalid_Argument );
+ FT_Error error;
+ FT_Service_PsInfo service;
- if ( face )
- {
- FT_Service_PsInfo service = NULL;
+ if ( !face )
+ return FT_THROW( Invalid_Face_Handle );
+ if ( !afont_info )
+ return FT_THROW( Invalid_Argument );
- FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
+ FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
- if ( service && service->ps_get_font_info )
- error = service->ps_get_font_info( face, afont_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;
}
@@ -51,8 +55,8 @@
FT_EXPORT_DEF( FT_Int )
FT_Has_PS_Glyph_Names( FT_Face face )
{
- FT_Int result = 0;
- FT_Service_PsInfo service = NULL;
+ FT_Int result = 0;
+ FT_Service_PsInfo service;
if ( face )
@@ -73,19 +77,22 @@
FT_Get_PS_Font_Private( FT_Face face,
PS_PrivateRec* afont_private )
{
- FT_Error error = FT_ERR( Invalid_Argument );
+ FT_Error error;
+ FT_Service_PsInfo service;
- if ( face )
- {
- FT_Service_PsInfo service = NULL;
+ if ( !face )
+ return FT_THROW( Invalid_Face_Handle );
+ if ( !afont_private )
+ return FT_THROW( Invalid_Argument );
- FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
+ FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
- if ( service && service->ps_get_font_private )
- error = service->ps_get_font_private( face, afont_private );
- }
+ if ( service && service->ps_get_font_private )
+ error = service->ps_get_font_private( face, afont_private );
+ else
+ error = FT_THROW( Invalid_Argument );
return error;
}
diff --git a/freetype/src/base/ftutil.c b/freetype/src/base/ftutil.c
index 317280b85..e26aa87f5 100644
--- a/freetype/src/base/ftutil.c
+++ b/freetype/src/base/ftutil.c
@@ -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,8 +267,13 @@
FT_List_Add( FT_List list,
FT_ListNode node )
{
- FT_ListNode before = list->tail;
+ FT_ListNode before;
+
+
+ if ( !list || !node )
+ return;
+ before = list->tail;
node->next = 0;
node->prev = before;
@@ -285,8 +293,13 @@
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;
@@ -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;
@@ -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 )
{
@@ -411,26 +438,4 @@
}
- FT_BASE_DEF( FT_UInt32 )
- ft_highpow2( FT_UInt32 value )
- {
- FT_UInt32 value2;
-
-
- /*
- * We simply clear the lowest bit in each iteration. When
- * we reach 0, we know that the previous value was our result.
- */
- for ( ;; )
- {
- value2 = value & (value - 1); /* clear lowest bit */
- if ( value2 == 0 )
- break;
-
- value = value2;
- }
- return value;
- }
-
-
/* END */
diff --git a/freetype/src/base/ftwinfnt.c b/freetype/src/base/ftwinfnt.c
index c5ae97e1a..cb3733523 100644
--- a/freetype/src/base/ftwinfnt.c
+++ b/freetype/src/base/ftwinfnt.c
@@ -4,7 +4,7 @@
/* */
/* FreeType API for accessing Windows FNT specific info (body). */
/* */
-/* Copyright 2003, 2004 by */
+/* Copyright 2003, 2004, 2014 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 <freetype/internal/ftobjs.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;
}