// Generated by gmmproc 2.86.0 -- DO NOT MODIFY!
#ifndef _GSKMM_PATH_H
#define _GSKMM_PATH_H

#include <gskmmconfig.h>


#include <glibmm/ustring.h>
#include <sigc++/sigc++.h>

/* Copyright (C) 2026 The gtkmm Development Team
 *
 * This library 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.1 of the License, or (at your option) any later version.
 *
 * This library 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. If not, see <http://www.gnu.org/licenses/>.
 */


#include <glibmm/refptr.h>
#include <gdkmm/graphene_rect.h>
#include <gskmm/pathpoint.h>
#include <cairomm/context.h>
#include <gsk/gsk.h> // GskPath
#include <optional>
#include <utility> // std::pair
#include <vector>

namespace Gsk
{
class GSKMM_API Stroke;

/** Describes lines and curves that are more complex than simple rectangles.
 *
 * Paths can be used for rendering (filling or stroking) and for animations
 * (e.g. as trajectories).
 *
 * %Gsk::Path is an immutable, opaque, reference-counted struct.
 * After creation, you cannot change the types it represents. Instead,
 * new %Gsk::Path objects have to be created. The Gsk::PathBuilder
 * structure is meant to help in this endeavor.
 *
 * Conceptually, a path consists of zero or more contours (continuous, connected
 * curves), each of which may or may not be closed. Contours are typically
 * constructed from Bézier segments.
 *
 * <picture>
 *   <source srcset="path-dark.png" media="(prefers-color-scheme: dark)">
 *   <img alt="A Path" src="path-light.png">
 * </picture>
 *
 * @newin{4,24}
 */
class GSKMM_API Path final
{
  // GskPath is registered as a boxed type, but it has custom
  // reference-counting instead of copy/free functions, so we use it via RefPtr.
  public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  using CppObjectType = Path;
  using BaseObjectType = GskPath;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


  /** Increment the reference count for this object.
   * You should never need to do this manually - use the object via a RefPtr instead.
   */
  void reference()   const;

  /** Decrement the reference count for this object.
   * You should never need to do this manually - use the object via a RefPtr instead.
   */
  void unreference() const;

  ///Provides access to the underlying C instance.
  GskPath*       gobj();

  ///Provides access to the underlying C instance.
  const GskPath* gobj() const;

  ///Provides access to the underlying C instance. The caller is responsible for unrefing it. Use when directly setting fields in structs.
  GskPath* gobj_copy() const;

  Path() = delete;

  // noncopyable
  Path(const Path&) = delete;
  Path& operator=(const Path&) = delete;

protected:
  // Do not derive this.  Gsk::Path can neither be constructed nor deleted.

  void operator delete(void*, std::size_t);

private:

  // Necessary if used in _WRAP_PROPERTY: _IS_REFCOUNTED_BOXEDTYPE dnl// Generate a Glib::Value specialization
  

public:
  /** @addtogroup gskmmEnums gskmm Enums and Flags */

