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:
David Turner 2000-03-28 11:22:31 +00:00
parent ed7f62aca5
commit 37379e2170
20 changed files with 3613 additions and 2910 deletions

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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
};

View File

@ -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

View File

@ -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
};

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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
View 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 */

View File

@ -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 */

View File

@ -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
View 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:
;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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, &params );
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 */

View File

@ -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 */

View File

@ -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
};

View File

@ -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
#