pub fn layout_horizontal<T: Borrow<Font>>(
        &mut self,
        fonts: &[T],
        styles: &[&TextStyle],
        settings: &LayoutSettings,
        output: &mut Vec<GlyphPosition>,
    ) {
        // Reset internal buffers.
        unsafe {
            self.line_metrics.set_len(0);
            output.set_len(0);
        }

        // There is a lot of context.
        let wrap_mask = Self::wrap_mask_from_settings(settings); // Wrap mask based on settings.
        let max_width = settings.max_width.unwrap_or(core::f32::MAX); // The max width of the bounding box.
        let mut state: u8 = 0; // Current linebreak state.
        let mut last_linebreak_state = 0; // Last highest ranked linebreak state for the given line.
        let mut last_linebreak_x = 0.0; // X position of the last linebreak.
        let mut last_linebreak_index = 0; // Glyph position of the last linebreak.
        let mut current_x = 0.0; // Starting x for the current line.
        let mut caret_x = 0.0; // Total x for the whole text.
        let mut total_height = 0.0; // Total y for the whole text.
        let mut next_line = LineMetrics {
            padding: 0.0,
            ascent: 0.0,
            new_line_size: 0.0,
            end_index: core::usize::MAX,
        };
        let mut current_ascent = 0.0; // Ascent for the current style.
        let mut current_new_line_size = 0.0; // New line height for the current style.
        for style in styles {
            let mut byte_offset = 0;
            let font = &fonts[style.font_index];
            if let Some(metrics) = font.borrow().horizontal_line_metrics(style.px) {
                current_ascent = ceil(metrics.ascent);
                current_new_line_size = ceil(metrics.new_line_size);
                if current_ascent > next_line.ascent {
                    next_line.ascent = current_ascent;
                }
                if current_new_line_size > next_line.new_line_size {
                    next_line.new_line_size = current_new_line_size;
                }
            }
            while byte_offset < style.text.len() {
                let character = read_utf8(style.text, &mut byte_offset);
                let linebreak_state = linebreak_property(&mut state, character) & wrap_mask;
                let metrics = if character as u32 > 0x1F {
                    font.borrow().metrics(character, style.px)
                } else {
                    ZERO_METRICS
                };
                let advance = ceil(metrics.advance_width);
                if linebreak_state >= last_linebreak_state {
                    last_linebreak_state = linebreak_state;
                    last_linebreak_x = caret_x;
                    last_linebreak_index = output.len();
                }
                if caret_x - current_x + advance >= max_width || last_linebreak_state == 2 {
                    total_height += next_line.new_line_size;
                    next_line.padding = max_width - (last_linebreak_x - current_x);
                    next_line.end_index = last_linebreak_index;
                    self.line_metrics.push(next_line);
                    next_line.ascent = current_ascent;
                    next_line.new_line_size = current_new_line_size;
                    last_linebreak_state = 0;
                    current_x = last_linebreak_x;
                }
                if metrics.width != 0 {
                    output.push(GlyphPosition {
                        key: GlyphRasterConfig {
                            c: character,
                            px: style.px,
                            font_index: style.font_index,
                        },
                        x: caret_x + floor(metrics.bounds.xmin),
                        y: floor(metrics.bounds.ymin),
                        width: metrics.width,
                        height: metrics.height,
                    });
                }
                caret_x += advance;
            }
        }
        total_height += next_line.new_line_size;
        next_line.padding = max_width - (caret_x - current_x);
        next_line.end_index = core::usize::MAX;
        self.line_metrics.push(next_line);

        let mut line_metrics = self.line_metrics.iter();
        let mut next_line_index = core::usize::MAX;
        let mut current_index = 0;
        let mut current_ascent = 0.0;
        let mut current_new_line_size = 0.0;
        let mut x_base = settings.x;
        let mut y_base = settings.y - Self::vertical_padding(settings, total_height);
        if let Some(line) = line_metrics.next() {
            next_line_index = line.end_index;
            current_ascent = line.ascent;
            current_new_line_size = line.new_line_size;
            x_base += Self::horizontal_padding(settings, line.padding);
        }
        for glyph in output.iter_mut() {
            if current_index == next_line_index {
                if let Some(line) = line_metrics.next() {
                    x_base = settings.x - glyph.x;
                    y_base -= current_new_line_size;
                    next_line_index = line.end_index;
                    current_ascent = line.ascent;
                    current_new_line_size = line.new_line_size;
                    x_base += Self::horizontal_padding(settings, line.padding);
                }
            }
            glyph.x += x_base;
            glyph.y += y_base - current_ascent;
            current_index += 1;
        }
    }
