* 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.
This commit is contained in:
Werner Lemberg 2005-05-25 05:51:01 +00:00
parent b4119a933e
commit afb2ba5756
7 changed files with 401 additions and 83 deletions

View File

@ -1,3 +1,24 @@
2005-05-24 Werner Lemberg <wl@gnu.org>
* docs/CHANGES: Updated.
2005-05-24 Chia I Wu <b90201047@ntu.edu.tw>
* 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 <wl@gnu.org>
* configure: Always remove config.mk, builds/unix/unix-def.mk, and

View File

@ -60,10 +60,17 @@ LATEST CHANGES BETWEEN 2.1.10 and 2.1.9
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

View File

@ -89,6 +89,42 @@ FT_BEGIN_HEADER
FT_Bitmap *target);
/*************************************************************************/
/* */
/* <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> */

View File

@ -58,6 +58,7 @@ FT_BEGIN_HEADER
/* FT_Outline_Copy */
/* FT_Outline_Translate */
/* FT_Outline_Transform */
/* FT_Outline_Embolden */
/* FT_Outline_Reverse */
/* FT_Outline_Check */
/* */
@ -303,6 +304,31 @@ FT_BEGIN_HEADER
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 );
/*************************************************************************/
/* */
/* <Function> */

View File

@ -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 )

View File

@ -668,6 +668,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 )

View File

@ -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_INTERNAL_OBJECTS_H
#include FT_INTERNAL_CALC_H
#include FT_OUTLINE_H
#include FT_TRIGONOMETRY_H
#include FT_SYNTHESIS_H
#include FT_INTERNAL_OBJECTS_H
#include FT_OUTLINE_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];
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;
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 );
slot->metrics.horiAdvance =
( slot->metrics.horiAdvance + distance*4 ) & ~63;
error = FT_Bitmap_Embolden( library, &slot->bitmap, xstr, ystr );
/* XXX should we set these? */
if ( !error )
slot->bitmap_top += ystr >> 6;
}
else
error = FT_Err_Invalid_Argument;
/* 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;
}
}