Compare commits

..

1 Commits

Author SHA1 Message Date
Matthias Clasen dd6f5597c1 Add GtkContour 2023-07-12 06:17:29 -04:00
4 changed files with 384 additions and 2275 deletions
File diff suppressed because it is too large Load Diff
+2 -19
View File
@@ -43,23 +43,6 @@ make_circle_path (void)
return gsk_path_builder_free_to_path (builder);
}
static GskPath *
make_fancy_path (void)
{
GskPathBuilder *builder;
builder = gsk_path_builder_new ();
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (150, 150), 100);
gsk_path_builder_add_rect (builder, &GRAPHENE_RECT_INIT (100, 100, 100, 100));
gsk_path_builder_move_to (builder, 300, 150);
gsk_path_builder_cubic_to (builder, 300, 50, 400, 50, 400, 150);
gsk_path_builder_cubic_to (builder, 400, 250, 500, 250, 500, 150);
gsk_path_builder_line_to (builder, 600, 150);
gsk_path_builder_line_to (builder, 530, 190);
return gsk_path_builder_free_to_path (builder);
}
static void
edit_changed (GtkToggleButton *button,
GParamSpec *pspec,
@@ -74,7 +57,7 @@ reset (GtkButton *button,
{
GskPath *path;
path = make_fancy_path ();
path = make_circle_path ();
curve_editor_set_path (editor, path);
gsk_path_unref (path);
}
@@ -274,7 +257,7 @@ do_curve (GtkWidget *do_widget)
gtk_spin_button_set_value (GTK_SPIN_BUTTON (line_width_spin), 6);
gtk_color_dialog_button_set_rgba (GTK_COLOR_DIALOG_BUTTON (color_button), &(GdkRGBA) { 1, 0, 0, 1 });
gtk_drop_down_set_selected (GTK_DROP_DOWN (cap_combo), GSK_LINE_CAP_ROUND);
//gtk_editable_set_text (GTK_EDITABLE (dash_entry), "0 8");
gtk_editable_set_text (GTK_EDITABLE (dash_entry), "0 8");
gtk_window_set_child (GTK_WINDOW (window), demo);
}
+24 -183
View File
@@ -65,12 +65,6 @@ gtk_contour_new (const graphene_point_t *start)
return self;
}
static inline unsigned int
num_curves (GtkContour *self)
{
return self->curves->len;
}
unsigned int
gtk_contour_get_n_curves (GtkContour *self)
{
@@ -79,18 +73,12 @@ gtk_contour_get_n_curves (GtkContour *self)
return self->curves->len;
}
static inline unsigned int
num_points (GtkContour *self)
{
return self->curves->len + (1 - self->closed);
}
unsigned int
gtk_contour_get_n_points (GtkContour *self)
{
g_return_val_if_fail (GTK_IS_CONTOUR (self), 0);
return num_points (self);
return self->curves->len + (1 - self->closed);
}
void
@@ -101,7 +89,7 @@ gtk_contour_set_point (GtkContour *self,
GtkCurve *curve;
g_return_if_fail (GTK_IS_CONTOUR (self));
g_return_if_fail (pos < num_points (self));
g_return_if_fail (pos < self->curves->len);
g_return_if_fail (point != NULL);
if (pos < self->curves->len)
@@ -111,7 +99,7 @@ gtk_contour_set_point (GtkContour *self,
}
if (pos == 0 && self->closed)
pos = self->curves->len;
pos = self->curves->len - 1;
if (pos > 0)
{
@@ -129,7 +117,7 @@ gtk_contour_get_point (GtkContour *self,
GtkCurve *curve;
g_return_if_fail (GTK_IS_CONTOUR (self));
g_return_if_fail (pos < num_points (self));
g_return_if_fail (pos < self->curves->len + (1 - self->closed));
g_return_if_fail (point != NULL);
if (pos < self->curves->len)
@@ -154,7 +142,7 @@ gtk_contour_get_curve (GtkContour *self,
GtkCurve *curve;
g_return_if_fail (GTK_IS_CONTOUR (self));
g_return_if_fail (pos < num_curves (self));
g_return_if_fail (pos < self->curves->len);
curve = g_ptr_array_index (self->curves, pos);
if (op)
@@ -175,7 +163,7 @@ gtk_contour_set_curve (GtkContour *self,
GtkCurve *curve;
g_return_if_fail (GTK_IS_CONTOUR (self));
g_return_if_fail (pos < num_curves (self));
g_return_if_fail (pos < self->curves->len);
curve = g_ptr_array_index (self->curves, pos);
curve->op = op;
@@ -190,7 +178,7 @@ gtk_contour_set_line (GtkContour *self,
GtkCurve *curve;
g_return_if_fail (GTK_IS_CONTOUR (self));
g_return_if_fail (pos < num_curves (self));
g_return_if_fail (pos < self->curves->len);
curve = g_ptr_array_index (self->curves, pos);
curve->op = GSK_PATH_LINE;
@@ -204,7 +192,7 @@ gtk_contour_set_quad (GtkContour *self,
GtkCurve *curve;
g_return_if_fail (GTK_IS_CONTOUR (self));
g_return_if_fail (pos < num_curves (self));
g_return_if_fail (pos < self->curves->len);
g_return_if_fail (cp != NULL);
curve = g_ptr_array_index (self->curves, pos);
@@ -221,7 +209,7 @@ gtk_contour_set_cubic (GtkContour *self,
GtkCurve *curve;
g_return_if_fail (GTK_IS_CONTOUR (self));
g_return_if_fail (pos < num_curves (self));
g_return_if_fail (pos < self->curves->len);
g_return_if_fail (cp1 != NULL);
g_return_if_fail (cp2 != NULL);
@@ -240,7 +228,7 @@ gtk_contour_set_conic (GtkContour *self,
GtkCurve *curve;
g_return_if_fail (GTK_IS_CONTOUR (self));
g_return_if_fail (pos < num_curves (self));
g_return_if_fail (pos < self->curves->len);
g_return_if_fail (cp != NULL);
g_return_if_fail (0 < weight);
@@ -414,12 +402,12 @@ gtk_contour_split (GtkContour *self,
GtkContour **contour1,
GtkContour **contour2)
{
GtkCurve *curve, *curve1, *curve2;
GtkCurve *curve, *curve1;
GtkContour *c1, *c2;
g_return_if_fail (GTK_IS_CONTOUR (self));
g_return_if_fail (pos < num_curves (self));
g_return_if_fail (pos < self->curves->len);
g_return_if_fail (contour1 != NULL);
g_return_if_fail (contour2 != NULL);
@@ -432,13 +420,10 @@ gtk_contour_split (GtkContour *self,
{
curve1 = g_ptr_array_index (self->curves, i);
curve2 = g_new0 (GtkCurve, 1);
memcpy (curve2, curve1, sizeof (GtkCurve));
if (i < pos)
g_ptr_array_add (c1->curves, curve2);
g_ptr_array_add (c1->curves, curve1);
else if (i > pos)
g_ptr_array_add (c2->curves, curve2);
g_ptr_array_add (c2->curves, curve1);
}
if (self->closed)
@@ -452,6 +437,10 @@ gtk_contour_split (GtkContour *self,
*contour1 = c1;
*contour2 = c2;
g_ptr_array_set_free_func (self->curves, NULL);
g_free (curve);
g_object_unref (self);
}
static inline int
@@ -482,12 +471,12 @@ gtk_curve_init_from_gsk (GtkCurve *curve,
{
case GSK_PATH_LINE:
curve->p[0] = c->line.points[0];
curve->p[3] = c->line.points[1];
curve->p[1] = c->line.points[1];
break;
case GSK_PATH_QUAD:
curve->p[0] = c->quad.points[0];
curve->p[1] = c->quad.points[1];
curve->p[3] = c->quad.points[2];
curve->p[2] = c->quad.points[2];
break;
case GSK_PATH_CUBIC:
curve->p[0] = c->cubic.points[0];
@@ -498,7 +487,7 @@ gtk_curve_init_from_gsk (GtkCurve *curve,
case GSK_PATH_CONIC:
curve->p[0] = c->conic.points[0];
curve->p[1] = c->conic.points[1];
curve->p[3] = c->conic.points[3];
curve->p[2] = c->conic.points[3];
curve->weight = c->conic.points[2].x;
break;
case GSK_PATH_MOVE:
@@ -515,19 +504,8 @@ split_curve (const GtkCurve *curve,
GtkCurve *curve2)
{
GskCurve c, c1, c2;
graphene_point_t pp[2];
const graphene_point_t *p = curve->p;
if (curve->op == GSK_PATH_LINE)
{
pp[0] = curve->p[0];
pp[1] = curve->p[3];
p = pp;
}
else
p = curve->p;
gsk_curve_init_foreach (&c, curve->op, p, n_points (curve->op), curve->weight);
gsk_curve_init_foreach (&c, curve->op, curve->p, n_points (curve->op), curve->weight);
gsk_curve_split (&c, t, &c1, &c2);
gtk_curve_init_from_gsk (curve1, &c1);
gtk_curve_init_from_gsk (curve2, &c2);
@@ -541,7 +519,7 @@ gtk_contour_insert_point (GtkContour *self,
GtkCurve *curve, *curve2;
g_return_if_fail (GTK_IS_CONTOUR (self));
g_return_if_fail (pos < num_curves (self));
g_return_if_fail (pos < self->curves->len);
curve = g_ptr_array_index (self->curves, pos);
@@ -550,133 +528,6 @@ gtk_contour_insert_point (GtkContour *self,
g_ptr_array_insert (self->curves, pos + 1, curve2);
}
static int
curve_before_point (GtkContour *self,
unsigned int point)
{
if (point > 0)
return point - 1;
else if (self->closed)
return self->curves->len - 1;
else
return -1;
}
static int
curve_after_point (GtkContour *self,
unsigned int point)
{
if (point < self->curves->len)
return point;
else if (self->closed)
return 0;
else
return -1;
}
static gboolean
line_intersection (const graphene_point_t *a,
const graphene_point_t *b,
const graphene_point_t *c,
const graphene_point_t *d,
graphene_point_t *p)
{
double a1 = b->y - a->y;
double b1 = a->x - b->x;
double c1 = a1*a->x + b1*a->y;
double a2 = d->y - c->y;
double b2 = c->x - d->x;
double c2 = a2*c->x+ b2*c->y;
double det = a1*b2 - a2*b1;
if (det != 0)
{
p->x = (b2*c1 - b1*c2) / det;
p->y = (a1*c2 - a2*c1) / det;
return TRUE;
}
return FALSE;
}
void
gtk_contour_remove_point (GtkContour *self,
unsigned int pos)
{
unsigned int before, after;
g_return_if_fail (GTK_IS_CONTOUR (self));
g_return_if_fail (pos < num_points (self));
before = curve_before_point (self, pos);
after = curve_after_point (self, pos);
if (before != -1 && after != -1)
{
GtkCurve *curve1 = g_ptr_array_index (self->curves, before);
GtkCurve *curve2 = g_ptr_array_index (self->curves, after);
graphene_point_t c1, c2;
if (curve1->op == GSK_PATH_CUBIC && curve2->op == GSK_PATH_CUBIC)
{
/* FIXME: We should make the new curve go through
* the removed point if possible.
*/
c1 = curve1->p[1];
c2 = curve2->p[2];
}
else
{
const graphene_point_t *a, *b, *c, *d;
graphene_point_t p;
a = &curve1->p[0];
d = &curve2->p[3];
if (curve1->op == GSK_PATH_LINE)
b = &curve1->p[3];
else
b = &curve1->p[1];
if (curve2->op == GSK_PATH_LINE)
c = &curve2->p[0];
else if (curve2->op == GSK_PATH_CUBIC)
c = &curve2->p[2];
else
c = &curve2->p[1];
if (line_intersection (a, b, c, d, &p))
{
graphene_point_interpolate (&curve1->p[0], &p, 0.667, &c1);
graphene_point_interpolate (&p, &curve2->p[3], 0.333, &c2);
}
else
{
c1 = *b;
c2 = *c;
}
}
curve1->op = GSK_PATH_CUBIC;
curve1->p[1] = c1;
curve1->p[2] = c2;
curve1->p[3] = curve2->p[3];
g_ptr_array_remove_index (self->curves, after);
}
else if (before != -1)
{
g_ptr_array_remove_index (self->curves, before);
}
else if (after != -1)
{
g_ptr_array_remove_index (self->curves, after);
}
/* Check if the contour is now empty */
if (self->curves->len == 0)
self->closed = FALSE;
}
static void
path_builder_add_curve (GskPathBuilder *builder,
GtkCurve *curve)
@@ -703,7 +554,6 @@ path_builder_add_curve (GskPathBuilder *builder,
curve->p[3].x, curve->p[3].y,
curve->weight);
break;
case GSK_PATH_MOVE:
case GSK_PATH_CLOSE:
default:
@@ -723,10 +573,6 @@ gtk_contour_find_closest_curve (GtkContour *self,
float t;
unsigned int best;
g_return_val_if_fail (GTK_IS_CONTOUR (self), FALSE);
g_return_val_if_fail (point != NULL, FALSE);
g_return_val_if_fail (threshold > 0, FALSE);
best = G_MAXUINT;
for (unsigned int i = 0; i < self->curves->len; i++)
{
@@ -782,9 +628,6 @@ gtk_contour_add_to_path_builder (GtkContour *self,
{
GtkCurve *curve;
g_return_if_fail (GTK_IS_CONTOUR (self));
g_return_if_fail (builder != NULL);
if (self->curves->len == 0)
return;
@@ -798,7 +641,5 @@ gtk_contour_add_to_path_builder (GtkContour *self,
}
if (self->closed)
{
gsk_path_builder_close (builder);
}
gsk_path_builder_close (builder);
}
-4
View File
@@ -103,10 +103,6 @@ void gtk_contour_insert_point (GtkContour *self,
unsigned int idx,
float t);
GDK_AVAILABLE_IN_ALL
void gtk_contour_remove_point (GtkContour *self,
unsigned int idx);
GDK_AVAILABLE_IN_ALL
gboolean gtk_contour_find_closest_curve (GtkContour *self,
const graphene_point_t *point,