ref: 37379e2170f4e8c28bb9271929dcca76eab22a07
parent: ed7f62aca5eab9d808daf0879607779bd2670173
author: David Turner <[email protected]>
date: Tue Mar 28 06:22:31 EST 2000
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..
--- a/config/ftoption.h
+++ b/config/ftoption.h
@@ -46,6 +46,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 */
/* */
/* By default, the glyph images returned by the FreeType glyph loader */
--- a/config/unix/detect.mk
+++ b/config/unix/detect.mk
@@ -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
--- a/demos/Makefile
+++ b/demos/Makefile
@@ -152,7 +152,7 @@
#
# 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 @@
$(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 @@
$(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 @@
$(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,8 +268,19 @@
$(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
--- a/demos/src/ftgrays.c
+++ b/demos/src/ftgrays.c
@@ -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,8 +96,72 @@
#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 */
/* */
static
@@ -783,401 +852,8 @@
#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,
FT_Raster raster )
{
@@ -1224,7 +900,7 @@
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 @@
}
#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 @@
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 @@
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,8 +1031,8 @@
ras.num_gray_spans++;
}
}
-#endif
+
static
void grays_sweep( RAS_ARG_ FT_Bitmap* target )
{
@@ -1427,7 +1096,7 @@
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 @@
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 @@
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 @@
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,8 +1188,14 @@
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;
@@ -1521,41 +1202,76 @@
}
+ /**** RASTER OBJECT CREATION : in standalone mode, we simply use *****/
+ /**** a static object .. *****/
+#ifdef _STANDALONE_
+ static
+ int grays_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 grays_raster_done( FT_Raster raster )
+ {
+ /* nothing */
+ (void)raster;
+ }
+#else
- extern
- int grays_raster_init( FT_Raster raster,
- const char* pool_base,
- long pool_size )
+#include "ftobjs.h"
+
+ static
+ int grays_raster_new( FT_Memory memory, FT_Raster* araster )
{
-/* static const char default_palette[5] = { 0, 1, 2, 3, 4 }; */
+ 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
- /* 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;
+ 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
};
-
--- a/demos/src/ftgrays.h
+++ b/demos/src/ftgrays.h
@@ -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
--- a/demos/src/ftgrays2.c
+++ b/demos/src/ftgrays2.c
@@ -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 @@
/* 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 @@
/* 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 @@
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)
@@ -424,6 +529,35 @@
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 )
{
TPos x0, y0;
@@ -484,32 +618,6 @@
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,
TPos x3, TPos y3 )
@@ -581,9 +689,393 @@
}
}
}
+#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
int is_less_than( PCell a, PCell b )
{
if (a->y < b->y) goto Yes;
@@ -592,8 +1084,8 @@
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 @@
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 @@
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 @@
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 @@
/* 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,16 +1992,15 @@
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;
+
+ else
+ area = (varea+harea+ONE_PIXEL) >> 1;
-#if 1
- if ( varea < ONE_PIXEL && harea == 0 && (icover|cover) == 0 && area < ONE_PIXEL)
- area += ONE_HALF;
-#endif
-
is_black = ( area >= 2*ONE_PIXEL );
/* if the start cell isn't black, we may need to draw a black */
@@ -1604,19 +2106,27 @@
/* 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 @@
}
+ /**** 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
- extern
- int grays2_raster_init( FT_Raster raster,
- const char* pool_base,
- long pool_size )
+#include "ftobjs.h"
+
+ static
+ int grays2_raster_new( FT_Memory memory, FT_Raster* araster )
{
-/* static const char default_palette[5] = { 0, 1, 2, 3, 4 }; */
+ 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
- /* 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;
+ static
+ void grays2_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_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
};
-
--- a/demos/src/ftgrays2.h
+++ b/demos/src/ftgrays2.h
@@ -1,102 +1,9 @@
#ifndef FTGRAYS2_H
#define FTGRAYS2_H
-typedef int TScan;
-typedef long TPos;
-typedef float TDist;
+#include <ftimage.h>
-#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;
-
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
--- a/demos/src/fttimer.c
+++ b/demos/src/fttimer.c
@@ -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;
--- a/demos/src/ftview.c
+++ b/demos/src/ftview.c
@@ -59,7 +59,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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;
--- a/include/freetype.h
+++ b/include/freetype.h
@@ -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;
@@ -1568,46 +1612,6 @@
/*************************************************************************/
/* */
/* <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> */
/* FT_Set_Char_Size */
/* */
/* <Description> */
@@ -1660,48 +1664,6 @@
/*************************************************************************/
/* */
/* <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> */
/* FT_Load_Glyph */
/* */
/* <Description> */
@@ -1875,8 +1837,12 @@
/* 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
/*************************************************************************/
@@ -1896,36 +1862,6 @@
/*************************************************************************/
/* */
/* <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> */
/* FT_Get_Kerning */
/* */
/* <Description> */
@@ -2087,6 +2023,75 @@
/*************************************************************************/
/* */
/* <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> */
/* FT_Outline_Decompose */
/* */
/* <Description> */
@@ -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,25 +2255,81 @@
/* Register a given raster to the library. */
/* */
/* <Input> */
- /* library :: A handle to a target library object. */
+ /* library :: A handle to a target library object. */
+ /* raster_funcs :: pointer to the raster's interface */
/* */
- /* 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. */
/* */
+ /* <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_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_Set_Raster( FT_Library library,
- FT_Raster_Interface* interface,
- FT_Raster raster );
+ 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 );
+
+
/*************************************************************************/
/* */
/* <Function> */
@@ -2289,11 +2347,162 @@
/* 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
}
--- /dev/null
+++ b/include/ftglyph.h
@@ -1,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 */
--- a/include/ftimage.h
+++ b/include/ftimage.h
@@ -470,8 +470,6 @@
} FT_Outline_Funcs;
-
-
/*************************************************************************/
/* */
/* <Macro> */
@@ -491,7 +489,7 @@
/***********************************************************************
*
* <Enum>
- * FT_Glyph_Tag
+ * FT_Glyph_Format
*
* <Description>
* An enumeration type used to describethe format of a given glyph
@@ -518,7 +516,7 @@
*
***********************************************************************/
- typedef enum FT_Glyph_Tag_
+ typedef enum FT_Glyph_Format_
{
ft_glyph_format_none = 0,
ft_glyph_format_composite = FT_IMAGE_TAG('c','o','m','p'),
@@ -526,9 +524,29 @@
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 *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /**************************************************************************
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ **************************************************************************/
+
/*************************************************************************/
/* */
/* <Type> */
@@ -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,
- 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 );
+ 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_Interface
+ * FT_Raster_Params
*
* <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 hold the arguments used by a raster's render
+ * function.
+ *
* <Fields>
- * size :: the size in bytes of the given raster object. This
- * is used to allocate a new raster when calling
- * `FT_Set_Raster'.
+ * 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..
*
- * format :: the source glyph image format this raster is able to
- * handle.
+ * <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.
*
- * init :: the raster's initialisation routine
+ * 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.
*
- * set_mode :: the raster's mode set routine
+ * This allows direct composition over a pre-existing bitmap through
+ * user-provided callbacks to perform the span drawing/composition.
*
- * render :: the raster's rendering routine
+ * 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_Interface_
+ typedef struct FT_Raster_Params_
{
- 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_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_Interface;
+ } 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,
+ 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_Funcs
+ *
+ * <Description>
+ * A structure used to describe a given raster class to the library.
+ *
+ * <Fields>
+ * 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_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 */
--- a/include/ftraster.h
+++ b/include/ftraster.h
@@ -38,25 +38,7 @@
#endif
EXPORT_DEF
- int FT_Raster_Init( FT_Raster raster,
- const char* pool_base,
- long pool_size );
-
- EXPORT_DEF
- int FT_Raster_Render( FT_Raster raster,
- FT_Outline* outline,
- FT_Bitmap* target_map );
-
- EXPORT_DEF
- long FT_Raster_ObjSize( void );
-
- /* FT_Raster_SetPalette() is currently unused by FreeType 2 */
-
- EXPORT_DEF
- int FT_Raster_SetPalette( FT_Raster raster,
- int count,
- const char* palette );
-
+ FT_Raster_Funcs ft_raster_funcs;
#ifdef __cplusplus
}
--- /dev/null
+++ b/src/base/ftglyph.c
@@ -1,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:
+ ;
+ }
+ }
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -220,48 +220,58 @@
static
FT_Error ft_new_input_stream( FT_Library library,
FT_Open_Args* args,
- FT_Stream* astream )
+ FT_Stream *astream )
{
FT_Error error;
FT_Memory memory;
FT_Stream stream;
-
- memory = library->memory;
+ *astream = 0;
+ memory = library->memory;
if ( ALLOC( stream, sizeof ( *stream ) ) )
- return error;
+ goto Exit;
stream->memory = memory;
- /* is it a memory stream? */
- if ( args->memory_base && args->memory_size )
- FT_New_Memory_Stream( library,
- args->memory_base,
- args->memory_size,
- stream );
-
- /* do we have an 8-bit pathname? */
- else if ( args->pathname )
+ /* now, look at the stream type */
+ switch ( args->stream_type )
{
- error = FT_New_Stream( args->pathname, stream );
- stream->pathname.pointer = args->pathname;
- }
-
- /* do we have a custom stream? */
- else if ( args->stream )
- {
- /* copy the contents of the argument stream */
- /* into the new stream object */
- *stream = *(args->stream);
- stream->memory = memory;
- }
- else
- error = FT_Err_Invalid_Argument;
+ /***** is it a memory-based stream ? *****************************/
+ case ft_stream_memory:
+ {
+ FT_New_Memory_Stream( library,
+ args->memory_base,
+ args->memory_size,
+ stream );
+ break;
+ }
+ /***** is is a pathname stream ? ********************************/
+ case ft_stream_pathname:
+ {
+ error = FT_New_Stream( args->pathname, stream );
+ stream->pathname.pointer = args->pathname;
+ break;
+ }
+
+ case ft_stream_copy:
+ {
+ if ( args->stream)
+ {
+ *stream = *(args->stream);
+ stream->memory = memory;
+ break;
+ }
+ }
+ default:
+ error = FT_Err_Invalid_Argument;
+ }
+
if ( error )
FREE( stream );
*astream = stream;
+ Exit:
return error;
}
@@ -280,7 +290,6 @@
FT_Stream stream = *astream;
FT_Memory memory = stream->memory;
-
if ( stream->close )
stream->close( stream );
@@ -387,110 +396,171 @@
}
+ /*************************************************************************
+ *
+ * <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 the raster's interface
+ *
+ * <Return>
+ * a pointer to the corresponding raster object.
+ *
+ *************************************************************************/
+
+ EXPORT_FUNC
+ FT_Raster FT_Get_Raster( FT_Library library,
+ FT_Glyph_Format glyph_format,
+ FT_Raster_Funcs *raster_funcs )
+ {
+ FT_Int n;
+
+ for ( n = 0; n < FT_MAX_GLYPH_FORMATS; n++ )
+ {
+ FT_Raster_Funcs* funcs = &library->raster_funcs[n];
+ if (funcs->glyph_format == glyph_format)
+ {
+ if (raster_funcs)
+ *raster_funcs = *funcs;
+ return library->rasters[n];
+ }
+ }
+ return 0;
+ }
+
/*************************************************************************/
/* */
/* <Function> */
- /* FT_Get_Glyph_Format */
+ /* FT_Set_Raster */
/* */
/* <Description> */
- /* Gets the glyph format for a given format tag. */
+ /* Register a given raster to the library. */
/* */
/* <Input> */
- /* library :: A handle to the library object. */
- /* format_tag :: A tag identifying the glyph format. */
+ /* library :: A handle to a target library object. */
+ /* raster_funcs :: pointer to the raster's interface */
/* */
/* <Return> */
- /* A pointer to a glyph format. 0 if `format_tag' isn't defined. */
+ /* Error code. 0 means success. */
/* */
- BASE_FUNC
- FT_Glyph_Format* FT_Get_Glyph_Format( FT_Library library,
- FT_Glyph_Tag format_tag )
+ /* <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_FUNC
+ FT_Error FT_Set_Raster( FT_Library library,
+ FT_Raster_Funcs* raster_funcs )
{
- FT_Glyph_Format* cur = library->glyph_formats;
- FT_Glyph_Format* limit = cur + FT_MAX_GLYPH_FORMATS;
+ FT_Glyph_Format glyph_format = raster_funcs->glyph_format;
+ FT_Raster_Funcs* funcs;
+ FT_Raster raster;
+ FT_Error error;
+ FT_Int n, index;
+
+ if ( glyph_format == ft_glyph_format_none)
+ return FT_Err_Invalid_Argument;
+
+ /* create a new raster object */
+ error = raster_funcs->raster_new( library->memory, &raster );
+ if (error) goto Exit;
+
+ raster_funcs->raster_reset( raster,
+ library->raster_pool,
+ library->raster_pool_size );
+
+ index = -1;
+ for (n = 0; n < FT_MAX_GLYPH_FORMATS; n++)
+ {
+ FT_Raster_Funcs* funcs = library->raster_funcs + n;
+ /* record the first vacant entry in "index" */
+ if (index < 0 && funcs->glyph_format == ft_glyph_format_none)
+ index = n;
+
+ /* compare this entry's glyph format with the one we need */
+ if (funcs->glyph_format == glyph_format)
+ {
+ /* a raster already exists for this glyph format, we will */
+ /* destroy it before updating its entry in the table */
+ funcs->raster_done( library->rasters[n] );
+ index = n;
+ break;
+ }
+ }
- for ( ; cur < limit; cur ++ )
+ if (index < 0)
{
- if ( cur->format_tag == format_tag )
- return cur;
+ /* the table is full and has no vacant entries */
+ error = FT_Err_Too_Many_Glyph_Formats;
+ goto Fail;
}
- return 0;
- }
+ funcs = library->raster_funcs + index;
+ *funcs = *raster_funcs;
+ library->rasters[index] = raster;
+ Exit:
+ return error;
+ Fail:
+ raster_funcs->raster_done( raster );
+ goto Exit;
+ }
+
/*************************************************************************/
/* */
/* <Function> */
- /* FT_Set_Raster */
+ /* FT_Unset_Raster */
/* */
/* <Description> */
- /* This function changes the raster module used to convert from a */
- /* given memory object. It is thus possible to use libraries with */
- /* distinct memory allocators within the same program. */
+ /* Removes a given raster from the library. */
/* */
/* <Input> */
- /* library :: A handle to the library object. */
- /* interface :: A pointer to the interface of the new raster module. */
+ /* library :: A handle to a target library object. */
+ /* raster_funcs :: pointer to the raster's interface */
/* */
- /* <Output> */
- /* raster :: A handle to the raster object. */
- /* */
/* <Return> */
- /* FreeType error code. 0 means success. */
+ /* Error code. 0 means success. */
/* */
- EXPORT_FUNC
- FT_Error FT_Set_Raster( FT_Library library,
- FT_Raster_Interface* interface,
- FT_Raster raster )
+ EXPORT_DEF
+ FT_Error FT_Unset_Raster( FT_Library library,
+ FT_Raster_Funcs* raster_funcs )
{
- FT_Memory memory = library->memory;
- FT_Error error = FT_Err_Ok;
- FT_Glyph_Format* format;
-
-
- /* allocate the render pool if necessary */
- if ( !library->raster_pool &&
- ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
+ FT_Glyph_Format glyph_format = raster_funcs->glyph_format;
+ FT_Error error;
+ FT_Int n;
+
+ error = FT_Err_Invalid_Argument;
+ if ( glyph_format == ft_glyph_format_none)
goto Exit;
- /* find the glyph formatter for the raster's format */
- format = FT_Get_Glyph_Format( library, interface->format_tag );
- if ( !format )
+ for (n = 0; n < FT_MAX_GLYPH_FORMATS; n++)
{
- error = FT_Err_Invalid_Argument;
- goto Exit;
- }
+ FT_Raster_Funcs* funcs = library->raster_funcs + n;
- /* free previous raster object if necessary */
- if ( format->raster_allocated )
- {
- FREE( format->raster );
- format->raster_allocated = 0;
- }
-
- /* allocate new raster object is necessary */
- if ( !raster )
- {
- if ( ALLOC( raster, interface->size ) )
- goto Exit;
-
- format->raster_allocated = 1;
- }
- format->raster = raster;
- format->raster_interface = interface;
-
- /* initialize the raster object */
- error = interface->init( raster,
- (char*)library->raster_pool,
- FT_RENDER_POOL_SIZE );
- if ( error )
- {
- if ( format->raster_allocated )
+ if (funcs->glyph_format == glyph_format)
{
- FREE( format->raster );
- format->raster_allocated = 0;
+ funcs->raster_done( library->rasters[n] );
+ library->rasters[n] = 0;
+ library->raster_funcs[n].glyph_format = ft_glyph_format_none;
+ error = FT_Err_Ok;
+ break;
}
}
@@ -502,6 +572,38 @@
/*************************************************************************/
/* */
/* <Function> */
+ /* FT_Set_Raster_Mode */
+ /* */
+ /* <Description> */
+ /* Set a raster-specific mode. */
+ /* */
+ /* <Input> */
+ /* library :: A handle to a target library object. */
+ /* format :: the glyph format used to select the raster */
+ /* mode :: the raster-specific mode descriptor */
+ /* args :: the mode arguments */
+ /* <Return> */
+ /* Error code. 0 means success. */
+ /* */
+ EXPORT_FUNC
+ FT_Error FT_Set_Raster_Mode( FT_Library library,
+ FT_Glyph_Format format,
+ const char* mode,
+ void* args )
+ {
+ FT_Raster_Funcs funcs;
+ FT_Raster raster;
+
+ raster = FT_Get_Raster( library, format, &funcs );
+ if (raster && funcs.raster_set_mode )
+ return funcs.raster_set_mode( raster, mode, args );
+ else
+ return FT_Err_Invalid_Argument;
+ }
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
/* FT_Set_Debug_Hook */
/* */
/* <Description> */
@@ -532,105 +634,6 @@
/*************************************************************************/
/* */
/* <Function> */
- /* FT_Add_Glyph_Format */
- /* */
- /* <Description> */
- /* Adds a glyph format to the library. */
- /* */
- /* <InOut> */
- /* library :: A handle to the library object. */
- /* */
- /* <Input> */
- /* format :: A pointer to the new glyph format. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- BASE_FUNC
- FT_Error FT_Add_Glyph_Format( FT_Library library,
- FT_Glyph_Format* format )
- {
- FT_Glyph_Format* new = 0;
-
-
- {
- FT_Glyph_Format* cur = library->glyph_formats;
- FT_Glyph_Format* limit = cur + FT_MAX_GLYPH_FORMATS;
-
-
- for ( ; cur < limit; cur++ )
- {
- /* return an error if the format is already registered */
- if ( cur->format_tag == format->format_tag )
- return FT_Err_Invalid_Glyph_Format;
-
- if ( cur->format_tag == 0 && new == 0 )
- new = cur;
- }
- }
-
- /* if there is no place to hold the new format, return an error */
- if ( !new )
- return FT_Err_Too_Many_Glyph_Formats;
-
- *new = *format;
-
- /* now, create a raster object if we need to */
- return FT_Set_Raster( library,
- format->raster_interface,
- format->raster );
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* FT_Remove_Glyph_Format */
- /* */
- /* <Description> */
- /* Removes a glyph format from the library. */
- /* */
- /* <InOut> */
- /* library :: A handle to the library object. */
- /* */
- /* <Input> */
- /* format_tag :: A tag identifying the format to be removed. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- BASE_FUNC
- FT_Error FT_Remove_Glyph_Format( FT_Library library,
- FT_Glyph_Tag format_tag )
- {
- FT_Memory memory;
- FT_Glyph_Format* cur = library->glyph_formats;
- FT_Glyph_Format* limit = cur + FT_MAX_GLYPH_FORMATS;
-
-
- memory = library->memory;
-
- for ( ; cur < limit; cur++ )
- {
- if ( cur->format_tag == format_tag )
- {
- if ( cur->raster_allocated )
- {
- FREE( cur->raster );
- cur->raster_allocated = 0;
- }
- cur->format_tag = 0;
- return FT_Err_Ok;
- }
- }
-
- return FT_Err_Invalid_Argument;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
/* FT_New_Library */
/* */
/* <Description> */
@@ -654,7 +657,6 @@
FT_Library library = 0;
FT_Error error;
-
/* first of all, allocate the library object */
if ( ALLOC( library, sizeof ( *library ) ) )
return error;
@@ -661,24 +663,23 @@
library->memory = memory;
+ /* allocate the render pool */
+ library->raster_pool_size = FT_RENDER_POOL_SIZE;
+ if ( ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
+ goto Fail;
+
/* now register the default raster for the `outline' glyph image format */
- {
- FT_Glyph_Format outline_format =
- {
- ft_glyph_format_outline,
- &ft_default_raster,
- 0,
- 0
- };
+ /* for now, ignore the error... */
+ error = FT_Set_Raster( library, &ft_default_raster );
+
-
- error = FT_Add_Glyph_Format( library, &outline_format );
- }
-
/* That's ok now */
*alibrary = library;
return FT_Err_Ok;
+ Fail:
+ FREE( library );
+ return error;
}
@@ -726,20 +727,22 @@
}
}
- /* Destroy raster object */
+ /* Destroy raster objects */
FREE( library->raster_pool );
+ library->raster_pool_size = 0;
{
- FT_Glyph_Format* cur = library->glyph_formats;
- FT_Glyph_Format* limit = cur + FT_MAX_GLYPH_FORMATS;
+ FT_Raster_Funcs* cur = library->raster_funcs;
+ FT_Raster_Funcs* limit = cur + FT_MAX_GLYPH_FORMATS;
+ FT_Raster* raster = library->rasters;
-
- for ( ; cur < limit; cur++ )
+ for ( ; cur < limit; cur++, raster++ )
{
- if ( cur->raster_allocated )
+ if ( cur->glyph_format != ft_glyph_format_none )
{
- FREE( cur->raster );
- cur->raster_allocated = 0;
+ cur->raster_done( *raster );
+ *raster = 0;
+ cur->glyph_format = ft_glyph_format_none;
}
}
}
@@ -753,65 +756,6 @@
/*************************************************************************/
/* */
/* <Function> */
- /* FT_Set_Raster_Mode */
- /* */
- /* <Description> */
- /* Sets a raster-specific mode. */
- /* */
- /* <InOut> */
- /* library :: A handle to a target library object. */
- /* */
- /* <Input> */
- /* format :: The glyph format used to select the raster. */
- /* mode :: The raster-specific mode descriptor. */
- /* args :: The mode arguments. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- EXPORT_FUNC
- FT_Error FT_Set_Raster_Mode( FT_Library library,
- FT_Glyph_Tag format_tag,
- const char* mode,
- const char* args )
- {
- FT_Memory memory;
- FT_Error error;
- FT_Glyph_Format* format = 0;
-
-
- {
- FT_Glyph_Format* cur = library->glyph_formats;
- FT_Glyph_Format* limit = cur + FT_MAX_GLYPH_FORMATS;
-
-
- for ( ; cur < limit; cur++ )
- {
- if ( cur->format_tag == format_tag )
- {
- format = cur;
- break;
- }
- }
- }
-
- if ( !format )
- return FT_Err_Invalid_Argument;
-
- memory = library->memory;
-
- error = FT_Err_Ok;
- if ( format->raster )
- error = format->raster_interface->set_mode( format->raster,
- mode, args );
-
- return error;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
/* FT_Add_Driver */
/* */
/* <Description> */
@@ -1028,11 +972,7 @@
}
- static
- const FT_Open_Args ft_default_open_args =
- { 0, 0, 0, 0, 0 };
-
/*************************************************************************/
/* */
/* <Function> */
@@ -1076,10 +1016,11 @@
FT_Long face_index,
FT_Face* aface )
{
- FT_Open_Args args = ft_default_open_args;
+ FT_Open_Args args;
-
- args.pathname = (char*)pathname;
+ args.stream_type = ft_stream_pathname;
+ args.driver = 0;
+ args.pathname = (char*)pathname;
return FT_Open_Face( library, &args, face_index, aface );
}
@@ -1129,11 +1070,12 @@
FT_Long face_index,
FT_Face* face )
{
- FT_Open_Args args = ft_default_open_args;
+ FT_Open_Args args;
-
+ args.stream_type = ft_stream_memory;
args.memory_base = file_base;
args.memory_size = file_size;
+ args.driver = 0;
return FT_Open_Face( library, &args, face_index, face );
}
@@ -1198,8 +1140,7 @@
/* create input stream */
error = ft_new_input_stream( library, args, &stream );
- if ( error )
- goto Exit;
+ if ( error ) goto Exit;
memory = library->memory;
@@ -1281,6 +1222,15 @@
goto Fail;
}
+ /* initialize transform for convenience functions */
+ face->transform_matrix.xx = 0x10000L;
+ face->transform_matrix.xy = 0;
+ face->transform_matrix.yx = 0;
+ face->transform_matrix.yy = 0x10000L;
+
+ face->transform_delta.x = 0;
+ face->transform_delta.y = 0;
+
*aface = face;
goto Exit;
@@ -1329,9 +1279,10 @@
FT_Error FT_Attach_File( FT_Face face,
const char* filepathname )
{
- FT_Open_Args open = ft_default_open_args;
+ FT_Open_Args open;
- open.pathname = (char*)filepathname;
+ open.stream_type = ft_stream_pathname;
+ open.pathname = (char*)filepathname;
return FT_Attach_Stream( face, &open );
}
@@ -1875,6 +1826,10 @@
return FT_Err_Invalid_Face_Handle;
driver = face->driver;
+
+ /* when the flag NO_RECURSE is set, we disable hinting and scaling */
+ if (load_flags & FT_LOAD_NO_RECURSE)
+ load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
error = driver->interface.load_glyph( face->glyph,
face->size,
@@ -2006,615 +1961,6 @@
result = driver->interface.get_char_index( face->charmap, charcode );
}
return result;
- }
-
- /*************************************************************************/
- /* */
- /* <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_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 FT_Err_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 = FT_Err_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 FT_Err_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 = FT_Err_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 = FT_Err_Invalid_Outline;
- break;
-
- default:
- error = FT_Err_Invalid_Outline;
- break;
- }
-
- if ( error )
- return error;
-
- first = last + 1;
- }
-
- return 0;
- }
-
-
- static
- const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0 };
-
-
- /*************************************************************************/
- /* */
- /* <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. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- /* <MT-Note> */
- /* Yes. */
- /* */
- BASE_FUNC
- FT_Error 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;
- return FT_Err_Ok;
- }
- else
- return FT_Err_Invalid_Argument;
- }
-
-
-
- /*************************************************************************/
- /* */
- /* <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_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;
}
--- a/src/base/ftobjs.h
+++ b/src/base/ftobjs.h
@@ -95,68 +95,11 @@
/*************************************************************************/
/*************************************************************************/
- /*************************************************************************/
- /* */
- /* <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,
@@ -163,27 +106,6 @@
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,
@@ -377,132 +327,6 @@
/*************************************************************************/
/**** ****/
/**** ****/
- /**** 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 */
-
- /*************************************************************************/
- /*************************************************************************/
- /*************************************************************************/
- /**** ****/
- /**** ****/
/**** L I B R A R I E S ****/
/**** ****/
/**** ****/
@@ -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,9 +377,11 @@
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];
@@ -566,50 +388,11 @@
} 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,70 +404,15 @@
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 );
@@ -691,57 +419,11 @@
#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
--- a/src/base/ftoutln.c
+++ b/src/base/ftoutln.c
@@ -29,50 +29,269 @@
#include <ftimage.h>
#include <ftoutln.h>
+ static
+ const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0 };
+
/*************************************************************************/
/* */
/* <Function> */
- /* FT_Outline_Copy */
+ /* FT_Outline_Decompose */
/* */
/* <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. */
+ /* 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> */
- /* source :: A handle to the source outline. */
- /* target :: A handle to the target outline. */
+ /* 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_Copy( FT_Outline* source,
- FT_Outline* target )
+ FT_Error FT_Outline_New( FT_Library library,
+ FT_UInt numPoints,
+ FT_Int numContours,
+ FT_Outline* outline )
{
- FT_Int is_owner;
-
- if ( !source || !target ||
- source->n_points != target->n_points ||
- source->n_contours != target->n_contours )
+ FT_Error error;
+ FT_Memory memory;
+
+
+ if ( !outline )
return FT_Err_Invalid_Argument;
- MEM_Copy( target->points, source->points,
- source->n_points * 2 * sizeof ( FT_Pos ) );
+ *outline = null_outline;
+ memory = library->memory;
- MEM_Copy( target->tags, source->tags,
- source->n_points * sizeof ( FT_Byte ) );
+ 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;
- MEM_Copy( target->contours, source->contours,
- source->n_contours * sizeof ( FT_Short ) );
+ outline->n_points = (FT_UShort)numPoints;
+ outline->n_contours = (FT_Short)numContours;
+ outline->flags |= ft_outline_owner;
- /* copy all flags, except the "ft_outline_owner" one */
- is_owner = target->flags & ft_outline_owner;
- target->flags = source->flags;
-
- target->flags &= ~ft_outline_owner;
- target->flags |= is_owner;
return FT_Err_Ok;
+
+ Fail:
+ outline->flags |= ft_outline_owner;
+ FT_Outline_Done( library, outline );
+
+ return error;
}
@@ -79,6 +298,351 @@
/*************************************************************************/
/* */
/* <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> */
@@ -104,30 +668,151 @@
/* */
/* It will use the raster correponding to the default glyph format. */
/* */
- BASE_FUNC
+ EXPORT_FUNC
FT_Error FT_Outline_Get_Bitmap( FT_Library library,
FT_Outline* outline,
FT_Bitmap* map )
{
FT_Error error;
- FT_Glyph_Format* format;
+ FT_Raster raster;
+ FT_Raster_Funcs funcs;
+ FT_Raster_Params params;
error = FT_Err_Invalid_Glyph_Format;
- format = FT_Get_Glyph_Format( library, ft_glyph_format_outline );
- if (!format) goto Exit;
+ raster = FT_Get_Raster( library, ft_glyph_format_outline, &funcs );
+ if (!raster) goto Exit;
- error = FT_Err_Invalid_Glyph_Format;
- if (!format->raster) goto Exit;
+ params.target = map;
+ params.source = outline;
+ params.flags = 0;
+ if (map->pixel_mode == ft_pixel_mode_grays)
+ params.flags |= ft_raster_flag_aa;
+
+ error = funcs.raster_render( raster, ¶ms );
+ Exit:
+ return error;
+ }
- error = format->raster_interface->render( format->raster, outline, 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_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> */
+ /* 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. */
+ /* */
+ BASE_FUNC
+ FT_Error FT_Outline_Copy( FT_Outline* source,
+ FT_Outline* target )
+ {
+ FT_Int is_owner;
+
+ if ( !source || !target ||
+ source->n_points != target->n_points ||
+ source->n_contours != target->n_contours )
+ return FT_Err_Invalid_Argument;
+
+ MEM_Copy( target->points, source->points,
+ source->n_points * 2 * sizeof ( FT_Pos ) );
+
+ MEM_Copy( target->tags, source->tags,
+ source->n_points * sizeof ( FT_Byte ) );
+
+ MEM_Copy( target->contours, source->contours,
+ source->n_contours * sizeof ( FT_Short ) );
+
+ /* copy all flags, except the "ft_outline_owner" one */
+ is_owner = target->flags & ft_outline_owner;
+ target->flags = source->flags;
+
+ target->flags &= ~ft_outline_owner;
+ target->flags |= is_owner;
+ return FT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
/* FT_Outline_Transform */
/* */
/* <Description> */
@@ -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 */
--- a/src/base/ftoutln.h
+++ b/src/base/ftoutln.h
@@ -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 */
--- a/src/base/ftraster.c
+++ b/src/base/ftraster.c
@@ -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,264 +2205,10 @@
#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
-
- /*************************************************************************/
- /* */
- /* <Function> */
/* Convert_Glyph */
/* */
/* <Description> */
@@ -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 @@
#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 @@
/* 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;
-
-
-
- /*************************************************************************/
- /* */
- /* <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 )
- {
- return (long)sizeof( struct FT_RasterRec_ );
+ return ( params->flags & ft_raster_flag_aa
+ ? Raster_Render8( raster )
+ : Raster_Render1( raster ) );
}
- /*************************************************************************/
- /* */
- /* <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 )
+ FT_Raster_Funcs ft_default_raster =
{
-/* 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
};
--- a/src/base/rules.mk
+++ b/src/base/rules.mk
@@ -33,8 +33,10 @@
$(BASE_)ftextend.c \
$(BASE_)ftlist.c \
$(BASE_)ftobjs.c \
- $(BASE_)ftstream.c
+ $(BASE_)ftstream.c \
+ $(BASE_)ftoutln.c
+
# Base layer headers
#
BASE_H := $(BASE_)ftcalc.h \
@@ -53,7 +55,7 @@
# symbols is used by the application.
#
BASE_EXT_SRC := $(BASE_)ftraster.c \
- $(BASE_)ftoutln.c
+ $(BASE_)ftglyph.c
# Base layer extensions headers
#