shithub: freetype+ttf2subf

Download patch

ref: b7e18efcd2d6a71ec1a4bdf167f78d707ac91593
parent: 318f3befc67e026037da33fb7b5b9a22d567df9a
author: David Turner <[email protected]>
date: Wed Jun 26 18:05:05 EDT 2002

adding path stroker component (first steps)

git/fs: mount .git/fs: mount/attach disallowed
--- /dev/null
+++ b/include/freetype/ftstroker.h
@@ -1,0 +1,144 @@
+#ifndef __FT_STROKER_H__
+#define __FT_STROKER_H__
+
+#include <ft2build.h>
+#include FT_OUTLINE_H
+
+FT_BEGIN_HEADER
+
+/**************************************************************
+ *
+ * @type: FT_Stroker
+ *
+ * @description:
+ *    opaque handler to a path stroker object
+ */
+  typedef struct FT_StrokerRec_*    FT_Stroker;
+
+
+/**************************************************************
+ *
+ * @enum: FT_Stroker_LineJoin
+ *
+ * @description:
+ *    these values determine how two joining lines are rendered
+ *    in a stroker.
+ *
+ * @values:
+ *    FT_STROKER_LINEJOIN_ROUND ::
+ *      used to render rounded line joins. circular arcs are used
+ *      to join two lines smoothly
+ *
+ *    FT_STROKER_LINEJOIN_BEVEL ::
+ *      used to render beveled line joins; i.e. the two joining lines
+ *      are extended until they intersect
+ *
+ *    FT_STROKER_LINEJOIN_MITER ::
+ *      same as beveled rendering, except that an additional line
+ *      break is added if the angle between the two joining lines
+ *      is too closed (this is useful to avoid unpleasant spikes
+ *      in beveled rendering).
+ */
+  typedef enum
+  {
+    FT_STROKER_LINEJOIN_ROUND = 0,
+    FT_STROKER_LINEJOIN_BEVEL,
+    FT_STROKER_LINEJOIN_MITER
+  
+  } FT_Stroker_LineJoin;
+
+
+/**************************************************************
+ *
+ * @enum: FT_Stroker_LineCap
+ *
+ * @description:
+ *    these values determine how the end of opened sub-paths are
+ *    rendered in a stroke
+ *
+ * @values:
+ *    FT_STROKER_LINECAP_BUTT ::
+ *      the end of lines is rendered as a full stop on the last
+ *      point itself
+ *
+ *    FT_STROKER_LINECAP_ROUND ::
+ *      the end of lines is rendered as a half-circle around the
+ *      last point
+ *
+ *    FT_STROKER_LINEJOIN_MITER ::
+ *      the end of lines is rendered as a square around the
+ *      last point
+ */
+  typedef enum
+  {
+    FT_STROKER_LINECAP_BUTT = 0,
+    FT_STROKER_LINECAP_ROUND,
+    FT_STROKER_LINECAP_SQUARE
+    
+  } FT_Stroker_LineCap;
+
+  
+  FT_EXPORT( FT_Error )
+  FT_Stroker_New( FT_Memory    memory,
+                  FT_Stroker  *astroker );
+
+  FT_EXPORT( void )
+  FT_Stroker_Set( FT_Stroker           stroker,
+                  FT_Fixed             radius,
+                  FT_Stroker_LineCap   line_cap,
+                  FT_Stroker_LineJoin  line_join,
+                  FT_Fixed             miter_limit );
+
+  FT_EXPORT( FT_Error )
+  FT_Stroker_BeginSubPath( FT_Stroker  stroker,
+                           FT_Pos      x,
+                           FT_Pos      y,
+                           FT_Bool     open );
+
+  FT_EXPORT( FT_Error )
+  FT_Stroker_EndSubPath( FT_Stroker  stroker );
+
+
+  FT_EXPORT( FT_Error )
+  FT_Stroker_LineTo( FT_Stroker  stroker,
+                     FT_Pos      to_x,
+                     FT_Pos      to_y );
+
+  FT_EXPORT( FT_Error )
+  FT_Stroker_ConicTo( FT_Stroker  stroker,
+                      FT_Pos      control_x,
+                      FT_Pos      control_y,
+                      FT_Pos      to_x,
+                      FT_Pos      to_y );
+
+  FT_EXPORT( FT_Error )
+  FT_Stroker_CubicTo( FT_Stroker  stroker,
+                      FT_Pos      control1_x,
+                      FT_Pos      control1_y,
+                      FT_Pos      control2_x,
+                      FT_Pos      control2_y,
+                      FT_Pos      to_x,
+                      FT_Pos      to_y );
+
+
+  FT_EXPORT( FT_Error )
+  FT_Stroker_GetCounts( FT_Stroker  stroker,
+                        FT_UInt    *anum_points,
+                        FT_UInt    *anum_contours );
+
+  FT_EXPORT( void )
+  FT_Stroker_Export( FT_Stroker    stroker,
+                     FT_Outliner*  outline );
+
+  FT_EXPORT( void )
+  FT_Stroker_Done( FT_Stroker  stroker );
+
+
+  FT_EXPORT( FT_Error )
+  FT_Stroker_ParseOutline( FT_Stroker   stroker,
+                           FT_Outline*  outline,
+                           FT_Bool      opened );
+
+FT_END_HEADER
+
+#endif /* __FT_STROKER_H__ */
--- a/include/freetype/fttrigon.h
+++ b/include/freetype/fttrigon.h
@@ -176,6 +176,27 @@
   /*************************************************************************/
   /*                                                                       */
   /* @function:                                                            */
