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}