major changes to the library:
- there is now a "convenience" API to manage glyphs in "include/ftglyph.h". See the demo program "ftstring" for an example.. - the raster interface has been changed in order to allow direct composition through user-provided callbacks. This has been tested but isn't demonstrated for now in "demos" - the FT_LOAD_NO_RECURSE flag is supported, as this is required by some new code in the auto-hinting engine - some bug fixed in FT_MulFix which made FT_xxx_Transform return incorrect results..
This commit is contained in:
parent
ed7f62aca5
commit
37379e2170
@ -44,6 +44,24 @@
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Convenience functions support */
|
||||
/* */
|
||||
/* Some functions of the FreeType 2 API are provided as a convenience */
|
||||
/* for client applications and developers. However, they are not */
|
||||
/* required to build and run the library itself. */
|
||||
/* */
|
||||
/* By defining this configuration macro, you'll disable the */
|
||||
/* compilation of these functions at build time. This can be useful */
|
||||
/* to reduce the library's code size when you don't need any of */
|
||||
/* these functions.. */
|
||||
/* */
|
||||
/* All convenience functions are declared as such in their */
|
||||
/* documentation. */
|
||||
/* */
|
||||
#undef FT_CONFIG_OPTION_NO_CONVENIENCE_FUNCS
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Alternate Glyph Image Format support */
|
||||
|
@ -18,9 +18,13 @@
|
||||
|
||||
|
||||
ifeq ($(PLATFORM),ansi)
|
||||
has_inittab := $(strip $(wildcard /etc/inittab))
|
||||
|
||||
ifneq ($(has_inittab),)
|
||||
# Some Unix systems like *BSD do not have a /etc/inittab so we commented
|
||||
# the line.. (thanks to Yamano-uchi, Hidetoshi for pointing this out)..
|
||||
#
|
||||
# has_inittab := $(strip $(wildcard /etc/inittab))
|
||||
has_init := $(strip $(wildcard /sbin/init))
|
||||
ifneq ($(has_init),)
|
||||
|
||||
PLATFORM := unix
|
||||
COPY := cp
|
||||
|
@ -152,7 +152,7 @@ else
|
||||
#
|
||||
# The list of demonstration programs to build.
|
||||
#
|
||||
EXES := ftlint ftview fttimer
|
||||
EXES := ftlint ftview fttimer compos ftstring
|
||||
|
||||
ifneq ($(findstring $(PLATFORM),os2 unix),)
|
||||
EXES += ttdebug
|
||||
@ -182,9 +182,15 @@ else
|
||||
$(OBJ_)ftlint.$O: $(SRC_DIR_)ftlint.c
|
||||
$(COMPILE) $T$@ $<
|
||||
|
||||
$(OBJ_)compos.$O: $(SRC_DIR_)compos.c
|
||||
$(COMPILE) $T$@ $<
|
||||
|
||||
$(OBJ_)ftgrays.$O: $(SRC_DIR_)ftgrays.c
|
||||
$(COMPILE) $T$@ $<
|
||||
|
||||
$(OBJ_)ftgrays2.$O: $(SRC_DIR_)ftgrays2.c
|
||||
$(COMPILE) $T$@ $<
|
||||
|
||||
$(OBJ_)fttry.$O: $(SRC_DIR_)fttry.c
|
||||
$(COMPILE) $T$@ $<
|
||||
|
||||
@ -192,9 +198,19 @@ else
|
||||
$(OBJ_)ftview.$O: $(SRC_DIR_)ftview.c $(GRAPH_LIB)
|
||||
$(COMPILE) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
|
||||
|
||||
$(OBJ_)ftstring.$O: $(SRC_DIR_)ftstring.c $(GRAPH_LIB)
|
||||
$(COMPILE) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
|
||||
|
||||
$(OBJ_)try.$O: $(SRC_DIR_)try.c $(GRAPH_LIB)
|
||||
$(COMPILE) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
|
||||
|
||||
$(OBJ_)fttimer.$O: $(SRC_DIR_)fttimer.c $(GRAPH_LIB)
|
||||
$(COMPILE) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
|
||||
|
||||
$(OBJ_)fttimer2.$O: $(SRC_DIR_)fttimer2.c $(GRAPH_LIB)
|
||||
$(COMPILE) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
|
||||
|
||||
|
||||
# $(OBJ_)ftsbit.$O: $(SRC_DIR)/ftsbit.c $(GRAPH_LIB)
|
||||
# $(COMPILE) $T$@ $<
|
||||
|
||||
@ -233,6 +249,9 @@ else
|
||||
$(BIN_)ftlint$E: $(OBJ_)ftlint.$O $(FTLIB) $(COMMON_OBJ)
|
||||
$(COMMON_LINK)
|
||||
|
||||
$(BIN_)compos$E: $(OBJ_)compos.$O $(FTLIB) $(COMMON_OBJ)
|
||||
$(COMMON_LINK)
|
||||
|
||||
$(BIN_)fttry$E: $(OBJ_)fttry.$O $(FTLIB)
|
||||
$(LINK)
|
||||
|
||||
@ -249,9 +268,20 @@ else
|
||||
$(BIN_)ftview$E: $(OBJ_)ftview.$O $(FTLIB) $(GRAPH_LIB) $(COMMON_OBJ) $(OBJ_)ftgrays.$O
|
||||
$(GRAPH_LINK) $(OBJ_)ftgrays.$O
|
||||
|
||||
$(BIN_)ftstring$E: $(OBJ_)ftstring.$O $(FTLIB) $(GRAPH_LIB) $(COMMON_OBJ) $(OBJ_)ftgrays.$O
|
||||
$(GRAPH_LINK) $(OBJ_)ftgrays.$O
|
||||
|
||||
|
||||
$(BIN_)try$E: $(OBJ_)try.$O $(FTLIB) $(GRAPH_LIB) $(COMMON_OBJ) $(OBJ_)ftgrays2.$O
|
||||
$(GRAPH_LINK) $(OBJ_)ftgrays2.$O
|
||||
|
||||
$(BIN_)fttimer$E: $(OBJ_)fttimer.$O $(FTLIB) $(GRAPH_LIB) $(COMMON_OBJ) $(OBJ_)ftgrays.$O
|
||||
$(GRAPH_LINK) $(OBJ_)ftgrays.$O
|
||||
|
||||
$(BIN_)fttimer2$E: $(OBJ_)fttimer2.$O $(FTLIB) $(GRAPH_LIB) $(COMMON_OBJ) $(OBJ_)ftgrays2.$O
|
||||
$(GRAPH_LINK) $(OBJ_)ftgrays2.$O
|
||||
|
||||
|
||||
endif
|
||||
|
||||
# EOF
|
||||
|
@ -55,6 +55,11 @@
|
||||
#define ErrRaster_Invalid_Outline -1
|
||||
|
||||
#include "ftgrays.h"
|
||||
#ifdef _STANDALONE_
|
||||
#error "implementation of FT_Outline_Decompose missing !!!"
|
||||
#else
|
||||
#include <freetype.h> /* to link to FT_Outline_Decompose */
|
||||
#endif
|
||||
|
||||
#define xxxDEBUG_GRAYS
|
||||
|
||||
@ -91,6 +96,70 @@
|
||||
#define UPSCALE(x) (PIXEL_BITS >= 6 ? (x) << (PIXEL_BITS-6) : (x) >> (6-PIXEL_BITS))
|
||||
#define DOWNSCALE(x) (PIXEL_BITS >= 6 ? (x) >> (PIXEL_BITS-6) : (x) << (6-PIXEL_BITS))
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* TYPE DEFINITIONS */
|
||||
/* */
|
||||
|
||||
typedef int TScan;
|
||||
typedef long TPos;
|
||||
typedef float TDist;
|
||||
|
||||
#define FT_MAX_GRAY_SPANS 32
|
||||
|
||||
|
||||
typedef struct TCell_
|
||||
{
|
||||
TScan x;
|
||||
TScan y;
|
||||
int area;
|
||||
int cover;
|
||||
|
||||
} TCell, *PCell;
|
||||
|
||||
|
||||
typedef struct TRaster_
|
||||
{
|
||||
PCell cells;
|
||||
int max_cells;
|
||||
int num_cells;
|
||||
|
||||
TScan min_ex, max_ex;
|
||||
TScan min_ey, max_ey;
|
||||
|
||||
int area;
|
||||
int cover;
|
||||
int invalid;
|
||||
|
||||
TScan ex, ey;
|
||||
TScan cx, cy;
|
||||
TPos x, y;
|
||||
|
||||
TScan last_ey;
|
||||
|
||||
FT_Vector bez_stack[32*3];
|
||||
int lev_stack[32];
|
||||
|
||||
FT_Outline outline;
|
||||
FT_Bitmap target;
|
||||
|
||||
FT_Span gray_spans[ FT_MAX_GRAY_SPANS ];
|
||||
int num_gray_spans;
|
||||
|
||||
FT_Raster_Span_Func render_span;
|
||||
void* render_span_data;
|
||||
int span_y;
|
||||
|
||||
void* memory;
|
||||
|
||||
} TRaster, *PRaster;
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* INITIALIZE THE CELLS TABLE */
|
||||
@ -783,399 +852,6 @@ int check_sort( PCell cells, int count )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static
|
||||
int FT_Decompose_Outline( FT_Outline* outline,
|
||||
FT_Outline_Funcs* interface,
|
||||
void* user )
|
||||
{
|
||||
typedef enum _phases
|
||||
{
|
||||
phase_point,
|
||||
phase_conic,
|
||||
phase_cubic,
|
||||
phase_cubic2
|
||||
|
||||
} TPhase;
|
||||
|
||||
FT_Vector v_first;
|
||||
FT_Vector v_last;
|
||||
FT_Vector v_control;
|
||||
FT_Vector v_start;
|
||||
|
||||
FT_Vector* point;
|
||||
FT_Vector* limit;
|
||||
char* tags;
|
||||
|
||||
int n; /* index of contour in outline */
|
||||
int first; /* index of first point in contour */
|
||||
int error;
|
||||
char tag; /* current point's state */
|
||||
|
||||
|
||||
first = 0;
|
||||
|
||||
for ( n = 0; n < outline->n_contours; n++ )
|
||||
{
|
||||
int last; /* index of last point in contour */
|
||||
|
||||
last = outline->contours[n];
|
||||
limit = outline->points + last;
|
||||
|
||||
v_first = outline->points[first];
|
||||
v_last = outline->points[last];
|
||||
|
||||
v_start = v_control = v_first;
|
||||
|
||||
point = outline->points + first;
|
||||
tags = outline->tags + first;
|
||||
tag = FT_CURVE_TAG( tags[0] );
|
||||
|
||||
/* A contour cannot start with a cubic control point! */
|
||||
if ( tag == FT_Curve_Tag_Cubic )
|
||||
goto Invalid_Outline;
|
||||
|
||||
/* check first point to determine origin */
|
||||
if ( tag == FT_Curve_Tag_Conic )
|
||||
{
|
||||
/* first point is conic control. Yes, this happens. */
|
||||
if ( FT_CURVE_TAG( outline->tags[last] ) == FT_Curve_Tag_On )
|
||||
{
|
||||
/* start at last point if it is on the curve */
|
||||
v_start = v_last;
|
||||
limit--;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if both first and last points are conic, */
|
||||
/* start at their middle and record its position */
|
||||
/* for closure */
|
||||
v_start.x = ( v_start.x + v_last.x ) / 2;
|
||||
v_start.y = ( v_start.y + v_last.y ) / 2;
|
||||
|
||||
v_last = v_start;
|
||||
}
|
||||
point--;
|
||||
tags--;
|
||||
}
|
||||
|
||||
error = interface->move_to( &v_start, user );
|
||||
if (error) goto Exit;
|
||||
|
||||
while (point < limit)
|
||||
{
|
||||
point++;
|
||||
tags++;
|
||||
|
||||
tag = FT_CURVE_TAG( tags[0] );
|
||||
switch (tag)
|
||||
{
|
||||
case FT_Curve_Tag_On: /* emit a single line_to */
|
||||
{
|
||||
error = interface->line_to( point, user );
|
||||
if (error) goto Exit;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
case FT_Curve_Tag_Conic: /* consume conic arcs */
|
||||
{
|
||||
v_control = point[0];
|
||||
|
||||
Do_Conic:
|
||||
if (point < limit)
|
||||
{
|
||||
FT_Vector v_middle;
|
||||
|
||||
point++;
|
||||
tags++;
|
||||
tag = FT_CURVE_TAG( tags[0] );
|
||||
|
||||
if (tag == FT_Curve_Tag_On)
|
||||
{
|
||||
error = interface->conic_to( &v_control, point, user );
|
||||
if (error) goto Exit;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tag != FT_Curve_Tag_Conic)
|
||||
goto Invalid_Outline;
|
||||
|
||||
v_middle.x = (v_control.x + point->x)/2;
|
||||
v_middle.y = (v_control.y + point->y)/2;
|
||||
|
||||
error = interface->conic_to( &v_control, &v_middle, user );
|
||||
if (error) goto Exit;
|
||||
|
||||
v_control = point[0];
|
||||
goto Do_Conic;
|
||||
}
|
||||
|
||||
error = interface->conic_to( &v_control, &v_start, user );
|
||||
goto Close;
|
||||
}
|
||||
|
||||
default: /* FT_Curve_Tag_Cubic */
|
||||
{
|
||||
if ( point+1 > limit ||
|
||||
FT_CURVE_TAG( tags[1] ) != FT_Curve_Tag_Cubic )
|
||||
goto Invalid_Outline;
|
||||
|
||||
point += 2;
|
||||
tags += 2;
|
||||
|
||||
if (point <= limit)
|
||||
{
|
||||
error = interface->cubic_to( point-2, point-1, point, user );
|
||||
if (error) goto Exit;
|
||||
continue;
|
||||
}
|
||||
|
||||
error = interface->cubic_to( point-2, point-1, &v_start, user );
|
||||
goto Close;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* close the contour with a line segment */
|
||||
error = interface->line_to( &v_start, user );
|
||||
|
||||
Close:
|
||||
if (error) goto Exit;
|
||||
first = last+1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
Exit:
|
||||
return error;
|
||||
|
||||
Invalid_Outline:
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
static
|
||||
int FT_Decompose_Outline( FT_Outline* outline,
|
||||
FT_Outline_Funcs* interface,
|
||||
void* user )
|
||||
{
|
||||
typedef enum _phases
|
||||
{
|
||||
phase_point,
|
||||
phase_conic,
|
||||
phase_cubic,
|
||||
phase_cubic2
|
||||
|
||||
} TPhase;
|
||||
|
||||
FT_Vector v_first;
|
||||
FT_Vector v_last;
|
||||
FT_Vector v_control;
|
||||
FT_Vector v_control2;
|
||||
FT_Vector v_start;
|
||||
|
||||
FT_Vector* point;
|
||||
char* tags;
|
||||
|
||||
int n; /* index of contour in outline */
|
||||
int first; /* index of first point in contour */
|
||||
int index; /* current point's index */
|
||||
|
||||
int error;
|
||||
|
||||
char tag; /* current point's state */
|
||||
TPhase phase;
|
||||
|
||||
|
||||
first = 0;
|
||||
|
||||
for ( n = 0; n < outline->n_contours; n++ )
|
||||
{
|
||||
int last; /* index of last point in contour */
|
||||
|
||||
|
||||
last = outline->contours[n];
|
||||
|
||||
v_first = outline->points[first];
|
||||
v_last = outline->points[last];
|
||||
|
||||
v_start = v_control = v_first;
|
||||
|
||||
tag = FT_CURVE_TAG( outline->tags[first] );
|
||||
index = first;
|
||||
|
||||
/* A contour cannot start with a cubic control point! */
|
||||
|
||||
if ( tag == FT_Curve_Tag_Cubic )
|
||||
return ErrRaster_Invalid_Outline;
|
||||
|
||||
|
||||
/* check first point to determine origin */
|
||||
|
||||
if ( tag == FT_Curve_Tag_Conic )
|
||||
{
|
||||
/* first point is conic control. Yes, this happens. */
|
||||
if ( FT_CURVE_TAG( outline->tags[last] ) == FT_Curve_Tag_On )
|
||||
{
|
||||
/* start at last point if it is on the curve */
|
||||
v_start = v_last;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if both first and last points are conic, */
|
||||
/* start at their middle and record its position */
|
||||
/* for closure */
|
||||
v_start.x = ( v_start.x + v_last.x ) / 2;
|
||||
v_start.y = ( v_start.y + v_last.y ) / 2;
|
||||
|
||||
v_last = v_start;
|
||||
}
|
||||
phase = phase_conic;
|
||||
}
|
||||
else
|
||||
phase = phase_point;
|
||||
|
||||
|
||||
/* Begin a new contour with MOVE_TO */
|
||||
|
||||
error = interface->move_to( &v_start, user );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
point = outline->points + first;
|
||||
tags = outline->tags + first;
|
||||
|
||||
/* now process each contour point individually */
|
||||
|
||||
while ( index < last )
|
||||
{
|
||||
index++;
|
||||
point++;
|
||||
tags++;
|
||||
|
||||
tag = FT_CURVE_TAG( tags[0] );
|
||||
|
||||
switch ( phase )
|
||||
{
|
||||
case phase_point: /* the previous point was on the curve */
|
||||
|
||||
switch ( tag )
|
||||
{
|
||||
/* two succesive on points -> emit segment */
|
||||
case FT_Curve_Tag_On:
|
||||
error = interface->line_to( point, user );
|
||||
break;
|
||||
|
||||
/* on point + conic control -> remember control point */
|
||||
case FT_Curve_Tag_Conic:
|
||||
v_control = point[0];
|
||||
phase = phase_conic;
|
||||
break;
|
||||
|
||||
/* on point + cubic control -> remember first control */
|
||||
default:
|
||||
v_control = point[0];
|
||||
phase = phase_cubic;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case phase_conic: /* the previous point was a conic control */
|
||||
|
||||
switch ( tag )
|
||||
{
|
||||
/* conic control + on point -> emit conic arc */
|
||||
case FT_Curve_Tag_On:
|
||||
error = interface->conic_to( &v_control, point, user );
|
||||
phase = phase_point;
|
||||
break;
|
||||
|
||||
/* two successive conics -> emit conic arc `in between' */
|
||||
case FT_Curve_Tag_Conic:
|
||||
{
|
||||
FT_Vector v_middle;
|
||||
|
||||
|
||||
v_middle.x = (v_control.x + point->x)/2;
|
||||
v_middle.y = (v_control.y + point->y)/2;
|
||||
|
||||
error = interface->conic_to( &v_control,
|
||||
&v_middle, user );
|
||||
v_control = point[0];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
error = ErrRaster_Invalid_Outline;
|
||||
}
|
||||
break;
|
||||
|
||||
case phase_cubic: /* the previous point was a cubic control */
|
||||
|
||||
/* this point _must_ be a cubic control too */
|
||||
if ( tag != FT_Curve_Tag_Cubic )
|
||||
return ErrRaster_Invalid_Outline;
|
||||
|
||||
v_control2 = point[0];
|
||||
phase = phase_cubic2;
|
||||
break;
|
||||
|
||||
|
||||
case phase_cubic2: /* the two previous points were cubics */
|
||||
|
||||
/* this point _must_ be an on point */
|
||||
if ( tag != FT_Curve_Tag_On )
|
||||
error = ErrRaster_Invalid_Outline;
|
||||
else
|
||||
error = interface->cubic_to( &v_control, &v_control2,
|
||||
point, user );
|
||||
phase = phase_point;
|
||||
break;
|
||||
}
|
||||
|
||||
/* lazy error testing */
|
||||
if ( error )
|
||||
return error;
|
||||
}
|
||||
|
||||
/* end of contour, close curve cleanly */
|
||||
error = 0;
|
||||
|
||||
tag = FT_CURVE_TAG( outline->tags[first] );
|
||||
|
||||
switch ( phase )
|
||||
{
|
||||
case phase_point:
|
||||
if ( tag == FT_Curve_Tag_On )
|
||||
error = interface->line_to( &v_first, user );
|
||||
break;
|
||||
|
||||
case phase_conic:
|
||||
error = interface->conic_to( &v_control, &v_start, user );
|
||||
break;
|
||||
|
||||
case phase_cubic2:
|
||||
if ( tag == FT_Curve_Tag_On )
|
||||
error = interface->cubic_to( &v_control, &v_control2,
|
||||
&v_first, user );
|
||||
else
|
||||
error = ErrRaster_Invalid_Outline;
|
||||
break;
|
||||
|
||||
default:
|
||||
error = ErrRaster_Invalid_Outline;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
first = last + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static
|
||||
int Move_To( FT_Vector* to,
|
||||
@ -1224,7 +900,7 @@ int check_sort( PCell cells, int count )
|
||||
|
||||
|
||||
static
|
||||
void grays_render_span( int y, int count, FT_GraySpan* spans, PRaster raster )
|
||||
void grays_render_span( int y, int count, FT_Span* spans, PRaster raster )
|
||||
{
|
||||
unsigned char *p, *q, *limit;
|
||||
FT_Bitmap* map = &raster->target;
|
||||
@ -1270,21 +946,12 @@ int check_sort( PCell cells, int count )
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static
|
||||
void grays_hline( RAS_ARG_ TScan x, TScan y, TPos area, int count )
|
||||
{
|
||||
if (area)
|
||||
fprintf( stderr, "hline( %3d, %3d, %2d, %5.2f )\n",
|
||||
y, x, count, (float)area/(2.0*ONE_PIXEL*ONE_PIXEL) );
|
||||
}
|
||||
#else
|
||||
static
|
||||
void grays_hline( RAS_ARG_ TScan x, TScan y, TPos area, int acount )
|
||||
{
|
||||
FT_GraySpan* span;
|
||||
int count;
|
||||
int coverage;
|
||||
FT_Span* span;
|
||||
int count;
|
||||
int coverage;
|
||||
|
||||
/* compute the coverage line's coverage, depending on the */
|
||||
/* outline fill rule.. */
|
||||
@ -1331,7 +998,8 @@ int check_sort( PCell cells, int count )
|
||||
if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS)
|
||||
{
|
||||
if (ras.render_span)
|
||||
ras.render_span( ras.span_y, count, ras.gray_spans, ras.render_span_closure );
|
||||
ras.render_span( ras.span_y, count, ras.gray_spans,
|
||||
ras.render_span_data );
|
||||
/* ras.render_span( span->y, ras.gray_spans, count ); */
|
||||
|
||||
#ifdef DEBUG_GRAYS
|
||||
@ -1341,7 +1009,8 @@ int check_sort( PCell cells, int count )
|
||||
fprintf( stderr, "y=%3d ", ras.span_y );
|
||||
span = ras.gray_spans;
|
||||
for (n = 0; n < count; n++, span++)
|
||||
fprintf( stderr, "[%d..%d]:%02x ", span->x, span->x + span->len-1, span->coverage );
|
||||
fprintf( stderr, "[%d..%d]:%02x ",
|
||||
span->x, span->x + span->len-1, span->coverage );
|
||||
fprintf( stderr, "\n" );
|
||||
}
|
||||
#endif
|
||||
@ -1362,7 +1031,7 @@ int check_sort( PCell cells, int count )
|
||||
ras.num_gray_spans++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static
|
||||
void grays_sweep( RAS_ARG_ FT_Bitmap* target )
|
||||
@ -1427,7 +1096,7 @@ int check_sort( PCell cells, int count )
|
||||
|
||||
if (ras.render_span && ras.num_gray_spans > 0)
|
||||
ras.render_span( ras.span_y, ras.num_gray_spans,
|
||||
ras.gray_spans, ras.render_span_closure );
|
||||
ras.gray_spans, ras.render_span_data );
|
||||
#ifdef DEBUG_GRAYS
|
||||
{
|
||||
int n;
|
||||
@ -1465,7 +1134,7 @@ int check_sort( PCell cells, int count )
|
||||
ras.num_cells = 0;
|
||||
|
||||
/* Now decompose curve */
|
||||
if ( FT_Decompose_Outline( outline, &interface, &ras ) )
|
||||
if ( FT_Outline_Decompose( outline, &interface, &ras ) )
|
||||
return 1;
|
||||
/* XXX: the error condition is in ras.error */
|
||||
|
||||
@ -1475,10 +1144,12 @@ int check_sort( PCell cells, int count )
|
||||
|
||||
|
||||
extern
|
||||
int grays_raster_render( TRaster* raster,
|
||||
FT_Outline* outline,
|
||||
FT_Bitmap* target_map )
|
||||
int grays_raster_render( PRaster raster,
|
||||
FT_Raster_Params* params )
|
||||
{
|
||||
FT_Outline* outline = (FT_Outline*)params->source;
|
||||
FT_Bitmap* target_map = params->target;
|
||||
|
||||
if ( !raster || !raster->cells || !raster->max_cells )
|
||||
return -1;
|
||||
|
||||
@ -1495,6 +1166,10 @@ int check_sort( PCell cells, int count )
|
||||
if ( !target_map || !target_map->buffer )
|
||||
return -1;
|
||||
|
||||
/* XXXX: this version does not support monochrome rendering yet ! */
|
||||
if ( !(params->flags & ft_raster_flag_aa) )
|
||||
return -1;
|
||||
|
||||
ras.outline = *outline;
|
||||
ras.target = *target_map;
|
||||
ras.num_cells = 0;
|
||||
@ -1513,49 +1188,90 @@ int check_sort( PCell cells, int count )
|
||||
check_sort( ras.cells, ras.num_cells );
|
||||
dump_cells( RAS_VAR );
|
||||
#endif
|
||||
ras.render_span = (FT_GraySpan_Func)grays_render_span;
|
||||
ras.render_span_closure = &ras;
|
||||
|
||||
ras.render_span = (FT_Raster_Span_Func)grays_render_span;
|
||||
ras.render_span_data = &ras;
|
||||
if ( params->flags & ft_raster_flag_direct )
|
||||
{
|
||||
ras.render_span = (FT_Raster_Span_Func)params->gray_spans;
|
||||
ras.render_span_data = params->user;
|
||||
}
|
||||
|
||||
grays_sweep( (PRaster)raster, target_map );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**** RASTER OBJECT CREATION : in standalone mode, we simply use *****/
|
||||
/**** a static object .. *****/
|
||||
#ifdef _STANDALONE_
|
||||
|
||||
|
||||
|
||||
|
||||
extern
|
||||
int grays_raster_init( FT_Raster raster,
|
||||
const char* pool_base,
|
||||
long pool_size )
|
||||
static
|
||||
int grays_raster_new( void* memory, FT_Raster *araster )
|
||||
{
|
||||
/* static const char default_palette[5] = { 0, 1, 2, 3, 4 }; */
|
||||
static FT_RasterRec_ the_raster;
|
||||
*araster = &the_raster;
|
||||
memset( &the_raster, sizeof(the_raster), 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check the object address */
|
||||
if ( !raster )
|
||||
return -1;
|
||||
static
|
||||
void grays_raster_done( FT_Raster raster )
|
||||
{
|
||||
/* nothing */
|
||||
(void)raster;
|
||||
}
|
||||
|
||||
/* check the render pool - we won't go under 4 Kb */
|
||||
if ( !pool_base || pool_size < 4096 )
|
||||
return -1;
|
||||
#else
|
||||
|
||||
/* save the pool */
|
||||
init_cells( (PRaster)raster, (char*)pool_base, pool_size );
|
||||
#include "ftobjs.h"
|
||||
|
||||
return 0;
|
||||
static
|
||||
int grays_raster_new( FT_Memory memory, FT_Raster* araster )
|
||||
{
|
||||
FT_Error error;
|
||||
PRaster raster;
|
||||
|
||||
*araster = 0;
|
||||
if ( !ALLOC( raster, sizeof(TRaster) ))
|
||||
{
|
||||
raster->memory = memory;
|
||||
*araster = (FT_Raster)raster;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static
|
||||
void grays_raster_done( FT_Raster raster )
|
||||
{
|
||||
FT_Memory memory = (FT_Memory)((PRaster)raster)->memory;
|
||||
FREE( raster );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
static
|
||||
void grays_raster_reset( FT_Raster raster,
|
||||
const char* pool_base,
|
||||
long pool_size )
|
||||
{
|
||||
if (raster && pool_base && pool_size >= 4096)
|
||||
init_cells( (PRaster)raster, (char*)pool_base, pool_size );
|
||||
}
|
||||
|
||||
|
||||
|
||||
FT_Raster_Interface ft_grays_raster =
|
||||
FT_Raster_Funcs ft_grays_raster =
|
||||
{
|
||||
sizeof( TRaster ),
|
||||
ft_glyph_format_outline,
|
||||
|
||||
(FT_Raster_Init_Proc) grays_raster_init,
|
||||
(FT_Raster_Set_Mode_Proc) 0,
|
||||
(FT_Raster_Render_Proc) grays_raster_render
|
||||
|
||||
(FT_Raster_New_Func) grays_raster_new,
|
||||
(FT_Raster_Reset_Func) grays_raster_reset,
|
||||
(FT_Raster_Set_Mode_Func) 0,
|
||||
(FT_Raster_Render_Func) grays_raster_render,
|
||||
(FT_Raster_Done_Func) grays_raster_done
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,78 +1,7 @@
|
||||
#ifndef FTGRAYS_H
|
||||
#define FTGRAYS_H
|
||||
|
||||
typedef int TScan;
|
||||
typedef long TPos;
|
||||
typedef float TDist;
|
||||
|
||||
#define FT_MAX_GRAY_SPANS 32
|
||||
|
||||
typedef struct FT_GraySpan_
|
||||
{
|
||||
short x;
|
||||
short len;
|
||||
unsigned char coverage;
|
||||
|
||||
} FT_GraySpan;
|
||||
|
||||
typedef int (*FT_GraySpan_Func)( int y,
|
||||
int count,
|
||||
FT_GraySpan* spans,
|
||||
void* user );
|
||||
|
||||
|
||||
typedef struct TCell_
|
||||
{
|
||||
TScan x;
|
||||
TScan y;
|
||||
int area;
|
||||
int cover;
|
||||
|
||||
} TCell, *PCell;
|
||||
|
||||
|
||||
typedef struct TRaster_
|
||||
{
|
||||
PCell cells;
|
||||
int max_cells;
|
||||
int num_cells;
|
||||
|
||||
TScan min_ex, max_ex;
|
||||
TScan min_ey, max_ey;
|
||||
|
||||
int area;
|
||||
int cover;
|
||||
int invalid;
|
||||
|
||||
TScan ex, ey;
|
||||
TScan cx, cy;
|
||||
TPos x, y;
|
||||
|
||||
TScan last_ey;
|
||||
|
||||
FT_Vector bez_stack[32*3];
|
||||
int lev_stack[32];
|
||||
|
||||
FT_Outline outline;
|
||||
FT_Bitmap target;
|
||||
|
||||
FT_GraySpan gray_spans[ FT_MAX_GRAY_SPANS ];
|
||||
int num_gray_spans;
|
||||
|
||||
FT_GraySpan_Func render_span;
|
||||
void* render_span_closure;
|
||||
int span_y;
|
||||
|
||||
} TRaster, *PRaster;
|
||||
|
||||
extern
|
||||
int grays_raster_render( TRaster* raster,
|
||||
FT_Outline* outline,
|
||||
FT_Bitmap* target_map );
|
||||
|
||||
extern
|
||||
int grays_raster_init( FT_Raster raster,
|
||||
const char* pool_base,
|
||||
long pool_size );
|
||||
extern FT_Raster_Funcs ft_grays_raster;
|
||||
|
||||
#endif
|
||||
|
@ -8,7 +8,7 @@
|
||||
/* */
|
||||
/* After writing a "perfect" anti-aliaser (see ftgrays.c), it is clear */
|
||||
/* that the standard FreeType renderer is better at generating glyph images */
|
||||
/* because it uses an approximation that simply produced more contrasted */
|
||||
/* because it uses an approximation that simply produces more contrasted */
|
||||
/* edges, making its output more legible.. */
|
||||
/* */
|
||||
/* This code is an attempt to rewrite the standard renderer in order to */
|
||||
@ -19,14 +19,22 @@
|
||||
/* of span in successive scan-lines (the standard code is forced to use */
|
||||
/* an intermediate buffer, and this is just _bad_ :-) */
|
||||
/* */
|
||||
/* */
|
||||
/* This thing works, but it's slower than the original ftraster.c, */
|
||||
/* probably because the bezier intersection code is different.. */
|
||||
/* */
|
||||
/* Note that Type 1 fonts, using a reverse fill algorithm are not */
|
||||
/* supported for now (this should come soon though..) */
|
||||
/* */
|
||||
|
||||
#include <ftimage.h>
|
||||
|
||||
#define _STANDALONE_
|
||||
|
||||
#define xxxDEBUG_GRAYS
|
||||
#define SPECIAL
|
||||
#define HORZ
|
||||
#define DEBUG_GRAYS
|
||||
#define DIRECT_BEZIER
|
||||
#define PRECISION_STEP ONE_HALF
|
||||
#define xxxDYNAMIC_BEZIER_STEPS
|
||||
|
||||
#define ErrRaster_Invalid_Outline -1
|
||||
#define ErrRaster_Overflow -2
|
||||
@ -42,6 +50,99 @@
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
typedef int TScan;
|
||||
typedef long TPos;
|
||||
typedef float TDist;
|
||||
|
||||
#define FT_MAX_GRAY_SPANS 32
|
||||
|
||||
typedef struct FT_GraySpan_
|
||||
{
|
||||
short x;
|
||||
short len;
|
||||
unsigned char coverage;
|
||||
|
||||
} FT_GraySpan;
|
||||
|
||||
typedef int (*FT_GraySpan_Func)( int y,
|
||||
int count,
|
||||
FT_GraySpan* spans,
|
||||
void* user );
|
||||
|
||||
typedef enum {
|
||||
|
||||
dir_up = 0,
|
||||
dir_down = 1,
|
||||
dir_right = 2,
|
||||
dir_left = 3,
|
||||
|
||||
dir_horizontal = 2,
|
||||
dir_reverse = 1,
|
||||
dir_silent = 4,
|
||||
|
||||
dir_unknown = 8
|
||||
|
||||
} TDir;
|
||||
|
||||
|
||||
typedef struct TCell_
|
||||
{
|
||||
unsigned short x;
|
||||
unsigned short y;
|
||||
unsigned short pos;
|
||||
TDir dir;
|
||||
|
||||
} TCell, *PCell;
|
||||
|
||||
|
||||
|
||||
typedef struct TRaster_
|
||||
{
|
||||
PCell cells;
|
||||
PCell cursor;
|
||||
PCell cell_limit;
|
||||
int max_cells;
|
||||
int num_cells;
|
||||
|
||||
TScan min_ex, max_ex;
|
||||
TScan min_ey, max_ey;
|
||||
TPos min_x, min_y;
|
||||
TPos max_x, max_y;
|
||||
|
||||
TScan ex, ey;
|
||||
TScan cx, cy;
|
||||
TPos x, y;
|
||||
|
||||
PCell contour_cell; /* first contour cell */
|
||||
|
||||
char joint;
|
||||
char horizontal;
|
||||
TDir dir;
|
||||
PCell last;
|
||||
|
||||
FT_Vector starter;
|
||||
FT_Vector* start;
|
||||
|
||||
int error;
|
||||
|
||||
FT_Vector* arc;
|
||||
FT_Vector bez_stack[32*3];
|
||||
int lev_stack[32];
|
||||
|
||||
FT_Outline outline;
|
||||
FT_Bitmap target;
|
||||
|
||||
FT_GraySpan gray_spans[ FT_MAX_GRAY_SPANS ];
|
||||
int num_gray_spans;
|
||||
|
||||
FT_GraySpan_Func render_span;
|
||||
void* render_span_closure;
|
||||
int span_y;
|
||||
|
||||
} TRaster, *PRaster;
|
||||
|
||||
|
||||
|
||||
#ifndef FT_STATIC_RASTER
|
||||
|
||||
#define RAS_ARG PRaster raster
|
||||
@ -122,8 +223,8 @@ int write_cell( RAS_ARG_ PCell cell, TPos u, TPos v, TDir dir )
|
||||
/* get rid of horizontal cells with pos == 0, they're irrelevant */
|
||||
if ( FRAC(u) == 0 ) goto Nope;
|
||||
|
||||
cell->y = TRUNC( u - ras.min_y );
|
||||
cell->x = TRUNC( v - ras.min_x );
|
||||
cell->y = (unsigned short)TRUNC( u - ras.min_y );
|
||||
cell->x = (unsigned short)TRUNC( v - ras.min_x );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -137,8 +238,8 @@ int write_cell( RAS_ARG_ PCell cell, TPos u, TPos v, TDir dir )
|
||||
/* all cells that are on the left of the clipping box are located */
|
||||
/* on the same virtual "border" cell.. */
|
||||
if (u < 0) u = -1;
|
||||
cell->x = TRUNC( u );
|
||||
cell->y = TRUNC( v );
|
||||
cell->x = (unsigned short)TRUNC( u );
|
||||
cell->y = (unsigned short)TRUNC( v );
|
||||
}
|
||||
cell->dir = dir;
|
||||
cell->pos = FRAC(u);
|
||||
@ -257,6 +358,10 @@ Exit:
|
||||
du = u2 - u1;
|
||||
dv = v2 - v1;
|
||||
|
||||
/* set the silent flag */
|
||||
if (du > dv)
|
||||
dir |= dir_silent;
|
||||
|
||||
/* compute the first scanline in "e1" */
|
||||
e1 = CEILING(v1);
|
||||
if (e1 == v1 && ras.joint)
|
||||
@ -423,6 +528,35 @@ void split_conic( FT_Vector* base )
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void split_cubic( FT_Vector* base )
|
||||
{
|
||||
TPos a, b, c, d;
|
||||
|
||||
base[6].x = base[3].x;
|
||||
c = base[1].x;
|
||||
d = base[2].x;
|
||||
base[1].x = a = ( base[0].x + c ) / 2;
|
||||
base[5].x = b = ( base[3].x + d ) / 2;
|
||||
c = ( c + d ) / 2;
|
||||
base[2].x = a = ( a + c ) / 2;
|
||||
base[4].x = b = ( b + c ) / 2;
|
||||
base[3].x = ( a + b ) / 2;
|
||||
|
||||
base[6].y = base[3].y;
|
||||
c = base[1].y;
|
||||
d = base[2].y;
|
||||
base[1].y = a = ( base[0].y + c ) / 2;
|
||||
base[5].y = b = ( base[3].y + d ) / 2;
|
||||
c = ( c + d ) / 2;
|
||||
base[2].y = a = ( a + c ) / 2;
|
||||
base[4].y = b = ( b + c ) / 2;
|
||||
base[3].y = ( a + b ) / 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef DIRECT_BEZIER
|
||||
static
|
||||
int render_conic( RAS_ARG_ TPos x1, TPos y1, TPos x2, TPos y2 )
|
||||
{
|
||||
@ -483,32 +617,6 @@ int render_conic( RAS_ARG_ TPos x1, TPos y1, TPos x2, TPos y2 )
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void split_cubic( FT_Vector* base )
|
||||
{
|
||||
TPos a, b, c, d;
|
||||
|
||||
base[6].x = base[3].x;
|
||||
c = base[1].x;
|
||||
d = base[2].x;
|
||||
base[1].x = a = ( base[0].x + c ) / 2;
|
||||
base[5].x = b = ( base[3].x + d ) / 2;
|
||||
c = ( c + d ) / 2;
|
||||
base[2].x = a = ( a + c ) / 2;
|
||||
base[4].x = b = ( b + c ) / 2;
|
||||
base[3].x = ( a + b ) / 2;
|
||||
|
||||
base[6].y = base[3].y;
|
||||
c = base[1].y;
|
||||
d = base[2].y;
|
||||
base[1].y = a = ( base[0].y + c ) / 2;
|
||||
base[5].y = b = ( base[3].y + d ) / 2;
|
||||
c = ( c + d ) / 2;
|
||||
base[2].y = a = ( a + c ) / 2;
|
||||
base[4].y = b = ( b + c ) / 2;
|
||||
base[3].y = ( a + b ) / 2;
|
||||
}
|
||||
|
||||
static
|
||||
int render_cubic( RAS_ARG_ TPos x1, TPos y1,
|
||||
TPos x2, TPos y2,
|
||||
@ -581,6 +689,390 @@ int render_cubic( RAS_ARG_ TPos x1, TPos y1,
|
||||
}
|
||||
}
|
||||
}
|
||||
#else /* !DIRECT_BEZIER */
|
||||
/* A function type describing the functions used to split bezier arcs */
|
||||
typedef void (*TSplitter)( FT_Vector* base );
|
||||
|
||||
#ifdef DYNAMIC_BEZIER_STEPS
|
||||
static
|
||||
TPos Dynamic_Bezier_Threshold( RAS_ARG_ int degree, FT_Vector* arc )
|
||||
{
|
||||
TPos min_x, max_x, min_y, max_y, A, B;
|
||||
TPos wide_x, wide_y, threshold;
|
||||
|
||||
FT_Vector* cur = arc;
|
||||
FT_Vector* limit = cur + degree;
|
||||
|
||||
/* first of all, set the threshold to the maximum x or y extent */
|
||||
min_x = max_x = arc[0].x;
|
||||
min_y = max_y = arc[0].y;
|
||||
cur++;
|
||||
for ( ; cur < limit; cur++ )
|
||||
{
|
||||
TPos x = cur->x;
|
||||
TPos y = cur->y;
|
||||
|
||||
if ( x < min_x ) min_x = x;
|
||||
if ( x > max_x ) max_x = x;
|
||||
|
||||
if ( y < min_y ) min_y = y;
|
||||
if ( y > max_y ) max_y = y;
|
||||
}
|
||||
wide_x = (max_x - min_x) << 4;
|
||||
wide_y = (max_y - min_y) << 4;
|
||||
|
||||
threshold = wide_x;
|
||||
if (threshold < wide_y) threshold = wide_y;
|
||||
|
||||
/* now compute the second and third order error values */
|
||||
|
||||
wide_x = arc[0].x + arc[1].x - arc[2].x*2;
|
||||
wide_y = arc[0].y + arc[1].y - arc[2].y*2;
|
||||
|
||||
if (wide_x < 0) wide_x = -wide_x;
|
||||
if (wide_y < 0) wide_y = -wide_y;
|
||||
|
||||
A = wide_x; if ( A < wide_y ) A = wide_y;
|
||||
|
||||
if (degree >= 3)
|
||||
{
|
||||
wide_x = arc[3].x - arc[0].x + 3*(arc[2].x - arc[3].x);
|
||||
wide_y = arc[3].y - arc[0].y + 3*(arc[2].y - arc[3].y);
|
||||
|
||||
if (wide_x < 0) wide_x = -wide_x;
|
||||
if (wide_y < 0) wide_y = -wide_y;
|
||||
|
||||
B = wide_x; if ( B < wide_y ) B = wide_y;
|
||||
}
|
||||
else
|
||||
B = 0;
|
||||
|
||||
while ( A > 0 || B > 0 )
|
||||
{
|
||||
threshold >>= 1;
|
||||
A >>= 2;
|
||||
B >>= 3;
|
||||
}
|
||||
|
||||
if (threshold < PRECISION_STEP)
|
||||
threshold = PRECISION_STEP;
|
||||
|
||||
return threshold;
|
||||
}
|
||||
#endif /* DYNAMIC_BEZIER_STEPS */
|
||||
|
||||
static
|
||||
int render_bezier( RAS_ARG_ int degree,
|
||||
TSplitter splitter,
|
||||
TPos minv,
|
||||
TPos maxv,
|
||||
TDir dir )
|
||||
{
|
||||
TPos v1, v2, u, v, e1, e2, threshold;
|
||||
int reverse;
|
||||
|
||||
FT_Vector* arc;
|
||||
FT_Vector init;
|
||||
|
||||
PCell top;
|
||||
|
||||
arc = ras.arc;
|
||||
init = arc[0];
|
||||
|
||||
arc[0].y -= ONE_HALF;
|
||||
arc[1].y -= ONE_HALF;
|
||||
arc[2].y -= ONE_HALF;
|
||||
maxv -= ONE_PIXEL;
|
||||
|
||||
top = ras.cursor;
|
||||
|
||||
/* ensure that our segment is ascending */
|
||||
v1 = arc[degree].y;
|
||||
v2 = arc[0].y;
|
||||
reverse = 0;
|
||||
if ( v2 < v1 )
|
||||
{
|
||||
TPos tmp;
|
||||
v1 = -v1;
|
||||
v2 = -v2;
|
||||
arc[0].y = v2;
|
||||
arc[1].y = -arc[1].y;
|
||||
arc[degree].y = v1;
|
||||
if (degree > 2)
|
||||
arc[2].y = -arc[2].y;
|
||||
|
||||
tmp = minv; minv = -maxv; maxv = -tmp;
|
||||
reverse = 1;
|
||||
}
|
||||
|
||||
if ( v2 < minv || v1 > maxv )
|
||||
goto Fin;
|
||||
|
||||
/* compute the first scanline in "e1" */
|
||||
e1 = CEILING(v1);
|
||||
if (e1 == v1 && ras.joint)
|
||||
e1 += ONE_PIXEL;
|
||||
|
||||
/* compute the last scanline in "e2" */
|
||||
if (v2 <= maxv)
|
||||
{
|
||||
e2 = FLOOR(v2);
|
||||
ras.joint = (v2 == e2);
|
||||
}
|
||||
else
|
||||
{
|
||||
e2 = maxv;
|
||||
ras.joint = 0;
|
||||
}
|
||||
|
||||
/* exit if the current scanline is already above the max scanline */
|
||||
if ( e2 < e1 )
|
||||
goto Fin;
|
||||
|
||||
/* check for overflow */
|
||||
if ( ( top + TRUNC(e2-e1)+1 ) >= ras.cell_limit )
|
||||
{
|
||||
ras.cursor = top;
|
||||
ras.error = ErrRaster_Overflow;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef DYNAMIC_BEZIER_STEPS
|
||||
/* compute dynamic bezier step threshold */
|
||||
threshold = Dynamic_Bezier_Threshold( RAS_VAR_ degree, arc );
|
||||
#else
|
||||
threshold = PRECISION_STEP;
|
||||
#endif
|
||||
|
||||
/* loop while there is still an arc on the bezier stack */
|
||||
/* and the current scan line is below y max == e2 */
|
||||
while ( arc >= ras.arc && e1 <= e2 )
|
||||
{
|
||||
ras.joint = 0;
|
||||
|
||||
v2 = arc[0].y; /* final y of the top-most arc */
|
||||
|
||||
if ( v2 > e1 ) /* the arc intercepts the current scanline */
|
||||
{
|
||||
v1 = arc[degree].y; /* start y of top-most arc */
|
||||
|
||||
if ( v2 >= e1 + ONE_PIXEL || v2 - v1 >= threshold )
|
||||
{
|
||||
/* if the arc's height is too great, split it */
|
||||
splitter( arc );
|
||||
arc += degree;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* otherwise, approximate it as a segment and compute */
|
||||
/* its intersection with the current scanline */
|
||||
u = arc[degree].x +
|
||||
FMulDiv( arc[0].x-arc[degree].x,
|
||||
e1 - v1,
|
||||
v2 - v1 );
|
||||
|
||||
v = e1; if (reverse) v = -e1;
|
||||
v += ONE_HALF;
|
||||
if (WRITE_CELL( top, u, v, dir ))
|
||||
top++;
|
||||
|
||||
arc -= degree; /* pop the arc */
|
||||
e1 += ONE_PIXEL; /* go to next scanline */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( v2 == e1 ) /* if the arc falls on the scanline */
|
||||
{ /* record its _joint_ intersection */
|
||||
ras.joint = 1;
|
||||
u = arc[degree].x;
|
||||
v = e1; if (reverse) v = -e1;
|
||||
v += ONE_HALF;
|
||||
if (WRITE_CELL( top, u, v, dir ))
|
||||
top++;
|
||||
|
||||
e1 += ONE_PIXEL; /* go to next scanline */
|
||||
}
|
||||
arc -= degree; /* pop the arc */
|
||||
}
|
||||
}
|
||||
|
||||
Fin:
|
||||
ras.arc[0] = init;
|
||||
ras.cursor = top;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int render_conic( RAS_ARG_ TPos x1, TPos y1, TPos x2, TPos y2 )
|
||||
{
|
||||
TPos x0, y0;
|
||||
TPos minv, maxv;
|
||||
FT_Vector* arc;
|
||||
|
||||
x0 = ras.x;
|
||||
y0 = ras.y;
|
||||
|
||||
minv = ras.min_y;
|
||||
maxv = ras.max_y;
|
||||
if (ras.horizontal)
|
||||
{
|
||||
minv = ras.min_x;
|
||||
maxv = ras.max_x;
|
||||
}
|
||||
|
||||
arc = ras.bez_stack;
|
||||
arc[2].x = ras.x; arc[2].y = ras.y;
|
||||
arc[1].x = x1; arc[1].y = y1;
|
||||
arc[0].x = x2; arc[0].y = y2;
|
||||
|
||||
do
|
||||
{
|
||||
TDir dir;
|
||||
TPos ymin, ymax;
|
||||
|
||||
y0 = arc[2].y;
|
||||
y1 = arc[1].y;
|
||||
y2 = arc[0].y;
|
||||
x2 = arc[0].x;
|
||||
|
||||
/* first, categorize the Bezier arc */
|
||||
ymin = y0;
|
||||
ymax = y2;
|
||||
if (ymin > ymax)
|
||||
{
|
||||
ymin = y2;
|
||||
ymax = y0;
|
||||
}
|
||||
|
||||
if (y1 < ymin || y1 > ymax)
|
||||
{
|
||||
/* this arc isn't y-monotonous, split it */
|
||||
split_conic( arc );
|
||||
arc += 2;
|
||||
}
|
||||
else if ( y0 == y2 )
|
||||
{
|
||||
/* this arc is flat, ignore it */
|
||||
arc -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the arc is y-monotonous, either ascending or descending */
|
||||
/* detect a change of direction */
|
||||
dir = ( y0 < y2 ) ? dir_up : dir_down;
|
||||
if (ras.horizontal) dir |= dir_horizontal;
|
||||
if (dir != ras.dir)
|
||||
{
|
||||
ras.joint = 0;
|
||||
ras.dir = dir;
|
||||
}
|
||||
|
||||
ras.arc = arc;
|
||||
if (render_bezier( RAS_VAR_ 2, split_conic, minv, maxv, dir ))
|
||||
goto Fail;
|
||||
arc -= 2;
|
||||
}
|
||||
} while ( arc >= ras.bez_stack );
|
||||
|
||||
ras.x = x2;
|
||||
ras.y = y2;
|
||||
return 0;
|
||||
Fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
int render_cubic( RAS_ARG_ TPos x1, TPos y1, TPos x2, TPos y2, TPos x3, TPos y3 )
|
||||
{
|
||||
TPos x0, y0;
|
||||
TPos minv, maxv;
|
||||
FT_Vector* arc;
|
||||
|
||||
x0 = ras.x;
|
||||
y0 = ras.y;
|
||||
|
||||
minv = ras.min_y;
|
||||
maxv = ras.max_y;
|
||||
if (ras.horizontal)
|
||||
{
|
||||
minv = ras.min_x;
|
||||
maxv = ras.max_x;
|
||||
}
|
||||
|
||||
arc = ras.bez_stack;
|
||||
arc[0].x = ras.x; arc[0].y = ras.y;
|
||||
arc[1].x = x1; arc[1].y = y1;
|
||||
arc[2].x = x2; arc[2].y = y2;
|
||||
arc[3].x = x3; arc[3].y = y3;
|
||||
|
||||
do
|
||||
{
|
||||
TDir dir;
|
||||
TPos ymin1, ymax1, ymin2, ymax2;
|
||||
|
||||
y0 = arc[3].y;
|
||||
y1 = arc[2].y;
|
||||
y2 = arc[1].y;
|
||||
y3 = arc[0].y;
|
||||
x3 = arc[0].x;
|
||||
|
||||
/* first, categorize the Bezier arc */
|
||||
ymin1 = y0;
|
||||
ymax1 = y3;
|
||||
if (ymin1 > ymax1)
|
||||
{
|
||||
ymin1 = y3;
|
||||
ymax1 = y0;
|
||||
}
|
||||
|
||||
ymin2 = y1;
|
||||
ymax2 = y2;
|
||||
if (ymin2 > ymax2)
|
||||
{
|
||||
ymin2 = y2;
|
||||
ymax2 = y1;
|
||||
}
|
||||
|
||||
if ( ymin2 < ymin1 || ymax2 > ymax1)
|
||||
{
|
||||
/* this arc isn't y-monotonous, split it */
|
||||
split_cubic( arc );
|
||||
arc += 3;
|
||||
}
|
||||
else if ( y0 == y3 )
|
||||
{
|
||||
/* this arc is flat, ignore it */
|
||||
arc -= 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the arc is y-monotonous, either ascending or descending */
|
||||
/* detect a change of direction */
|
||||
dir = ( y0 < y3 ) ? dir_up : dir_down;
|
||||
if (ras.horizontal) dir |= dir_horizontal;
|
||||
if (dir != ras.dir)
|
||||
{
|
||||
ras.joint = 0;
|
||||
ras.dir = dir;
|
||||
}
|
||||
|
||||
ras.arc = arc;
|
||||
if (render_bezier( RAS_VAR_ 3, split_cubic, minv, maxv, dir ))
|
||||
goto Fail;
|
||||
arc -= 3;
|
||||
}
|
||||
} while ( arc >= ras.bez_stack );
|
||||
|
||||
ras.x = x2;
|
||||
ras.y = y2;
|
||||
return 0;
|
||||
Fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* !DIRECT_BEZIER */
|
||||
|
||||
|
||||
static
|
||||
@ -592,8 +1084,8 @@ int is_less_than( PCell a, PCell b )
|
||||
if (a->x < b->x) goto Yes;
|
||||
if (a->x == b->x)
|
||||
{
|
||||
TDir ad = a->dir & dir_horizontal;
|
||||
TDir bd = b->dir & dir_horizontal;
|
||||
TDir ad = a->dir & (dir_horizontal|dir_silent);
|
||||
TDir bd = b->dir & (dir_horizontal|dir_silent);
|
||||
if ( ad < bd ) goto Yes;
|
||||
if ( ad == bd && a->pos < b->pos) goto Yes;
|
||||
}
|
||||
@ -1308,7 +1800,7 @@ int check_sort( PCell cells, int count )
|
||||
q = p + spans->x;
|
||||
limit = q + spans->len;
|
||||
for ( ; q < limit; q++ )
|
||||
q[0] = (spans->coverage+1) >> 1;
|
||||
q[0] = spans->coverage >> 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1364,6 +1856,8 @@ int check_sort( PCell cells, int count )
|
||||
|
||||
if (coverage)
|
||||
{
|
||||
x += ras.min_ex;
|
||||
|
||||
/* see if we can add this span to the current list */
|
||||
count = ras.num_gray_spans;
|
||||
span = ras.gray_spans + count-1;
|
||||
@ -1377,7 +1871,7 @@ int check_sort( PCell cells, int count )
|
||||
if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS)
|
||||
{
|
||||
if (ras.render_span)
|
||||
ras.render_span( ras.span_y, count, ras.gray_spans, ras.render_span_closure );
|
||||
ras.render_span( ras.min_ey + ras.span_y, count, ras.gray_spans, ras.render_span_closure );
|
||||
/* ras.render_span( span->y, ras.gray_spans, count ); */
|
||||
|
||||
#ifdef DEBUG_GRAYS
|
||||
@ -1452,32 +1946,41 @@ int check_sort( PCell cells, int count )
|
||||
/* accumulate all start cells */
|
||||
for (;;)
|
||||
{
|
||||
/* XXX : for now, only deal with vertical intersections */
|
||||
switch ((cur->dir)&3)
|
||||
#if 0
|
||||
/* we ignore silent cells for now XXXX */
|
||||
if (!(cur->dir & dir_silent))
|
||||
#endif
|
||||
{
|
||||
case dir_up:
|
||||
varea += ONE_PIXEL - cur->pos;
|
||||
if (cur->pos <= 32)
|
||||
hpos = ONE_PIXEL;
|
||||
cover++;
|
||||
numv++;
|
||||
break;
|
||||
|
||||
case dir_down:
|
||||
varea -= ONE_PIXEL - cur->pos;
|
||||
if (cur->pos <= 32)
|
||||
hpos = 0;
|
||||
cover--;
|
||||
numv++;
|
||||
break;
|
||||
switch ((cur->dir)&3)
|
||||
{
|
||||
case dir_up:
|
||||
varea += ONE_PIXEL - cur->pos;
|
||||
if (cur->pos <= 32)
|
||||
hpos = ONE_PIXEL;
|
||||
cover++;
|
||||
numv++;
|
||||
break;
|
||||
|
||||
case dir_left:
|
||||
harea += ONE_PIXEL - cur->pos;
|
||||
break;
|
||||
|
||||
default:
|
||||
harea -= ONE_PIXEL - cur->pos;
|
||||
break;
|
||||
case dir_down:
|
||||
varea -= ONE_PIXEL - cur->pos;
|
||||
if (cur->pos <= 32)
|
||||
hpos = 0;
|
||||
cover--;
|
||||
numv++;
|
||||
break;
|
||||
#if 0
|
||||
case dir_left:
|
||||
harea += ONE_PIXEL - cur->pos;
|
||||
break;
|
||||
|
||||
default:
|
||||
harea -= ONE_PIXEL - cur->pos;
|
||||
break;
|
||||
#else
|
||||
default:
|
||||
;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
++cur;
|
||||
@ -1489,15 +1992,14 @@ int check_sort( PCell cells, int count )
|
||||
if (varea < 0) varea += ONE_PIXEL;
|
||||
if (harea < 0) harea += ONE_PIXEL;
|
||||
|
||||
if (harea)
|
||||
area = varea + harea;
|
||||
else
|
||||
if (varea == 0)
|
||||
area = 2*harea;
|
||||
|
||||
else if (harea == 0)
|
||||
area = 2*varea;
|
||||
|
||||
#if 1
|
||||
if ( varea < ONE_PIXEL && harea == 0 && (icover|cover) == 0 && area < ONE_PIXEL)
|
||||
area += ONE_HALF;
|
||||
#endif
|
||||
|
||||
else
|
||||
area = (varea+harea+ONE_PIXEL) >> 1;
|
||||
|
||||
is_black = ( area >= 2*ONE_PIXEL );
|
||||
|
||||
@ -1604,19 +2106,27 @@ int check_sort( PCell cells, int count )
|
||||
/* compute vertical intersections */
|
||||
if (FT_Outline_Decompose( outline, &interface, &ras ))
|
||||
return 1;
|
||||
#if 1
|
||||
#if 0
|
||||
/* compute horizontal intersections */
|
||||
ras.horizontal = 1;
|
||||
return FT_Outline_Decompose( outline, &interface, &ras );
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern
|
||||
int grays2_raster_render( TRaster* raster,
|
||||
FT_Outline* outline,
|
||||
FT_Bitmap* target_map )
|
||||
int grays2_raster_render( PRaster raster,
|
||||
FT_Raster_Params* params )
|
||||
{
|
||||
FT_Outline* outline = (FT_Outline*)params->source;
|
||||
FT_Bitmap* target_map = params->target;
|
||||
|
||||
if ( !raster || !raster->cells || !raster->max_cells )
|
||||
return -1;
|
||||
|
||||
@ -1665,41 +2175,76 @@ int check_sort( PCell cells, int count )
|
||||
}
|
||||
|
||||
|
||||
/**** RASTER OBJECT CREATION : in standalone mode, we simply use *****/
|
||||
/**** a static object .. *****/
|
||||
#ifdef _STANDALONE_
|
||||
|
||||
static
|
||||
int grays2_raster_new( void* memory, FT_Raster *araster )
|
||||
{
|
||||
static TRaster the_raster;
|
||||
*araster = (FT_Raster)&the_raster;
|
||||
memset( &the_raster, sizeof(the_raster), 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void grays2_raster_done( FT_Raster raster )
|
||||
{
|
||||
/* nothing */
|
||||
(void)raster;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "ftobjs.h"
|
||||
|
||||
static
|
||||
int grays2_raster_new( FT_Memory memory, FT_Raster* araster )
|
||||
{
|
||||
FT_Error error;
|
||||
PRaster raster;
|
||||
|
||||
*araster = 0;
|
||||
if ( !ALLOC( raster, sizeof(TRaster) ))
|
||||
{
|
||||
raster->memory = memory;
|
||||
*araster = (FT_Raster)raster;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static
|
||||
void grays2_raster_done( FT_Raster raster )
|
||||
{
|
||||
FT_Memory memory = (FT_Memory)((PRaster)raster)->memory;
|
||||
FREE( raster );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
extern
|
||||
int grays2_raster_init( FT_Raster raster,
|
||||
static
|
||||
void grays2_raster_reset( FT_Raster raster,
|
||||
const char* pool_base,
|
||||
long pool_size )
|
||||
{
|
||||
/* static const char default_palette[5] = { 0, 1, 2, 3, 4 }; */
|
||||
|
||||
/* check the object address */
|
||||
if ( !raster )
|
||||
return -1;
|
||||
|
||||
/* check the render pool - we won't go under 4 Kb */
|
||||
if ( !pool_base || pool_size < 4096 )
|
||||
return -1;
|
||||
|
||||
/* save the pool */
|
||||
init_cells( (PRaster)raster, (char*)pool_base, pool_size );
|
||||
|
||||
return 0;
|
||||
if (raster && pool_base && pool_size >= 4096)
|
||||
init_cells( (PRaster)raster, (char*)pool_base, pool_size );
|
||||
}
|
||||
|
||||
|
||||
|
||||
FT_Raster_Interface ft_grays2_raster =
|
||||
FT_Raster_Funcs ft_grays2_raster =
|
||||
{
|
||||
sizeof( TRaster ),
|
||||
ft_glyph_format_outline,
|
||||
|
||||
(FT_Raster_Init_Proc) grays2_raster_init,
|
||||
(FT_Raster_Set_Mode_Proc) 0,
|
||||
(FT_Raster_Render_Proc) grays2_raster_render
|
||||
|
||||
(FT_Raster_New_Func) grays2_raster_new,
|
||||
(FT_Raster_Reset_Func) grays2_raster_reset,
|
||||
(FT_Raster_Set_Mode_Func) 0,
|
||||
(FT_Raster_Render_Func) grays2_raster_render,
|
||||
(FT_Raster_Done_Func) grays2_raster_done
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,102 +1,9 @@
|
||||
#ifndef FTGRAYS2_H
|
||||
#define FTGRAYS2_H
|
||||
|
||||
typedef int TScan;
|
||||
typedef long TPos;
|
||||
typedef float TDist;
|
||||
|
||||
#define FT_MAX_GRAY_SPANS 32
|
||||
|
||||
typedef struct FT_GraySpan_
|
||||
{
|
||||
short x;
|
||||
short len;
|
||||
unsigned char coverage;
|
||||
|
||||
} FT_GraySpan;
|
||||
|
||||
typedef int (*FT_GraySpan_Func)( int y,
|
||||
int count,
|
||||
FT_GraySpan* spans,
|
||||
void* user );
|
||||
|
||||
typedef enum {
|
||||
|
||||
dir_up = 0,
|
||||
dir_down = 1,
|
||||
dir_right = 2,
|
||||
dir_left = 3,
|
||||
|
||||
dir_horizontal = 2,
|
||||
dir_reverse = 1,
|
||||
|
||||
dir_unknown = 4
|
||||
|
||||
} TDir;
|
||||
|
||||
typedef struct TCell_
|
||||
{
|
||||
unsigned short x;
|
||||
unsigned short y;
|
||||
unsigned short pos;
|
||||
TDir dir;
|
||||
|
||||
} TCell, *PCell;
|
||||
|
||||
|
||||
|
||||
typedef struct TRaster_
|
||||
{
|
||||
PCell cells;
|
||||
PCell cursor;
|
||||
PCell cell_limit;
|
||||
int max_cells;
|
||||
int num_cells;
|
||||
|
||||
TScan min_ex, max_ex;
|
||||
TScan min_ey, max_ey;
|
||||
TPos min_x, min_y;
|
||||
TPos max_x, max_y;
|
||||
|
||||
TScan ex, ey;
|
||||
TScan cx, cy;
|
||||
TPos x, y;
|
||||
|
||||
PCell contour_cell; /* first contour cell */
|
||||
|
||||
char joint;
|
||||
char horizontal;
|
||||
TDir dir;
|
||||
PCell last;
|
||||
|
||||
FT_Vector starter;
|
||||
FT_Vector* start;
|
||||
|
||||
int error;
|
||||
|
||||
FT_Vector bez_stack[32*3];
|
||||
int lev_stack[32];
|
||||
|
||||
FT_Outline outline;
|
||||
FT_Bitmap target;
|
||||
|
||||
FT_GraySpan gray_spans[ FT_MAX_GRAY_SPANS ];
|
||||
int num_gray_spans;
|
||||
|
||||
FT_GraySpan_Func render_span;
|
||||
void* render_span_closure;
|
||||
int span_y;
|
||||
|
||||
} TRaster, *PRaster;
|
||||
#include <ftimage.h>
|
||||
|
||||
extern
|
||||
int grays2_raster_render( TRaster* raster,
|
||||
FT_Outline* outline,
|
||||
FT_Bitmap* target_map );
|
||||
|
||||
extern
|
||||
int grays2_raster_init( FT_Raster raster,
|
||||
const char* pool_base,
|
||||
long pool_size );
|
||||
FT_Raster_Funcs ft_grays2_raster;
|
||||
|
||||
#endif
|
||||
|
@ -78,10 +78,9 @@
|
||||
int vio_Height, vio_Width;
|
||||
|
||||
short visual; /* display glyphs while rendering */
|
||||
short gray_render; /* smooth fonts with gray levels */
|
||||
short antialias; /* smooth fonts with gray levels */
|
||||
short force_low;
|
||||
|
||||
TRaster raster;
|
||||
|
||||
#define RASTER_BUFF_SIZE 128000
|
||||
char raster_buff[ RASTER_BUFF_SIZE ];
|
||||
@ -122,7 +121,7 @@
|
||||
Bit.width = bit.width;
|
||||
Bit.pitch = bit.pitch;
|
||||
Bit.buffer = bit.buffer;
|
||||
Bit.pixel_mode = gray_render ? ft_pixel_mode_grays : ft_pixel_mode_mono;
|
||||
Bit.pixel_mode = antialias ? ft_pixel_mode_grays : ft_pixel_mode_mono;
|
||||
Bit.num_grays = bit.grays;
|
||||
Clear_Buffer();
|
||||
}
|
||||
@ -219,10 +218,7 @@
|
||||
FT_Error ConvertRaster( int index )
|
||||
{
|
||||
outlines[index].flags |= ~ft_outline_single_pass;
|
||||
if (use_grays)
|
||||
return grays_raster_render( &raster, &outlines[index], &Bit );
|
||||
else
|
||||
return FT_Outline_Get_Bitmap( library, &outlines[index], &Bit );
|
||||
return FT_Outline_Get_Bitmap( library, &outlines[index], &Bit );
|
||||
}
|
||||
|
||||
|
||||
@ -255,7 +251,7 @@
|
||||
|
||||
execname = argv[0];
|
||||
|
||||
gray_render = 0;
|
||||
antialias = 0;
|
||||
visual = 0;
|
||||
force_low = 0;
|
||||
|
||||
@ -264,7 +260,7 @@
|
||||
switch ( argv[1][1] )
|
||||
{
|
||||
case 'g':
|
||||
gray_render = 1;
|
||||
antialias = 1;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
@ -333,8 +329,12 @@
|
||||
if ( (error = FT_Init_FreeType( &library )) )
|
||||
Panic( "Error while initializing engine" );
|
||||
|
||||
error = grays_raster_init( (FT_Raster)&raster, (const char*)raster_buff, RASTER_BUFF_SIZE );
|
||||
if (error) Panic( "Could not initialize smooth anti-aliasing renderer" );
|
||||
/* set-up smooth anti-aliaser */
|
||||
if (use_grays)
|
||||
{
|
||||
error = FT_Set_Raster( library, &ft_grays_raster );
|
||||
if (error) Panic( "Could not initialize smooth anti-aliasing renderer" );
|
||||
}
|
||||
|
||||
/* Load face */
|
||||
|
||||
@ -358,7 +358,7 @@
|
||||
error = FT_Set_Pixel_Sizes( face, pixel_size, pixel_size );
|
||||
if ( error ) Panic( "Could not reset instance" );
|
||||
|
||||
bit.mode = gray_render ? gr_pixel_mode_gray : gr_pixel_mode_mono;
|
||||
bit.mode = antialias ? gr_pixel_mode_gray : gr_pixel_mode_mono;
|
||||
bit.width = 640;
|
||||
bit.rows = 480;
|
||||
bit.grays = 128;
|
||||
|
@ -59,7 +59,7 @@ $\243^\250*\265\371%!\247:/;.,?<>";
|
||||
int ptsize; /* current point size */
|
||||
|
||||
int hinted = 1; /* is glyph hinting active ? */
|
||||
int gray_render = 1; /* is anti-aliasing active ? */
|
||||
int antialias = 1; /* is anti-aliasing active ? */
|
||||
int use_sbits = 1; /* do we use embedded bitmaps ? */
|
||||
int low_prec = 1; /* force low precision */
|
||||
int Num; /* current first glyph index */
|
||||
@ -76,8 +76,9 @@ $\243^\250*\265\371%!\247:/;.,?<>";
|
||||
int render_mode = 1;
|
||||
int use_grays = 0;
|
||||
|
||||
TRaster raster;
|
||||
|
||||
/* the standard raster's interface */
|
||||
FT_Raster_Funcs std_raster;
|
||||
|
||||
#define RASTER_BUFF_SIZE 32768
|
||||
char raster_buff[ RASTER_BUFF_SIZE ];
|
||||
|
||||
@ -167,7 +168,7 @@ $\243^\250*\265\371%!\247:/;.,?<>";
|
||||
|
||||
if ( glyph->format == ft_glyph_format_outline )
|
||||
{
|
||||
pitch = ( gray_render ? (width+3) & -4 : (width+7) >> 3 );
|
||||
pitch = ( antialias ? (width+3) & -4 : (width+7) >> 3 );
|
||||
size = pitch*height;
|
||||
|
||||
if (size > MAX_BUFFER)
|
||||
@ -176,13 +177,13 @@ $\243^\250*\265\371%!\247:/;.,?<>";
|
||||
bit2.width = width;
|
||||
bit2.rows = height;
|
||||
bit2.pitch = pitch;
|
||||
bit2.pixel_mode = gray_render ? ft_pixel_mode_grays : ft_pixel_mode_mono;
|
||||
bit2.pixel_mode = antialias ? ft_pixel_mode_grays : ft_pixel_mode_mono;
|
||||
bit2.buffer = bit_buffer;
|
||||
|
||||
bit3.rows = bit2.rows;
|
||||
bit3.width = bit2.width;
|
||||
bit3.pitch = bit2.pitch;
|
||||
bit3.mode = gray_render ? bit.mode : gr_pixel_mode_mono;
|
||||
bit3.mode = antialias ? bit.mode : gr_pixel_mode_mono;
|
||||
bit3.buffer = bit_buffer;
|
||||
bit3.grays = 128;
|
||||
|
||||
@ -192,10 +193,7 @@ $\243^\250*\265\371%!\247:/;.,?<>";
|
||||
if (low_prec)
|
||||
glyph->outline.flags &= ~ft_outline_high_precision;
|
||||
|
||||
if (use_grays & gray_render)
|
||||
error = grays_raster_render( &raster, &glyph->outline, &bit2 );
|
||||
else
|
||||
error = FT_Outline_Get_Bitmap( library, &glyph->outline, &bit2 );
|
||||
error = FT_Outline_Get_Bitmap( library, &glyph->outline, &bit2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -416,6 +414,17 @@ $\243^\250*\265\371%!\247:/;.,?<>";
|
||||
grListenSurface( surface, gr_event_key, &dummy_event );
|
||||
}
|
||||
|
||||
static void reset_raster( void )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
error = 1;
|
||||
if ( use_grays && antialias )
|
||||
error = FT_Set_Raster( library, &ft_grays_raster );
|
||||
|
||||
if (error)
|
||||
(void)FT_Set_Raster( library, &std_raster );
|
||||
}
|
||||
|
||||
|
||||
static int Process_Event( grEvent* event )
|
||||
@ -429,10 +438,11 @@ $\243^\250*\265\371%!\247:/;.,?<>";
|
||||
return 0;
|
||||
|
||||
case grKEY('a'):
|
||||
gray_render = !gray_render;
|
||||
new_header = ( gray_render
|
||||
antialias = !antialias;
|
||||
new_header = ( antialias
|
||||
? "anti-aliasing is now on"
|
||||
: "anti-aliasing is now off" );
|
||||
reset_raster();
|
||||
return 1;
|
||||
|
||||
case grKEY('b'):
|
||||
@ -451,6 +461,7 @@ $\243^\250*\265\371%!\247:/;.,?<>";
|
||||
new_header = ( use_grays
|
||||
? "now using the smooth anti-aliaser"
|
||||
: "now using the standard anti-aliaser" );
|
||||
reset_raster();
|
||||
break;
|
||||
|
||||
case grKEY('l'):
|
||||
@ -598,10 +609,9 @@ $\243^\250*\265\371%!\247:/;.,?<>";
|
||||
error = FT_Init_FreeType( &library );
|
||||
if (error) PanicZ( "Could not initialise FreeType library" );
|
||||
|
||||
error = grays_raster_init( (FT_Raster)&raster, (const char*)raster_buff, RASTER_BUFF_SIZE );
|
||||
if (error) PanicZ( "Could not initialize anti-aliasing renderer" );
|
||||
/* retrieve the standard raster's interface */
|
||||
(void)FT_Get_Raster( library, ft_glyph_format_outline, &std_raster );
|
||||
|
||||
/* FT_Set_Raster_Palette( library, 17, palette_17 ); */
|
||||
|
||||
NewFile:
|
||||
ptsize = orig_ptsize;
|
||||
|
@ -736,15 +736,6 @@
|
||||
/* resolution and point-size independent data found in a font file. */
|
||||
/* */
|
||||
/* <Fields> */
|
||||
/* driver :: A handle to the face's parent driver */
|
||||
/* object. */
|
||||
/* */
|
||||
/* memory :: A handle to the face's parent memory */
|
||||
/* object. Used for the allocation of */
|
||||
/* subsequent objects. */
|
||||
/* */
|
||||
/* stream :: A handle to the face's stream. */
|
||||
/* */
|
||||
/* num_faces :: In the case where the face is located in a */
|
||||
/* collection (i.e., a resource which embeds */
|
||||
/* several faces), this is the total number of */
|
||||
@ -756,18 +747,6 @@
|
||||
/* collections (which embed several fonts in a */
|
||||
/* single resource/file). */
|
||||
/* */
|
||||
/* generic :: A field reserved for client uses. See the */
|
||||
/* FT_Generic type description. */
|
||||
/* */
|
||||
/* glyph :: The face's associated glyph slot(s). This */
|
||||
/* object is created automatically with a new */
|
||||
/* face object. However, certain kinds of */
|
||||
/* applications (mainly tools like converters) */
|
||||
/* can need more than one slot to ease their */
|
||||
/* task. */
|
||||
/* */
|
||||
/* sizes_list :: The list of child sizes for this face. */
|
||||
/* */
|
||||
/* face_flags :: A set of bit flags that give important */
|
||||
/* information about the face; see the */
|
||||
/* FT_FACE_FLAG_XXX macros for details. */
|
||||
@ -778,9 +757,6 @@
|
||||
/* */
|
||||
/* num_glyphs :: The total number of glyphs in the face. */
|
||||
/* */
|
||||
/* num_charmaps :: The total number of character maps in the */
|
||||
/* face. */
|
||||
/* */
|
||||
/* family_name :: The face's family name. This is an ASCII */
|
||||
/* string, usually in English, which describes */
|
||||
/* the typeface's family (like `Times New */
|
||||
@ -814,6 +790,19 @@
|
||||
/* NULL if the field `num_fixed_sizes' is set */
|
||||
/* to 0. */
|
||||
/* */
|
||||
/* num_charmaps :: The total number of character maps in the */
|
||||
/* face. */
|
||||
/* */
|
||||
/* charmaps :: A table of pointers to the face's charmaps */
|
||||
/* Used to scan the list of available charmaps */
|
||||
/* this table might change after a call to */
|
||||
/* FT_Attach_File/Stream (e.g. when it used */
|
||||
/* to hook and additional encoding/CMap to */
|
||||
/* the face object). */
|
||||
/* */
|
||||
/* generic :: A field reserved for client uses. See the */
|
||||
/* FT_Generic type description. */
|
||||
/* */
|
||||
/* bbox :: The font bounding box. Coordinates are */
|
||||
/* expressed in font units (see units_per_EM). */
|
||||
/* The box is large enough to contain any */
|
||||
@ -880,6 +869,24 @@
|
||||
/* underline for this face. Only relevant for */
|
||||
/* scalable formats. */
|
||||
/* */
|
||||
/* driver :: A handle to the face's parent driver */
|
||||
/* object. */
|
||||
/* */
|
||||
/* memory :: A handle to the face's parent memory */
|
||||
/* object. Used for the allocation of */
|
||||
/* subsequent objects. */
|
||||
/* */
|
||||
/* stream :: A handle to the face's stream. */
|
||||
/* */
|
||||
/* glyph :: The face's associated glyph slot(s). This */
|
||||
/* object is created automatically with a new */
|
||||
/* face object. However, certain kinds of */
|
||||
/* applications (mainly tools like converters) */
|
||||
/* can need more than one slot to ease their */
|
||||
/* task. */
|
||||
/* */
|
||||
/* sizes_list :: The list of child sizes for this face. */
|
||||
/* */
|
||||
/* max_points :: The maximum number of points used to store */
|
||||
/* the vectorial outline of any glyph in this */
|
||||
/* face. If this value cannot be known in */
|
||||
@ -894,37 +901,24 @@
|
||||
/* this should be set to 0. Only relevant for */
|
||||
/* scalable formats. */
|
||||
/* */
|
||||
/* transform_matrix :: a 2x2 matrix of 16.16 coefficients used */
|
||||
/* to transform glyph outlines after they're */
|
||||
/* loaded from the font. Only used by the */
|
||||
/* convenience functions. */
|
||||
/* */
|
||||
/* transform_delta :: a translation vector used to transform */
|
||||
/* glyph outlines after they're loaded from */
|
||||
/* the font. Only used by the convenience */
|
||||
/* functions. */
|
||||
/* */
|
||||
/* transform_flags :: some flags used to classify the transform. */
|
||||
/* Only used by the convenience functions. */
|
||||
/* */
|
||||
typedef struct FT_FaceRec_
|
||||
{
|
||||
FT_Driver driver;
|
||||
FT_Memory memory;
|
||||
FT_Stream stream;
|
||||
|
||||
FT_Long num_faces;
|
||||
FT_Long face_index;
|
||||
|
||||
/* a generic pointer for client use */
|
||||
FT_Generic generic;
|
||||
|
||||
/* the face's current glyph slot(s) */
|
||||
FT_GlyphSlot glyph;
|
||||
|
||||
/* the face's current size, may be nil */
|
||||
FT_Size size;
|
||||
|
||||
/* the face's current charmap */
|
||||
FT_CharMap charmap;
|
||||
|
||||
/* the face's table of available charmaps */
|
||||
FT_Int num_charmaps;
|
||||
FT_CharMap* charmaps;
|
||||
|
||||
/* the face's current sizes list */
|
||||
FT_ListRec sizes_list;
|
||||
|
||||
/* a pointer to the face's extensions block, if supported */
|
||||
void* extensions;
|
||||
|
||||
FT_Long face_flags;
|
||||
FT_Long style_flags;
|
||||
|
||||
@ -936,8 +930,13 @@
|
||||
FT_Int num_fixed_sizes;
|
||||
FT_Bitmap_Size* available_sizes;
|
||||
|
||||
/* the following are only relevant for scalable outlines */
|
||||
/* the face's table of available charmaps */
|
||||
FT_Int num_charmaps;
|
||||
FT_CharMap* charmaps;
|
||||
|
||||
FT_Generic generic;
|
||||
|
||||
/* the following are only relevant for scalable outlines */
|
||||
FT_BBox bbox;
|
||||
|
||||
FT_UShort units_per_EM;
|
||||
@ -951,9 +950,28 @@
|
||||
FT_Short underline_position;
|
||||
FT_Short underline_thickness;
|
||||
|
||||
/************************************************************/
|
||||
/* The following fields should be considered private and */
|
||||
/* rarely, if ever, used by client applications.. */
|
||||
|
||||
FT_Driver driver;
|
||||
FT_Memory memory;
|
||||
FT_Stream stream;
|
||||
|
||||
FT_GlyphSlot glyph;
|
||||
FT_Size size;
|
||||
FT_CharMap charmap;
|
||||
FT_ListRec sizes_list;
|
||||
|
||||
void* extensions;
|
||||
|
||||
FT_UShort max_points;
|
||||
FT_Short max_contours;
|
||||
|
||||
FT_Matrix transform_matrix;
|
||||
FT_Vector transform_delta;
|
||||
FT_Int transform_flags;
|
||||
|
||||
} FT_FaceRec;
|
||||
|
||||
|
||||
@ -1284,7 +1302,7 @@
|
||||
FT_Glyph_Metrics metrics;
|
||||
FT_Glyph_Metrics metrics2;
|
||||
|
||||
FT_Glyph_Tag format;
|
||||
FT_Glyph_Format format;
|
||||
FT_Bitmap bitmap;
|
||||
FT_Outline outline;
|
||||
|
||||
@ -1347,6 +1365,28 @@
|
||||
FT_Error FT_Done_FreeType( FT_Library library );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Stream_Type */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* An enumeration used to list the possible ways to open a new */
|
||||
/* input stream. It is used by the FT_Open_Args structure.. */
|
||||
/* */
|
||||
/* <Fields> */
|
||||
/* ft_stream_memory :: this is a memory-based stream */
|
||||
/* ft_stream_copy :: copy the stream from the "stream" field */
|
||||
/* ft_stream_pathname :: create a new input stream from a C pathname */
|
||||
/* */
|
||||
typedef enum {
|
||||
|
||||
ft_stream_memory = 1,
|
||||
ft_stream_copy = 2,
|
||||
ft_stream_pathname = 3
|
||||
|
||||
} FT_Stream_Type;
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* <Struct>
|
||||
@ -1358,6 +1398,8 @@
|
||||
* function FT_Open_Face & FT_Attach_Stream.
|
||||
*
|
||||
* <Fields>
|
||||
* stream_type :: type of input stream
|
||||
*
|
||||
* memory_base :: first byte of file in memory
|
||||
* memory_size :: size in bytes of file in memory
|
||||
*
|
||||
@ -1371,28 +1413,30 @@
|
||||
* the face with each one of the drivers in its list.
|
||||
*
|
||||
* <Note>
|
||||
* Here's how a new input stream is built from a FT_Open_Args
|
||||
* structure:
|
||||
* The stream_type determines which fields are used to create a new
|
||||
* input stream.
|
||||
*
|
||||
* a/ if 'memory_base' and 'memory_size' are non-null, create a
|
||||
* memory-based stream from the indicated address and length.
|
||||
* If it is ft_stream_memory, a new memory-based stream will be created
|
||||
* using the memory block specified by "memory_base" and "memory_size"
|
||||
*
|
||||
* b/ Otherwise, if 'pathname' is non NULL, use it to build a
|
||||
* new system-specific stream (by calling FT_New_Stream)
|
||||
* If it is ft_stream_pathname, a new stream will be created with the
|
||||
* "pathname" field, calling the system-specific FT_New_Stream function
|
||||
*
|
||||
* c/ Otherwise, if 'stream' is non NULL, use it to access the
|
||||
* font file (note that a new FT_Stream object will be created
|
||||
* where the contents of 'stream' will be copied).
|
||||
* It is is ft_stream_copy, then the content of "stream" will be copied
|
||||
* to a new input stream object. The object will be closed and destroyed
|
||||
* when the face is destroyed itself.. Note that this means that you
|
||||
* should not close the stream before the library does !!
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
typedef struct FT_Open_Args_
|
||||
{
|
||||
FT_Byte* memory_base;
|
||||
FT_Long memory_size;
|
||||
FT_String* pathname;
|
||||
FT_Stream stream;
|
||||
FT_Driver driver;
|
||||
FT_Stream_Type stream_type;
|
||||
FT_Byte* memory_base;
|
||||
FT_Long memory_size;
|
||||
FT_String* pathname;
|
||||
FT_Stream stream;
|
||||
FT_Driver driver;
|
||||
|
||||
} FT_Open_Args;
|
||||
|
||||
@ -1565,46 +1609,6 @@
|
||||
FT_Error FT_Done_Face( FT_Face face );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_New_Size */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Creates a new size object from a given face object. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* face :: A handle to a parent face object. */
|
||||
/* */
|
||||
/* <Output> */
|
||||
/* size :: A handle to a new size object. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Error code. 0 means success. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_New_Size( FT_Face face,
|
||||
FT_Size* size );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Done_Size */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Discards a given size object. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* size :: A handle to a target size object */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Error code. 0 means success. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Done_Size( FT_Size size );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
@ -1657,48 +1661,6 @@
|
||||
FT_UInt pixel_height );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_New_GlyphSlot */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* It is sometimes useful to have more than one glyph slot for a */
|
||||
/* given face object. This function is used to create additional */
|
||||
/* slots. All of them are automatically discarded when the face is */
|
||||
/* destroyed. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* face :: A handle to a parent face object. */
|
||||
/* */
|
||||
/* <Output> */
|
||||
/* slot :: A handle to a new glyph slot object. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Error code. 0 means success. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_New_GlyphSlot( FT_Face face,
|
||||
FT_GlyphSlot* aslot );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Done_GlyphSlot */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Destroys a given glyph slot. Remember however that all slots are */
|
||||
/* automatically destroyed with its parent. Using this function is */
|
||||
/* not always mandatory. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* slot :: A handle to a target glyph slot. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
void FT_Done_GlyphSlot( FT_GlyphSlot slot );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
@ -1875,7 +1837,11 @@
|
||||
/* the values of `num_subglyphs' and `subglyphs', as well as set */
|
||||
/* `face->glyph.format' to ft_glyph_format_composite. */
|
||||
/* */
|
||||
/* XXXXX : IMPORTANT NOTE, THIS FLAG IS NOT YET IMPLEMENTED !! */
|
||||
/* This is for use by the auto-hinter and possibly other tools */
|
||||
/* For nearly all applications, this flags should be left unset */
|
||||
/* when invoking FT_Load_Glyph(). */
|
||||
/* */
|
||||
/* Note that the flag forces the load of unscaled glyphs */
|
||||
/* */
|
||||
#define FT_LOAD_NO_RECURSE 1024
|
||||
|
||||
@ -1893,36 +1859,6 @@
|
||||
#define FT_LOAD_DEFAULT 0
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Get_Glyph_Bitmap */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Renders a given glyph into a bitmap or pixmap. This function will */
|
||||
/* use the registered rasters to render the glyph image. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* face :: handle to the face object whose glyph slot contains */
|
||||
/* the glyph image */
|
||||
/* map :: A pointer to the target bitmap descriptor. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* YES. Rendering is synchronized, so that concurrent calls to the */
|
||||
/* scan-line converter will be serialized. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* This function does NOT CREATE the bitmap, it only renders a */
|
||||
/* glyph image into it! */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Get_Glyph_Bitmap( FT_Face face,
|
||||
FT_Bitmap* map );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
@ -2084,6 +2020,75 @@
|
||||
FT_Long b );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Get_Bitmap */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Renders an outline within a bitmap. The outline's image is simply */
|
||||
/* or-ed to the target bitmap. */
|
||||
/* */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* library :: A handle to a FreeType library object. */
|
||||
/* outline :: A pointer to the source outline descriptor. */
|
||||
/* map :: A pointer to the target bitmap descriptor. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* YES. Rendering is synchronized, so that concurrent calls to the */
|
||||
/* scan-line converter will be serialized. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* This function does NOT CREATE the bitmap, it only renders an */
|
||||
/* outline image within the one you pass to it! */
|
||||
/* */
|
||||
/* It will use the raster correponding to the default glyph format. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Outline_Get_Bitmap( FT_Library library,
|
||||
FT_Outline* outline,
|
||||
FT_Bitmap* map );
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Render */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Renders an outline within a bitmap using the current scan-convert */
|
||||
/* This functions uses a FT_Raster_Params as argument, allowing */
|
||||
/* advanced features like direct composition/translucency, etc.. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* library :: A handle to a FreeType library object. */
|
||||
/* outline :: A pointer to the source outline descriptor. */
|
||||
/* params :: A pointer to a FT_Raster_Params used to describe */
|
||||
/* the rendering operation */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* YES. Rendering is synchronized, so that concurrent calls to the */
|
||||
/* scan-line converter will be serialized. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* You should know what you're doing and the role of FT_Raster_Params */
|
||||
/* to use this function. */
|
||||
/* */
|
||||
/* the field "params.source" will be set to "outline" before the */
|
||||
/* scan converter is called, which means that the value you give it */
|
||||
/* is actually ignored.. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Outline_Render( FT_Library library,
|
||||
FT_Outline* outline,
|
||||
FT_Raster_Params* params );
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
@ -2211,15 +2216,12 @@
|
||||
/* <Output> */
|
||||
/* cbox :: The outline's control box. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* Yes. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Outline_Get_CBox( FT_Outline* outline,
|
||||
FT_BBox* cbox );
|
||||
void FT_Outline_Get_CBox( FT_Outline* outline,
|
||||
FT_BBox* cbox );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
@ -2253,23 +2255,79 @@
|
||||
/* Register a given raster to the library. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* library :: A handle to a target library object. */
|
||||
/* */
|
||||
/* interface :: pointer to the raster's interface */
|
||||
/* */
|
||||
/* raster :: if this field is nil, this function will allocate */
|
||||
/* a new objet. Otherwise, it will simply use the one */
|
||||
/* provided here. */
|
||||
/* <Return> */
|
||||
/* Error code. 0 means success. */
|
||||
/* library :: A handle to a target library object. */
|
||||
/* raster_funcs :: pointer to the raster's interface */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Error code. 0 means success. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* This function will do the following: */
|
||||
/* */
|
||||
/* - a new raster object is created through raster_func.raster_new */
|
||||
/* if this fails, then the function returns */
|
||||
/* */
|
||||
/* - if a raster is already registered for the glyph format */
|
||||
/* specified in raster_funcs, it will be destroyed */
|
||||
/* */
|
||||
/* - the new raster is registered for the glyph format */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Set_Raster( FT_Library library,
|
||||
FT_Raster_Interface* interface,
|
||||
FT_Raster raster );
|
||||
FT_Error FT_Set_Raster( FT_Library library,
|
||||
FT_Raster_Funcs* raster_funcs );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Unset_Raster */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Removes a given raster from the library. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* library :: A handle to a target library object. */
|
||||
/* raster_funcs :: pointer to the raster's interface */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Error code. 0 means success. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* This function should never be used by a normal client application */
|
||||
/* as FT_Set_Raster unregisters the previous raster for a given */
|
||||
/* glyph format.. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Unset_Raster( FT_Library library,
|
||||
FT_Raster_Funcs* raster_funcs );
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* FT_Get_Raster
|
||||
*
|
||||
* <Description>
|
||||
* Return a pointer to the raster corresponding to a given glyph
|
||||
* format tag.
|
||||
*
|
||||
* <Input>
|
||||
* library :: handle to source library object
|
||||
* glyph_format :: glyph format tag
|
||||
*
|
||||
* <Output>
|
||||
* raster_funcs :: if this field is not 0, returns a pointer to the
|
||||
* raster's interface/descriptor..
|
||||
*
|
||||
* <Return>
|
||||
* a pointer to the corresponding raster object.
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
EXPORT_DEF
|
||||
FT_Raster FT_Get_Raster( FT_Library library,
|
||||
FT_Glyph_Format glyph_format,
|
||||
FT_Raster_Funcs *raster_funcs );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
@ -2289,12 +2347,163 @@
|
||||
/* Error code. 0 means success. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Set_Raster_Mode( FT_Library library,
|
||||
FT_Glyph_Tag format,
|
||||
const char* mode,
|
||||
const char* args );
|
||||
FT_Error FT_Set_Raster_Mode( FT_Library library,
|
||||
FT_Glyph_Format format,
|
||||
const char* mode,
|
||||
void* args );
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
/***** *****/
|
||||
/***** C O N V E N I E N C E F U N C T I O N S *****/
|
||||
/***** *****/
|
||||
/***** *****/
|
||||
/***** The following functions are provided as a convenience *****/
|
||||
/***** to client applications. However, their compilation might *****/
|
||||
/***** be discarded if FT_CONFIG_OPTION_NO_CONVENIENCE_FUNCS *****/
|
||||
/***** is defined in "config/ftoption.h". *****/
|
||||
/***** *****/
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Copy */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Copies an outline into another one. Both objects must have the */
|
||||
/* same sizes (number of points & number of contours) when this */
|
||||
/* function is called. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* source :: A handle to the source outline. */
|
||||
/* target :: A handle to the target outline. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Outline_Copy( FT_Outline* source,
|
||||
FT_Outline* target );
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Transform */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Applies a simple 2x2 matrix to all of an outline's points. Useful */
|
||||
/* for applying rotations, slanting, flipping, etc. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* outline :: A pointer to the target outline descriptor. */
|
||||
/* matrix :: A pointer to the transformation matrix. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* Yes. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* You can use FT_Outline_Translate() if you need to translate the */
|
||||
/* outline's points. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
void FT_Outline_Transform( FT_Outline* outline,
|
||||
FT_Matrix* matrix );
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Reverse */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Reverse the drawing direction of an outline. This is used to */
|
||||
/* ensure consistent fill conventions for mirrored glyphs.. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* outline :: A pointer to the target outline descriptor. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* This functions toggles the bit flag ft_outline_reverse_fill in */
|
||||
/* the outline's "flags" field.. */
|
||||
/* */
|
||||
/* It shouldn't be used by a normal client application, unless it */
|
||||
/* knows what it's doing.. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
void FT_Outline_Reverse( FT_Outline* outline );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Vector_Transform */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Transforms a single vector through a 2x2 matrix. */
|
||||
/* */
|
||||
/* <InOut> */
|
||||
/* vector :: The target vector to transform */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* matrix :: A pointer to the source 2x2 matrix. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* Yes. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
void FT_Vector_Transform( FT_Vector* vector,
|
||||
FT_Matrix* matrix );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Matrix_Multiply */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Performs the matrix operation `b = a*b'. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* a :: A pointer to matrix `a'. */
|
||||
/* */
|
||||
/* <InOut> */
|
||||
/* b :: A pointer to matrix `b'. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* Yes. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
void FT_Matrix_Multiply( FT_Matrix* a,
|
||||
FT_Matrix* b );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Matrix_Invert */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Inverts a 2x2 matrix. Returns an error if it can't be inverted. */
|
||||
/* */
|
||||
/* <InOut> */
|
||||
/* matrix :: A pointer to the target matrix. Remains untouched in */
|
||||
/* case of error. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* Yes. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Matrix_Invert( FT_Matrix* matrix );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
320
include/ftglyph.h
Normal file
320
include/ftglyph.h
Normal file
@ -0,0 +1,320 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftglyph.h */
|
||||
/* */
|
||||
/* FreeType convenience functions to handle glyphs.. */
|
||||
/* */
|
||||
/* Copyright 1996-1999 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. */
|
||||
/* */
|
||||
/* This file contains the definition of several convenience functions */
|
||||
/* that can be used by client applications to easily retrieve glyph */
|
||||
/* bitmaps and outlines from a given face. */
|
||||
/* */
|
||||
/* These functions should be optional if you're writing a font server */
|
||||
/* or text layout engine on top of FreeType. However, they are pretty */
|
||||
/* handy for many other simple uses of the library.. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
#ifndef FTGLYPH_H
|
||||
#define FTGLYPH_H
|
||||
|
||||
#include <freetype.h>
|
||||
|
||||
typedef enum {
|
||||
|
||||
ft_glyph_type_none = 0,
|
||||
ft_glyph_type_bitmap = 1,
|
||||
ft_glyph_type_outline = 2
|
||||
|
||||
} FT_GlyphType;
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* <Struct>
|
||||
* FT_GlyphRec
|
||||
*
|
||||
* <Description>
|
||||
* The root glyph structure contains a given glyph image's metrics.
|
||||
* Note that the FT_Glyph type is a pointer to FT_GlyphRec
|
||||
*
|
||||
* <Field>
|
||||
* memory :: a handle to the memory allocator that is used to
|
||||
* create/clone/destroy this glyph..
|
||||
*
|
||||
* glyph_type :: the glyph type..
|
||||
*
|
||||
* height :: height of glyph image
|
||||
* width :: width of glyph image
|
||||
*
|
||||
* bearingX :: horizontal bearing, this is the distance from the
|
||||
* the current pen position to the left of the glyph
|
||||
*
|
||||
* bearingY :: vertical bearing, this is the distance from the
|
||||
* current pen position to the top of the glyph
|
||||
*
|
||||
* advance :: this is the horizontal or vertical advance for the
|
||||
* glyph
|
||||
*
|
||||
* <Note>
|
||||
* the distances expressed in the metrics are expressed in 26.6 fixed
|
||||
* float sub-pixels (i.e. 1/64th of pixels).
|
||||
*
|
||||
* the vertical bearing has a positive value when the glyph top is
|
||||
* above the baseline, and negative when it is under..
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
typedef struct FT_GlyphRec_
|
||||
{
|
||||
FT_Memory memory;
|
||||
FT_GlyphType glyph_type;
|
||||
FT_Int height;
|
||||
FT_Int width;
|
||||
FT_Int bearingX;
|
||||
FT_Int bearingY;
|
||||
FT_Int advance;
|
||||
|
||||
} FT_GlyphRec, *FT_Glyph;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* <Struct>
|
||||
* FT_BitmapGlyphRec
|
||||
*
|
||||
* <Description>
|
||||
* A structure used to describe a bitmap glyph image..
|
||||
* Note that the FT_BitmapGlyph type is a pointer to FT_BitmapGlyphRec
|
||||
*
|
||||
* <Field>
|
||||
* metrics :: the corresponding glyph metrics
|
||||
* bitmap :: a descriptor for the bitmap.
|
||||
*
|
||||
* <Note>
|
||||
* the "width" and "height" fields of the metrics are expressed in
|
||||
* 26.6 sub-pixels. However, the width and height in pixels can be
|
||||
* read directly from "bitmap.width" and "bitmap.height"
|
||||
*
|
||||
* this structure is used for both monochrome and anti-aliased
|
||||
* bitmaps (the bitmap descriptor contains field describing the
|
||||
* format of the pixel buffer)
|
||||
*
|
||||
* the corresponding pixel buffer is always owned by the BitmapGlyph
|
||||
* and is thus creatde and destroyed with it..
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
typedef struct FT_BitmapGlyphRec_
|
||||
{
|
||||
FT_GlyphRec metrics;
|
||||
FT_Int left;
|
||||
FT_Int top;
|
||||
FT_Bitmap bitmap;
|
||||
|
||||
} FT_BitmapGlyphRec_, *FT_BitmapGlyph;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* <Struct>
|
||||
* FT_OutlineGlyphRec
|
||||
*
|
||||
* <Description>
|
||||
* A structure used to describe a vectorial outline glyph image..
|
||||
* Note that the FT_OutlineGlyph type is a pointer to FT_OutlineGlyphRec
|
||||
*
|
||||
* <Field>
|
||||
* metrics :: the corresponding glyph metrics
|
||||
* outline :: a descriptor for the outline
|
||||
*
|
||||
* <Note>
|
||||
* the "width" and "height" fields of the metrics are expressed in
|
||||
* 26.6 sub-pixels. However, the width and height in pixels can be
|
||||
* read directly from "bitmap.width" and "bitmap.rows"
|
||||
*
|
||||
* the corresponding outline points tables is always owned by the
|
||||
* object and are destroyed with it..
|
||||
*
|
||||
* an OutlineGlyph can be used to generate a BitmapGlyph with the
|
||||
* function FT_OutlineGlyph_Render()
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
typedef struct FT_OutlineGlyphRec_
|
||||
{
|
||||
FT_GlyphRec metrics;
|
||||
FT_Outline outline;
|
||||
|
||||
} FT_OutlineGlyphRec_, *FT_OutlineGlyph;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* FT_Get_Glyph_Bitmap
|
||||
*
|
||||
* <Description>
|
||||
* A function used to directly return a monochrome bitmap glyph image
|
||||
* from a face.
|
||||
*
|
||||
* <Input>
|
||||
* face :: handle to source face object
|
||||
* glyph_index :: glyph index in face
|
||||
* load_flags :: load flags, see FT_LOAD_FLAG_XXXX constants..
|
||||
* grays :: number of gray levels for anti-aliased bitmaps,
|
||||
* set to 0 if you want to render a monochrome bitmap
|
||||
* origin :: a pointer to the origin's position. Set to 0
|
||||
* if the current transform is the identity..
|
||||
*
|
||||
* <Output>
|
||||
* bitglyph :: pointer to the new bitmap glyph
|
||||
*
|
||||
* <Return>
|
||||
* Error code. 0 means success.
|
||||
*
|
||||
* <Note>
|
||||
* If the font contains glyph outlines, these will be automatically
|
||||
* converted to a bitmap according to the value of "grays"
|
||||
*
|
||||
* If "grays" is set to 0, the result is a 1-bit monochrome bitmap
|
||||
* otherwise, it is an 8-bit gray-level bitmap
|
||||
*
|
||||
* The number of gray levels in the result anti-aliased bitmap might
|
||||
* not be "grays", depending on the current scan-converter implementation
|
||||
*
|
||||
* Note that it is not possible to generate 8-bit monochrome bitmaps
|
||||
* with this function. Rather, use FT_Get_Glyph_Outline, then
|
||||
* FT_Glyph_Render_Outline and provide your own span callbacks..
|
||||
*
|
||||
* When the face doesn't contain scalable outlines, this function will
|
||||
* fail if the current transform is not the identity, or if the glyph
|
||||
* origin's phase to the pixel grid is not 0 in both directions !!
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Get_Glyph_Bitmap( FT_Face face,
|
||||
FT_UInt glyph_index,
|
||||
FT_UInt load_flags,
|
||||
FT_Int grays,
|
||||
FT_Vector* origin,
|
||||
FT_BitmapGlyph *abitglyph );
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* FT_Get_Glyph_Outline
|
||||
*
|
||||
* <Description>
|
||||
* A function used to directly return a bitmap glyph image from a
|
||||
* face. This is faster than calling FT_Load_Glyph+FT_Get_Outline_Bitmap..
|
||||
*
|
||||
* <Input>
|
||||
* face :: handle to source face object
|
||||
* glyph_index :: glyph index in face
|
||||
* load_flags :: load flags, see FT_LOAD_FLAG_XXXX constants..
|
||||
*
|
||||
* <Output>
|
||||
* vecglyph :: pointer to the new outline glyph
|
||||
*
|
||||
* <Return>
|
||||
* Error code. 0 means success.
|
||||
*
|
||||
* <Note>
|
||||
* If the glyph is not an outline in the face, this function will
|
||||
* fail..
|
||||
*
|
||||
* This function will fail if the load flags FT_LOAD_NO_OUTLINE and
|
||||
* FT_LOAD_NO_RECURSE are set..
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Get_Glyph_Outline( FT_Face face,
|
||||
FT_UInt glyph_index,
|
||||
FT_UInt load_flags,
|
||||
FT_OutlineGlyph *vecglyph );
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* FT_Set_Transform
|
||||
*
|
||||
* <Description>
|
||||
* A function used to set the transform that is applied to glyph images
|
||||
* just after they're loaded in the face's glyph slot, and before they're
|
||||
* returned by either FT_Get_Glyph_Bitmap or FT_Get_Glyph_Outline
|
||||
*
|
||||
* <Input>
|
||||
* face :: handle to source face object
|
||||
* matrix :: pointer to the transform's 2x2 matrix. 0 for identity
|
||||
* delta :: pointer to the transform's translation. 0 for null vector
|
||||
*
|
||||
* <Note>
|
||||
* The transform is only applied to glyph outlines when they are found
|
||||
* in a font face. It is unable to transform embedded glyph bitmaps
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
EXPORT_DEF
|
||||
void FT_Set_Transform( FT_Face face,
|
||||
FT_Matrix* matrix,
|
||||
FT_Vector* delta );
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* FT_Done_Glyph
|
||||
*
|
||||
* <Description>
|
||||
* Destroys a given glyph..
|
||||
*
|
||||
* <Input>
|
||||
* glyph :: handle to target glyph object
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
EXPORT_DEF
|
||||
void FT_Done_Glyph( FT_Glyph glyph );
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* FT_Glyph_Get_Box
|
||||
*
|
||||
* <Description>
|
||||
* Returns the glyph image's bounding box in pixels.
|
||||
*
|
||||
* <Input>
|
||||
* glyph :: handle to target glyph object
|
||||
*
|
||||
* <Output>
|
||||
* box :: the glyph bounding box. Coordinates are expressed in
|
||||
* _integer_ pixels, with exclusive max bounds
|
||||
*
|
||||
* <Note>
|
||||
* Coordinates are relative to the glyph origin, using the Y-upwards
|
||||
* convention..
|
||||
*
|
||||
* The width of the box in pixels is box.xMax-box.xMin
|
||||
* The height is box.yMax - box.yMin
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
EXPORT_DEF
|
||||
void FT_Glyph_Get_Box( FT_Glyph glyph,
|
||||
FT_BBox *box );
|
||||
|
||||
#endif /* FTGLYPH_H */
|
@ -470,8 +470,6 @@
|
||||
} FT_Outline_Funcs;
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Macro> */
|
||||
@ -491,7 +489,7 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* <Enum>
|
||||
* FT_Glyph_Tag
|
||||
* FT_Glyph_Format
|
||||
*
|
||||
* <Description>
|
||||
* An enumeration type used to describethe format of a given glyph
|
||||
@ -518,7 +516,7 @@
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
typedef enum FT_Glyph_Tag_
|
||||
typedef enum FT_Glyph_Format_
|
||||
{
|
||||
ft_glyph_format_none = 0,
|
||||
ft_glyph_format_composite = FT_IMAGE_TAG('c','o','m','p'),
|
||||
@ -526,8 +524,28 @@
|
||||
ft_glyph_format_outline = FT_IMAGE_TAG('o','u','t','l'),
|
||||
ft_glyph_format_plotter = FT_IMAGE_TAG('p','l','o','t')
|
||||
|
||||
} FT_Glyph_Tag;
|
||||
} FT_Glyph_Format;
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** R A S T E R D E F I N I T I O N S *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
@ -543,126 +561,374 @@
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <FuncType> */
|
||||
/* FT_Raster_Init_Proc */
|
||||
/* <Struct> */
|
||||
/* FT_Span */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Initializes a fresh raster object which should have been allocated */
|
||||
/* by client applications. This function is also used to set the */
|
||||
/* object's render pool. It can be used repeatedly on a single */
|
||||
/* object if one wants to change the pool's address or size. */
|
||||
/* A structure used to model a single span of gray (or black) pixels */
|
||||
/* when rendering a monocrhome or anti-aliased bitmap. */
|
||||
/* */
|
||||
/* Note that the render pool has no state and is only used during a */
|
||||
/* call to FT_Raster_Render(). It is thus theorically possible to */
|
||||
/* share it between several non-concurrent components of your */
|
||||
/* applications when memory is a scarce resource. */
|
||||
/* <Fields> */
|
||||
/* x :: the span's horizontal start position */
|
||||
/* len :: the span's length in pixels */
|
||||
/* coverage :: the span color/coverage, ranging from 0 (background) */
|
||||
/* to 255 (foreground). Only used for anti-aliased */
|
||||
/* rendering.. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* raster :: a handle to the target raster object. */
|
||||
/* pool_base :: the render pool's base address in memory */
|
||||
/* pool_size :: the render pool's size in bytes. this must be at */
|
||||
/* least 4 kByte. */
|
||||
/* <Return> */
|
||||
/* An error condition, used as a FT_Error in the FreeType library. */
|
||||
/* 0 means success. */
|
||||
/* <Note> */
|
||||
/* This structure is used by the span drawing callback type */
|
||||
/* named FT_Raster_Span_Func, which takes the y coordinate of the */
|
||||
/* span as a paremeter.. */
|
||||
/* */
|
||||
typedef int (*FT_Raster_Init_Proc)( FT_Raster raster,
|
||||
const char* pool_base,
|
||||
long pool_size );
|
||||
/* The coverage value is always between 0 and 255, even if the */
|
||||
/* number of gray levels have been set through FT_Set_Gray_Levels() */
|
||||
/* */
|
||||
typedef struct FT_Span_
|
||||
{
|
||||
short x;
|
||||
short len;
|
||||
unsigned char coverage;
|
||||
|
||||
} FT_Span;
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <FuncType> */
|
||||
/* FT_Raster_Set_Mode_Proc */
|
||||
/* FT_Raster_Span_Func */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Some raster implementations may have several modes of operation. */
|
||||
/* This function is used to select one of them, as well as pass some */
|
||||
/* arguments. */
|
||||
/* A function used as a call-back by the anti-aliased renderer in */
|
||||
/* order to let client applications draw themselves the gray pixel */
|
||||
/* spans on each scan line. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* raster :: The target raster object. */
|
||||
/* y :: the scanline's y coordinate */
|
||||
/* count :: the number of spans to draw on this scanline */
|
||||
/* spans :: a table of 'count' spans to draw on the scanline */
|
||||
/* user :: user-supplied data that is passed to the callback */
|
||||
/* */
|
||||
/* mode :: A pointer used to describe the mode to set. This is */
|
||||
/* completely raster-specific, and could be, for example, */
|
||||
/* a text string. */
|
||||
/* <Note> */
|
||||
/* This callback allows client applications to directly render the */
|
||||
/* gray spans of the anti-aliased bitmap to any kind of surfaces. */
|
||||
/* */
|
||||
/* args :: An argument to the set_mode command. This is completely */
|
||||
/* specific to the raster and the mode used. */
|
||||
/* This can be used to write anti-aliased outlines directly to a */
|
||||
/* given background bitmap, and even perform translucency.. */
|
||||
/* */
|
||||
/* Note that the "count" field cannot be greater than a fixed value */
|
||||
/* defined by the FT_MAX_GRAY_SPANS configuration macro in ftoption.h */
|
||||
/* */
|
||||
/* By default, this value is set to 32, which means that if there are */
|
||||
/* more than 32 spans on a given scanline, the callback will be called */
|
||||
/* several times with the same "y" parameter in order to draw all */
|
||||
/* callbacks.. */
|
||||
/* */
|
||||
/* Otherwise, the callback is only called once per scan-line, and */
|
||||
/* only for those scanlines that do have "gray" pixels on them.. */
|
||||
/* */
|
||||
typedef void (*FT_Raster_Span_Func)( int y,
|
||||
int count,
|
||||
FT_Span* spans,
|
||||
void* user );
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <FuncType> */
|
||||
/* FT_Raster_BitTest_Func */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* A function used as a call-back by the monochrome scan-converter */
|
||||
/* to test wether a given target pixel is already set to the drawing */
|
||||
/* "color". These tests are crucial to implement drop-out control */
|
||||
/* per-se the TrueType spec.. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* y :: the pixel's y coordinate */
|
||||
/* x :: the pixel's x coordinate */
|
||||
/* user :: user-supplied data that is passed to the callback */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* An error code, used as a FT_Error by the FreeType library. */
|
||||
/* 0 means success. */
|
||||
/* 1 if the pixel is "set", 0 otherwise */
|
||||
/* */
|
||||
typedef int (*FT_Raster_Set_Mode_Proc)( FT_Raster raster,
|
||||
typedef int (*FT_Raster_BitTest_Func)( int y,
|
||||
int x,
|
||||
void* user );
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <FuncType> */
|
||||
/* FT_Raster_BitSet_Func */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* A function used as a call-back by the monochrome scan-converter */
|
||||
/* used to set an individual target pixel. This is crucial to */
|
||||
/* implement drop-out control per-se the TrueType spec.. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* y :: the pixel's y coordinate */
|
||||
/* x :: the pixel's x coordinate */
|
||||
/* user :: user-supplied data that is passed to the callback */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* 1 if the pixel is "set", 0 otherwise */
|
||||
/* */
|
||||
typedef void (*FT_Raster_BitSet_Func)( int y,
|
||||
int x,
|
||||
void* user );
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* <Enum>
|
||||
* FT_Raster_Flag
|
||||
*
|
||||
* <Description>
|
||||
* An enumeration used to list the bit flags used in the "flags"
|
||||
* field of a FT_Raster_Params function.
|
||||
*
|
||||
* <Fields>
|
||||
* ft_raster_flag_default :: this value is 0
|
||||
*
|
||||
* ft_raster_flag_aa :: resquests the rendering of an anti-aliased
|
||||
* glyph bitmap. If unset, a monchrome bitmap
|
||||
* will be rendered.
|
||||
*
|
||||
* ft_raster_flag_direct :: requests direct rendering over the target
|
||||
* bitmap. Direct rendering uses user-provided
|
||||
* callbacks in order to perform direct
|
||||
* drawing or composition over an existing
|
||||
* bitmap. If this bit is unset, the content
|
||||
* of the target bitmap **must be zeroed** !
|
||||
*
|
||||
**************************************************************************/
|
||||
typedef enum {
|
||||
|
||||
ft_raster_flag_default = 0,
|
||||
ft_raster_flag_aa = 1,
|
||||
ft_raster_flag_direct = 2
|
||||
|
||||
} FT_Raster_Flag;
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* <Struct>
|
||||
* FT_Raster_Params
|
||||
*
|
||||
* <Description>
|
||||
* A structure used to hold the arguments used by a raster's render
|
||||
* function.
|
||||
*
|
||||
* <Fields>
|
||||
* target :: the target bitmap
|
||||
* source :: pointer to the source glyph image (e.g. a FT_Outline)
|
||||
* flags :: rendering flags
|
||||
* gray_spans :: gray span drawing callback
|
||||
* black_spans :: black span drawing callback
|
||||
* bit_test :: bit test callback
|
||||
* bit_set :: bit set callback
|
||||
* user :: user-supplied data that is passed to each drawing
|
||||
* callback..
|
||||
*
|
||||
* <Note>
|
||||
* An anti-aliased glyph bitmap is drawn if the ft_raster_flag_aa bit
|
||||
* flag is set in the "flags" field, otherwise a monochrome bitmap will
|
||||
* be generated.
|
||||
*
|
||||
* When the ft_raster_flag_direct bit flag is set in "flags", the raster
|
||||
* will call the "gray_spans" callback to drawn gray pixel spans, in the
|
||||
* case of an aa glyph bitmap, or "black_spans", "bit_test" and "bit_set"
|
||||
* in the case of a monochrome bitmap.
|
||||
*
|
||||
* This allows direct composition over a pre-existing bitmap through
|
||||
* user-provided callbacks to perform the span drawing/composition.
|
||||
*
|
||||
* Note that the "bit_test" and "bit_set" callbacks are required when
|
||||
* rendering a monochrome bitmap, as they are crucial to implement correct
|
||||
* drop-out control per-se the TrueType specification..
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
typedef struct FT_Raster_Params_
|
||||
{
|
||||
FT_Bitmap* target;
|
||||
void* source;
|
||||
int flags;
|
||||
FT_Raster_Span_Func gray_spans;
|
||||
FT_Raster_Span_Func black_spans;
|
||||
FT_Raster_BitTest_Func bit_test;
|
||||
FT_Raster_BitSet_Func bit_set;
|
||||
void* user;
|
||||
|
||||
} FT_Raster_Params;
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* <FuncType>
|
||||
* FT_Raster_New_Func
|
||||
*
|
||||
* <Description>
|
||||
* A function used to create a new raster object.
|
||||
*
|
||||
* <Input>
|
||||
* memory :: handle to memory allocator.
|
||||
*
|
||||
* <Output>
|
||||
* raster :: handle to new raster object
|
||||
*
|
||||
* <Return>
|
||||
* Error code. 0 means success
|
||||
*
|
||||
* <Note>
|
||||
* the "memory" parameter is a typeless pointer in order to avoid
|
||||
* un-wanted dependencies on the rest of the FreeType code.
|
||||
*
|
||||
* in practice, it is a FT_Memory, i.e. a handle to the standard
|
||||
* FreeType memory allocator. However, this field can be completely
|
||||
* ignored by a given raster implementation..
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
typedef int (*FT_Raster_New_Func)( void* memory,
|
||||
FT_Raster *raster );
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* <FuncType>
|
||||
* FT_Raster_Done_Func
|
||||
*
|
||||
* <Description>
|
||||
* A function used to destroy a given raster object.
|
||||
*
|
||||
* <Input>
|
||||
* raster :: handle to new raster object
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
typedef void (*FT_Raster_Done_Func)( FT_Raster raster );
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* <FuncType>
|
||||
* FT_Raster_Reset_Func
|
||||
*
|
||||
* <Description>
|
||||
* FreeType provides an area of memory called the "render pool",
|
||||
* available to all registered rasters. This pool can be freely
|
||||
* used during a given scan-conversion but is shared by all rasters.
|
||||
* Its content is thus transient.
|
||||
*
|
||||
* This function is called each time the render pool changes, or
|
||||
* just after a new raster object is created.
|
||||
*
|
||||
* <Input>
|
||||
* raster :: handle to new raster object
|
||||
* pool_base :: address in memory of render pool
|
||||
* pool_size :: size in bytes of render pool
|
||||
*
|
||||
* <Note>
|
||||
* Rasters can ignore the render pool and rely on dynamic memory
|
||||
* allocation if they want to (a handle to the memory allocator is
|
||||
* passed to the raster constructor). However, this is not recommended
|
||||
* for efficiency purposes..
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
typedef void (*FT_Raster_Reset_Func)( FT_Raster raster,
|
||||
const char* pool_base,
|
||||
long pool_size );
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* <FuncType>
|
||||
* FT_Raster_Set_Mode_Func
|
||||
*
|
||||
* <Description>
|
||||
* This function is a generic facility to change modes or attributes
|
||||
* in a given raster. This can be used for debugging purposes, or
|
||||
* simply to allow implementation-specific "features" in a given
|
||||
* raster module.
|
||||
*
|
||||
* <Input>
|
||||
* raster :: handle to new raster object
|
||||
* mode :: an C string naming the mode or property to change
|
||||
* args :: a pointer to the new mode/property to use
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
typedef int (*FT_Raster_Set_Mode_Func)( FT_Raster raster,
|
||||
const char* mode,
|
||||
const char* args );
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* <FuncType>
|
||||
* FT_Raster_Render_Proc
|
||||
*
|
||||
* <Description>
|
||||
* Renders an outline into a target bitmap/pixmap.
|
||||
*
|
||||
* <Input>
|
||||
* raster :: A handle to a raster object used during rendering.
|
||||
*
|
||||
* source_image :: a typeless pointer to the source glyph image.
|
||||
* (usually a FT_Outline*).
|
||||
*
|
||||
* target_bitmap :: descriptor to the target bitmap.
|
||||
*
|
||||
* <Return>
|
||||
* Error code, interpreted as a FT_Error by FreeType library.
|
||||
* 0 means success.
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
typedef int (*FT_Raster_Render_Proc)( FT_Raster raster,
|
||||
void* source_image,
|
||||
FT_Bitmap* target_bitmap );
|
||||
void* args );
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* <FuncType>
|
||||
* FT_Raster_Render_Func
|
||||
*
|
||||
* <Description>
|
||||
* Invokes a given raster to scan-convert a given glyph image into
|
||||
* a target bitmap.
|
||||
*
|
||||
* <Input>
|
||||
* raster :: handle to raster object
|
||||
* params :: pointer to a FT_Raster_Params structure used to store
|
||||
* the rendering parameters.
|
||||
*
|
||||
* <Return>
|
||||
* Error code. 0 means success
|
||||
*
|
||||
* <Note>
|
||||
* The exact format of the source image depends on the raster's
|
||||
* glyph format defined in its FT_Raster_Funcs structure. It can be
|
||||
* an FT_Outline or anything else in order to support a large array
|
||||
* of glyph formats.
|
||||
*
|
||||
* Note also that the render function can fail and return a
|
||||
* FT_Err_Unimplemented_Feature error code when the raster used does
|
||||
* not support direct composition.
|
||||
*
|
||||
* XXX: For now, the standard raster doesn't support direct composition
|
||||
* but this should change for the final release (see the files
|
||||
* demos/src/ftgrays.c and demos/src/ftgrays2.c for examples of
|
||||
* distinct implementations which support direct composition).
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
typedef int (*FT_Raster_Render_Func)( FT_Raster raster,
|
||||
FT_Raster_Params* params );
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* <Struct>
|
||||
* FT_Raster_Interface
|
||||
* FT_Raster_Funcs
|
||||
*
|
||||
* <Description>
|
||||
* A structure used to model the default raster interface. A raster
|
||||
* is a module in charge of converting a glyph image into a bitmap.
|
||||
*
|
||||
* A structure used to describe a given raster class to the library.
|
||||
*
|
||||
* <Fields>
|
||||
* size :: the size in bytes of the given raster object. This
|
||||
* is used to allocate a new raster when calling
|
||||
* `FT_Set_Raster'.
|
||||
*
|
||||
* format :: the source glyph image format this raster is able to
|
||||
* handle.
|
||||
*
|
||||
* init :: the raster's initialisation routine
|
||||
*
|
||||
* set_mode :: the raster's mode set routine
|
||||
*
|
||||
* render :: the raster's rendering routine
|
||||
* glyph_format :: the supported glyph format for this raster
|
||||
* raster_new :: the raster constructor
|
||||
* raster_reset :: used to reset the render pool within the raster
|
||||
* raster_render :: renders a glyph into a given bitmap
|
||||
* raster_done :: the raster destructor
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
typedef struct FT_Raster_Interface_
|
||||
{
|
||||
long size;
|
||||
FT_Glyph_Tag format_tag;
|
||||
FT_Raster_Init_Proc init;
|
||||
FT_Raster_Set_Mode_Proc set_mode;
|
||||
FT_Raster_Render_Proc render;
|
||||
|
||||
|
||||
} FT_Raster_Interface;
|
||||
|
||||
|
||||
typedef struct FT_Raster_Funcs_
|
||||
{
|
||||
FT_Glyph_Format glyph_format;
|
||||
FT_Raster_New_Func raster_new;
|
||||
FT_Raster_Reset_Func raster_reset;
|
||||
FT_Raster_Set_Mode_Func raster_set_mode;
|
||||
FT_Raster_Render_Func raster_render;
|
||||
FT_Raster_Done_Func raster_done;
|
||||
|
||||
} FT_Raster_Funcs;
|
||||
|
||||
#endif /* FTIMAGE_H */
|
||||
|
||||
|
@ -38,25 +38,7 @@
|
||||
#endif
|
||||
|
||||
EXPORT_DEF
|
||||
int FT_Raster_Init( FT_Raster raster,
|
||||
const char* pool_base,
|
||||
long pool_size );
|
||||
|
||||
EXPORT_DEF
|
||||
int FT_Raster_Render( FT_Raster raster,
|
||||
FT_Outline* outline,
|
||||
FT_Bitmap* target_map );
|
||||
|
||||
EXPORT_DEF
|
||||
long FT_Raster_ObjSize( void );
|
||||
|
||||
/* FT_Raster_SetPalette() is currently unused by FreeType 2 */
|
||||
|
||||
EXPORT_DEF
|
||||
int FT_Raster_SetPalette( FT_Raster raster,
|
||||
int count,
|
||||
const char* palette );
|
||||
|
||||
FT_Raster_Funcs ft_raster_funcs;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
500
src/base/ftglyph.c
Normal file
500
src/base/ftglyph.c
Normal file
@ -0,0 +1,500 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftglyph.c */
|
||||
/* */
|
||||
/* FreeType convenience functions to handle glyphs.. */
|
||||
/* */
|
||||
/* Copyright 1996-1999 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. */
|
||||
/* */
|
||||
/* This file contains the definition of several convenience functions */
|
||||
/* that can be used by client applications to easily retrieve glyph */
|
||||
/* bitmaps and outlines from a given face. */
|
||||
/* */
|
||||
/* These functions should be optional if you're writing a font server */
|
||||
/* or text layout engine on top of FreeType. However, they are pretty */
|
||||
/* handy for many other simple uses of the library.. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
#include <ftglyph.h>
|
||||
#include <ftobjs.h>
|
||||
|
||||
static
|
||||
void ft_prepare_glyph( FT_Glyph glyph,
|
||||
FT_Face face,
|
||||
FT_Bool vertical )
|
||||
{
|
||||
FT_Glyph_Metrics* metrics = &face->glyph->metrics;
|
||||
|
||||
glyph->memory = face->memory;
|
||||
glyph->width = metrics->width;
|
||||
glyph->height = metrics->height;
|
||||
|
||||
if (vertical)
|
||||
{
|
||||
glyph->bearingX = metrics->vertBearingX;
|
||||
glyph->bearingY = metrics->vertBearingY;
|
||||
glyph->advance = metrics->vertAdvance;
|
||||
}
|
||||
else
|
||||
{
|
||||
glyph->bearingX = metrics->horiBearingX;
|
||||
glyph->bearingY = metrics->horiBearingY;
|
||||
glyph->advance = metrics->horiAdvance;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* FT_Get_Glyph_Bitmap
|
||||
*
|
||||
* <Description>
|
||||
* A function used to directly return a monochrome bitmap glyph image
|
||||
* from a face.
|
||||
*
|
||||
* <Input>
|
||||
* face :: handle to source face object
|
||||
* glyph_index :: glyph index in face
|
||||
* load_flags :: load flags, see FT_LOAD_FLAG_XXXX constants..
|
||||
* grays :: number of gray levels for anti-aliased bitmaps,
|
||||
* set to 0 if you want to render a monochrome bitmap
|
||||
* origin :: a pointer to the origin's position. Set to 0
|
||||
* if the current transform is the identity..
|
||||
*
|
||||
* <Output>
|
||||
* bitglyph :: pointer to the new bitmap glyph
|
||||
*
|
||||
* <Return>
|
||||
* Error code. 0 means success.
|
||||
*
|
||||
* <Note>
|
||||
* If the font contains glyph outlines, these will be automatically
|
||||
* converted to a bitmap according to the value of "grays"
|
||||
*
|
||||
* If "grays" is set to 0, the result is a 1-bit monochrome bitmap
|
||||
* otherwise, it is an 8-bit gray-level bitmap
|
||||
*
|
||||
* The number of gray levels in the result anti-aliased bitmap might
|
||||
* not be "grays", depending on the current scan-converter implementation
|
||||
*
|
||||
* Note that it is not possible to generate 8-bit monochrome bitmaps
|
||||
* with this function. Rather, use FT_Get_Glyph_Outline, then
|
||||
* FT_Glyph_Render_Outline and provide your own span callbacks..
|
||||
*
|
||||
* When the face doesn't contain scalable outlines, this function will
|
||||
* fail if the current transform is not the identity, or if the glyph
|
||||
* origin's phase to the pixel grid is not 0 in both directions !!
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
EXPORT_FUNC
|
||||
FT_Error FT_Get_Glyph_Bitmap( FT_Face face,
|
||||
FT_UInt glyph_index,
|
||||
FT_UInt load_flags,
|
||||
FT_Int grays,
|
||||
FT_Vector* origin,
|
||||
FT_BitmapGlyph *abitglyph )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory;
|
||||
FT_BitmapGlyph bitglyph;
|
||||
FT_Glyph glyph;
|
||||
FT_Pos origin_x = 0;
|
||||
FT_Pos origin_y = 0;
|
||||
|
||||
*abitglyph = 0;
|
||||
|
||||
if (origin)
|
||||
{
|
||||
origin_x = origin->x & 63;
|
||||
origin_y = origin->y & 63;
|
||||
}
|
||||
|
||||
/* check arguments if the face's format is not scalable */
|
||||
if ( !(face->face_flags & FT_FACE_FLAG_SCALABLE) && face->transform_flags )
|
||||
{
|
||||
/* we can't transform bitmaps, so return an error */
|
||||
error = FT_Err_Unimplemented_Feature;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* check that NO_SCALE and NO_RECURSE are not set */
|
||||
if (load_flags & (FT_LOAD_NO_SCALE|FT_LOAD_NO_RECURSE))
|
||||
{
|
||||
error = FT_Err_Invalid_Argument;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* disable embedded bitmaps for transformed images */
|
||||
if ( face->face_flags & FT_FACE_FLAG_SCALABLE && face->transform_flags )
|
||||
load_flags |= FT_LOAD_NO_BITMAP;
|
||||
|
||||
error = FT_Load_Glyph( face, glyph_index, load_flags );
|
||||
if (error) goto Exit;
|
||||
|
||||
/* now, handle bitmap and outline glyph images */
|
||||
memory = face->memory;
|
||||
switch ( face->glyph->format )
|
||||
{
|
||||
case ft_glyph_format_bitmap:
|
||||
{
|
||||
FT_Long size;
|
||||
FT_Bitmap* source;
|
||||
|
||||
if ( ALLOC( bitglyph, sizeof(*bitglyph) ) )
|
||||
goto Exit;
|
||||
|
||||
glyph = (FT_Glyph)bitglyph;
|
||||
glyph->glyph_type = ft_glyph_type_bitmap;
|
||||
ft_prepare_glyph( glyph, face, 0 );
|
||||
|
||||
source = &face->glyph->bitmap;
|
||||
size = source->rows * source->pitch;
|
||||
if (size < 0) size = -size;
|
||||
|
||||
bitglyph->bitmap = *source;
|
||||
if ( ALLOC( bitglyph->bitmap.buffer, size ) )
|
||||
goto Fail;
|
||||
|
||||
/* copy the content of the source glyph */
|
||||
MEM_Copy( bitglyph->bitmap.buffer, source->buffer, size );
|
||||
}
|
||||
break;
|
||||
|
||||
case ft_glyph_format_outline:
|
||||
{
|
||||
FT_BBox cbox;
|
||||
FT_Int width, height, pitch;
|
||||
FT_Long size;
|
||||
|
||||
/* transform the outline - note that the original metrics are NOT */
|
||||
/* transformed by this.. only the outline points themselves.. */
|
||||
FT_Outline_Transform( &face->glyph->outline, &face->transform_matrix );
|
||||
FT_Outline_Translate( &face->glyph->outline,
|
||||
face->transform_delta.x + origin_x,
|
||||
face->transform_delta.y + origin_y );
|
||||
|
||||
/* compute the size in pixels of the outline */
|
||||
FT_Outline_Get_CBox( &face->glyph->outline, &cbox );
|
||||
cbox.xMin &= -64;
|
||||
cbox.yMin &= -64;
|
||||
cbox.xMax = (cbox.xMax+63) & -64;
|
||||
cbox.yMax = (cbox.yMax+63) & -64;
|
||||
|
||||
width = (cbox.xMax - cbox.xMin) >> 6;
|
||||
height = (cbox.yMax - cbox.yMin) >> 6;
|
||||
|
||||
/* allocate the pixel buffer for the glyph bitmap */
|
||||
if (grays) pitch = (width+3) & -4; /* some raster implementation need this */
|
||||
else pitch = (width+7) >> 3;
|
||||
|
||||
size = pitch * height;
|
||||
if ( ALLOC( bitglyph, sizeof(*bitglyph) ) )
|
||||
goto Exit;
|
||||
|
||||
glyph = (FT_Glyph)bitglyph;
|
||||
glyph->glyph_type = ft_glyph_type_bitmap;
|
||||
ft_prepare_glyph( glyph, face, 0 );
|
||||
|
||||
if ( ALLOC( bitglyph->bitmap.buffer, size ) )
|
||||
goto Fail;
|
||||
|
||||
bitglyph->bitmap.width = width;
|
||||
bitglyph->bitmap.rows = height;
|
||||
bitglyph->bitmap.pitch = pitch;
|
||||
bitglyph->bitmap.pixel_mode = grays ? ft_pixel_mode_grays
|
||||
: ft_pixel_mode_mono;
|
||||
bitglyph->bitmap.num_grays = (short)grays;
|
||||
|
||||
bitglyph->left = (cbox.xMin >> 6);
|
||||
bitglyph->top = (cbox.yMax >> 6);
|
||||
|
||||
/* render the monochrome outline into the target buffer */
|
||||
FT_Outline_Translate( &face->glyph->outline, -cbox.xMin, -cbox.yMin );
|
||||
error = FT_Outline_Get_Bitmap( face->driver->library,
|
||||
&face->glyph->outline,
|
||||
&bitglyph->bitmap );
|
||||
if (error)
|
||||
{
|
||||
FREE( bitglyph->bitmap.buffer );
|
||||
goto Fail;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
error = FT_Err_Invalid_Glyph_Index;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
*abitglyph = bitglyph;
|
||||
Exit:
|
||||
return error;
|
||||
|
||||
Fail:
|
||||
FREE( glyph );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* FT_Get_Glyph_Outline
|
||||
*
|
||||
* <Description>
|
||||
* A function used to directly return a bitmap glyph image from a
|
||||
* face. This is faster than calling FT_Load_Glyph+FT_Get_Outline_Bitmap..
|
||||
*
|
||||
* <Input>
|
||||
* face :: handle to source face object
|
||||
* glyph_index :: glyph index in face
|
||||
* load_flags :: load flags, see FT_LOAD_FLAG_XXXX constants..
|
||||
*
|
||||
* <Output>
|
||||
* vecglyph :: pointer to the new outline glyph
|
||||
*
|
||||
* <Return>
|
||||
* Error code. 0 means success.
|
||||
*
|
||||
* <Note>
|
||||
* This function will fail if the load flags FT_LOAD_NO_OUTLINE and
|
||||
* FT_LOAD_NO_RECURSE are set..
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
EXPORT_FUNC
|
||||
FT_Error FT_Get_Glyph_Outline( FT_Face face,
|
||||
FT_UInt glyph_index,
|
||||
FT_UInt load_flags,
|
||||
FT_OutlineGlyph *vecglyph )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory;
|
||||
FT_OutlineGlyph glyph;
|
||||
|
||||
*vecglyph = 0;
|
||||
|
||||
/* check that NO_OUTLINE and NO_RECURSE are not set */
|
||||
if (load_flags & (FT_LOAD_NO_OUTLINE|FT_LOAD_NO_RECURSE))
|
||||
{
|
||||
error = FT_Err_Invalid_Argument;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* disable the loading of embedded bitmaps */
|
||||
load_flags |= FT_LOAD_NO_BITMAP;
|
||||
|
||||
error = FT_Load_Glyph( face, glyph_index, load_flags );
|
||||
if (error) goto Exit;
|
||||
|
||||
/* check that we really loaded an outline */
|
||||
if ( face->glyph->format != ft_glyph_format_outline )
|
||||
{
|
||||
error = FT_Err_Invalid_Glyph_Index;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* transform the outline - note that the original metrics are NOT */
|
||||
/* transformed by this.. only the outline points themselves.. */
|
||||
if ( face->transform_flags )
|
||||
{
|
||||
FT_Outline_Transform( &face->glyph->outline, &face->transform_matrix );
|
||||
FT_Outline_Translate( &face->glyph->outline,
|
||||
face->transform_delta.x,
|
||||
face->transform_delta.y );
|
||||
}
|
||||
|
||||
/* now, create a new outline glyph and copy everything there */
|
||||
memory = face->memory;
|
||||
if ( ALLOC( glyph, sizeof(*glyph) ) )
|
||||
goto Exit;
|
||||
|
||||
ft_prepare_glyph( (FT_Glyph)glyph, face, 0 );
|
||||
glyph->metrics.glyph_type = ft_glyph_type_outline;
|
||||
|
||||
error = FT_Outline_New( face->driver->library,
|
||||
face->glyph->outline.n_points,
|
||||
face->glyph->outline.n_contours,
|
||||
&glyph->outline );
|
||||
if (!error)
|
||||
error = FT_Outline_Copy( &face->glyph->outline, &glyph->outline );
|
||||
|
||||
if (error) goto Fail;
|
||||
|
||||
*vecglyph = glyph;
|
||||
Exit:
|
||||
return error;
|
||||
|
||||
Fail:
|
||||
FREE( glyph );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* FT_Set_Transform
|
||||
*
|
||||
* <Description>
|
||||
* A function used to set the transform that is applied to glyph images
|
||||
* just after they're loaded in the face's glyph slot, and before they're
|
||||
* returned by either FT_Get_Glyph_Bitmap or FT_Get_Glyph_Outline
|
||||
*
|
||||
* <Input>
|
||||
* face :: handle to source face object
|
||||
* matrix :: pointer to the transform's 2x2 matrix. 0 for identity
|
||||
* delta :: pointer to the transform's translation. 0 for null vector
|
||||
*
|
||||
* <Note>
|
||||
* The transform is only applied to glyph outlines when they are found
|
||||
* in a font face. It is unable to transform embedded glyph bitmaps
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
EXPORT_FUNC
|
||||
void FT_Set_Transform( FT_Face face,
|
||||
FT_Matrix* matrix,
|
||||
FT_Vector* delta )
|
||||
{
|
||||
face->transform_flags = 0;
|
||||
|
||||
if (!matrix)
|
||||
{
|
||||
face->transform_matrix.xx = 0x10000L;
|
||||
face->transform_matrix.xy = 0;
|
||||
face->transform_matrix.yx = 0L;
|
||||
face->transform_matrix.yy = 0x10000L;
|
||||
matrix = &face->transform_matrix;
|
||||
}
|
||||
else
|
||||
face->transform_matrix = *matrix;
|
||||
|
||||
/* set transform_flags bit flag 0 if delta isn't the null vector */
|
||||
if ( (matrix->xy | matrix->yx) ||
|
||||
matrix->xx != 0x10000L ||
|
||||
matrix->yy != 0x10000L )
|
||||
face->transform_flags |= 1;
|
||||
|
||||
if (!delta)
|
||||
{
|
||||
face->transform_delta.x = 0;
|
||||
face->transform_delta.y = 0;
|
||||
delta = &face->transform_delta;
|
||||
}
|
||||
else
|
||||
face->transform_delta = *delta;
|
||||
|
||||
/* set transform_flags bit flag 1 if delta isn't the null vector */
|
||||
if ( delta->x | delta->y )
|
||||
face->transform_flags |= 2;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* FT_Done_Glyph
|
||||
*
|
||||
* <Description>
|
||||
* Destroys a given glyph..
|
||||
*
|
||||
* <Input>
|
||||
* glyph :: handle to target glyph object
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
EXPORT_FUNC
|
||||
void FT_Done_Glyph( FT_Glyph glyph )
|
||||
{
|
||||
if (glyph)
|
||||
{
|
||||
FT_Memory memory = glyph->memory;
|
||||
|
||||
if ( glyph->glyph_type == ft_glyph_type_bitmap )
|
||||
{
|
||||
FT_BitmapGlyph bit = (FT_BitmapGlyph)glyph;
|
||||
FREE( bit->bitmap.buffer );
|
||||
}
|
||||
else if ( glyph->glyph_type == ft_glyph_type_outline )
|
||||
{
|
||||
FT_OutlineGlyph out = (FT_OutlineGlyph)glyph;
|
||||
if (out->outline.flags & ft_outline_owner)
|
||||
{
|
||||
FREE( out->outline.points );
|
||||
FREE( out->outline.contours );
|
||||
FREE( out->outline.tags );
|
||||
}
|
||||
}
|
||||
|
||||
FREE( glyph );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* FT_Glyph_Get_Box
|
||||
*
|
||||
* <Description>
|
||||
* Returns the glyph image's bounding box in pixels.
|
||||
*
|
||||
* <Input>
|
||||
* glyph :: handle to target glyph object
|
||||
*
|
||||
* <Output>
|
||||
* box :: the glyph bounding box. Coordinates are expressed in
|
||||
* _integer_ pixels, with exclusive max bounds
|
||||
*
|
||||
* <Note>
|
||||
* Coordinates are relative to the glyph origin, using the Y-upwards
|
||||
* convention..
|
||||
*
|
||||
* The width of the box in pixels is box.xMax-box.xMin
|
||||
* The height is box.yMax - box.yMin
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
EXPORT_DEF
|
||||
void FT_Glyph_Get_Box( FT_Glyph glyph,
|
||||
FT_BBox *box )
|
||||
{
|
||||
box->xMin = box->xMax = 0;
|
||||
box->yMin = box->yMax = 0;
|
||||
|
||||
if (glyph) switch (glyph->glyph_type)
|
||||
{
|
||||
case ft_glyph_type_bitmap:
|
||||
{
|
||||
FT_BitmapGlyph bit = (FT_BitmapGlyph)glyph;
|
||||
box->xMin = bit->left;
|
||||
box->xMax = box->xMin + bit->bitmap.width;
|
||||
box->yMax = bit->top;
|
||||
box->yMin = box->yMax - bit->bitmap.rows;
|
||||
}
|
||||
break;
|
||||
|
||||
case ft_glyph_type_outline:
|
||||
{
|
||||
FT_OutlineGlyph out = (FT_OutlineGlyph)glyph;
|
||||
|
||||
FT_Outline_Get_CBox( &out->outline, box );
|
||||
box->xMin >>= 6;
|
||||
box->yMin >>= 6;
|
||||
box->xMax = (box->xMax+63) >> 6;
|
||||
box->yMax = (box->yMax+63) >> 6;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
1168
src/base/ftobjs.c
1168
src/base/ftobjs.c
File diff suppressed because it is too large
Load Diff
@ -95,95 +95,17 @@
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Alloc */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Allocates a new block of memory. The returned area is always */
|
||||
/* zero-filled, this is a strong convention in many FreeType parts. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A handle to a given `memory object' where allocation */
|
||||
/* occurs. */
|
||||
/* */
|
||||
/* size :: The size in bytes of the block to allocate. */
|
||||
/* */
|
||||
/* <Output> */
|
||||
/* P :: A pointer to the fresh new block. It should be set to */
|
||||
/* NULL if `size' is 0, or in case of error. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
BASE_DEF
|
||||
FT_Error FT_Alloc( FT_Memory memory,
|
||||
FT_Long size,
|
||||
void** P );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Realloc */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Reallocates a block of memory pointed to by `*P' to `Size' bytes */
|
||||
/* from the heap, possibly changing `*P'. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A handle to a given `memory object' where allocation */
|
||||
/* occurs. */
|
||||
/* */
|
||||
/* current :: current block size in bytes */
|
||||
/* size :: the new block size in bytes */
|
||||
/* */
|
||||
/* <InOut> */
|
||||
/* P :: A pointer to the fresh new block. It should be set to */
|
||||
/* NULL if `size' is 0, or in case of error. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* All callers of FT_Realloc _must_ provide the current block size */
|
||||
/* as well as the new one. */
|
||||
/* */
|
||||
/* When the memory object's flag FT_memory_FLAG_NO_REALLOC is */
|
||||
/* set, this function will try to emulate a realloc through uses */
|
||||
/* of FT_Alloc and FT_Free. Otherwise, it will call the memory- */
|
||||
/* specific "realloc" implementation. */
|
||||
/* */
|
||||
/* (Some embedded memorys do not have a working realloc). */
|
||||
/* */
|
||||
BASE_DEF
|
||||
FT_Error FT_Realloc( FT_Memory memory,
|
||||
FT_Long current,
|
||||
FT_Long size,
|
||||
void** P );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Free */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Releases a given block of memory allocated through FT_Alloc(). */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A handle to a given `memory object' where allocation */
|
||||
/* occured. */
|
||||
/* */
|
||||
/* P :: This is the _address_ of a _pointer_ which points to the */
|
||||
/* allocated block. It is always set to NULL on exit. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* If P or *P are NULL, this function should return successfully. */
|
||||
/* This is a strong convention within all of FreeType and its */
|
||||
/* drivers. */
|
||||
/* */
|
||||
BASE_DEF
|
||||
void FT_Free( FT_Memory memory,
|
||||
void** P );
|
||||
@ -246,6 +168,23 @@
|
||||
|
||||
|
||||
|
||||
EXPORT_DEF
|
||||
FT_Error FT_New_Size( FT_Face face,
|
||||
FT_Size* size );
|
||||
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Done_Size( FT_Size size );
|
||||
|
||||
EXPORT_DEF
|
||||
FT_Error FT_New_GlyphSlot( FT_Face face,
|
||||
FT_GlyphSlot* aslot );
|
||||
|
||||
EXPORT_DEF
|
||||
void FT_Done_GlyphSlot( FT_GlyphSlot slot );
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
@ -317,7 +256,17 @@
|
||||
} FT_DriverRec;
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/**** G L Y P H Z O N E S ****/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
*
|
||||
@ -357,6 +306,7 @@
|
||||
|
||||
} FT_GlyphZone;
|
||||
|
||||
|
||||
BASE_DEF
|
||||
FT_Error FT_New_GlyphZone( FT_Memory memory,
|
||||
FT_UShort maxPoints,
|
||||
@ -372,132 +322,6 @@
|
||||
FT_Short num_contours );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/**** G L Y P H F O R M A T S ****/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* <Struct>
|
||||
* FT_Glyph_Format
|
||||
*
|
||||
* <Description>
|
||||
* A structure used to model various properties of a non-standard
|
||||
* glyph image format.
|
||||
*
|
||||
* <Fields>
|
||||
* format_tag :: the glyph format tag
|
||||
*
|
||||
* raster_interface :: the default rasters interface for this glyph
|
||||
* format.
|
||||
*
|
||||
* raster :: the default raster object for this glyph format
|
||||
* if set to nil, a new object will be allocated
|
||||
* automatically through the raster interface.
|
||||
*
|
||||
* raster_owned :: a boolean used internally by the library. If
|
||||
* set, if indicates that the current raster object
|
||||
* was allocated by the library.
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
typedef struct FT_Glyph_Format_
|
||||
{
|
||||
FT_Glyph_Tag format_tag;
|
||||
FT_Raster_Interface* raster_interface;
|
||||
FT_Raster raster;
|
||||
FT_Bool raster_allocated;
|
||||
|
||||
} FT_Glyph_Format;
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* FT_Add_Glyph_Format
|
||||
*
|
||||
* <Description>
|
||||
* Register a new glyph format into the library
|
||||
*
|
||||
* <Input>
|
||||
* library :: handle to target library object
|
||||
* interface :: pointer to glyph format interface
|
||||
*
|
||||
* <Return>
|
||||
* Error code. 0 means success
|
||||
*
|
||||
* <Note>
|
||||
* This function should normally be called by those font drivers which
|
||||
* need to use their own glyph image format.
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Add_Glyph_Format( FT_Library library,
|
||||
FT_Glyph_Format* format );
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* FT_Remove_Glyph_Format
|
||||
*
|
||||
* <Description>
|
||||
* Un-Register a given glyph format from the library
|
||||
*
|
||||
* <Input>
|
||||
* library :: handle to target library object
|
||||
* glyph_format :: glyph format tag
|
||||
*
|
||||
* <Return>
|
||||
* Error code. 0 means success
|
||||
*
|
||||
* <Note>
|
||||
* This function should normally be called by those font drivers which
|
||||
* need to use their own glyph image format.
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Remove_Glyph_Format( FT_Library library,
|
||||
FT_Glyph_Tag glyph_format );
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* FT_Get_Glyph_Format
|
||||
*
|
||||
* <Description>
|
||||
* Return a pointer to the glyph format descriptor corresponding to
|
||||
* a given format tag.
|
||||
*
|
||||
* <Input>
|
||||
* library :: handle to source library object
|
||||
*
|
||||
* format_tag :: glyph format tag
|
||||
*
|
||||
* <Return>
|
||||
* a pointer to the corresponding glyph format descriptor, if it was
|
||||
* registered in the library. 0 otherwise.
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
BASE_DEF
|
||||
FT_Glyph_Format* FT_Get_Glyph_Format( FT_Library library,
|
||||
FT_Glyph_Tag format_tag );
|
||||
|
||||
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS */
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
@ -539,10 +363,6 @@
|
||||
/* registered font drivers. Note that each driver */
|
||||
/* contains a list of its opened faces. */
|
||||
/* */
|
||||
/* glyph_formats :: A table used to store glyph format descriptors */
|
||||
/* for new image formats that may have been */
|
||||
/* registered within the library */
|
||||
/* */
|
||||
/* raster_pool :: The raster object's render pool. This can */
|
||||
/* ideally be changed dynamically at run-time. */
|
||||
/* */
|
||||
@ -557,59 +377,22 @@
|
||||
FT_Int num_drivers;
|
||||
FT_Driver drivers[ FT_MAX_DRIVERS ]; /* driver objects */
|
||||
|
||||
FT_Glyph_Format glyph_formats[FT_MAX_GLYPH_FORMATS];
|
||||
FT_Raster_Funcs raster_funcs[ FT_MAX_GLYPH_FORMATS ];
|
||||
FT_Raster rasters [ FT_MAX_GLYPH_FORMATS ];
|
||||
|
||||
void* raster_pool; /* scan-line conversion render pool */
|
||||
void* raster_pool; /* scan-line conversion render pool */
|
||||
long raster_pool_size; /* size of render pool in bytes */
|
||||
|
||||
FT_DebugHook_Func debug_hooks[4];
|
||||
|
||||
} FT_LibraryRec;
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_New_Library */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* This function is used to create a new FreeType library instance */
|
||||
/* from a given memory object. It is thus possible to use libraries */
|
||||
/* with distinct memory allocators within the same program. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A handle to the original memory object. */
|
||||
/* */
|
||||
/* <Output> */
|
||||
/* library :: A handle to a new library object. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Error code. 0 means success. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* This function is normally not called by client applications, */
|
||||
/* unless they want to create a specific instance of FreeType which */
|
||||
/* uses a specific memory allocator. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_New_Library( FT_Memory memory,
|
||||
FT_Library* library );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Done_Library */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Discards a given library object. This closes all drivers and */
|
||||
/* discards all face objects. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* library :: A handle to the target library. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Error code. 0 means success. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Done_Library( FT_Library library );
|
||||
|
||||
@ -621,127 +404,26 @@
|
||||
FT_DebugHook_Func debug_hook );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Add_Driver */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Registers a new driver in a given library object. This function */
|
||||
/* takes only a pointer to a driver interface. It uses it to create */
|
||||
/* the new driver, then sets up some important fields. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* library :: A handle to the target library object. */
|
||||
/* */
|
||||
/* driver_interface :: A pointer to a driver interface table. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Error code. 0 means success. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* This function doesn't check whether the driver is already */
|
||||
/* installed! */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Add_Driver( FT_Library library,
|
||||
const FT_DriverInterface* driver_interface );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Remove_Driver */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Unregister a given driver. This closes the driver, which in turn */
|
||||
/* destroys all faces, sizes, slots, etc. associated with it. */
|
||||
/* */
|
||||
/* This function also DESTROYS the driver object. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* driver :: A handle to target driver object. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Error code. 0 means success. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Remove_Driver( FT_Driver driver );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Get_Driver */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* returns the handle of the driver responsible for a given format */
|
||||
/* (or service) according to its `name'. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* library :: handle to library object. */
|
||||
/* driver_name :: name of driver to look-up. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* handle to driver object. 0 otherwise */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Driver FT_Get_Driver( FT_Library library,
|
||||
char* driver_name );
|
||||
|
||||
#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* FT_New_Stream
|
||||
*
|
||||
* <Description>
|
||||
* Open a new stream from a given standard ASCII file path name
|
||||
*
|
||||
* <Input>
|
||||
* filepathname :: an ASCII string naming the file to be opened
|
||||
*
|
||||
* <Output>
|
||||
* astream :: the opened stream descriptor to be used by the library
|
||||
*
|
||||
* <Return>
|
||||
* Error code. 0 means success
|
||||
*
|
||||
* <Note>
|
||||
* This function must be implemented by the system-specific part
|
||||
* of the engine, i.e. `ftsystem.c'.
|
||||
*
|
||||
* This function should only fill the stream descriptor. Note that
|
||||
* the stream's `memory' field should be left to the caller.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
extern
|
||||
FT_Error FT_New_Stream( const char* filepathname,
|
||||
FT_Stream astream );
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* FT_New_Memory
|
||||
*
|
||||
* <Description>
|
||||
* Returns a handle to a new memory object
|
||||
*
|
||||
* <Return>
|
||||
* Handle to the memory object. 0 means failure
|
||||
*
|
||||
* <Note>
|
||||
* This function must be implemented by the system-specific part
|
||||
* of the engine, i.e. `ftsystem.c'.
|
||||
*
|
||||
* It is only used by `ftinit' in order to implement the function
|
||||
* FT_Init_FreeType.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
extern
|
||||
FT_Memory FT_New_Memory( void );
|
||||
|
||||
@ -753,7 +435,7 @@
|
||||
/* */
|
||||
#ifndef FT_NO_DEFAULT_RASTER
|
||||
extern
|
||||
FT_Raster_Interface ft_default_raster;
|
||||
FT_Raster_Funcs ft_default_raster;
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -29,6 +29,740 @@
|
||||
#include <ftimage.h>
|
||||
#include <ftoutln.h>
|
||||
|
||||
static
|
||||
const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Decompose */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Walks over an outline's structure to decompose it into individual */
|
||||
/* segments and Bezier arcs. This function is also able to emit */
|
||||
/* `move to' and `close to' operations to indicate the start and end */
|
||||
/* of new contours in the outline. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* outline :: A pointer to the source target. */
|
||||
/* */
|
||||
/* interface :: A table of `emitters', i.e,. function pointers called */
|
||||
/* during decomposition to indicate path operations. */
|
||||
/* */
|
||||
/* user :: A typeless pointer which is passed to each emitter */
|
||||
/* during the decomposition. It can be used to store */
|
||||
/* the state during the decomposition. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Error code. 0 means sucess. */
|
||||
/* */
|
||||
EXPORT_FUNC
|
||||
int FT_Outline_Decompose( FT_Outline* outline,
|
||||
FT_Outline_Funcs* interface,
|
||||
void* user )
|
||||
{
|
||||
typedef enum _phases
|
||||
{
|
||||
phase_point,
|
||||
phase_conic,
|
||||
phase_cubic,
|
||||
phase_cubic2
|
||||
|
||||
} TPhase;
|
||||
|
||||
FT_Vector v_first;
|
||||
FT_Vector v_last;
|
||||
FT_Vector v_control;
|
||||
FT_Vector v_start;
|
||||
|
||||
FT_Vector* point;
|
||||
FT_Vector* limit;
|
||||
char* tags;
|
||||
|
||||
int n; /* index of contour in outline */
|
||||
int first; /* index of first point in contour */
|
||||
int error;
|
||||
char tag; /* current point's state */
|
||||
|
||||
|
||||
first = 0;
|
||||
|
||||
for ( n = 0; n < outline->n_contours; n++ )
|
||||
{
|
||||
int last; /* index of last point in contour */
|
||||
|
||||
last = outline->contours[n];
|
||||
limit = outline->points + last;
|
||||
|
||||
v_first = outline->points[first];
|
||||
v_last = outline->points[last];
|
||||
|
||||
v_start = v_control = v_first;
|
||||
|
||||
point = outline->points + first;
|
||||
tags = outline->tags + first;
|
||||
tag = FT_CURVE_TAG( tags[0] );
|
||||
|
||||
/* A contour cannot start with a cubic control point! */
|
||||
if ( tag == FT_Curve_Tag_Cubic )
|
||||
goto Invalid_Outline;
|
||||
|
||||
/* check first point to determine origin */
|
||||
if ( tag == FT_Curve_Tag_Conic )
|
||||
{
|
||||
/* first point is conic control. Yes, this happens. */
|
||||
if ( FT_CURVE_TAG( outline->tags[last] ) == FT_Curve_Tag_On )
|
||||
{
|
||||
/* start at last point if it is on the curve */
|
||||
v_start = v_last;
|
||||
limit--;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if both first and last points are conic, */
|
||||
/* start at their middle and record its position */
|
||||
/* for closure */
|
||||
v_start.x = ( v_start.x + v_last.x ) / 2;
|
||||
v_start.y = ( v_start.y + v_last.y ) / 2;
|
||||
|
||||
v_last = v_start;
|
||||
}
|
||||
point--;
|
||||
tags--;
|
||||
}
|
||||
|
||||
error = interface->move_to( &v_start, user );
|
||||
if (error) goto Exit;
|
||||
|
||||
while (point < limit)
|
||||
{
|
||||
point++;
|
||||
tags++;
|
||||
|
||||
tag = FT_CURVE_TAG( tags[0] );
|
||||
switch (tag)
|
||||
{
|
||||
case FT_Curve_Tag_On: /* emit a single line_to */
|
||||
{
|
||||
error = interface->line_to( point, user );
|
||||
if (error) goto Exit;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
case FT_Curve_Tag_Conic: /* consume conic arcs */
|
||||
{
|
||||
v_control = point[0];
|
||||
|
||||
Do_Conic:
|
||||
if (point < limit)
|
||||
{
|
||||
FT_Vector v_middle;
|
||||
|
||||
point++;
|
||||
tags++;
|
||||
tag = FT_CURVE_TAG( tags[0] );
|
||||
|
||||
if (tag == FT_Curve_Tag_On)
|
||||
{
|
||||
error = interface->conic_to( &v_control, point, user );
|
||||
if (error) goto Exit;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tag != FT_Curve_Tag_Conic)
|
||||
goto Invalid_Outline;
|
||||
|
||||
v_middle.x = (v_control.x + point->x)/2;
|
||||
v_middle.y = (v_control.y + point->y)/2;
|
||||
|
||||
error = interface->conic_to( &v_control, &v_middle, user );
|
||||
if (error) goto Exit;
|
||||
|
||||
v_control = point[0];
|
||||
goto Do_Conic;
|
||||
}
|
||||
|
||||
error = interface->conic_to( &v_control, &v_start, user );
|
||||
goto Close;
|
||||
}
|
||||
|
||||
default: /* FT_Curve_Tag_Cubic */
|
||||
{
|
||||
if ( point+1 > limit ||
|
||||
FT_CURVE_TAG( tags[1] ) != FT_Curve_Tag_Cubic )
|
||||
goto Invalid_Outline;
|
||||
|
||||
point += 2;
|
||||
tags += 2;
|
||||
|
||||
if (point <= limit)
|
||||
{
|
||||
error = interface->cubic_to( point-2, point-1, point, user );
|
||||
if (error) goto Exit;
|
||||
continue;
|
||||
}
|
||||
|
||||
error = interface->cubic_to( point-2, point-1, &v_start, user );
|
||||
goto Close;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* close the contour with a line segment */
|
||||
error = interface->line_to( &v_start, user );
|
||||
|
||||
Close:
|
||||
if (error) goto Exit;
|
||||
first = last+1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
Exit:
|
||||
return error;
|
||||
|
||||
Invalid_Outline:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_New */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Creates a new outline of a given size. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* library :: A handle to the library object from where the */
|
||||
/* outline is allocated. Note however that the new */
|
||||
/* outline will NOT necessarily be FREED when */
|
||||
/* destroying the library, by FT_Done_FreeType(). */
|
||||
/* */
|
||||
/* numPoints :: The maximum number of points within the outline. */
|
||||
/* */
|
||||
/* numContours :: The maximum number of contours within the outline. */
|
||||
/* */
|
||||
/* <Output> */
|
||||
/* outline :: A handle to the new outline. NULL in case of */
|
||||
/* error. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* No. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* The reason why this function takes a `library' parameter is simply */
|
||||
/* to use the library's memory allocator. You can copy the source */
|
||||
/* code of this function, replacing allocations with `malloc()' if */
|
||||
/* you want to control where the objects go. */
|
||||
/* */
|
||||
BASE_FUNC
|
||||
FT_Error FT_Outline_New( FT_Library library,
|
||||
FT_UInt numPoints,
|
||||
FT_Int numContours,
|
||||
FT_Outline* outline )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory;
|
||||
|
||||
|
||||
if ( !outline )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
*outline = null_outline;
|
||||
memory = library->memory;
|
||||
|
||||
if ( ALLOC_ARRAY( outline->points, numPoints * 2L, FT_Pos ) ||
|
||||
ALLOC_ARRAY( outline->tags, numPoints, FT_Byte ) ||
|
||||
ALLOC_ARRAY( outline->contours, numContours, FT_UShort ) )
|
||||
goto Fail;
|
||||
|
||||
outline->n_points = (FT_UShort)numPoints;
|
||||
outline->n_contours = (FT_Short)numContours;
|
||||
outline->flags |= ft_outline_owner;
|
||||
|
||||
return FT_Err_Ok;
|
||||
|
||||
Fail:
|
||||
outline->flags |= ft_outline_owner;
|
||||
FT_Outline_Done( library, outline );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Done */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Destroys an outline created with FT_Outline_New(). */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* library :: A handle of the library object used to allocate the */
|
||||
/* outline. */
|
||||
/* */
|
||||
/* outline :: A pointer to the outline object to be discarded. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* No. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* If the outline's `owner' field is not set, only the outline */
|
||||
/* descriptor will be released. */
|
||||
/* */
|
||||
/* The reason why this function takes an `outline' parameter is */
|
||||
/* simply to use FT_Alloc()/FT_Free(). You can copy the source code */
|
||||
/* of this function, replacing allocations with `malloc()' in your */
|
||||
/* application if you want something simpler. */
|
||||
/* */
|
||||
BASE_FUNC
|
||||
FT_Error FT_Outline_Done( FT_Library library,
|
||||
FT_Outline* outline )
|
||||
{
|
||||
FT_Memory memory = library->memory;
|
||||
|
||||
if ( outline )
|
||||
{
|
||||
if ( outline->flags & ft_outline_owner )
|
||||
{
|
||||
FREE( outline->points );
|
||||
FREE( outline->tags );
|
||||
FREE( outline->contours );
|
||||
}
|
||||
*outline = null_outline;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
else
|
||||
return FT_Err_Invalid_Argument;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Get_CBox */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Returns an outline's `control box'. The control box encloses all */
|
||||
/* the outline's points, including Bezier control points. Though it */
|
||||
/* coincides with the exact bounding box for most glyphs, it can be */
|
||||
/* slightly larger in some situations (like when rotating an outline */
|
||||
/* which contains Bezier outside arcs). */
|
||||
/* */
|
||||
/* Computing the control box is very fast, while getting the bounding */
|
||||
/* box can take much more time as it needs to walk over all segments */
|
||||
/* and arcs in the outline. To get the latter, you can use the */
|
||||
/* `ftbbox' component which is dedicated to this single task. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* outline :: A pointer to the source outline descriptor. */
|
||||
/* */
|
||||
/* <Output> */
|
||||
/* cbox :: The outline's control box. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* Yes. */
|
||||
/* */
|
||||
BASE_FUNC
|
||||
void FT_Outline_Get_CBox( FT_Outline* outline,
|
||||
FT_BBox* cbox )
|
||||
{
|
||||
FT_Pos xMin, yMin, xMax, yMax;
|
||||
|
||||
if ( outline && cbox )
|
||||
{
|
||||
if ( outline->n_points == 0 )
|
||||
{
|
||||
xMin = 0;
|
||||
yMin = 0;
|
||||
xMax = 0;
|
||||
yMax = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_Vector* vec = outline->points;
|
||||
FT_Vector* limit = vec + outline->n_points;
|
||||
|
||||
xMin = xMax = vec->x;
|
||||
yMin = yMax = vec->y;
|
||||
vec++;
|
||||
|
||||
for ( ; vec < limit; vec++ )
|
||||
{
|
||||
FT_Pos x, y;
|
||||
|
||||
x = vec->x;
|
||||
if ( x < xMin ) xMin = x;
|
||||
if ( x > xMax ) xMax = x;
|
||||
|
||||
y = vec->y;
|
||||
if ( y < yMin ) yMin = y;
|
||||
if ( y > yMax ) yMax = y;
|
||||
}
|
||||
}
|
||||
cbox->xMin = xMin;
|
||||
cbox->xMax = xMax;
|
||||
cbox->yMin = yMin;
|
||||
cbox->yMax = yMax;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Translate */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Applies a simple translation to the points of an outline. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* outline :: A pointer to the target outline descriptor. */
|
||||
/* xOffset :: The horizontal offset. */
|
||||
/* yOffset :: The vertical offset. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* Yes. */
|
||||
/* */
|
||||
BASE_FUNC
|
||||
void FT_Outline_Translate( FT_Outline* outline,
|
||||
FT_Pos xOffset,
|
||||
FT_Pos yOffset )
|
||||
{
|
||||
FT_UShort n;
|
||||
FT_Vector* vec = outline->points;
|
||||
|
||||
for ( n = 0; n < outline->n_points; n++ )
|
||||
{
|
||||
vec->x += xOffset;
|
||||
vec->y += yOffset;
|
||||
vec++;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Reverse */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Reverse the drawing direction of an outline. This is used to */
|
||||
/* ensure consistent fill conventions for mirrored glyphs.. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* outline :: A pointer to the target outline descriptor. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* This functions toggles the bit flag ft_outline_reverse_fill in */
|
||||
/* the outline's "flags" field.. */
|
||||
/* */
|
||||
BASE_FUNC
|
||||
void FT_Outline_Reverse( FT_Outline* outline )
|
||||
{
|
||||
FT_UShort n;
|
||||
FT_Int first, last;
|
||||
|
||||
first = 0;
|
||||
for ( n = 0; n < outline->n_contours; n++ )
|
||||
{
|
||||
last = outline->contours[n];
|
||||
|
||||
/* reverse point table */
|
||||
{
|
||||
FT_Vector* p = outline->points + first;
|
||||
FT_Vector* q = outline->points + last;
|
||||
FT_Vector swap;
|
||||
|
||||
while (p < q)
|
||||
{
|
||||
swap = *p;
|
||||
*p = *q;
|
||||
*q = swap;
|
||||
p++;
|
||||
q--;
|
||||
}
|
||||
}
|
||||
|
||||
/* reverse tags table */
|
||||
{
|
||||
char* p = outline->tags + first;
|
||||
char* q = outline->tags + last;
|
||||
char swap;
|
||||
|
||||
while (p < q)
|
||||
{
|
||||
swap = *p;
|
||||
*p = *q;
|
||||
*q = swap;
|
||||
p++;
|
||||
q--;
|
||||
}
|
||||
}
|
||||
|
||||
first = last+1;
|
||||
}
|
||||
outline->flags ^= ft_outline_reverse_fill;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Done_GlyphZone */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Deallocates a glyph zone. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* zone :: pointer to the target glyph zone. */
|
||||
/* */
|
||||
BASE_FUNC
|
||||
void FT_Done_GlyphZone( FT_GlyphZone* zone )
|
||||
{
|
||||
FT_Memory memory = zone->memory;
|
||||
|
||||
FREE( zone->contours );
|
||||
FREE( zone->tags );
|
||||
FREE( zone->cur );
|
||||
FREE( zone->org );
|
||||
|
||||
zone->max_points = zone->n_points = 0;
|
||||
zone->max_contours = zone->n_contours = 0;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_New_GlyphZone */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Allocates a new glyph zone. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* memory :: A handle to the current memory object. */
|
||||
/* */
|
||||
/* maxPoints :: The capacity of glyph zone in points. */
|
||||
/* */
|
||||
/* maxContours :: The capacity of glyph zone in contours. */
|
||||
/* */
|
||||
/* <Output> */
|
||||
/* zone :: A pointer to the target glyph zone record. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
BASE_FUNC
|
||||
FT_Error FT_New_GlyphZone( FT_Memory memory,
|
||||
FT_UShort maxPoints,
|
||||
FT_Short maxContours,
|
||||
FT_GlyphZone* zone )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
if (maxPoints > 0)
|
||||
maxPoints += 2;
|
||||
|
||||
MEM_Set( zone, 0, sizeof(*zone) );
|
||||
zone->memory = memory;
|
||||
|
||||
if ( ALLOC_ARRAY( zone->org, maxPoints*2, FT_F26Dot6 ) ||
|
||||
ALLOC_ARRAY( zone->cur, maxPoints*2, FT_F26Dot6 ) ||
|
||||
ALLOC_ARRAY( zone->tags, maxPoints, FT_Byte ) ||
|
||||
ALLOC_ARRAY( zone->contours, maxContours, FT_UShort ) )
|
||||
{
|
||||
FT_Done_GlyphZone(zone);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Update_GlyphZone */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Checks the size of a zone and reallocates it if necessary. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* newPoints :: The new capacity for points. We add two slots for */
|
||||
/* phantom points. */
|
||||
/* */
|
||||
/* newContours :: The new capacity for contours. */
|
||||
/* */
|
||||
/* <InOut> */
|
||||
/* zone :: The address of the target zone. */
|
||||
/* */
|
||||
/* maxPoints :: The address of the zone's current capacity for */
|
||||
/* points. */
|
||||
/* */
|
||||
/* maxContours :: The address of the zone's current capacity for */
|
||||
/* contours. */
|
||||
/* */
|
||||
BASE_FUNC
|
||||
FT_Error FT_Update_GlyphZone( FT_GlyphZone* zone,
|
||||
FT_UShort newPoints,
|
||||
FT_Short newContours )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Memory memory = zone->memory;
|
||||
|
||||
newPoints += 2;
|
||||
if ( zone->max_points < newPoints )
|
||||
{
|
||||
/* reallocate the points arrays */
|
||||
if ( REALLOC_ARRAY( zone->org, zone->max_points*2, newPoints*2, FT_F26Dot6 ) ||
|
||||
REALLOC_ARRAY( zone->cur, zone->max_points*2, newPoints*2, FT_F26Dot6 ) ||
|
||||
REALLOC_ARRAY( zone->tags, zone->max_points*2, newPoints, FT_Byte ) )
|
||||
goto Exit;
|
||||
|
||||
zone->max_points = newPoints;
|
||||
}
|
||||
|
||||
if ( zone->max_contours < newContours )
|
||||
{
|
||||
/* reallocate the contours array */
|
||||
if ( REALLOC_ARRAY( zone->contours, zone->max_contours, newContours, FT_UShort ) )
|
||||
goto Exit;
|
||||
|
||||
zone->max_contours = newContours;
|
||||
}
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Get_Bitmap */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Renders an outline within a bitmap. The outline's image is simply */
|
||||
/* or-ed to the target bitmap. */
|
||||
/* */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* library :: A handle to a FreeType library object. */
|
||||
/* outline :: A pointer to the source outline descriptor. */
|
||||
/* map :: A pointer to the target bitmap descriptor. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* YES. Rendering is synchronized, so that concurrent calls to the */
|
||||
/* scan-line converter will be serialized. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* This function does NOT CREATE the bitmap, it only renders an */
|
||||
/* outline image within the one you pass to it! */
|
||||
/* */
|
||||
/* It will use the raster correponding to the default glyph format. */
|
||||
/* */
|
||||
EXPORT_FUNC
|
||||
FT_Error FT_Outline_Get_Bitmap( FT_Library library,
|
||||
FT_Outline* outline,
|
||||
FT_Bitmap* map )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Raster raster;
|
||||
FT_Raster_Funcs funcs;
|
||||
FT_Raster_Params params;
|
||||
|
||||
error = FT_Err_Invalid_Glyph_Format;
|
||||
raster = FT_Get_Raster( library, ft_glyph_format_outline, &funcs );
|
||||
if (!raster) goto Exit;
|
||||
|
||||
params.target = map;
|
||||
params.source = outline;
|
||||
params.flags = 0;
|
||||
if (map->pixel_mode == ft_pixel_mode_grays)
|
||||
params.flags |= ft_raster_flag_aa;
|
||||
|
||||
error = funcs.raster_render( raster, ¶ms );
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Render */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Renders an outline within a bitmap using the current scan-convert */
|
||||
/* This functions uses a FT_Raster_Params as argument, allowing */
|
||||
/* advanced features like direct composition/translucency, etc.. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* library :: A handle to a FreeType library object. */
|
||||
/* outline :: A pointer to the source outline descriptor. */
|
||||
/* params :: A pointer to a FT_Raster_Params used to describe */
|
||||
/* the rendering operation */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* YES. Rendering is synchronized, so that concurrent calls to the */
|
||||
/* scan-line converter will be serialized. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* You should know what you're doing and the role of FT_Raster_Params */
|
||||
/* to use this function. */
|
||||
/* */
|
||||
/* the field "params.source" will be set to "outline" before the */
|
||||
/* scan converter is called, which means that the value you give it */
|
||||
/* is actually ignored.. */
|
||||
/* */
|
||||
EXPORT_FUNC
|
||||
FT_Error FT_Outline_Render( FT_Library library,
|
||||
FT_Outline* outline,
|
||||
FT_Raster_Params* params )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Raster raster;
|
||||
FT_Raster_Funcs funcs;
|
||||
|
||||
error = FT_Err_Invalid_Glyph_Format;
|
||||
raster = FT_Get_Raster( library, ft_glyph_format_outline, &funcs );
|
||||
if (!raster) goto Exit;
|
||||
|
||||
params->source = (void*)outline;
|
||||
error = funcs.raster_render( raster, params );
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/**** ****/
|
||||
/**** The following functions are not used by the font drivers ****/
|
||||
/**** but they are provided as a convenience for client apps. ****/
|
||||
/**** ****/
|
||||
/**** Note that they will not be compiled if the configuration ****/
|
||||
/**** macro FT_CONFIG_OPTION_NO_CONVENIENCE_FUNCS is defined ****/
|
||||
/**** ****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef FT_CONFIG_OPTION_NO_CONVENIENCE_FUNCS
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
@ -76,55 +810,6 @@
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Get_Bitmap */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Renders an outline within a bitmap. The outline's image is simply */
|
||||
/* or-ed to the target bitmap. */
|
||||
/* */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* library :: A handle to a FreeType library object. */
|
||||
/* outline :: A pointer to the source outline descriptor. */
|
||||
/* map :: A pointer to the target bitmap descriptor. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* YES. Rendering is synchronized, so that concurrent calls to the */
|
||||
/* scan-line converter will be serialized. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* This function does NOT CREATE the bitmap, it only renders an */
|
||||
/* outline image within the one you pass to it! */
|
||||
/* */
|
||||
/* It will use the raster correponding to the default glyph format. */
|
||||
/* */
|
||||
BASE_FUNC
|
||||
FT_Error FT_Outline_Get_Bitmap( FT_Library library,
|
||||
FT_Outline* outline,
|
||||
FT_Bitmap* map )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Glyph_Format* format;
|
||||
|
||||
error = FT_Err_Invalid_Glyph_Format;
|
||||
format = FT_Get_Glyph_Format( library, ft_glyph_format_outline );
|
||||
if (!format) goto Exit;
|
||||
|
||||
error = FT_Err_Invalid_Glyph_Format;
|
||||
if (!format->raster) goto Exit;
|
||||
|
||||
error = format->raster_interface->render( format->raster, outline, map );
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
@ -158,7 +843,6 @@
|
||||
{
|
||||
FT_Pos x, y;
|
||||
|
||||
|
||||
x = FT_MulFix( vec->x, matrix->xx ) +
|
||||
FT_MulFix( vec->y, matrix->xy );
|
||||
|
||||
@ -181,8 +865,7 @@
|
||||
/* Transforms a single vector through a 2x2 matrix. */
|
||||
/* */
|
||||
/* <InOut> */
|
||||
/* x :: The horizontal vector coordinate. */
|
||||
/* y :: The vertical vector coordinate. */
|
||||
/* vector :: The target vector to transform */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* matrix :: A pointer to the source 2x2 matrix. */
|
||||
@ -190,22 +873,20 @@
|
||||
/* <MT-Note> */
|
||||
/* Yes. */
|
||||
/* */
|
||||
BASE_FUNC
|
||||
void FT_Vector_Transform( FT_Pos* x,
|
||||
FT_Pos* y,
|
||||
EXPORT_DEF
|
||||
void FT_Vector_Transform( FT_Vector* vector,
|
||||
FT_Matrix* matrix )
|
||||
{
|
||||
FT_Pos xz, yz;
|
||||
|
||||
xz = FT_MulFix( vector->x, matrix->xx ) +
|
||||
FT_MulFix( vector->y, matrix->xy );
|
||||
|
||||
xz = FT_MulFix( *x, matrix->xx ) +
|
||||
FT_MulFix( *y, matrix->xy );
|
||||
yz = FT_MulFix( vector->x, matrix->yx ) +
|
||||
FT_MulFix( vector->y, matrix->yy );
|
||||
|
||||
yz = FT_MulFix( *x, matrix->yx ) +
|
||||
FT_MulFix( *y, matrix->yy );
|
||||
|
||||
*x = xz;
|
||||
*y = yz;
|
||||
vector->x = xz;
|
||||
vector->y = yz;
|
||||
}
|
||||
|
||||
|
||||
@ -286,5 +967,6 @@
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* END */
|
||||
|
@ -3,151 +3,4 @@
|
||||
|
||||
#include <ftobjs.h>
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Copy */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Copies an outline into another one. Both objects must have the */
|
||||
/* same sizes (number of points & number of contours) when this */
|
||||
/* function is called. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* source :: A handle to the source outline. */
|
||||
/* target :: A handle to the target outline. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Outline_Copy( FT_Outline* source,
|
||||
FT_Outline* target );
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Get_Bitmap */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Renders an outline within a bitmap. The outline's image is simply */
|
||||
/* or-ed to the target bitmap. */
|
||||
/* */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* library :: A handle to a FreeType library object. */
|
||||
/* outline :: A pointer to the source outline descriptor. */
|
||||
/* map :: A pointer to the target bitmap descriptor. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* YES. Rendering is synchronized, so that concurrent calls to the */
|
||||
/* scan-line converter will be serialized. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* This function does NOT CREATE the bitmap, it only renders an */
|
||||
/* outline image within the one you pass to it! */
|
||||
/* */
|
||||
/* It will use the raster correponding to the default glyph format. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Outline_Get_Bitmap( FT_Library library,
|
||||
FT_Outline* outline,
|
||||
FT_Bitmap* map );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Transform */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Applies a simple 2x2 matrix to all of an outline's points. Useful */
|
||||
/* for applying rotations, slanting, flipping, etc. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* outline :: A pointer to the target outline descriptor. */
|
||||
/* matrix :: A pointer to the transformation matrix. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* Yes. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* You can use FT_Outline_Translate() if you need to translate the */
|
||||
/* outline's points. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
void FT_Outline_Transform( FT_Outline* outline,
|
||||
FT_Matrix* matrix );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Vector_Transform */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Transforms a single vector through a 2x2 matrix. */
|
||||
/* */
|
||||
/* <InOut> */
|
||||
/* x :: The horizontal vector coordinate. */
|
||||
/* y :: The vertical vector coordinate. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* matrix :: A pointer to the source 2x2 matrix. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* Yes. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
void FT_Vector_Transform( FT_Pos* x,
|
||||
FT_Pos* y,
|
||||
FT_Matrix* matrix );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Matrix_Multiply */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Performs the matrix operation `b = a*b'. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* a :: A pointer to matrix `a'. */
|
||||
/* */
|
||||
/* <InOut> */
|
||||
/* b :: A pointer to matrix `b'. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* Yes. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
void FT_Matrix_Multiply( FT_Matrix* a,
|
||||
FT_Matrix* b );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Matrix_Invert */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Inverts a 2x2 matrix. Returns an error if it can't be inverted. */
|
||||
/* */
|
||||
/* <InOut> */
|
||||
/* matrix :: A pointer to the target matrix. Remains untouched in */
|
||||
/* case of error. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
/* <MT-Note> */
|
||||
/* Yes. */
|
||||
/* */
|
||||
EXPORT_DEF
|
||||
FT_Error FT_Matrix_Invert( FT_Matrix* matrix );
|
||||
|
||||
#endif /* FTOUTLN_H */
|
||||
|
@ -92,7 +92,7 @@
|
||||
/* Define this configuration macro if you want to support */
|
||||
/* anti-aliasing. */
|
||||
/* */
|
||||
#define FT_RASTER_OPTION_ANTI_ALIAS
|
||||
#undef FT_RASTER_OPTION_ANTI_ALIAS
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
@ -643,6 +643,7 @@
|
||||
TDirection state; /* rendering state */
|
||||
|
||||
FT_Bitmap target; /* description of target bit/pixmap */
|
||||
void* memory;
|
||||
|
||||
int trace_bit; /* current offset in target bitmap */
|
||||
int trace_pix; /* current offset in target pixmap */
|
||||
@ -2204,260 +2205,6 @@
|
||||
#endif /* FT_RASTER_CUBIC_BEZIERS */
|
||||
|
||||
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* The following function is compiled in the raster only when it is */
|
||||
/* compile as a stand-alone module.. */
|
||||
|
||||
/* It can, otherwise, be found in the FreeType base layer */
|
||||
|
||||
#ifdef _STANDALONE_
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Outline_Decompose */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Walks over an outline's structure to decompose it into individual */
|
||||
/* segments and Bezier arcs. This function is also able to emit */
|
||||
/* `move to' and `close to' operations to indicate the start and end */
|
||||
/* of new contours in the outline. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* outline :: A pointer to the source target. */
|
||||
/* */
|
||||
/* interface :: A table of `emitters', i.e,. function pointers called */
|
||||
/* during decomposition to indicate path operations. */
|
||||
/* */
|
||||
/* user :: A typeless pointer which is passed to each emitter */
|
||||
/* during the decomposition. It can be used to store */
|
||||
/* the state during the decomposition. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Error code. 0 means sucess. */
|
||||
/* */
|
||||
static
|
||||
int FT_Outline_Decompose( FT_Outline* outline,
|
||||
FT_Outline_Funcs* interface,
|
||||
void* user )
|
||||
{
|
||||
typedef enum _phases
|
||||
{
|
||||
phase_point,
|
||||
phase_conic,
|
||||
phase_cubic,
|
||||
phase_cubic2
|
||||
|
||||
} TPhase;
|
||||
|
||||
FT_Vector v_first;
|
||||
FT_Vector v_last;
|
||||
FT_Vector v_control;
|
||||
FT_Vector v_control2;
|
||||
FT_Vector v_start;
|
||||
|
||||
FT_Vector* point;
|
||||
char* flags;
|
||||
|
||||
int n; /* index of contour in outline */
|
||||
int first; /* index of first point in contour */
|
||||
int index; /* current point's index */
|
||||
|
||||
int error;
|
||||
|
||||
char tag; /* current point's state */
|
||||
TPhase phase;
|
||||
|
||||
|
||||
first = 0;
|
||||
|
||||
for ( n = 0; n < outline->n_contours; n++ )
|
||||
{
|
||||
int last; /* index of last point in contour */
|
||||
|
||||
|
||||
last = outline->contours[n];
|
||||
|
||||
v_first = outline->points[first];
|
||||
v_last = outline->points[last];
|
||||
|
||||
v_start = v_control = v_first;
|
||||
|
||||
tag = FT_CURVE_TAG( outline->flags[first] );
|
||||
index = first;
|
||||
|
||||
/* A contour cannot start with a cubic control point! */
|
||||
|
||||
if ( tag == FT_Curve_Tag_Cubic )
|
||||
return ErrRaster_Invalid_Outline;
|
||||
|
||||
|
||||
/* check first point to determine origin */
|
||||
|
||||
if ( tag == FT_Curve_Tag_Conic )
|
||||
{
|
||||
/* first point is conic control. Yes, this happens. */
|
||||
if ( FT_CURVE_TAG( outline->flags[last] ) == FT_Curve_Tag_On )
|
||||
{
|
||||
/* start at last point if it is on the curve */
|
||||
v_start = v_last;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if both first and last points are conic, */
|
||||
/* start at their middle and record its position */
|
||||
/* for closure */
|
||||
v_start.x = ( v_start.x + v_last.x ) / 2;
|
||||
v_start.y = ( v_start.y + v_last.y ) / 2;
|
||||
|
||||
v_last = v_start;
|
||||
}
|
||||
phase = phase_conic;
|
||||
}
|
||||
else
|
||||
phase = phase_point;
|
||||
|
||||
|
||||
/* Begin a new contour with MOVE_TO */
|
||||
|
||||
error = interface->move_to( &v_start, user );
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
point = outline->points + first;
|
||||
flags = outline->flags + first;
|
||||
|
||||
/* now process each contour point individually */
|
||||
|
||||
while ( index < last )
|
||||
{
|
||||
index++;
|
||||
point++;
|
||||
flags++;
|
||||
|
||||
tag = FT_CURVE_TAG( flags[0] );
|
||||
|
||||
switch ( phase )
|
||||
{
|
||||
case phase_point: /* the previous point was on the curve */
|
||||
|
||||
switch ( tag )
|
||||
{
|
||||
/* two succesive on points -> emit segment */
|
||||
case FT_Curve_Tag_On:
|
||||
error = interface->line_to( point, user );
|
||||
break;
|
||||
|
||||
/* on point + conic control -> remember control point */
|
||||
case FT_Curve_Tag_Conic:
|
||||
v_control = point[0];
|
||||
phase = phase_conic;
|
||||
break;
|
||||
|
||||
/* on point + cubic control -> remember first control */
|
||||
default:
|
||||
v_control = point[0];
|
||||
phase = phase_cubic;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case phase_conic: /* the previous point was a conic control */
|
||||
|
||||
switch ( tag )
|
||||
{
|
||||
/* conic control + on point -> emit conic arc */
|
||||
case FT_Curve_Tag_On:
|
||||
error = interface->conic_to( &v_control, point, user );
|
||||
phase = phase_point;
|
||||
break;
|
||||
|
||||
/* two successive conics -> emit conic arc `in between' */
|
||||
case FT_Curve_Tag_Conic:
|
||||
{
|
||||
FT_Vector v_middle;
|
||||
|
||||
|
||||
v_middle.x = (v_control.x + point->x)/2;
|
||||
v_middle.y = (v_control.y + point->y)/2;
|
||||
|
||||
error = interface->conic_to( &v_control,
|
||||
&v_middle, user );
|
||||
v_control = point[0];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
error = ErrRaster_Invalid_Outline;
|
||||
}
|
||||
break;
|
||||
|
||||
case phase_cubic: /* the previous point was a cubic control */
|
||||
|
||||
/* this point _must_ be a cubic control too */
|
||||
if ( tag != FT_Curve_Tag_Cubic )
|
||||
return ErrRaster_Invalid_Outline;
|
||||
|
||||
v_control2 = point[0];
|
||||
phase = phase_cubic2;
|
||||
break;
|
||||
|
||||
|
||||
case phase_cubic2: /* the two previous points were cubics */
|
||||
|
||||
/* this point _must_ be an on point */
|
||||
if ( tag != FT_Curve_Tag_On )
|
||||
error = ErrRaster_Invalid_Outline;
|
||||
else
|
||||
error = interface->cubic_to( &v_control, &v_control2,
|
||||
point, user );
|
||||
phase = phase_point;
|
||||
break;
|
||||
}
|
||||
|
||||
/* lazy error testing */
|
||||
if ( error )
|
||||
return error;
|
||||
}
|
||||
|
||||
/* end of contour, close curve cleanly */
|
||||
error = 0;
|
||||
|
||||
tag = FT_CURVE_TAG( outline->flags[first] );
|
||||
|
||||
switch ( phase )
|
||||
{
|
||||
case phase_point:
|
||||
if ( tag == FT_Curve_Tag_On )
|
||||
error = interface->line_to( &v_first, user );
|
||||
break;
|
||||
|
||||
case phase_conic:
|
||||
error = interface->conic_to( &v_control, &v_start, user );
|
||||
break;
|
||||
|
||||
case phase_cubic2:
|
||||
if ( tag == FT_Curve_Tag_On )
|
||||
error = interface->cubic_to( &v_control, &v_control2,
|
||||
&v_first, user );
|
||||
else
|
||||
error = ErrRaster_Invalid_Outline;
|
||||
break;
|
||||
|
||||
default:
|
||||
error = ErrRaster_Invalid_Outline;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
first = last + 1;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
@ -3109,14 +2856,6 @@
|
||||
x1 += PRECISION_HALF;
|
||||
x2 += PRECISION_HALF;
|
||||
|
||||
#ifdef FT_RASTER_OPTION_CONTRAST
|
||||
if ( x2-x1 < PRECISION )
|
||||
{
|
||||
x1 = ((x1+x2) >> 1) - PRECISION_HALF;
|
||||
x2 = x1 + PRECISION;
|
||||
}
|
||||
#endif
|
||||
|
||||
e1 = TRUNC( x1 );
|
||||
e2 = TRUNC( x2 );
|
||||
|
||||
@ -3324,14 +3063,6 @@
|
||||
x1 += PRECISION_HALF;
|
||||
x2 += PRECISION_HALF;
|
||||
|
||||
#ifdef FT_RASTER_OPTION_CONTRAST
|
||||
if (x2-x1 < PRECISION)
|
||||
{
|
||||
x1 = ((x1+x2) >> 1) - PRECISION_HALF;
|
||||
x2 = x1 + PRECISION;
|
||||
}
|
||||
#endif
|
||||
|
||||
e1 = TRUNC( x1 );
|
||||
e2 = TRUNC( x2 );
|
||||
|
||||
@ -4081,38 +3812,87 @@ Scan_DropOuts :
|
||||
#endif /* FT_RASTER_OPTION_ANTI_ALIAS */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Raster_Render */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Renders an outline into a target bitmap. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* raster :: A handle to the raster object used during rendering. */
|
||||
/* outline :: A pointer to the source outline record/object. */
|
||||
/* bitmap :: A pointer to the target bitmap descriptor. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Error code, interpreted as a FT_Error by FreeType. 0 means */
|
||||
/* success. */
|
||||
/* */
|
||||
EXPORT_FUNC
|
||||
int FT_Raster_Render( FT_Raster raster,
|
||||
FT_Outline* outline,
|
||||
FT_Bitmap* target_map )
|
||||
|
||||
/**** RASTER OBJECT CREATION : in standalone mode, we simply use *****/
|
||||
/**** a static object .. *****/
|
||||
#ifdef _STANDALONE_
|
||||
|
||||
static
|
||||
int ft_raster_new( void* memory, FT_Raster *araster )
|
||||
{
|
||||
static FT_RasterRec_ the_raster;
|
||||
*araster = &the_raster;
|
||||
memset( &the_raster, sizeof(the_raster), 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void ft_raster_done( FT_Raster raster )
|
||||
{
|
||||
/* nothing */
|
||||
raster->init = 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "ftobjs.h"
|
||||
|
||||
static
|
||||
int ft_raster_new( FT_Memory memory, FT_Raster* araster )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Raster raster;
|
||||
|
||||
*araster = 0;
|
||||
if ( !ALLOC( raster, sizeof(*raster) ))
|
||||
{
|
||||
raster->memory = memory;
|
||||
*araster = raster;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static
|
||||
void ft_raster_done( FT_Raster raster )
|
||||
{
|
||||
FT_Memory memory = (FT_Memory)raster->memory;
|
||||
FREE( raster );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static void ft_raster_reset( FT_Raster raster,
|
||||
const char* pool_base,
|
||||
long pool_size )
|
||||
{
|
||||
if ( raster && pool_base && pool_size >= 4096 )
|
||||
{
|
||||
/* save the pool */
|
||||
raster->pool = (PPos)pool_base;
|
||||
raster->pool_size = raster->pool + pool_size / sizeof ( TPos );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int ft_raster_render( FT_Raster raster,
|
||||
FT_Raster_Params* params )
|
||||
{
|
||||
FT_Outline* outline = (FT_Outline*)params->source;
|
||||
FT_Bitmap* target_map = params->target;
|
||||
|
||||
if ( !raster || !raster->pool || !raster->pool_size )
|
||||
return ErrRaster_Uninitialized_Object;
|
||||
|
||||
if ( !outline || !outline->contours || !outline->points )
|
||||
return ErrRaster_Invalid_Outline;
|
||||
|
||||
/* return immediately if the outline is empty */
|
||||
if ( outline->n_points == 0 || outline->n_contours <= 0 )
|
||||
return ErrRaster_Ok;
|
||||
|
||||
if ( !outline || !outline->contours || !outline->points )
|
||||
return ErrRaster_Invalid_Outline;
|
||||
|
||||
if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 )
|
||||
return ErrRaster_Invalid_Outline;
|
||||
|
||||
@ -4125,107 +3905,29 @@ Scan_DropOuts :
|
||||
/* Note that we always use drop-out mode 2, because it seems that */
|
||||
/* it's the only way to do to get results consistent with Windows */
|
||||
/* rendering.. */
|
||||
#if 0
|
||||
ras.dropout_mode = outline->dropout_mode;
|
||||
#else
|
||||
ras.dropout_mode = 2;
|
||||
#endif
|
||||
|
||||
ras.second_pass = (outline->flags & ft_outline_single_pass) == 0;
|
||||
SET_High_Precision( (char)((outline->flags & ft_outline_high_precision)!= 0) );
|
||||
|
||||
switch ( target_map->pixel_mode )
|
||||
{
|
||||
case ft_pixel_mode_mono: return Raster_Render1( raster );
|
||||
case ft_pixel_mode_grays: return Raster_Render8( raster );
|
||||
default: return ErrRaster_Unimplemented;
|
||||
}
|
||||
/* this version of the raster does not support direct rendering, sorry */
|
||||
if ( params->flags & ft_raster_flag_direct )
|
||||
return ErrRaster_Unimplemented;
|
||||
|
||||
return ( params->flags & ft_raster_flag_aa
|
||||
? Raster_Render8( raster )
|
||||
: Raster_Render1( raster ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Raster_ObjSize */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* This function returns the size of a raster object in bytes. */
|
||||
/* Client applications are thus able to allocate objects in their own */
|
||||
/* heap/memory space, without revealing the internal structures of */
|
||||
/* the scan-line converter. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* The size in bytes of a single raster object. */
|
||||
/* */
|
||||
EXPORT_FUNC
|
||||
long FT_Raster_ObjSize( void )
|
||||
FT_Raster_Funcs ft_default_raster =
|
||||
{
|
||||
return (long)sizeof( struct FT_RasterRec_ );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Raster_Init */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Initializes a fresh raster object which should have been allocated */
|
||||
/* by client applications. This function is also used to set the */
|
||||
/* object's render pool. It can be used repeatedly on a single */
|
||||
/* object if one wants to change the pool's address or size. */
|
||||
/* */
|
||||
/* Note that the render pool has no state and is only used during a */
|
||||
/* call to FT_Raster_Render(). It is thus theorically possible to */
|
||||
/* share it between several non-concurrent components of your */
|
||||
/* applications when memory is a scarce resource. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* pool_size :: The render pool's size in bytes. This must be at */
|
||||
/* least 4 kByte. */
|
||||
/* */
|
||||
/* <InOut> */
|
||||
/* raster :: A handle to the target raster object. */
|
||||
/* */
|
||||
/* pool_base :: The render pool's base address in memory. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* An error condition, used as a FT_Error in the FreeType library. */
|
||||
/* 0 means success. */
|
||||
/* */
|
||||
EXPORT_FUNC
|
||||
int FT_Raster_Init( FT_Raster raster,
|
||||
const char* pool_base,
|
||||
long pool_size )
|
||||
{
|
||||
/* static const char default_palette[5] = { 0, 1, 2, 3, 4 }; */
|
||||
|
||||
/* check the object address */
|
||||
if ( !raster )
|
||||
return ErrRaster_Uninitialized_Object;
|
||||
|
||||
/* check the render pool - we won't go under 4 Kb */
|
||||
if ( !pool_base || pool_size < 4096 )
|
||||
return ErrRaster_Invalid_Pool;
|
||||
|
||||
/* save the pool */
|
||||
raster->pool = (PPos)pool_base;
|
||||
raster->pool_size = raster->pool + pool_size / sizeof ( TPos );
|
||||
|
||||
return ErrRaster_Ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
FT_Raster_Interface ft_default_raster =
|
||||
{
|
||||
sizeof( struct FT_RasterRec_ ),
|
||||
ft_glyph_format_outline,
|
||||
|
||||
(FT_Raster_Init_Proc) FT_Raster_Init,
|
||||
(FT_Raster_Set_Mode_Proc) 0,
|
||||
(FT_Raster_Render_Proc) FT_Raster_Render
|
||||
(FT_Raster_New_Func) ft_raster_new,
|
||||
(FT_Raster_Reset_Func) ft_raster_reset,
|
||||
(FT_Raster_Set_Mode_Func) 0,
|
||||
(FT_Raster_Render_Func) ft_raster_render,
|
||||
(FT_Raster_Done_Func) ft_raster_done
|
||||
};
|
||||
|
||||
|
||||
|
@ -33,7 +33,9 @@ BASE_SRC := $(BASE_)ftcalc.c \
|
||||
$(BASE_)ftextend.c \
|
||||
$(BASE_)ftlist.c \
|
||||
$(BASE_)ftobjs.c \
|
||||
$(BASE_)ftstream.c
|
||||
$(BASE_)ftstream.c \
|
||||
$(BASE_)ftoutln.c
|
||||
|
||||
|
||||
# Base layer headers
|
||||
#
|
||||
@ -53,7 +55,7 @@ BASE_H := $(BASE_)ftcalc.h \
|
||||
# symbols is used by the application.
|
||||
#
|
||||
BASE_EXT_SRC := $(BASE_)ftraster.c \
|
||||
$(BASE_)ftoutln.c
|
||||
$(BASE_)ftglyph.c
|
||||
|
||||
# Base layer extensions headers
|
||||
#
|
||||
|
Loading…
Reference in New Issue
Block a user