  /** 
   *  @var ForeachFlags::ONLY_LINES
   * The default behavior, only allow lines.
   * 
   *  @var ForeachFlags::QUAD
   * Allow emission of `Gdk::Path::Operation::QUAD` operations.
   * 
   *  @var ForeachFlags::CUBIC
   * Allow emission of `Gdk::Path::Operation::CUBIC` operations.
   * 
   *  @var ForeachFlags::CONIC
   * Allow emission of `Gdk::Path::Operation::CONIC` operations.
   */
   /** Flags that can be passed to Gsk::Path::foreach() to influence what
   * kinds of operations the path is decomposed into.
   * 
   * By default, Gsk::Path::foreach() will only emit a path with all
   * operations flattened to straight lines to allow for maximum compatibility.
   * The only operations emitted will be `Gdk::Path::Operation::MOVE`, `Gdk::Path::Operation::LINE` and
   * `Gdk::Path::Operation::CLOSE`.
   * 
   * @newin{4,24}
   *
   * @ingroup gskmmEnums
   * @par Bitwise operators:
   * <tt>Path::ForeachFlags operator|(Path::ForeachFlags, Path::ForeachFlags)</tt><br>
   * <tt>Path::ForeachFlags operator&(Path::ForeachFlags, Path::ForeachFlags)</tt><br>
   * <tt>Path::ForeachFlags operator^(Path::ForeachFlags, Path::ForeachFlags)</tt><br>
   * <tt>Path::ForeachFlags operator~(Path::ForeachFlags)</tt><br>
   * <tt>Path::ForeachFlags& operator|=(Path::ForeachFlags&, Path::ForeachFlags)</tt><br>
   * <tt>Path::ForeachFlags& operator&=(Path::ForeachFlags&, Path::ForeachFlags)</tt><br>
   * <tt>Path::ForeachFlags& operator^=(Path::ForeachFlags&, Path::ForeachFlags)</tt><br>
   */
  enum class ForeachFlags
  {
    ONLY_LINES = 0x0,
    QUAD = 1 << 0,
    CUBIC = 1 << 1,
    CONIC = 1 << 2
  };


  /** 
   *  @var Intersection::NONE
   * No intersection.
   * 
   *  @var Intersection::NORMAL
   * A normal intersection, where the two paths
   * cross each other.
   * 
   *  @var Intersection::START
   * The start of a segment where the two paths coincide.
   * 
   *  @var Intersection::END
   * The end of a segment where the two paths coincide.
   */
   /** The values of this enumeration classify intersections
   * between paths.
   * 
   * @newin{4,24}
   *
   * @ingroup gskmmEnums
   */
  enum class Intersection
  {
    NONE,
    NORMAL,
    START,
    END
  };


  /** 
   *  @var Operation::MOVE
   * A move-to operation, with 1 point describing the target point.
   * 
   *  @var Operation::CLOSE
   * A close operation ending the current contour with a line back
   * to the starting point. Two points describe the start and end of the line.
   * 
   *  @var Operation::LINE
   * A line-to operation, with 2 points describing the start and
   * end point of a straight line.
   * 
   *  @var Operation::QUAD
   * A curve-to operation describing a quadratic Bézier curve
   * with 3 points describing the start point, the control point and the end
   * point of the curve.
   * 
   *  @var Operation::CUBIC
   * A curve-to operation describing a cubic Bézier curve with 4
   * points describing the start point, the two control points and the end point
   * of the curve.
   * 
   *  @var Operation::CONIC
   * A rational quadratic Bézier curve with 3 points describing
   * the start point, control point and end point of the curve. A weight for the
   * curve will be passed, too.
   */
   /** Describes the segments of a `Gsk::Path`.
   * 
   * More values may be added in the future.
   * 
   * @newin{4,24}
   *
   * @ingroup gskmmEnums
   */
  enum class Operation
  {
    MOVE,
    CLOSE,
    LINE,
    QUAD,
    CUBIC,
    CONIC
  };


  /** Type of the callback to iterate through the operations of a path.
   *
   * For each operation, the callback is given the @a op itself, the points
   * that the operation is applied to in @a pts, and a @a weight for conic curves.
   *
   * Each contour of the path starts with a Gsk::Path::Operation::MOVE operation.
   * Closed contours end with a Gsk::Path::Operation::CLOSE operation.
   *
   * @newin{4,24}
   *
   * @param op The operation.
   * @param pts The points of the operation.
   * @param weight The weight for conic curves, or unused if not a conic curve.
   * @return <tt>true</tt> to continue iterating the path, <tt>false</tt> to
   *   immediately abort and not call the function again.
   */
  using SlotForeach = sigc::slot<bool(Operation, const std::vector<Gdk::Graphene::Point>&, float)>;

