mirror of https://github.com/freetype/freetype
* include/freetype/ftoutln.h (enum FT_Orientation): New value
`FT_ORIENTATION_NONE'. * src/base/ftoutln.c (FT_OUTLINE_GET_CONTOUR, ft_contour_has, ft_contour_enclosed, ft_outline_get_orientation): Another version of `FT_Outline_Get_Orientation'. This version differs from the public one in that each part (contour not enclosed in another contour) of the outline is checked for orientation. (FT_Outline_Embolden): Use `ft_outline_get_orientation'. * src/base/ftsynth.c (FT_GlyphSlot_Embolden): Render the outline and use bitmap's embolden routine when the outline one failed.
This commit is contained in:
parent
0d9be1c31e
commit
890f807a7b
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
2006-02-23 Chia-I Wu <b90201047@ntu.edu.tw>
|
||||
|
||||
* include/freetype/ftoutln.h (enum FT_Orientation): New value
|
||||
`FT_ORIENTATION_NONE'.
|
||||
|
||||
* src/base/ftoutln.c (FT_OUTLINE_GET_CONTOUR, ft_contour_has,
|
||||
ft_contour_enclosed, ft_outline_get_orientation): Another version of
|
||||
`FT_Outline_Get_Orientation'. This version differs from the public
|
||||
one in that each part (contour not enclosed in another contour) of the
|
||||
outline is checked for orientation.
|
||||
(FT_Outline_Embolden): Use `ft_outline_get_orientation'.
|
||||
|
||||
* src/base/ftsynth.c (FT_GlyphSlot_Embolden): Render the outline and
|
||||
use bitmap's embolden routine when the outline one failed.
|
||||
|
||||
2006-02-22 Chia-I Wu <b90201047@ntu.edu.tw>
|
||||
|
||||
* modules.cfg: Compile in ftotval.c and ftxf86.c by default for ABI
|
||||
|
|
|
@ -465,13 +465,19 @@ FT_BEGIN_HEADER
|
|||
* This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to
|
||||
* remember that in Postscript, everything that is to the left of
|
||||
* the drawing direction of a contour must be filled.
|
||||
*
|
||||
* FT_ORIENTATION_NONE ::
|
||||
* The orientation cannot be determined. That is, different part of the
|
||||
* glyph has different orientation.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
FT_ORIENTATION_TRUETYPE = 0,
|
||||
FT_ORIENTATION_POSTSCRIPT = 1,
|
||||
FT_ORIENTATION_FILL_RIGHT = FT_ORIENTATION_TRUETYPE,
|
||||
FT_ORIENTATION_FILL_LEFT = FT_ORIENTATION_POSTSCRIPT
|
||||
FT_ORIENTATION_FILL_LEFT = FT_ORIENTATION_POSTSCRIPT,
|
||||
FT_ORIENTATION_NONE
|
||||
|
||||
} FT_Orientation;
|
||||
|
||||
|
|
|
@ -668,6 +668,168 @@
|
|||
}
|
||||
|
||||
|
||||
#define FT_OUTLINE_GET_CONTOUR( outline, c, first, last ) \
|
||||
do { \
|
||||
( first ) = ( c > 0 ) ? ( outline )->points + \
|
||||
( outline )->contours[c - 1] + 1 \
|
||||
: ( outline )->points; \
|
||||
( last ) = ( outline )->points + ( outline )->contours[c]; \
|
||||
} while ( 0 )
|
||||
|
||||
|
||||
/* Is a point in some contour? */
|
||||
/* */
|
||||
/* We treat every point of the contour as if it */
|
||||
/* it is ON. That is, we allow false positive, */
|
||||
/* but disallow false negative. (XXX really?) */
|
||||
static FT_Bool
|
||||
ft_contour_has( FT_Outline* outline,
|
||||
FT_Short c,
|
||||
FT_Vector* point )
|
||||
{
|
||||
FT_Vector* first;
|
||||
FT_Vector* last;
|
||||
FT_Vector* a;
|
||||
FT_Vector* b;
|
||||
FT_UInt n = 0;
|
||||
|
||||
|
||||
FT_OUTLINE_GET_CONTOUR( outline, c, first, last );
|
||||
|
||||
for ( a = first; a <= last; a++ )
|
||||
{
|
||||
FT_Pos x;
|
||||
FT_Int intersect;
|
||||
|
||||
|
||||
b = ( a == last ) ? first : a + 1;
|
||||
|
||||
intersect = ( a->y - point->y ) ^ ( b->y - point->y );
|
||||
|
||||
/* a and b are on the same side */
|
||||
if ( intersect >= 0 )
|
||||
{
|
||||
if ( intersect == 0 && a->y == point->y )
|
||||
{
|
||||
if ( ( a->x <= point->x && b->x >= point->x ) ||
|
||||
( a->x >= point->x && b->x <= point->x ) )
|
||||
return 1;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
x = a->x + ( b->x - a->x ) * (point->y - a->y ) / ( b->y - a->y );
|
||||
|
||||
if ( x < point->x )
|
||||
n++;
|
||||
else if ( x == point->x )
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ( n % 2 );
|
||||
}
|
||||
|
||||
|
||||
static FT_Bool
|
||||
ft_contour_enclosed( FT_Outline* outline,
|
||||
FT_UShort c )
|
||||
{
|
||||
FT_Vector* first;
|
||||
FT_Vector* last;
|
||||
FT_Short i;
|
||||
|
||||
|
||||
FT_OUTLINE_GET_CONTOUR( outline, c, first, last );
|
||||
|
||||
for ( i = 0; i < outline->n_contours; i++ )
|
||||
{
|
||||
if ( i != c && ft_contour_has( outline, i, first ) )
|
||||
{
|
||||
FT_Vector* pt;
|
||||
|
||||
|
||||
for ( pt = first + 1; pt <= last; pt++ )
|
||||
if ( !ft_contour_has( outline, i, pt ) )
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* This version differs from the public one in that each */
|
||||
/* part (contour not enclosed in another contour) of the */
|
||||
/* outline is checked for orientation. This is */
|
||||
/* necessary for some buggy CJK fonts. */
|
||||
static FT_Orientation
|
||||
ft_outline_get_orientation( FT_Outline* outline )
|
||||
{
|
||||
FT_Short i;
|
||||
FT_Vector* first;
|
||||
FT_Vector* last;
|
||||
FT_Orientation orient = FT_ORIENTATION_NONE;
|
||||
|
||||
|
||||
first = outline->points;
|
||||
for ( i = 0; i < outline->n_contours; i++, first = last + 1 )
|
||||
{
|
||||
FT_Vector* point;
|
||||
FT_Vector* xmin_point;
|
||||
FT_Pos xmin;
|
||||
|
||||
|
||||
last = outline->points + outline->contours[i];
|
||||
|
||||
/* skip degenerate contours */
|
||||
if ( last < first + 2 )
|
||||
continue;
|
||||
|
||||
if ( ft_contour_enclosed( outline, i ) )
|
||||
continue;
|
||||
|
||||
xmin = first->x;
|
||||
xmin_point = first;
|
||||
|
||||
for ( point = first + 1; point <= last; point++ )
|
||||
{
|
||||
if ( point->x < xmin )
|
||||
{
|
||||
xmin = point->x;
|
||||
xmin_point = point;
|
||||
}
|
||||
}
|
||||
|
||||
/* check the orientation of the contour */
|
||||
{
|
||||
FT_Vector* prev;
|
||||
FT_Vector* next;
|
||||
FT_Orientation o;
|
||||
|
||||
|
||||
prev = ( xmin_point == first ) ? last : xmin_point - 1;
|
||||
next = ( xmin_point == last ) ? first : xmin_point + 1;
|
||||
|
||||
if ( FT_Atan2( prev->x - xmin_point->x, prev->y - xmin_point->y ) >
|
||||
FT_Atan2( next->x - xmin_point->x, next->y - xmin_point->y ) )
|
||||
o = FT_ORIENTATION_POSTSCRIPT;
|
||||
else
|
||||
o = FT_ORIENTATION_TRUETYPE;
|
||||
|
||||
if ( orient == FT_ORIENTATION_NONE )
|
||||
orient = o;
|
||||
else if ( orient != o )
|
||||
return FT_ORIENTATION_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
return orient;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftoutln.h */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
|
@ -678,6 +840,7 @@
|
|||
FT_Vector v_prev, v_first, v_next, v_cur;
|
||||
FT_Angle rotate, angle_in, angle_out;
|
||||
FT_Int c, n, first;
|
||||
FT_Int orientation;
|
||||
|
||||
|
||||
if ( !outline )
|
||||
|
@ -687,7 +850,16 @@
|
|||
if ( strength == 0 )
|
||||
return FT_Err_Ok;
|
||||
|
||||
if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_TRUETYPE )
|
||||
orientation = ft_outline_get_orientation( outline );
|
||||
if ( orientation == FT_ORIENTATION_NONE )
|
||||
{
|
||||
if ( outline->n_contours )
|
||||
return FT_Err_Invalid_Argument;
|
||||
else
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
if ( orientation == FT_ORIENTATION_TRUETYPE )
|
||||
rotate = -FT_ANGLE_PI2;
|
||||
else
|
||||
rotate = FT_ANGLE_PI2;
|
||||
|
|
|
@ -75,10 +75,14 @@
|
|||
{
|
||||
FT_Library library = slot->library;
|
||||
FT_Face face = FT_SLOT_FACE( slot );
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_Error error;
|
||||
FT_Pos xstr, ystr;
|
||||
|
||||
|
||||
if ( slot->format != FT_GLYPH_FORMAT_OUTLINE &&
|
||||
slot->format != FT_GLYPH_FORMAT_BITMAP )
|
||||
return;
|
||||
|
||||
/* some reasonable strength */
|
||||
xstr = FT_MulFix( face->units_per_EM,
|
||||
face->size->metrics.y_scale ) / 24;
|
||||
|
@ -87,13 +91,22 @@
|
|||
if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
|
||||
{
|
||||
error = FT_Outline_Embolden( &slot->outline, xstr );
|
||||
|
||||
/* this is more than enough for most glyphs; */
|
||||
/* if you need accurate values, you have to call FT_Outline_Get_CBox */
|
||||
xstr = xstr * 2;
|
||||
ystr = xstr;
|
||||
if ( error )
|
||||
{
|
||||
error = FT_Render_Glyph( slot, FT_RENDER_MODE_NORMAL );
|
||||
if ( error )
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this is more than enough for most glyphs; */
|
||||
/* if you need accurate values, you have to call FT_Outline_Get_CBox */
|
||||
xstr = xstr * 2;
|
||||
ystr = xstr;
|
||||
}
|
||||
}
|
||||
else if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
|
||||
|
||||
if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
|
||||
{
|
||||
xstr = FT_PIX_FLOOR( xstr );
|
||||
if ( xstr == 0 )
|
||||
|
@ -108,37 +121,31 @@
|
|||
|
||||
FT_Bitmap_New( &bitmap );
|
||||
error = FT_Bitmap_Copy( library, &slot->bitmap, &bitmap );
|
||||
if ( error )
|
||||
return;
|
||||
|
||||
if ( !error )
|
||||
{
|
||||
slot->bitmap = bitmap;
|
||||
slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
|
||||
}
|
||||
slot->bitmap = bitmap;
|
||||
slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
|
||||
}
|
||||
|
||||
if ( !error )
|
||||
error = FT_Bitmap_Embolden( library, &slot->bitmap, xstr, ystr );
|
||||
error = FT_Bitmap_Embolden( library, &slot->bitmap, xstr, ystr );
|
||||
if ( error )
|
||||
return;
|
||||
}
|
||||
else
|
||||
error = FT_Err_Invalid_Argument;
|
||||
|
||||
/* modify the metrics accordingly */
|
||||
if ( !error )
|
||||
{
|
||||
/* assume the layout is horizontal */
|
||||
slot->advance.x += xstr;
|
||||
/* assume the layout is horizontal */
|
||||
slot->advance.x += xstr;
|
||||
|
||||
slot->metrics.width += xstr;
|
||||
slot->metrics.height += ystr;
|
||||
slot->metrics.horiBearingY += ystr;
|
||||
slot->metrics.horiAdvance += xstr;
|
||||
slot->metrics.vertBearingX -= xstr / 2;
|
||||
slot->metrics.vertBearingY += ystr;
|
||||
slot->metrics.vertAdvance += ystr;
|
||||
slot->metrics.width += xstr;
|
||||
slot->metrics.height += ystr;
|
||||
slot->metrics.horiBearingY += ystr;
|
||||
slot->metrics.horiAdvance += xstr;
|
||||
slot->metrics.vertBearingX -= xstr / 2;
|
||||
slot->metrics.vertBearingY += ystr;
|
||||
slot->metrics.vertAdvance += ystr;
|
||||
|
||||
if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
|
||||
slot->bitmap_top += ystr >> 6;
|
||||
}
|
||||
if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
|
||||
slot->bitmap_top += ystr >> 6;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue