blob: 9b445515c7d1ddd619bb782a248e9af14a83df3f [file] [log] [blame]
#include <ft2build.h>
#include FT_RGB_FILTER_H
#include FT_INTERNAL_OBJECTS_H
typedef struct FT_RgbFilterRec_
{
FT_Fixed factors[9];
FT_Memory memory;
} FT_RgbFilterRec;
typedef struct FT_RgbFilterinRec_
{
FT_Fixed factors[9];
FT_Byte* in_line;
FT_Long in_pitch;
FT_Byte* out_line;
FT_Long out_pitch;
FT_Int width;
FT_Int height;
} FT_RgbFilteringRec, *FT_RgbFiltering;
/* these values come from libXft */
static const FT_RgbFilterRec ft_rgbfilter_default =
{
{ 65538*9/13, 65538*3/13, 65538*1/13,
65538*1/6, 65538*4/6, 65538*1/6,
65538*1/13, 65538*3/13, 65538*9/13 },
NULL
};
static void
ft_rgbfilter_apply_argb_rgb( FT_RgbFiltering oper )
{
#define HMUL 3
#define VMUL 1
#define OFF_R 0
#define OFF_G 1
#define OFF_B 2
#include "ftrgbgen.h"
}
static void
ft_rgbfilter_apply_argb_bgr( FT_RgbFiltering oper )
{
#define HMUL 3
#define VMUL 1
#define OFF_R 2
#define OFF_G 1
#define OFF_B 0
#include "ftrgbgen.h"
}
static void
ft_rgbfilter_apply_argb_vrgb( FT_RgbFiltering oper )
{
#define HMUL 1
#define VMUL 3
#define OFF_R (0*in_pitch)
#define OFF_G (1*in_pitch)
#define OFF_B (2*in_pitch)
#include "ftrgbgen.h"
}
static void
ft_rgbfilter_apply_argb_vbgr( FT_RgbFiltering oper )
{
#define HMUL 1
#define VMUL 3
#define OFF_R (2*in_pitch)
#define OFF_G (1*in_pitch)
#define OFF_B (0*in_pitch)
#include "ftrgbgen.h"
}
static void
ft_rgbfilter_apply_inplace_rgb( FT_RgbFiltering oper )
{
#define HMUL 3
#define VMUL 1
#define OFF_R 0
#define OFF_G 1
#define OFF_B 2
#include "ftrgbgn2.h"
}
static void
ft_rgbfilter_apply_inplace_bgr( FT_RgbFiltering oper )
{
#define HMUL 3
#define VMUL 1
#define OFF_R 2
#define OFF_G 1
#define OFF_B 0
#include "ftrgbgn2.h"
}
static void
ft_rgbfilter_apply_inplace_vrgb( FT_RgbFiltering oper )
{
#define HMUL 1
#define VMUL 3
#define OFF_R (0*in_pitch)
#define OFF_G (1*in_pitch)
#define OFF_B (2*in_pitch)
#include "ftrgbgn2.h"
}
static void
ft_rgbfilter_apply_inplace_vbgr( FT_RgbFiltering oper )
{
#define HMUL 1
#define VMUL 3
#define OFF_R (2*in_pitch)
#define OFF_G (1*in_pitch)
#define OFF_B (0*in_pitch)
#include "ftrgbgn2.h"
}
FT_EXPORT_DEF( FT_Error )
FT_RgbFilter_ApplyARGB( FT_RgbFilter filter,
FT_Bool inverted,
FT_Pixel_Mode in_mode,
FT_Byte* in_bytes,
FT_Long in_pitch,
FT_Int out_width,
FT_Int out_height,
FT_UInt32* out_bytes,
FT_Long out_pitch )
{
FT_RgbFilteringRec oper;
int in_width = out_width;
int in_height = out_height;
switch ( in_mode )
{
case FT_PIXEL_MODE_LCD:
in_width = 3*out_width;
break;
case FT_PIXEL_MODE_LCD_V:
in_height = 3*out_height;
break;
default:
return FT_Err_Invalid_Argument;
}
if ( FT_ABS(in_pitch) < in_width ||
FT_ABS(out_pitch) < 4*out_width )
return FT_Err_Invalid_Argument;
oper.width = out_width;
oper.height = out_height;
oper.in_line = in_bytes;
oper.in_pitch = in_pitch;
if ( in_pitch < 0 )
oper.in_line -= in_pitch*(in_height-1);
oper.out_line = (FT_Byte*) out_bytes;
oper.out_pitch = out_pitch;
if ( out_pitch < 0 )
oper.out_line -= out_pitch*(out_height-1);
if ( filter == NULL )
filter = (FT_RgbFilter)&ft_rgbfilter_default;
FT_ARRAY_COPY( oper.factors, filter->factors, 9 );
switch ( in_mode )
{
case FT_PIXEL_MODE_LCD:
if ( inverted )
ft_rgbfilter_apply_argb_bgr( &oper );
else
ft_rgbfilter_apply_argb_rgb( &oper );
break;
case FT_PIXEL_MODE_LCD_V:
if ( inverted )
ft_rgbfilter_apply_argb_vbgr( &oper );
else
ft_rgbfilter_apply_argb_vrgb( &oper );
break;
default:
;
}
return 0;
}
FT_EXPORT_DEF( FT_Error )
FT_RgbFilter_ApplyInPlace( FT_RgbFilter filter,
FT_Bool inverted,
FT_Pixel_Mode in_mode,
FT_Byte* in_bytes,
FT_Long in_pitch,
FT_Int org_width,
FT_Int org_height )
{
FT_RgbFilteringRec oper;
int in_width = org_width;
int in_height = org_height;
switch ( in_mode )
{
case FT_PIXEL_MODE_LCD:
in_width = 3*org_width;
break;
case FT_PIXEL_MODE_LCD_V:
in_height = 3*org_height;
break;
default:
return FT_Err_Invalid_Argument;
}
if ( FT_ABS(in_pitch) < in_width )
return FT_Err_Invalid_Argument;
oper.width = org_width;
oper.height = org_height;
oper.in_line = in_bytes;
oper.in_pitch = in_pitch;
if ( in_pitch < 0 )
oper.in_line -= in_pitch*(in_height-1);
if ( filter == NULL )
filter = (FT_RgbFilter)&ft_rgbfilter_default;
FT_ARRAY_COPY( oper.factors, filter->factors, 9 );
switch ( in_mode )
{
case FT_PIXEL_MODE_LCD:
if ( inverted )
ft_rgbfilter_apply_inplace_bgr( &oper );
else
ft_rgbfilter_apply_inplace_rgb( &oper );
break;
case FT_PIXEL_MODE_LCD_V:
if ( inverted )
ft_rgbfilter_apply_inplace_vbgr( &oper );
else
ft_rgbfilter_apply_inplace_vrgb( &oper );
break;
default:
;
}
return 0;
}
FT_EXPORT_DEF( FT_Error )
FT_RgbFilter_New( FT_Library library,
FT_Fixed* values_9,
FT_RgbFilter *pfilter )
{
FT_Error error = 0;
FT_RgbFilter filter = NULL;
if ( !library || !values_9 )
error = FT_Err_Invalid_Argument;
else
{
FT_Memory memory = library->memory;
if ( !FT_NEW( filter ) )
{
FT_ARRAY_COPY( filter->factors, values_9, 9 );
filter->memory = memory;
}
}
*pfilter = filter;
return error;
}
FT_EXPORT_DEF( void )
FT_RgbFilter_Done( FT_RgbFilter filter )
{
if ( filter )
{
FT_Memory memory = filter->memory;
filter->memory = NULL;
if ( memory )
FT_FREE( filter );
}
}
FT_EXPORT_DEF( void )
FT_RgbFilter_Reset( FT_RgbFilter filter,
FT_Fixed* values_9 )
{
if ( filter && values_9 )
FT_ARRAY_COPY( filter->factors, values_9, 9 );
}