[gtk/wip/matthiasc/lottie-stroke: 13/17] wip: Support conics in the stroker




commit 6428dfe37c21fad60db2a1f55367bc2194906ccb
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Dec 3 01:44:39 2020 -0500

    wip: Support conics in the stroker

 gsk/gskpathstroke.c | 67 ++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 54 insertions(+), 13 deletions(-)
---
diff --git a/gsk/gskpathstroke.c b/gsk/gskpathstroke.c
index 4704652195..94ffe66af4 100644
--- a/gsk/gskpathstroke.c
+++ b/gsk/gskpathstroke.c
@@ -743,9 +743,9 @@ conic_get_bounds (Curve           *c,
     }
 }
 
-static void init_conic (Curve            *c,
-                        graphene_point_t  p[3],
-                        float             weight);
+static void init_conic (Curve                  *c,
+                        const graphene_point_t  p[3],
+                        float                   weight);
 
 static void
 conic_split (Curve *c, float t, Curve *left, Curve *right)
@@ -811,9 +811,9 @@ static CurveClass CONIC_CLASS =
 };
 
 static void
-init_conic (Curve            *c,
-            graphene_point_t  p[3],
-            float             weight)
+init_conic (Curve                  *c,
+            const graphene_point_t  p[3],
+            float                   weight)
 {
   c->class = &CONIC_CLASS;
   c->p[0] = p[0];
@@ -1054,6 +1054,17 @@ compute_offsets (PathOpData *op,
       if (!line_intersection (&m2, &m3, &m4, &op->l[3], &op->l[2]))
         op->l[2] = m4;
     }
+  else if (op->op == GSK_PATH_CONIC)
+    {
+      graphene_point_t m;
+
+      midpoint (&op->pts[0], &op->pts[2], &m);
+
+      direction_vector (&m, &op->pts[1], &n1);
+
+      scale_point (&op->pts[1], &n1, d, &op->r[1]);
+      scale_point (&op->pts[1], &n1, -d, &op->l[1]);
+    }
 
   op->re[0] = op->r[0];
   op->le[0] = op->l[0];
@@ -1178,6 +1189,7 @@ compute_intersections (PathOpData *op1,
 static PathOpData *
 path_op_data_new (GskPathOperation        op,
                   const graphene_point_t *pts,
+                  float                   w,
                   gsize                   n_pts)
 {
   PathOpData *d;
@@ -1188,6 +1200,7 @@ path_op_data_new (GskPathOperation        op,
   for (i = 0; i < n_pts; i++)
     d->pts[i] = pts[i];
   d->n_pts = n_pts;
+  d->w = w;
 
 #if STROKE_DEBUG
   /* detect uninitialized values */
@@ -1216,7 +1229,7 @@ subdivide_and_add (const graphene_point_t  pts[4],
 {
   if (level == 0 || cubic_is_simple (pts))
     data->ops = g_list_prepend (data->ops,
-                                path_op_data_new (GSK_PATH_CURVE, pts, 4));
+                                path_op_data_new (GSK_PATH_CURVE, pts, 0, 4));
   else
     {
       graphene_point_t left[4];
@@ -1229,6 +1242,19 @@ subdivide_and_add (const graphene_point_t  pts[4],
     }
 }
 
+static void
+subdivide_and_add_conic (const graphene_point_t  pts[4],
+                         float                   weight,
+                         AddOpData              *data)
+{
+  Curve c, c1, c2;
+
+  init_conic (&c, pts, weight);
+  curve_split (&c, 0.5, &c1, &c2);
+  data->ops = g_list_prepend (data->ops, path_op_data_new (GSK_PATH_CONIC, c1.p, c1.weight, 3));
+  data->ops = g_list_prepend (data->ops, path_op_data_new (GSK_PATH_CONIC, c2.p, c2.weight, 3));
+}
+
 static gboolean
 add_op_to_list (GskPathOperation        op,
                 const graphene_point_t *pts,
@@ -1267,7 +1293,7 @@ add_op_to_list (GskPathOperation        op,
 
     case GSK_PATH_CLOSE:
     case GSK_PATH_LINE:
-      data->ops = g_list_prepend (data->ops, path_op_data_new (op, pts, n_pts));
+      data->ops = g_list_prepend (data->ops, path_op_data_new (op, pts, weight, n_pts));
       break;
 
     case GSK_PATH_CURVE:
@@ -1275,10 +1301,13 @@ add_op_to_list (GskPathOperation        op,
       break;
 
     case GSK_PATH_CONIC:
+      subdivide_and_add_conic (pts, weight, data);
+#if 0
       gsk_spline_decompose_conic ((graphene_point_t[4]) { pts[0], pts[1], { weight, }, pts[2] },
                                   0.0001,
                                   conic_add_point,
                                   data);
+#endif
       break;
 
     default:
@@ -1505,7 +1534,7 @@ gsk_contour_stroke (const GskContour *contour,
         }
     }
 
-#ifdef STROKE_DEBUG
+#if 0
   for (l = ops; l; l = l->next)
     {
       int i;
@@ -1571,8 +1600,14 @@ gsk_contour_stroke (const GskContour *contour,
           break;
 
         case GSK_PATH_CONIC:
-          g_warning ("FIXME: support conics in the stroker");
-          g_assert_not_reached ();
+          if (op->angle[1] >= 181)
+            gsk_path_builder_conic_to (builder, op->r[1].x, op->r[1].y,
+                                                op->re[1].x, op->re[1].y,
+                                                op->w);
+          else
+            gsk_path_builder_conic_to (builder, op->r[1].x, op->r[1].y,
+                                                op->r[2].x, op->r[2].y,
+                                                op->w);
           break;
 
         default:
@@ -1704,8 +1739,14 @@ gsk_contour_stroke (const GskContour *contour,
           break;
 
         case GSK_PATH_CONIC:
-          g_warning ("FIXME: support conics in the stroker");
-          g_assert_not_reached ();
+          if (op->angle[0] <= 179)
+            gsk_path_builder_conic_to (builder, op->l[1].x, op->l[1].y,
+                                                op->le[0].x, op->le[0].y,
+                                                op->w);
+          else
+            gsk_path_builder_conic_to (builder, op->l[1].x, op->l[1].y,
+                                                op->l[0].x, op->l[0].y,
+                                                op->w);
           break;
 
         default:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]