shithub: freetype+ttf2subf

Download patch

ref: afb2ba5756be264d7dd74516d5b27b4c43c3cc97
parent: b4119a933ea0bced1adf2ebc5b0e46df5fb845c2
author: Werner Lemberg <[email protected]>
date: Wed May 25 01:51:01 EDT 2005

* docs/CHANGES: Updated.


* include/freetype/ftbitmap.h (FT_Bitmap_Embolden): New declaration.

* include/freetype/ftoutln.h (FT_Outline_Embolden): New declaration.

* src/base/ftbitmap.c (ft_bitmap_assure_buffer): New auxiliary
function.
(FT_Bitmap_Embolden): New function.

* src/base/ftoutln.c (FT_Outline_Embolden): New function.

* src/base/ftsynth.c: Don't include FT_INTERNAL_CALC_H and
FT_TRIGONOMETRY_H but FT_BITMAP_H.
(FT_GlyphSlot_Embolden): Use FT_Outline_Embolden or
FT_Bitmap_Embolden.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,26 @@
 2005-05-24  Werner Lemberg  <[email protected]>
 
+	* docs/CHANGES: Updated.
+
+2005-05-24  Chia I Wu  <[email protected]>
+
+	* include/freetype/ftbitmap.h (FT_Bitmap_Embolden): New declaration.
+
+	* include/freetype/ftoutln.h (FT_Outline_Embolden): New declaration.
+
+	* src/base/ftbitmap.c (ft_bitmap_assure_buffer): New auxiliary
+	function.
+	(FT_Bitmap_Embolden): New function.
+
+	* src/base/ftoutln.c (FT_Outline_Embolden): New function.
+
+	* src/base/ftsynth.c: Don't include FT_INTERNAL_CALC_H and
+	FT_TRIGONOMETRY_H but FT_BITMAP_H.
+	(FT_GlyphSlot_Embolden): Use FT_Outline_Embolden or
+	FT_Bitmap_Embolden.
+
+2005-05-24  Werner Lemberg  <[email protected]>
+
 	* configure: Always remove config.mk, builds/unix/unix-def.mk, and
 	builds/unix/unix-cc.mk.  This fixes repeated calls of the script.
 	Reported by Nelson Beebe and Behdad Esfahbod.
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -60,10 +60,17 @@
       for errors in those tables while accessing them.
 
     - A new API in FT_BITMAP_H  (`FT_Bitmap_New', `FT_Bitmap_Convert',
-      `FT_Bitmap_Copy', `FT_Bitmap_Done') has been added.   Its use is
-      to convert an FT_Bitmap structure in 1bpp,  2bpp, 4bpp, or  8bpp
-      format into another 8bpp FT_Bitmap,  probably using a  different
-      pitch.
+      `FT_Bitmap_Copy',  `FT_Bitmap_Embolden',  `FT_Bitmap_Done')  has
+      been added.   Its  use is  to convert an  FT_Bitmap structure in
+      1bpp, 2bpp,  4bpp, or 8bpp  format into  another 8bpp FT_Bitmap,
+      probably using a different pitch, and to further manipulate it.
+
+    - A new  API `FT_Outline_Embolden'  (in FT_OUTLINE_H) gives  finer
+      control how  outlines are embolded.
+
+    - `FT_GlyphSlot_Embolden' (in FT_SYNTHESIS_H)  now handles bitmaps
+      also (code contributed  by Chia I Wu).  Note that this  function
+      is still experimental and may be replaced with a better API.
 
     - The method  how BDF and PCF  bitmap fonts  are accessed has been
       refined.   Formerly,   FT_Set_Pixel_Sizes  and  FT_Set_Char_Size
--- a/include/freetype/ftbitmap.h
+++ b/include/freetype/ftbitmap.h
@@ -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.                         */
+  /*                                                                       */
+  /*    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.                      */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    bitmap    :: A handle to the target bitmap.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The 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>                                                         */
--- a/include/freetype/ftoutln.h
+++ b/include/freetype/ftoutln.h
@@ -58,6 +58,7 @@
   /*    FT_Outline_Copy                                                    */
   /*    FT_Outline_Translate                                               */
   /*    FT_Outline_Transform                                               */
+  /*    FT_Outline_Embolden                                                */
   /*    FT_Outline_Reverse                                                 */
   /*    FT_Outline_Check                                                   */
   /*                                                                       */
@@ -301,6 +302,31 @@
   FT_EXPORT( void )
   FT_Outline_Transform( const FT_Outline*  outline,
                         const FT_Matrix*   matrix );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <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.  0 means success.                             */
+  /*                                                                       */
+  FT_EXPORT_DEF( FT_Error )
+  FT_Outline_Embolden( FT_Outline*  outline,
+                       FT_Pos       strength );
 
 
   /*************************************************************************/
--- a/src/base/ftbitmap.c
+++ b/src/base/ftbitmap.c
@@ -94,6 +94,188 @@
   }
 
 
+  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;
+    FT_UInt         ppb;
+    FT_Int          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;
+    }
+
+    /* check whether we must allocate memory */
+    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;
+    FT_Int          i, x, y, pitch;
+    FT_Int          xstr, ystr;
+
+
+    if ( !library )
+      return FT_Err_Invalid_Library_Handle;
+
+    if ( !bitmap )
+      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;
+    }
+
+    xstr = FT_PIX_ROUND( xStrength ) >> 6;
+    ystr = FT_PIX_ROUND( 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 maximum value of 8 for `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 )
--- a/src/base/ftoutln.c
+++ b/src/base/ftoutln.c
@@ -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 )
   {
--- a/src/base/ftsynth.c
+++ b/src/base/ftsynth.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType synthesizing code for emboldening and slanting (body).      */
 /*                                                                         */
-/*  Copyright 2000-2001, 2002, 2003, 2004 by                               */
+/*  Copyright 2000-2001, 2002, 2003, 2004, 2005 by                         */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -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,50 @@
   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 ( 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++ )
+    if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
     {
-      int  last = outline->contours[c];
+      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 );
 
+      error = FT_Bitmap_Embolden( library, &slot->bitmap, xstr, ystr );
 
-      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;
+      /* XXX should we set these? */
+      if ( !error )
+        slot->bitmap_top += ystr >> 6;
     }
+    else
+      error = FT_Err_Invalid_Argument;
 
-    slot->metrics.horiAdvance =
-      ( slot->metrics.horiAdvance + distance*4 ) & ~63;
+    /* XXX should we set these? */
+    if ( !error )
+    {
+#if 0
+      slot->advance.x            += xstr;
+      slot->metrics.width        += xstr;
+      slot->metrics.height       += ystr;
+      slot->metrics.horiBearingY += ystr;
+#endif
+      slot->metrics.horiAdvance  += xstr;
+    }
   }