/*
* GPAC - Multimedia Framework C SDK
*
* Authors: Jean Le Feuvre
* Copyright (c) Telecom ParisTech 2000-2012
* All rights reserved
*
* This file is part of GPAC / common tools sub-project
*
* GPAC is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* GPAC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef _GF_PATH2D_H_
#define _GF_PATH2D_H_
/*!
* \file <gpac/path2d.h>
* \brief 2D Vectorial Path.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <gpac/maths.h>
#include <gpac/tools.h>
/*!
*\addtogroup path_grp 2D Vector Path
*\ingroup math_grp
*\brief Vectorial 2D Path manipulation
*
*This section documents the 2D path object used in the GPAC framework.
* @{
*/
/*!\brief 2D Path Object
*
*The 2D path object is used to construct complex 2D shapes for later drawing
* or outlining.
*/
typedef struct
{
/*! number of contours in path*/
u32 n_contours;
/*! number of points in path and alloc size*/
u32 n_points, n_alloc_points;
/*! path points */
GF_Point2D *points;
/*! point tags (one per point)*/
u8 *tags;
/*! contour end points*/
u32 *contours;
/*! path bbox - NEVER USE WITHOUT FIRST CALLING \ref gf_path_get_bounds*/
GF_Rect bbox;
/*! path flags*/
s32 flags;
/*! fineness to use whenever flattening the path - default is \ref FIX_ONE*/
Fixed fineness;
} GF_Path;
/*!
* \brief path constructor
*
* Constructs an empty 2D path object
* \return new path object
*/
GF_Path *gf_path_new();
/*!
* \brief path destructor
*
* Destructs a 2D path object
* \param gp the target path
*/
void gf_path_del(GF_Path *gp);
/*!
* \brief path reset
*
* Resets the 2D path object
* \param gp the target path
*/
void gf_path_reset(GF_Path *gp);
/*!
* \brief path copy constuctor
*
* Resets a copy of a 2D path object
* \param gp the target path
* \return new path copy
*/
GF_Path *gf_path_clone(GF_Path *gp);
/*!
* \brief path close
*
* Closes current path contour
* \param gp the target path
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_close(GF_Path *gp);
/*!
* \brief path moveTo
*
* Starts a new contour from the specified point
* \param gp the target path
* \param x x-coordinate of the new point
* \param y y-coordinate of the new point
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_add_move_to(GF_Path *gp, Fixed x, Fixed y);
/*!
* \brief starts new contour
*
* Starts a new contour from the specified point
* \param gp the target path
* \param pt pointer to the new start point
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_add_move_to_vec(GF_Path *gp, GF_Point2D *pt);
/*!
* \brief adds line to path
*
* Adds a line from the current point in path to the specified point
* \param gp the target path
* \param x x-coordinate of the line end
* \param y y-coordinate of the line end
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_add_line_to(GF_Path *gp, Fixed x, Fixed y);
/*!
* \brief adds line to path
*
* Adds a line from the current point in path to the specified point
* \param gp the target path
* \param pt line end
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_add_line_to_vec(GF_Path *gp, GF_Point2D *pt);
/*!
* \brief adds cubic to path
*
* Adds a cubic bezier curve to the current contour, starting from the current path point
* \param gp the target path
* \param c1_x x-coordinate of the first control point of the cubic curve
* \param c1_y y-coordinate of the first control point of the cubic curve
* \param c2_x x-coordinate of the second control point of the cubic curve
* \param c2_y y-coordinate of the second control point of the cubic curve
* \param x x-coordinate of the end point of the cubic curve
* \param y y-coordinate of the end point of the cubic curve
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_add_cubic_to(GF_Path *gp, Fixed c1_x, Fixed c1_y, Fixed c2_x, Fixed c2_y, Fixed x, Fixed y);
/*!
* \brief adds cubic to path
*
* Adds a cubic bezier curve to the current contour, starting from the current path point
* \param gp the target path
* \param c1 first control point of the cubic curve
* \param c2 second control point of the cubic curve
* \param pt end point of the cubic curve
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_add_cubic_to_vec(GF_Path *gp, GF_Point2D *c1, GF_Point2D *c2, GF_Point2D *pt);
/*!
* \brief adds quadratic to path
*
* Adds a quadratic bezier curve to the current contour, starting from the current path point
* \param gp the target path
* \param c_x x-coordinate of the control point of the quadratic curve
* \param c_y y-coordinate of the control point of the quadratic curve
* \param x x-coordinate of the end point of the cubic quadratic
* \param y y-coordinate of the end point of the cubic quadratic
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_add_quadratic_to(GF_Path *gp, Fixed c_x, Fixed c_y, Fixed x, Fixed y);
/*!
* \brief adds quadratic to path
*
* Adds a quadratic bezier curve to the current contour, starting from the current path point
* \param gp the target path
* \param c control point of the quadratic curve
* \param pt end point of the cubic quadratic
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_add_quadratic_to_vec(GF_Path *gp, GF_Point2D *c, GF_Point2D *pt);
/*!
* \brief adds rectangle to path
*
* Adds a rectangle contour to the path
* \param gp the target path
* \param cx x-coordinate of the rectangle center
* \param cy y-coordinate of the rectangle center
* \param w width of the rectangle
* \param h height of the rectangle
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_add_rect_center(GF_Path *gp, Fixed cx, Fixed cy, Fixed w, Fixed h);
/*!
* \brief adds rectangle to path
*
* Adds a rectangle contour to the path
* \param gp the target path
* \param ox left-most coordinate of the rectangle
* \param oy top-most coordinate of the rectangle
* \param w width of the rectangle
* \param h height of the rectangle
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_add_rect(GF_Path *gp, Fixed ox, Fixed oy, Fixed w, Fixed h);
/*!
* \brief adds ellipse to path
*
* Adds an ellipse contour to the path
* \param gp the target path
* \param cx x-coordinate of the ellipse center
* \param cy y-coordinate of the ellipse center
* \param a_axis length of the horizontal ellipse axis
* \param b_axis length of the vertical ellipse axis
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_add_ellipse(GF_Path *gp, Fixed cx, Fixed cy, Fixed a_axis, Fixed b_axis);
/*!
* \brief adds N-bezier curve to path
*
* Adds an N-degree bezier curve to the path, starting from the current point
* \param gp the target path
* \param pts points used to define the curve
* \param nb_pts number of points used to define the curve. The degree of the curve is therefore (nb_pts-1).
* \return error code if any error, \ref GF_OK otherwise
* \note the fineness of the path must be set before calling this function.
*/
GF_Err gf_path_add_bezier(GF_Path *gp, GF_Point2D *pts, u32 nb_pts);
/*!
* \brief adds arc as described in MPEG-4 BIFS to path
*
* Adds an arc contour to the path from focal and end points.
* \param gp the target path
* \param end_x x-coordinate of the arc end point
* \param end_y y-coordinate of the arc end point
* \param fa_x x-coordinate of the arc first focal point
* \param fa_y y-coordinate of the arc first focal point
* \param fb_x x-coordinate of the arc second focal point
* \param fb_y y-coordinate of the arc second focal point
* \param cw if 1, the arc will be clockwise, otherwise counter-clockwise.
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_add_arc_to(GF_Path *gp, Fixed end_x, Fixed end_y, Fixed fa_x, Fixed fa_y, Fixed fb_x, Fixed fb_y, Bool cw);
/*!
* \brief adds arc as described in SVG to path
*
* Adds an arc contour to the path from end point, radii and 3 parameters.
* \param gp the target path
* \param end_x x-coordinate of the arc end point
* \param end_y y-coordinate of the arc end point
* \param r_x x-axis radius
* \param r_y y-axis radius
* \param x_axis_rotation angle for the x-axis
* \param large_arc_flag large or short arc selection
* \param sweep_flag if 1, the arc will be clockwise, otherwise counter-clockwise.
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_add_svg_arc_to(GF_Path *gp, Fixed end_x, Fixed end_y, Fixed r_x, Fixed r_y, Fixed x_axis_rotation, Bool large_arc_flag, Bool sweep_flag);
/*!
* \brief adds arc to path
*
* Adds an arc contour to the path.
* \param gp the target path
* \param radius radius of the arc
* \param start_angle start angle of the arc in radians
* \param end_angle end angle of the arc in radians
* \param close_type closing type: 0 for open arc, 1 for close arc, 2 for pie
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_add_arc(GF_Path *gp, Fixed radius, Fixed start_angle, Fixed end_angle, u32 close_type);
/*!
* \brief concatenates path
*
* Adds a sub-path to the path with a given transform.
* \param gp the target path
* \param subpath the path to add
* \param mx Matrix for subpath
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_add_subpath(GF_Path *gp, GF_Path *subpath, GF_Matrix2D *mx);
/*!
* \brief gets path control bounds
*
* Gets the path control bounds, i.e. the rectangle covering all lineTo and bezier control points.
* \param gp the target path
* \param rc pointer to rectangle receiving the control rectangle
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_get_control_bounds(GF_Path *gp, GF_Rect *rc);
/*!
* \brief gets path bounds
*
* Gets the path bounds, i.e. the rectangle covering all points in path except bezier control points.
* \param gp the target path
* \param rc pointer to rectangle receiving the control rectangle
* \return error code if any error, \ref GF_OK otherwise
*/
GF_Err gf_path_get_bounds(GF_Path *gp, GF_Rect *rc);
/*!
* \brief flattens path
*
* Flattens the path, i.e. transform all bezier curves to lines according to the path flatness.
* \param gp the target path
*/
void gf_path_flatten(GF_Path *gp);
/*!
* \brief gets flatten copy of path
*
* Gets a flatten copy of the path.
* \param gp the target path
* \return the flatten path
*/
GF_Path *gf_path_get_flatten(GF_Path *gp);
/*!
* \brief point over path testing
*
* Tests if a point is over a path or not, according to the path filling rule.
* \param gp the target path
* \param x x-coordinate of the point to check
* \param y y-coordinate of the point to check
* \return 1 if the point is over the path, 0 otherwise.
*/
Bool gf_path_point_over(GF_Path *gp, Fixed x, Fixed y);
/*!
* \brief path init testing
*
* Tests if the path is empty or not.
* \param gp the target path
* \return 1 if the path is empty, 0 otherwise.
*/
Bool gf_path_is_empty(GF_Path *gp);
/*!
* \brief path iterator
*
* The path iterator object is used to compute the length of a given path as well
* as transformation matrices along this path.
*/
typedef struct _path_iterator GF_PathIterator;
/*!
* \brief path iterator constructor
*
* Creates a new path iterator from a given path
* \param gp the target path
* \return the path iterator object.
*/
GF_PathIterator *gf_path_iterator_new(GF_Path *gp);
/*!
* \brief path iterator destructor
*
* Destructs the path iterator object
* \param it the target path iterator
*/
void gf_path_iterator_del(GF_PathIterator *it);
/*!
* \brief get path length
*
* Gets a path length from its iterator
* \param it the target path iterator
* \return the length of the path
*/
Fixed gf_path_iterator_get_length(GF_PathIterator *it);
/*!
*\brief gets transformation matrix at given point on path
*
* Gets the transformation of a given point on the path, given by offset from origin.
*The transform is so that a local system is translated to the given point, its x-axis tangent
*to the path and in the same direction. The path direction is from first point to last point
*of the path.
* \param it the target path iterator
* \param offset length on the path in local system unit
* \param follow_tangent indicates if transformation shall be computed if offset indicates a point outside the path (<0 or >path_length). In which case the path shall be virtually extended by the tangent at origin (offset <0) or at end (offset>path_length). Otherwise the transformation is not computed and 0 is returned.
* \param mat matrix to be transformed (transformation shall be appended) - the matrix shall not be initialized
* \param smooth_edges indicates if discontinuities shall be smoothed. If not set, the rotation angle THETA is the slope (DX/DY) of the current segment found.
* \param length_after_point if set and smooth_edges is set, the amount of the object that lies on next segment shall be computed according to length_after_point.
\code
Let:
len_last: length of current checked segment
len1: length of all previous segments so that len1 + len_last >= offset then if (offset + length_after_point > len1 + len_last) {
ratio = (len1 + len_last - offset) / length_after_point;
then THETA = ratio * slope(L1) + (1-ratio) * slope(L2)
Of course care must be taken for PI/2 angles and similar situations
\endcode
* \return 1 if matrix has been updated, 0 otherwise, if failure or if point is out of path without tangent extension.
*/
Bool gf_path_iterator_get_transform(GF_PathIterator *it, Fixed offset, Bool follow_tangent, GF_Matrix2D *mat, Bool smooth_edges, Fixed length_after_point);
/*! brief gets convexity type for a 2D polygon
*
* Gets the convexity type of the given 2D polygon
* \param pts the points of the polygon
* \param nb_pts number of points in the polygon
* \return the convexity type of the polygon
*/
u32 gf_polygone2d_get_convexity(GF_Point2D *pts, u32 nb_pts);
/* 2D Path constants */
/*!
*2D Path point tags
* \hideinitializer
*/
enum
{
/*/! Point is on curve (moveTo, lineTo, end of splines)*/
GF_PATH_CURVE_ON = 1,
/*! Point is a contour close*/
GF_PATH_CLOSE = 5,
/*! Point is a quadratic control point*/
GF_PATH_CURVE_CONIC = 0,
/*! Point is a cubic control point*/
GF_PATH_CURVE_CUBIC = 2,
};
/*!
*2D Path flags
* \hideinitializer
*/
enum
{
/*! Path is filled using the zero-nonzero rule. If not set, filling uses odd/even rule*/
GF_PATH_FILL_ZERO_NONZERO = 1,
/*! When set bbox must be recomputed.
\note Read only, used to avoid wasting time on bounds calculation*/
GF_PATH_BBOX_DIRTY = 2,
/*! Indicates the path is flattened flattened
\note Read only, used to avoid wasting time on flattening*/
GF_PATH_FLATTENED = 4,
};
/*!
* 2D Polygon convexity type
* \hideinitializer
*/
enum
{
/*! Polygon is either complex or unknown*/
GF_POLYGON_COMPLEX,
/*! Polygon is complex, starting in counter-clockwise order*/
GF_POLYGON_COMPLEX_CCW,
/*! Polygon is complex, starting in clockwise order*/
GF_POLYGON_COMPLEX_CW,
/*! Polygon is a counter-clockwise convex polygon*/
GF_POLYGON_CONVEX_CCW,
/*! Polygon is a clockwise convex polygon*/
GF_POLYGON_CONVEX_CW,
/*! Polygon is a convex line (degenerated path with all segments aligned)*/
GF_POLYGON_CONVEX_LINE
};
/*!
* Stencil alignment type for outlining
* \hideinitializer
*/
enum
{
/*! outline is centered on the path (default)*/
GF_PATH_LINE_CENTER = 0,
/*! outline is inside the path*/
GF_PATH_LINE_INSIDE,
/*! outline is outside the path*/
GF_PATH_LINE_OUTSIDE,
};
/*!
* Line cap type for outlining
* \hideinitializer
*/
enum
{
/*! End of line is flat (default)*/
GF_LINE_CAP_FLAT = 0,
/*! End of line is round*/
GF_LINE_CAP_ROUND,
/*! End of line is square*/
GF_LINE_CAP_SQUARE,
/*! End of line is triangle*/
GF_LINE_CAP_TRIANGLE,
};
/*!
* Line join type for outlining
* \hideinitializer
*/
enum
{
/*! Line join is a miter join (default)*/
GF_LINE_JOIN_MITER = 0,
/*! Line join is a round join*/
GF_LINE_JOIN_ROUND,
/*! Line join is a bevel join*/
GF_LINE_JOIN_BEVEL,
/*! Line join is a miter then bevel join*/
GF_LINE_JOIN_MITER_SVG
};
/*!
* Dash types for outlining
* \hideinitializer
*/
enum
{
/*! No dashing is used (default)*/
GF_DASH_STYLE_PLAIN = 0,
/*! Predefined dash pattern is used*/
GF_DASH_STYLE_DASH,
/*! Predefined dot pattern is used*/
GF_DASH_STYLE_DOT,
/*! Predefined dash-dot pattern is used*/
GF_DASH_STYLE_DASH_DOT,
/*! Predefined dash-dash-dot pattern is used*/
GF_DASH_STYLE_DASH_DASH_DOT,
/*! Predefined dash-dot-dot pattern is used*/
GF_DASH_STYLE_DASH_DOT_DOT,
/*! Custom pattern is used. Dash lengths are given in percentage of the pen width*/
GF_DASH_STYLE_CUSTOM,
/*! SVG pattern is used. Dash lengths are given in the same unit as the pen width
and dash offset follows SVG specs (offset in dash pattern)*/
GF_DASH_STYLE_SVG,
};
/*!\brief Custom dash pattern
*
*The custom dash pattern object is used to specify custom dashes when outlining a path.
*/
typedef struct
{
/*beginning of the structure is casted in MFFloat in BIFS, DO NOT CHANGE ORDER*/
/*! Number of dashes in the pattern*/
u32 num_dash;
/*! Value of the pattern dashes. Unit depends on the dash type*/
Fixed *dashes;
/*! SVG/CSS unit for the dashes */
u8 *dash_units;
} GF_DashSettings;
/*!\brief Pen properties
*
*The pen properties object is used to specify several parameters used when building
*the vectorial outline of a path.
*/
typedef struct
{
/*! The width of the outline*/
Fixed width;
/*! The style of the lines ends*/
u8 cap;
/*! The style of the lines joins*/
u8 join;
/*! The alignment of the outline with regard to the path*/
u8 align;
/*! The dash style of the line*/
u8 dash;
/*! The miter limit of the line joins*/
Fixed miterLimit;
/*! The initial dash offset in the outline. All points before this offset will be
* ignored when building the outline*/
Fixed dash_offset;
/*! The dash pattern used for curstom dashing*/
GF_DashSettings *dash_set;
/*! The author-specified path length. Ignored if <= 0*/
Fixed path_length;
} GF_PenSettings;
/*! brief builds the vectorial outline of a path
*
* Builds the vectorial outline of a path for the given settings. The outline of a path is a path.
* \param path the desired path to outline
* \param pen the properties of the virtual pen used for outlining
* \return the outline of the path
*/
GF_Path *gf_path_get_outline(GF_Path *path, GF_PenSettings pen);
/*! @} */
#ifdef __cplusplus
}
#endif
#endif /*_GF_PATH2D_H_*/