shithub: freetype+ttf2subf

Download patch

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

git/fs: mount .git/fs: mount/attach disallowed
--- 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 )
       {