1 /* GnomeCanvas Bezier polyline paths & segments
2 *
3 * GnomeCanvas is basically a port of the Tk toolkit's most excellent canvas widget. Tk is
4 * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
5 *
6 * Copyright (C) 1998,1999 The Free Software Foundation
7 *
8 * Authors: Federico Mena <federico@nuclecu.unam.mx>
9 * Lauris Kaplinski <lauris@ariman.ee>
10 * Raph Levien <raph@acm.org>
11 */
13 #include <glib/gmem.h>
14 #include <glib/gmessages.h>
16 #include "libnr/n-art-bpath.h"
17 #include "gnome-canvas-bpath-util.h"
19 GnomeCanvasBpathDef *
20 gnome_canvas_bpath_def_new (void)
21 {
22 GnomeCanvasBpathDef *bpd;
24 bpd = g_new (GnomeCanvasBpathDef, 1);
25 bpd->n_bpath = 0;
26 bpd->n_bpath_max = 16;
27 bpd->moveto_idx = -1;
28 bpd->bpath = g_new (NArtBpath, bpd->n_bpath_max);
29 bpd->ref_count = 1;
31 return bpd;
32 }
34 GnomeCanvasBpathDef *
35 gnome_canvas_bpath_def_new_from (NArtBpath *path)
36 {
37 GnomeCanvasBpathDef *bpd;
38 int i;
40 g_return_val_if_fail (path != NULL, NULL);
42 bpd = g_new (GnomeCanvasBpathDef, 1);
44 for (i = 0; path [i].code != NR_END; i++)
45 ;
46 bpd->n_bpath = i;
47 bpd->n_bpath_max = i;
48 bpd->moveto_idx = -1;
49 bpd->ref_count = 1;
50 bpd->bpath = g_new (NArtBpath, i);
52 memcpy (bpd->bpath, path, i * sizeof (NArtBpath));
53 return bpd;
54 }
56 GnomeCanvasBpathDef *
57 gnome_canvas_bpath_def_ref (GnomeCanvasBpathDef *bpd)
58 {
59 g_return_val_if_fail (bpd != NULL, NULL);
61 bpd->ref_count += 1;
62 return bpd;
63 }
65 void
66 gnome_canvas_bpath_def_free (GnomeCanvasBpathDef *bpd)
67 {
68 g_return_if_fail (bpd != NULL);
70 bpd->ref_count -= 1;
71 if (bpd->ref_count == 0) {
72 g_free (bpd->bpath);
73 g_free (bpd);
74 }
75 }
77 void
78 gnome_canvas_bpath_def_moveto (GnomeCanvasBpathDef *bpd, double x, double y)
79 {
80 NArtBpath *bpath;
81 int n_bpath;
83 g_return_if_fail (bpd != NULL);
85 n_bpath = bpd->n_bpath++;
87 if (n_bpath == bpd->n_bpath_max)
88 bpd->bpath = (NArtBpath*)g_realloc (bpd->bpath,
89 (bpd->n_bpath_max <<= 1) * sizeof (NArtBpath));
90 bpath = bpd->bpath;
91 bpath[n_bpath].code = NR_MOVETO_OPEN;
92 bpath[n_bpath].x3 = x;
93 bpath[n_bpath].y3 = y;
94 bpd->moveto_idx = n_bpath;
95 }
97 void
98 gnome_canvas_bpath_def_lineto (GnomeCanvasBpathDef *bpd, double x, double y)
99 {
100 NArtBpath *bpath;
101 int n_bpath;
103 g_return_if_fail (bpd != NULL);
104 g_return_if_fail (bpd->moveto_idx >= 0);
106 n_bpath = bpd->n_bpath++;
108 if (n_bpath == bpd->n_bpath_max)
109 bpd->bpath = (NArtBpath*)g_realloc (bpd->bpath,
110 (bpd->n_bpath_max <<= 1) * sizeof (NArtBpath));
111 bpath = bpd->bpath;
112 bpath[n_bpath].code = NR_LINETO;
113 bpath[n_bpath].x3 = x;
114 bpath[n_bpath].y3 = y;
115 }
117 void
118 gnome_canvas_bpath_def_curveto (GnomeCanvasBpathDef *bpd, double x1, double y1, double x2, double y2, double x3, double y3)
119 {
120 NArtBpath *bpath;
121 int n_bpath;
123 g_return_if_fail (bpd != NULL);
124 g_return_if_fail (bpd->moveto_idx >= 0);
126 n_bpath = bpd->n_bpath++;
128 if (n_bpath == bpd->n_bpath_max)
129 bpd->bpath = (NArtBpath*)g_realloc (bpd->bpath,
130 (bpd->n_bpath_max <<= 1) * sizeof (NArtBpath));
131 bpath = bpd->bpath;
132 bpath[n_bpath].code = NR_CURVETO;
133 bpath[n_bpath].x1 = x1;
134 bpath[n_bpath].y1 = y1;
135 bpath[n_bpath].x2 = x2;
136 bpath[n_bpath].y2 = y2;
137 bpath[n_bpath].x3 = x3;
138 bpath[n_bpath].y3 = y3;
139 }
141 void
142 gnome_canvas_bpath_def_closepath (GnomeCanvasBpathDef *bpd)
143 {
144 NArtBpath *bpath;
145 int n_bpath;
147 g_return_if_fail (bpd != NULL);
148 g_return_if_fail (bpd->moveto_idx >= 0);
149 g_return_if_fail (bpd->n_bpath > 0);
151 bpath = bpd->bpath;
152 n_bpath = bpd->n_bpath;
154 /* Add closing vector if we need it. */
155 if (bpath[n_bpath - 1].x3 != bpath[bpd->moveto_idx].x3 ||
156 bpath[n_bpath - 1].y3 != bpath[bpd->moveto_idx].y3) {
157 gnome_canvas_bpath_def_lineto (bpd, bpath[bpd->moveto_idx].x3,
158 bpath[bpd->moveto_idx].y3);
159 bpath = bpd->bpath;
160 }
161 bpath[bpd->moveto_idx].code = NR_MOVETO;
162 bpd->moveto_idx = -1;
163 }
165 void
166 gnome_canvas_bpath_def_art_finish (GnomeCanvasBpathDef *bpd)
167 {
168 int n_bpath;
170 g_return_if_fail (bpd != NULL);
172 n_bpath = bpd->n_bpath++;
174 if (n_bpath == bpd->n_bpath_max)
175 bpd->bpath = (NArtBpath*)g_realloc (bpd->bpath,
176 (bpd->n_bpath_max <<= 1) * sizeof (NArtBpath));
177 bpd->bpath [n_bpath].code = NR_END;
178 }