summaryrefslogtreecommitdiff
path: root/engine/src/windowing/dpi.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2026-06-28 00:09:06 +0200
committerHampusM <hampus@hampusmat.com>2026-06-30 18:24:47 +0200
commit9df8a4d197e66accb389edb5a5c54117933f157e (patch)
tree2d348fea32df9dd73ec6b961fae63e8ccb60899d /engine/src/windowing/dpi.rs
parent4a5e3e612e8b597dd1734afefd01324b74fd99ab (diff)
feat(engine): add windowing DPI utilities
Diffstat (limited to 'engine/src/windowing/dpi.rs')
-rw-r--r--engine/src/windowing/dpi.rs182
1 files changed, 182 insertions, 0 deletions
diff --git a/engine/src/windowing/dpi.rs b/engine/src/windowing/dpi.rs
new file mode 100644
index 0000000..2bac619
--- /dev/null
+++ b/engine/src/windowing/dpi.rs
@@ -0,0 +1,182 @@
+macro_rules! gen_struct_from_to_impls {
+ ($struct: ident, fields=($($field: ident),*)) => {
+ impl<Pixel> From<winit::dpi::$struct<Pixel>> for $struct<Pixel>
+ {
+ fn from(source: winit::dpi::$struct<Pixel>) -> Self
+ {
+ Self {
+ $($field: source.$field),*
+ }
+ }
+ }
+
+ impl<Pixel> From<$struct<Pixel>> for winit::dpi::$struct<Pixel>
+ {
+ fn from(source: $struct<Pixel>) -> Self
+ {
+ Self {
+ $($field: source.$field),*
+ }
+ }
+ }
+ };
+}
+
+macro_rules! gen_enum_from_to_impls {
+ ($enum: ident, variants=($($variant: ident),*)) => {
+ impl From<winit::dpi::$enum> for $enum
+ {
+ fn from(source: winit::dpi::$enum) -> Self
+ {
+ match source {
+ $(winit::dpi::$enum::$variant(pos) => Self::$variant(pos.into())),*
+ }
+ }
+ }
+
+ impl From<$enum> for winit::dpi::$enum
+ {
+ fn from(source: $enum) -> Self
+ {
+ match source {
+ $($enum::$variant(pos) => Self::$variant(pos.into())),*
+ }
+ }
+ }
+ };
+}
+
+#[derive(Debug, Default, Clone, PartialEq)]
+pub struct PhysicalPosition<Pixel>
+{
+ pub x: Pixel,
+ pub y: Pixel
+}
+
+impl<Pixel> PhysicalPosition<Pixel>
+{
+ pub fn to_logical<LogicalPixel>(&self, scale_factor: f64) -> LogicalPosition<LogicalPixel>
+ where
+ Pixel: Into<f64> + Clone,
+ LogicalPixel: From<f64>
+ {
+ let x = self.x.clone().into();
+ let y = self.y.clone().into();
+
+ LogicalPosition {
+ x: (x / scale_factor).into(),
+ y: (y / scale_factor).into()
+ }
+ }
+
+ pub fn try_convert_from<SourcePixel>(source: PhysicalPosition<SourcePixel>) -> Result<Self, Pixel::Error>
+ where
+ Pixel: TryFrom<SourcePixel>
+ {
+ Ok(Self {
+ x: source.x.try_into()?,
+ y: source.y.try_into()?
+ })
+ }
+}
+
+gen_struct_from_to_impls!(PhysicalPosition, fields=(x, y));
+
+#[derive(Debug, Default, Clone, PartialEq)]
+pub struct LogicalPosition<Pixel>
+{
+ pub x: Pixel,
+ pub y: Pixel
+}
+
+impl<Pixel> LogicalPosition<Pixel>
+{
+ pub fn try_convert_from<SourcePixel>(source: LogicalPosition<SourcePixel>) -> Result<Self, Pixel::Error>
+ where
+ Pixel: TryFrom<SourcePixel>
+ {
+ Ok(Self {
+ x: source.x.try_into()?,
+ y: source.y.try_into()?
+ })
+ }
+}
+
+gen_struct_from_to_impls!(LogicalPosition, fields=(x, y));
+
+#[derive(Debug, Clone, PartialEq)]
+pub enum Position
+{
+ Physical(PhysicalPosition<i32>),
+ Logical(LogicalPosition<f64>)
+}
+
+gen_enum_from_to_impls!(Position, variants=(Physical, Logical));
+
+#[derive(Debug, Default, Clone, PartialEq)]
+pub struct PhysicalSize<Pixel>
+{
+ pub width: Pixel,
+ pub height: Pixel
+}
+
+impl<Pixel> PhysicalSize<Pixel>
+{
+ pub fn to_logical<LogicalPixel>(&self, scale_factor: f64) -> LogicalSize<LogicalPixel>
+ where
+ Pixel: Into<f64> + Clone,
+ LogicalPixel: From<f64>
+ {
+ let width = self.width.clone().into();
+ let height = self.height.clone().into();
+
+ LogicalSize {
+ width: (width / scale_factor).into(),
+ height: (height / scale_factor).into()
+ }
+ }
+}
+
+impl<Pixel> PhysicalSize<Pixel>
+{
+ pub fn try_convert_from<SourcePixel>(source: PhysicalSize<SourcePixel>) -> Result<Self, Pixel::Error>
+ where
+ Pixel: TryFrom<SourcePixel>
+ {
+ Ok(Self {
+ width: source.width.try_into()?,
+ height: source.height.try_into()?
+ })
+ }
+}
+
+gen_struct_from_to_impls!(PhysicalSize, fields=(width, height));
+
+#[derive(Debug, Default, Clone, PartialEq)]
+pub struct LogicalSize<Pixel>
+{
+ pub width: Pixel,
+ pub height: Pixel
+}
+
+impl<Pixel> LogicalSize<Pixel>
+{
+ pub fn try_convert_from<SourcePixel>(source: LogicalSize<SourcePixel>) -> Result<Self, Pixel::Error>
+ where
+ Pixel: TryFrom<SourcePixel>
+ {
+ Ok(Self {
+ width: source.width.try_into()?,
+ height: source.height.try_into()?
+ })
+ }
+}
+
+gen_struct_from_to_impls!(LogicalSize, fields=(width, height));
+
+#[derive(Debug, Clone, PartialEq)]
+pub enum Size
+{
+ Physical(PhysicalSize<u32>),
+ Logical(LogicalSize<f64>)
+}