[instancer] Switch delta calculations back to floats (#6424)

The scalar cache stores floats, so computing uncached tuple scalars and
instancer deltas as doubles made results depend on whether the cache was
used. Restore single-precision calculations throughout the instancer and
update the affected CFF2 partial-instancing fixtures.

The current glyf partial-instancing comparison still matches fontTools,
so it does not need a new no_fonttools opt-out.

Fixes: https://github.com/harfbuzz/harfbuzz/issues/6423
Assisted-by: OpenAI Codex <codex@openai.com>
diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh
index d4586ec..a7cd032 100644
--- a/src/hb-ot-layout-common.hh
+++ b/src/hb-ot-layout-common.hh
@@ -5027,13 +5027,13 @@
       if (!c->plan->axes_old_index_tag_map.has (src.axisIndex, &axis_tag))
         return LOOKUP_CONDITION_SUBSET_ERROR;
 
-      Triple axis_limit {-1.0, 0.0, 1.0};
+      Triple axis_limit {-1.f, 0.f, 1.f};
       Triple *normalized_limit;
       if (c->plan->axes_location.has (*axis_tag, &normalized_limit))
         axis_limit = *normalized_limit;
 
-      double filter_min = (double) src.filterRangeMinValue.to_float ();
-      double filter_max = (double) src.filterRangeMaxValue.to_float ();
+      float filter_min = src.filterRangeMinValue.to_float ();
+      float filter_max = src.filterRangeMaxValue.to_float ();
       if (filter_min > filter_max)
         return LOOKUP_CONDITION_SUBSET_FALSE;
       if (axis_limit.is_point ())
@@ -5054,7 +5054,7 @@
       if (unlikely (!out))
         return LOOKUP_CONDITION_SUBSET_ERROR;
 
-      TripleDistances axis_distances {1.0, 1.0};
+      TripleDistances axis_distances {1.f, 1.f};
       TripleDistances *distances;
       if (c->plan->axes_triple_distances.has (*axis_tag, &distances))
         axis_distances = *distances;
diff --git a/src/hb-ot-os2-table.hh b/src/hb-ot-os2-table.hh
index db8fd4d..8215b31 100644
--- a/src/hb-ot-os2-table.hh
+++ b/src/hb-ot-os2-table.hh
@@ -272,7 +272,7 @@
     Triple *axis_range;
     if (c->plan->user_axes_location.has (HB_TAG ('w','g','h','t'), &axis_range))
     {
-      unsigned weight_class = static_cast<unsigned> (roundf (hb_clamp (axis_range->middle, 1.0, 1000.0)));
+      unsigned weight_class = static_cast<unsigned> (roundf (hb_clamp (axis_range->middle, 1.0f, 1000.0f)));
       if (os2_prime->usWeightClass != weight_class)
         os2_prime->usWeightClass = weight_class;
     }
diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh
index d89a454..ac70e11 100644
--- a/src/hb-ot-post-table.hh
+++ b/src/hb-ot-post-table.hh
@@ -116,7 +116,7 @@
     Triple *axis_range;
     if (c->plan->user_axes_location.has (HB_TAG ('s','l','n','t'), &axis_range))
     {
-      float italic_angle = hb_max (-90.0, hb_min (axis_range->middle, 90.0));
+      float italic_angle = hb_max (-90.f, hb_min (axis_range->middle, 90.f));
       if (post_prime->italicAngle.to_float () != italic_angle)
         post_prime->italicAngle.set_float (italic_angle);
     }
diff --git a/src/hb-ot-stat-table.hh b/src/hb-ot-stat-table.hh
index ac24dff..e0041b8 100644
--- a/src/hb-ot-stat-table.hh
+++ b/src/hb-ot-stat-table.hh
@@ -63,9 +63,8 @@
   if (!user_axes_location->has (axis_tag))
     return false;
 
-  double axis_value_double = static_cast<double>(axis_value);
   Triple axis_range = user_axes_location->get (axis_tag);
-  return (axis_value_double < axis_range.minimum || axis_value_double > axis_range.maximum);
+  return (axis_value < axis_range.minimum || axis_value > axis_range.maximum);
 }
 
 struct StatAxisRecord
diff --git a/src/hb-ot-var-avar-table.hh b/src/hb-ot-var-avar-table.hh
index 0e59c04..42138ea 100644
--- a/src/hb-ot-var-avar-table.hh
+++ b/src/hb-ot-var-avar-table.hh
@@ -257,7 +257,7 @@
     float unmapped_middle = unmap_float (axis_range.middle);
     float unmapped_max = unmap_float (axis_range.maximum);
 
-    return Triple{(double) unmapped_min, (double) unmapped_middle, (double) unmapped_max};
+    return Triple{unmapped_min, unmapped_middle, unmapped_max};
   }
 
   bool subset (hb_subset_context_t *c, hb_tag_t axis_tag,
@@ -1025,9 +1025,9 @@
            * Omitting that knot (as a plain two-tent encoding would) makes
            * interior coordinates wrong. */
           double z_old = _avar2_normalize_value ((double) old_def,
-                                                 new_user->minimum,
-                                                 new_user->middle,
-                                                 new_user->maximum);
+                                                 (double) new_user->minimum,
+                                                 (double) new_user->middle,
+                                                 (double) new_user->maximum);
           z_old = _avar2_map_new_mapping (new_mapping, z_old);
           z_old = (double) roundf ((float) (z_old * 16384.0)) / 16384.0;
           if (-1.0 < z_old && z_old < 1.0)
@@ -1050,9 +1050,9 @@
             if (!(-1.0 < z && z < 1.0))
               continue;
             double user = _avar2_denormalize_value (from,
-                                                    new_user->minimum,
-                                                    new_user->middle,
-                                                    new_user->maximum);
+                                                    (double) new_user->minimum,
+                                                    (double) new_user->middle,
+                                                    (double) new_user->maximum);
             double n_old = _avar2_normalize_value (user, old_min, old_def, old_max);
             double x_old = (double) old_seg_maps[i]->map_float ((float) n_old);
             x_old = (double) roundf ((float) (x_old * 16384.0)) / 16384.0;
@@ -1071,17 +1071,17 @@
            * steep retained segment that cannot be reproduced in F2Dot14). */
           unsigned err = _avar2_estimate_offset_error (*old_seg_maps[i], new_mapping,
                                                        old_min, old_def, old_max,
-                                                       new_user->minimum,
-                                                       new_user->middle,
-                                                       new_user->maximum,
+                                                       (double) new_user->minimum,
+                                                       (double) new_user->middle,
+                                                       (double) new_user->maximum,
                                                        knots);
           if (with_breakpoints.length != knots.length)
           {
             unsigned err_with = _avar2_estimate_offset_error (*old_seg_maps[i], new_mapping,
                                                               old_min, old_def, old_max,
-                                                              new_user->minimum,
-                                                              new_user->middle,
-                                                              new_user->maximum,
+                                                              (double) new_user->minimum,
+                                                              (double) new_user->middle,
+                                                              (double) new_user->maximum,
                                                               with_breakpoints);
             if (err_with <= err)
             {
diff --git a/src/hb-ot-var-common.hh b/src/hb-ot-var-common.hh
index 2fc55bf..9f5bdd3 100644
--- a/src/hb-ot-var-common.hh
+++ b/src/hb-ot-var-common.hh
@@ -103,14 +103,14 @@
         start = hb_min (peak, 0.f);
         end = hb_max (peak, 0.f);
       }
-      axis_tuples.set (*axis_tag, Triple ((double) start, (double) peak, (double) end));
+      axis_tuples.set (*axis_tag, Triple (start, peak, end));
     }
 
     return true;
   }
 
   HB_ALWAYS_INLINE
