pub fn match_resolver<'a>(y: u32, window_size: u32, matches: &[Match<'a>]) -> Vec<Match2D<'a>> {
    let mut res: Vec<Match2D<'a>> = vec![];

    // So, whitespace in matches, which delimit the consecutive glyph blocks.
    let mut match_index: usize = 0;
    while match_index < matches.len() {
        // Skip over whitespace matches
        if let Token::WhiteSpace(_) = matches[match_index].token {
            match_index += 1;
            continue;
        }

        if let Token::Glyph { glyph, .. } = matches[match_index].token {
            // Trimming left is easy, just check if this glyph should be tirmmed and advance if so.
            if glyph.trim_left() {
                match_index += 1;
                continue;
            }

            // Find the index where this consecutive glyph block ends, this is either on whitespace
            // or when max_consecutive is reached for a particular glyph.
            let mut block_end = matches.len() - match_index;
            let mut consecutive_counter: Option<(&glyphs::Glyph, usize)> = None;
            for (potential_i, potential) in matches[match_index..].iter().enumerate() {
                match potential.token {
                    Token::WhiteSpace(_v) => {
                        block_end = potential_i;
                        break;
                    }
                    Token::Glyph { ref glyph, .. } => {
                        // Check if this glyph has a maximum consecutive count.
                        if let Some(max_consecutive) = glyph.max_consecutive() {
                            // Check if there's already a counter.
                            if let Some((counting_glyph, count)) = consecutive_counter.as_mut() {
                                // Check if the glyph is identical, else clear it.
                                if glyph != counting_glyph {
                                    consecutive_counter = None;
                                } else {
                                    *count += 1;
                                    // Same glyph, increment the counter.
                                    if *count > max_consecutive {
                                        block_end = potential_i;
                                        break;
                                    }
                                }
                            } else {
                                // No counter yet, but we should have one.
                                consecutive_counter = Some((glyph, 1));
                            }
                        } else {
                            consecutive_counter = None;
                        }
                    }
                }
            }

            // Determine the slice of glyphs, first and last.
            let glyphs = &matches[match_index..match_index + block_end];
            let untrimmed_length = glyphs.len();

            // Now, all that remains is trimming the right side.
            // Perform trimming if glyphs on the sides require so.
            let mut right_limit = glyphs.len();
            for rev_i in (0..glyphs.len()).rev() {
                if let Token::Glyph { glyph, .. } = glyphs[rev_i].token {
                    if glyph.trim_right() {
                        right_limit = rev_i;
                    } else {
                        break;
                    }
                } else {
                    break;
                }
            }
            let glyphs = &glyphs[..right_limit];

            if glyphs.is_empty() {
                match_index += untrimmed_length;
                continue;
            }

            let first_glyph = glyphs.first().expect("never empty");
            let last_glyph = glyphs.last().expect("never empty");

            // Use the width of the match and to create a bounding box for this glyph block.
            let block_width = last_glyph.position + last_glyph.width - first_glyph.position;
            let this_block_region = Rect {
                x: first_glyph.position,
                y,
                w: block_width - 1, // -1 to stay inside our window instead of one pixel beyond.
                h: window_size - 1,
            };

            // We should insert our current entry.
            res.push(Match2D {
                tokens: glyphs
                    .iter()
                    .map(|z| match z.token {
                        Token::Glyph { glyph, label } => LabelledGlyph { glyph, label },
                        _ => panic!("should never have whitespace here"),
                    })
                    .collect::<_>(),
                location: this_block_region,
            });

            match_index += untrimmed_length;
        }
    }
    res
}
/// Function that resolves the individual 1D matches into consecutive glyphs and their Match2D
/// Representation. Also deals with special things like glyphs that may not be consecutive like
/// space characters.
Function that resolves the individual 1D matches into consecutive glyphs and their Match2D
Representation. Also deals with special things like glyphs that may not be consecutive like
space characters.
Function that resolves the individual 1D matches into consecutive glyphs and their Match2D Representation . Also deals with special things like glyphs that may not be consecutive like space characters .
pub fn match_resolver<'a>(y: u32, window_size: u32, matches: &[Match<'a>]) -> Vec<Match2D<'a>> {
    let mut res: Vec<Match2D<'a>> = vec![];
    // So, whitespace in matches, which delimit the consecutive glyph blocks.
    let mut match_index: usize = 0;
    while match_index < matches.len() {
        // Skip over whitespace matches
        if let Token::WhiteSpace(_) = matches[match_index].token {
            match_index += 1;
            continue;
        }
        if let Token::Glyph { glyph, .. } = matches[match_index].token {
            // Trimming left is easy, just check if this glyph should be tirmmed and advance if so.
            if glyph.trim_left() {
                match_index += 1;
                continue;
            }
            // Find the index where this consecutive glyph block ends, this is either on whitespace
            // or when max_consecutive is reached for a particular glyph.
            let mut block_end = matches.len() - match_index;
            let mut consecutive_counter: Option<(&glyphs::Glyph, usize)> = None;
            for (potential_i, potential) in matches[match_index..].iter().enumerate() {
                match potential.token {
                    Token::WhiteSpace(_v) => {
                        block_end = potential_i;
                        break;
                    }
                    Token::Glyph { ref glyph, .. } => {
                        // Check if this glyph has a maximum consecutive count.
                        if let Some(max_consecutive) = glyph.max_consecutive() {
                            // Check if there's already a counter.
                            if let Some((counting_glyph, count)) = consecutive_counter.as_mut() {
                                // Check if the glyph is identical, else clear it.
                                if glyph != counting_glyph {
                                    consecutive_counter = None;
                                } else {
                                    *count += 1;
                                    // Same glyph, increment the counter.
                                    if *count > max_consecutive {
                                        block_end = potential_i;
                                        break;
                                    }
                                }
                            } else {
                                // No counter yet, but we should have one.
                                consecutive_counter = Some((glyph, 1));
                            }
                        } else {
                            consecutive_counter = None;
                        }
                    }
                }
            }
            // Determine the slice of glyphs, first and last.
            let glyphs = &matches[match_index..match_index + block_end];
            let untrimmed_length = glyphs.len();
            // Now, all that remains is trimming the right side.
            // Perform trimming if glyphs on the sides require so.
            let mut right_limit = glyphs.len();
            for rev_i in (0..glyphs.len()).rev() {
                if let Token::Glyph { glyph, .. } = glyphs[rev_i].token {
                    if glyph.trim_right() {
                        right_limit = rev_i;
                    } else {
                        break;
                    }
                } else {
                    break;
                }
            }
            let glyphs = &glyphs[..right_limit];
            if glyphs.is_empty() {
                match_index += untrimmed_length;
                continue;
            }
            let first_glyph = glyphs.first().expect("never empty");
            let last_glyph = glyphs.last().expect("never empty");
            // Use the width of the match and to create a bounding box for this glyph block.
            let block_width = last_glyph.position + last_glyph.width - first_glyph.position;
            let this_block_region = Rect {
                x: first_glyph.position,
                y,
                w: block_width - 1, // -1 to stay inside our window instead of one pixel beyond.
                h: window_size - 1,
            };
            // We should insert our current entry.
            res.push(Match2D {
                tokens: glyphs
                    .iter()
                    .map(|z| match z.token {
                        Token::Glyph { glyph, label } => LabelledGlyph { glyph, label },
                        _ => panic!("should never have whitespace here"),
                    })
                    .collect::<_>(),
                location: this_block_region,
            });
            match_index += untrimmed_length;
        }
    }
    res
}
pub fn match_resolver < ' a > ( y : u32 , window_size : u32 , matches : & [ Match < ' a > ] ) -> Vec < Match2D < ' a > > { let mut res : Vec < Match2D < ' a > > = vec ! [ ] ; // So, whitespace in matches, which delimit the consecutive glyph blocks. let mut match_index : usize = 0 ; while match_index < matches . len ( ) { // Skip over whitespace matches if let Token :: WhiteSpace ( _ ) = matches [ match_index ] . token { match_index += 1 ; continue ; } if let Token :: Glyph { glyph , .. } = matches [ match_index ] . token { // Trimming left is easy, just check if this glyph should be tirmmed and advance if so. if glyph . trim_left ( ) { match_index += 1 ; continue ; } // Find the index where this consecutive glyph block ends, this is either on whitespace // or when max_consecutive is reached for a particular glyph. let mut block_end = matches . len ( ) - match_index ; let mut consecutive_counter : Option < ( & glyphs :: Glyph , usize ) > = None ; for ( potential_i , potential ) in matches [ match_index .. ] . iter ( ) . enumerate ( ) { match potential . token { Token :: WhiteSpace ( _v ) => { block_end = potential_i ; break ; } Token :: Glyph { ref glyph , .. } => { // Check if this glyph has a maximum consecutive count. if let Some ( max_consecutive ) = glyph . max_consecutive ( ) { // Check if there's already a counter. if let Some ( ( counting_glyph , count ) ) = consecutive_counter . as_mut ( ) { // Check if the glyph is identical, else clear it. if glyph != counting_glyph { consecutive_counter = None ; } else { * count += 1 ; // Same glyph, increment the counter. if * count > max_consecutive { block_end = potential_i ; break ; } } } else { // No counter yet, but we should have one. consecutive_counter = Some ( ( glyph , 1 ) ) ; } } else { consecutive_counter = None ; } } } } // Determine the slice of glyphs, first and last. let glyphs = & matches [ match_index .. match_index + block_end ] ; let untrimmed_length = glyphs . len ( ) ; // Now, all that remains is trimming the right side. // Perform trimming if glyphs on the sides require so. let mut right_limit = glyphs . len ( ) ; for rev_i in ( 0 .. glyphs . len ( ) ) . rev ( ) { if let Token :: Glyph { glyph , .. } = glyphs [ rev_i ] . token { if glyph . trim_right ( ) { right_limit = rev_i ; } else { break ; } } else { break ; } } let glyphs = & glyphs [ .. right_limit ] ; if glyphs . is_empty ( ) { match_index += untrimmed_length ; continue ; } let first_glyph = glyphs . first ( ) . expect ( " " ) ; let last_glyph = glyphs . last ( ) . expect ( " " ) ; // Use the width of the match and to create a bounding box for this glyph block. let block_width = last_glyph . position + last_glyph . width - first_glyph . position ; let this_block_region = Rect { x : first_glyph . position , y , w : block_width - 1 , // -1 to stay inside our window instead of one pixel beyond. h : window_size - 1 , } ; // We should insert our current entry. res . push ( Match2D { tokens : glyphs . iter ( ) . map ( | z | match z . token { Token :: Glyph { glyph , label } => LabelledGlyph { glyph , label } , _ => panic ! ( " " ) , } ) . collect :: < _ > ( ) , location : this_block_region , } ) ; match_index += untrimmed_length ; } } res }
Function that resolves the individual 1D matches into consecutive glyphs and their Match2D
Representation.
Function that resolves the individual 1D matches into consecutive glyphs and their Match2D Representation .
y
u32
window_size
u32
matches
&[Match<'a>]