You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: output.go
    path of file: ./repos/caire/vendor/github.com/go-text/typesetting/shaping
    
    the code of the file until where you have to start completion: // SPDX-License-Identifier: Unlicense OR BSD-3-Clause

package shaping

import (
	"github.com/go-text/typesetting/di"
	"github.com/go-text/typesetting/font"
	"golang.org/x/image/math/fixed"
)

// Glyph describes the attributes of a single glyph from a single
// font face in a shaped output.
type Glyph struct {
	Width    fixed.Int26_6
	Height   fixed.Int26_6
	XBearing fixed.Int26_6
	YBearing fixed.Int26_6
	XAdvance fixed.Int26_6
	YAdvance fixed.Int26_6
	XOffset  fixed.Int26_6
	YOffset  fixed.Int26_6
	// ClusterIndex is the lowest rune index of all runes shaped into
	// this glyph cluster. All glyphs sharing the same cluste
    
func (o *Output) RecalculateAll() {
	var (
		advance fixed.Int26_6
		tallest fixed.Int26_6
		lowest  fixed.Int26_6
	)

	if o.Direction.IsVertical() {
		for i := range o.Glyphs {
			g := &o.Glyphs[i]
			advance += g.YAdvance
			height := g.XBearing + g.XOffset
			if height > tallest {
				tallest = height
			}
			depth := height + g.Width
			if depth < lowest {
				lowest = depth
			}
		}
	} else { // horizontal
		for i := range o.Glyphs {
			g := &o.Glyphs[i]
			advance += g.XAdvance
			height := g.YBearing + g.YOffset
			if height > tallest {
				tallest = height
			}
			depth := height + g.Height
			if depth < lowest {
				lowest = depth
			}
		}
	}
	o.Advance = advance
	o.GlyphBounds = Bounds{
		Ascent:  tallest,
		Descent: lowest,
	}
}