use pdf_oxide::fonts::{FontSubsetter, TrueTypeError, UnicodeEncoder};
use pdf_oxide::writer::{EmbeddedFont, EmbeddedFontManager};
#[test]
fn test_font_subsetter_tracks_glyphs() {
let mut subsetter = FontSubsetter::new();
subsetter.use_char(0x0041, 1); subsetter.use_char(0x0042, 2); subsetter.use_char(0x0043, 3);
assert_eq!(subsetter.char_count(), 3);
assert_eq!(subsetter.glyph_count(), 3);
let used = subsetter.used_glyphs();
assert!(used.contains(&1));
assert!(used.contains(&2));
assert!(used.contains(&3));
}
#[test]
fn test_subset_tag_deterministic() {
let mut subsetter1 = FontSubsetter::new();
subsetter1.use_char(0x0041, 1);
subsetter1.use_char(0x0042, 2);
let mut subsetter2 = FontSubsetter::new();
subsetter2.use_char(0x0041, 1);
subsetter2.use_char(0x0042, 2);
let tag1 = subsetter1.generate_subset_tag().to_string();
let tag2 = subsetter2.generate_subset_tag().to_string();
assert_eq!(tag1, tag2);
assert_eq!(tag1.len(), 6);
assert!(tag1.chars().all(|c| c.is_ascii_uppercase()));
}
#[test]
fn test_unicode_encoder_identity_h() {
let mut encoder = UnicodeEncoder::new();
let lookup = |cp: u32| match cp {
0x41 => Some(0x0001_u16), 0x42 => Some(0x0002_u16), 0x43 => Some(0x0003_u16), _ => None,
};
let encoded = encoder.encode_identity_h("ABC", lookup);
assert_eq!(encoded, "<000100020003>");
}
#[test]
fn test_unicode_encoder_missing_glyph() {
let mut encoder = UnicodeEncoder::new();
let lookup = |_: u32| None;
let encoded = encoder.encode_identity_h("A", lookup);
assert_eq!(encoded, "<0000>");
}
#[test]
fn test_utf16be_encoding() {
let result = UnicodeEncoder::encode_utf16be("A");
assert!(result.starts_with("<FEFF")); assert!(result.contains("0041"));
let result = UnicodeEncoder::encode_utf16be("\u{1F600}"); assert!(result.contains("D83D")); assert!(result.contains("DE00")); }
#[test]
fn test_literal_string_encoding() {
let result = UnicodeEncoder::encode_literal("Hello");
assert_eq!(result, "(Hello)");
let result = UnicodeEncoder::encode_literal("(test)");
assert_eq!(result, "(\\(test\\))");
}
#[test]
fn test_embedded_font_manager() {
let manager = EmbeddedFontManager::new();
assert!(manager.is_empty());
assert_eq!(manager.len(), 0);
}
#[test]
fn test_invalid_font_data_rejected() {
let result = EmbeddedFont::from_data(None, vec![0, 1, 2, 3]);
assert!(result.is_err());
let err = result.unwrap_err();
assert!(err.contains("Failed to parse font"));
}
#[test]
fn test_empty_font_data_rejected() {
let result = EmbeddedFont::from_data(None, vec![]);
assert!(result.is_err());
}
#[test]
fn test_tounicode_cmap_format() {
let mut subsetter = FontSubsetter::new();
subsetter.use_char(0x0041, 1); subsetter.use_char(0x0042, 2);
let used_chars = subsetter.used_chars();
assert_eq!(used_chars.len(), 2);
assert_eq!(used_chars.get(&0x0041), Some(&1));
assert_eq!(used_chars.get(&0x0042), Some(&2));
}
#[test]
fn test_widths_array_generation() {
let mut subsetter = FontSubsetter::new();
subsetter.use_char(0x0041, 10); subsetter.use_char(0x0042, 11); subsetter.use_char(0x0043, 12);
subsetter.use_char(0x0044, 20);
let used_glyphs = subsetter.used_glyphs();
assert_eq!(used_glyphs.len(), 4);
assert!(used_glyphs.contains(&10));
assert!(used_glyphs.contains(&11));
assert!(used_glyphs.contains(&12));
assert!(used_glyphs.contains(&20));
}
#[test]
fn test_truetype_error_types() {
let result = pdf_oxide::fonts::TrueTypeFont::parse(&[]);
assert!(matches!(result, Err(TrueTypeError::EmptyFont)));
let result = pdf_oxide::fonts::TrueTypeFont::parse(b"not a font");
assert!(matches!(result, Err(TrueTypeError::ParseError(_))));
}
#[test]
fn test_subset_stats() {
let mut subsetter = FontSubsetter::new();
subsetter.use_char(0x0041, 5);
subsetter.use_char(0x0042, 10);
subsetter.use_char(0x0043, 15);
let stats = subsetter.stats();
assert_eq!(stats.unique_chars, 3);
assert_eq!(stats.unique_glyphs, 3);
assert_eq!(stats.min_glyph_id, Some(5));
assert_eq!(stats.max_glyph_id, Some(15));
let reduction = stats.estimated_reduction(1000);
assert!(reduction > 99.0); }
#[test]
fn test_encoder_caching() {
let mut encoder = UnicodeEncoder::new();
let lookup = |cp: u32| Some(cp as u16);
encoder.encode_identity_h("AAA", lookup);
assert_eq!(encoder.cache_size(), 1);
encoder.encode_identity_h("ABC", lookup);
assert_eq!(encoder.cache_size(), 3);
encoder.clear_cache();
assert_eq!(encoder.cache_size(), 0);
}
#[test]
fn test_encode_text_auto_selection() {
let result = UnicodeEncoder::encode_text("Hello");
assert!(result.starts_with('('));
assert!(result.ends_with(')'));
let result = UnicodeEncoder::encode_text("Hello \u{4E2D}\u{6587}"); assert!(result.starts_with("<FEFF")); }