Commit 3cc7d630bdccc1f2ae4bbf97ba7fddcddeb470c5

David Turner 2006-09-27T08:48:38

adding missing file

diff --git a/src/base/ftlcdfil.c b/src/base/ftlcdfil.c
new file mode 100644
index 0000000..ae1a221
--- /dev/null
+++ b/src/base/ftlcdfil.c
@@ -0,0 +1,169 @@
+#include <ft2build.h>
+#include FT_LCD_FILTER_H
+#include FT_IMAGE_H
+#include FT_INTERNAL_OBJECTS_H
+
+#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
+
+ /* this function will be invoked from within the smooth
+  * rasterizer
+  */
+  static void
+  _ft_lcd_filter( FT_Bitmap*      bitmap,
+                  FT_Render_Mode  mode,
+                  FT_Byte*        weights )
+  {
+    FT_UInt   width  = (FT_UInt) bitmap->width;
+    FT_UInt   height = (FT_UInt) bitmap->rows;
+
+    /* horizontal in-place FIR filter */
+    if ( mode == FT_RENDER_MODE_LCD && width >= 4 )
+    {
+      FT_Byte*   line = bitmap->buffer;
+
+      for ( ; height > 0; height--, line += bitmap->pitch )
+      {
+        FT_UInt   fir[5];
+        FT_UInt   val1, xx;
+
+        val1   = line[0];
+        fir[0] = weights[2]*val1;
+        fir[1] = weights[3]*val1;
+        fir[2] = weights[4]*val1;
+        fir[3] = 0;
+        fir[4] = 0;
+
+
+        val1    = line[1];
+        fir[0] += weights[1]*val1;
+        fir[1] += weights[2]*val1;
+        fir[2] += weights[3]*val1;
+        fir[3] += weights[4]*val1;
+
+        for ( xx = 2; xx < width; xx++ )
+        {
+          FT_UInt  val, pix;
+
+          val    = line[xx];
+          pix    = fir[0] + weights[0]*val;
+          fir[0] = fir[1] + weights[1]*val;
+          fir[1] = fir[2] + weights[2]*val;
+          fir[2] = fir[3] + weights[3]*val;
+          fir[3] =          weights[4]*val;
+
+          pix      >>= 8;
+          pix       |= -(pix >> 8);
+          line[xx-2] = (FT_Byte)pix;
+        }
+
+        {
+          FT_UInt  pix;
+
+          pix        = fir[0] >> 8;
+          pix       |= -(pix >> 8);
+          line[xx-2] = (FT_Byte)pix;
+
+          pix        = fir[1] >> 8;
+          pix       |= -(pix >> 8);
+          line[xx-1] = (FT_Byte)pix;
+        }
+      }
+    }
+    /* vertical in-place FIR filter */
+    else if ( mode == FT_RENDER_MODE_LCD_V && height >= 4 )
+    {
+      FT_Byte*   column = bitmap->buffer;
+      FT_Int     pitch  = bitmap->pitch;
+
+      for ( ; width > 0; width--, column++ )
+      {
+        FT_Byte*  col = column;
+        FT_UInt   fir[5];
+        FT_UInt   val1, yy;
+
+        val1   = col[0];
+        fir[0] = weights[2]*val1;
+        fir[1] = weights[3]*val1;
+        fir[2] = weights[4]*val1;
+        fir[3] = 0;
+        fir[4] = 0;
+        col   += pitch;
+
+        val1    = col[0];
+        fir[0] += weights[1]*val1;
+        fir[1] += weights[2]*val1;
+        fir[2] += weights[3]*val1;
+        fir[3] += weights[4]*val1;
+        col    += pitch;
+
+        for ( yy = 2; yy < height; yy++ )
+        {
+          FT_UInt  val, pix;
+
+          val    = col[0];
+          pix    = fir[0] + weights[0]*val;
+          fir[0] = fir[1] + weights[1]*val;
+          fir[1] = fir[2] + weights[2]*val;
+          fir[2] = fir[3] + weights[3]*val;
+          fir[3] =          weights[4]*val;
+
+          pix         >>= 8;
+          pix          |= -(pix >> 8);
+          col[-2*pitch] = (FT_Byte)pix;
+          col          += pitch;
+        }
+
+        {
+          FT_UInt  pix;
+
+          pix           = fir[0] >> 8;
+          pix          |= -(pix >> 8);
+          col[-2*pitch] = (FT_Byte)pix;
+
+          pix         = fir[1] >> 8;
+          pix        |= -(pix >> 8);
+          col[-pitch] = (FT_Byte)pix;
+        }
+      }
+    }
+  }
+
+
+  FT_EXPORT( FT_Error )
+  FT_Library_SetLcdFilter( FT_Library       library,
+                           const FT_Byte*   filter_weights )
+  {
+    static const FT_Byte  default_filter[5] = { 0x10, 0x40, 0x70, 0x40, 0x10 };
+
+    if ( library == NULL )
+      return FT_Err_Invalid_Argument;
+
+    if ( filter_weights == FT_LCD_FILTER_NONE )
+    {
+      library->lcd_filter = NULL;
+      return 0;
+    }
+
+    if ( filter_weights == FT_LCD_FILTER_DEFAULT )
+      filter_weights = default_filter;
+
+    memcpy( library->lcd_filter_weights, filter_weights, 5 );
+    library->lcd_filter = _ft_lcd_filter;
+
+    return 0;
+  }
+
+#else
+
+  FT_EXPORT( FT_Error )
+  FT_Library_SetLcdFilter( FT_Library       library,
+                           const FT_Byte*   filter_weights )
+  {
+    FT_UNUSED(library);
+    FT_UNUSED(filter_weights);
+
+    return FT_Err_Unimplemented_Feature;
+  }
+
+
+#endif