/// Performs layout for text horizontally, and wrapping vertically. This makes a best effort
/// attempt at laying out the text defined in the given styles with the provided layout
/// settings. Text may overflow out of the bounds defined in the layout settings and it's up
/// to the application to decide how to deal with this. Works with &[Font] or &[&Font].
Performs layout for text horizontally, and wrapping vertically. This makes a best effort
attempt at laying out the text defined in the given styles with the provided layout
settings. Text may overflow out of the bounds defined in the layout settings and it's up
to the application to decide how to deal with this. Works with &[Font] or &[&Font].
Performs layout for text horizontally and wrapping vertically . This makes a best effort attempt at laying out the text defined in the given styles with the provided layout settings . Text may overflow out of the bounds defined in the layout settings and it ' s up to the application to decide how to deal with this . Works with & [ Font ] or & [ &Font ] .
pub fn layout_horizontal<T: Borrow<Font>>(
        &mut self,
        fonts: &[T],
        styles: &[&TextStyle],
        settings: &LayoutSettings,
        output: &mut Vec<GlyphPosition>,
    ) {
        // Reset internal buffers.
        unsafe {
            self.line_metrics.set_len(0);
            output.set_len(0);
        }
        // There is a lot of context.
        let wrap_mask = Self::wrap_mask_from_settings(settings); // Wrap mask based on settings.
        let max_width = settings.max_width.unwrap_or(core::f32::MAX); // The max width of the bounding box.
        let mut state: u8 = 0; // Current linebreak state.
        let mut last_linebreak_state = 0; // Last highest ranked linebreak state for the given line.
        let mut last_linebreak_x = 0.0; // X position of the last linebreak.
        let mut last_linebreak_index = 0; // Glyph position of the last linebreak.
        let mut current_x = 0.0; // Starting x for the current line.
        let mut caret_x = 0.0; // Total x for the whole text.
        let mut total_height = 0.0; // Total y for the whole text.
        let mut next_line = LineMetrics {
            padding: 0.0,
            ascent: 0.0,
            new_line_size: 0.0,
            end_index: core::usize::MAX,
        };
        let mut current_ascent = 0.0; // Ascent for the current style.
        let mut current_new_line_size = 0.0; // New line height for the current style.
        for style in styles {
            let mut byte_offset = 0;
            let font = &fonts[style.font_index];
            if let Some(metrics) = font.borrow().horizontal_line_metrics(style.px) {
                current_ascent = ceil(metrics.ascent);
                current_new_line_size = ceil(metrics.new_line_size);
                if current_ascent > next_line.ascent {
                    next_line.ascent = current_ascent;
                }
                if current_new_line_size > next_line.new_line_size {
                    next_line.new_line_size = current_new_line_size;
                }
            }
            while byte_offset < style.text.len() {
                let character = read_utf8(style.text, &mut byte_offset);
                let linebreak_state = linebreak_property(&mut state, character) & wrap_mask;
                let metrics = if character as u32 > 0x1F {
                    font.borrow().metrics(character, style.px)
                } else {
                    ZERO_METRICS
                };
                let advance = ceil(metrics.advance_width);
                if linebreak_state >= last_linebreak_state {
                    last_linebreak_state = linebreak_state;
                    last_linebreak_x = caret_x;
                    last_linebreak_index = output.len();
                }
                if caret_x - current_x + advance >= max_width || last_linebreak_state == 2 {
                    total_height += next_line.new_line_size;
                    next_line.padding = max_width - (last_linebreak_x - current_x);
                    next_line.end_index = last_linebreak_index;
                    self.line_metrics.push(next_line);
                    next_line.ascent = current_ascent;
                    next_line.new_line_size = current_new_line_size;
                    last_linebreak_state = 0;
                    current_x = last_linebreak_x;
                }
                if metrics.width != 0 {
                    output.push(GlyphPosition {
                        key: GlyphRasterConfig {
                            c: character,
                            px: style.px,
                            font_index: style.font_index,
                        },
                        x: caret_x + floor(metrics.bounds.xmin),
                        y: floor(metrics.bounds.ymin),
                        width: metrics.width,
                        height: metrics.height,
                    });
                }
                caret_x += advance;
            }
        }
        total_height += next_line.new_line_size;
        next_line.padding = max_width - (caret_x - current_x);
        next_line.end_index = core::usize::MAX;
        self.line_metrics.push(next_line);
        let mut line_metrics = self.line_metrics.iter();
        let mut next_line_index = core::usize::MAX;
        let mut current_index = 0;
        let mut current_ascent = 0.0;
        let mut current_new_line_size = 0.0;
        let mut x_base = settings.x;
        let mut y_base = settings.y - Self::vertical_padding(settings, total_height);
        if let Some(line) = line_metrics.next() {
            next_line_index = line.end_index;
            current_ascent = line.ascent;
            current_new_line_size = line.new_line_size;
            x_base += Self::horizontal_padding(settings, line.padding);
        }
        for glyph in output.iter_mut() {
            if current_index == next_line_index {
                if let Some(line) = line_metrics.next() {
                    x_base = settings.x - glyph.x;
                    y_base -= current_new_line_size;
                    next_line_index = line.end_index;
                    current_ascent = line.ascent;
                    current_new_line_size = line.new_line_size;
                    x_base += Self::horizontal_padding(settings, line.padding);
                }
            }
            glyph.x += x_base;
            glyph.y += y_base - current_ascent;
            current_index += 1;
        }
    }