  /** Type of the callback to iterate through the intersections of two paths.
   *
   * @newin{4,24}
   *
   * @param path1 The first path.
   * @param point1 The intersection as point on @a path1.
   * @param path2 The second path.
   * @param point2 The intersection as point on @a path2.
   * @param kind The nature of the intersection.
   * @return <tt>true</tt> to continue iterating, <tt>false</tt> to
   *   stop the iteration and not call the function again
   */
  using SlotIntersection = sigc::slot<bool(const Glib::RefPtr<Path>&,
    const PathPoint&, const Glib::RefPtr<Path>&, const PathPoint&, Intersection kind)>;

  
  /** Converts the path into a human-readable string.
   * 
   * You can use this function in a debugger to get a quick overview
   * of the path.
   * 
   * This is a wrapper around print(), see that function
   * for details.
   * 
   * @newin{4,24}
   * 
   * @return A new string for @a self.
   */
  Glib::ustring to_string() const;
  
  
  /** Constructs a path from a serialized form.
   * 
   * The string is expected to be in (a superset of)
   * [SVG path syntax](https://www.w3.org/TR/SVG11/paths.htmlPath::Data),
   * as e.g. produced by to_string().
   * 
   * A high-level summary of the syntax:
   * 
   * - `M x y` Move to `(x, y)`
   * - `L x y` Add a line from the current point to `(x, y)`
   * - `Q x1 y1 x2 y2` Add a quadratic Bézier from the current point to `(x2, y2)`, with control point `(x1, y1)`
   * - `C x1 y1 x2 y2 x3 y3` Add a cubic Bézier from the current point to `(x3, y3)`, with control points `(x1, y1)` and `(x2, y2)`
   * - `Z` Close the contour by drawing a line back to the start point
   * - `H x` Add a horizontal line from the current point to the given x value
   * - `V y` Add a vertical line from the current point to the given y value
   * - `T x2 y2` Add a quadratic Bézier, using the reflection of the previous segments' control point as control point
   * - `S x2 y2 x3 y3` Add a cubic Bézier, using the reflection of the previous segments' second control point as first control point
   * - `A rx ry r l s x y` Add an elliptical arc from the current point to `(x, y)` with radii rx and ry. See the SVG documentation for how the other parameters influence the arc.
   * - `O x1 y1 x2 y2 w` Add a rational quadratic Bézier from the current point to `(x2, y2)` with control point `(x1, y1)` and weight `w`.
   * 
   * All the commands have lowercase variants that interpret coordinates
   * relative to the current point.
   * 
   * The `O` command is an extension that is not supported in SVG.
   * 
   * @newin{4,24}
   * 
   * @param string A string.
   * @return A new `Gsk::Path`, or <tt>nullptr</tt> if @a string could not be parsed.
   */
  static Glib::RefPtr<Path> parse(const Glib::ustring& string);
  
  /** Appends the path to a cairo context for drawing with Cairo.
   * 
   * This may cause some suboptimal conversions to be performed as
   * Cairo does not support all features of `Gsk::Path`.
   * 
   * This function does not clear the existing Cairo path. Call
   * cairo_new_path() if you want this.
   * 
   * @newin{4,24}
   * 
   * @param cr A cairo context.
   */
  void to_cairo(const ::Cairo::RefPtr< ::Cairo::Context>& cr) const;
  
  /** Checks if the path is empty, i.e.\ contains no lines or curves.
   * 
   * @newin{4,24}
   * 
   * @return True if the path is empty.
   */
  bool is_empty() const;
  
  /** Returns if the path represents a single closed contour.
   * 
   * @newin{4,24}
   * 
   * @return True if the path is closed.
   */
  bool is_closed() const;

