On Tue, May 24, 2005 at 04:05:39PM +0200, Werner LEMBERG wrote:
> 
> > This patch implements FT_Bitmap_Embolden and FT_Outline_Embolden.
> > It is intended for testing the algorithm and for discussing what
> > arguments should these function calls take.
> 
> Since David has fixed the problem (and rejected your modifications
> because of too great distortions under some circumstances), can you
> update your patch?
> 
Updated.

You may think of this patch as:
1. moving outline emboldening code from FT_GlyphSlot_Embolden to
   FT_Outline_Embolden,
2. implementing FT_Bitmap_Embolden, and
3. making FT_GlyphSlot_Embolden depend on both of them.

And as the previous one, both FT_Outline_Embolden and FT_Bitmap_Embolden
needs discussions on what arguments they should take.
> > I also make FT_GlyphSlot_Embolden to use these function calls.  You
> > can see it as an example of how applications are gonna use the
> > function calls and it will eventually be removed.
> 
> You mean FT_GlyphSlot_Embolden shall not be added to the library?
A glyph slot should be for glyph loading, not for glyph manipulations.
So I think a FT_Glyph_Embolden might be better.
> Then I suggest that you add this functionality to ftview instead.
=== include/freetype/ftbitmap.h
==================================================================
--- include/freetype/ftbitmap.h   (/freetype2/trunk)   (revision 898)
+++ include/freetype/ftbitmap.h   (/freetype2/branches/embolden)   (local)
@@ -92,6 +92,42 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
+  /*    FT_Bitmap_Embolden                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Emboldens a bitmap. The new bitmap will be about xStrength         */
+  /*    pixels wider and yStrength pixels higher. (The left and bottom     */
+  /*    borders are kept unchanged)                                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library   :: A handle to a library object.                         */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    bitmap    :: A handle to the target bitmap.                        */
+  /*                                                                       */
+  /*    xStrength :: How strong the glyph is emboldened horizontally.      */
+  /*                 Expressed in 16.16 pixel format.                      */
+  /*                                                                       */
+  /*    yStrength :: How strong the glyph is emboldened vertically.        */
+  /*                 Expressed in 16.16 pixel format.                      */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code                                                */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Current implementation restricts xStrength to be less than or      */
+  /*    equal to 8.                                                        */
+  /*                                                                       */
+  FT_EXPORT_DEF( FT_Error )
+  FT_Bitmap_Embolden( FT_Library  library,
+                      FT_Bitmap*  bitmap,
+                      FT_Pos*     xStrength,
+                      FT_Pos*     yStrength );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
   /*    FT_Bitmap_Convert                                                  */
   /*                                                                       */
   /* <Description>                                                         */
=== include/freetype/ftoutln.h
==================================================================
--- include/freetype/ftoutln.h   (/freetype2/trunk)   (revision 898)
+++ include/freetype/ftoutln.h   (/freetype2/branches/embolden)   (local)
@@ -58,6 +58,7 @@
   /*    FT_Outline_Copy                                                    */
   /*    FT_Outline_Translate                                               */
   /*    FT_Outline_Transform                                               */
+  /*    FT_Outline_Embolden                                                */
   /*    FT_Outline_Reverse                                                 */
   /*    FT_Outline_Check                                                   */
   /*                                                                       */
@@ -306,6 +307,30 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
+  /*    FT_Outline_Embolden                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Emboldens an outline. The new outline will be at most 4 times      */
+  /*    strength pixels wider and higher. You may think of the left and    */
+  /*    bottom borders as unchanged.                                       */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    outline  :: A handle to the target outline.                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    strength :: How strong the glyph is emboldened. Expressed in 16.16 */
+  /*                pixel format.                                          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code                                                */
+  /*                                                                       */
+  FT_EXPORT_DEF( FT_Error )
+  FT_Outline_Embolden( FT_Outline*  outline,
+                       FT_Pos       strength );
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
   /*    FT_Outline_Reverse                                                 */
   /*                                                                       */
   /* <Description>                                                         */
=== src/base/ftbitmap.c
==================================================================
--- src/base/ftbitmap.c   (/freetype2/trunk)   (revision 898)
+++ src/base/ftbitmap.c   (/freetype2/branches/embolden)   (local)
@@ -94,9 +94,194 @@
   }
 
 
