/* PIKA - Photo and Image Kooker Application * a rebranding of The GNU Image Manipulation Program (created with heckimp) * A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio * * Original copyright, applying to most contents (license remains unchanged): * Copyright (C) 1995 Spencer Kimball and Peter Mattis * * pikastroke.h * Copyright (C) 2002 Simon Budig * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef __PIKA_STROKE_H__ #define __PIKA_STROKE_H__ #include "core/pikaobject.h" #define PIKA_TYPE_STROKE (pika_stroke_get_type ()) #define PIKA_STROKE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PIKA_TYPE_STROKE, PikaStroke)) #define PIKA_STROKE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PIKA_TYPE_STROKE, PikaStrokeClass)) #define PIKA_IS_STROKE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PIKA_TYPE_STROKE)) #define PIKA_IS_STROKE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIKA_TYPE_STROKE)) #define PIKA_STROKE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PIKA_TYPE_STROKE, PikaStrokeClass)) typedef struct _PikaStrokeClass PikaStrokeClass; struct _PikaStroke { PikaObject parent_instance; gint id; GQueue *anchors; gboolean closed; }; struct _PikaStrokeClass { PikaObjectClass parent_class; void (* changed) (PikaStroke *stroke); void (* removed) (PikaStroke *stroke); PikaAnchor * (* anchor_get) (PikaStroke *stroke, const PikaCoords *coord); gdouble (* nearest_point_get) (PikaStroke *stroke, const PikaCoords *coord, gdouble precision, PikaCoords *ret_point, PikaAnchor **ret_segment_start, PikaAnchor **ret_segment_end, gdouble *ret_pos); gdouble (* nearest_tangent_get) (PikaStroke *stroke, const PikaCoords *coord1, const PikaCoords *coord2, gdouble precision, PikaCoords *nearest, PikaAnchor **ret_segment_start, PikaAnchor **ret_segment_end, gdouble *ret_pos); gdouble (* nearest_intersection_get) (PikaStroke *stroke, const PikaCoords *coord1, const PikaCoords *direction, gdouble precision, PikaCoords *nearest, PikaAnchor **ret_segment_start, PikaAnchor **ret_segment_end, gdouble *ret_pos); PikaAnchor * (* anchor_get_next) (PikaStroke *stroke, const PikaAnchor *prev); void (* anchor_select) (PikaStroke *stroke, PikaAnchor *anchor, gboolean selected, gboolean exclusive); void (* anchor_move_relative) (PikaStroke *stroke, PikaAnchor *anchor, const PikaCoords *deltacoord, PikaAnchorFeatureType feature); void (* anchor_move_absolute) (PikaStroke *stroke, PikaAnchor *anchor, const PikaCoords *coord, PikaAnchorFeatureType feature); void (* anchor_convert) (PikaStroke *stroke, PikaAnchor *anchor, PikaAnchorFeatureType feature); void (* anchor_delete) (PikaStroke *stroke, PikaAnchor *anchor); gboolean (* point_is_movable) (PikaStroke *stroke, PikaAnchor *predec, gdouble position); void (* point_move_relative) (PikaStroke *stroke, PikaAnchor *predec, gdouble position, const PikaCoords *deltacoord, PikaAnchorFeatureType feature); void (* point_move_absolute) (PikaStroke *stroke, PikaAnchor *predec, gdouble position, const PikaCoords *coord, PikaAnchorFeatureType feature); void (* close) (PikaStroke *stroke); PikaStroke * (* open) (PikaStroke *stroke, PikaAnchor *end_anchor); gboolean (* anchor_is_insertable) (PikaStroke *stroke, PikaAnchor *predec, gdouble position); PikaAnchor * (* anchor_insert) (PikaStroke *stroke, PikaAnchor *predec, gdouble position); gboolean (* is_extendable) (PikaStroke *stroke, PikaAnchor *neighbor); PikaAnchor * (* extend) (PikaStroke *stroke, const PikaCoords *coords, PikaAnchor *neighbor, PikaVectorExtendMode extend_mode); gboolean (* connect_stroke) (PikaStroke *stroke, PikaAnchor *anchor, PikaStroke *extension, PikaAnchor *neighbor); gboolean (* is_empty) (PikaStroke *stroke); gboolean (* reverse) (PikaStroke *stroke); gboolean (* shift_start) (PikaStroke *stroke, PikaAnchor *new_start); gdouble (* get_length) (PikaStroke *stroke, gdouble precision); gdouble (* get_distance) (PikaStroke *stroke, const PikaCoords *coord); gboolean (* get_point_at_dist) (PikaStroke *stroke, gdouble dist, gdouble precision, PikaCoords *position, gdouble *slope); GArray * (* interpolate) (PikaStroke *stroke, gdouble precision, gboolean *ret_closed); PikaStroke * (* duplicate) (PikaStroke *stroke); PikaBezierDesc * (* make_bezier) (PikaStroke *stroke); void (* translate) (PikaStroke *stroke, gdouble offset_x, gdouble offset_y); void (* scale) (PikaStroke *stroke, gdouble scale_x, gdouble scale_y); void (* rotate) (PikaStroke *stroke, gdouble center_x, gdouble center_y, gdouble angle); void (* flip) (PikaStroke *stroke, PikaOrientationType flip_type, gdouble axis); void (* flip_free) (PikaStroke *stroke, gdouble x1, gdouble y1, gdouble x2, gdouble y2); void (* transform) (PikaStroke *stroke, const PikaMatrix3 *matrix, GQueue *ret_strokes); GList * (* get_draw_anchors) (PikaStroke *stroke); GList * (* get_draw_controls) (PikaStroke *stroke); GArray * (* get_draw_lines) (PikaStroke *stroke); GArray * (* control_points_get) (PikaStroke *stroke, gboolean *ret_closed); }; GType pika_stroke_get_type (void) G_GNUC_CONST; void pika_stroke_set_id (PikaStroke *stroke, gint id); gint pika_stroke_get_id (PikaStroke *stroke); /* accessing / modifying the anchors */ GArray * pika_stroke_control_points_get (PikaStroke *stroke, gboolean *closed); PikaAnchor * pika_stroke_anchor_get (PikaStroke *stroke, const PikaCoords *coord); gdouble pika_stroke_nearest_point_get (PikaStroke *stroke, const PikaCoords *coord, gdouble precision, PikaCoords *ret_point, PikaAnchor **ret_segment_start, PikaAnchor **ret_segment_end, gdouble *ret_pos); gdouble pika_stroke_nearest_tangent_get (PikaStroke *stroke, const PikaCoords *coords1, const PikaCoords *coords2, gdouble precision, PikaCoords *nearest, PikaAnchor **ret_segment_start, PikaAnchor **ret_segment_end, gdouble *ret_pos); gdouble pika_stroke_nearest_intersection_get (PikaStroke *stroke, const PikaCoords *coords1, const PikaCoords *direction, gdouble precision, PikaCoords *nearest, PikaAnchor **ret_segment_start, PikaAnchor **ret_segment_end, gdouble *ret_pos); /* prev == NULL: "first" anchor */ PikaAnchor * pika_stroke_anchor_get_next (PikaStroke *stroke, const PikaAnchor *prev); void pika_stroke_anchor_select (PikaStroke *stroke, PikaAnchor *anchor, gboolean selected, gboolean exclusive); /* type will be an xorable enum: * VECTORS_NONE, VECTORS_FIX_ANGLE, VECTORS_FIX_RATIO, VECTORS_RESTRICT_ANGLE * or so. */ void pika_stroke_anchor_move_relative (PikaStroke *stroke, PikaAnchor *anchor, const PikaCoords *delta, PikaAnchorFeatureType feature); void pika_stroke_anchor_move_absolute (PikaStroke *stroke, PikaAnchor *anchor, const PikaCoords *coord, PikaAnchorFeatureType feature); gboolean pika_stroke_point_is_movable (PikaStroke *stroke, PikaAnchor *predec, gdouble position); void pika_stroke_point_move_relative (PikaStroke *stroke, PikaAnchor *predec, gdouble position, const PikaCoords *deltacoord, PikaAnchorFeatureType feature); void pika_stroke_point_move_absolute (PikaStroke *stroke, PikaAnchor *predec, gdouble position, const PikaCoords *coord, PikaAnchorFeatureType feature); void pika_stroke_close (PikaStroke *stroke); void pika_stroke_anchor_convert (PikaStroke *stroke, PikaAnchor *anchor, PikaAnchorFeatureType feature); void pika_stroke_anchor_delete (PikaStroke *stroke, PikaAnchor *anchor); PikaStroke * pika_stroke_open (PikaStroke *stroke, PikaAnchor *end_anchor); gboolean pika_stroke_anchor_is_insertable (PikaStroke *stroke, PikaAnchor *predec, gdouble position); PikaAnchor * pika_stroke_anchor_insert (PikaStroke *stroke, PikaAnchor *predec, gdouble position); gboolean pika_stroke_is_extendable (PikaStroke *stroke, PikaAnchor *neighbor); PikaAnchor * pika_stroke_extend (PikaStroke *stroke, const PikaCoords *coords, PikaAnchor *neighbor, PikaVectorExtendMode extend_mode); gboolean pika_stroke_connect_stroke (PikaStroke *stroke, PikaAnchor *anchor, PikaStroke *extension, PikaAnchor *neighbor); gboolean pika_stroke_is_empty (PikaStroke *stroke); gboolean pika_stroke_reverse (PikaStroke *stroke); gboolean pika_stroke_shift_start (PikaStroke *stroke, PikaAnchor *new_start); /* accessing the shape of the curve */ gdouble pika_stroke_get_length (PikaStroke *stroke, gdouble precision); gdouble pika_stroke_get_distance (PikaStroke *stroke, const PikaCoords *coord); gboolean pika_stroke_get_point_at_dist (PikaStroke *stroke, gdouble dist, gdouble precision, PikaCoords *position, gdouble *slope); /* returns an array of valid coordinates */ GArray * pika_stroke_interpolate (PikaStroke *stroke, const gdouble precision, gboolean *closed); PikaStroke * pika_stroke_duplicate (PikaStroke *stroke); /* creates a bezier approximation. */ PikaBezierDesc * pika_stroke_make_bezier (PikaStroke *stroke); void pika_stroke_translate (PikaStroke *stroke, gdouble offset_x, gdouble offset_y); void pika_stroke_scale (PikaStroke *stroke, gdouble scale_x, gdouble scale_y); void pika_stroke_rotate (PikaStroke *stroke, gdouble center_x, gdouble center_y, gdouble angle); void pika_stroke_flip (PikaStroke *stroke, PikaOrientationType flip_type, gdouble axis); void pika_stroke_flip_free (PikaStroke *stroke, gdouble x1, gdouble y1, gdouble x2, gdouble y2); void pika_stroke_transform (PikaStroke *stroke, const PikaMatrix3 *matrix, GQueue *ret_strokes); GList * pika_stroke_get_draw_anchors (PikaStroke *stroke); GList * pika_stroke_get_draw_controls (PikaStroke *stroke); GArray * pika_stroke_get_draw_lines (PikaStroke *stroke); #endif /* __PIKA_STROKE_H__ */