320 lines
6.6 KiB
C
320 lines
6.6 KiB
C
#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
|
|
#define OFF_G 1
|
|
#define OFF_B 2
|
|
#include "ftrgbgen.h"
|
|
}
|
|
|
|
|
|
static void
|
|
ft_rgbfilter_apply_argb_vbgr( FT_RgbFiltering oper )
|
|
{
|
|
#define HMUL 1
|
|
#define VMUL 3
|
|
#define OFF_R 2
|
|
#define OFF_G 1
|
|
#define OFF_B 0
|
|
#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
|
|
#define OFF_G 1
|
|
#define OFF_B 2
|
|
#include "ftrgbgn2.h"
|
|
}
|
|
|
|
|
|
static void
|
|
ft_rgbfilter_apply_inplace_vbgr( FT_RgbFiltering oper )
|
|
{
|
|
#define HMUL 1
|
|
#define VMUL 3
|
|
#define OFF_R 2
|
|
#define OFF_G 1
|
|
#define OFF_B 0
|
|
#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 );
|
|
}
|