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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
use crate::graphics::Rectangle;
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum ScreenScaling {
None,
Stretch,
ShowAll,
ShowAllPixelPerfect,
Crop,
CropPixelPerfect,
Resize,
}
impl ScreenScaling {
pub(crate) fn get_screen_rect(
self,
internal_width: i32,
internal_height: i32,
window_width: i32,
window_height: i32,
) -> Rectangle {
let f_internal_width = internal_width as f32;
let f_internal_height = internal_height as f32;
let f_window_width = window_width as f32;
let f_window_height = window_height as f32;
let internal_aspect_ratio = f_internal_width / f_internal_height;
let screen_aspect_ratio = f_window_width / f_window_height;
match self {
ScreenScaling::None => {
let screen_x = (window_width - internal_width) / 2;
let screen_y = (window_height - internal_height) / 2;
Rectangle::new(
screen_x as f32,
screen_y as f32,
internal_width as f32,
internal_height as f32,
)
}
ScreenScaling::Stretch | ScreenScaling::Resize => {
Rectangle::new(0.0, 0.0, window_width as f32, window_height as f32)
}
ScreenScaling::ShowAll => {
let scale_factor = if internal_aspect_ratio > screen_aspect_ratio {
f_window_width / f_internal_width
} else {
f_window_height / f_internal_height
};
let screen_width = (f_internal_width * scale_factor).ceil();
let screen_height = (f_internal_height * scale_factor).ceil();
let screen_x = ((f_window_width - screen_width) / 2.0).ceil();
let screen_y = ((f_window_height - screen_height) / 2.0).ceil();
Rectangle::new(screen_x, screen_y, screen_width, screen_height)
}
ScreenScaling::ShowAllPixelPerfect => {
let mut scale_factor = if internal_aspect_ratio > screen_aspect_ratio {
window_width / internal_width
} else {
window_height / internal_height
};
if scale_factor == 0 {
scale_factor = 1;
}
let screen_width = internal_width * scale_factor;
let screen_height = internal_height * scale_factor;
let screen_x = (window_width - screen_width) / 2;
let screen_y = (window_height - screen_height) / 2;
Rectangle::new(
screen_x as f32,
screen_y as f32,
screen_width as f32,
screen_height as f32,
)
}
ScreenScaling::Crop => {
let scale_x = f_window_width / f_internal_width;
let scale_y = f_window_height / f_internal_height;
let scale_factor = scale_x.max(scale_y);
let screen_width = (f_internal_width * scale_factor).ceil();
let screen_height = (f_internal_height * scale_factor).ceil();
let screen_x = ((f_window_width - screen_width) / 2.0).ceil();
let screen_y = ((f_window_height - screen_height) / 2.0).ceil();
Rectangle::new(screen_x, screen_y, screen_width, screen_height)
}
ScreenScaling::CropPixelPerfect => {
let mut scale_factor = if internal_aspect_ratio > screen_aspect_ratio {
f_window_height / f_internal_height
} else {
f_window_width / f_internal_width
}
.ceil() as i32;
if scale_factor == 0 {
scale_factor = 1;
}
let screen_width = internal_width * scale_factor;
let screen_height = internal_height * scale_factor;
let screen_x = (window_width - screen_width) / 2;
let screen_y = (window_height - screen_height) / 2;
Rectangle::new(
screen_x as f32,
screen_y as f32,
screen_width as f32,
screen_height as f32,
)
}
}
}
}