ref: 20e33158da0a2078b85eb102e93b0f9772462c14
parent: 91f905885f8a85ea65c72ac519124761001ca49c
author: David Turner <[email protected]>
date: Tue Jan 7 17:54:02 EST 2003
* src/base/ftstroker.c: probably the last bug-fixes to the stroker, the API is likely to change however. * src/base/fttrigon.c (FT_Angle_Diff): fixing function, it returned invalid values for large negative angle differences (resulting in incorrect stroker computations, among other things) * src/cache/ftccache.c (ftc_node_unlink): removing incorrect assertion, and changing code to avoid hash table size contraction * src/base/Jamfile, src/base/rules.mk, src/base/descrip.mms: adding "ftstroker.obj" to default build, as optional component
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2003-01-07 David Turner <[email protected]>
+
+ * src/base/ftstroker.c: probably the last bug-fixes to the stroker,
+ the API is likely to change however.
+
+ * src/base/fttrigon.c (FT_Angle_Diff): fixing function, it returned
+ invalid values for large negative angle differences (resulting in
+ incorrect stroker computations, among other things)
+
+ * src/cache/ftccache.c (ftc_node_unlink): removing incorrect
+ assertion, and changing code to avoid hash table size contraction
+
+ * src/base/Jamfile, src/base/rules.mk, src/base/descrip.mms:
+ adding "ftstroker.obj" to default build, as optional component
+
2002-12-26 David Turner <[email protected]>
* src/gzip/adler32.c, src/gzip/infblock.c, src/gzip/inflate.c,
--- a/Jamfile.in
+++ b/Jamfile.in
@@ -1,6 +1,21 @@
-# FreeType 2 top Jamfile (c) 2001, 2002 David Turner
+# FreeType 2 top Jamfile (c) 2001-2002 David Turner
#
+# The HDRMACRO is already defined in FTJam and is used to add
+# the content of certain macros to the list of included header
+# files.
+#
+# we can compile FreeType 2 with classic Jam however thanks to
+# the following code
+#
+if ! $(JAM_TOOLSET)
+{
+ rule HDRMACRO
+ {
+ # nothing !!
+ }
+}
+
# We need to invoke a SubDir rule if the FT2 source directory top is not the
# current directory. This allows us to build FreeType 2 as part of a larger
# project easily.
@@ -10,18 +25,73 @@
SubDir FT2_TOP ;
}
-FT2_INCLUDE = [ FT2_SubDir include ] ;
-FT2_SRC = [ FT2_SubDir src ] ;
+#
+# The following macros define the include directory, the source directory
+# and the final library name (without library extensions). They can be
+# replaced by other definitions when the library is compiled as part of
+# a larger project.
+#
-FT2_LIB = $(LIBPREFIX)freetype ;
+# name of FreeType include directory during compilation.
+# relative to FT2_TOP
+#
+FT2_INCLUDE_DIR ?= include ;
+# name of FreeType source directory during compilation.
+# relative to FT2_TOP
+#
+FT2_SRC_DIR ?= src ;
-# We don't support libtool just yet. It seems that this is not
-# so simple with Jam, but I'll study this topic later.
+# name of final library, without extension
#
+FT2_LIB ?= $(LIBPREFIX)freetype ;
-# used only when trying to debug the hinter(s)
+
+# define FT2_BUILD_INCLUDE to point to your build-specific directory
+# this is prepended to FT2_INCLUDE_DIR. This can be used to specify
+# the location of a custom <ft2build.h> which will point to custom
+# versions of "ftmodule.h" and "ftoption.h", for example
#
+FT2_BUILD_INCLUDE ?= ;
+
+# the list of modules to compile on any given build of the library
+# by default, this will contain _all_ modules defined in FT2_SRC_DIR
+#
+# IMPORTANT: You'll need to change the content of "ftmodule.h" as well
+# if you modify this list or provide your own.
+#
+FT2_COMPONENTS ?= gzip # support for gzip-compressed files.
+ autohint # auto-hinter
+ base # base component (public APIs)
+ bdf # BDF font driver
+ cache # cache sub-system
+ ccg # Chinese Character Generator font driver
+ cff # CFF/CEF font driver
+ cid # Postscript CID-keyed font driver
+ pcf # PCF font driver
+ pfr # PFR/TrueDoc font driver
+ psaux # Common Postscript routines module
+ pshinter # Postscript hinter module
+ psnames # Postscript names handling
+ raster # Monochrome rasterizer
+ smooth # Anti-aliased rasterizer
+ sfnt # SFNT-based format support routines
+ truetype # TrueType font driver
+ type1 # Postscript Type 1 font driver
+ type42 # Postscript Type 42 (embedded TrueType) driver
+ winfonts # Windows FON/FNT font driver
+ ;
+
+
+# don't touch
+#
+FT2_INCLUDE = $(FT2_BUILD_INCLUDE)
+ [ FT2_SubDir $(FT2_INCLUDE_DIR) ] ;
+
+FT2_SRC = [ FT2_SubDir $(FT2_SRC_DIR) ] ;
+
+# only used by FreeType developers
+#
if $(DEBUG_HINTER)
{
CCFLAGS += -DDEBUG_HINTER ;
@@ -31,7 +101,7 @@
# We need "freetype2/include" in the current include path in order to
# compile any part of FreeType 2.
#
-SubDirHdr += $(FT2_INCLUDE) ;
+SubDirHdr += $(FT2_INCLUDE) ;
# Uncomment the following line if you want to build individual source files
# for each FreeType 2 module.
@@ -51,7 +121,7 @@
SubInclude FT2_TOP $(FT2_SRC_DIR) ;
-# tests files (hinter debugging)
+# tests files (hinter debugging). only used by FreeType developers
#
if $(DEBUG_HINTER)
{
--- a/src/base/Jamfile
+++ b/src/base/Jamfile
@@ -22,7 +22,8 @@
# Add the optional/replaceable files.
#
Library $(FT2_LIB) : ftsystem.c ftinit.c ftglyph.c ftmm.c ftbdf.c
- ftbbox.c ftdebug.c ftxf86.c fttype1.c ftpfr.c ;
+ ftbbox.c ftdebug.c ftxf86.c fttype1.c ftpfr.c
+ ftstroker.c ;
# Add Macintosh-specific file to the library when necessary.
#
--- a/src/base/descrip.mms
+++ b/src/base/descrip.mms
@@ -15,7 +15,7 @@
CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.builds.vms],[--.include],[--.src.base])
-OBJS=ftbase.obj,ftinit.obj,ftglyph.obj,ftdebug.obj,ftbdf.obj,ftmm.obj,fttype1.obj,ftxf86.obj,ftpfr.obj
+OBJS=ftbase.obj,ftinit.obj,ftglyph.obj,ftdebug.obj,ftbdf.obj,ftmm.obj,fttype1.obj,ftxf86.obj,ftpfr.obj, ftstroker.obj
all : $(OBJS)
library [--.lib]freetype.olb $(OBJS)
--- a/src/base/ftstroker.c
+++ b/src/base/ftstroker.c
@@ -233,8 +233,12 @@
{
FT_ASSERT( border->start >= 0 );
- border->tags[ border->start ] |= FT_STROKE_TAG_BEGIN;
- border->tags[ border->num_points-1 ] |= FT_STROKE_TAG_END;
+ /* don't record empty paths !! */
+ if ( border->num_points > (FT_UInt)border->start )
+ {
+ border->tags[ border->start ] |= FT_STROKE_TAG_BEGIN;
+ border->tags[ border->num_points-1 ] |= FT_STROKE_TAG_END;
+ }
border->start = -1;
border->movable = 0;
@@ -469,7 +473,7 @@
FT_Byte* tags = border->tags;
FT_Int in_contour = 0;
- for ( ; count > 0; count--, point++, tags++ )
+ for ( ; count > 0; count--, num_points++, point++, tags++ )
{
if ( tags[0] & FT_STROKE_TAG_BEGIN )
{
@@ -538,7 +542,7 @@
FT_Short* write = outline->contours + outline->n_contours;
FT_Short index = (FT_Short) outline->n_points;
- for ( ; count > 0; count--, tags++, write++, index++ )
+ for ( ; count > 0; count--, tags++, index++ )
{
if ( *tags & FT_STROKE_TAG_END )
{
@@ -787,9 +791,15 @@
theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out );
if (theta == FT_ANGLE_PI)
+ {
theta = rotate;
+ phi = stroker->angle_in;
+ }
else
+ {
theta = theta/2;
+ phi = stroker->angle_in + theta + rotate;
+ }
thcos = FT_Cos( theta );
sigma = FT_MulFix( stroker->miter_limit, thcos );
@@ -797,7 +807,6 @@
if ( sigma >= 0x10000L )
miter = 0;
- phi = stroker->angle_in + theta + rotate;
if (miter) /* this is a miter (broken angle) */
{
@@ -1361,4 +1370,208 @@
ft_stroke_border_export( stroker->borders+0, outline );
ft_stroke_border_export( stroker->borders+1, outline );
}
+ }
+
+
+
+
+
+ /*
+ * the following is very similar to FT_Outline_Decompose, except
+ * that we do support opened paths, and do not scale the outline
+ */
+ FT_EXPORT_DEF( FT_Error )
+ FT_Stroker_ParseOutline( FT_Stroker stroker,
+ FT_Outline* outline,
+ FT_Bool opened )
+ {
+ FT_Vector v_last;
+ FT_Vector v_control;
+ FT_Vector v_start;
+
+ FT_Vector* point;
+ FT_Vector* limit;
+ char* tags;
+
+ FT_Error error;
+
+ FT_Int n; /* index of contour in outline */
+ FT_UInt first; /* index of first point in contour */
+ FT_Int tag; /* current point's state */
+ FT_Int in_path;
+
+ if ( !outline || !stroker )
+ return FT_Err_Invalid_Argument;
+
+ first = 0;
+
+ in_path = 0;
+
+ for ( n = 0; n < outline->n_contours; n++ )
+ {
+ FT_Int last; /* index of last point in contour */
+
+
+ last = outline->contours[n];
+ limit = outline->points + last;
+
+ v_start = outline->points[first];
+ v_last = outline->points[last];
+
+ v_control = v_start;
+
+ 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 = FT_Stroker_BeginSubPath( stroker, &v_start, opened );
+ if ( error )
+ goto Exit;
+
+ in_path = 1;
+
+ while ( point < limit )
+ {
+ point++;
+ tags++;
+
+ tag = FT_CURVE_TAG( tags[0] );
+ switch ( tag )
+ {
+ case FT_CURVE_TAG_ON: /* emit a single line_to */
+ {
+ FT_Vector vec;
+
+
+ vec.x = point->x;
+ vec.y = point->y;
+
+ error = FT_Stroker_LineTo( stroker, &vec );
+ if ( error )
+ goto Exit;
+ continue;
+ }
+
+ case FT_CURVE_TAG_CONIC: /* consume conic arcs */
+ v_control.x = point->x;
+ v_control.y = point->y;
+
+ Do_Conic:
+ if ( point < limit )
+ {
+ FT_Vector vec;
+ FT_Vector v_middle;
+
+
+ point++;
+ tags++;
+ tag = FT_CURVE_TAG( tags[0] );
+
+ vec = point[0];
+
+ if ( tag == FT_CURVE_TAG_ON )
+ {
+ error = FT_Stroker_ConicTo( stroker, &v_control, &vec );
+ if ( error )
+ goto Exit;
+ continue;
+ }
+
+ if ( tag != FT_CURVE_TAG_CONIC )
+ goto Invalid_Outline;
+
+ v_middle.x = ( v_control.x + vec.x ) / 2;
+ v_middle.y = ( v_control.y + vec.y ) / 2;
+
+ error = FT_Stroker_ConicTo( stroker, &v_control, &v_middle );
+ if ( error )
+ goto Exit;
+
+ v_control = vec;
+ goto Do_Conic;
+ }
+
+ error = FT_Stroker_ConicTo( stroker, &v_control, &v_start );
+ goto Close;
+
+ default: /* FT_CURVE_TAG_CUBIC */
+ {
+ FT_Vector vec1, vec2;
+
+
+ if ( point + 1 > limit ||
+ FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )
+ goto Invalid_Outline;
+
+ point += 2;
+ tags += 2;
+
+ vec1 = point[-2];
+ vec2 = point[-1];
+
+ if ( point <= limit )
+ {
+ FT_Vector vec;
+
+
+ vec = point[0];
+
+ error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &vec );
+ if ( error )
+ goto Exit;
+ continue;
+ }
+
+ error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &v_start );
+ goto Close;
+ }
+ }
+ }
+
+ Close:
+ if ( error )
+ goto Exit;
+
+ error = FT_Stroker_EndSubPath( stroker );
+ if ( error )
+ goto Exit;
+
+ first = last + 1;
+ }
+
+ return 0;
+
+ Exit:
+ return error;
+
+ Invalid_Outline:
+ return FT_Err_Invalid_Outline;
}
--- a/src/base/fttrigon.c
+++ b/src/base/fttrigon.c
@@ -474,6 +474,8 @@
FT_Angle delta = angle2 - angle1;
delta %= FT_ANGLE_2PI;
+ if ( delta < 0 )
+ delta += FT_ANGLE_2PI;
if ( delta > FT_ANGLE_PI )
delta -= FT_ANGLE_2PI;
--- a/src/base/rules.mk
+++ b/src/base/rules.mk
@@ -49,12 +49,13 @@
# object. It will then be linked to the final executable only if one of its
# symbols is used by the application.
#
-BASE_EXT_SRC := $(BASE_)ftglyph.c \
- $(BASE_)ftmm.c \
- $(BASE_)ftbdf.c \
- $(BASE_)fttype1.c \
- $(BASE_)ftxf86.c \
- $(BASE_)ftpfr.c \
+BASE_EXT_SRC := $(BASE_)ftglyph.c \
+ $(BASE_)ftmm.c \
+ $(BASE_)ftbdf.c \
+ $(BASE_)fttype1.c \
+ $(BASE_)ftxf86.c \
+ $(BASE_)ftpfr.c \
+ $(BASE_)ftstroker.c \
$(BASE_)ftbbox.c
# Default extensions objects
--- a/src/cache/ftccache.c
+++ b/src/cache/ftccache.c
@@ -196,7 +196,8 @@
FTC_Node* pold;
- FT_ASSERT( old_index >= FTC_HASH_INITIAL_SIZE );
+ if ( old_index+1 <= FTC_HASH_INITIAL_SIZE )
+ goto Exit;
if ( p == 0 )
{