Compare commits

...

4 Commits

Author SHA1 Message Date
Alexei Podtelezhnikov
468eaf19d9 * src/base/ftbitmap.c (FT_Bitmap_Copy): Clarify the flow control.
* include/freetype/ftbitmap.h (FT_Bitmap_Copy): Ditto.
2022-09-21 16:57:34 +00:00
Alexei Podtelezhnikov
82c5ecfee1 * src/base/ftbitmap.c (FT_Bitmap_Copy): Recreate target.
There is no need to preserve bits before overwriting them.
Therefore, free-malloc could be faster than realloc.
2022-09-21 14:44:23 +00:00
Alexei Podtelezhnikov
baae1a2775 [base] Accept negative bitmap alignment for bottom-up flow.
* src/base/ftbitmap.c (FT_Bitmap_Convert): Use negative alignment
to produce negative pitch.
* include/freetype/ftbitmap.c (FT_Bitmap_Convert): Document it.
2022-09-20 14:16:29 -04:00
Alexei Podtelezhnikov
4dba6795b6 * src/base/ftbitmap.c (FT_Bitmap_Convert): Recreate target.
There is no need to preserve bits before overwriting them.
Therefore, free-malloc could be faster than realloc.
2022-09-20 03:15:42 +00:00
2 changed files with 46 additions and 82 deletions

View File

@ -47,14 +47,6 @@ FT_BEGIN_HEADER
* @description:
* This section contains functions for handling @FT_Bitmap objects,
* automatically adjusting the target's bitmap buffer size as needed.
*
* Note that none of the functions changes the bitmap's 'flow' (as
* indicated by the sign of the `pitch` field in @FT_Bitmap).
*
* To set the flow, assign an appropriate positive or negative value to
* the `pitch` field of the target @FT_Bitmap object after calling
* @FT_Bitmap_Init but before calling any of the other functions
* described here.
*/
@ -105,8 +97,14 @@ FT_BEGIN_HEADER
* FreeType error code. 0~means success.
*
* @note:
* `source->buffer` and `target->buffer` must neither be equal nor
* overlap.
* This function reallocates the memory in the target bitmap, which has
* to be valid, either initialized by @FT_Bitmap_Init or reused multiple
* times. `source->buffer` and `target->buffer` must neither be equal
* nor overlap. Use @FT_Bitmap_Done to finally remove the bitmap object.
*
* The source and target bitmaps can have different flows if their
* pitches are set to opposite signs before calling this function.
* Otherwise, the flow is preserved.
*/
FT_EXPORT( FT_Error )
FT_Bitmap_Copy( FT_Library library,
@ -178,8 +176,8 @@ FT_BEGIN_HEADER
* The source bitmap.
*
* alignment ::
* The pitch of the bitmap is a multiple of this argument. Common
* values are 1, 2, or 4.
* The pitch of the target bitmap is a multiple of this argument.
* Common values are 1, 2, or 4.
*
* @output:
* target ::
@ -189,16 +187,16 @@ FT_BEGIN_HEADER
* FreeType error code. 0~means success.
*
* @note:
* It is possible to call @FT_Bitmap_Convert multiple times without
* calling @FT_Bitmap_Done (the memory is simply reallocated).
* This function reallocates the memory in the target bitmap, which has
* to be valid, either initialized by @FT_Bitmap_Init or reused multiple
* times. `source->buffer` and `target->buffer` must neither be equal
* nor overlap. Use @FT_Bitmap_Done to finally remove the bitmap object.
*
* Use @FT_Bitmap_Done to finally remove the bitmap object.
* Negative alignment values produce bottom-up bitmaps with negative
* pitch. Zero alignment is treated as one, i.e., no padding is used.
*
* The `library` argument is taken to have access to FreeType's memory
* handling functions.
*
* `source->buffer` and `target->buffer` must neither be equal nor
* overlap.
*/
FT_EXPORT( FT_Error )
FT_Bitmap_Convert( FT_Library library,

View File

@ -66,11 +66,8 @@
{
FT_Memory memory;
FT_Error error = FT_Err_Ok;
FT_Int pitch;
FT_ULong size;
FT_Int source_pitch_sign, target_pitch_sign;
FT_Int pitch;
FT_Int flip;
if ( !library )
@ -82,53 +79,29 @@
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 )
{
*target = *source;
if ( source_pitch_sign != target_pitch_sign )
target->pitch = -target->pitch;
return FT_Err_Ok;
}
flip = ( source->pitch < 0 && target->pitch > 0 ) ||
( source->pitch > 0 && target->pitch < 0 );
memory = library->memory;
pitch = source->pitch;
FT_FREE( target->buffer );
*target = *source;
if ( flip )
target->pitch = -target->pitch;
if ( !source->buffer )
return FT_Err_Ok;
pitch = source->pitch;
if ( pitch < 0 )
pitch = -pitch;
size = (FT_ULong)pitch * source->rows;
if ( target->buffer )
{
FT_Int target_pitch = target->pitch;
FT_ULong target_size;
if ( target_pitch < 0 )
target_pitch = -target_pitch;
target_size = (FT_ULong)target_pitch * target->rows;
if ( target_size != size )
FT_MEM_QREALLOC( target->buffer, target_size, size );
}
else
FT_MEM_QALLOC( target->buffer, size );
FT_MEM_QALLOC_MULT( target->buffer, target->rows, pitch );
if ( !error )
{
unsigned char *p;
p = target->buffer;
*target = *source;
target->buffer = p;
if ( source_pitch_sign == target_pitch_sign )
FT_MEM_COPY( target->buffer, source->buffer, size );
else
if ( flip )
{
/* take care of bitmap flow */
FT_UInt i;
@ -146,6 +119,9 @@
t -= pitch;
}
}
else
FT_MEM_COPY( target->buffer, source->buffer,
(FT_Long)source->rows * pitch );
}
return error;
@ -542,39 +518,29 @@
case FT_PIXEL_MODE_LCD_V:
case FT_PIXEL_MODE_BGRA:
{
FT_Int pad, old_target_pitch, target_pitch;
FT_ULong old_size;
FT_Int width = (FT_Int)source->width;
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;
FT_Bitmap_Done( library, target );
target->pixel_mode = FT_PIXEL_MODE_GRAY;
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;
if ( rem )
width = alignment < 0 ? width - rem - alignment
: width - rem + alignment;
}
target_pitch = (FT_Int)source->width + pad;
if ( target_pitch > 0 &&
(FT_ULong)target->rows > FT_ULONG_MAX / (FT_ULong)target_pitch )
return FT_THROW( Invalid_Argument );
if ( FT_QREALLOC( target->buffer,
old_size, target->rows * (FT_UInt)target_pitch ) )
if ( FT_QALLOC_MULT( target->buffer, target->rows, width ) )
return error;
target->pitch = target->pitch < 0 ? -target_pitch : target_pitch;
target->pitch = alignment < 0 ? -width : width;
}
break;