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.
--- 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;
+ }
}