@@ -47,6 +47,11 @@ enum TuiTextOverflow {
4747 Clip ,
4848 Ellipsis ,
4949}
50+ #[ derive( Clone , Copy ) ]
51+ struct TuiTextMeasurement {
52+ available_width : u16 ,
53+ natural_size : TuiSize ,
54+ }
5055
5156pub struct TuiText {
5257 /// Styled runs that concatenate into the full text. Runs may contain hard
@@ -56,6 +61,7 @@ pub struct TuiText {
5661 style : TuiStyle ,
5762 wrap : bool ,
5863 overflow : TuiTextOverflow ,
64+ cached_measurement : Option < TuiTextMeasurement > ,
5965 size : Option < TuiSize > ,
6066 origin : Option < TuiScreenPoint > ,
6167}
@@ -75,6 +81,7 @@ impl TuiText {
7581 style : TuiStyle :: default ( ) ,
7682 wrap : true ,
7783 overflow : TuiTextOverflow :: default ( ) ,
84+ cached_measurement : None ,
7885 size : None ,
7986 origin : None ,
8087 }
@@ -262,18 +269,30 @@ impl TuiElement for TuiText {
262269 _ctx : & mut TuiLayoutContext ,
263270 _app : & AppContext ,
264271 ) -> TuiSize {
265- let size = if self . is_empty ( ) {
266- constraint. clamp ( TuiSize :: ZERO )
272+ let width = constraint. max . width ;
273+ let natural_size = if self . is_empty ( ) {
274+ TuiSize :: ZERO
275+ } else if let Some ( measurement) = self
276+ . cached_measurement
277+ . filter ( |measurement| measurement. available_width == width)
278+ {
279+ measurement. natural_size
267280 } else {
268281 let paragraph = self . paragraph ( constraint. max . width ) ;
269282 let height =
270283 u16:: try_from ( paragraph. line_count ( constraint. max . width ) ) . unwrap_or ( u16:: MAX ) ;
271284 let content_width = u16:: try_from ( paragraph. line_width ( ) ) . unwrap_or ( u16:: MAX ) ;
272- TuiSize :: new (
273- constraint. constrain_width ( content_width) ,
274- constraint. constrain_height ( height) ,
275- )
285+ let size = TuiSize :: new ( content_width, height) ;
286+ self . cached_measurement = Some ( TuiTextMeasurement {
287+ available_width : width,
288+ natural_size : size,
289+ } ) ;
290+ size
276291 } ;
292+ let size = TuiSize :: new (
293+ constraint. constrain_width ( natural_size. width ) ,
294+ constraint. constrain_height ( natural_size. height ) ,
295+ ) ;
277296 self . size = Some ( size) ;
278297 size
279298 }
0 commit comments