display_types/screen.rs
1/// Physical screen dimensions or aspect ratio, decoded from EDID base block bytes `0x15`–`0x16`.
2///
3/// The two bytes encode one of three things depending on which are zero:
4///
5/// | `0x15` | `0x16` | Meaning |
6/// |--------|--------|-----------------------------------|
7/// | non-0 | non-0 | Physical width × height in cm |
8/// | non-0 | 0 | Landscape aspect ratio |
9/// | 0 | non-0 | Portrait aspect ratio |
10/// | 0 | 0 | Undefined — `None` on the field |
11#[non_exhaustive]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum ScreenSize {
15 /// Physical screen dimensions. Values are in centimetres (1–255 cm per axis).
16 Physical {
17 /// Horizontal screen size in centimetres.
18 width_cm: u8,
19 /// Vertical screen size in centimetres.
20 height_cm: u8,
21 },
22 /// Landscape aspect ratio (width ÷ height > 1), encoded as a raw EDID byte.
23 ///
24 /// Call [`landscape_ratio`][Self::landscape_ratio] for the computed `f32` value.
25 Landscape(u8),
26 /// Portrait aspect ratio (width ÷ height < 1), encoded as a raw EDID byte.
27 ///
28 /// Call [`portrait_ratio`][Self::portrait_ratio] for the computed `f32` value.
29 Portrait(u8),
30}
31
32impl ScreenSize {
33 /// Returns the landscape aspect ratio (width ÷ height) for a `Landscape` variant.
34 ///
35 /// Formula: `(raw + 99) / 100`. Range: 1.00 → 3.54.
36 /// Returns `None` for other variants.
37 pub fn landscape_ratio(&self) -> Option<f32> {
38 if let Self::Landscape(v) = self {
39 Some((*v as f32 + 99.0) / 100.0)
40 } else {
41 None
42 }
43 }
44
45 /// Returns the portrait aspect ratio (width ÷ height) for a `Portrait` variant.
46 ///
47 /// Formula: `100 / (raw + 99)`. Range: 0.28 → 0.99.
48 /// Returns `None` for other variants.
49 pub fn portrait_ratio(&self) -> Option<f32> {
50 if let Self::Portrait(v) = self {
51 Some(100.0 / (*v as f32 + 99.0))
52 } else {
53 None
54 }
55 }
56}