[gtk+/wip/alexl/broadway4] broadway: Add linear gradient node



commit 8425231e6e3e51cb9503d07f2c81259af4356d98
Author: Alexander Larsson <alexl redhat com>
Date:   Wed Nov 22 12:31:36 2017 +0100

    broadway: Add linear gradient node

 gdk/broadway/broadway-protocol.h |    1 +
 gdk/broadway/broadway.js         |   84 ++++++++++++++++++++++++++++++++++----
 gdk/broadway/broadwayd.c         |    8 +++-
 gsk/gskbroadwayrenderer.c        |   22 ++++++++++
 4 files changed, 106 insertions(+), 9 deletions(-)
---
diff --git a/gdk/broadway/broadway-protocol.h b/gdk/broadway/broadway-protocol.h
index bc772d9..e4ce21e 100644
--- a/gdk/broadway/broadway-protocol.h
+++ b/gdk/broadway/broadway-protocol.h
@@ -16,6 +16,7 @@ typedef enum { /* Sync changes with broadway.js */
   BROADWAY_NODE_OUTSET_SHADOW = 4,
   BROADWAY_NODE_INSET_SHADOW = 5,
   BROADWAY_NODE_ROUNDED_CLIP = 6,
+  BROADWAY_NODE_LINEAR_GRADIENT = 7,
 } BroadwayNodeType;
 
 typedef enum {
diff --git a/gdk/broadway/broadway.js b/gdk/broadway/broadway.js
index 68f7b8a..45dae02 100644
--- a/gdk/broadway/broadway.js
+++ b/gdk/broadway/broadway.js
@@ -331,15 +331,16 @@ SwapNodes.prototype.decode_int32 = function() {
 
 SwapNodes.prototype.decode_color = function() {
     var rgba = this.decode_uint32();
-    a = (rgba >> 24) & 0xff;
-    r = (rgba >> 16) & 0xff;
-    g = (rgba >> 8) & 0xff;
-    b = (rgba >> 0) & 0xff;
+    var a = (rgba >> 24) & 0xff;
+    var r = (rgba >> 16) & 0xff;
+    var g = (rgba >> 8) & 0xff;
+    var b = (rgba >> 0) & 0xff;
+    var c;
     if (a == 0)
         c = "rgb(" + r + "," + g + "," + b + ")";
     else
         c = "rgba(" + r + "," + g + "," + b + "," + (a / 255.0) + ")";
-    return c
+    return c;
 }
 
 SwapNodes.prototype.decode_float = function() {
@@ -350,7 +351,14 @@ SwapNodes.prototype.decode_size = function() {
     var s = new Object();
     s.width = this.decode_float ();
     s.height = this.decode_float ();
-    return s
+    return s;
+}
+
+SwapNodes.prototype.decode_point = function() {
+    var p = new Object();
+    p.x = this.decode_float ();
+    p.y = this.decode_float ();
+    return p;
 }
 
 SwapNodes.prototype.decode_rect = function() {
@@ -374,10 +382,25 @@ SwapNodes.prototype.decode_irect = function() {
 SwapNodes.prototype.decode_rounded_rect = function() {
     var r = new Object();
     r.bounds = this.decode_rect();
-    r.sizes = []
+    r.sizes = [];
     for (var i = 0; i < 4; i++)
         r.sizes[i] = this.decode_size();
-    return r
+    return r;
+}
+
+SwapNodes.prototype.decode_color_stop = function() {
+    var s = new Object();
+    s.offset = this.decode_float ();
+    s.color = this.decode_color ();
+    return s;
+}
+
+SwapNodes.prototype.decode_color_stops = function() {
+    var stops = [];
+    var len = this.decode_uint32();
+    for (var i = 0; i < len; i++)
+        stops[i] = this.decode_color_stop();
+    return stops;
 }
 
 function args() {
@@ -524,6 +547,51 @@ SwapNodes.prototype.handle_node = function(parent, offset_x, offset_y)
         }
         break;
 
+    case 7:  // LINEAR_GRADIENT
+        {
+            var rect = this.decode_rect();
+            var start = this.decode_point ();
+            var end = this.decode_point ();
+            var stops = this.decode_color_stops ();
+            var div = document.createElement('div');
+            div.style["position"] = "absolute";
+            set_rect_style(div, rect, offset_x, offset_y);
+
+            // direction:
+            var dx = end.x - start.x;
+            var dy = end.y - start.y;
+
+            // Angle in css coords (clockwise degrees, up = 0), note that y goes downwards so we have to 
invert
+            var angle = Math.atan2(dx, -dy) * 180.0 / Math.PI;
+
+            // Figure out which corner has offset == 0 in css
+            var start_corner_x, start_corner_y;
+            if (dx >= 0) // going right
+                start_corner_x = rect.x;
+            else
+                start_corner_x = rect.x + rect.width;
+            if (dy >= 0) // going down
+                start_corner_y = rect.y;
+            else
+                start_corner_y = rect.y + rect.height;
+
+            /* project start corner on the line */
+            var l2 = dx*dx + dy*dy;
+            var l = Math.sqrt(l2);
+            var offset = ((start_corner_x - start.x) * dx  + (start_corner_y - start.y) * dy) / l2;
+
+            var gradient = "linear-gradient(" + angle + "deg";
+            for (var i = 0; i < stops.length; i++) {
+                var stop = stops[i];
+                gradient = gradient + ", " + stop.color + " " + px(stop.offset * l - offset);
+            }
+            gradient = gradient + ")";
+
+            div.style["background-image"] = gradient;
+            parent.appendChild(div);
+        }
+        break;
+
     default:
         alert("Unexpected node type " + type);
     }
diff --git a/gdk/broadway/broadwayd.c b/gdk/broadway/broadwayd.c
index b3ebd4b..693e76c 100644
--- a/gdk/broadway/broadwayd.c
+++ b/gdk/broadway/broadwayd.c
@@ -221,13 +221,14 @@ get_client_serial (BroadwayClient *client, guint32 daemon_serial)
 #define NODE_SIZE_SIZE 2
 #define NODE_SIZE_RECT (NODE_SIZE_POINT + NODE_SIZE_SIZE)
 #define NODE_SIZE_RRECT (NODE_SIZE_RECT + 4 * NODE_SIZE_SIZE)
+#define NODE_SIZE_COLOR_STOP (NODE_SIZE_FLOAT + NODE_SIZE_COLOR)
 
 static int
 rewrite_node_textures (BroadwayClient *client,
                        int len, guint32 data[], int pos)
 {
   guint32 type;
-  guint32 i, n_children;
+  guint32 i, n_children, n_stops;
 
   g_assert (pos < len);
 
@@ -257,6 +258,11 @@ rewrite_node_textures (BroadwayClient *client,
     pos += NODE_SIZE_RRECT;
     pos = rewrite_node_textures (client, len, data, pos);
     break;
+  case BROADWAY_NODE_LINEAR_GRADIENT:
+    pos += NODE_SIZE_RECT + 2 * NODE_SIZE_POINT;
+    n_stops = data[pos++];
+    pos += n_stops * NODE_SIZE_COLOR_STOP;
+    break;
   default:
     g_assert_not_reached ();
   }
diff --git a/gsk/gskbroadwayrenderer.c b/gsk/gskbroadwayrenderer.c
index 0720369..b2ead65 100644
--- a/gsk/gskbroadwayrenderer.c
+++ b/gsk/gskbroadwayrenderer.c
@@ -146,6 +146,13 @@ add_rounded_rect (GArray *nodes, const GskRoundedRect *rrect)
 }
 
 static void
+add_color_stop (GArray *nodes, const GskColorStop *stop)
+{
+  add_float (nodes, stop->offset);
+  add_rgba (nodes, &stop->color);
+}
+
+static void
 gsk_broadway_renderer_add_node (GskRenderer *self,
                                 GArray *nodes,
                                 GPtrArray *node_textures,
@@ -228,6 +235,21 @@ gsk_broadway_renderer_add_node (GskRenderer *self,
       }
       return;
 
+    case GSK_LINEAR_GRADIENT_NODE:
+      {
+        guint i, n;
+
+        add_uint32 (nodes, BROADWAY_NODE_LINEAR_GRADIENT);
+        add_rect (nodes, &node->bounds);
+        add_point (nodes, gsk_linear_gradient_node_peek_start (node));
+        add_point (nodes, gsk_linear_gradient_node_peek_end (node));
+        n = gsk_linear_gradient_node_get_n_color_stops (node);
+        add_uint32 (nodes, n);
+        for (i = 0; i < n; i++)
+          add_color_stop (nodes, &gsk_linear_gradient_node_peek_color_stops (node)[i]);
+      }
+      return;
+
     default:
       {
         cairo_surface_t *surface;


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