Repository: typst/typst
File: crates/typst/src/math/equation.rs (Rust)

Code before:
    fn layout(
        &self,
        engine: &mut Engine,
        styles: StyleChain,
        regions: Regions,
    ) -> SourceResult<Fragment> {
        assert!(self.block(styles));

        let span = self.span();
        let font = find_math_font(engine, styles, span)?;

        let mut ctx = MathContext::new(engine, styles, regions, &font);
        let full_equation_builder = ctx
            .layout_into_run(self, styles)?
            .multiline_frame_builder(&ctx, styles);
        let width = full_equation_builder.size.x;

        let equation_builders = if BlockElem::breakable_in(styles) {
            let mut rows = full_equation_builder.frames.into_iter().peekable();
            let mut equation_builders = vec![];
            let mut last_first_pos = Point::zero();

            for region in regions.iter() {
                // Keep track of the position of the first row in this region,
                // so that the offset can be reverted later.
                let Some(first_pos) = rows.peek().map(|(_, pos)| *pos) else { break };
                last_first_pos = first_pos;

                let mut frames = vec![];
                let mut height = Abs::zero();
                while let Some((sub, pos)) = rows.peek() {
                    let mut pos = *pos;
                    pos.y -= first_pos.y;

                    if !region.y.fits(sub.height() + pos.y) {
                        // Allow first row to overflow to prevent infinite
                        // creation of new regions which may all be too small.
                        if !(frames.is_empty() && regions.in_last()) {
                            break;
                        }
                    }

                    let (sub, _) = rows.next().unwrap();
                    height = height.max(pos.y + sub.height());
                    frames.push((sub, pos));
                }

                equation_builders
                    .push(MathRunFrameBuilder { frames, size: Size::new(width, height) });
            }


Review comment (suggestion):
```suggestion
                let Some(&(_, first_pos)) = rows.peek() else { break };
```

Code after:
    fn layout(
        &self,
        engine: &mut Engine,
        styles: StyleChain,
        regions: Regions,
    ) -> SourceResult<Fragment> {
        assert!(self.block(styles));

        let span = self.span();
        let font = find_math_font(engine, styles, span)?;

        let mut ctx = MathContext::new(engine, styles, regions, &font);
        let full_equation_builder = ctx
            .layout_into_run(self, styles)?
            .multiline_frame_builder(&ctx, styles);
        let width = full_equation_builder.size.x;

        let equation_builders = if BlockElem::breakable_in(styles) {
            let mut rows = full_equation_builder.frames.into_iter().peekable();
            let mut equation_builders = vec![];
            let mut last_first_pos = Point::zero();

            for region in regions.iter() {
                // Keep track of the position of the first row in this region,
                // so that the offset can be reverted later.
                let Some(&(_, first_pos)) = rows.peek() else { break };
                last_first_pos = first_pos;

                let mut frames = vec![];
                let mut height = Abs::zero();
                while let Some((sub, pos)) = rows.peek() {
                    let mut pos = *pos;
                    pos.y -= first_pos.y;

                    // Finish this region if the line doesn't fit. Only do it if
                    // we placed at least one line _or_ we still have non-last
                    // regions. Crucially, we don't want to infinitely create
                    // new regions which are too small.
                    if !region.y.fits(sub.height() + pos.y)
                        && (!frames.is_empty() || !regions.in_last())
                    {
                        break;
                    }

                    let (sub, _) = rows.next().unwrap();
                    height = height.max(pos.y + sub.height());
                    frames.push((sub, pos));
                }

                equation_builders
                    .push(MathRunFrameBuilder { frames, size: Size::new(width, height) });