diff --git a/src/draw/layout.rs b/src/draw/layout.rs index ac21777..61ea6a1 100644 --- a/src/draw/layout.rs +++ b/src/draw/layout.rs @@ -17,6 +17,20 @@ use crate::widget::{ Element, LaidOutWidget, WidgetHandlers }; use super::DrawCtx; use super::damage::clamp_rect_to; +/// The previous frame's sub-canvas resized to `width × height`, or a new one when the parent's scale changed since, as a sub-canvas keeps the scale it was made with. +fn reuse_sub_canvas( pooled: Option, parent: &Canvas, width: u32, height: u32 ) -> Canvas +{ + match pooled + { + Some( mut sub ) if sub.dpi_scale() == parent.dpi_scale() => + { + if sub.size() != ( width, height ) { sub.resize( width, height ); } + sub + } + _ => parent.sub_canvas( width, height ), + } +} + pub( crate ) fn layout_and_draw( element: &Element, canvas: &mut Canvas, @@ -295,13 +309,9 @@ pub( crate ) fn layout_and_draw( ctx.scroll_offsets.insert( my_idx, ( ox, oy ) ); } - // Reuse the sub-canvas from the previous frame if its size matches; - // only reallocate when the viewport is resized. let sw = (rect.width.ceil() as u32).max( 1 ); let sh = (rect.height.ceil() as u32).max( 1 ); - let mut sub = ctx.scroll_canvases.remove( &my_idx ) - .map( |mut c| { if c.size() != ( sw, sh ) { c.resize( sw, sh ); } c } ) - .unwrap_or_else( || canvas.sub_canvas( sw, sh ) ); + let mut sub = reuse_sub_canvas( ctx.scroll_canvases.remove( &my_idx ), canvas, sw, sh ); sub.clear(); // Child content fills at least the full viewport on each @@ -462,9 +472,7 @@ pub( crate ) fn layout_and_draw( let vh = ( rect.height.ceil() as u32 ).max( 1 ); let seq = ctx.viewport_seq; ctx.viewport_seq += 1; - let mut sub = ctx.viewport_canvases.remove( &seq ) - .map( |mut c| { if c.size() != ( vw, vh ) { c.resize( vw, vh ); } c } ) - .unwrap_or_else( || canvas.sub_canvas( vw, vh ) ); + let mut sub = reuse_sub_canvas( ctx.viewport_canvases.remove( &seq ), canvas, vw, vh ); if v.local_viewport { sub.set_local_layout_viewport(); } sub.clear();