@@ -126,32 +126,94 @@ fn layout_multiline_text<'a, F: FnMut(&'a str)>(
126126 if max_width == 0 || line. is_empty ( ) {
127127 func ( line) ;
128128 } else {
129- let mut remaining = & line[ 0 ..] ;
129+ let mut indices = line. char_indices ( ) . map ( |( idx, _) | idx) . peekable ( ) ;
130+ let font2 = font. clone ( ) ;
130131
131- while !remaining. is_empty ( ) {
132- let mut left = 0 ;
133- while left < remaining. len ( ) {
134- let width = font. box_size ( & remaining[ 0 ..=left] ) . unwrap_or ( ( 0 , 0 ) ) . 0 as i32 ;
132+ let it = std:: iter:: from_fn ( || {
133+ let start_idx = match indices. next ( ) {
134+ Some ( idx) => idx,
135+ None => return None ,
136+ } ;
135137
138+ // iterate over indices
139+ while let Some ( idx) = indices. next ( ) {
140+ let substring = & line[ start_idx..idx] ;
141+ let width = font2. box_size ( substring) . unwrap_or ( ( 0 , 0 ) ) . 0 as i32 ;
136142 if width > max_width as i32 {
137143 break ;
138144 }
139- left += 1 ;
140145 }
141146
142- if left == 0 {
143- left += 1 ;
144- }
147+ let end_idx = match indices. peek ( ) {
148+ Some ( idx) => * idx,
149+ None => line. bytes ( ) . len ( ) ,
150+ } ;
145151
146- let cur_line = & remaining [ ..left ] ;
147- remaining = & remaining [ left.. ] ;
152+ Some ( & line [ start_idx..end_idx ] )
153+ } ) ;
148154
149- func ( cur_line) ;
155+ for chunk in it {
156+ func ( chunk) ;
150157 }
151158 }
152159 }
153160}
154161
162+ #[ cfg( test) ]
163+ #[ test]
164+ fn test_multi_layout ( ) {
165+ use plotters_backend:: { FontFamily , FontStyle } ;
166+
167+ let font = FontDesc :: new ( FontFamily :: SansSerif , 20 as f64 , FontStyle :: Bold ) ;
168+
169+ layout_multiline_text ( "öäabcde" , 40 , font, |txt| {
170+ println ! ( "Got: {}" , txt) ;
171+ assert ! ( txt == "öäabc" || txt == "de" ) ;
172+ } ) ;
173+
174+ let font = FontDesc :: new ( FontFamily :: SansSerif , 20 as f64 , FontStyle :: Bold ) ;
175+ layout_multiline_text ( "öä" , 40 , font, |txt| {
176+ println ! ( "Got: {}" , txt) ;
177+ assert_eq ! ( txt, "öä" )
178+ } ) ;
179+ }
180+
181+ // fn layout_multiline_text<'a, F: FnMut(&'a str)>(
182+ // text: &'a str,
183+ // max_width: u32,
184+ // font: FontDesc<'a>,
185+ // mut func: F,
186+ // ) {
187+ // for line in text.lines() {
188+ // if max_width == 0 || line.is_empty() {
189+ // func(line);
190+ // } else {
191+ // let mut remaining = &line[0..];
192+
193+ // while !remaining.is_empty() {
194+ // let mut left = 0;
195+ // while left < remaining.len() {
196+ // let width = font.box_size(&remaining[0..=left]).unwrap_or((0, 0)).0 as i32;
197+
198+ // if width > max_width as i32 {
199+ // break;
200+ // }
201+ // left += 1;
202+ // }
203+
204+ // if left == 0 {
205+ // left += 1;
206+ // }
207+
208+ // let cur_line = &remaining[..left];
209+ // remaining = &remaining[left..];
210+
211+ // func(cur_line);
212+ // }
213+ // }
214+ // }
215+ // }
216+
155217impl < ' a , T : Borrow < str > > MultiLineText < ' a , BackendCoord , T > {
156218 /// Compute the line layout
157219 pub fn compute_line_layout ( & self ) -> FontResult < Vec < LayoutBox > > {
0 commit comments