+  /*    FT_Angle_Diff                                                      */
+  /*                                                                       */
+  /* @description:                                                         */
+  /*    Returns the difference between two angles. The result is always    */
+  /*    constrained to the ]-PI..PI] interval                              */
+  /*                                                                       */
+  /* @input:                                                               */
+  /*    angle1 :: first angle                                              */
+  /*    angle2 :: second angle                                             */
+  /*                                                                       */
+  /* @return:                                                              */
+  /*    contrainted value of 'value2-value1'                               */
+  /*                                                                       */
+  FT_EXPORT_DEF( FT_Angle )
+  FT_Angle_Dif( FT_Angle  angle1,
+                FT_Angle  angle2 );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* @function:                                                            */
   /*    FT_Vector_Unit                                                     */
   /*                                                                       */
   /* @description:                                                         */
--- /dev/null
+++ b/src/base/ftstroker.c
@@ -1,0 +1,290 @@
+#include <ft2build.h>
+#include FT_STROKER_H
+#include FT_TRIGONOMETRY_H
+
+ /***************************************************************************/
+ /***************************************************************************/
+ /*****                                                                 *****/
+ /*****                       STROKE BORDERS                            *****/
+ /*****                                                                 *****/
+ /***************************************************************************/
+ /***************************************************************************/
+
+  typedef enum
+  {
+    FT_STROKE_TAG_ON    = 1,   /* on-curve point  */
+    FT_STROKE_TAG_CUBIC = 2,   /* cubic off-point */
+    FT_STROKE_TAG_BEGIN = 4,   /* sub-path start  */
+    FT_STROKE_TAG_END   = 8    /* sub-path end    */
+  
+  } FT_StrokeTags;
+
+
+  typedef struct FT_StrokeBorderRec_
+  {
+    FT_UInt     num_points;
+    FT_UInt     max_points;
+    FT_Vector*  points;
+    FT_Byte*    tags;
+    FT_Bool     movable;
+    FT_Int      start;    /* index of current sub-path start point */
+    FT_Memory   memory;
+  
+  } FT_StrokeBorderRec, *FT_StrokeBorder;
+
+
+  static FT_Error
+  ft_stroke_border_grow( FT_StrokeBorder  border,
+                         FT_UInt          new_points )
+  {
+    FT_UInt   old_max = border->max_points;
+    FT_UInt   new_max = border->num_points + new_points;
+    FT_Error  error   = 0;
+    
+    if ( new_max > old_max )
+    {
+      FT_UInt    cur_max = old_max;
+      FT_Memory  memory  = 
+      
+      while ( cur_max < new_max )
+        cur_max += (cur_max >> 1) + 16;
+
+      if ( FT_RENEW_ARRAY( border->points, old_max, cur_max ) ||
+           FT_RENEW_ARRAY( border->tags,   old_max, cur_max ) )
+        goto Exit;
+      
+      border->max_points = cur_max;
+    }
+  Exit:
+    return error;
+  }
+
+  static void
+  ft_stroke_border_close( FT_StrokeBorder  border )
+  {
+    FT_ASSERT( border->start >= 0 );
+    
+    border->tags[ border->start        ] |= FT_STROKE_TAG_BEGIN;
+    border->tags[ border->num_points-1 ] |= FT_STROKE_TAG_END;
+    
+    border->start = -1;
+  }
+
+
+  static FT_Error
+  ft_stroke_border_lineto( FT_StrokeBorder  border,
+                           FT_Vector*       to )
+  {
+    FT_Error  error;
+    
+    FT_ASSERT( border->start >= 0 );
+    
+    error = ft_stroker_border_grow( border, 1 );
+    if (!error)
+    {
+      FT_Vector*  vec = border->points + border->num_points;
+      FT_Byte*    tag = border->tags   + border->num_points;
+      
+      vec[0] = *to;
+      tag[0] = FT_STROKE_TAG_ON;
+      
+      border->num_points += 1;
+    }
+    return error;
+  }                           
+
+
+  static FT_Error
+  ft_stroke_border_conicto( FT_StrokeBorder  border,
+                            FT_Vector*       control,
+                            FT_Vector*       to )
+  {
+    FT_Error  error;
+    
+    FT_ASSERT( border->start >= 0 );
+    
+    error = ft_stroker_border_grow( border, 2 );
+    if (!error)
+    {
+      FT_Vector*  vec = border->points + border->num_points;
+      FT_Byte*    tag = border->tags   + border->num_points;
+      
+      vec[0] = *control;
+      vec[1] = *to;
+
+      tag[0] = 0;
+      tag[1] = FT_STROKE_TAG_ON;
+      
+      border->num_points += 2;
+    }
+    return error;
+  }                           
+
+
+  static FT_Error
+  ft_stroke_border_cubicto( FT_StrokeBorder  border,
+                            FT_Vector*       control1,
+                            FT_Vector*       control2,
+                            FT_Vector*       to )
+  {
+    FT_Error  error;
+    
+    FT_ASSERT( border->start >= 0 );
+    
+    error = ft_stroker_border_grow( border, 3 );
+    if (!error)
+    {
+      FT_Vector*  vec = border->points + border->num_points;
+      FT_Byte*    tag = border->tags   + border->num_points;
+      
+      vec[0] = *control1;
+      vec[1] = *control2;
+      vec[2] = *to;
+      
+      tag[0] = FT_STROKE_TAG_CUBIC;
+      tag[1] = FT_STROKE_TAG_CUBIC;
+      tag[2] = FT_STROKE_TAG_ON;
+      
+      border->num_points += 3;
+    }
+    return error;
+  }
+
+
+  static FT_Error
+  ft_stroke_border_moveto( FT_StrokeBorder  border,
+                           FT_Vector*       to )
+  {
+    FT_Error  error;
+    
+    /* close current open path if any ? */
+    if ( border->start >= 0 )
+      ft_stroke_border_close( border );
+    
+    border->start = border->num_points;
+
+    return ft_stroke_border_lineto( border, to );
+  }
+  
+ 
+ static void
+ ft_stroke_border_init( FT_StrokeBorder  border,
+                        FT_Memory        memory )
+ {
+   border->memory = memory;
+   border->points = NULL;
+   border->tags   = NULL;
+   
+   border->num_points = 0;
+   border->max_points = 0;
+   border->start      = -1;
+ }
+ 
+
+ static void
+ ft_stroke_border_reset( FT_StrokeBorder  border )
+ {
+   border->num_points = 0;
+   border->start      = -1;
+ }
+ 
+
+ static void
+ ft_stroke_border_done( FT_StrokeBorder  border )
+ {
+   memory = border->memory;
+   
+   FT_FREE( border->points );
+   FT_FREE( border->tags );
+   
+   border->num_points = 0;
+   border->max_points = 0;
+   border->start      = -1;
+ }
+
+
+ /***************************************************************************/
+ /***************************************************************************/
+ /*****                                                                 *****/
+ /*****                           STROKER                               *****/
+ /*****                                                                 *****/
+ /***************************************************************************/
+ /***************************************************************************/
+
+#define  FT_SIDE_TO_ROTATE(s)   (FT_PI2 - (s)*FT_PI)
+
+  typedef struct FT_StrokerRec_
+  {
+    FT_Angle             angle_in;
+    FT_Angle             angle_out;
+    FT_Vector            center;
+    FT_Bool              first_point;
+    FT_Bool              subpath_open;
+    FT_Angle             subpath_angle;
+    FT_Vector            subpath_start;
+
+    FT_Stroker_LineCap   line_cap;
+    FT_Stroker_LineJoin  line_join;
+    FT_Fixed             miter_limit;
+    FT_Fixed             radius;
+
+    FT_StrokeBorderRec   borders[2];
+    FT_Memory            memory;
+  
+  } FT_StrokerRec;
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Stroker_New( FT_Memory    memory,
+                  FT_Stroker  *astroker )
+  {
+    FT_Error    error;
+    FT_Stroker  stroker;
+    
+    if ( !FT_NEW( stroker ) )
+    {
+      stroker->memory = memory;
+      
+      ft_stroke_border_init( &stroker->borders[0], memory );
+      ft_stroke_border_init( &stroker->borders[1], memory );
+    }
+    *astroker = stroker;
+    return error;
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FT_Stroker_Set( FT_Stroker           stroker,
+                  FT_Fixed             radius,
+                  FT_Stroker_LineCap   line_cap,
+                  FT_Stroker_LineJoin  line_join,
+                  FT_Fixed             miter_limit )
+  {
+    stroker->radius      = radius;
+    stroker->line_cap    = line_cap;
+    stroker->line_join   = line_join;
+    stroker->miter_limit = miter_limit;
+    
+    ft_stroke_border_reset( &stroker->borders[0] );
+    ft_stroke_border_reset( &stroker->borders[1] );
+  }
+
+
+  FT_EXPORT( void )
+  FT_Stroker_Done( FT_Stroker  stroker )
+  {
+    if ( stroker )
+    {
+      FT_Memory  memory = stroker->memory;
+      
+      ft_stroke_border_done( &stroker->borders[0] );
+      ft_stroke_border_done( &stroker->borders[1] );
+      
+      stroker->memory = NULL;
+      FT_FREE( stroker );
+    }
+  }
+
+
+
+  
\ No newline at end of file
--- a/src/base/fttrigon.c
+++ b/src/base/fttrigon.c
@@ -451,4 +451,21 @@
   }
 
 
+  /* documentation is in fttrigon.h */
+
+  FT_EXPORT_DEF( FT_Angle )
+  FT_Angle_Dif( FT_Angle  angle1,
+                FT_Angle  angle2 )
+  {
+    FT_Angle  delta = angle2 - angle1;
+    
+    delta %= FT_ANGLE_2PI;
+
+    if ( delta > FT_ANGLE_PI )
+      delta -= FT_ANGLE_2PI;
+    
+    return delta;
+  }                
+
+
 /* END */