1use crate::LengthU32;
8
9#[cfg(all(not(feature = "std"), feature = "no-std-float"))]
10use tiny_skia_path::NoStdFloat;
11
12pub const LENGTH_U32_ONE: LengthU32 = unsafe { LengthU32::new_unchecked(1) };
14
15pub fn left_shift(value: i32, shift: i32) -> i32 {
16 ((value as u32) << shift) as i32
17}
18
19pub fn left_shift64(value: i64, shift: i32) -> i64 {
20 ((value as u64) << shift) as i64
21}
22
23pub fn bound<T: Ord + Copy>(min: T, value: T, max: T) -> T {
24 max.min(value).max(min)
25}
26
27pub fn approx_powf(x: f32, y: f32) -> f32 {
29 if x == 0.0 || x == 1.0 {
30 return x;
31 }
32
33 let e = x.to_bits() as f32 * (1.0f32 / ((1 << 23) as f32));
34 let m = f32::from_bits((x.to_bits() & 0x007fffff) | 0x3f000000);
35
36 let log2_x = e - 124.225514990f32 - 1.498030302f32 * m - 1.725879990f32 / (0.3520887068f32 + m);
37
38 let x = log2_x * y;
39
40 let f = x - x.floor();
41
42 let mut a = x + 121.274057500f32;
43 a -= f * 1.490129070f32;
44 a += 27.728023300f32 / (4.84252568f32 - f);
45 a *= (1 << 23) as f32;
46
47 if a < f32::INFINITY.to_bits() as f32 {
48 if a > 0.0 {
49 f32::from_bits(a.round() as u32)
50 } else {
51 0.0
52 }
53 } else {
54 f32::INFINITY
55 }
56}