use std::collections::HashMap;
#[derive(Debug, Clone, Default)]
pub struct ModeWeightStatistics {
weights: HashMap<ordered_float::OrderedFloat<f64>, f64>,
total_count: usize,
}
impl ModeWeightStatistics {
pub fn new() -> Self {
Self::default()
}
pub fn add(&mut self, font_size: f64, char_count: usize) {
let key = ordered_float::OrderedFloat(font_size);
*self.weights.entry(key).or_insert(0.0) += char_count as f64;
self.total_count += char_count;
}
pub fn mode_font_size(&self) -> Option<f64> {
self.weights
.iter()
.max_by(|a, b| a.1.partial_cmp(b.1).unwrap_or(std::cmp::Ordering::Equal))
.map(|(k, _)| k.into_inner())
}
pub fn total_count(&self) -> usize {
self.total_count
}
pub fn is_larger_than_mode(&self, font_size: f64) -> bool {
match self.mode_font_size() {
Some(mode) => font_size > mode + 0.5,
None => false,
}
}
pub fn is_mode_size(&self, font_size: f64) -> bool {
match self.mode_font_size() {
Some(mode) => (font_size - mode).abs() < 0.5,
None => false,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct TextStyle {
pub font_name: String,
pub font_size: f64,
pub font_weight: f64,
pub is_bold: bool,
pub is_italic: bool,
}
impl TextStyle {
pub fn is_compatible(&self, other: &TextStyle) -> bool {
self.font_name == other.font_name
&& (self.font_size - other.font_size).abs() < 0.5
&& self.is_bold == other.is_bold
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_mode_weight_statistics() {
let mut stats = ModeWeightStatistics::new();
stats.add(12.0, 100);
stats.add(14.0, 20);
stats.add(12.0, 200);
assert!((stats.mode_font_size().unwrap() - 12.0).abs() < 0.01);
assert!(stats.is_mode_size(12.0));
assert!(stats.is_larger_than_mode(14.0));
assert!(!stats.is_larger_than_mode(12.0));
}
}