Commit c9c326312f1156bc5865d076620fa13953d24a8c

Alexei Podtelezhnikov 2022-09-22T20:40:21

[base] Clean up the bitmap flow control. * src/base/ftbitmap.c (FT_Bitmap_Copy): Flip the copy if its pitch is trully opposite, zero is not a positive value. (FT_Bitmap_Convert): Set negative pitch as needed, accept negative alignment values.

diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c
index c79409d..d521aa4 100644
--- a/src/base/ftbitmap.c
+++ b/src/base/ftbitmap.c
@@ -67,8 +67,7 @@
     FT_Memory  memory;
     FT_Error   error  = FT_Err_Ok;
     FT_Int     pitch;
-
-    FT_Int  source_pitch_sign, target_pitch_sign;
+    FT_Int     flip;
 
 
     if ( !library )
@@ -80,15 +79,15 @@
     if ( source == target )
       return FT_Err_Ok;
 
-    source_pitch_sign = source->pitch < 0 ? -1 : 1;
-    target_pitch_sign = target->pitch < 0 ? -1 : 1;
+    flip = ( source->pitch < 0 && target->pitch > 0 ) ||
+           ( source->pitch > 0 && target->pitch < 0 );
 
     memory = library->memory;
     FT_FREE( target->buffer );
 
     *target = *source;
 
-    if ( source_pitch_sign != target_pitch_sign )
+    if ( flip )
       target->pitch = -target->pitch;
 
     if ( !source->buffer )
@@ -102,10 +101,7 @@
 
     if ( !error )
     {
-      if ( source_pitch_sign == target_pitch_sign )
-        FT_MEM_COPY( target->buffer, source->buffer,
-                     (FT_Long)source->rows * pitch );
-      else
+      if ( flip )
       {
         /* take care of bitmap flow */
         FT_UInt   i;
@@ -123,6 +119,9 @@
           t -= pitch;
         }
       }
+      else
+        FT_MEM_COPY( target->buffer, source->buffer,
+                     (FT_Long)source->rows * pitch );
     }
 
     return error;
@@ -519,8 +518,9 @@
     case FT_PIXEL_MODE_LCD_V:
     case FT_PIXEL_MODE_BGRA:
       {
-        FT_Int  pad, target_pitch; 
-        FT_Int  old_target_pitch = target->pitch;
+        FT_Int  width = (FT_Int)source->width;
+        FT_Int  neg = ( target->pitch == 0 && source->pitch < 0 ) ||
+                        target->pitch  < 0;
 
 
         FT_Bitmap_Done( library, target );
@@ -529,20 +529,20 @@
         target->rows       = source->rows;
         target->width      = source->width;
 
-        pad = 0;
-        if ( alignment > 0 )
+        if ( alignment )
         {
-          pad = (FT_Int)source->width % alignment;
-          if ( pad != 0 )
-            pad = alignment - pad;
-        }
+          FT_Int  rem = width % alignment;
 
-        target_pitch = (FT_Int)source->width + pad;
 
-        if ( FT_QALLOC_MULT( target->buffer, target->rows, target_pitch ) )
+          if ( rem )
+            width = alignment > 0 ? width - rem + alignment
+                                  : width - rem - alignment;
+        }
+
+        if ( FT_QALLOC_MULT( target->buffer, target->rows, width ) )
           return error;
 
-        target->pitch = old_target_pitch < 0 ? -target_pitch : target_pitch;
+        target->pitch = neg ? -width : width;
       }
       break;