diff --git a/ChangeLog b/ChangeLog index 65e5c16e4..c62b5f53b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2014-11-21 Werner Lemberg + + * src/base/ftbitmap.c (FT_Bitmap_Copy): Improve. + + This commit adds argument checks and support for different flow + directions. + 2014-11-20 Werner Lemberg * src/base/ftbitmap.c (FT_Bitmap_New): Check argument. diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c index d33364391..b33afec11 100644 --- a/src/base/ftbitmap.c +++ b/src/base/ftbitmap.c @@ -45,22 +45,39 @@ 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; @@ -71,7 +88,7 @@ FT_ULong target_size; - if ( target_pitch < 0 ) + if ( target_pitch < 0 ) target_pitch = -target_pitch; target_size = (FT_ULong)target_pitch * target->rows; @@ -90,7 +107,26 @@ *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;