+  static FT_Error
+  ft_bitmap_assure_buffer( FT_Memory   memory,
+                           FT_Bitmap*  bitmap,
+                           FT_UInt     xpixels,
+                           FT_UInt     ypixels )
+  {
+    FT_Error        error;
+    int             pitch;
+    int             new_pitch;
+    int             ppb, i;
+    unsigned char*  buffer;
+
+
+    pitch = bitmap->pitch;
+    if ( pitch < 0 )
+      pitch = -pitch;
+
+    switch ( bitmap->pixel_mode )
+    {
+      case FT_PIXEL_MODE_MONO:
+        ppb = 8;
+        break;
+      case FT_PIXEL_MODE_GRAY2:
+        ppb = 4;
+        break;
+      case FT_PIXEL_MODE_GRAY4:
+        ppb = 2;
+        break;
+      case FT_PIXEL_MODE_GRAY:
+        ppb = 1;
+        break;
+      default:
+        return FT_Err_Invalid_Glyph_Format;
+    }
+
+    /* no need to allocation */
+    if ( ypixels == 0 && pitch * ppb >= bitmap->width + xpixels )
+      return FT_Err_Ok;
+
+    new_pitch = ( bitmap->width + xpixels + ppb - 1 ) / ppb;
+
+    if ( FT_ALLOC( buffer, new_pitch * ( bitmap->rows + ypixels ) ) )
+      return error;
+
+    if ( bitmap->pitch > 0 )
+    {
+      for ( i = 0; i < bitmap->rows; i++ )
+        FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ),
+                     bitmap->buffer + pitch * i, pitch );
+    }
+    else
+    {
+      for ( i = 0; i < bitmap->rows; i++ )
+        FT_MEM_COPY( buffer + new_pitch * i,
+                     bitmap->buffer + pitch * i, pitch );
+    }
+
+    FT_FREE( bitmap->buffer );
+    bitmap->buffer = buffer;
+
+    if ( bitmap->pitch < 0 )
+      new_pitch = -new_pitch;
+
+    /* set pitch only */
+    bitmap->pitch = new_pitch;
+
+    return FT_Err_Ok;
+  }
+
+
   /* documentation is in ftbitmap.h */
 
   FT_EXPORT_DEF( FT_Error )