-  double calculate_scalar (hb_array_t<const int> coords, unsigned int coord_count,
+  float calculate_scalar (hb_array_t<const int> coords, unsigned int coord_count,
 			   const hb_array_t<const F2DOT14> shared_tuples,
 			   hb_scalar_cache_t *shared_tuple_scalar_cache = (hb_scalar_cache_t *) &Null(hb_scalar_cache_t)) const
   {
@@ -126,7 +126,7 @@
     {
       float scalar;
       if (likely (shared_tuple_scalar_cache->get (index, &scalar)))
-	return (double) scalar;
+	return scalar;
     }
 
     const F2DOT14 *peak_tuple;
@@ -148,11 +148,11 @@
         if (has_interm && (scalar != 0 && scalar != 1.f))
 	  shared_tuple_scalar_cache = nullptr;
 	else
-	  return (double) scalar;
+	  return scalar;
       }
 
       if (unlikely ((index + 1) * coord_count > shared_tuples.length))
-        return 0.0;
+        return 0.f;
       peak_tuple = shared_tuples.arrayZ + (coord_count * index);
 
     }
@@ -166,7 +166,7 @@
       end_tuple = get_end_tuple (coord_count);
     }
 
-    double scalar = 1.0;
+    float scalar = 1.f;
 #ifndef HB_OPTIMIZE_SIZE
 #if HB_FAST_NUM_ACCESS
     bool skip = coord_count >= 16;
@@ -192,7 +192,7 @@
       if (!peak) continue;
 
       int v = coords[i];
-      if (!v) { scalar = 0.0; break; }
+      if (!v) { scalar = 0.f; break; }
       if (v == peak) continue;
 
       if (has_interm)
@@ -202,15 +202,15 @@
         int end = end_tuple[i].to_int ();
         if (unlikely (start > peak || peak > end ||
                       (start < 0 && end > 0 && peak))) continue;
-        if (v < start || v > end) { scalar = 0.0; break; }
+        if (v < start || v > end) { scalar = 0.f; break; }
         if (v < peak)
-        { if (peak != start) scalar *= (double) (v - start) / (peak - start); }
+        { if (peak != start) scalar *= (float) (v - start) / (peak - start); }
         else
-        { if (peak != end) scalar *= (double) (end - v) / (end - peak); }
+        { if (peak != end) scalar *= (float) (end - v) / (end - peak); }
       }
-      else if (v < hb_min (0, peak) || v > hb_max (0, peak)) { scalar = 0.0; break; }
+      else if (v < hb_min (0, peak) || v > hb_max (0, peak)) { scalar = 0.f; break; }
       else
-        scalar *= (double) v / peak;
+        scalar *= (float) v / peak;
     }
     if (shared_tuple_scalar_cache)
       shared_tuple_scalar_cache->set (index, scalar);
@@ -412,21 +412,21 @@
       return;
     }
 
-    if ((tent->minimum < 0.0 && tent->maximum > 0.0) ||
+    if ((tent->minimum < 0.f && tent->maximum > 0.f) ||
         !(tent->minimum <= tent->middle && tent->middle <= tent->maximum))
       return;
 
-    if (tent->middle == 0.0)
+    if (tent->middle == 0.f)
     {
       out.push (std::move (*this));
       return;
     }
 
     if (!axis_limit.is_point () &&
-        !(-1.0 <= axis_limit.minimum &&
+        !(-1.f <= axis_limit.minimum &&
           axis_limit.minimum <= axis_limit.middle &&
           axis_limit.middle <= axis_limit.maximum &&
-          axis_limit.maximum <= +1.0))
+          axis_limit.maximum <= +1.f))
       return;
 
     rebase_tent_result_t &solutions = scratch.first;
@@ -723,14 +723,14 @@
         {
           i = next_index (i, start_point, end_point);
           if (i == next) break;
-          deltas_x.arrayZ[i] = infer_delta ((double) orig_points.arrayZ[i].x,
-                                            (double) orig_points.arrayZ[prev].x,
-                                            (double) orig_points.arrayZ[next].x,
-                                            (double) deltas_x.arrayZ[prev], (double) deltas_x.arrayZ[next]);
-          deltas_y.arrayZ[i] = infer_delta ((double) orig_points.arrayZ[i].y,
-                                            (double) orig_points.arrayZ[prev].y,
-                                            (double) orig_points.arrayZ[next].y,
-                                            (double) deltas_y.arrayZ[prev], (double) deltas_y.arrayZ[next]);
+          deltas_x.arrayZ[i] = infer_delta (orig_points.arrayZ[i].x,
+                                            orig_points.arrayZ[prev].x,
+                                            orig_points.arrayZ[next].x,
+                                            deltas_x.arrayZ[prev], deltas_x.arrayZ[next]);
+          deltas_y.arrayZ[i] = infer_delta (orig_points.arrayZ[i].y,
+                                            orig_points.arrayZ[prev].y,
+                                            orig_points.arrayZ[next].y,
+                                            deltas_y.arrayZ[prev], deltas_y.arrayZ[next]);
           inferred_idxes.add (i);
           if (--unref_count == 0) goto no_more_gaps;
         }
@@ -747,8 +747,8 @@
       {
         if (!inferred_idxes.has (i))
         {
-          deltas_x.arrayZ[i] = 0.0;
-          deltas_y.arrayZ[i] = 0.0;
+          deltas_x.arrayZ[i] = 0.f;
+          deltas_y.arrayZ[i] = 0.f;
         }
         indices[i] = true;
       }
@@ -919,16 +919,16 @@
     return compiled_points.resize_dirty  (pos);
   }
 
-  static double infer_delta (double target_val, double prev_val, double next_val, double prev_delta, double next_delta)
+  static float infer_delta (float target_val, float prev_val, float next_val, float prev_delta, float next_delta)
   {
     if (prev_val == next_val)
-      return (prev_delta == next_delta) ? prev_delta : 0.0;
+      return (prev_delta == next_delta) ? prev_delta : 0.f;
     else if (target_val <= hb_min (prev_val, next_val))
       return (prev_val < next_val) ? prev_delta : next_delta;
     else if (target_val >= hb_max (prev_val, next_val))
       return (prev_val > next_val) ? prev_delta : next_delta;
 
-    double r = (target_val - prev_val) / (next_val - prev_val);
+    float r = (target_val - prev_val) / (next_val - prev_val);
     return prev_delta + r * (next_delta - prev_delta);
   }
 
@@ -1159,7 +1159,7 @@
         Triple *axis_limit;
         if (!normalized_axes_location.has (axis_tag, &axis_limit))
           return false;
-        TripleDistances axis_triple_distances{1.0, 1.0};
+        TripleDistances axis_triple_distances{1.f, 1.f};
         if (axes_triple_distances.has (axis_tag))
           axis_triple_distances = axes_triple_distances.get (axis_tag);
 
diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh
index 142055c..4f5f2bd 100644
--- a/src/hb-ot-var-fvar-table.hh
+++ b/src/hb-ot-var-fvar-table.hh
@@ -43,7 +43,7 @@
                                                     unsigned axis_index,
                                                     Triple axis_limit)
 {
-  double axis_coord = static_cast<double>(coords[axis_index].to_float ());
+  float axis_coord = coords[axis_index].to_float ();
   if (axis_limit.is_point ())
   {
     if (axis_limit.minimum != axis_coord)
@@ -222,10 +222,7 @@
   {
     float min, default_, max;
     get_coordinates (min, default_, max);
-    return TripleDistances (
-      static_cast<double>(min),
-      static_cast<double>(default_),
-      static_cast<double>(max));
+    return TripleDistances (min, default_, max);
   }
 
   bool subset (hb_subset_context_t *c) const
diff --git a/src/hb-subset-instancer-solver.cc b/src/hb-subset-instancer-solver.cc
index c838240..593c3c3 100644
--- a/src/hb-subset-instancer-solver.cc
+++ b/src/hb-subset-instancer-solver.cc
@@ -32,28 +32,28 @@
  * This should be safe.
  */
 
-constexpr static double EPSILON = 1.0 / (1 << 14);
-constexpr static double MAX_F2DOT14 = double (0x7FFF) / (1 << 14);
+constexpr static float EPSILON = 1.f / (1 << 14);
+constexpr static float MAX_F2DOT14 = float (0x7FFF) / (1 << 14);
 
 static inline Triple _reverse_negate(const Triple &v)
 { return {-v.maximum, -v.middle, -v.minimum}; }
 
 
-static inline double supportScalar (double coord, const Triple &tent)
+static inline float supportScalar (float coord, const Triple &tent)
 {
   /* Copied from VarRegionAxis::evaluate() */
-  double start = tent.minimum, peak = tent.middle, end = tent.maximum;
+  float start = tent.minimum, peak = tent.middle, end = tent.maximum;
 
   if (unlikely (start > peak || peak > end))
-    return 1.;
+    return 1.f;
   if (unlikely (start < 0 && end > 0 && peak != 0))
-    return 1.;
+    return 1.f;
 
   if (peak == 0 || coord == peak)
-    return 1.;
+    return 1.f;
 
   if (coord <= start || end <= coord)
-    return 0.;
+    return 0.f;
 
   /* Interpolate */
   if (coord < peak)
@@ -66,12 +66,12 @@
 _solve (Triple tent, Triple axisLimit, rebase_tent_result_t &out, bool negative = false)
 {
   out.reset();
-  double axisMin = axisLimit.minimum;
-  double axisDef = axisLimit.middle;
-  double axisMax = axisLimit.maximum;
-  double lower = tent.minimum;
-  double peak  = tent.middle;
-  double upper = tent.maximum;
+  float axisMin = axisLimit.minimum;
+  float axisDef = axisLimit.middle;
+  float axisMax = axisLimit.maximum;
+  float lower = tent.minimum;
+  float peak  = tent.middle;
+  float upper = tent.maximum;
 
   // Mirror the problem such that axisDef <= peak
   if (axisDef > peak)
@@ -129,7 +129,7 @@
    */
   if (axisMax < peak)
   {
-    double mult = supportScalar (axisMax, tent);
+    float mult = supportScalar (axisMax, tent);
     tent = Triple{lower, axisMax, axisMax};
 
     _solve (tent, axisLimit, out);
@@ -142,13 +142,13 @@
 
   // lower <= axisDef <= peak <= axisMax
 
-  double gain = supportScalar (axisDef, tent);
+  float gain = supportScalar (axisDef, tent);
   out.push(hb_pair (gain, Triple{}));
 
   // First, the positive side
 
   // outGain is the scalar of axisMax at the tent.
-  double outGain = supportScalar (axisMax, tent);
+  float outGain = supportScalar (axisMax, tent);
 
   /* Case 3a: Gain is more than outGain. The tent down-slope crosses
    * the axis into negative. We have to split it into multiples.
@@ -172,10 +172,10 @@
     // Note that this is the branch taken if both gain and outGain are 0.
 
     // Crossing point on the axis.
-    double crossing = peak + (1 - gain) * (upper - peak);
+    float crossing = peak + (1 - gain) * (upper - peak);
 
     Triple loc{hb_max (lower, axisDef), peak, crossing};
-    double scalar = 1.0;
+    float scalar = 1.f;
 
     // The part before the crossing point.
     out.push (hb_pair (scalar - gain, loc));
@@ -190,7 +190,7 @@
     if (upper >= axisMax)
     {
       Triple loc {crossing, axisMax, axisMax};
-      double scalar = outGain;
+      float scalar = outGain;
 
       out.push (hb_pair (scalar - gain, loc));
     }
@@ -220,11 +220,11 @@
 
       // Downslope.
       Triple loc1 {crossing, upper, axisMax};
-      double scalar1 = 0.0;
+      float scalar1 = 0.f;
 
       // Eternity justify.
       Triple loc2 {upper, axisMax, axisMax};
-      double scalar2 = 0.0;
+      float scalar2 = 0.f;
 
       out.push (hb_pair (scalar1 - gain, loc1));
       out.push (hb_pair (scalar2 - gain, loc2));
@@ -253,7 +253,7 @@
      *                    |      |  newUpper
      *              axisDef      axisMax
      */
-    double newUpper = peak + (1 - gain) * (upper - peak);
+    float newUpper = peak + (1 - gain) * (upper - peak);
     assert (axisMax <= newUpper);  // Because outGain > gain
     /* Disabled because ots doesn't like us:
      * https://github.com/fonttools/fonttools/issues/3350 */
@@ -269,7 +269,7 @@
       }
 
       Triple loc {hb_max (axisDef, lower), peak, upper};
-      double scalar = 1.0;
+      float scalar = 1.f;
 
       out.push (hb_pair (scalar - gain, loc));
     }
@@ -293,10 +293,10 @@
     else
     {
       Triple loc1 {hb_max (axisDef, lower), peak, axisMax};
-      double scalar1 = 1.0;
+      float scalar1 = 1.f;
 
       Triple loc2 {peak, axisMax, axisMax};
-      double scalar2 = outGain;
+      float scalar2 = outGain;
 
       out.push (hb_pair (scalar1 - gain, loc1));
       // Don't add a dirac delta!
@@ -324,7 +324,7 @@
   if (lower <= axisMin)
   {
     Triple loc {axisMin, axisMin, axisDef};
-    double scalar = supportScalar (axisMin, tent);
+    float scalar = supportScalar (axisMin, tent);
 
     out.push (hb_pair (scalar - gain, loc));
   }
@@ -352,11 +352,11 @@
 
     // Downslope.
     Triple loc1 {axisMin, lower, axisDef};
-    double scalar1 = 0.0;
+    float scalar1 = 0.f;
 
     // Eternity justify.
     Triple loc2 {axisMin, axisMin, lower};
-    double scalar2 = 0.0;
+    float scalar2 = 0.f;
 
     out.push (hb_pair (scalar1 - gain, loc1));
     out.push (hb_pair (scalar2 - gain, loc2));
@@ -366,48 +366,48 @@
 static inline TripleDistances _reverse_triple_distances (const TripleDistances &v)
 { return TripleDistances (v.positive, v.negative); }
 
-double renormalizeValue (double v, const Triple &triple,
+float renormalizeValue (float v, const Triple &triple,
                          const TripleDistances &triple_distances, bool extrapolate)
 {
-  double lower = triple.minimum, def = triple.middle, upper = triple.maximum;
+  float lower = triple.minimum, def = triple.middle, upper = triple.maximum;
   if (unlikely (!(lower <= def && def <= upper)))
-    return hb_clamp (v, -1.0, +1.0);
+    return hb_clamp (v, -1.f, +1.f);
 
   if (!extrapolate)
     v = hb_clamp (v, lower, upper);
 
   if (v == def)
-    return 0.0;
+    return 0.f;
 
-  if (def < 0.0)
+  if (def < 0.f)
     return -renormalizeValue (-v, _reverse_negate (triple),
                               _reverse_triple_distances (triple_distances), extrapolate);
 
   /* default >= 0 and v != default */
   if (v > def)
   {
-    double positive_range = upper - def;
+    float positive_range = upper - def;
     if (unlikely (!positive_range))
-      return +1.0;
+      return +1.f;
     return (v - def) / positive_range;
   }
 
   /* v < def */
-  if (lower >= 0.0)
+  if (lower >= 0.f)
   {
-    double negative_range = def - lower;
+    float negative_range = def - lower;
     if (unlikely (!negative_range))
-      return -1.0;
+      return -1.f;
     return (v - def) / negative_range;
   }
 
   /* lower < 0 and v < default */
-  double total_distance = triple_distances.negative * (-lower) + triple_distances.positive * def;
+  float total_distance = triple_distances.negative * (-lower) + triple_distances.positive * def;
   if (unlikely (!total_distance))
-    return 0.0;
+    return 0.f;
 
-  double v_distance;
-  if (v >= 0.0)
+  float v_distance;
+  if (v >= 0.f)
     v_distance = (def - v) * triple_distances.positive;
   else
     v_distance = (-v) * triple_distances.negative + triple_distances.positive * def;
@@ -420,15 +420,15 @@
 	     rebase_tent_result_t &out,
 	     rebase_tent_result_t &scratch)
 {
-  if (unlikely (!(-1.0 <= axisLimit.minimum &&
+  if (unlikely (!(-1.f <= axisLimit.minimum &&
                   axisLimit.minimum <= axisLimit.middle &&
                   axisLimit.middle <= axisLimit.maximum &&
-                  axisLimit.maximum <= +1.0) ||
-                !(-2.0 <= tent.minimum &&
+                  axisLimit.maximum <= +1.f) ||
+                !(-2.f <= tent.minimum &&
                   tent.minimum <= tent.middle &&
                   tent.middle <= tent.maximum &&
-                  tent.maximum <= +2.0) ||
-                tent.middle == 0.0))
+                  tent.maximum <= +2.f) ||
+                tent.middle == 0.f))
   {
     out.reset ();
     return;
@@ -437,7 +437,7 @@
   rebase_tent_result_t &sols = scratch;
   _solve (tent, axisLimit, sols);
 
-  auto n = [&axisLimit, &axis_triple_distances] (double v) { return renormalizeValue (v, axisLimit, axis_triple_distances); };
+  auto n = [&axisLimit, &axis_triple_distances] (float v) { return renormalizeValue (v, axisLimit, axis_triple_distances); };
 
   out.reset();
   for (auto &p : sols)
diff --git a/src/hb-subset-instancer-solver.hh b/src/hb-subset-instancer-solver.hh
index 3462d3c..f7834af 100644
--- a/src/hb-subset-instancer-solver.hh
+++ b/src/hb-subset-instancer-solver.hh
@@ -30,23 +30,23 @@
 /* pre-normalized distances */
 struct TripleDistances
 {
-  TripleDistances (): negative (1.0), positive (1.0) {}
-  TripleDistances (double neg_, double pos_): negative (neg_), positive (pos_) {}
-  TripleDistances (double min, double default_, double max)
+  TripleDistances (): negative (1.f), positive (1.f) {}
+  TripleDistances (float neg_, float pos_): negative (neg_), positive (pos_) {}
+  TripleDistances (float min, float default_, float max)
   {
     negative = default_ - min;
     positive = max - default_;
   }
 
-  double negative;
-  double positive;
+  float negative;
+  float positive;
 };
 
 struct Triple
 {
   Triple () = default;
 
-  Triple (double minimum_, double middle_, double maximum_) :
+  Triple (float minimum_, float middle_, float maximum_) :
     minimum (minimum_), middle (middle_), maximum (maximum_) {}
 
   bool operator == (const Triple &o) const
@@ -62,7 +62,7 @@
   bool is_point () const
   { return minimum == middle && middle == maximum; }
 
-  bool contains (double point) const
+  bool contains (float point) const
   { return minimum <= point && point <= maximum; }
 
   /* from hb_array_t hash ()*/
@@ -80,18 +80,18 @@
     return current;
   }
 
-  double minimum = 0;
-  double middle = 0;
-  double maximum = 0;
+  float minimum = 0;
+  float middle = 0;
+  float maximum = 0;
 };
 
-using rebase_tent_result_item_t = hb_pair_t<double, Triple>;
+using rebase_tent_result_item_t = hb_pair_t<float, Triple>;
 using rebase_tent_result_t = hb_vector_t<rebase_tent_result_item_t>;
 
 /* renormalize a normalized value v to the range of an axis,
  * considering the prenormalized distances as well as the new axis limits.
  * Ported from fonttools */
-HB_INTERNAL double renormalizeValue (double v, const Triple &triple,
+HB_INTERNAL float renormalizeValue (float v, const Triple &triple,
                                     const TripleDistances &triple_distances,
                                     bool extrapolate = true);
 /* Given a tuple (lower,peak,upper) "tent" and new axis limits
diff --git a/src/hb-subset-plan-var.cc b/src/hb-subset-plan-var.cc
index b101a8a..4e71798 100644
--- a/src/hb-subset-plan-var.cc
+++ b/src/hb-subset-plan-var.cc
@@ -60,7 +60,9 @@
  static double
  _tent_eval (const Triple &tent, double v)
  {
-   double start = tent.minimum, peak = tent.middle, end = tent.maximum;
+   double start = (double) tent.minimum;
+   double peak = (double) tent.middle;
+   double end = (double) tent.maximum;
    if (unlikely (start > peak || peak > end)) return 1.0;
    if (unlikely (start < 0.0 && end > 0.0 && peak != 0.0)) return 1.0;
    if (peak == 0.0 || v == peak) return 1.0;
@@ -80,7 +82,7 @@
    double b = _tent_eval (tent, hi);
    *tmin = hb_min (a, b);
    *tmax = hb_max (a, b);
-   if (lo <= tent.middle && tent.middle <= hi)
+   if (lo <= (double) tent.middle && (double) tent.middle <= hi)
      *tmax = hb_max (*tmax, 1.0);
  }
 
@@ -118,8 +120,8 @@
      if (plan->user_axes_location.has (tag))
      {
        if (!plan->old_intermediates.has (tag, &old_int)) return false;
-       lo = old_int->minimum;
-       hi = old_int->maximum;
+       lo = (double) old_int->minimum;
+       hi = (double) old_int->maximum;
      }
      else if (axis.is_hidden ())
        lo = hi = 0.0; /* private axis: intermediate is always 0 */
@@ -214,17 +216,17 @@
        {
 	 const Triple &tent = _.second;
 	 /* Tents the runtime ignores (constant scalar 1) add no breakpoints. */
-	 if (tent.middle == 0.0 ||
+	 if (tent.middle == 0.f ||
 	     tent.minimum > tent.middle || tent.middle > tent.maximum ||
-	     (tent.minimum < 0.0 && tent.maximum > 0.0))
+	     (tent.minimum < 0.f && tent.maximum > 0.f))
 	   continue;
 	 int pos = add_grid_axis (_.first);
 	 if (pos < 0) return false;
 	 auto &points = grid_points[pos];
 	 double blo = points[0], bhi = points[1];
-	 points.push (hb_clamp (tent.minimum, blo, bhi));
-	 points.push (hb_clamp (tent.middle, blo, bhi));
-	 points.push (hb_clamp (tent.maximum, blo, bhi));
+	 points.push (hb_clamp ((double) tent.minimum, blo, bhi));
+	 points.push (hb_clamp ((double) tent.middle, blo, bhi));
+	 points.push (hb_clamp ((double) tent.maximum, blo, bhi));
 	 tents.push (hb_pair ((unsigned) pos, tent));
 	 if (points.in_error () || tents.in_error ()) return false;
        }
@@ -472,9 +474,9 @@
     float minimum, middle, maximum;
     axis.get_coordinates (minimum, middle, maximum);
     if (plan->user_axes_location.has (tag, &range) && !range->is_point () &&
-        range->minimum == static_cast<double> (minimum) &&
-        range->middle == static_cast<double> (middle) &&
-        range->maximum == static_cast<double> (maximum))
+        range->minimum == minimum &&
+        range->middle == middle &&
+        range->maximum == maximum)
       plan->user_axes_location.del (tag);
   }
   if (plan->user_axes_location.is_empty ())
diff --git a/src/test-subset-instancer-solver.cc b/src/test-subset-instancer-solver.cc
index 2ebf900..fd9cf34 100644
--- a/src/test-subset-instancer-solver.cc
+++ b/src/test-subset-instancer-solver.cc
@@ -29,25 +29,25 @@
 
 static inline bool approx (Triple a, Triple b)
 {
-  return abs (a.minimum - b.minimum) < 0.000001 &&
-         abs (a.middle - b.middle) < 0.000001 &&
-         abs (a.maximum - b.maximum) < 0.000001;
+  return abs (a.minimum - b.minimum) < 0.000001f &&
+         abs (a.middle - b.middle) < 0.000001f &&
+         abs (a.maximum - b.maximum) < 0.000001f;
 }
 
-static inline bool approx (double a, double b)
-{ return abs (a - b) < 0.000001; }
+static inline bool approx (float a, float b)
+{ return abs (a - b) < 0.000001f; }
 
 /* tests ported from
  * https://github.com/fonttools/fonttools/blob/main/Tests/varLib/instancer/solver_test.py */
 int
 main (int argc, char **argv)
 {
-  TripleDistances default_axis_distances{1.0, 1.0};
+  TripleDistances default_axis_distances{1.0f, 1.0f};
   /* Case 1 */
   {
     /* pin axis*/
-    Triple tent (0.0, 1.0, 1.0);
-    Triple axis_range (0.0, 0.0, 0.0);
+    Triple tent (0.0f, 1.0f, 1.0f);
+    Triple axis_range (0.0f, 0.0f, 0.0f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 0);
@@ -55,19 +55,19 @@
 
   {
     /* pin axis*/
-    Triple tent (0.0, 1.0, 1.0);
-    Triple axis_range (0.5, 0.5, 0.5);
+    Triple tent (0.0f, 1.0f, 1.0f);
+    Triple axis_range (0.5f, 0.5f, 0.5f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 1);
-    hb_always_assert (out[0].first == 0.5);
+    hb_always_assert (out[0].first == 0.5f);
     hb_always_assert (out[0].second == Triple ());
   }
 
   {
     /* tent falls outside the new axis range */
-    Triple tent (0.3, 0.5, 0.8);
-    Triple axis_range (0.1, 0.2, 0.3);
+    Triple tent (0.3f, 0.5f, 0.8f);
+    Triple axis_range (0.1f, 0.2f, 0.3f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 0);
@@ -75,8 +75,8 @@
 
   {
     /* malformed axis range should be rejected, not abort */
-    Triple tent (0.3, 0.5, 0.8);
-    Triple axis_range (0.4, 0.2, 0.3);
+    Triple tent (0.3f, 0.5f, 0.8f);
+    Triple axis_range (0.4f, 0.2f, 0.3f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 0);
@@ -84,396 +84,396 @@
 
   {
     /* malformed triple should not abort in renormalization */
-    Triple malformed_range (0.4, 0.2, 0.3);
-    double normalized = renormalizeValue (0.25, malformed_range, default_axis_distances, true);
-    hb_always_assert (approx (normalized, 0.25));
+    Triple malformed_range (0.4f, 0.2f, 0.3f);
+    float normalized = renormalizeValue (0.25f, malformed_range, default_axis_distances, true);
+    hb_always_assert (approx (normalized, 0.25f));
   }
 
   /* Case 2 */
   {
-    Triple tent (0.0, 1.0, 1.0);
-    Triple axis_range (-1.0, 0.0, 0.5);
+    Triple tent (0.0f, 1.0f, 1.0f);
+    Triple axis_range (-1.0f, 0.0f, 0.5f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 1);
-    hb_always_assert (out[0].first == 0.5);
-    hb_always_assert (out[0].second == Triple (0.0, 1.0, 1.0));
+    hb_always_assert (out[0].first == 0.5f);
+    hb_always_assert (out[0].second == Triple (0.0f, 1.0f, 1.0f));
   }
 
   /* Case 2 */
   {
-    Triple tent (0.0, 1.0, 1.0);
-    Triple axis_range (-1.0, 0.0, 0.75);
+    Triple tent (0.0f, 1.0f, 1.0f);
+    Triple axis_range (-1.0f, 0.0f, 0.75f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 1);
-    hb_always_assert (out[0].first == 0.75);
-    hb_always_assert (out[0].second == Triple (0.0, 1.0, 1.0));
+    hb_always_assert (out[0].first == 0.75f);
+    hb_always_assert (out[0].second == Triple (0.0f, 1.0f, 1.0f));
   }
 
   /* Without gain: */
   /* Case 3 */
   {
-    Triple tent (0.0, 0.2, 1.0);
-    Triple axis_range (-1.0, 0.0, 0.8);
+    Triple tent (0.0f, 0.2f, 1.0f);
+    Triple axis_range (-1.0f, 0.0f, 0.8f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 2);
-    hb_always_assert (out[0].first == 1.0);
-    hb_always_assert (out[0].second == Triple (0.0, 0.25, 1.0));
-    hb_always_assert (approx (out[1].first, 0.250));
-    hb_always_assert (out[1].second == Triple (0.25, 1.0, 1.0));
+    hb_always_assert (out[0].first == 1.0f);
+    hb_always_assert (out[0].second == Triple (0.0f, 0.25f, 1.0f));
+    hb_always_assert (approx (out[1].first, 0.250f));
+    hb_always_assert (out[1].second == Triple (0.25f, 1.0f, 1.0f));
   }
 
   /* Case 3 boundary */
   {
-    Triple tent (0.0, 0.4, 1.0);
-    Triple axis_range (-1.0, 0.0, 0.5);
+    Triple tent (0.0f, 0.4f, 1.0f);
+    Triple axis_range (-1.0f, 0.0f, 0.5f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 2);
-    hb_always_assert (out[0].first == 1.0);
-    hb_always_assert (out[0].second == Triple (0.0, 0.8, 1.0));
-    hb_always_assert (approx (out[1].first, 2.5/3));
-    hb_always_assert (out[1].second == Triple (0.8, 1.0, 1.0));
+    hb_always_assert (out[0].first == 1.0f);
+    hb_always_assert (out[0].second == Triple (0.0f, 0.8f, 1.0f));
+    hb_always_assert (approx (out[1].first, 2.5f/3));
+    hb_always_assert (out[1].second == Triple (0.8f, 1.0f, 1.0f));
   }
 
   /* Case 4 */
   {
-    Triple tent (0.0, 0.25, 1.0);
-    Triple axis_range (-1.0, 0.0, 0.4);
+    Triple tent (0.0f, 0.25f, 1.0f);
+    Triple axis_range (-1.0f, 0.0f, 0.4f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 2);
-    hb_always_assert (out[0].first == 1.0);
-    hb_always_assert (out[0].second == Triple (0.0, 0.625, 1.0));
-    hb_always_assert (approx (out[1].first, 0.80));
-    hb_always_assert (out[1].second == Triple (0.625, 1.0, 1.0));
+    hb_always_assert (out[0].first == 1.0f);
+    hb_always_assert (out[0].second == Triple (0.0f, 0.625f, 1.0f));
+    hb_always_assert (approx (out[1].first, 0.80f));
+    hb_always_assert (out[1].second == Triple (0.625f, 1.0f, 1.0f));
   }
 
   /* Case 4 */
   {
-    Triple tent (0.25, 0.3, 1.05);
-    Triple axis_range (0.0, 0.2, 0.4);
+    Triple tent (0.25f, 0.3f, 1.05f);
+    Triple axis_range (0.0f, 0.2f, 0.4f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 2);
-    hb_always_assert (out[0].first == 1.0);
-    hb_always_assert (approx (out[0].second, Triple (0.25, 0.5, 1.0)));
-    hb_always_assert (approx (out[1].first, 2.6 / 3));
-    hb_always_assert (approx (out[1].second, Triple (0.5, 1.0, 1.0)));
+    hb_always_assert (out[0].first == 1.0f);
+    hb_always_assert (approx (out[0].second, Triple (0.25f, 0.5f, 1.0f)));
+    hb_always_assert (approx (out[1].first, 2.6f / 3));
+    hb_always_assert (approx (out[1].second, Triple (0.5f, 1.0f, 1.0f)));
   }
 
   /* Case 4 boundary */
   {
-    Triple tent (0.25, 0.5, 1.0);
-    Triple axis_range (0.0, 0.25, 0.5);
+    Triple tent (0.25f, 0.5f, 1.0f);
+    Triple axis_range (0.0f, 0.25f, 0.5f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 1);
-    hb_always_assert (out[0].first == 1.0);
-    hb_always_assert (out[0].second == Triple (0.0, 1.0, 1.0));
+    hb_always_assert (out[0].first == 1.0f);
+    hb_always_assert (out[0].second == Triple (0.0f, 1.0f, 1.0f));
   }
 
   /* With gain */
   /* Case 3a/1neg */
   {
-    Triple tent (0.0, 0.5, 1.0);
-    Triple axis_range (0.0, 0.5, 1.0);
+    Triple tent (0.0f, 0.5f, 1.0f);
+    Triple axis_range (0.0f, 0.5f, 1.0f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 3);
-    hb_always_assert (out[0].first == 1.0);
+    hb_always_assert (out[0].first == 1.0f);
     hb_always_assert (out[0].second == Triple ());
-    hb_always_assert (out[1].first == -1.0);
-    hb_always_assert (out[1].second == Triple (0.0, 1.0, 1.0));
-    hb_always_assert (out[2].first == -1.0);
-    hb_always_assert (out[2].second == Triple (-1.0, -1.0, 0.0));
+    hb_always_assert (out[1].first == -1.0f);
+    hb_always_assert (out[1].second == Triple (0.0f, 1.0f, 1.0f));
+    hb_always_assert (out[2].first == -1.0f);
+    hb_always_assert (out[2].second == Triple (-1.0f, -1.0f, 0.0f));
   }
 
   {
-    Triple tent (0.0, 0.5, 1.0);
-    Triple axis_range (0.0, 0.5, 0.75);
+    Triple tent (0.0f, 0.5f, 1.0f);
+    Triple axis_range (0.0f, 0.5f, 0.75f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 3);
-    hb_always_assert (out[0].first == 1.0);
+    hb_always_assert (out[0].first == 1.0f);
     hb_always_assert (out[0].second == Triple ());
-    hb_always_assert (out[1].first == -0.5);
-    hb_always_assert (out[1].second == Triple (0.0, 1.0, 1.0));
-    hb_always_assert (out[2].first == -1.0);
-    hb_always_assert (out[2].second == Triple (-1.0, -1.0, 0.0));
+    hb_always_assert (out[1].first == -0.5f);
+    hb_always_assert (out[1].second == Triple (0.0f, 1.0f, 1.0f));
+    hb_always_assert (out[2].first == -1.0f);
+    hb_always_assert (out[2].second == Triple (-1.0f, -1.0f, 0.0f));
   }
 
   {
-    Triple tent (0.0, 0.50, 1.0);
-    Triple axis_range (0.0, 0.25, 0.8);
+    Triple tent (0.0f, 0.50f, 1.0f);
+    Triple axis_range (0.0f, 0.25f, 0.8f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 4);
-    hb_always_assert (out[0].first == 0.5);
+    hb_always_assert (out[0].first == 0.5f);
     hb_always_assert (out[0].second == Triple ());
-    hb_always_assert (out[1].first == 0.5);
-    hb_always_assert (approx (out[1].second, Triple (0.0, 0.454545, 0.909091)));
-    hb_always_assert (approx (out[2].first, -0.1));
-    hb_always_assert (approx (out[2].second, Triple (0.909091, 1.0, 1.0)));
-    hb_always_assert (out[3].first == -0.5);
-    hb_always_assert (out[3].second == Triple (-1.0, -1.0, 0.0));
+    hb_always_assert (out[1].first == 0.5f);
+    hb_always_assert (approx (out[1].second, Triple (0.0f, 0.454545f, 0.909091f)));
+    hb_always_assert (approx (out[2].first, -0.1f));
+    hb_always_assert (approx (out[2].second, Triple (0.909091f, 1.0f, 1.0f)));
+    hb_always_assert (out[3].first == -0.5f);
+    hb_always_assert (out[3].second == Triple (-1.0f, -1.0f, 0.0f));
   }
 
   /* Case 3a/1neg */
   {
-    Triple tent (0.0, 0.5, 2.0);
-    Triple axis_range (0.2, 0.5, 0.8);
+    Triple tent (0.0f, 0.5f, 2.0f);
+    Triple axis_range (0.2f, 0.5f, 0.8f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 3);
-    hb_always_assert (out[0].first == 1.0);
+    hb_always_assert (out[0].first == 1.0f);
     hb_always_assert (out[0].second == Triple ());
-    hb_always_assert (approx (out[1].first, -0.2));
-    hb_always_assert (out[1].second == Triple (0.0, 1.0, 1.0));
-    hb_always_assert (approx (out[2].first, -0.6));
-    hb_always_assert (out[2].second == Triple (-1.0, -1.0, 0.0));
+    hb_always_assert (approx (out[1].first, -0.2f));
+    hb_always_assert (out[1].second == Triple (0.0f, 1.0f, 1.0f));
+    hb_always_assert (approx (out[2].first, -0.6f));
+    hb_always_assert (approx (out[2].second, Triple (-1.0f, -1.0f, 0.0f)));
   }
 
   /* Case 3a/1neg */
   {
-    Triple tent (0.0, 0.5, 2.0);
-    Triple axis_range (0.2, 0.5, 1.0);
+    Triple tent (0.0f, 0.5f, 2.0f);
+    Triple axis_range (0.2f, 0.5f, 1.0f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 3);
-    hb_always_assert (out[0].first == 1.0);
+    hb_always_assert (out[0].first == 1.0f);
     hb_always_assert (out[0].second == Triple ());
-    hb_always_assert (approx (out[1].first, -1.0/3));
-    hb_always_assert (out[1].second == Triple (0.0, 1.0, 1.0));
-    hb_always_assert (approx (out[2].first, -0.6));
-    hb_always_assert (out[2].second == Triple (-1.0, -1.0, 0.0));
+    hb_always_assert (approx (out[1].first, -1.0f/3));
+    hb_always_assert (out[1].second == Triple (0.0f, 1.0f, 1.0f));
+    hb_always_assert (approx (out[2].first, -0.6f));
+    hb_always_assert (approx (out[2].second, Triple (-1.0f, -1.0f, 0.0f)));
   }
 
   /* Case 3 */
   {
-    Triple tent (0.0, 0.5, 1.0);
-    Triple axis_range (0.25, 0.25, 0.75);
+    Triple tent (0.0f, 0.5f, 1.0f);
+    Triple axis_range (0.25f, 0.25f, 0.75f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 2);
-    hb_always_assert (out[0].first == 0.5);
+    hb_always_assert (out[0].first == 0.5f);
     hb_always_assert (out[0].second == Triple ());
-    hb_always_assert (out[1].first == 0.5);
-    hb_always_assert (out[1].second == Triple (0.0, 0.5, 1.0));
+    hb_always_assert (out[1].first == 0.5f);
+    hb_always_assert (out[1].second == Triple (0.0f, 0.5f, 1.0f));
   }
 
   /* Case 1neg */
   {
-    Triple tent (0.0, 0.5, 1.0);
-    Triple axis_range (0.0, 0.25, 0.5);
+    Triple tent (0.0f, 0.5f, 1.0f);
+    Triple axis_range (0.0f, 0.25f, 0.5f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 3);
-    hb_always_assert (out[0].first == 0.5);
+    hb_always_assert (out[0].first == 0.5f);
     hb_always_assert (out[0].second == Triple ());
-    hb_always_assert (out[1].first == 0.5);
-    hb_always_assert (out[1].second == Triple (0.0, 1.0, 1.0));
-    hb_always_assert (out[2].first == -0.5);
-    hb_always_assert (out[2].second == Triple (-1.0, -1.0, 0.0));
+    hb_always_assert (out[1].first == 0.5f);
+    hb_always_assert (out[1].second == Triple (0.0f, 1.0f, 1.0f));
+    hb_always_assert (out[2].first == -0.5f);
+    hb_always_assert (out[2].second == Triple (-1.0f, -1.0f, 0.0f));
   }
 
   /* Case 2neg */
   {
-    Triple tent (0.05, 0.55, 1.0);
-    Triple axis_range (0.0, 0.25, 0.5);
+    Triple tent (0.05f, 0.55f, 1.0f);
+    Triple axis_range (0.0f, 0.25f, 0.5f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 4);
-    hb_always_assert (approx (out[0].first, 0.4));
+    hb_always_assert (approx (out[0].first, 0.4f));
     hb_always_assert (out[0].second == Triple ());
-    hb_always_assert (approx (out[1].first, 0.5));
-    hb_always_assert (out[1].second == Triple (0.0, 1.0, 1.0));
-    hb_always_assert (approx (out[2].first, -0.4));
-    hb_always_assert (out[2].second == Triple (-1.0, -0.8, 0.0));
-    hb_always_assert (approx (out[3].first, -0.4));
-    hb_always_assert (out[3].second == Triple (-1.0, -1.0, -0.8));
+    hb_always_assert (approx (out[1].first, 0.5f));
+    hb_always_assert (out[1].second == Triple (0.0f, 1.0f, 1.0f));
+    hb_always_assert (approx (out[2].first, -0.4f));
+    hb_always_assert (out[2].second == Triple (-1.0f, -0.8f, 0.0f));
+    hb_always_assert (approx (out[3].first, -0.4f));
+    hb_always_assert (out[3].second == Triple (-1.0f, -1.0f, -0.8f));
   }
 
   /* Case 2neg, other side */
   {
-    Triple tent (-1.0, -0.55, -0.05);
-    Triple axis_range (-0.5, -0.25, 0.0);
+    Triple tent (-1.0f, -0.55f, -0.05f);
+    Triple axis_range (-0.5f, -0.25f, 0.0f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 4);
-    hb_always_assert (approx (out[0].first, 0.4));
+    hb_always_assert (approx (out[0].first, 0.4f));
     hb_always_assert (out[0].second == Triple ());
-    hb_always_assert (approx (out[1].first, 0.5));
-    hb_always_assert (out[1].second == Triple (-1.0, -1.0, 0.0));
-    hb_always_assert (approx (out[2].first, -0.4));
-    hb_always_assert (out[2].second == Triple (0.0, 0.8, 1.0));
-    hb_always_assert (approx (out[3].first, -0.4));
-    hb_always_assert (out[3].second == Triple (0.8, 1.0, 1.0));
+    hb_always_assert (approx (out[1].first, 0.5f));
+    hb_always_assert (out[1].second == Triple (-1.0f, -1.0f, 0.0f));
+    hb_always_assert (approx (out[2].first, -0.4f));
+    hb_always_assert (out[2].second == Triple (0.0f, 0.8f, 1.0f));
+    hb_always_assert (approx (out[3].first, -0.4f));
+    hb_always_assert (out[3].second == Triple (0.8f, 1.0f, 1.0f));
   }
 
   /* Misc corner cases */
   {
-    Triple tent (0.5, 0.5, 0.5);
-    Triple axis_range (0.5, 0.5, 0.5);
+    Triple tent (0.5f, 0.5f, 0.5f);
+    Triple axis_range (0.5f, 0.5f, 0.5f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 1);
-    hb_always_assert (out[0].first == 1.0);
+    hb_always_assert (out[0].first == 1.0f);
     hb_always_assert (out[0].second == Triple ());
   }
 
   {
-    Triple tent (0.3, 0.5, 0.7);
-    Triple axis_range (0.1, 0.5, 0.9);
+    Triple tent (0.3f, 0.5f, 0.7f);
+    Triple axis_range (0.1f, 0.5f, 0.9f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 5);
-    hb_always_assert (out[0].first == 1.0);
+    hb_always_assert (out[0].first == 1.0f);
     hb_always_assert (out[0].second == Triple ());
-    hb_always_assert (out[1].first == -1.0);
-    hb_always_assert (approx(out[1].second, Triple (0.0, 0.5, 1.0)));
-    hb_always_assert (out[2].first == -1.0);
-    hb_always_assert (approx(out[2].second, Triple (0.5, 1.0, 1.0)));
-    hb_always_assert (out[3].first == -1.0);
-    hb_always_assert (approx (out[3].second, Triple (-1.0, -0.5, 0.0)));
-    hb_always_assert (out[4].first == -1.0);
-    hb_always_assert (approx (out[4].second, Triple (-1.0, -1.0, -0.5)));
+    hb_always_assert (out[1].first == -1.0f);
+    hb_always_assert (approx(out[1].second, Triple (0.0f, 0.5f, 1.0f)));
+    hb_always_assert (out[2].first == -1.0f);
+    hb_always_assert (approx(out[2].second, Triple (0.5f, 1.0f, 1.0f)));
+    hb_always_assert (out[3].first == -1.0f);
+    hb_always_assert (approx (out[3].second, Triple (-1.0f, -0.5f, 0.0f)));
+    hb_always_assert (out[4].first == -1.0f);
+    hb_always_assert (approx (out[4].second, Triple (-1.0f, -1.0f, -0.5f)));
   }
 
   {
-    Triple tent (0.5, 0.5, 0.5);
-    Triple axis_range (0.25, 0.25, 0.5);
+    Triple tent (0.5f, 0.5f, 0.5f);
+    Triple axis_range (0.25f, 0.25f, 0.5f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 1);
-    hb_always_assert (out[0].first == 1.0);
-    hb_always_assert (out[0].second == Triple (1.0, 1.0, 1.0));
+    hb_always_assert (out[0].first == 1.0f);
+    hb_always_assert (out[0].second == Triple (1.0f, 1.0f, 1.0f));
   }
 
   {
-    Triple tent (0.5, 0.5, 0.5);
-    Triple axis_range (0.25, 0.35, 0.5);
+    Triple tent (0.5f, 0.5f, 0.5f);
+    Triple axis_range (0.25f, 0.35f, 0.5f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 1);
-    hb_always_assert (out[0].first == 1.0);
-    hb_always_assert (out[0].second == Triple (1.0, 1.0, 1.0));
+    hb_always_assert (out[0].first == 1.0f);
+    hb_always_assert (out[0].second == Triple (1.0f, 1.0f, 1.0f));
   }
 
   {
-    Triple tent (0.5, 0.5, 0.55);
-    Triple axis_range (0.25, 0.35, 0.5);
+    Triple tent (0.5f, 0.5f, 0.55f);
+    Triple axis_range (0.25f, 0.35f, 0.5f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 1);
-    hb_always_assert (out[0].first == 1.0);
-    hb_always_assert (out[0].second == Triple (1.0, 1.0, 1.0));
+    hb_always_assert (out[0].first == 1.0f);
+    hb_always_assert (out[0].second == Triple (1.0f, 1.0f, 1.0f));
   }
 
   {
-    Triple tent (0.5, 0.5, 1.0);
-    Triple axis_range (0.5, 0.5, 1.0);
+    Triple tent (0.5f, 0.5f, 1.0f);
+    Triple axis_range (0.5f, 0.5f, 1.0f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 2);
-    hb_always_assert (out[0].first == 1.0);
+    hb_always_assert (out[0].first == 1.0f);
     hb_always_assert (out[0].second == Triple ());
-    hb_always_assert (out[1].first == -1.0);
-    hb_always_assert (out[1].second == Triple (0.0, 1.0, 1.0));
+    hb_always_assert (out[1].first == -1.0f);
+    hb_always_assert (out[1].second == Triple (0.0f, 1.0f, 1.0f));
   }
 
   {
-    Triple tent (0.25, 0.5, 1.0);
-    Triple axis_range (0.5, 0.5, 1.0);
+    Triple tent (0.25f, 0.5f, 1.0f);
+    Triple axis_range (0.5f, 0.5f, 1.0f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 2);
-    hb_always_assert (out[0].first == 1.0);
+    hb_always_assert (out[0].first == 1.0f);
     hb_always_assert (out[0].second == Triple ());
-    hb_always_assert (out[1].first == -1.0);
-    hb_always_assert (out[1].second == Triple (0.0, 1.0, 1.0));
+    hb_always_assert (out[1].first == -1.0f);
+    hb_always_assert (out[1].second == Triple (0.0f, 1.0f, 1.0f));
   }
 
   {
-    Triple tent (0.0, 0.2, 1.0);
-    Triple axis_range (0.0, 0.0, 0.5);
+    Triple tent (0.0f, 0.2f, 1.0f);
+    Triple axis_range (0.0f, 0.0f, 0.5f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 2);
-    hb_always_assert (out[0].first == 1.0);
-    hb_always_assert (out[0].second == Triple (0.0, 0.4, 1.0));
-    hb_always_assert (out[1].first == 0.625);
-    hb_always_assert (out[1].second == Triple (0.4, 1.0, 1.0));
+    hb_always_assert (out[0].first == 1.0f);
+    hb_always_assert (out[0].second == Triple (0.0f, 0.4f, 1.0f));
+    hb_always_assert (out[1].first == 0.625f);
+    hb_always_assert (out[1].second == Triple (0.4f, 1.0f, 1.0f));
   }
 
 
   {
-    Triple tent (0.0, 0.5, 1.0);
-    Triple axis_range (-1.0, 0.25, 1.0);
+    Triple tent (0.0f, 0.5f, 1.0f);
+    Triple axis_range (-1.0f, 0.25f, 1.0f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 5);
-    hb_always_assert (out[0].first == 0.5);
+    hb_always_assert (out[0].first == 0.5f);
     hb_always_assert (out[0].second == Triple ());
-    hb_always_assert (out[1].first == 0.5);
-    hb_always_assert (out[1].second == Triple (0.0, 1.0/3, 2.0/3));
-    hb_always_assert (out[2].first == -0.5);
-    hb_always_assert (out[2].second == Triple (2.0/3, 1.0, 1.0));
-    hb_always_assert (out[3].first == -0.5);
-    hb_always_assert (out[3].second == Triple (-1.0, -0.2, 0.0));
-    hb_always_assert (out[4].first == -0.5);
-    hb_always_assert (out[4].second == Triple (-1.0, -1.0, -0.2));
+    hb_always_assert (out[1].first == 0.5f);
+    hb_always_assert (out[1].second == Triple (0.0f, 1.0f/3, 2.0f/3));
+    hb_always_assert (out[2].first == -0.5f);
+    hb_always_assert (out[2].second == Triple (2.0f/3, 1.0f, 1.0f));
+    hb_always_assert (out[3].first == -0.5f);
+    hb_always_assert (out[3].second == Triple (-1.0f, -0.2f, 0.0f));
+    hb_always_assert (out[4].first == -0.5f);
+    hb_always_assert (out[4].second == Triple (-1.0f, -1.0f, -0.2f));
   }
 
   {
-    Triple tent (0.5, 0.5, 0.5);
-    Triple axis_range (0.0, 0.5, 1.0);
+    Triple tent (0.5f, 0.5f, 0.5f);
+    Triple axis_range (0.0f, 0.5f, 1.0f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 5);
-    hb_always_assert (out[0].first == 1.0);
+    hb_always_assert (out[0].first == 1.0f);
     hb_always_assert (out[0].second == Triple ());
-    hb_always_assert (out[1].first == -1.0);
-    hb_always_assert (out[1].second == Triple (0.0, 2/(double) (1 << 14), 1.0));
-    hb_always_assert (out[2].first == -1.0);
-    hb_always_assert (out[2].second == Triple (2/(double) (1 << 14), 1.0, 1.0));
-    hb_always_assert (out[3].first == -1.0);
-    hb_always_assert (out[3].second == Triple (-1.0, -2/(double) (1 << 14), 0.0));
-    hb_always_assert (out[4].first == -1.0);
-    hb_always_assert (out[4].second == Triple (-1.0, -1.0, -2/(double) (1 << 14)));
+    hb_always_assert (out[1].first == -1.0f);
+    hb_always_assert (out[1].second == Triple (0.0f, 2/(double) (1 << 14), 1.0f));
+    hb_always_assert (out[2].first == -1.0f);
+    hb_always_assert (out[2].second == Triple (2/(double) (1 << 14), 1.0f, 1.0f));
+    hb_always_assert (out[3].first == -1.0f);
+    hb_always_assert (out[3].second == Triple (-1.0f, -2/(double) (1 << 14), 0.0f));
+    hb_always_assert (out[4].first == -1.0f);
+    hb_always_assert (out[4].second == Triple (-1.0f, -1.0f, -2/(double) (1 << 14)));
   }
 
   {
-    Triple tent (0.0, 1.0, 1.0);
-    Triple axis_range (-1.0, -0.5, 1.0);
+    Triple tent (0.0f, 1.0f, 1.0f);
+    Triple axis_range (-1.0f, -0.5f, 1.0f);
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, default_axis_distances, out, scratch);
     hb_always_assert (out.length == 1);
-    hb_always_assert (out[0].first == 1.0);
-    hb_always_assert (out[0].second == Triple (1.0/3, 1.0, 1.0));
+    hb_always_assert (out[0].first == 1.0f);
+    hb_always_assert (out[0].second == Triple (1.0f/3, 1.0f, 1.0f));
   }
 
   {
-    Triple tent (0.0, 1.0, 1.0);
-    Triple axis_range (-1.0, -0.5, 1.0);
-    TripleDistances axis_distances{2.0, 1.0};
+    Triple tent (0.0f, 1.0f, 1.0f);
+    Triple axis_range (-1.0f, -0.5f, 1.0f);
+    TripleDistances axis_distances{2.0f, 1.0f};
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, axis_distances, out, scratch);
     hb_always_assert (out.length == 1);
-    hb_always_assert (out[0].first == 1.0);
-    hb_always_assert (out[0].second == Triple (0.5, 1.0, 1.0));
+    hb_always_assert (out[0].first == 1.0f);
+    hb_always_assert (out[0].second == Triple (0.5f, 1.0f, 1.0f));
   }
 
   {
-    Triple tent (0.6, 0.7, 0.8);
-    Triple axis_range (-1.0, 0.2, 1.0);
-    TripleDistances axis_distances{1.0, 1.0};
+    Triple tent (0.6f, 0.7f, 0.8f);
+    Triple axis_range (-1.0f, 0.2f, 1.0f);
+    TripleDistances axis_distances{1.0f, 1.0f};
     rebase_tent_result_t out, scratch;
     rebase_tent (tent, axis_range, axis_distances, out, scratch);
     hb_always_assert (out.length == 1);
-    hb_always_assert (out[0].first == 1.0);
-    hb_always_assert (approx (out[0].second, Triple (0.5, 0.625, 0.75)));
+    hb_always_assert (out[0].first == 1.0f);
+    hb_always_assert (approx (out[0].second, Triple (0.5f, 0.625f, 0.75f)));
   }
 }
diff --git a/test/subset/data/expected/instantiate_cff2_partial/AdobeVFPrototype.default.41,42,43.wght=300-500-700,CNTR=25-75.otf b/test/subset/data/expected/instantiate_cff2_partial/AdobeVFPrototype.default.41,42,43.wght=300-500-700,CNTR=25-75.otf
index d59b75d..5c91a9b 100644
--- a/test/subset/data/expected/instantiate_cff2_partial/AdobeVFPrototype.default.41,42,43.wght=300-500-700,CNTR=25-75.otf
+++ b/test/subset/data/expected/instantiate_cff2_partial/AdobeVFPrototype.default.41,42,43.wght=300-500-700,CNTR=25-75.otf
Binary files differ
diff --git a/test/subset/data/expected/instantiate_cff2_partial/AdobeVFPrototype.default.all.wght=300-500-700,CNTR=25-75.otf b/test/subset/data/expected/instantiate_cff2_partial/AdobeVFPrototype.default.all.wght=300-500-700,CNTR=25-75.otf
index 9d54125..801b6ec 100644
--- a/test/subset/data/expected/instantiate_cff2_partial/AdobeVFPrototype.default.all.wght=300-500-700,CNTR=25-75.otf
+++ b/test/subset/data/expected/instantiate_cff2_partial/AdobeVFPrototype.default.all.wght=300-500-700,CNTR=25-75.otf
Binary files differ
diff --git a/test/subset/data/expected/instantiate_cff2_partial/AdobeVFPrototype_vsindex.default.41,42,43.wght=300-500-700,CNTR=25-75.otf b/test/subset/data/expected/instantiate_cff2_partial/AdobeVFPrototype_vsindex.default.41,42,43.wght=300-500-700,CNTR=25-75.otf
index b7b353a..86131a8 100644
--- a/test/subset/data/expected/instantiate_cff2_partial/AdobeVFPrototype_vsindex.default.41,42,43.wght=300-500-700,CNTR=25-75.otf
+++ b/test/subset/data/expected/instantiate_cff2_partial/AdobeVFPrototype_vsindex.default.41,42,43.wght=300-500-700,CNTR=25-75.otf
Binary files differ
diff --git a/test/subset/data/expected/instantiate_cff2_partial/AdobeVFPrototype_vsindex.default.all.wght=300-500-700,CNTR=25-75.otf b/test/subset/data/expected/instantiate_cff2_partial/AdobeVFPrototype_vsindex.default.all.wght=300-500-700,CNTR=25-75.otf
index b7b353a..86131a8 100644
--- a/test/subset/data/expected/instantiate_cff2_partial/AdobeVFPrototype_vsindex.default.all.wght=300-500-700,CNTR=25-75.otf
+++ b/test/subset/data/expected/instantiate_cff2_partial/AdobeVFPrototype_vsindex.default.all.wght=300-500-700,CNTR=25-75.otf
Binary files differ