#[cfg(test)]
mod tests {
use crate::font::metrics::{FaceMetrics, Metrics};
struct TestFontData {
name: &'static str,
face: FaceMetrics,
}
impl TestFontData {
fn cascadia_code() -> Self {
Self {
name: "Cascadia Code",
face: FaceMetrics {
cell_width: 9.6,
ascent: 11.5,
descent: 2.5,
line_gap: 0.8,
underline_position: Some(-1.2),
underline_thickness: Some(1.0),
strikethrough_position: Some(5.8),
strikethrough_thickness: Some(1.0),
cap_height: Some(8.7),
ex_height: Some(5.8),
ic_width: None,
},
}
}
fn noto_sans_cjk() -> Self {
Self {
name: "Noto Sans CJK",
face: FaceMetrics {
cell_width: 19.2, ascent: 13.8,
descent: 3.2,
line_gap: 1.2,
underline_position: Some(-1.8),
underline_thickness: Some(1.1),
strikethrough_position: Some(6.9),
strikethrough_thickness: Some(1.1),
cap_height: Some(10.4),
ex_height: Some(6.9),
ic_width: None,
},
}
}
fn source_han_sans() -> Self {
Self {
name: "Source Han Sans",
face: FaceMetrics {
cell_width: 18.8,
ascent: 14.2,
descent: 3.8,
line_gap: 1.0,
underline_position: Some(-2.0),
underline_thickness: Some(1.2),
strikethrough_position: Some(7.1),
strikethrough_thickness: Some(1.2),
cap_height: Some(10.7),
ex_height: Some(7.1),
ic_width: None,
},
}
}
fn wenquanyi_micro_hei() -> Self {
Self {
name: "WenQuanYi Micro Hei",
face: FaceMetrics {
cell_width: 20.0,
ascent: 15.0,
descent: 4.0,
line_gap: 1.5,
underline_position: Some(-1.5),
underline_thickness: Some(1.0),
strikethrough_position: Some(7.5),
strikethrough_thickness: Some(1.0),
cap_height: Some(11.25),
ex_height: Some(7.5),
ic_width: None,
},
}
}
fn dejavu_sans_mono() -> Self {
Self {
name: "DejaVu Sans Mono",
face: FaceMetrics {
cell_width: 8.4,
ascent: 10.8,
descent: 2.2,
line_gap: 0.6,
underline_position: Some(-1.0),
underline_thickness: Some(0.8),
strikethrough_position: Some(5.4),
strikethrough_thickness: Some(0.8),
cap_height: Some(8.1),
ex_height: Some(5.4),
ic_width: None,
},
}
}
fn noto_color_emoji() -> Self {
Self {
name: "Noto Color Emoji",
face: FaceMetrics {
cell_width: 20.0, ascent: 14.0,
descent: 3.5,
line_gap: 1.0,
underline_position: Some(-2.0),
underline_thickness: Some(1.2),
strikethrough_position: Some(7.0),
strikethrough_thickness: Some(1.2),
cap_height: Some(10.5),
ex_height: Some(7.0),
ic_width: None,
},
}
}
}
#[test]
fn test_cjk_font_consistency_with_latin_primary() {
let latin_font = TestFontData::cascadia_code();
let cjk_fonts = vec![
TestFontData::noto_sans_cjk(),
TestFontData::source_han_sans(),
TestFontData::wenquanyi_micro_hei(),
];
let primary_metrics = Metrics::calc(latin_font.face);
for cjk_font in cjk_fonts {
let cjk_metrics = Metrics::calc_with_primary_cell_dimensions(
cjk_font.face,
&primary_metrics,
);
assert_eq!(
cjk_metrics.cell_width, primary_metrics.cell_width,
"{} should use primary cell width",
cjk_font.name
);
assert_eq!(
cjk_metrics.cell_height, primary_metrics.cell_height,
"{} should use primary cell height",
cjk_font.name
);
assert_eq!(
cjk_metrics.cell_baseline, primary_metrics.cell_baseline,
"{} should use primary baseline",
cjk_font.name
);
assert_eq!(
cjk_metrics.cursor_height, primary_metrics.cursor_height,
"{} should use primary cursor height",
cjk_font.name
);
assert!(
cjk_metrics.cell_width > 0,
"{} cell width should be positive",
cjk_font.name
);
assert!(
cjk_metrics.cell_height > 0,
"{} cell height should be positive",
cjk_font.name
);
assert!(
cjk_metrics.cell_baseline < cjk_metrics.cell_height,
"{} baseline should be within cell height",
cjk_font.name
);
}
}
#[test]
fn test_multiple_latin_fonts_consistency() {
let fonts = [
TestFontData::cascadia_code(),
TestFontData::dejavu_sans_mono(),
];
let primary_metrics = Metrics::calc(fonts[0].face);
for font in fonts.iter().skip(1) {
let font_metrics =
Metrics::calc_with_primary_cell_dimensions(font.face, &primary_metrics);
assert_eq!(
font_metrics.cell_width, primary_metrics.cell_width,
"{} should use primary cell width",
font.name
);
assert_eq!(
font_metrics.cell_height, primary_metrics.cell_height,
"{} should use primary cell height",
font.name
);
assert_eq!(
font_metrics.cell_baseline, primary_metrics.cell_baseline,
"{} should use primary baseline",
font.name
);
}
}
#[test]
fn test_cjk_primary_font_scenario() {
let cjk_font = TestFontData::noto_sans_cjk();
let latin_font = TestFontData::cascadia_code();
let primary_metrics = Metrics::calc(cjk_font.face);
let latin_metrics =
Metrics::calc_with_primary_cell_dimensions(latin_font.face, &primary_metrics);
assert_eq!(latin_metrics.cell_width, primary_metrics.cell_width);
assert_eq!(latin_metrics.cell_height, primary_metrics.cell_height);
assert_eq!(latin_metrics.cell_baseline, primary_metrics.cell_baseline);
let expected_height = (cjk_font.face.ascent
+ cjk_font.face.descent
+ (cjk_font.face.line_gap * 2.0))
.ceil() as u32;
assert_eq!(primary_metrics.cell_height, expected_height);
}
#[test]
fn test_rich_text_format_consistency() {
let latin_font = TestFontData::cascadia_code();
let cjk_font = TestFontData::noto_sans_cjk();
let primary_metrics = Metrics::calc(latin_font.face);
let cjk_metrics =
Metrics::calc_with_primary_cell_dimensions(cjk_font.face, &primary_metrics);
let (latin_ascent, latin_descent, latin_leading) =
primary_metrics.for_rich_text();
let (cjk_ascent, cjk_descent, cjk_leading) = cjk_metrics.for_rich_text();
assert_eq!(
latin_ascent, cjk_ascent,
"Rich text ascent should be consistent"
);
assert_eq!(
latin_descent, cjk_descent,
"Rich text descent should be consistent"
);
assert_eq!(
latin_leading, cjk_leading,
"Rich text leading should be consistent"
);
assert!(latin_ascent > 0.0, "Ascent should be positive");
assert!(latin_descent > 0.0, "Descent should be positive");
assert_eq!(
latin_leading, 0.0,
"Leading should be 0 (incorporated into height)"
);
assert_eq!(
latin_ascent + latin_descent,
primary_metrics.cell_height as f32
);
}
#[test]
fn test_underline_positioning_across_fonts() {
let latin_font = TestFontData::cascadia_code();
let cjk_font = TestFontData::noto_sans_cjk();
let primary_metrics = Metrics::calc(latin_font.face);
let cjk_metrics =
Metrics::calc_with_primary_cell_dimensions(cjk_font.face, &primary_metrics);
assert!(primary_metrics.underline_position <= primary_metrics.cell_height);
assert!(primary_metrics.underline_thickness > 0);
assert!(cjk_metrics.underline_thickness > 0);
assert_eq!(cjk_metrics.cell_width, primary_metrics.cell_width);
assert_eq!(cjk_metrics.cell_height, primary_metrics.cell_height);
assert_eq!(cjk_metrics.cell_baseline, primary_metrics.cell_baseline);
}
#[test]
fn test_strikethrough_positioning_across_fonts() {
let latin_font = TestFontData::cascadia_code();
let cjk_font = TestFontData::noto_sans_cjk();
let primary_metrics = Metrics::calc(latin_font.face);
let cjk_metrics =
Metrics::calc_with_primary_cell_dimensions(cjk_font.face, &primary_metrics);
assert!(primary_metrics.strikethrough_position < primary_metrics.cell_height);
assert!(cjk_metrics.strikethrough_position < cjk_metrics.cell_height);
assert!(primary_metrics.strikethrough_thickness > 0);
assert!(cjk_metrics.strikethrough_thickness > 0);
assert!(
primary_metrics.strikethrough_position < primary_metrics.underline_position
);
assert!(cjk_metrics.strikethrough_position < cjk_metrics.underline_position);
}
#[test]
fn test_extreme_font_metrics() {
let tiny_font = FaceMetrics {
cell_width: 1.0,
ascent: 2.0,
descent: 0.5,
line_gap: 0.1,
underline_position: Some(-0.1),
underline_thickness: Some(0.1),
strikethrough_position: Some(1.0),
strikethrough_thickness: Some(0.1),
cap_height: Some(1.5),
ex_height: Some(1.0),
ic_width: None,
};
let huge_font = FaceMetrics {
cell_width: 100.0,
ascent: 120.0,
descent: 30.0,
line_gap: 10.0,
underline_position: Some(-5.0),
underline_thickness: Some(3.0),
strikethrough_position: Some(60.0),
strikethrough_thickness: Some(3.0),
cap_height: Some(90.0),
ex_height: Some(60.0),
ic_width: None,
};
let tiny_metrics = Metrics::calc(tiny_font);
let huge_metrics =
Metrics::calc_with_primary_cell_dimensions(huge_font, &tiny_metrics);
assert_eq!(huge_metrics.cell_width, tiny_metrics.cell_width);
assert_eq!(huge_metrics.cell_height, tiny_metrics.cell_height);
assert_eq!(huge_metrics.cell_baseline, tiny_metrics.cell_baseline);
assert!(tiny_metrics.cell_width > 0);
assert!(tiny_metrics.cell_height > 0);
assert!(huge_metrics.cell_width > 0);
assert!(huge_metrics.cell_height > 0);
}
#[test]
fn test_line_height_calculation_precision() {
let font = FaceMetrics {
cell_width: 9.6,
ascent: 11.7,
descent: 2.3,
line_gap: 0.9,
underline_position: None,
underline_thickness: None,
strikethrough_position: None,
strikethrough_thickness: None,
cap_height: None,
ex_height: None,
ic_width: None,
};
let metrics = Metrics::calc(font);
let expected_height =
(font.ascent + font.descent + (font.line_gap * 2.0)).ceil() as u32;
assert_eq!(metrics.cell_height, expected_height);
assert_eq!(metrics.cell_width, 10);
}
#[test]
fn test_baseline_consistency_across_font_combinations() {
let fonts = [
TestFontData::cascadia_code(),
TestFontData::dejavu_sans_mono(),
TestFontData::noto_sans_cjk(),
TestFontData::source_han_sans(),
TestFontData::wenquanyi_micro_hei(),
];
for (i, primary_font) in fonts.iter().enumerate() {
let primary_metrics = Metrics::calc(primary_font.face);
for (j, secondary_font) in fonts.iter().enumerate() {
if i == j {
continue;
}
let secondary_metrics = Metrics::calc_with_primary_cell_dimensions(
secondary_font.face,
&primary_metrics,
);
assert_eq!(
secondary_metrics.cell_baseline, primary_metrics.cell_baseline,
"Baseline inconsistent: {} primary, {} secondary",
primary_font.name, secondary_font.name
);
assert_eq!(
secondary_metrics.cell_width, primary_metrics.cell_width,
"Cell width inconsistent: {} primary, {} secondary",
primary_font.name, secondary_font.name
);
assert_eq!(
secondary_metrics.cell_height, primary_metrics.cell_height,
"Cell height inconsistent: {} primary, {} secondary",
primary_font.name, secondary_font.name
);
}
}
}
#[test]
fn test_issue_1071_cjk_latin_line_height_consistency() {
let latin_font = FaceMetrics {
cell_width: 9.0,
ascent: 11.0,
descent: 3.0,
line_gap: 1.0,
underline_position: Some(-1.0),
underline_thickness: Some(1.0),
strikethrough_position: Some(5.5),
strikethrough_thickness: Some(1.0),
cap_height: Some(8.5),
ex_height: Some(5.5),
ic_width: None,
};
let cjk_font = FaceMetrics {
cell_width: 18.0, ascent: 14.0, descent: 4.0, line_gap: 2.0, underline_position: Some(-1.5),
underline_thickness: Some(1.2),
strikethrough_position: Some(7.0),
strikethrough_thickness: Some(1.2),
cap_height: Some(10.5),
ex_height: Some(7.0),
ic_width: Some(36.0), };
let latin_metrics = Metrics::calc(latin_font);
let cjk_metrics =
Metrics::calc_with_primary_cell_dimensions(cjk_font, &latin_metrics);
assert_eq!(
cjk_metrics.cell_height,
latin_metrics.cell_height,
"CJK and Latin fonts must have identical cell heights to prevent scrolling issues"
);
assert_eq!(
cjk_metrics.cell_width, latin_metrics.cell_width,
"CJK and Latin fonts must have identical cell widths for consistent grid"
);
assert_eq!(
cjk_metrics.cell_baseline,
latin_metrics.cell_baseline,
"CJK and Latin fonts must have identical baselines to prevent text misalignment"
);
let lines_to_scroll = 4;
let expected_scroll_distance = lines_to_scroll * latin_metrics.cell_height;
let actual_scroll_distance = lines_to_scroll * cjk_metrics.cell_height;
assert_eq!(
expected_scroll_distance,
actual_scroll_distance,
"Scroll distance calculation must be consistent between Latin and CJK content"
);
}
#[test]
fn test_issue_1071_long_cjk_text_scrolling() {
let primary_font = FaceMetrics {
cell_width: 10.0,
ascent: 12.0,
descent: 3.0,
line_gap: 1.0,
underline_position: Some(-1.0),
underline_thickness: Some(1.0),
strikethrough_position: Some(6.0),
strikethrough_thickness: Some(1.0),
cap_height: Some(9.0),
ex_height: Some(6.0),
ic_width: None,
};
let cjk_font = FaceMetrics {
cell_width: 20.0,
ascent: 15.0,
descent: 4.0,
line_gap: 2.0,
underline_position: Some(-2.0),
underline_thickness: Some(1.5),
strikethrough_position: Some(7.5),
strikethrough_thickness: Some(1.5),
cap_height: Some(11.0),
ex_height: Some(7.5),
ic_width: Some(40.0),
};
let primary_metrics = Metrics::calc(primary_font);
let cjk_metrics =
Metrics::calc_with_primary_cell_dimensions(cjk_font, &primary_metrics);
let terminal_rows = 24; let content_lines = 30; let lines_to_scroll = content_lines - terminal_rows;
let latin_based_scroll = lines_to_scroll * primary_metrics.cell_height;
let cjk_based_scroll = lines_to_scroll * cjk_metrics.cell_height;
assert_eq!(
latin_based_scroll, cjk_based_scroll,
"Scroll calculations must be identical for Latin and CJK content"
);
let total_content_height = content_lines * cjk_metrics.cell_height;
let visible_area_height = terminal_rows * cjk_metrics.cell_height;
let scroll_position = total_content_height - visible_area_height;
let input_line_position = total_content_height - cjk_metrics.cell_height;
let input_line_visible = input_line_position >= scroll_position;
assert!(
input_line_visible,
"Input line must remain visible after scrolling CJK content"
);
}
#[test]
fn test_issue_1071_printf_command_scrolling() {
let latin_font = FaceMetrics {
cell_width: 8.0,
ascent: 10.0,
descent: 2.0,
line_gap: 0.5,
underline_position: Some(-1.0),
underline_thickness: Some(1.0),
strikethrough_position: Some(5.0),
strikethrough_thickness: Some(1.0),
cap_height: Some(7.5),
ex_height: Some(5.0),
ic_width: None,
};
let cjk_font = FaceMetrics {
cell_width: 16.0,
ascent: 13.0,
descent: 3.5,
line_gap: 1.5,
underline_position: Some(-1.5),
underline_thickness: Some(1.2),
strikethrough_position: Some(6.5),
strikethrough_thickness: Some(1.2),
cap_height: Some(9.5),
ex_height: Some(6.5),
ic_width: Some(32.0),
};
let latin_metrics = Metrics::calc(latin_font);
let cjk_metrics =
Metrics::calc_with_primary_cell_dimensions(cjk_font, &latin_metrics);
let printf_output_lines = 4;
let expected_scroll_distance = printf_output_lines * latin_metrics.cell_height;
let actual_content_height = printf_output_lines * cjk_metrics.cell_height;
assert_eq!(
expected_scroll_distance, actual_content_height,
"printf output height calculation must be consistent between font types"
);
assert_eq!(
latin_metrics.cell_height, cjk_metrics.cell_height,
"Both fonts must use same cell height to prevent printf scrolling issues"
);
}
#[test]
fn test_issue_1071_baseline_adjustment_consistency() {
let font = FaceMetrics {
cell_width: 10.0,
ascent: 12.0,
descent: 3.0,
line_gap: 1.0,
underline_position: Some(-1.0),
underline_thickness: Some(1.0),
strikethrough_position: Some(6.0),
strikethrough_thickness: Some(1.0),
cap_height: Some(9.0),
ex_height: Some(6.0),
ic_width: None,
};
let mut metrics = Metrics::calc(font);
let original_baseline = metrics.get_baseline_adjustment();
let new_height = metrics.cell_height + 4;
metrics.apply_cell_height_adjustment(new_height);
let adjusted_baseline = metrics.get_baseline_adjustment();
assert_eq!(adjusted_baseline, original_baseline + 2.0);
let (ascent, descent, _) = metrics.for_rich_text();
assert_eq!(ascent + descent, new_height as f32);
}
#[test]
fn test_issue_1071_cjk_font_size_normalization() {
let latin_font = FaceMetrics {
cell_width: 9.0,
ascent: 11.0,
descent: 2.5,
line_gap: 0.8,
underline_position: Some(-1.0),
underline_thickness: Some(1.0),
strikethrough_position: Some(5.5),
strikethrough_thickness: Some(1.0),
cap_height: Some(8.5),
ex_height: Some(5.5),
ic_width: Some(18.0), };
let cjk_font = FaceMetrics {
cell_width: 18.0,
ascent: 14.0,
descent: 3.5,
line_gap: 1.2,
underline_position: Some(-1.5),
underline_thickness: Some(1.2),
strikethrough_position: Some(7.0),
strikethrough_thickness: Some(1.2),
cap_height: Some(10.5),
ex_height: Some(7.0),
ic_width: Some(36.0), };
let size_adjustment =
Metrics::calculate_cjk_font_size_adjustment(&latin_font, &cjk_font);
assert!(
size_adjustment.is_some(),
"Font size adjustment should be calculated"
);
let adjustment_ratio = size_adjustment.unwrap();
assert!((adjustment_ratio - 0.5).abs() < 0.001);
}
#[test]
fn test_issue_1071_complete_fix_integration() {
let latin_font = FaceMetrics {
cell_width: 10.0,
ascent: 12.0,
descent: 3.0,
line_gap: 1.0,
underline_position: Some(-1.0),
underline_thickness: Some(1.0),
strikethrough_position: Some(6.0),
strikethrough_thickness: Some(1.0),
cap_height: Some(9.0),
ex_height: Some(6.0),
ic_width: None,
};
let cjk_font = FaceMetrics {
cell_width: 20.0,
ascent: 15.0,
descent: 4.0,
line_gap: 2.0,
underline_position: Some(-2.0),
underline_thickness: Some(1.5),
strikethrough_position: Some(7.5),
strikethrough_thickness: Some(1.5),
cap_height: Some(11.0),
ex_height: Some(7.5),
ic_width: Some(40.0),
};
let primary_metrics = Metrics::calc(latin_font);
let cjk_metrics =
Metrics::calc_with_primary_cell_dimensions(cjk_font, &primary_metrics);
assert_eq!(primary_metrics.cell_height, cjk_metrics.cell_height);
assert_eq!(primary_metrics.cell_width, cjk_metrics.cell_width);
assert_eq!(primary_metrics.cell_baseline, cjk_metrics.cell_baseline);
let (latin_ascent, latin_descent, latin_leading) =
primary_metrics.for_rich_text();
let (cjk_ascent, cjk_descent, cjk_leading) = cjk_metrics.for_rich_text();
assert_eq!(latin_ascent, cjk_ascent);
assert_eq!(latin_descent, cjk_descent);
assert_eq!(latin_leading, cjk_leading);
assert_eq!(
primary_metrics.get_baseline_adjustment(),
cjk_metrics.get_baseline_adjustment()
);
let terminal_rows = 24;
let content_lines = 30;
let scroll_lines = content_lines - terminal_rows;
let latin_scroll_height = scroll_lines * primary_metrics.cell_height;
let cjk_scroll_height = scroll_lines * cjk_metrics.cell_height;
assert_eq!(latin_scroll_height, cjk_scroll_height);
assert_eq!(cjk_metrics.cell_height, primary_metrics.cell_height);
}
#[test]
fn test_issue_1071_mixed_content_consistency() {
let latin_font = FaceMetrics {
cell_width: 8.0,
ascent: 10.0,
descent: 2.0,
line_gap: 0.5,
underline_position: Some(-1.0),
underline_thickness: Some(1.0),
strikethrough_position: Some(5.0),
strikethrough_thickness: Some(1.0),
cap_height: Some(7.5),
ex_height: Some(5.0),
ic_width: None,
};
let cjk_font = FaceMetrics {
cell_width: 16.0,
ascent: 12.0,
descent: 3.0,
line_gap: 1.0,
underline_position: Some(-1.5),
underline_thickness: Some(1.2),
strikethrough_position: Some(6.0),
strikethrough_thickness: Some(1.2),
cap_height: Some(9.0),
ex_height: Some(6.0),
ic_width: Some(32.0),
};
let latin_metrics = Metrics::calc(latin_font);
let cjk_metrics =
Metrics::calc_with_primary_cell_dimensions(cjk_font, &latin_metrics);
let mixed_line_height = latin_metrics.cell_height; let cjk_line_height = cjk_metrics.cell_height;
assert_eq!(
mixed_line_height, cjk_line_height,
"Mixed content lines must have consistent height"
);
let line_count = 5;
let total_height_latin = line_count * latin_metrics.cell_height;
let total_height_mixed = line_count * cjk_metrics.cell_height;
assert_eq!(
total_height_latin, total_height_mixed,
"Mixed content must not affect total height calculations"
);
}
#[test]
fn test_edge_cases() {
let tiny_font = FaceMetrics {
cell_width: 0.1,
ascent: 0.1,
descent: 0.05,
line_gap: 0.01,
underline_position: Some(-0.01),
underline_thickness: Some(0.01),
strikethrough_position: Some(0.05),
strikethrough_thickness: Some(0.01),
cap_height: Some(0.08),
ex_height: Some(0.05),
ic_width: None,
};
let tiny_metrics = Metrics::calc(tiny_font);
assert!(
tiny_metrics.cell_width >= 1,
"Cell width must be at least 1 pixel"
);
assert!(
tiny_metrics.cell_height >= 1,
"Cell height must be at least 1 pixel"
);
assert!(
tiny_metrics.underline_thickness >= 1,
"Line thickness must be at least 1 pixel"
);
let huge_font = FaceMetrics {
cell_width: 1000.0,
ascent: 1200.0,
descent: 300.0,
line_gap: 100.0,
underline_position: Some(-100.0),
underline_thickness: Some(100.0),
strikethrough_position: Some(600.0),
strikethrough_thickness: Some(100.0),
cap_height: Some(900.0),
ex_height: Some(600.0),
ic_width: None,
};
let huge_metrics = Metrics::calc(huge_font);
assert_eq!(
huge_metrics.cell_width, 1000,
"Large font metrics should be preserved"
);
assert_eq!(
huge_metrics.cell_height, 1700,
"Large font height calculation"
);
let minimal_font = FaceMetrics {
cell_width: 10.0,
ascent: 12.0,
descent: 3.0,
line_gap: 1.0,
underline_position: None,
underline_thickness: None,
strikethrough_position: None,
strikethrough_thickness: None,
cap_height: None,
ex_height: None,
ic_width: None,
};
let minimal_metrics = Metrics::calc(minimal_font);
assert!(
minimal_metrics.underline_thickness >= 1,
"Default underline thickness"
);
assert!(
minimal_metrics.strikethrough_thickness >= 1,
"Default strikethrough thickness"
);
assert!(
minimal_metrics.underline_position > 0,
"Default underline position"
);
assert!(
minimal_metrics.strikethrough_position > 0,
"Default strikethrough position"
);
}
#[test]
fn test_mixed_script_rendering() {
let latin_font = TestFontData::cascadia_code();
let cjk_font = TestFontData::noto_sans_cjk();
let emoji_font = TestFontData::noto_color_emoji();
let latin_metrics = Metrics::calc(latin_font.face);
let cjk_metrics =
Metrics::calc_with_primary_cell_dimensions(cjk_font.face, &latin_metrics);
let emoji_metrics =
Metrics::calc_with_primary_cell_dimensions(emoji_font.face, &latin_metrics);
assert_eq!(latin_metrics.cell_height, cjk_metrics.cell_height);
assert_eq!(latin_metrics.cell_height, emoji_metrics.cell_height);
assert_eq!(latin_metrics.cell_baseline, cjk_metrics.cell_baseline);
assert_eq!(latin_metrics.cell_baseline, emoji_metrics.cell_baseline);
let mixed_line_height = latin_metrics.cell_height;
let latin_only_height = latin_metrics.cell_height;
let cjk_only_height = cjk_metrics.cell_height;
let emoji_only_height = emoji_metrics.cell_height;
assert_eq!(
mixed_line_height, latin_only_height,
"Mixed script lines must have same height as single script lines"
);
assert_eq!(mixed_line_height, cjk_only_height);
assert_eq!(mixed_line_height, emoji_only_height);
}
}