use crate::text::types::*;
use crate::text::Alignment;
use crate::types::*;
static LINE_BREAKERS: [char; 7] = [
'\u{A}', '\u{B}', '\u{C}', '\u{D}', '\u{85}', '\u{2028}', '\u{2029}',
];
static WORD_BREAKERS: [char; 19] = [
'\u{9}', '\u{20}', '\u{1680}', '\u{2000}', '\u{2001}', '\u{2002}', '\u{2003}', '\u{2004}',
'\u{2005}', '\u{2006}', '\u{2008}', '\u{2009}', '\u{200A}', '\u{205F}', '\u{3000}', '\u{180E}',
'\u{200B}', '\u{200C}', '\u{200D}',
];
fn can_break(c: char) -> bool {
WORD_BREAKERS.contains(&c) || LINE_BREAKERS.contains(&c)
}
fn must_break(c: char) -> bool {
LINE_BREAKERS.contains(&c)
}
pub(crate) fn get_line_start_x(
base_x: i32,
line_width: i32,
max_line_width: i32,
alignment: Alignment,
) -> i32 {
match alignment {
Alignment::Left => base_x,
Alignment::Center => base_x + (max_line_width - line_width) / 2,
Alignment::Right => base_x + (max_line_width - line_width),
}
}
pub(crate) fn get_line_length_and_width(
max_width: Option<i32>,
glyphs: &[(char, GlyphId, RectPx, Advance)],
) -> (usize, usize, i32) {
let mut total_width = 0;
let mut width_since_can_break = 0;
let mut previous_width = None;
let mut len = 0;
let mut can_break_len = None;
let mut broken_by_line_breaker = false;
for (c, _, metric, advance) in glyphs {
len += 1;
let mut width = 0;
if let Some(previous_width) = previous_width {
width += advance.advance_x - previous_width;
}
width += metric.width;
total_width += width;
previous_width = Some(metric.width);
if can_break(*c) {
can_break_len = Some(len);
width_since_can_break = 0;
}
if can_break_len.is_some() {
width_since_can_break += width;
}
if must_break(*c) {
total_width -= width; broken_by_line_breaker = true;
break;
} else if let Some(max_width) = max_width {
if total_width > max_width {
if let Some(can_break_len) = can_break_len {
total_width -= width_since_can_break;
len = can_break_len;
} else if len > 1 {
total_width -= width; len -= 1;
}
break;
}
}
}
let printable_len = if broken_by_line_breaker { len - 1 } else { len };
(len, printable_len, total_width)
}
pub(crate) fn get_line_length(glyphs: &[(char, GlyphId, RectPx, Advance)]) -> (usize, usize) {
if let Some(len) = glyphs.iter().position(|(c, _, _, _)| must_break(*c)) {
let stride = if len < glyphs.len() { len + 1 } else { len };
(stride, len)
} else {
(glyphs.len(), glyphs.len())
}
}