+  FT_Bitmap_Embolden( FT_Library  library,
+                      FT_Bitmap*  bitmap,
+                      FT_Pos*     xStrength,
+                      FT_Pos*     yStrength )
+  {
+    FT_Error        error;
+    unsigned char*  p;
+    int             i, x, y, pitch;
+    FT_UInt         xstr, ystr;
+
+
+    if ( !library )
+      return FT_Err_Invalid_Library_Handle;
+
+    if ( !bitmap || !xStrength || !yStrength )
+      return FT_Err_Invalid_Argument;
+
+    switch ( bitmap->pixel_mode )
+    {
+      case FT_PIXEL_MODE_GRAY2:
+      case FT_PIXEL_MODE_GRAY4:
+        return FT_Err_Invalid_Glyph_Format;
+    }
+
+    *xStrength = FT_PIX_ROUND( *xStrength );
+    *yStrength = FT_PIX_ROUND( *yStrength );
+
+    xstr = *xStrength >> 6;
+    ystr = *yStrength >> 6;
+
+    if ( xstr == 0 && ystr == 0 )
+      return FT_Err_Ok;
+    else if ( xstr < 0 || ystr < 0 || xstr > 8 )
+      return FT_Err_Invalid_Argument;
+
+    error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr );
+    if ( error )
+      return error;
+
+    pitch = bitmap->pitch;
+    if ( pitch > 0 )
+    {
+      p = bitmap->buffer + pitch * ystr;
+    }
+    else
+    {
+      pitch = -pitch;
+      p = bitmap->buffer + pitch * ( bitmap->rows - ystr - 1 );
+    }
+
+    /* for each row */
+    for ( y = 0; y < bitmap->rows ; y++ )
+    {
+      /* 
+       * Horizontally:
+       *
+       * From the last pixel on, make each pixel or'ed with the
+       * xstr pixels before it
+       */
+      for ( x = pitch - 1; x >= 0; x-- )
+      {
+        unsigned char tmp;
+
+        tmp = p[x];
+        for ( i = 1; i <= xstr; i++ )
+        {
+          if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO )
+          {
+            p[x] |= tmp >> i;
+
+            /* the "8" restriction of xstr comes from here */
+            if ( x > 0 )
+              p[x] |= p[x - 1] << ( 8 - i );
+          }
+          else if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY )
+          {
+            if ( x - i >= 0 )
+            {
+              if ( p[x] + p[x - i] > 0xff )
+                p[x] = 0xff;
+              else
+                p[x] += p[x - i];
+            }
+          }
+        }
+      }
+
+      /* 
+       * Vertically:
+       *
+       * make the above ystr rows or'ed with it
+       */
+      for ( x = 1; x <= ystr; x++ )
+      {
+        unsigned char*  q;
+
+
+        q = p - bitmap->pitch * x;
+        for ( i = 0; i < pitch; i++ )
+          q[i] |= p[i];
+      }
+
+      p += bitmap->pitch;
+    }
+
+    bitmap->width += xstr;
+    bitmap->rows += ystr;
+
+    return FT_Err_Ok;
+  }
+
+
+  /* documentation is in ftbitmap.h */
+
+  FT_EXPORT_DEF( FT_Error )
   FT_Bitmap_Convert( FT_Library        library,
                      const FT_Bitmap  *source,
                      FT_Bitmap        *target,
=== src/base/ftoutln.c
==================================================================
--- src/base/ftoutln.c   (/freetype2/trunk)   (revision 898)
+++ src/base/ftoutln.c   (/freetype2/branches/embolden)   (local)
@@ -670,6 +670,89 @@
 
   /* documentation is in ftoutln.h */
 
+  FT_EXPORT_DEF( FT_Error )
+  FT_Outline_Embolden( FT_Outline*  outline,
+                       FT_Pos       strength )
+  {
+    FT_Vector*  points;
+    FT_Vector   v_prev, v_first, v_next, v_cur;
+    FT_Angle    rotate, angle_in, angle_out;
+    FT_Int      c, n, first;
+
+
+    if ( !outline )
+      return FT_Err_Invalid_Argument;
+
+    if ( strength == 0 )
+      return FT_Err_Ok;
+
+    if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_TRUETYPE )
+      rotate = -FT_ANGLE_PI2;
+    else
+      rotate = FT_ANGLE_PI2;
+
+    points = outline->points;
+
+    first = 0;
+    for ( c = 0; c < outline->n_contours; c++ )
+    {
+      int  last = outline->contours[c];
+
+
+      v_first = points[first];
+      v_prev  = points[last];
+      v_cur   = v_first;
+
+      for ( n = first; n <= last; n++ )
+      {
+        FT_Vector  in, out;
+        FT_Angle   angle_diff;
+        FT_Pos     d;
+        FT_Fixed   scale;
+
+
+        if ( n < last ) v_next = points[n + 1];
+        else            v_next = v_first;
+
+        /* compute the in and out vectors */
+        in.x  = v_cur.x - v_prev.x;
+        in.y  = v_cur.y - v_prev.y;
+
+        out.x = v_next.x - v_cur.x;
+        out.y = v_next.y - v_cur.y;
+
+        angle_in   = FT_Atan2( in.x, in.y );
+        angle_out  = FT_Atan2( out.x, out.y );
+        angle_diff = FT_Angle_Diff( angle_in, angle_out );
+        scale      = FT_Cos( angle_diff / 2 );
+
+        if ( scale < 0x4000L && scale > -0x4000L )
+        {
+          in.x = in.y = 0;
+        }
+        else
+        {
+          d = FT_DivFix( strength, scale );
+
+          FT_Vector_From_Polar( &in, d, angle_in + angle_diff / 2 - rotate );
+        }
+
+        outline->points[n].x = v_cur.x + strength + in.x;
+        outline->points[n].y = v_cur.y + strength + in.y;
+
+        v_prev = v_cur;
+        v_cur  = v_next;
+      }
+
+      first = last + 1;
+    }
+
+    return FT_Err_Ok;
+  }
+
+
+  /* documentation is in ftoutln.h */
+
   FT_EXPORT_DEF( FT_Orientation )
   FT_Outline_Get_Orientation( FT_Outline*  outline )
   {
=== src/base/ftsynth.c
==================================================================
--- src/base/ftsynth.c   (/freetype2/trunk)   (revision 898)
+++ src/base/ftsynth.c   (/freetype2/branches/embolden)   (local)
@@ -17,11 +17,10 @@
 
 
 #include <ft2build.h>
+#include FT_SYNTHESIS_H
 #include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_CALC_H
 #include FT_OUTLINE_H
-#include FT_TRIGONOMETRY_H
-#include FT_SYNTHESIS_H
+#include FT_BITMAP_H
 
 
 #define FT_BOLD_THRESHOLD  0x0100
@@ -77,86 +76,51 @@
   FT_EXPORT_DEF( void )
   FT_GlyphSlot_Embolden( FT_GlyphSlot  slot )
   {
-    FT_Vector*   points;
-    FT_Vector    v_prev, v_first, v_next, v_cur;
-    FT_Pos       distance;
-    FT_Outline*  outline = &slot->outline;
-    FT_Face      face = FT_SLOT_FACE( slot );
-    FT_Angle     rotate, angle_in, angle_out;
-    FT_Int       c, n, first;
+    FT_Library  library = slot->library;
+    FT_Face     face    = FT_SLOT_FACE( slot );
+    FT_Pos      xstr, ystr;
+    FT_Error    error;
 
 
-    /* only embolden outline glyph images */
-    if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
-      return;
+    /* some reasonable strength */
+    xstr = FT_MulFix( face->units_per_EM,
+        face->size->metrics.y_scale ) / 32;
+    ystr = xstr;
 
-    /* compute control distance */
-    distance = FT_MulFix( face->units_per_EM / 60,
-                          face->size->metrics.y_scale );
+    if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
+    {
+      error = FT_Outline_Embolden( &slot->outline, xstr );
+      xstr = ( xstr * 4 ) & ~63;
+      ystr = xstr;
+    }
+    else if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
+    {
+      xstr = FT_PIX_FLOOR( xstr );
+      if ( xstr == 0 )
+        xstr = 1 << 6;
+      ystr = FT_PIX_FLOOR( ystr );
 
-    if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_TRUETYPE )
-      rotate = -FT_ANGLE_PI2;
+      error = FT_Bitmap_Embolden( library, &slot->bitmap, &xstr, &ystr );
+
+      /* XXX should we set these? */
+      if ( !error )
+        slot->bitmap_top += ystr >> 6;
+    }
     else
-      rotate = FT_ANGLE_PI2;
+      error = FT_Err_Invalid_Argument;
 
-    points = outline->points;
-
-    first = 0;
-    for ( c = 0; c < outline->n_contours; c++ )
+    /* XXX should we set these? */
+    if ( !error )
     {
-      int  last = outline->contours[c];
+#if 0
+      slot->advance.x += xstr;
 
-
-      v_first = points[first];
-      v_prev  = points[last];
-      v_cur   = v_first;
-
-      for ( n = first; n <= last; n++ )
-      {
-        FT_Pos     d;
-        FT_Vector  in, out;
-        FT_Fixed   scale;
-        FT_Angle   angle_diff;
-
-
-        if ( n < last ) v_next = points[n + 1];
-        else            v_next = v_first;
-
-        /* compute the in and out vectors */
-        in.x  = v_cur.x - v_prev.x;
-        in.y  = v_cur.y - v_prev.y;
-
-        out.x = v_next.x - v_cur.x;
-        out.y = v_next.y - v_cur.y;
-
-        angle_in   = FT_Atan2( in.x, in.y );
-        angle_out  = FT_Atan2( out.x, out.y );
-        angle_diff = FT_Angle_Diff( angle_in, angle_out );
-        scale      = FT_Cos( angle_diff/2 );
-
-        if ( scale < 0x4000L && scale > -0x4000L )
-        {
-          in.x = in.y = 0;
-        }
-        else
-        {
-          d = FT_DivFix( distance, scale );
-
-          FT_Vector_From_Polar( &in, d, angle_in + angle_diff/2 - rotate );
-        }
-
-        outline->points[n].x = v_cur.x + distance + in.x;
-        outline->points[n].y = v_cur.y + distance + in.y;
-
-        v_prev = v_cur;
-        v_cur  = v_next;
-      }
-
-      first = last + 1;
+      slot->metrics.width += xstr;
+      slot->metrics.height += ystr;
+      slot->metrics.horiBearingY += ystr;
+#endif
+      slot->metrics.horiAdvance += xstr;
     }
-
-    slot->metrics.horiAdvance =
-      ( slot->metrics.horiAdvance + distance*4 ) & ~63;
   }
 
 

Property changes on: 
___________________________________________________________________
Name: svk:merge
 +5f392c16-9bf0-0310-b16c-a65848a4e34f:/freetype2/trunk:895

_______________________________________________
Freetype mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/freetype

Reply via email to