* src/base/ftstroke.c, include/freetype/ftstroke.h: fixing bugs and

adding FT_Glyph_Stroke and FT_Glyph_StrokerBorder APIs
This commit is contained in:
David Turner 2004-01-16 08:57:05 +00:00
parent cd9f3b3b5a
commit fa0346d6d9
2 changed files with 276 additions and 26 deletions

View File

@ -21,6 +21,7 @@
#include <ft2build.h>
#include FT_OUTLINE_H
#include FT_GLYPH_H
FT_BEGIN_HEADER
@ -128,7 +129,7 @@ FT_BEGIN_HEADER
{
FT_STROKER_BORDER_LEFT = 0,
FT_STROKER_BORDER_RIGHT
} FT_StrokerBorder;
@ -173,7 +174,7 @@ FT_BEGIN_HEADER
FT_EXPORT( FT_StrokerBorder )
FT_Outline_GetOutsideBorder( FT_Outline* outline );
/**************************************************************
*
* @function:
@ -234,6 +235,24 @@ FT_BEGIN_HEADER
FT_Fixed miter_limit );
/**************************************************************
*
* @function:
* FT_Stroker_Rewind
*
* @description:
* Reset a stroker object without changing its attributes.
* you should call this function before beginning a new
* series of calls to @FT_Stroker_BeginSubPath/@FT_Stroker_EndSubPath
*
* @input:
* stroker ::
* The target stroker handle.
*/
FT_EXPORT( void )
FT_Stroker_Rewind( FT_Stroker stroker );
/**************************************************************
*
* @function:
@ -264,6 +283,8 @@ FT_BEGIN_HEADER
*
* If `opened' is 1, the outline is processed as an open path, and the
* stroker will generate a single `stroke' outline.
*
* this function calls @FT_Stroker_Rewind automatically
*/
FT_EXPORT( FT_Error )
FT_Stroker_ParseOutline( FT_Stroker stroker,
@ -278,7 +299,7 @@ FT_BEGIN_HEADER
*
* @description:
* Start a new sub-path in the stroker.
*
*
* @input:
* stroker ::
* The target stroker handle.
@ -309,7 +330,7 @@ FT_BEGIN_HEADER
*
* @description:
* Close the current sub-path in the stroker.
*
*
* @input:
* stroker ::
* The target stroker handle.
@ -334,7 +355,7 @@ FT_BEGIN_HEADER
* @description:
* `Draw' a single line segment in the stroker's current sub-path,
* from the last position.
*
*
* @input:
* stroker ::
* The target stroker handle.
@ -362,7 +383,7 @@ FT_BEGIN_HEADER
* @description:
* `Draw; a single quadratic bezier in the stroker's current sub-path,
* from the last position.
*
*
* @input:
* stroker ::
* The target stroker handle.
@ -394,7 +415,7 @@ FT_BEGIN_HEADER
* @description:
* `Draw' a single cubic Bézier in the stroker's current sub-path,
* from the last position.
*
*
* @input:
* stroker ::
* The target stroker handle.
@ -432,7 +453,7 @@ FT_BEGIN_HEADER
* with the stroker. It will return the number of points and
* contours necessary to export one of the `border' or `stroke'
* outlines generated by the stroker.
*
*
* @input:
* stroker ::
* The target stroker handle.
@ -453,7 +474,7 @@ FT_BEGIN_HEADER
* @note:
* When an outline, or a sub-path, is `closed', the stroker generates
* two independent `border' outlines, named `left' and `right'.
*
*
* When the outline, or a sub-path, is `opened', the stroker merges
* the `border' outlines with caps. The `left' border receives all
* points, while the `right' border becomes empty.
@ -477,7 +498,7 @@ FT_BEGIN_HEADER
* Call this function after @FT_Stroker_GetBorderCounts to
* export the corresponding border to your own @FT_Outline
* structure.
*
*
* Note that this function will append the border points and
* contours to your outline, but will not try to resize its
* arrays.
@ -499,7 +520,7 @@ FT_BEGIN_HEADER
*
* When an outline, or a sub-path, is `closed', the stroker generates
* two independent `border' outlines, named `left' and `right'
*
*
* When the outline, or a sub-path, is `opened', the stroker merges
* the `border' outlines with caps. The `left' border receives all
* points, while the `right' border becomes empty.
@ -523,7 +544,7 @@ FT_BEGIN_HEADER
* with the stroker. It returns the number of points and
* contours necessary to export all points/borders from the stroked
* outline/path.
*
*
* @input:
* stroker ::
* The target stroker handle.
@ -552,7 +573,7 @@ FT_BEGIN_HEADER
* @description:
* Call this function after @FT_Stroker_GetBorderCounts to
* export the all borders to your own @FT_Outline structure.
*
*
* Note that this function will append the border points and
* contours to your outline, but will not try to resize its
* arrays.
@ -584,6 +605,73 @@ FT_BEGIN_HEADER
FT_EXPORT( void )
FT_Stroker_Done( FT_Stroker stroker );
/**************************************************************
*
* @function:
* FT_Glyph_Stroke
*
* @description:
* stroke a given outline glyph object with a given stroker
*
* @inout:
* pglyph :: source glyph handle on input, new glyph handle
* on output.
*
* @input:
* stroker ::
* A stroker handle.
*
* destroy :: boolean. If TRUE, the source glyph object is destroyed
* on success
*
* @return:
* FreeType error code. 0 means success
*
* @note:
* the source glyph is untouched in case of error.
*/
FT_EXPORT( FT_Error )
FT_Glyph_Stroke( FT_Glyph *pglyph,
FT_Stroker stroker,
FT_Bool destroy );
/**************************************************************
*
* @function:
* FT_Glyph_StrokeBorder
*
* @description:
* stroke a given outline glyph object with a given stroker, but
* only returns either its inside or outside border
*
* @inout:
* pglyph :: source glyph handle on input, new glyph handle
* on output.
*
* @input:
* stroker ::
* A stroker handle.
*
* inside :: boolean. If TRUE, return the inside border; otherwise,
* the outside border
*
* destroy :: boolean. If TRUE, the source glyph object is destroyed
* on success
*
* @return:
* FreeType error code. 0 means success
*
* @note:
* the source glyph is untouched in case of error.
*/
FT_EXPORT( FT_Error )
FT_Glyph_StrokeBorder( FT_Glyph *pglyph,
FT_Stroker stroker,
FT_Bool inside,
FT_Bool destroy );
/* */
FT_END_HEADER

View File

@ -22,7 +22,7 @@
#include FT_OUTLINE_H
#include FT_INTERNAL_MEMORY_H
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_OBJECTS_H
FT_EXPORT_DEF( FT_StrokerBorder )
FT_Outline_GetInsideBorder( FT_Outline* outline )
@ -41,8 +41,8 @@
FT_Orientation o = FT_Outline_Get_Orientation( outline );
return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_RIGHT
: FT_STROKER_BORDER_LEFT ;
return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_LEFT
: FT_STROKER_BORDER_RIGHT ;
}
@ -581,7 +581,8 @@
{
/* copy point locations */
FT_ARRAY_COPY( outline->points + outline->n_points,
border->points, border->num_points );
border->points,
border->num_points );
/* copy tags */
{
@ -689,8 +690,18 @@
stroker->line_join = line_join;
stroker->miter_limit = miter_limit;
ft_stroke_border_reset( &stroker->borders[0] );
ft_stroke_border_reset( &stroker->borders[1] );
FT_Stroker_Rewind( stroker );
}
FT_EXPORT_DEF( void )
FT_Stroker_Rewind( FT_Stroker stroker )
{
if ( stroker )
{
ft_stroke_border_reset( &stroker->borders[0] );
ft_stroke_border_reset( &stroker->borders[1] );
}
}
@ -1373,7 +1384,6 @@
{
FT_Error error = 0;
if ( stroker->subpath_open )
{
FT_StrokeBorder right = stroker->borders;
@ -1406,6 +1416,15 @@
FT_Angle turn;
FT_Int inside_side;
/* close the path if needed
*/
if ( stroker->center.x != stroker->subpath_start.x ||
stroker->center.y != stroker->subpath_start.y )
{
error = FT_Stroker_LineTo( stroker, &stroker->subpath_start );
if ( error )
goto Exit;
}
/* process the corner */
stroker->angle_out = stroker->subpath_angle;
@ -1434,14 +1453,9 @@
goto Exit;
}
/* we will first end our two subpaths */
/* then end our two subpaths */
ft_stroke_border_close( stroker->borders + 0 );
ft_stroke_border_close( stroker->borders + 1 );
/* now, add the reversed left subpath to "right" */
error = ft_stroker_add_reverse_left( stroker, 0 );
if ( error )
goto Exit;
}
Exit:
@ -1561,6 +1575,8 @@
if ( !outline || !stroker )
return FT_Err_Invalid_Argument;
FT_Stroker_Rewind( stroker );
first = 0;
for ( n = 0; n < outline->n_contours; n++ )
@ -1731,4 +1747,150 @@
}
extern const FT_Glyph_Class ft_outline_glyph_class;
FT_EXPORT_DEF( FT_Error )
FT_Glyph_Stroke( FT_Glyph *pglyph,
FT_Stroker stroker,
FT_Bool destroy )
{
FT_Error error = FT_Err_Invalid_Argument;
FT_Glyph glyph = NULL;
if ( pglyph == NULL )
goto Exit;
glyph = *pglyph;
if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class )
goto Exit;
{
FT_Glyph copy;
error = FT_Glyph_Copy( glyph, &copy );
if ( error )
goto Exit;
glyph = copy;
}
{
FT_OutlineGlyph oglyph = (FT_OutlineGlyph) glyph;
FT_Outline* outline = &oglyph->outline;
FT_UInt num_points, num_contours;
error = FT_Stroker_ParseOutline( stroker, outline, 0 );
if (error)
goto Fail;
(void)FT_Stroker_GetCounts( stroker, &num_points, &num_contours );
FT_Outline_Done( glyph->library, outline );
error = FT_Outline_New( glyph->library, num_points, num_contours, outline );
if ( error )
goto Fail;
outline->n_points = 0;
outline->n_contours = 0;
FT_Stroker_Export( stroker, outline );
}
if ( destroy )
FT_Done_Glyph( *pglyph );
*pglyph = glyph;
goto Exit;
Fail:
FT_Done_Glyph( glyph );
glyph = NULL;
if ( !destroy )
*pglyph = NULL;
Exit:
return error;
}
FT_EXPORT_DEF( FT_Error )
FT_Glyph_StrokeBorder( FT_Glyph *pglyph,
FT_Stroker stroker,
FT_Bool inside,
FT_Bool destroy )
{
FT_Error error = FT_Err_Invalid_Argument;
FT_Glyph glyph = NULL;
if ( pglyph == NULL )
goto Exit;
glyph = *pglyph;
if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class )
goto Exit;
{
FT_Glyph copy;
error = FT_Glyph_Copy( glyph, &copy );
if ( error )
goto Exit;
glyph = copy;
}
{
FT_OutlineGlyph oglyph = (FT_OutlineGlyph) glyph;
FT_StrokerBorder border;
FT_Outline* outline = &oglyph->outline;
FT_UInt num_points, num_contours;
border = FT_Outline_GetOutsideBorder( outline );
if ( inside )
border = 1-border;
error = FT_Stroker_ParseOutline( stroker, outline, 0 );
if (error)
goto Fail;
(void)FT_Stroker_GetBorderCounts( stroker, border,
&num_points, &num_contours );
FT_Outline_Done( glyph->library, outline );
error = FT_Outline_New( glyph->library,
num_points,
num_contours,
outline );
if ( error )
goto Fail;
outline->n_points = 0;
outline->n_contours = 0;
FT_Stroker_ExportBorder( stroker, border, outline );
}
if ( destroy )
FT_Done_Glyph( *pglyph );
*pglyph = glyph;
goto Exit;
Fail:
FT_Done_Glyph( glyph );
glyph = NULL;
if ( !destroy )
*pglyph = NULL;
Exit:
return error;
}
/* END */