1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use arctk_attr::load;
use std::fmt::{Display, Formatter, Result};
#[load]
#[derive(Clone)]
pub enum AspectRatio {
Square,
Classic,
Golden,
Silver,
Standard,
Widescreen,
IPhoneXS,
IPhone7,
Custom(f64, f64),
}
impl AspectRatio {
#[inline]
#[must_use]
pub fn ratio(&self) -> f64 {
match *self {
Self::Square => 1.0,
Self::Classic => 3.0 / 2.0,
Self::Golden => (1.0 + 5.0_f64.sqrt()) / 2.0,
Self::Silver => 1.0 + 2.0_f64.sqrt(),
Self::Standard => 16.0 / 9.0,
Self::Widescreen => 43.0 / 18.0,
Self::IPhoneXS => 1125.0 / 2436.0,
Self::IPhone7 => 750.0 / 1334.0,
Self::Custom(w, h) => w / h,
}
}
#[inline]
#[must_use]
pub fn resolution(&self, total_target: u64, mult: (u64, u64)) -> (u64, u64) {
debug_assert!(total_target > 0);
let fx = (total_target as f64 * self.ratio()).sqrt().ceil() as u64;
let fy = (total_target as f64 / self.ratio()).sqrt().ceil() as u64;
let mx = if fx % mult.0 == 0 {
fx
} else {
fx + (mult.0 - (fx % mult.0))
};
let my = if fy % mult.1 == 0 {
fy
} else {
fy + (mult.1 - (fx % mult.1))
};
(mx, my)
}
#[inline]
#[must_use]
pub fn vt_res(&self, hr_res: u64) -> u64 {
debug_assert!(hr_res > 0);
(hr_res as f64 / self.ratio()).ceil() as u64
}
}
impl Display for AspectRatio {
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> Result {
match *self {
Self::Square { .. } => write!(fmt, "Square"),
Self::Classic { .. } => write!(fmt, "Classic"),
Self::Golden { .. } => write!(fmt, "Golden"),
Self::Silver { .. } => write!(fmt, "Silver"),
Self::Standard { .. } => write!(fmt, "Standard"),
Self::Widescreen { .. } => write!(fmt, "Widescreen"),
Self::IPhoneXS { .. } => write!(fmt, "IPhoneXS"),
Self::IPhone7 { .. } => write!(fmt, "IPhone7"),
Self::Custom(w, h) => write!(fmt, "Custom [{}:{}]", w, h),
}
}
}