Index: third_party/freetype/src/base/ftbitmap.c |
diff --git a/core/src/fxge/fx_freetype/fxft2.5.01/src/base/fxft_ftbitmap.c b/third_party/freetype/src/base/ftbitmap.c |
similarity index 76% |
rename from core/src/fxge/fx_freetype/fxft2.5.01/src/base/fxft_ftbitmap.c |
rename to third_party/freetype/src/base/ftbitmap.c |
index 7f1ef189dcd7444c0562d8f4c12e278c092e1b74..5dd33a26f1dfd2140522dceef8314c9269d20513 100644 |
--- a/core/src/fxge/fx_freetype/fxft2.5.01/src/base/fxft_ftbitmap.c |
+++ b/third_party/freetype/src/base/ftbitmap.c |
@@ -1,11 +1,10 @@ |
-#if !defined(_FXFT_VERSION_) || _FXFT_VERSION_ == 2501 |
/***************************************************************************/ |
/* */ |
/* ftbitmap.c */ |
/* */ |
/* FreeType utility functions for bitmaps (body). */ |
/* */ |
-/* Copyright 2004-2009, 2011, 2013 by */ |
+/* Copyright 2004-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, */ |
@@ -16,12 +15,13 @@ |
/* */ |
/***************************************************************************/ |
-#define FT2_BUILD_LIBRARY |
-#include "../../include/ft2build.h" |
-#include "../../include/freetype/internal/ftdebug.h" |
-#include "../../include/freetype/ftbitmap.h" |
-#include "../../include/freetype/ftimage.h" |
-#include "../../include/freetype/internal/ftobjs.h" |
+ |
+#include <ft2build.h> |
+#include FT_INTERNAL_DEBUG_H |
+ |
+#include FT_BITMAP_H |
+#include FT_IMAGE_H |
+#include FT_INTERNAL_OBJECTS_H |
static |
@@ -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]; |
@@ -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; |
} |
@@ -375,15 +414,16 @@ |
} |
- FT_Byte |
+ 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 division by zero. */ |
+ if ( !a ) |
+ return 0; |
/* |
* Luminosity for sRGB is defined using ~0.2126,0.7152,0.0722 |
@@ -391,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 ); |
} |
@@ -439,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 ) |
@@ -455,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_target_pitch = target->pitch; |
+ if ( old_target_pitch < 0 ) |
+ old_target_pitch = -old_target_pitch; |
- old_size = target->rows * target->pitch; |
- if ( old_size < 0 ) |
- old_size = -old_size; |
+ old_size = target->rows * old_target_pitch; |
target->pixel_mode = FT_PIXEL_MODE_GRAY; |
target->rows = source->rows; |
@@ -475,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; |
@@ -492,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; |
@@ -507,7 +556,7 @@ |
{ |
FT_Byte* ss = s; |
FT_Byte* tt = t; |
- FT_Int j; |
+ FT_UInt j; |
/* get the full bytes */ |
@@ -555,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; |
@@ -569,8 +614,8 @@ |
{ |
FT_ARRAY_COPY( t, s, width ); |
- s += s_pitch; |
- t += t_pitch; |
+ s += source->pitch; |
+ t += target->pitch; |
} |
} |
break; |
@@ -578,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; |
@@ -589,7 +632,7 @@ |
{ |
FT_Byte* ss = s; |
FT_Byte* tt = t; |
- FT_Int j; |
+ FT_UInt j; |
/* get the full bytes */ |
@@ -630,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; |
@@ -641,7 +682,7 @@ |
{ |
FT_Byte* ss = s; |
FT_Byte* tt = t; |
- FT_Int j; |
+ FT_UInt j; |
/* get the full bytes */ |
@@ -666,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; |
@@ -681,7 +719,7 @@ |
{ |
FT_Byte* ss = s; |
FT_Byte* tt = t; |
- FT_Int j; |
+ FT_UInt j; |
for ( j = source->width; j > 0; j-- ) |
@@ -692,8 +730,8 @@ |
tt += 1; |
} |
- s += s_pitch; |
- t += t_pitch; |
+ s += source->pitch; |
+ t += target->pitch; |
} |
} |
break; |
@@ -756,5 +794,3 @@ |
/* END */ |
-#endif |
- |