shithub: freetype+ttf2subf

Download patch

ref: fa0346d6d98d98c61042810b5bd6223606e0f3ca
parent: cd9f3b3b5a89fe6ee32e605212eb921544392448
author: David Turner <[email protected]>
date: Fri Jan 16 03:57:05 EST 2004

* src/base/ftstroke.c, include/freetype/ftstroke.h: fixing bugs and
        adding FT_Glyph_Stroke and FT_Glyph_StrokerBorder APIs

git/fs: mount .git/fs: mount/attach disallowed
--- a/include/freetype/ftstroke.h
+++ b/include/freetype/ftstroke.h
@@ -21,6 +21,7 @@
 
 #include <ft2build.h>
 #include FT_OUTLINE_H
+#include FT_GLYPH_H
 
 FT_BEGIN_HEADER
 
@@ -128,7 +129,7 @@
   {
     FT_STROKER_BORDER_LEFT = 0,
     FT_STROKER_BORDER_RIGHT
-  
+
   } FT_StrokerBorder;
 
 
@@ -173,7 +174,7 @@
   FT_EXPORT( FT_StrokerBorder )
   FT_Outline_GetOutsideBorder( FT_Outline*  outline );
 
- 
+
   /**************************************************************
    *
    * @function:
@@ -237,6 +238,24 @@
   /**************************************************************
    *
    * @function:
+   *   FT_Stroker_Rewind
+   *
+   * @description:
+   *   Reset a stroker object without changing its attributes.
+   *   you should call this function before beginning a new
+   *   series of calls to @FT_Stroker_BeginSubPath/@FT_Stroker_EndSubPath
+   *
+   * @input:
+   *   stroker ::
+   *     The target stroker handle.
+   */
+  FT_EXPORT( void )
+  FT_Stroker_Rewind( FT_Stroker  stroker );
+
+
+  /**************************************************************
+   *
+   * @function:
    *   FT_Stroker_ParseOutline
    *
    * @description:
@@ -264,6 +283,8 @@
    *
    *   If `opened' is 1, the outline is processed as an open path, and the
    *   stroker will generate a single `stroke' outline.
+   *
+   *   this function calls @FT_Stroker_Rewind automatically
    */
   FT_EXPORT( FT_Error )
   FT_Stroker_ParseOutline( FT_Stroker   stroker,
@@ -278,7 +299,7 @@
    *
    * @description:
    *   Start a new sub-path in the stroker.
-   *    
+   *
    * @input:
    *   stroker ::
    *     The target stroker handle.
@@ -309,7 +330,7 @@
    *
    * @description:
    *   Close the current sub-path in the stroker.
-   *    
+   *
    * @input:
    *   stroker ::
    *     The target stroker handle.
@@ -334,7 +355,7 @@
    * @description:
    *   `Draw' a single line segment in the stroker's current sub-path,
    *   from the last position.
-   *    
+   *
    * @input:
    *   stroker ::
    *     The target stroker handle.
@@ -362,7 +383,7 @@
    * @description:
    *   `Draw; a single quadratic bezier in the stroker's current sub-path,
    *   from the last position.
-   *    
+   *
    * @input:
    *   stroker ::
    *     The target stroker handle.
@@ -394,7 +415,7 @@
    * @description:
    *   `Draw' a single cubic B�zier in the stroker's current sub-path,
    *   from the last position.
-   *    
+   *
    * @input:
    *   stroker ::
    *     The target stroker handle.
@@ -432,7 +453,7 @@
    *   with the stroker.  It will return the number of points and
    *   contours necessary to export one of the `border' or `stroke'
    *   outlines generated by the stroker.
-   *    
+   *
    * @input:
    *   stroker ::
    *     The target stroker handle.
@@ -453,7 +474,7 @@
    * @note:
    *   When an outline, or a sub-path, is `closed', the stroker generates
    *   two independent `border' outlines, named `left' and `right'.
-   *   
+   *
    *   When the outline, or a sub-path, is `opened', the stroker merges
    *   the `border' outlines with caps.  The `left' border receives all
    *   points, while the `right' border becomes empty.
@@ -477,7 +498,7 @@
    *   Call this function after @FT_Stroker_GetBorderCounts to
    *   export the corresponding border to your own @FT_Outline
    *   structure.
-   *    
+   *
    *   Note that this function will append the border points and
    *   contours to your outline, but will not try to resize its
    *   arrays.
@@ -499,7 +520,7 @@
    *
    *   When an outline, or a sub-path, is `closed', the stroker generates
    *   two independent `border' outlines, named `left' and `right'
-   *   
+   *
    *   When the outline, or a sub-path, is `opened', the stroker merges
    *   the `border' outlines with caps. The `left' border receives all
    *   points, while the `right' border becomes empty.
@@ -523,7 +544,7 @@
    *   with the stroker.  It returns the number of points and
    *   contours necessary to export all points/borders from the stroked
    *   outline/path.
-   *    
+   *
    * @input:
    *   stroker ::
    *     The target stroker handle.
@@ -552,7 +573,7 @@
    * @description:
    *   Call this function after @FT_Stroker_GetBorderCounts to
    *   export the all borders to your own @FT_Outline structure.
-   *    
+   *
    *   Note that this function will append the border points and
    *   contours to your outline, but will not try to resize its
    *   arrays.
@@ -583,6 +604,73 @@
    */
   FT_EXPORT( void )
   FT_Stroker_Done( FT_Stroker  stroker );
+
+
+  /**************************************************************
+   *
+   * @function:
+   *   FT_Glyph_Stroke
+   *
+   * @description:
+   *   stroke a given outline glyph object with a given stroker
+   *
+   * @inout:
+   *   pglyph :: source glyph handle on input, new glyph handle
+   *             on output.
+   *
+   * @input:
+   *   stroker ::
+   *     A stroker handle.
+   *
+   *   destroy :: boolean. If TRUE, the source glyph object is destroyed
+   *              on success
+   *
+   * @return:
+   *    FreeType error code. 0 means success
+   *
+   * @note:
+   *   the source glyph is untouched in case of error.
+   */
+  FT_EXPORT( FT_Error )
+  FT_Glyph_Stroke( FT_Glyph    *pglyph,
+                   FT_Stroker   stroker,
+                   FT_Bool      destroy );
+
+
+  /**************************************************************
+   *
+   * @function:
+   *   FT_Glyph_StrokeBorder
+   *
+   * @description:
+   *   stroke a given outline glyph object with a given stroker, but
+   *   only returns either its inside or outside border
+   *
+   * @inout:
+   *   pglyph :: source glyph handle on input, new glyph handle
+   *             on output.
+   *
+   * @input:
+   *   stroker ::
+   *     A stroker handle.
+   *
+   *   inside  :: boolean. If TRUE, return the inside border; otherwise,
+   *              the outside border
+   *
+   *   destroy :: boolean. If TRUE, the source glyph object is destroyed
+   *              on success
+   *
+   * @return:
+   *    FreeType error code. 0 means success
+   *
+   * @note:
+   *   the source glyph is untouched in case of error.
+   */
+  FT_EXPORT( FT_Error )
+  FT_Glyph_StrokeBorder( FT_Glyph    *pglyph,
+                         FT_Stroker   stroker,
+                         FT_Bool      inside,
+                         FT_Bool      destroy );
 
  /* */
 
--- a/src/base/ftstroke.c
+++ b/src/base/ftstroke.c
@@ -22,8 +22,8 @@
 #include FT_OUTLINE_H
 #include FT_INTERNAL_MEMORY_H
 #include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_OBJECTS_H
 
-
   FT_EXPORT_DEF( FT_StrokerBorder )
   FT_Outline_GetInsideBorder( FT_Outline*  outline )
   {
@@ -41,8 +41,8 @@
     FT_Orientation  o = FT_Outline_Get_Orientation( outline );
 
 
-    return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_RIGHT
-                                        : FT_STROKER_BORDER_LEFT ;
+    return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_LEFT
+                                        : FT_STROKER_BORDER_RIGHT ;
   }
 
 
@@ -581,7 +581,8 @@
   {
     /* copy point locations */
     FT_ARRAY_COPY( outline->points + outline->n_points,
-                   border->points, border->num_points );
+                   border->points,
+                   border->num_points );
 
     /* copy tags */
     {
@@ -689,12 +690,22 @@
     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_Stroker_Rewind( stroker );
   }
 
 
   FT_EXPORT_DEF( void )
+  FT_Stroker_Rewind( FT_Stroker  stroker )
+  {
+    if ( stroker )
+    {
+      ft_stroke_border_reset( &stroker->borders[0] );
+      ft_stroke_border_reset( &stroker->borders[1] );
+    }
+  }
+
+
+  FT_EXPORT_DEF( void )
   FT_Stroker_Done( FT_Stroker  stroker )
   {
     if ( stroker )
@@ -1373,7 +1384,6 @@
   {
     FT_Error  error  = 0;
 
-
     if ( stroker->subpath_open )
     {
       FT_StrokeBorder  right = stroker->borders;
@@ -1406,6 +1416,15 @@
       FT_Angle  turn;
       FT_Int    inside_side;
 
+     /* close the path if needed
+      */
+      if ( stroker->center.x != stroker->subpath_start.x ||
+           stroker->center.y != stroker->subpath_start.y )
+      {
+        error = FT_Stroker_LineTo( stroker, &stroker->subpath_start );
+        if ( error )
+          goto Exit;
+      }
 
       /* process the corner */
       stroker->angle_out = stroker->subpath_angle;
@@ -1434,14 +1453,9 @@
           goto Exit;
       }
 
-      /* we will first end our two subpaths */
+      /* then end our two subpaths */
       ft_stroke_border_close( stroker->borders + 0 );
       ft_stroke_border_close( stroker->borders + 1 );
-
-      /* now, add the reversed left subpath to "right" */
-      error = ft_stroker_add_reverse_left( stroker, 0 );
-      if ( error )
-        goto Exit;
     }
 
   Exit:
@@ -1561,6 +1575,8 @@
     if ( !outline || !stroker )
       return FT_Err_Invalid_Argument;
 
+    FT_Stroker_Rewind( stroker );
+
     first = 0;
 
     for ( n = 0; n < outline->n_contours; n++ )
@@ -1729,6 +1745,152 @@
   Invalid_Outline:
     return FT_Err_Invalid_Outline;
   }
+
+
+
+  extern const FT_Glyph_Class  ft_outline_glyph_class;
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Glyph_Stroke( FT_Glyph    *pglyph,
+                   FT_Stroker   stroker,
+                   FT_Bool      destroy )
+  {
+    FT_Error  error = FT_Err_Invalid_Argument;
+    FT_Glyph  glyph = NULL;
+
+    if ( pglyph == NULL )
+      goto Exit;
+
+    glyph = *pglyph;
+    if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class )
+      goto Exit;
+
+    {
+      FT_Glyph  copy;
+
+      error = FT_Glyph_Copy( glyph, &copy );
+      if ( error )
+        goto Exit;
+
+      glyph = copy;
+    }
+
+    {
+      FT_OutlineGlyph  oglyph  = (FT_OutlineGlyph) glyph;
+      FT_Outline*      outline = &oglyph->outline;
+      FT_UInt          num_points, num_contours;
+
+      error = FT_Stroker_ParseOutline( stroker, outline, 0 );
+      if (error)
+        goto Fail;
+
+      (void)FT_Stroker_GetCounts( stroker, &num_points, &num_contours );
+
+      FT_Outline_Done( glyph->library, outline );
+
+      error = FT_Outline_New( glyph->library, num_points, num_contours, outline );
+      if ( error )
+        goto Fail;
+
+      outline->n_points   = 0;
+      outline->n_contours = 0;
+
+      FT_Stroker_Export( stroker, outline );
+    }
+
+    if ( destroy )
+      FT_Done_Glyph( *pglyph );
+
+    *pglyph = glyph;
+    goto Exit;
+
+  Fail:
+    FT_Done_Glyph( glyph );
+    glyph = NULL;
+
+    if ( !destroy )
+      *pglyph = NULL;
+
+  Exit:
+    return error;
+  }
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Glyph_StrokeBorder( FT_Glyph    *pglyph,
+                         FT_Stroker   stroker,
+                         FT_Bool      inside,
+                         FT_Bool      destroy )
+  {
+    FT_Error  error = FT_Err_Invalid_Argument;
+    FT_Glyph  glyph = NULL;
+
+    if ( pglyph == NULL )
+      goto Exit;
+
+    glyph = *pglyph;
+    if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class )
+      goto Exit;
+
+    {
+      FT_Glyph  copy;
+
+      error = FT_Glyph_Copy( glyph, &copy );
+      if ( error )
+        goto Exit;
+
+      glyph = copy;
+    }
+
+    {
+      FT_OutlineGlyph   oglyph  = (FT_OutlineGlyph) glyph;
+      FT_StrokerBorder  border;
+      FT_Outline*       outline = &oglyph->outline;
+      FT_UInt           num_points, num_contours;
+
+      border = FT_Outline_GetOutsideBorder( outline );
+      if ( inside )
+        border = 1-border;
+
+      error = FT_Stroker_ParseOutline( stroker, outline, 0 );
+      if (error)
+        goto Fail;
+
+      (void)FT_Stroker_GetBorderCounts( stroker, border,
+                                        &num_points, &num_contours );
+
+      FT_Outline_Done( glyph->library, outline );
+
+      error = FT_Outline_New( glyph->library,
+                              num_points,
+                              num_contours,
+                              outline );
+      if ( error )
+        goto Fail;
+
+      outline->n_points   = 0;
+      outline->n_contours = 0;
+
+      FT_Stroker_ExportBorder( stroker, border, outline );
+    }
+
+    if ( destroy )
+      FT_Done_Glyph( *pglyph );
+
+    *pglyph = glyph;
+    goto Exit;
+
+  Fail:
+    FT_Done_Glyph( glyph );
+    glyph = NULL;
+
+    if ( !destroy )
+      *pglyph = NULL;
+
+  Exit:
+    return error;
+  }
+
 
 
 /* END */