@@ -145,8 +145,17 @@ impl<T: Data> Widget<T> for Image {
145145 ) -> Size {
146146 bc. debug_check ( "Image" ) ;
147147
148- if bc. is_width_bounded ( ) {
149- bc. max ( )
148+ // If either the width or height is constrained calculate a value so that the image fits
149+ // in the size exactly. If it is unconstrained by both width and height take the size of
150+ // the image.
151+ let max = bc. max ( ) ;
152+ let image_size = self . image_data . size ( ) ;
153+ if bc. is_width_bounded ( ) && !bc. is_height_bounded ( ) {
154+ let ratio = max. width / image_size. width ;
155+ Size :: new ( max. width , ratio * image_size. height )
156+ } else if bc. is_height_bounded ( ) && !bc. is_width_bounded ( ) {
157+ let ratio = max. height / image_size. height ;
158+ Size :: new ( ratio * image_size. width , max. height )
150159 } else {
151160 bc. constrain ( self . image_data . size ( ) )
152161 }
@@ -317,4 +326,60 @@ mod tests {
317326 } ,
318327 ) ;
319328 }
329+
330+ #[ test]
331+ fn width_bound_layout ( ) {
332+ use crate :: {
333+ tests:: harness:: Harness ,
334+ widget:: { Container , Scroll } ,
335+ WidgetExt , WidgetId ,
336+ } ;
337+ use float_cmp:: approx_eq;
338+
339+ let id_1 = WidgetId :: next ( ) ;
340+ let image_data = ImageBuf :: from_raw (
341+ vec ! [ 255 , 255 , 255 , 0 , 0 , 0 , 0 , 0 , 0 , 255 , 255 , 255 ] ,
342+ ImageFormat :: Rgb ,
343+ 2 ,
344+ 2 ,
345+ ) ;
346+
347+ let image_widget =
348+ Scroll :: new ( Container :: new ( Image :: new ( image_data) ) . with_id ( id_1) ) . vertical ( ) ;
349+
350+ Harness :: create_simple ( true , image_widget, |harness| {
351+ harness. send_initial_events ( ) ;
352+ harness. just_layout ( ) ;
353+ let state = harness. get_state ( id_1) ;
354+ assert ! ( approx_eq!( f64 , state. layout_rect( ) . x1, 400.0 ) ) ;
355+ } )
356+ }
357+
358+ #[ test]
359+ fn height_bound_layout ( ) {
360+ use crate :: {
361+ tests:: harness:: Harness ,
362+ widget:: { Container , Scroll } ,
363+ WidgetExt , WidgetId ,
364+ } ;
365+ use float_cmp:: approx_eq;
366+
367+ let id_1 = WidgetId :: next ( ) ;
368+ let image_data = ImageBuf :: from_raw (
369+ vec ! [ 255 , 255 , 255 , 0 , 0 , 0 , 0 , 0 , 0 , 255 , 255 , 255 ] ,
370+ ImageFormat :: Rgb ,
371+ 2 ,
372+ 2 ,
373+ ) ;
374+
375+ let image_widget =
376+ Scroll :: new ( Container :: new ( Image :: new ( image_data) ) . with_id ( id_1) ) . horizontal ( ) ;
377+
378+ Harness :: create_simple ( true , image_widget, |harness| {
379+ harness. send_initial_events ( ) ;
380+ harness. just_layout ( ) ;
381+ let state = harness. get_state ( id_1) ;
382+ assert ! ( approx_eq!( f64 , state. layout_rect( ) . x1, 400.0 ) ) ;
383+ } )
384+ }
320385}
0 commit comments