1 #define GNOME_CANVAS_PATH_DEF_C
6 * (C) 1999-2000 Lauris Kaplinski <lauris@ximian.com>
9 * Authors: Lauris Kaplinski <lauris@ximian.com>
10 * Rusty Conover <rconover@bangtail.net>
12 * Copyright 1999-2001 Ximian Inc. and authors.
16 #include <libart_lgpl/art_misc.h>
17 #include "gnome-canvas-path-def.h"
19 /* The number of points to allocate at once */
20 #define GNOME_CANVAS_PATH_DEF_LENSTEP 32
22 struct _GnomeCanvasPathDef {
25 gint end; /* ART_END position */
26 gint length; /* Num allocated Bpaths */
27 gint substart; /* subpath start */
28 gdouble x, y; /* previous moveto position */
29 guint sbpath : 1; /* Bpath is static */
30 guint hascpt : 1; /* Currentpoint is defined */
31 guint posset : 1; /* Previous was moveto */
32 guint moving : 1; /* Bpath end is moving */
33 guint allclosed : 1; /* All subpaths are closed */
34 guint allopen : 1; /* All subpaths are open */
37 static gboolean sp_bpath_good (ArtBpath * bpath);
38 static ArtBpath * sp_bpath_check_subpath (ArtBpath * bpath);
39 static gint sp_bpath_length (const ArtBpath * bpath);
40 static gboolean sp_bpath_all_closed (const ArtBpath * bpath);
41 static gboolean sp_bpath_all_open (const ArtBpath * bpath);
43 /* Boxed Type Support */
45 static GnomeCanvasPathDef *
46 path_def_boxed_copy (GnomeCanvasPathDef * path_def)
49 gnome_canvas_path_def_ref (path_def);
54 gnome_canvas_path_def_get_type (void)
58 t = g_boxed_type_register_static
59 ("GnomeCanvasPathDef",
60 (GBoxedCopyFunc)path_def_boxed_copy,
61 (GBoxedFreeFunc)gnome_canvas_path_def_unref);
68 * gnome_canvas_path_def_new:
70 * This function creates a new empty #gnome_canvas_path_def.
72 * Returns: the new canvas path definition.
75 gnome_canvas_path_def_new (void)
77 GnomeCanvasPathDef * path;
79 path = gnome_canvas_path_def_new_sized (GNOME_CANVAS_PATH_DEF_LENSTEP);
85 * gnome_canvas_path_def_new_sized:
86 * @length: number of points to allocate for the path
88 * This function creates a new #gnome_canvas_path_def with @length
89 * number of points allocated. It is useful, if you know the exact
90 * number of points in path, so you can avoid automatic point
93 * Returns: the new canvas path definition
96 gnome_canvas_path_def_new_sized (gint length)
98 GnomeCanvasPathDef * path;
100 g_return_val_if_fail (length > 0, NULL);
102 path = g_new (GnomeCanvasPathDef, 1);
105 path->bpath = art_new (ArtBpath, length);
107 path->bpath[path->end].code = ART_END;
108 path->length = length;
109 path->sbpath = FALSE;
110 path->hascpt = FALSE;
111 path->posset = FALSE;
112 path->moving = FALSE;
113 path->allclosed = TRUE;
114 path->allopen = TRUE;
120 * gnome_canvas_path_def_new_from_bpath:
121 * @bpath: libart bezier path
123 * This function constructs a new #gnome_canvas_path_def and uses the
124 * passed @bpath as the contents. The passed bpath should not be
125 * static as the path definition is editable when constructed with
126 * this function. Also, passed bpath will be freed with art_free, if
127 * path is destroyed, so use it with caution.
128 * For constructing a #gnome_canvas_path_def
129 * from (non-modifiable) bpath use
130 * #gnome_canvas_path_def_new_from_static_bpath.
132 * Returns: the new canvas path definition that is populated with the
133 * passed bezier path, if the @bpath is bad NULL is returned.
136 gnome_canvas_path_def_new_from_bpath (ArtBpath * bpath)
138 GnomeCanvasPathDef * path;
140 g_return_val_if_fail (sp_bpath_good (bpath), NULL);
142 path = g_new (GnomeCanvasPathDef, 1);
146 path->length = sp_bpath_length (bpath);
147 path->end = path->length - 1;
148 path->sbpath = FALSE;
149 path->hascpt = FALSE;
150 path->posset = FALSE;
151 path->moving = FALSE;
152 path->allclosed = sp_bpath_all_closed (bpath);
153 path->allopen = sp_bpath_all_open (bpath);
159 * gnome_canvas_path_def_new_from_static_bpath:
160 * @bpath: libart bezier path
162 * This function constructs a new #gnome_canvas_path_def and
163 * references the passed @bpath as its contents. The
164 * #gnome_canvas_path_def returned from this function is to be
165 * considered static and non-editable (meaning you cannot change the
166 * path from what you passed in @bpath). The bpath will not be freed,
167 * if path will be destroyed, so use it with caution.
169 * Returns: the new canvas path definition that references the passed
170 * @bpath, or if the path is bad NULL is returned.
173 gnome_canvas_path_def_new_from_static_bpath (ArtBpath * bpath)
175 GnomeCanvasPathDef * path;
177 g_return_val_if_fail (sp_bpath_good (bpath), NULL);
179 path = g_new (GnomeCanvasPathDef, 1);
183 path->length = sp_bpath_length (bpath);
184 path->end = path->length - 1;
186 path->hascpt = FALSE;
187 path->posset = FALSE;
188 path->moving = FALSE;
189 path->allclosed = sp_bpath_all_closed (bpath);
190 path->allopen = sp_bpath_all_open (bpath);
196 * gnome_canvas_path_def_new_from_foreign_bpath:
197 * @bpath: libart bezier path
199 * This function constructs a new #gnome_canvas_path_def and
200 * duplicates the contents of the passed @bpath in the definition.
202 * Returns: the newly created #gnome_canvas_path_def or NULL if the
206 gnome_canvas_path_def_new_from_foreign_bpath (ArtBpath * bpath)
208 GnomeCanvasPathDef * path;
211 g_return_val_if_fail (sp_bpath_good (bpath), NULL);
213 length = sp_bpath_length (bpath);
215 path = gnome_canvas_path_def_new_sized (length);
216 memcpy (path->bpath, bpath, sizeof (ArtBpath) * length);
217 path->end = length - 1;
218 path->allclosed = sp_bpath_all_closed (bpath);
219 path->allopen = sp_bpath_all_open (bpath);
225 * gnome_canvas_path_def_ref:
226 * @path: a GnomeCanvasPathDef
228 * Increment the reference count of the GnomeCanvasPathDef.
231 gnome_canvas_path_def_ref (GnomeCanvasPathDef * path)
233 g_return_if_fail (path != NULL);
239 * gnome_canvas_path_def_finish:
240 * @path: a GnomeCanvasPathDef
242 * Trims dynamic point array to exact length of path.
245 gnome_canvas_path_def_finish (GnomeCanvasPathDef * path)
247 g_return_if_fail (path != NULL);
248 g_return_if_fail (path->sbpath);
250 if ((path->end + 1) < path->length) {
251 path->bpath = art_renew (path->bpath, ArtBpath, path->end + 1);
252 path->length = path->end + 1;
255 path->hascpt = FALSE;
256 path->posset = FALSE;
257 path->moving = FALSE;
260 * gnome_canvas_path_def_ensure_space:
261 * @path: a GnomeCanvasPathDef
262 * @space: number of points to guarantee are allocated at the end of
265 * This function ensures that enough space for @space points is
266 * allocated at the end of the path.
269 gnome_canvas_path_def_ensure_space (GnomeCanvasPathDef * path, gint space)
271 g_return_if_fail (path != NULL);
272 g_return_if_fail (space > 0);
274 if (path->end + space < path->length) return;
276 if (space < GNOME_CANVAS_PATH_DEF_LENSTEP) space = GNOME_CANVAS_PATH_DEF_LENSTEP;
278 path->bpath = art_renew (path->bpath, ArtBpath, path->length + space);
280 path->length += space;
284 * gnome_canvas_path_def_copy:
285 * @dst: a GnomeCanvasPathDef where the contents of @src will be stored.
286 * @src: a GnomeCanvasPathDef whose contents will be copied it @src.
288 * This function copies the contents @src to @dest. The old @dest path
289 * array is freed and @dest is marked as non-static (editable),
290 * regardless of the status of @src.
293 gnome_canvas_path_def_copy (GnomeCanvasPathDef * dst, const GnomeCanvasPathDef * src)
295 g_return_if_fail (dst != NULL);
296 g_return_if_fail (src != NULL);
298 if (!dst->sbpath) g_free (dst->bpath);
300 memcpy (dst, src, sizeof (GnomeCanvasPathDef));
302 dst->bpath = g_new (ArtBpath, src->end + 1);
303 memcpy (dst->bpath, src->bpath, (src->end + 1) * sizeof (ArtBpath));
310 * gnome_canvas_path_def_duplicate:
311 * @path: a GnomeCanvasPathDef to duplicate
313 * This function duplicates the passed @path. The new path is
314 * marked as non-static regardless of the state of original.
316 * Returns: a GnomeCanvasPathDef which is a duplicate of @path.
319 gnome_canvas_path_def_duplicate (const GnomeCanvasPathDef * path)
321 GnomeCanvasPathDef * new;
323 g_return_val_if_fail (path != NULL, NULL);
325 new = gnome_canvas_path_def_new_from_foreign_bpath (path->bpath);
328 new->hascpt = path->hascpt;
329 new->posset = path->posset;
330 new->moving = path->moving;
331 new->allclosed = path->allclosed;
332 new->allopen = path->allopen;
338 * gnome_canvas_path_def_concat:
339 * @list: a GSList of GnomeCanvasPathDefs to concatenate into one new
342 * This function concatenates a list of GnomeCanvasPathDefs into one
343 * newly created GnomeCanvasPathDef.
345 * Returns: a new GnomeCanvasPathDef
348 gnome_canvas_path_def_concat (const GSList * list)
350 GnomeCanvasPathDef * c, * new;
355 g_return_val_if_fail (list != NULL, NULL);
359 for (l = list; l != NULL; l = l->next) {
360 c = (GnomeCanvasPathDef *) l->data;
364 new = gnome_canvas_path_def_new_sized (length);
368 for (l = list; l != NULL; l = l->next) {
369 c = (GnomeCanvasPathDef *) l->data;
370 memcpy (bp, c->bpath, c->end * sizeof (ArtBpath));
376 new->end = length - 1;
378 new->allclosed = sp_bpath_all_closed (new->bpath);
379 new->allopen = sp_bpath_all_open (new->bpath);
385 * gnome_canvas_path_def_split:
386 * @path: a GnomeCanvasPathDef
388 * This function splits the passed @path into a list of
389 * GnomeCanvasPathDefs which represent each segment of the origional
390 * path. The path is split when ever an ART_MOVETO or ART_MOVETO_OPEN
391 * is encountered. The closedness of resulting paths is set accordingly
392 * to closedness of corresponding segment.
394 * Returns: a list of GnomeCanvasPathDef(s).
397 gnome_canvas_path_def_split (const GnomeCanvasPathDef * path)
399 GnomeCanvasPathDef * new;
403 g_return_val_if_fail (path != NULL, NULL);
408 while (p < path->end) {
410 while ((path->bpath[p + i].code == ART_LINETO) || (path->bpath[p + i].code == ART_CURVETO)) i++;
411 new = gnome_canvas_path_def_new_sized (i + 1);
412 memcpy (new->bpath, path->bpath + p, i * sizeof (ArtBpath));
414 new->bpath[i].code = ART_END;
415 new->allclosed = (new->bpath->code == ART_MOVETO);
416 new->allopen = (new->bpath->code == ART_MOVETO_OPEN);
417 l = g_slist_append (l, new);
425 * gnome_canvas_path_def_open_parts:
426 * @path: a GnomeCanvasPathDef
428 * This function creates a new GnomeCanvasPathDef that contains all of
429 * the open segments on the passed @path.
431 * Returns: a new GnomeCanvasPathDef that contains all of the open segemtns in @path.
434 gnome_canvas_path_def_open_parts (const GnomeCanvasPathDef * path)
436 GnomeCanvasPathDef * new;
441 g_return_val_if_fail (path != NULL, NULL);
446 for (p = path->bpath; p->code != ART_END; p++) {
448 case ART_MOVETO_OPEN:
460 g_assert_not_reached ();
464 new = gnome_canvas_path_def_new_sized (len + 1);
469 for (p = path->bpath; p->code != ART_END; p++) {
471 case ART_MOVETO_OPEN:
480 if (!closed) *d++ = *p;
483 g_assert_not_reached ();
490 new->allclosed = FALSE;
497 * gnome_canvas_path_def_closed_parts:
498 * @path: a GnomeCanvasPathDef
500 * This function returns a new GnomeCanvasPathDef that contains the
501 * all of close parts of passed @path.
503 * Returns: a new GnomeCanvasPathDef that contains all of the closed
504 * parts of passed @path.
507 gnome_canvas_path_def_closed_parts (const GnomeCanvasPathDef * path)
509 GnomeCanvasPathDef * new;
514 g_return_val_if_fail (path != NULL, NULL);
519 for (p = path->bpath; p->code != ART_END; p++) {
521 case ART_MOVETO_OPEN:
533 g_assert_not_reached ();
537 new = gnome_canvas_path_def_new_sized (len + 1);
542 for (p = path->bpath; p->code != ART_END; p++) {
544 case ART_MOVETO_OPEN:
553 if (closed) *d++ = *p;
556 g_assert_not_reached ();
563 new->allclosed = TRUE;
564 new->allopen = FALSE;
570 * gnome_canvas_path_def_close_all:
571 * @path: a GnomeCanvasPathDef
573 * This function closes all of the open segments in the passed path
574 * and returns a new GnomeCanvasPathDef.
576 * Returns: a GnomeCanvasPathDef that contains the contents of @path
577 * but has modified the path is fully closed
580 gnome_canvas_path_def_close_all (const GnomeCanvasPathDef * path)
582 GnomeCanvasPathDef * new;
583 ArtBpath * p, * d, * start;
587 g_return_val_if_fail (path != NULL, NULL);
589 if (path->allclosed) {
590 new = gnome_canvas_path_def_duplicate (path);
596 /* Count MOVETO_OPEN */
598 for (p = path->bpath; p->code != ART_END; p++) {
600 if (p->code == ART_MOVETO_OPEN) len += 2;
603 new = gnome_canvas_path_def_new_sized (len);
605 d = start = new->bpath;
608 for (p = path->bpath; p->code != ART_END; p++) {
610 case ART_MOVETO_OPEN:
614 if ((!closed) && ((start->x3 != p->x3) || (start->y3 != p->y3))) {
615 d->code = ART_LINETO;
620 if (p->code == ART_MOVETO) closed = TRUE;
621 d->code = ART_MOVETO;
631 g_assert_not_reached ();
635 if ((!closed) && ((start->x3 != p->x3) || (start->y3 != p->y3))) {
636 d->code = ART_LINETO;
644 new->end = d - new->bpath;
645 new->allclosed = TRUE;
646 new->allopen = FALSE;
654 * gnome_canvas_path_def_unref:
655 * @path: a GnomeCanvasPathDef
657 * Decrease the reference count of the passed @path. If the reference
658 * count is < 1 the path is deallocated.
661 gnome_canvas_path_def_unref (GnomeCanvasPathDef * path)
663 g_return_if_fail (path != NULL);
665 if (--path->refcount < 1) {
666 if ((!path->sbpath) && (path->bpath)) art_free (path->bpath);
674 * gnome_canvas_path_def_reset:
675 * @path: a GnomeCanvasPathDef
677 * This function clears the contents of the passed @path.
680 gnome_canvas_path_def_reset (GnomeCanvasPathDef * path)
682 g_return_if_fail (path != NULL);
683 g_return_if_fail (!path->sbpath);
685 path->bpath->code = ART_END;
687 path->hascpt = FALSE;
688 path->posset = FALSE;
689 path->moving = FALSE;
690 path->allclosed = TRUE;
691 path->allopen = TRUE;
694 /* Several consequtive movetos are ALLOWED */
697 * gnome_canvas_path_def_moveto:
698 * @path: a GnomeCanvasPathDef
702 * This function adds starts new subpath on @path, and sets its
703 * starting point to @x and @y. If current subpath is empty, it
704 * simply changes its starting coordinates to new values.
707 gnome_canvas_path_def_moveto (GnomeCanvasPathDef * path, gdouble x, gdouble y)
709 g_return_if_fail (path != NULL);
710 g_return_if_fail (!path->sbpath);
711 g_return_if_fail (!path->moving);
713 path->substart = path->end;
719 path->allclosed = FALSE;
723 * gnome_canvas_path_def_lineto:
724 * @path: a GnomeCanvasPathDef
728 * This function add a line segment to the passed @path with the
729 * specified @x and @y coordinates.
732 gnome_canvas_path_def_lineto (GnomeCanvasPathDef * path, gdouble x, gdouble y)
736 g_return_if_fail (path != NULL);
737 g_return_if_fail (!path->sbpath);
738 g_return_if_fail (path->hascpt);
741 /* simply fix endpoint */
742 g_return_if_fail (!path->posset);
743 g_return_if_fail (path->end > 1);
744 bp = path->bpath + path->end - 1;
745 g_return_if_fail (bp->code == ART_LINETO);
748 path->moving = FALSE;
753 /* start a new segment */
754 gnome_canvas_path_def_ensure_space (path, 2);
755 bp = path->bpath + path->end;
756 bp->code = ART_MOVETO_OPEN;
760 bp->code = ART_LINETO;
766 path->posset = FALSE;
767 path->allclosed = FALSE;
771 /* Simply add line */
773 g_return_if_fail (path->end > 1);
774 gnome_canvas_path_def_ensure_space (path, 1);
775 bp = path->bpath + path->end;
776 bp->code = ART_LINETO;
786 * gnome_canvas_path_def_lineto_moving:
787 * @path: a GnomeCanvasPathDef
791 * This functions adds a new line segment with loose endpoint to the path, or
792 * if endpoint is already loose, changes its coordinates to @x, @y. You
793 * can change the coordinates of loose endpoint as many times as you want,
794 * the last ones set will be fixed, if you continue line. This is useful
795 * for handling drawing with mouse.
798 gnome_canvas_path_def_lineto_moving (GnomeCanvasPathDef * path, gdouble x, gdouble y)
802 g_return_if_fail (path != NULL);
803 g_return_if_fail (!path->sbpath);
804 g_return_if_fail (path->hascpt);
807 /* simply change endpoint */
808 g_return_if_fail (!path->posset);
809 g_return_if_fail (path->end > 1);
810 bp = path->bpath + path->end - 1;
811 g_return_if_fail (bp->code == ART_LINETO);
818 /* start a new segment */
819 gnome_canvas_path_def_ensure_space (path, 2);
820 bp = path->bpath + path->end;
821 bp->code = ART_MOVETO_OPEN;
825 bp->code = ART_LINETO;
831 path->posset = FALSE;
833 path->allclosed = FALSE;
837 /* Simply add line */
839 g_return_if_fail (path->end > 1);
840 gnome_canvas_path_def_ensure_space (path, 1);
841 bp = path->bpath + path->end;
842 bp->code = ART_LINETO;
852 * gnome_canvas_path_def_curveto:
853 * @path: a GnomeCanvasPathDef
854 * @x0: first control point x coordinate
855 * @y0: first control point y coordinate
856 * @x1: second control point x coordinate
857 * @y1: second control point y coordinate
858 * @x2: end of curve x coordinate
859 * @y2: end of curve y coordinate
861 * This function adds a bezier curve segment to the path definition.
865 gnome_canvas_path_def_curveto (GnomeCanvasPathDef * path, gdouble x0, gdouble y0, gdouble x1, gdouble y1, gdouble x2, gdouble y2)
869 g_return_if_fail (path != NULL);
870 g_return_if_fail (!path->sbpath);
871 g_return_if_fail (path->hascpt);
872 g_return_if_fail (!path->moving);
875 /* start a new segment */
876 gnome_canvas_path_def_ensure_space (path, 2);
877 bp = path->bpath + path->end;
878 bp->code = ART_MOVETO_OPEN;
882 bp->code = ART_CURVETO;
892 path->posset = FALSE;
893 path->allclosed = FALSE;
897 /* Simply add path */
899 g_return_if_fail (path->end > 1);
900 gnome_canvas_path_def_ensure_space (path, 1);
901 bp = path->bpath + path->end;
902 bp->code = ART_CURVETO;
915 * gnome_canvas_path_def_closepath:
916 * @path: a GnomeCanvasPathDef
918 * This function closes the last subpath of @path, adding a ART_LINETO to
919 * subpath starting point, if needed and changing starting pathcode to
923 gnome_canvas_path_def_closepath (GnomeCanvasPathDef * path)
927 g_return_if_fail (path != NULL);
928 g_return_if_fail (!path->sbpath);
929 g_return_if_fail (path->hascpt);
930 g_return_if_fail (!path->posset);
931 g_return_if_fail (!path->moving);
932 g_return_if_fail (!path->allclosed);
933 /* We need at last M + L + L + E */
934 g_return_if_fail (path->end - path->substart > 2);
936 bs = path->bpath + path->substart;
937 be = path->bpath + path->end - 1;
939 if ((bs->x3 != be->x3) || (bs->y3 != be->y3)) {
940 gnome_canvas_path_def_lineto (path, bs->x3, bs->y3);
943 bs = path->bpath + path->substart; /* NB. def_lineto can
945 bs->code = ART_MOVETO;
947 path->allclosed = sp_bpath_all_closed (path->bpath);
948 path->allopen = sp_bpath_all_open (path->bpath);
950 path->hascpt = FALSE;
954 * gnome_canvas_path_def_closepath_current:
955 * @path: a GnomeCanvasPathDef
957 * This function closes the last subpath by setting the coordinates of
958 * the endpoint of the last segment (line or curve) to starting point.
961 gnome_canvas_path_def_closepath_current (GnomeCanvasPathDef * path)
965 g_return_if_fail (path != NULL);
966 g_return_if_fail (!path->sbpath);
967 g_return_if_fail (path->hascpt);
968 g_return_if_fail (!path->posset);
969 g_return_if_fail (!path->allclosed);
970 /* We need at last M + L + L + E */
971 g_return_if_fail (path->end - path->substart > 2);
973 bs = path->bpath + path->substart;
974 be = path->bpath + path->end - 1;
979 bs->code = ART_MOVETO;
981 path->allclosed = sp_bpath_all_closed (path->bpath);
982 path->allopen = sp_bpath_all_open (path->bpath);
984 path->hascpt = FALSE;
985 path->moving = FALSE;
989 * gnome_canvas_path_def_bpath:
990 * @path: a GnomeCanvasPathDef
992 * This function returns a ArtBpath that consists of the path
997 ArtBpath * gnome_canvas_path_def_bpath (const GnomeCanvasPathDef * path)
999 g_return_val_if_fail (path != NULL, NULL);
1005 * gnome_canvas_path_def_length:
1006 * @path: a GnomeCanvasPathDef
1008 * This function returns the length of the path definition. Not
1009 * Euclidian length of the path but rather the number of points on the
1012 * Returns: integer, number of points on the path.
1014 gint gnome_canvas_path_def_length (const GnomeCanvasPathDef * path)
1016 g_return_val_if_fail (path != NULL, -1);
1018 return path->end + 1;
1022 * gnome_canvas_path_def_is_empty:
1023 * @path: a GnomeCanvasPathDef
1025 * This function is a boolean test to see if the path is empty,
1026 * meaning containing no line segments.
1028 * Returns: boolean, indicating if the path is empty.
1031 gnome_canvas_path_def_is_empty (const GnomeCanvasPathDef * path)
1033 g_return_val_if_fail (path != NULL, TRUE);
1035 return (path->bpath->code == ART_END);
1039 * gnome_canvas_path_def_has_currentpoint:
1040 * @path: a GnomeCanvasPathdef
1042 * This function is a boolean test checking to see if the path has a
1043 * current point defined. Current point will be set by line operators,
1044 * and cleared by closing subpath.
1046 * Returns: boolean, indicating if the path has a current point defined.
1049 gnome_canvas_path_def_has_currentpoint (const GnomeCanvasPathDef * path)
1051 g_return_val_if_fail (path != NULL, FALSE);
1053 return (path->hascpt);
1057 * gnome_canvas_path_def_currentpoint:
1058 * @path: a GnomeCanvasPathDef
1059 * @p: a ArtPoint where to store the current point
1061 * Stores the current point of the path definition in the passed ArtPoint @p.
1064 gnome_canvas_path_def_currentpoint (const GnomeCanvasPathDef * path, ArtPoint * p)
1066 g_return_if_fail (path != NULL);
1067 g_return_if_fail (p != NULL);
1068 g_return_if_fail (path->hascpt);
1074 p->x = (path->bpath + path->end - 1)->x3;
1075 p->y = (path->bpath + path->end - 1)->y3;
1080 * gnome_canvas_path_def_last_bpath:
1081 * @path: a GnomeCanvasPathDef
1083 * This function returns pointer to the last ArtBpath segment in the path
1086 * Returns: ArtBpath, being the last segment in the path definition or
1087 * null if no line segments have been defined.
1090 gnome_canvas_path_def_last_bpath (const GnomeCanvasPathDef * path)
1092 g_return_val_if_fail (path != NULL, NULL);
1094 if (path->end == 0) return NULL;
1096 return path->bpath + path->end - 1;
1100 * gnome_canvas_path_def_first_bpath:
1101 * @path: a GnomeCanvasPathDef
1103 * This function returns the first ArtBpath point in the definition.
1105 * Returns: ArtBpath being the first point in the path definition or
1106 * null if no points are defined
1109 gnome_canvas_path_def_first_bpath (const GnomeCanvasPathDef * path)
1111 g_return_val_if_fail (path != NULL, NULL);
1113 if (path->end == 0) return NULL;
1119 * gnome_canvas_path_def_any_open:
1120 * @path: a GnomeCanvasPathDef
1122 * This function returns a boolean value indicating if the path has
1123 * any open segments.
1125 * Returns: boolean, indicating if the path has any open segments.
1128 gnome_canvas_path_def_any_open (const GnomeCanvasPathDef * path)
1130 g_return_val_if_fail (path != NULL, FALSE);
1132 return (!path->allclosed);
1136 * gnome_canvas_path_def_all_open:
1137 * @path: a GnomeCanvasPathDef
1139 * This function returns a boolean value indicating if the path only
1140 * contains open segments.
1142 * Returns: boolean, indicating if the path has all open segments.
1145 gnome_canvas_path_def_all_open (const GnomeCanvasPathDef * path)
1147 g_return_val_if_fail (path != NULL, FALSE);
1149 return (path->allopen);
1153 * gnome_canvas_path_def_any_closed:
1154 * @path: a GnomeCanvasPathDef
1156 * This function returns a boolean valid indicating if the path has
1157 * any closed segements.
1159 * Returns: boolean, indicating if the path has any closed segments.
1162 gnome_canvas_path_def_any_closed (const GnomeCanvasPathDef * path)
1164 g_return_val_if_fail (path != NULL, FALSE);
1166 return (!path->allopen);
1170 * gnome_canvas_path_def_all_closed:
1171 * @path: a GnomeCanvasPathDef
1173 * This function returns a boolean value indicating if the path only
1174 * contains closed segments.
1176 * Returns: boolean, indicating if the path has all closed segments.
1179 gnome_canvas_path_def_all_closed (const GnomeCanvasPathDef * path)
1181 g_return_val_if_fail (path != NULL, FALSE);
1183 return (path->allclosed);
1186 /* Private methods */
1189 gboolean sp_bpath_good (ArtBpath * bpath)
1193 g_return_val_if_fail (bpath != NULL, FALSE);
1195 if (bpath->code == ART_END)
1200 while (bp->code != ART_END) {
1201 bp = sp_bpath_check_subpath (bp);
1202 if (bp == NULL) return FALSE;
1209 sp_bpath_check_subpath (ArtBpath * bpath)
1214 g_return_val_if_fail (bpath != NULL, NULL);
1216 if (bpath->code == ART_MOVETO) {
1218 } else if (bpath->code == ART_MOVETO_OPEN) {
1226 for (i = 1; (bpath[i].code != ART_END) && (bpath[i].code != ART_MOVETO) && (bpath[i].code != ART_MOVETO_OPEN); i++) {
1227 switch (bpath[i].code) {
1238 if (len < 2) return NULL;
1239 if ((bpath->x3 != bpath[i-1].x3) || (bpath->y3 != bpath[i-1].y3)) return NULL;
1241 if (len < 1) return NULL;
1248 sp_bpath_length (const ArtBpath * bpath)
1252 g_return_val_if_fail (bpath != NULL, FALSE);
1254 for (l = 0; bpath[l].code != ART_END; l++) ;
1262 sp_bpath_all_closed (const ArtBpath * bpath)
1264 const ArtBpath * bp;
1266 g_return_val_if_fail (bpath != NULL, FALSE);
1268 for (bp = bpath; bp->code != ART_END; bp++)
1269 if (bp->code == ART_MOVETO_OPEN) return FALSE;
1275 sp_bpath_all_open (const ArtBpath * bpath)
1277 const ArtBpath * bp;
1279 g_return_val_if_fail (bpath != NULL, FALSE);
1281 for (bp = bpath; bp->code != ART_END; bp++)
1282 if (bp->code == ART_MOVETO) return FALSE;