/**************************************************************************** * * ftstroke.h * * FreeType path stroker (specification). * * Copyright (C) 2002-2020 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, * modified, and distributed under the terms of the FreeType project * license, LICENSE.TXT. By continuing to use, modify, or distribute * this file you indicate that you have read the license and * understand and accept it fully. * */ #ifndef FTSTROKE_H_ #define FTSTROKE_H_ #include #include FT_OUTLINE_H #include FT_GLYPH_H FT_BEGIN_HEADER /************************************************************************** * * @section: * glyph_stroker * * @title: * Glyph Stroker * * @abstract: * Generating bordered and stroked glyphs. * * @description: * This component generates stroked outlines of a given vectorial glyph. * It also allows you to retrieve the 'outside' and/or the 'inside' * borders of the stroke. * * This can be useful to generate 'bordered' glyph, i.e., glyphs * displayed with a coloured (and anti-aliased) border around their * shape. * * @order: * FT_Stroker * * FT_Stroker_LineJoin * FT_Stroker_LineCap * FT_StrokerBorder * * FT_Outline_GetInsideBorder * FT_Outline_GetOutsideBorder * * FT_Glyph_Stroke * FT_Glyph_StrokeBorder * * FT_Stroker_New * FT_Stroker_Set * FT_Stroker_Rewind * FT_Stroker_ParseOutline * FT_Stroker_Done * * FT_Stroker_BeginSubPath * FT_Stroker_EndSubPath * * FT_Stroker_LineTo * FT_Stroker_ConicTo * FT_Stroker_CubicTo * * FT_Stroker_GetBorderCounts * FT_Stroker_ExportBorder * FT_Stroker_GetCounts * FT_Stroker_Export * */ /************************************************************************** * * @type: * FT_Stroker * * @description: * Opaque handle to a path stroker object. */ typedef struct FT_StrokerRec_* FT_Stroker; /************************************************************************** * * @enum: * FT_Stroker_LineJoin * * @description: * These values determine how two joining lines are rendered in a * stroker. * * @values: * FT_STROKER_LINEJOIN_ROUND :: * Used to render rounded line joins. Circular arcs are used to join * two lines smoothly. * * FT_STROKER_LINEJOIN_BEVEL :: * Used to render beveled line joins. The outer corner of the joined * lines is filled by enclosing the triangular region of the corner * with a straight line between the outer corners of each stroke. * * FT_STROKER_LINEJOIN_MITER_FIXED :: * Used to render mitered line joins, with fixed bevels if the miter * limit is exceeded. The outer edges of the strokes for the two * segments are extended until they meet at an angle. A bevel join * (see above) is used if the segments meet at too sharp an angle and * the outer edges meet beyond a distance corresponding to the meter * limit. This prevents long spikes being created. * `FT_STROKER_LINEJOIN_MITER_FIXED` generates a miter line join as * used in PostScript and PDF. * * FT_STROKER_LINEJOIN_MITER_VARIABLE :: * FT_STROKER_LINEJOIN_MITER :: * Used to render mitered line joins, with variable bevels if the miter * limit is exceeded. The intersection of the strokes is clipped * perpendicularly to the bisector, at a distance corresponding to * the miter limit. This prevents long spikes being created. * `FT_STROKER_LINEJOIN_MITER_VARIABLE` generates a mitered line join * as used in XPS. `FT_STROKER_LINEJOIN_MITER` is an alias for * `FT_STROKER_LINEJOIN_MITER_VARIABLE`, retained for backward * compatibility. */ typedef enum FT_Stroker_LineJoin_ { FT_STROKER_LINEJOIN_ROUND = 0, FT_STROKER_LINEJOIN_BEVEL = 1, FT_STROKER_LINEJOIN_MITER_VARIABLE = 2, FT_STROKER_LINEJOIN_MITER = FT_STROKER_LINEJOIN_MITER_VARIABLE, FT_STROKER_LINEJOIN_MITER_FIXED = 3 } FT_Stroker_LineJoin; /************************************************************************** * * @enum: * FT_Stroker_LineCap * * @description: * These values determine how the end of opened sub-paths are rendered in * a stroke. * * @values: * FT_STROKER_LINECAP_BUTT :: * The end of lines is rendered as a full stop on the last point * itself. * * FT_STROKER_LINECAP_ROUND :: * The end of lines is rendered as a half-circle around the last point. * * FT_STROKER_LINECAP_SQUARE :: * The end of lines is rendered as a square around the last point. */ typedef enum FT_Stroker_LineCap_ { FT_STROKER_LINECAP_BUTT = 0, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINECAP_SQUARE } FT_Stroker_LineCap; /************************************************************************** * * @enum: * FT_StrokerBorder * * @description: * These values are used to select a given stroke border in * @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder. * * @values: * FT_STROKER_BORDER_LEFT :: * Select the left border, relative to the drawing direction. * * FT_STROKER_BORDER_RIGHT :: * Select the right border, relative to the drawing direction. * * @note: * Applications are generally interested in the 'inside' and 'outside' * borders. However, there is no direct mapping between these and the * 'left' and 'right' ones, since this really depends on the glyph's * drawing orientation, which varies between font formats. * * You can however use @FT_Outline_GetInsideBorder and * @FT_Outline_GetOutsideBorder to get these. */ typedef enum FT_StrokerBorder_ { FT_STROKER_BORDER_LEFT = 0, FT_STROKER_BORDER_RIGHT } FT_StrokerBorder; /************************************************************************** * * @function: * FT_Outline_GetInsideBorder * * @description: * Retrieve the @FT_StrokerBorder value corresponding to the 'inside' * borders of a given outline. * * @input: * outline :: * The source outline handle. * * @return: * The border index. @FT_STROKER_BORDER_RIGHT for empty or invalid * outlines. */ FT_EXPORT( FT_StrokerBorder ) FT_Outline_GetInsideBorder( FT_Outline* outline ); /************************************************************************** * * @function: * FT_Outline_GetOutsideBorder * * @description: * Retrieve the @FT_StrokerBorder value corresponding to the 'outside' * borders of a given outline. * * @input: * outline :: * The source outline handle. * * @return: * The border index. @FT_STROKER_BORDER_LEFT for empty or invalid * outlines. */ FT_EXPORT( FT_StrokerBorder ) FT_Outline_GetOutsideBorder( FT_Outline* outline ); /************************************************************************** * * @function: * FT_Stroker_New * * @description: * Create a new stroker object. * * @input: * library :: * FreeType library handle. * * @output: * astroker :: * A new stroker object handle. `NULL` in case of error. * * @return: * FreeType error code. 0~means success. */ FT_EXPORT( FT_Error ) FT_Stroker_New( FT_Library library, FT_Stroker *astroker ); /************************************************************************** * * @function: * FT_Stroker_Set * * @description: * Reset a stroker object's attributes. * * @input: * stroker :: * The target stroker handle. * * radius :: * The border radius. * * line_cap :: * The line cap style. * * line_join :: * The line join style. * * miter_limit :: * The maximum reciprocal sine of half-angle at the miter join, * expressed as 16.16 fixed point value. * * @note: * The `radius` is expressed in the same units as the outline * coordinates. * * The `miter_limit` multiplied by the `radius` gives the maximum size * of a miter spike, at which it is clipped for * @FT_STROKER_LINEJOIN_MITER_VARIABLE or replaced with a bevel join for * @FT_STROKER_LINEJOIN_MITER_FIXED. * * This function calls @FT_Stroker_Rewind automatically. */ FT_EXPORT( void ) FT_Stroker_Set( FT_Stroker stroker, FT_Fixed radius, FT_Stroker_LineCap line_cap, FT_Stroker_LineJoin line_join, 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 or @FT_Stroker_EndSubPath. * * @input: * stroker :: * The target stroker handle. */ FT_EXPORT( void ) FT_Stroker_Rewind( FT_Stroker stroker ); /************************************************************************** * * @function: * FT_Stroker_ParseOutline * * @description: * A convenience function used to parse a whole outline with the stroker. * The resulting outline(s) can be retrieved later by functions like * @FT_Stroker_GetCounts and @FT_Stroker_Export. * * @input: * stroker :: * The target stroker handle. * * outline :: * The source outline. * * opened :: * A boolean. If~1, the outline is treated as an open path instead of * a closed one. * * @return: * FreeType error code. 0~means success. * * @note: * If `opened` is~0 (the default), the outline is treated as a closed * path, and the stroker generates two distinct 'border' outlines. * * If `opened` is~1, the outline is processed as an open path, and the * stroker generates a single 'stroke' outline. * * This function calls @FT_Stroker_Rewind automatically. */ FT_EXPORT( FT_Error ) FT_Stroker_ParseOutline( FT_Stroker stroker, FT_Outline* outline, FT_Bool opened ); /************************************************************************** * * @function: * FT_Stroker_BeginSubPath * * @description: * Start a new sub-path in the stroker. * * @input: * stroker :: * The target stroker handle. * * to :: * A pointer to the start vector. * * open :: * A boolean. If~1, the sub-path is treated as an open one. * * @return: * FreeType error code. 0~means success. * * @note: * This function is useful when you need to stroke a path that is not * stored as an @FT_Outline object. */ FT_EXPORT( FT_Error ) FT_Stroker_BeginSubPath( FT_Stroker stroker, FT_Vector* to, FT_Bool open ); /************************************************************************** * * @function: * FT_Stroker_EndSubPath * * @description: * Close the current sub-path in the stroker. * * @input: * stroker :: * The target stroker handle. * * @return: * FreeType error code. 0~means success. * * @note: * You should call this function after @FT_Stroker_BeginSubPath. If the * subpath was not 'opened', this function 'draws' a single line segment * to the start position when needed. */ FT_EXPORT( FT_Error ) FT_Stroker_EndSubPath( FT_Stroker stroker ); /************************************************************************** * * @function: * FT_Stroker_LineTo * * @description: * 'Draw' a single line segment in the stroker's current sub-path, from * the last position. * * @input: * stroker :: * The target stroker handle. * * to :: * A pointer to the destination point. * * @return: * FreeType error code. 0~means success. * * @note: * You should call this function between @FT_Stroker_BeginSubPath and * @FT_Stroker_EndSubPath. */ FT_EXPORT( FT_Error ) FT_Stroker_LineTo( FT_Stroker stroker, FT_Vector* to ); /************************************************************************** * * @function: * FT_Stroker_ConicTo * * @description: * 'Draw' a single quadratic Bezier in the stroker's current sub-path, * from the last position. * * @input: * stroker :: * The target stroker handle. * * control :: * A pointer to a Bezier control point. * * to :: * A pointer to the destination point. * * @return: * FreeType error code. 0~means success. * * @note: * You should call this function between @FT_Stroker_BeginSubPath and * @FT_Stroker_EndSubPath. */ FT_EXPORT( FT_Error ) FT_Stroker_ConicTo( FT_Stroker stroker, FT_Vector* control, FT_Vector* to ); /************************************************************************** * * @function: * FT_Stroker_CubicTo * * @description: * 'Draw' a single cubic Bezier in the stroker's current sub-path, from * the last position. * * @input: * stroker :: * The target stroker handle. * * control1 :: * A pointer to the first Bezier control point. * * control2 :: * A pointer to second Bezier control point. * * to :: * A pointer to the destination point. * * @return: * FreeType error code. 0~means success. * * @note: * You should call this function between @FT_Stroker_BeginSubPath and * @FT_Stroker_EndSubPath. */ FT_EXPORT( FT_Error ) FT_Stroker_CubicTo( FT_Stroker stroker, FT_Vector* control1, FT_Vector* control2, FT_Vector* to ); /************************************************************************** * * @function: * FT_Stroker_GetBorderCounts * * @description: * Call this function once you have finished parsing your paths with the * stroker. It returns 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. * * border :: * The border index. * * @output: * anum_points :: * The number of points. * * anum_contours :: * The number of contours. * * @return: * FreeType error code. 0~means success. * * @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. * * Use the function @FT_Stroker_GetCounts instead if you want to retrieve * the counts associated to both borders. */ FT_EXPORT( FT_Error ) FT_Stroker_GetBorderCounts( FT_Stroker stroker, FT_StrokerBorder border, FT_UInt *anum_points, FT_UInt *anum_contours ); /************************************************************************** * * @function: * FT_Stroker_ExportBorder * * @description: * Call this function after @FT_Stroker_GetBorderCounts to export the * corresponding border to your own @FT_Outline structure. * * Note that this function appends the border points and contours to your * outline, but does not try to resize its arrays. * * @input: * stroker :: * The target stroker handle. * * border :: * The border index. * * outline :: * The target outline handle. * * @note: * Always call this function after @FT_Stroker_GetBorderCounts to get * sure that there is enough room in your @FT_Outline object to receive * all new data. * * 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. * * Use the function @FT_Stroker_Export instead if you want to retrieve * all borders at once. */ FT_EXPORT( void ) FT_Stroker_ExportBorder( FT_Stroker stroker, FT_StrokerBorder border, FT_Outline* outline ); /************************************************************************** * * @function: * FT_Stroker_GetCounts * * @description: * Call this function once you have finished parsing your paths 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. * * @output: * anum_points :: * The number of points. * * anum_contours :: * The number of contours. * * @return: * FreeType error code. 0~means success. */ FT_EXPORT( FT_Error ) FT_Stroker_GetCounts( FT_Stroker stroker, FT_UInt *anum_points, FT_UInt *anum_contours ); /************************************************************************** * * @function: * FT_Stroker_Export * * @description: * Call this function after @FT_Stroker_GetBorderCounts to export all * borders to your own @FT_Outline structure. * * Note that this function appends the border points and contours to your * outline, but does not try to resize its arrays. * * @input: * stroker :: * The target stroker handle. * * outline :: * The target outline handle. */ FT_EXPORT( void ) FT_Stroker_Export( FT_Stroker stroker, FT_Outline* outline ); /************************************************************************** * * @function: * FT_Stroker_Done * * @description: * Destroy a stroker object. * * @input: * stroker :: * A stroker handle. Can be `NULL`. */ 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 :: * A Boolean. If~1, 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. * * Adding stroke may yield a significantly wider and taller glyph * depending on how large of a radius was used to stroke the glyph. You * may need to manually adjust horizontal and vertical advance amounts to * account for this added size. */ 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 * return either its inside or outside border. * * @inout: * pglyph :: * Source glyph handle on input, new glyph handle on output. * * @input: * stroker :: * A stroker handle. * * inside :: * A Boolean. If~1, return the inside border, otherwise the outside * border. * * destroy :: * A Boolean. If~1, 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. * * Adding stroke may yield a significantly wider and taller glyph * depending on how large of a radius was used to stroke the glyph. You * may need to manually adjust horizontal and vertical advance amounts to * account for this added size. */ FT_EXPORT( FT_Error ) FT_Glyph_StrokeBorder( FT_Glyph *pglyph, FT_Stroker stroker, FT_Bool inside, FT_Bool destroy ); /* */ FT_END_HEADER #endif /* FTSTROKE_H_ */ /* END */ /* Local Variables: */ /* coding: utf-8 */ /* End: */