1 /*
2 * Copyright 2006 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE.skia file.
6 */
7 use crate::Point;
8
intrect<T: Copy>(x1: T, y1: T, x2: T, y2: T) -> euclid::default::Box2D<T>9 pub fn intrect<T: Copy>(x1: T, y1: T, x2: T, y2: T) -> euclid::default::Box2D<T> {
10 euclid::default::Box2D::new(euclid::point2(x1, y1), euclid::point2(x2, y2))
11 }
12
abs(a: f32) -> f3213 pub fn abs(a: f32) -> f32 {
14 if a < 0. {
15 return -a;
16 }
17 return a;
18 }
19
20 // we can do this
valid_unit_divide(mut numer: f32, mut denom: f32, ratio: &mut f32) -> bool21 pub fn valid_unit_divide(mut numer: f32, mut denom: f32, ratio: &mut f32) -> bool {
22 if numer < 0. {
23 numer = -numer;
24 denom = -denom;
25 }
26
27 if denom == 0. || numer == 0. || numer >= denom {
28 return false;
29 }
30
31 let r = numer / denom;
32 if r.is_nan() {
33 return false;
34 }
35 debug_assert!(r >= 0. && r < 1.);
36 if r == 0. {
37 // catch underflow if numer <<<< denom
38 return false;
39 }
40 *ratio = r;
41 return true;
42 }
43
is_not_monotonic(a: f32, b: f32, c: f32) -> bool44 pub fn is_not_monotonic(a: f32, b: f32, c: f32) -> bool {
45 let ab = a - b;
46 let mut bc = b - c;
47 if ab < 0. {
48 bc = -bc;
49 }
50 return ab == 0. || bc < 0.;
51 }
52
interp(a: f32, b: f32, t: f32) -> f3253 fn interp(a: f32, b: f32, t: f32) -> f32 {
54 debug_assert!(t >= 0. && t <= 1.);
55 return a + (b - a) * t;
56 }
57
58 // Skia does a weird thing where it treats arrays of points as castable to array of floats.
59 // For now we just duplicate quad_x and quad_y
interp_quad_x_coords(src: &[Point; 3], dst: &mut [Point; 5], t: f32)60 fn interp_quad_x_coords(src: &[Point; 3], dst: &mut [Point; 5], t: f32) {
61 let ab = interp(src[0].x, src[1].x, t);
62 let bc = interp(src[1].x, src[2].x, t);
63
64 dst[0].x = src[0].x;
65 dst[1].x = ab;
66 dst[2].x = interp(ab, bc, t);
67 dst[3].x = bc;
68 dst[4].x = src[2].x;
69 }
70
interp_quad_y_coords(src: &[Point; 3], dst: &mut [Point; 5], t: f32)71 fn interp_quad_y_coords(src: &[Point; 3], dst: &mut [Point; 5], t: f32) {
72 let ab = interp(src[0].y, src[1].y, t);
73 let bc = interp(src[1].y, src[2].y, t);
74
75 dst[0].y = src[0].y;
76 dst[1].y = ab;
77 dst[2].y = interp(ab, bc, t);
78 dst[3].y = bc;
79 dst[4].y = src[2].y;
80 }
81
chop_quad_at(src: &[Point; 3], dst: &mut [Point; 5], t: f32)82 pub fn chop_quad_at(src: &[Point; 3], dst: &mut [Point; 5], t: f32) {
83 debug_assert!(t > 0. && t < 1.);
84
85 interp_quad_x_coords(src, dst, t);
86 interp_quad_y_coords(src, dst, t);
87 }
88
89 // ensures that the y values are contiguous
90 // dst[1].fY = dst[3].fY = dst[2].fY
91 // I'm not sure why we need this
flatten_double_quad_extrema(dst: &mut [Point; 5])92 pub fn flatten_double_quad_extrema(dst: &mut [Point; 5]) {
93 dst[1].y = dst[2].y;
94 dst[3].y = dst[2].y;
95 }
96