diff --git a/src/fontations/lib.rs b/src/fontations/lib.rs index d7f1d6130..c56ea734c 100644 --- a/src/fontations/lib.rs +++ b/src/fontations/lib.rs @@ -407,50 +407,32 @@ extern "C" fn _hb_fontations_get_extend( color_line_data.extend as hb_paint_extend_t // They are the same } -/// Returns (x0, y0, x1, y1, x2, y2) such that the original `_hb_cairo_reduce_anchors` -/// would produce (xx0, yy0, xx1, yy1) as outputs. pub fn _hb_fontations_unreduce_anchors( - xx0: f32, - yy0: f32, - xx1: f32, - yy1: f32, + x0: f32, + y0: f32, + x1: f32, + y1: f32, ) -> (f32, f32, f32, f32, f32, f32) { - // 1) Force the first anchor to match directly: - let x0 = xx0; - let y0 = yy0; + /* Returns (x0, y0, x1, y1, x2, y2) such that the original + * `_hb_cairo_reduce_anchors` would produce (xx0, yy0, xx1, yy1) + * as outputs. + * The OT spec has the following wording; we just need to + * invert that operation here: + * + * Note: An implementation can derive a single vector, from p₀ to a point p₃, by computing the + * orthogonal projection of the vector from p₀ to p₁ onto a line perpendicular to line p₀p₂ and + * passing through p₀ to obtain point p₃. The linear gradient defined using p₀, p₁ and p₂ as + * described above is functionally equivalent to a linear gradient defined by aligning stop + * offset 0 to p₀ and aligning stop offset 1.0 to p₃, with each color projecting on either side + * of that line in a perpendicular direction. This specification uses three points, p₀, p₁ and + * p₂, as that provides greater flexibility in controlling the placement and rotation of the + * gradient, as well as variations thereof. + */ - // 2) Force the second anchor to match directly: - let x1 = xx1; - let y1 = yy1; + let dx = x1 - x0; + let dy = y1 - y0; - // Vector from (xx0, yy0) to (xx1, yy1) - let dx = xx1 - xx0; - let dy = yy1 - yy0; - let dist2 = dx * dx + dy * dy; - - // 3) Pick (x2, y2) - let (x2, y2) = if dist2 < 1e-12 { - // Degenerate: both anchors are almost the same point - // => choose any non-zero offset from (x0, y0) - (xx0 + 100.0, yy0) - } else { - // Non-degenerate: pick a perpendicular vector to (dx, dy) - let len = dist2.sqrt(); - let mut q2x = dy; - let mut q2y = -dx; - - // Optionally scale it to the same length as (dx, dy) - let q2len = (q2x * q2x + q2y * q2y).sqrt(); - if q2len > 1e-12 { - let scale = len / q2len; - q2x *= scale; - q2y *= scale; - } - - (xx0 + q2x, yy0 + q2y) - }; - - (x0, y0, x1, y1, x2, y2) + (x0, y0, x1, y1, x0 + dy, y0 - dx) } impl ColorPainter for HbColorPainter { @@ -540,20 +522,19 @@ impl ColorPainter for HbColorPainter { }; let mut color_line = self.make_color_line(&color_stops); - // Untested - let points = _hb_fontations_unreduce_anchors(p0.x, p0.y, p1.x, p1.y); + let (x0, y0, x1, y1, x2, y2) = _hb_fontations_unreduce_anchors(p0.x, p0.y, p1.x, p1.y); unsafe { hb_paint_linear_gradient( self.paint_funcs, self.paint_data, &mut color_line, - points.0, - points.1, - points.2, - points.3, - points.4, - points.5, + x0, + y0, + x1, + y1, + x2, + y2, ); } }