More progress towards gradients in f32
diff --git a/sparse_strips/vello_common/src/encode.rs b/sparse_strips/vello_common/src/encode.rs
index 6693232..deb3ad0 100644
--- a/sparse_strips/vello_common/src/encode.rs
+++ b/sparse_strips/vello_common/src/encode.rs
@@ -357,6 +357,10 @@
     let create_range = |left_stop: &ColorStop, right_stop: &ColorStop| {
         let x0 = start + (end - start) * left_stop.offset;
         let x1 = start + (end - start) * right_stop.offset;
+        let c0_f32 = left_stop
+            .color
+            .to_alpha_color::<Srgb>()
+            .premultiply().components;
         let c0 = left_stop
             .color
             .to_alpha_color::<Srgb>()
@@ -389,6 +393,7 @@
             x0,
             x1,
             c0,
+            c0_f32,
             factors,
         }
     };
@@ -554,6 +559,8 @@
     pub x1: f32,
     /// The start color of the range.
     pub c0: [u8; 4],
+    /// The start color of the range.
+    pub c0_f32: [f32; 4],
     /// The interpolation factors of the range.
     pub factors: [f32; 4],
 }
diff --git a/sparse_strips/vello_cpu/src/fine/gradient.rs b/sparse_strips/vello_cpu/src/fine/gradient.rs
index bdfa591..7db84f6 100644
--- a/sparse_strips/vello_cpu/src/fine/gradient.rs
+++ b/sparse_strips/vello_cpu/src/fine/gradient.rs
@@ -3,7 +3,7 @@
 
 //! Rendering linear gradients.
 
-use crate::fine::{COLOR_COMPONENTS, TILE_HEIGHT_COMPONENTS};
+use crate::fine::{FineType, COLOR_COMPONENTS, TILE_HEIGHT_COMPONENTS};
 use vello_common::encode::{EncodedGradient, GradientLike, GradientRange};
 use vello_common::kurbo::Point;
 
@@ -49,7 +49,7 @@
         }
     }
 
-    pub(super) fn run(mut self, target: &mut [u8]) {
+    pub(super) fn run<F: FineType>(mut self, target: &mut [F]) {
         let original_pos = self.cur_pos;
 
         target
@@ -73,7 +73,7 @@
         }
     }
 
-    fn run_column(&mut self, col: &mut [u8]) {
+    fn run_column<F: FineType>(&mut self, col: &mut [F]) {
         let pad = self.gradient.pad;
         let extend = |val| extend(val, pad, self.gradient.clamp_range);
         let mut pos = self.cur_pos;
@@ -93,7 +93,7 @@
         }
     }
 
-    fn run_undefined(mut self, target: &mut [u8]) {
+    fn run_undefined<F: FineType>(mut self, target: &mut [F]) {
         target
             .chunks_exact_mut(TILE_HEIGHT_COMPONENTS)
             .for_each(|column| {
@@ -103,7 +103,7 @@
                     let actual_pos = pos;
 
                     if !self.kind.is_defined(&actual_pos) {
-                        pixel.copy_from_slice(&[0, 0, 0, 0]);
+                        pixel.copy_from_slice(&[F::ZERO, F::ZERO, F::ZERO, F::ZERO]);
                     }
 
                     pos += self.gradient.y_advance;
diff --git a/sparse_strips/vello_cpu/src/fine/mod.rs b/sparse_strips/vello_cpu/src/fine/mod.rs
index 8fe9121..8ccb9ca 100644
--- a/sparse_strips/vello_cpu/src/fine/mod.rs
+++ b/sparse_strips/vello_cpu/src/fine/mod.rs
@@ -11,7 +11,7 @@
 use alloc::vec;
 use alloc::vec::Vec;
 use core::iter;
-use vello_common::encode::{EncodedKind, EncodedPaint, GradientLike};
+use vello_common::encode::{EncodedKind, EncodedPaint, GradientLike, GradientRange};
 use vello_common::paint::{Paint, PremulColor};
 use vello_common::{
     coarse::{Cmd, WideTile},
@@ -386,6 +386,7 @@
     fn to_rgba8(_in: &[Self]) -> [u8; COLOR_COMPONENTS];
     fn is_max(&self) -> bool;
     fn inv(&self) -> Self;
+    fn grad_color(range: &GradientRange) -> [Self; COLOR_COMPONENTS];
 }
 
 impl FineType for u8 {
@@ -430,6 +431,10 @@
     fn inv(&self) -> Self {
         255 - self
     }
+
+    fn grad_color(range: &GradientRange) -> &[Self; COLOR_COMPONENTS] {
+        &range.c0
+    }
 }
 
 impl FineType for f32 {
@@ -480,4 +485,8 @@
     fn inv(&self) -> Self {
         1.0 - self
     }
+
+    fn grad_color(range: &GradientRange) -> &[Self; COLOR_COMPONENTS] {
+        &range.c0_f32
+    }
 }