pub fn layout_horizontal < T : Borrow < Font > > ( & mut self , fonts : & [ T ] , styles : & [ & TextStyle ] , settings : & LayoutSettings , output : & mut Vec < GlyphPosition > , ) { // Reset internal buffers. unsafe { self . line_metrics . set_len ( 0 ) ; output . set_len ( 0 ) ; } // There is a lot of context. let wrap_mask = Self :: wrap_mask_from_settings ( settings ) ; // Wrap mask based on settings. let max_width = settings . max_width . unwrap_or ( core :: f32 :: MAX ) ; // The max width of the bounding box. let mut state : u8 = 0 ; // Current linebreak state. let mut last_linebreak_state = 0 ; // Last highest ranked linebreak state for the given line. let mut last_linebreak_x = 0.0 ; // X position of the last linebreak. let mut last_linebreak_index = 0 ; // Glyph position of the last linebreak. let mut current_x = 0.0 ; // Starting x for the current line. let mut caret_x = 0.0 ; // Total x for the whole text. let mut total_height = 0.0 ; // Total y for the whole text. let mut next_line = LineMetrics { padding : 0.0 , ascent : 0.0 , new_line_size : 0.0 , end_index : core :: usize :: MAX , } ; let mut current_ascent = 0.0 ; // Ascent for the current style. let mut current_new_line_size = 0.0 ; // New line height for the current style. for style in styles { let mut byte_offset = 0 ; let font = & fonts [ style . font_index ] ; if let Some ( metrics ) = font . borrow ( ) . horizontal_line_metrics ( style . px ) { current_ascent = ceil ( metrics . ascent ) ; current_new_line_size = ceil ( metrics . new_line_size ) ; if current_ascent > next_line . ascent { next_line . ascent = current_ascent ; } if current_new_line_size > next_line . new_line_size { next_line . new_line_size = current_new_line_size ; } } while byte_offset < style . text . len ( ) { let character = read_utf8 ( style . text , & mut byte_offset ) ; let linebreak_state = linebreak_property ( & mut state , character ) & wrap_mask ; let metrics = if character as u32 > 0x1F { font . borrow ( ) . metrics ( character , style . px ) } else { ZERO_METRICS } ; let advance = ceil ( metrics . advance_width ) ; if linebreak_state >= last_linebreak_state { last_linebreak_state = linebreak_state ; last_linebreak_x = caret_x ; last_linebreak_index = output . len ( ) ; } if caret_x - current_x + advance >= max_width || last_linebreak_state == 2 { total_height += next_line . new_line_size ; next_line . padding = max_width - ( last_linebreak_x - current_x ) ; next_line . end_index = last_linebreak_index ; self . line_metrics . push ( next_line ) ; next_line . ascent = current_ascent ; next_line . new_line_size = current_new_line_size ; last_linebreak_state = 0 ; current_x = last_linebreak_x ; } if metrics . width != 0 { output . push ( GlyphPosition { key : GlyphRasterConfig { c : character , px : style . px , font_index : style . font_index , } , x : caret_x + floor ( metrics . bounds . xmin ) , y : floor ( metrics . bounds . ymin ) , width : metrics . width , height : metrics . height , } ) ; } caret_x += advance ; } } total_height += next_line . new_line_size ; next_line . padding = max_width - ( caret_x - current_x ) ; next_line . end_index = core :: usize :: MAX ; self . line_metrics . push ( next_line ) ; let mut line_metrics = self . line_metrics . iter ( ) ; let mut next_line_index = core :: usize :: MAX ; let mut current_index = 0 ; let mut current_ascent = 0.0 ; let mut current_new_line_size = 0.0 ; let mut x_base = settings . x ; let mut y_base = settings . y - Self :: vertical_padding ( settings , total_height ) ; if let Some ( line ) = line_metrics . next ( ) { next_line_index = line . end_index ; current_ascent = line . ascent ; current_new_line_size = line . new_line_size ; x_base += Self :: horizontal_padding ( settings , line . padding ) ; } for glyph in output . iter_mut ( ) { if current_index == next_line_index { if let Some ( line ) = line_metrics . next ( ) { x_base = settings . x - glyph . x ; y_base -= current_new_line_size ; next_line_index = line . end_index ; current_ascent = line . ascent ; current_new_line_size = line . new_line_size ; x_base += Self :: horizontal_padding ( settings , line . padding ) ; } } glyph . x += x_base ; glyph . y += y_base - current_ascent ; current_index += 1 ; } }
Performs layout for text horizontally, and wrapping vertically.
Performs layout for text horizontally and wrapping vertically .
&mut self
fonts
&[T]
styles
&[&TextStyle]
settings
&LayoutSettings
output
&mut Vec<GlyphPosition>
&mut self
fonts
&[T]
styles
&[&TextStyle]
settings
&LayoutSettings
output
&mut Vec<GlyphPosition>