2023-09-24 00:13:31 +03:00
use common ::DrawTestCfg ;
use cosmic_text ::Attrs ;
use fontdb ::Family ;
mod common ;
#[ test ]
fn test_hebrew_word_rendering ( ) {
let attrs = Attrs ::new ( ) . family ( Family ::Name ( " Noto Sans " ) ) ;
DrawTestCfg ::new ( " a_hebrew_word " )
. font_size ( 36. , 40. )
. font_attrs ( attrs )
. text ( " בדיקה " )
2024-02-02 10:50:17 -07:00
. canvas ( 120 , 60 )
2023-09-24 00:13:31 +03:00
. validate_text_rendering ( ) ;
}
#[ test ]
fn test_hebrew_paragraph_rendering ( ) {
let paragraph = " השועל החום המהיר קופץ מעל הכלב העצלן " ;
let attrs = Attrs ::new ( ) . family ( Family ::Name ( " Noto Sans " ) ) ;
DrawTestCfg ::new ( " a_hebrew_paragraph " )
. font_size ( 36. , 40. )
. font_attrs ( attrs )
. text ( paragraph )
. canvas ( 400 , 110 )
. validate_text_rendering ( ) ;
}
#[ test ]
fn test_english_mixed_with_hebrew_paragraph_rendering ( ) {
let paragraph = " Many computer programs fail to display bidirectional text correctly. For example, this page is mostly LTR English script, and here is the RTL Hebrew name Sarah: שרה, spelled sin (ש) on the right, resh (ר) in the middle, and heh (ה) on the left. " ;
let attrs = Attrs ::new ( ) . family ( Family ::Name ( " Noto Sans " ) ) ;
DrawTestCfg ::new ( " some_english_mixed_with_hebrew " )
. font_size ( 16. , 20. )
. font_attrs ( attrs )
. text ( paragraph )
. canvas ( 400 , 120 )
. validate_text_rendering ( ) ;
}
#[ test ]
fn test_arabic_word_rendering ( ) {
let attrs = Attrs ::new ( ) . family ( Family ::Name ( " Noto Sans " ) ) ;
DrawTestCfg ::new ( " an_arabic_word " )
. font_size ( 36. , 40. )
. font_attrs ( attrs )
. text ( " خالصة " )
2024-02-02 10:50:17 -07:00
. canvas ( 120 , 60 )
2023-09-24 00:13:31 +03:00
. validate_text_rendering ( ) ;
}
#[ test ]
fn test_arabic_paragraph_rendering ( ) {
let paragraph = " الثعلب البني السريع يقفز فوق الكلب الكسول " ;
let attrs = Attrs ::new ( ) . family ( Family ::Name ( " Noto Sans " ) ) ;
DrawTestCfg ::new ( " an_arabic_paragraph " )
. font_size ( 36. , 40. )
. font_attrs ( attrs )
. text ( paragraph )
. canvas ( 400 , 110 )
. validate_text_rendering ( ) ;
}
#[ test ]
fn test_english_mixed_with_arabic_paragraph_rendering ( ) {
let paragraph = " I like to render اللغة العربية in Rust! " ;
let attrs = Attrs ::new ( ) . family ( Family ::Name ( " Noto Sans " ) ) ;
DrawTestCfg ::new ( " some_english_mixed_with_arabic " )
. font_size ( 36. , 40. )
. font_attrs ( attrs )
. text ( paragraph )
. canvas ( 400 , 110 )
. validate_text_rendering ( ) ;
}
2026-01-08 21:24:40 -08:00
#[ test ]
fn test_ligature_segmentation ( ) {
use cosmic_text ::{ Buffer , FontSystem , Metrics , Shaping } ;
2026-01-16 21:21:00 -08:00
let mut font_system =
FontSystem ::new_with_locale_and_db ( " en-US " . into ( ) , fontdb ::Database ::new ( ) ) ;
2026-01-08 21:24:40 -08:00
let font = std ::fs ::read ( " fonts/Inter-Regular.ttf " ) . unwrap ( ) ;
font_system . db_mut ( ) . load_font_data ( font ) ;
let metrics = Metrics ::new ( 14.0 , 20.0 ) ;
let mut buffer = Buffer ::new ( & mut font_system , metrics ) ;
let mut buffer = buffer . borrow_with ( & mut font_system ) ;
buffer . set_text ( " |> " , & Attrs ::new ( ) , Shaping ::Advanced , None ) ;
buffer . shape_until_scroll ( false ) ;
let line = & buffer . lines [ 0 ] ;
let shape = line . shape_opt ( ) . expect ( " ShapeLine not found " ) ;
let span = & shape . spans [ 0 ] ;
2026-01-16 21:35:53 -08:00
// Inter-Regular HAS a contextual alternate for |> (changing the glyph ID),
// so our probe detects it and keeps them together.
2026-01-08 21:24:40 -08:00
assert_eq! (
span . words . len ( ) ,
2026-01-16 21:35:53 -08:00
1 ,
" Expected '|>' to be 1 word (contextual alternate in Inter), but found {} words. " ,
2026-01-08 21:24:40 -08:00
span . words . len ( )
) ;
2026-01-08 21:44:45 -08:00
2026-01-16 21:21:00 -08:00
// Test -> (Arrow), which is a common ligature.
buffer . set_text ( " -> " , & Attrs ::new ( ) , Shaping ::Advanced , None ) ;
buffer . shape_until_scroll ( false ) ;
let line = & buffer . lines [ 0 ] ;
let shape = line . shape_opt ( ) . expect ( " ShapeLine not found " ) ;
assert_eq! (
shape . spans [ 0 ] . words . len ( ) ,
1 ,
" Expected '->' to be a single word (ligature), but found {} words. " ,
shape . spans [ 0 ] . words . len ( )
) ;
2026-01-08 21:44:45 -08:00
// Test !=
buffer . set_text ( " != " , & Attrs ::new ( ) , Shaping ::Advanced , None ) ;
buffer . shape_until_scroll ( false ) ;
let line = & buffer . lines [ 0 ] ;
let shape = line . shape_opt ( ) . expect ( " ShapeLine not found " ) ;
2026-01-16 21:35:53 -08:00
// Inter has a contextual alternate for != too.
2026-01-08 21:44:45 -08:00
assert_eq! (
shape . spans [ 0 ] . words . len ( ) ,
2026-01-16 21:35:53 -08:00
1 ,
" Expected '!=' to be 1 word (contextual alternate), but found {} words. " ,
2026-01-08 21:44:45 -08:00
shape . spans [ 0 ] . words . len ( )
) ;
// Test ++
buffer . set_text ( " ++ " , & Attrs ::new ( ) , Shaping ::Advanced , None ) ;
buffer . shape_until_scroll ( false ) ;
let line = & buffer . lines [ 0 ] ;
let shape = line . shape_opt ( ) . expect ( " ShapeLine not found " ) ;
2026-01-16 21:21:00 -08:00
// Inter does not have a ++ ligature.
2026-01-08 21:44:45 -08:00
assert_eq! (
shape . spans [ 0 ] . words . len ( ) ,
2026-01-16 21:21:00 -08:00
2 ,
" Expected '++' to be 2 words, but found {} words. " ,
2026-01-08 21:44:45 -08:00
shape . spans [ 0 ] . words . len ( )
) ;
2026-01-16 21:21:00 -08:00
}