use crate::fonts::ScalableFont;
use cotis_defaults::element_configs::text_config::TextConfig;
use cotis_utils::math::Dimensions;
use raylib::ffi::GetFontDefault;
use raylib::prelude::Font;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
pub fn raylib_measure_text_inner(
text: &str,
config: &TextConfig,
user_data: Arc<Mutex<HashMap<usize, ScalableFont>>>,
) -> Dimensions {
let mut text_size = Dimensions {
width: 0.0,
height: 0.0,
};
let mut max_text_width: f32 = 0.0;
let mut line_text_width: f32 = 0.0;
let mut line_char_count: i32 = 0;
let mut line_count: i32 = 1;
let fonts_guard = user_data.lock().unwrap();
let opt_font_to_use = fonts_guard.get(&(config.font_id as usize));
let def_font;
let font_to_use: &Font = if let Some(scalable) = opt_font_to_use {
scalable.get_font_for_size_borrow(config.font_size as usize)
} else {
def_font = unsafe { Font::from_raw(GetFontDefault()) };
&def_font
};
let scale_factor = config.font_size / font_to_use.baseSize as f32;
let glyphs =
unsafe { std::slice::from_raw_parts(font_to_use.glyphs, font_to_use.glyphCount as usize) };
let recs =
unsafe { std::slice::from_raw_parts(font_to_use.recs, font_to_use.glyphCount as usize) };
for char in text.chars() {
if char == '\n' {
max_text_width = max_text_width.max(line_text_width);
line_text_width = 0.0;
line_char_count = 0;
line_count += 1;
continue;
}
let index: usize = (char as usize).saturating_sub(32);
if index >= font_to_use.glyphCount as usize {
line_char_count += 1;
continue;
}
if glyphs[index].advanceX != 0 {
line_text_width += glyphs[index].advanceX as f32;
} else {
line_text_width += recs[index].width + glyphs[index].offsetX as f32;
}
line_char_count += 1;
}
max_text_width = max_text_width.max(line_text_width);
text_size.width =
max_text_width * scale_factor + (line_char_count as f32 * config.letter_spacing);
let line_height = config.font_size;
text_size.height = line_count as f32 * line_height;
text_size
}