* src/base/ftbitmap.c (FT_Bitmap_Copy): Improve. This commit adds argument checks and support for different flow directions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
diff --git a/ChangeLog b/ChangeLog
index 65e5c16..c62b5f5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2014-11-21 Werner Lemberg <wl@gnu.org>
+
+ * src/base/ftbitmap.c (FT_Bitmap_Copy): Improve.
+
+ This commit adds argument checks and support for different flow
+ directions.
+
2014-11-20 Werner Lemberg <wl@gnu.org>
* src/base/ftbitmap.c (FT_Bitmap_New): Check argument.
diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c
index d333643..b33afec 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;