diff --git a/azul-core/src/display_list.rs b/azul-core/src/display_list.rs index b6f9a8c5..9a510ffd 100644 --- a/azul-core/src/display_list.rs +++ b/azul-core/src/display_list.rs @@ -36,6 +36,13 @@ pub struct GlyphInstance { pub size: LogicalSize, } +impl GlyphInstance { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.point.scale_for_dpi(scale_factor); + self.size.scale_for_dpi(scale_factor); + } +} + #[derive(Debug, Copy, Clone, PartialEq, PartialOrd)] pub struct DisplayListImageMask { pub image: ImageKey, @@ -43,6 +50,12 @@ pub struct DisplayListImageMask { pub repeat: bool, } +impl DisplayListImageMask { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.rect.scale_for_dpi(scale_factor); + } +} + #[derive(Debug, Clone, PartialEq, PartialOrd)] pub struct CachedDisplayList { pub root: DisplayListMsg, @@ -59,6 +72,12 @@ impl CachedDisplayList { root_size: LogicalSize::zero(), } } + + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.root_size.width *= scale_factor; + self.root_size.height *= scale_factor; + self.root.scale_for_dpi(scale_factor); + } } #[derive(Debug, Clone, PartialEq, PartialOrd)] @@ -70,6 +89,23 @@ pub enum DisplayListMsg { } impl DisplayListMsg { + + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + match self { + DisplayListMsg::IFrame(_, s, _, dl) => { + s.width *= scale_factor; + s.height *= scale_factor; + dl.scale_for_dpi(scale_factor); + }, + DisplayListMsg::Frame(f) => { + f.scale_for_dpi(scale_factor); + }, + DisplayListMsg::ScrollFrame(sf) => { + sf.scale_for_dpi(scale_factor); + } + } + } + pub fn get_transform_key(&self) -> Option<&(TransformKey, ComputedTransform3D)> { use self::DisplayListMsg::*; match self { @@ -212,6 +248,14 @@ pub struct DisplayListScrollFrame { pub frame: DisplayListFrame, } +impl DisplayListScrollFrame { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.parent_rect.scale_for_dpi(scale_factor); + self.content_rect.scale_for_dpi(scale_factor); + self.frame.scale_for_dpi(scale_factor); + } +} + impl fmt::Debug for DisplayListScrollFrame { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "DisplayListScrollFrame {{\r\n")?; @@ -284,6 +328,22 @@ impl fmt::Debug for DisplayListFrame { } impl DisplayListFrame { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.size.width *= scale_factor; + self.size.height *= scale_factor; + self.position.scale_for_dpi(scale_factor); + self.clip_children.as_mut().map(|s| s.scale_for_dpi(scale_factor)); + self.clip_mask.as_mut().map(|s| s.scale_for_dpi(scale_factor)); + self.border_radius.scale_for_dpi(scale_factor); + self.transform.as_mut().map(|(k, v)| v.scale_for_dpi(scale_factor)); + for c in self.content.iter_mut() { + c.scale_for_dpi(scale_factor); + } + for c in self.children.iter_mut() { + c.scale_for_dpi(scale_factor); + } + } + pub fn root(dimensions: LayoutSize, root_origin: LayoutPoint) -> Self { use crate::ui_solver::PositionInfoInner; DisplayListFrame { @@ -343,7 +403,15 @@ impl StyleBorderRadius { && self.bottom_left.is_none() && self.bottom_right.is_none() } + + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.top_left.as_mut().map(|s| s.scale_for_dpi(scale_factor)); + self.top_right.as_mut().map(|s| s.scale_for_dpi(scale_factor)); + self.bottom_left.as_mut().map(|s| s.scale_for_dpi(scale_factor)); + self.bottom_right.as_mut().map(|s| s.scale_for_dpi(scale_factor)); + } } + impl fmt::Debug for StyleBorderRadius { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "StyleBorderRadius {{")?; @@ -395,6 +463,14 @@ pub struct StyleBorderWidths { } impl StyleBorderWidths { + + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.top.as_mut().map(|s| s.scale_for_dpi(scale_factor)); + self.right.as_mut().map(|s| s.scale_for_dpi(scale_factor)); + self.bottom.as_mut().map(|s| s.scale_for_dpi(scale_factor)); + self.left.as_mut().map(|s| s.scale_for_dpi(scale_factor)); + } + #[inline] pub fn left_width(&self) -> f32 { self.left @@ -510,6 +586,55 @@ pub enum LayoutRectContent { }, } +impl LayoutRectContent { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + use self::LayoutRectContent::*; + match self { + Text { + glyphs, + font_instance_key, + color, + glyph_options, + overflow, + text_shadow, + } => { + for g in glyphs.iter_mut() { + g.scale_for_dpi(scale_factor); + } + text_shadow.as_mut().map(|s| s.scale_for_dpi(scale_factor)); + }, + Background { + content, + size, + offset, + repeat, + } => { + content.scale_for_dpi(scale_factor); + size.as_mut().map(|s| s.scale_for_dpi(scale_factor)); + offset.as_mut().map(|s| s.scale_for_dpi(scale_factor)); + }, + Image { + size, + offset, + image_rendering, + alpha_type, + image_key, + background_color, + } => { + size.scale_for_dpi(scale_factor); + offset.scale_for_dpi(scale_factor); + }, + Border { + widths, + colors, + styles, + } => { + widths.scale_for_dpi(scale_factor); + }, + } + } +} + impl fmt::Debug for LayoutRectContent { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use self::LayoutRectContent::*; @@ -616,6 +741,15 @@ impl fmt::Debug for RectBackground { } impl RectBackground { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + match self { + RectBackground::Image((_key, descriptor)) => { + descriptor.width = libm::round(descriptor.width as f64 * scale_factor as f64) as usize; + descriptor.height = libm::round(descriptor.height as f64 * scale_factor as f64) as usize; + } + _ => { }, + } + } pub fn get_content_size(&self) -> Option<(f32, f32)> { match self { RectBackground::Image((_key, descriptor)) => { diff --git a/azul-core/src/ui_solver.rs b/azul-core/src/ui_solver.rs index f9d42eb7..dabc778b 100644 --- a/azul-core/src/ui_solver.rs +++ b/azul-core/src/ui_solver.rs @@ -1596,18 +1596,18 @@ pub enum PositionInfo { Relative(PositionInfoInner), } -/* -impl ::core::fmt::Debug for PositionInfo { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + +impl PositionInfo { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { match self { - PositionInfo::Static(p) => write!(f, "static({}, {})", p.x_offset, p.y_offset), - PositionInfo::Fixed(p) => write!(f, "fixed({}, {})", p.x_offset, p.y_offset), - PositionInfo::Absolute(p) => write!(f, "absolute({}, {})", p.x_offset, p.y_offset), - PositionInfo::Relative(p) => write!(f, "relative({}, {})", p.x_offset, p.y_offset), + PositionInfo::Static(p) => p.scale_for_dpi(scale_factor), + PositionInfo::Fixed(p) => p.scale_for_dpi(scale_factor), + PositionInfo::Absolute(p) => p.scale_for_dpi(scale_factor), + PositionInfo::Relative(p) => p.scale_for_dpi(scale_factor), } } } -*/ + impl_option!( PositionInfo, OptionPositionInfo, @@ -1633,6 +1633,13 @@ impl PositionInfoInner { static_y_offset: 0.0, } } + + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.x_offset *= scale_factor; + self.y_offset *= scale_factor; + self.static_x_offset *= scale_factor; + self.static_y_offset *= scale_factor; + } } impl PositionInfo { @@ -2201,6 +2208,11 @@ impl ComputedTransform3D { Some(LogicalPosition { x: x / w, y: y / w }) } + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + let scale_matrix = Self::new_scale(scale_factor, scale_factor, 1.0); + *self = self.then(&scale_matrix); + } + /// Computes the sum of two matrices while applying `other` AFTER the current matrix. #[must_use] #[inline] diff --git a/azul-core/src/window.rs b/azul-core/src/window.rs index 0bc17410..66115134 100644 --- a/azul-core/src/window.rs +++ b/azul-core/src/window.rs @@ -2688,6 +2688,14 @@ impl LogicalRect { Self { origin, size } } + #[inline] + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.origin.x *= scale_factor; + self.origin.y *= scale_factor; + self.size.width *= scale_factor; + self.size.height *= scale_factor; + } + #[inline(always)] pub fn max_x(&self) -> f32 { self.origin.x + self.size.width @@ -2786,6 +2794,13 @@ pub struct LogicalPosition { pub y: f32, } +impl LogicalPosition { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.x *= scale_factor; + self.y *= scale_factor; + } +} + impl SubAssign for LogicalPosition { fn sub_assign(&mut self, other: LogicalPosition) { self.x -= other.x; @@ -2875,6 +2890,14 @@ pub struct LogicalSize { pub height: f32, } +impl LogicalSize { + pub fn scale_for_dpi(&mut self, scale_factor: f32) -> Self { + self.width *= scale_factor; + self.height *= scale_factor; + *self + } +} + impl core::fmt::Debug for LogicalSize { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!(f, "{}x{}", self.width, self.height) diff --git a/azul-css/src/css_properties.rs b/azul-css/src/css_properties.rs index e3a96e8d..1d61c623 100644 --- a/azul-css/src/css_properties.rs +++ b/azul-css/src/css_properties.rs @@ -3642,6 +3642,12 @@ pub struct PixelValueNoPercent { pub inner: PixelValue, } +impl PixelValueNoPercent { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.inner.scale_for_dpi(scale_factor); + } +} + impl_option!( PixelValueNoPercent, OptionPixelValueNoPercent, @@ -3830,6 +3836,12 @@ pub struct PixelValue { pub number: FloatValue, } +impl PixelValue { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.number = FloatValue::new(self.number.get() * scale_factor); + } +} + impl fmt::Debug for PixelValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}{}", self.number, self.metric) @@ -4102,6 +4114,19 @@ pub enum StyleBackgroundSize { Cover, } +impl StyleBackgroundSize { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + match self { + StyleBackgroundSize::ExactSize(a) => { + for q in a.iter_mut() { + q.scale_for_dpi(scale_factor); + } + }, + _ => { }, + } + } +} + impl Default for StyleBackgroundSize { fn default() -> Self { StyleBackgroundSize::Contain @@ -4133,6 +4158,13 @@ pub struct StyleBackgroundPosition { pub vertical: BackgroundPositionVertical, } +impl StyleBackgroundPosition { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.horizontal.scale_for_dpi(scale_factor); + self.vertical.scale_for_dpi(scale_factor); + } +} + impl_vec!( StyleBackgroundPosition, StyleBackgroundPositionVec, @@ -4168,6 +4200,15 @@ pub enum BackgroundPositionHorizontal { Exact(PixelValue), } +impl BackgroundPositionHorizontal { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + match self { + BackgroundPositionHorizontal::Exact(s) => { s.scale_for_dpi(scale_factor); }, + _ => { }, + } + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(C, u8)] pub enum BackgroundPositionVertical { @@ -4177,6 +4218,15 @@ pub enum BackgroundPositionVertical { Exact(PixelValue), } +impl BackgroundPositionVertical { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + match self { + BackgroundPositionVertical::Exact(s) => { s.scale_for_dpi(scale_factor); }, + _ => { }, + } + } +} + /// Represents a `background-repeat` attribute #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(C)] @@ -4290,6 +4340,126 @@ impl_pixel_value!(LayoutBorderLeftWidth); impl_pixel_value!(LayoutBorderRightWidth); impl_pixel_value!(LayoutBorderBottomWidth); +impl CssPropertyValue { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + match self { + CssPropertyValue::Exact(s) => { s.scale_for_dpi(scale_factor); }, + _ => { }, + } + } +} + +impl CssPropertyValue { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + match self { + CssPropertyValue::Exact(s) => { s.scale_for_dpi(scale_factor); }, + _ => { }, + } + } +} + +impl CssPropertyValue { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + match self { + CssPropertyValue::Exact(s) => { s.scale_for_dpi(scale_factor); }, + _ => { }, + } + } +} + +impl CssPropertyValue { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + match self { + CssPropertyValue::Exact(s) => { s.scale_for_dpi(scale_factor); }, + _ => { }, + } + } +} + +impl CssPropertyValue { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + match self { + CssPropertyValue::Exact(s) => { s.scale_for_dpi(scale_factor); }, + _ => { }, + } + } +} + +impl CssPropertyValue { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + match self { + CssPropertyValue::Exact(s) => { s.scale_for_dpi(scale_factor); }, + _ => { }, + } + } +} + +impl CssPropertyValue { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + match self { + CssPropertyValue::Exact(s) => { s.scale_for_dpi(scale_factor); }, + _ => { }, + } + } +} + +impl CssPropertyValue { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + match self { + CssPropertyValue::Exact(s) => { s.scale_for_dpi(scale_factor); }, + _ => { }, + } + } +} + +impl StyleBorderTopLeftRadius { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.inner.scale_for_dpi(scale_factor); + } +} + +impl StyleBorderTopRightRadius { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.inner.scale_for_dpi(scale_factor); + } +} + +impl StyleBorderBottomLeftRadius { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.inner.scale_for_dpi(scale_factor); + } +} + +impl StyleBorderBottomRightRadius { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.inner.scale_for_dpi(scale_factor); + } +} + +impl LayoutBorderTopWidth { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.inner.scale_for_dpi(scale_factor); + } +} + +impl LayoutBorderRightWidth { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.inner.scale_for_dpi(scale_factor); + } +} + +impl LayoutBorderBottomWidth { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.inner.scale_for_dpi(scale_factor); + } +} + +impl LayoutBorderLeftWidth { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + self.inner.scale_for_dpi(scale_factor); + } +} + /// Represents a `border-top-width` attribute #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(C)] @@ -4406,6 +4576,16 @@ pub struct StyleBoxShadow { pub clip_mode: BoxShadowClipMode, } +impl StyleBoxShadow { + pub fn scale_for_dpi(&mut self, scale_factor: f32) { + for s in self.offset.iter_mut() { + s.scale_for_dpi(scale_factor); + } + self.blur_radius.scale_for_dpi(scale_factor); + self.spread_radius.scale_for_dpi(scale_factor); + } +} + #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(C, u8)] pub enum StyleBackgroundContent { diff --git a/azul-desktop/src/wr_translate.rs b/azul-desktop/src/wr_translate.rs index 3d3fa040..293fb0dd 100644 --- a/azul-desktop/src/wr_translate.rs +++ b/azul-desktop/src/wr_translate.rs @@ -372,7 +372,7 @@ pub(crate) fn rebuild_display_list( // NOTE: Display list has to be rebuilt every frame, otherwise, the epochs get out of sync let root_id = DomId { inner: 0 }; - let cached_display_list = LayoutResult::get_cached_display_list( + let mut cached_display_list = LayoutResult::get_cached_display_list( &internal.document_id, root_id, internal.epoch, @@ -383,6 +383,9 @@ pub(crate) fn rebuild_display_list( image_cache, ); + // Scale everything in the display list to the DPI of the window + cached_display_list.scale_for_dpi(internal.current_window_state.size.get_hidpi_factor()); + println!("wr_translate hidpi factor {}", internal.current_window_state.size.get_hidpi_factor()); let root_pipeline_id = PipelineId(0, internal.document_id.id); let display_list = wr_translate_display_list(