  /** Computes the bounds of the given path.
   *
   * The returned bounds may be larger than necessary, because this
   * function aims to be fast, not accurate. The bounds are guaranteed
   * to contain the path. For accurate bounds, use get_tight_bounds().
   *
   * It is possible that the returned rectangle has 0 width and/or height.
   * This can happen when the path only describes a point or an
   * axis-aligned line.
   *
   * If the path is empty, no value is returned. This is different from the case
   * where the path is a single point at the origin, where a zero rectangle
   * is returned.
   *
   * @newin{4,24}
   *
   * @return The bounds of this path, if any.
   */
  std::optional<Gdk::Graphene::Rect> get_bounds() const;
  

  /** Computes the tight bounds of the given path.
   *
   * This function works harder than get_bounds() to
   * produce the smallest possible bounds.
   *
   * @newin{4,24}
   *
   * @return The bounds of this path, if any. See get_bounds().
   */
  std::optional<Gdk::Graphene::Rect> get_tight_bounds() const;
  

  /** Computes the bounds for stroking the given path with the
   * given parameters.
   *
   * The returned bounds may be larger than necessary, because this
   * function aims to be fast, not accurate. The bounds are guaranteed
   * to contain the area affected by the stroke, including protrusions
   * like miters.
   *
   * @newin{4,24}
   *
   * @param stroke Stroke parameters.
   * @return The bounds of this path, if any. See get_bounds().
   */
  std::optional<Gdk::Graphene::Rect> get_stroke_bounds(const Stroke& stroke) const;
  

  /** Returns whether a point is inside the fill area of a path.
   * 
   * Note that this function assumes that filling a contour
   * implicitly closes it.
   * 
   * @newin{4,24}
   * 
   * @param point The point to test.
   * @param fill_rule The fill rule to follow.
   * @return True if @a point is inside.
   */
  bool in_fill(const Gdk::Graphene::Point& point, FillRule fill_rule) const;

  /** Gets the start point of the path.
   *
   * An empty path has no points, so no value is returned in this case.
   *
   * @newin{4,24}
   *
   * @return The start point, if any.
   */
  std::optional<PathPoint> get_start_point() const;
  

  /** Gets the end point of the path.
   *
   * An empty path has no points, so no value is returned in this case.
   *
   * @newin{4,24}
   *
   * @return The end point, if any.
   */
  std::optional<PathPoint> get_end_point() const;
  

  /** Moves @a point to the next vertex.
   * 
   * An empty path has no points, so false
   * is returned in this case.
   * 
   * @newin{4,24}
   * 
   * @param point The current point.
   * @return True if @a point was set.
   */
  bool get_next(PathPoint& point) const;
  
  /** Moves @a point to the previous vertex.
   * 
   * An empty path has no points, so false
   * is returned in this case.
   * 
   * @newin{4,24}
   * 
   * @param point The current point.
   * @return True if @a point was set.
   */
  bool get_previous(PathPoint& point) const;

  /** Computes the closest point on the path to the given point.
   *
   * If there is no point closer than the given @a threshold, no value is returned.
   *
   * @newin{4,24}
   *
   * @param point The point.
   * @param threshold Maximum allowed distance.
   * @return {closest_point, distance}, if there is a point within @a threshold.
   */
  std::optional<std::pair<PathPoint,float>> get_closest_point(const Gdk::Graphene::Point& point,
    float threshold) const;
  

