Commit 07c654f4 authored by David Turner's avatar David Turner
Browse files

* include/freetype/config/ftheader.h, include/freetype/ftrgb.h,

        src/rgbfilt/ftrgb.c, src/rgbfilt/ftrgbgen.h, src/rgbfilt/ftrgbgen2.h,
        src/rgbfilt/Jamfile, src/rgbfilt/rules.mk, Jamfile: Adding color
        filter for LCD modes, in order to reduce "fringes"
parent f44a1f67
2005-09-27 David Turner <david@freetype.org>
* include/freetype/config/ftheader.h, include/freetype/ftrgb.h,
src/rgbfilt/ftrgb.c, src/rgbfilt/ftrgbgen.h, src/rgbfilt/ftrgbgen2.h,
src/rgbfilt/Jamfile, src/rgbfilt/rules.mk, Jamfile: Adding color
filter for LCD modes, in order to reduce "fringes"
2005-09-26 David Turner <david@freetype.org>
* src/autofit/aflatin.c (af_latin_compute_stem_width): fixed bad
......
......@@ -86,6 +86,7 @@ FT2_COMPONENTS ?= autofit # auto-fitter
pshinter # PostScript hinter module
psnames # PostScript names handling
raster # monochrome rasterizer
rgbfilt # RGB Color Filter for LCD modes
smooth # anti-aliased rasterizer
sfnt # SFNT-based format support routines
truetype # TrueType font driver
......
This diff is collapsed.
# FreeType 2 src/rgbfilt Jamfile
#
# Copyright 2005 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
SubDir FT2_TOP $(FT2_SRC_DIR) rgbfilt ;
Library $(FT2_LIB) : ftrgb.c ;
# end of src/rgbfilt Jamfile
#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 );
}
/* this file contains a template for the RGB color filter algorithm
* it is included several times by "ftrgb.c"
*/
#ifndef OFF_R
#error "OFF_R must be defined as the offset of the red channel"
#endif
#ifndef OFF_G
#error "OFF_G must be defiend as the offset of the green channel"
#endif
#ifndef OFF_B
#error "OFF_B must be defined as the offset of the blue channel"
#endif
#ifndef HMUL
#error "HMUL must be defined as the horizontal multiplier, either 1 or 3"
#endif
#ifndef VMUL
#error "VMUL must be defined as the vertical multipler, either 1 or 3"
#endif
int hh = oper->height;
FT_Byte* in_line = oper->in_line;
FT_Long in_pitch = oper->in_pitch;
FT_Byte* out_line = oper->out_line;
FT_Long out_pitch = oper->out_pitch;
FT_Fixed* mults = oper->factors;
for ( ; hh > 0; hh--, in_line += in_pitch*VMUL, out_line += out_pitch )
{
int ww = oper->width;
FT_Byte* read = in_line;
FT_UInt32* write = (FT_UInt32*)out_line;
for ( ; ww > 0; ww--, read += HMUL, write += 1 )
{
FT_UInt rr, gg, bb;
FT_UInt val;
val = read[OFF_R];
rr = mults[0]*val;
gg = mults[3]*val;
bb = mults[6]*val;
val = read[OFF_G];
rr += mults[1]*val;
gg += mults[4]*val;
bb += mults[7]*val;
val = read[OFF_B];
rr += mults[2]*val;
gg += mults[5]*val;
bb += mults[8]*val;
rr = (rr >> 16) & 255;
gg = (gg >> 16) & 255;
bb = (bb >> 16) & 255;
write[0] = (FT_UInt)( (gg << 24) | (rr << 16) | (gg << 8) | bb );
}
}
#undef OFF_R
#undef OFF_G
#undef OFF_B
#undef HMUL
#undef VMUL
/* this file contains a template for the in-place RGB color filter algorithm
* it is included several times by "ftrgb.c"
*/
#ifndef OFF_R
#error "OFF_R must be defined as the offset of the red channel"
#endif
#ifndef OFF_G
#error "OFF_G must be defiend as the offset of the green channel"
#endif
#ifndef OFF_B
#error "OFF_B must be defined as the offset of the blue channel"
#endif
#ifndef HMUL
#error "HMUL must be defined as the horizontal multiplier, either 1 or 3"
#endif
#ifndef VMUL
#error "VMUL must be defined as the vertical multipler, either 1 or 3"
#endif
int hh = oper->height;
FT_Byte* in_line = oper->in_line;
FT_Long in_pitch = oper->in_pitch;
FT_Fixed* mults = oper->factors;
for ( ; hh > 0; hh--, in_line += in_pitch*VMUL )
{
int ww = oper->width;
FT_Byte* pix = in_line;
for ( ; ww > 0; ww--, pix += HMUL )
{
FT_UInt rr, gg, bb;
FT_UInt val;
val = pix[OFF_R];
rr = mults[0]*val;
gg = mults[3]*val;
bb = mults[6]*val;
val = pix[OFF_G];
rr += mults[1]*val;
gg += mults[4]*val;
bb += mults[7]*val;
val = pix[OFF_B];
rr += mults[2]*val;
gg += mults[5]*val;
bb += mults[8]*val;
pix[OFF_R] = (FT_Byte)(rr >> 16);
pix[OFF_G] = (FT_Byte)(gg >> 16);
pix[OFF_B] = (FT_Byte)(bb >> 16);
}
}
#undef OFF_R
#undef OFF_G
#undef OFF_B
#undef HMUL
#undef VMUL
#
# FreeType 2 RGB filter configuration rules
#
# rgb driver directory
#
RGBFILT_DIR := $(SRC_DIR)/rgbfilt
RGBFILT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(RGBFILT_DIR))
# RGB filter sources (i.e., C files)
#
RGBFILT_DRV_SRC := $(RGBFILT_DIR)/ftrgb.c
# RGB filter driver headers
#
RGBFILT_DRV_H := $(RGBFILT_DIR)/ftrgbgen.h \
$(RGBFILT_DIR)/ftrgbgn2.h
# RGB filter driver object(s)
#
RGBFILT_DRV_OBJ := $(RGBFILT_DRV_SRC:$(RGBFILT_DIR)/%.c=$(OBJ_DIR)/%.$O)
$(RGBFILT_DRV_OBJ): $(RGBFILT_DRV_SRC) $(FREETYPE_H) $(RGBFILT_DRV_H)
$(RGBFILT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(RGBFILT_DRV_SRC))
# update main driver object lists
#
DRV_OBJS_S += $(RGBFILT_DRV_OBJ)
DRV_OBJS_M += $(RGBFILT_DRV_OBJ)
# EOF
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment