@@ -291,12 +291,25 @@ impl<'text> BidiInfo<'text> {
291291 }
292292 }
293293
294- /// Re-order a line based on resolved levels and return only the embedding levels.
294+ /// Re-order a line based on resolved levels and return only the embedding levels, one `Level`
295+ /// per *byte*.
295296 pub fn reordered_levels ( & self , para : & ParagraphInfo , line : Range < usize > ) -> Vec < Level > {
296297 let ( levels, _) = self . visual_runs ( para, line. clone ( ) ) ;
297298 levels
298299 }
299300
301+ /// Re-order a line based on resolved levels and return only the embedding levels, one `Level`
302+ /// per *character*.
303+ pub fn reordered_levels_per_char (
304+ & self ,
305+ para : & ParagraphInfo ,
306+ line : Range < usize > ,
307+ ) -> Vec < Level > {
308+ let levels = self . reordered_levels ( para, line) ;
309+ self . text . char_indices ( ) . map ( |( i, _) | levels[ i] ) . collect ( )
310+ }
311+
312+
300313 /// Re-order a line based on resolved levels and return the line in display order.
301314 pub fn reorder_line ( & self , para : & ParagraphInfo , line : Range < usize > ) -> Cow < ' text , str > {
302315 let ( levels, runs) = self . visual_runs ( para, line. clone ( ) ) ;
@@ -637,6 +650,10 @@ mod tests {
637650 ] ,
638651 }
639652 ) ;
653+
654+ /// BidiTest:69635 (AL ET EN)
655+ let bidi_info = BidiInfo :: new ( "\u{060B} \u{20CF} \u{06F9} " , None ) ;
656+ assert_eq ! ( bidi_info. original_classes, vec![ AL , AL , ET , ET , ET , EN , EN ] ) ;
640657 }
641658
642659 #[ test]
@@ -754,6 +771,60 @@ mod tests {
754771 vec![ "ef].)gh&[דג(בא" ]
755772 ) ;
756773 }
774+
775+ fn reordered_levels_for_paras ( text : & str ) -> Vec < Vec < Level > > {
776+ let bidi_info = BidiInfo :: new ( text, None ) ;
777+ bidi_info
778+ . paragraphs
779+ . iter ( )
780+ . map ( |para| bidi_info. reordered_levels ( para, para. range . clone ( ) ) )
781+ . collect ( )
782+ }
783+
784+ fn reordered_levels_per_char_for_paras ( text : & str ) -> Vec < Vec < Level > > {
785+ let bidi_info = BidiInfo :: new ( text, None ) ;
786+ bidi_info
787+ . paragraphs
788+ . iter ( )
789+ . map ( |para| bidi_info. reordered_levels_per_char ( para, para. range . clone ( ) ) )
790+ . collect ( )
791+ }
792+
793+ #[ test]
794+ fn test_reordered_levels ( ) {
795+
796+ /// BidiTest:946 (LRI PDI)
797+ let text = "\u{2067} \u{2069} " ;
798+ assert_eq ! (
799+ reordered_levels_for_paras( text) ,
800+ vec![ Level :: vec( & [ 0 , 0 , 0 , 0 , 0 , 0 ] ) ]
801+ ) ;
802+ assert_eq ! (
803+ reordered_levels_per_char_for_paras( text) ,
804+ vec![ Level :: vec( & [ 0 , 0 ] ) ]
805+ ) ;
806+
807+ /* TODO
808+ /// BidiTest:69635 (AL ET EN)
809+ let text = "\u{060B}\u{20CF}\u{06F9}";
810+ assert_eq!(
811+ reordered_levels_for_paras(text),
812+ vec![Level::vec(&[1, 1, 1, 1, 1, 2, 2])]
813+ );
814+ assert_eq!(
815+ reordered_levels_per_char_for_paras(text),
816+ vec![Level::vec(&[1, 1, 2])]
817+ );
818+ */
819+
820+ /* TODO
821+ // BidiTest:291284 (AN RLI PDF R)
822+ assert_eq!(
823+ reordered_levels_per_char_for_paras("\u{0605}\u{2067}\u{202C}\u{0590}"),
824+ vec![&["2", "0", "x", "1"]]
825+ );
826+ */
827+ }
757828}
758829
759830
0 commit comments