  /** Calls @a slot for every operation of the path.
   * 
   * Note that this may only approximate @a self, because paths can contain
   * optimizations for various specialized contours, and depending on the
   *  @a flags, the path may be decomposed into simpler curves than the ones
   * that it contained originally.
   * 
   * This function serves two purposes:
   * 
   * - When the @a flags allow everything, it provides access to the raw,
   * unmodified data of the path.
   * - When the @a flags disallow certain operations, it provides
   * an approximation of the path using just the allowed operations.
   * 
   * @newin{4,24}
   * 
   * @param flags Flags to pass to the foreach function.
   * @param slot The function to call for operations.
   * @return False if @a slot returned false, true otherwise.
   */
  bool foreach(ForeachFlags flags, const SlotForeach& slot);

  
  /** Returns whether two paths have identical structure.
   * 
   * Note that it is possible to construct paths that render
   * identical even though they don't have the same structure.
   * 
   * @newin{4,24}
   * 
   * @param path2 Another path.
   * @return True if @a path1 and @a path2 have identical structure.
   */
  bool equal(const Glib::RefPtr<const Path>& path2) const;

  
  /** Finds intersections between two paths.
   * 
   * This function finds intersections between @a path1 and @a path2,
   * and calls @a slot for each of them, in increasing order for @a path1.
   * 
   * If @a path2 is not provided or equal to @a path1, the function finds
   * non-trivial self-intersections of @a path1.
   * 
   * When segments of the paths coincide, the callback is called once
   * for the start of the segment, with @a GSK_PATH_INTERSECTION_START, and
   * once for the end of the segment, with @a GSK_PATH_INTERSECTION_END.
   * Note that other intersections may occur between the start and end
   * of such a segment.
   * 
   * If @a slot returns <tt>false</tt>, the iteration is stopped.
   * 
   * @newin{4,24}
   * 
   * @param path2 The second path.
   * @param slot The function to call for intersections.
   * @return <tt>false</tt> if @a slot returned <tt>false</tt>, <tt>true</tt> otherwise.
   */
  bool foreach_intersection(const Glib::RefPtr<const Path>& path2, const SlotIntersection& slot);


};

} // namespace Gsk

namespace Gsk
{

/** @ingroup gskmmEnums */
inline constexpr Path::ForeachFlags operator|(Path::ForeachFlags lhs, Path::ForeachFlags rhs)
  { return static_cast<Path::ForeachFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); }

/** @ingroup gskmmEnums */
inline constexpr Path::ForeachFlags operator&(Path::ForeachFlags lhs, Path::ForeachFlags rhs)
  { return static_cast<Path::ForeachFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); }

/** @ingroup gskmmEnums */
inline constexpr Path::ForeachFlags operator^(Path::ForeachFlags lhs, Path::ForeachFlags rhs)
  { return static_cast<Path::ForeachFlags>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs)); }

/** @ingroup gskmmEnums */
inline constexpr Path::ForeachFlags operator~(Path::ForeachFlags flags)
  { return static_cast<Path::ForeachFlags>(~static_cast<unsigned>(flags)); }

/** @ingroup gskmmEnums */
inline Path::ForeachFlags& operator|=(Path::ForeachFlags& lhs, Path::ForeachFlags rhs)
  { return (lhs = static_cast<Path::ForeachFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs))); }

/** @ingroup gskmmEnums */
inline Path::ForeachFlags& operator&=(Path::ForeachFlags& lhs, Path::ForeachFlags rhs)
  { return (lhs = static_cast<Path::ForeachFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs))); }

/** @ingroup gskmmEnums */
inline Path::ForeachFlags& operator^=(Path::ForeachFlags& lhs, Path::ForeachFlags rhs)
  { return (lhs = static_cast<Path::ForeachFlags>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs))); }
} // namespace Gsk

#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class GSKMM_API Value<Gsk::Path::ForeachFlags> : public Glib::Value_Flags<Gsk::Path::ForeachFlags>
{
public:
  static GType value_type();
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class GSKMM_API Value<Gsk::Path::Intersection> : public Glib::Value_Enum<Gsk::Path::Intersection>
{
public:
  static GType value_type();
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class GSKMM_API Value<Gsk::Path::Operation> : public Glib::Value_Enum<Gsk::Path::Operation>
{
public:
  static GType value_type();
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Glib
{

/** A Glib::wrap() method for this object.
 *
 * @param object The C instance.
 * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref.
 * @result A C++ instance that wraps this C instance.
 *
 * @relates Gsk::Path
 */
GSKMM_API
Glib::RefPtr<Gsk::Path> wrap(GskPath* object, bool take_copy = false);

} // namespace Glib


#endif /* _GSKMM_PATH_H */

