i_slint_core/textlayout/linebreak_unicode.rs
1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
4use core::marker::PhantomData;
5
6pub use unicode_linebreak::BreakOpportunity;
7
8use crate::SharedVector;
9
10#[derive(Clone)]
11pub struct LineBreakIterator<'a> {
12 breaks: SharedVector<(usize, unicode_linebreak::BreakOpportunity)>,
13 pos: usize,
14 phantom: PhantomData<&'a str>,
15}
16
17impl LineBreakIterator<'_> {
18 pub fn new(text: &str) -> Self {
19 let iterator = unicode_linebreak::linebreaks(text).filter(|(offset, opportunity)| {
20 // unicode-linebreaks emits a mandatory break at the end of the text. We're not interested
21 // in that.
22 *offset != text.len() || !matches!(opportunity, BreakOpportunity::Mandatory)
23 });
24
25 Self { breaks: iterator.collect(), pos: 0, phantom: Default::default() }
26 }
27}
28
29impl Iterator for LineBreakIterator<'_> {
30 type Item = (usize, unicode_linebreak::BreakOpportunity);
31
32 fn next(&mut self) -> Option<Self::Item> {
33 if self.pos < self.breaks.len() {
34 let i = self.pos;
35 self.pos += 1;
36 Some(self.breaks[i])
37 } else {
38 None
39 }
40 }
41}