* 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:
parent
b4119a933e
commit
afb2ba5756
21
ChangeLog
21
ChangeLog
|
@ -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
|
||||
|
|
15
docs/CHANGES
15
docs/CHANGES
|
@ -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
|
||||
|
|
|
@ -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> */
|
||||
|
|
|
@ -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> */
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue