Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Measuring styled text outside drawing

A tooltip component can determine its dimensions before it receives any draw context. Use ClientHost::text_width(&Text) and text_split(&Text, width): these are reads of the client's active font in unscaled GUI pixels, also usable in client setup. Native and wasm mods use the same methods.

Construct an owned Text with its content, style and children. A bridge with a flat component representation can build a TextForm and call Text::try_from(form) once at its boundary; the host reads accept that validated Text, not JSON or engine text types. Both methods return a TextFormError if the supplied component cannot be represented at the engine boundary.

Width is the same styled and translated width used by the engine's tooltip layout. Wrapping follows Font.split(FormattedText, width): it keeps styles, breaks at newlines and fitting spaces, and uses the vanilla one-pixel minimum for widths below one. Returned lines are API-owned Text values. Translation uses the current client language; a later language or resource-pack font change is reflected by the next call, so do not retain dimensions across reloads.

NeoForge's ClientTooltipComponent receives a Font in its width and drawing methods. These reads use that same role—the active client font—without passing an engine font object or requiring a DrawContext. They do not draw anything and do not expose a full rendering context.

For vanilla Component.getString() behavior, use ClientHost::text_string(&Text) -> Result<String, TextFormError>. This client setup read also works outside drawing on native and wasm. It uses the same component conversion as measurement: translation arguments, key names and nested siblings resolve against the current language on every call. The result contains plain characters, not serialized JSON or translation keys. Styles do not add characters; literal legacy § formatting codes remain in the string, unlike the font's formatted rendering. Invalid components return the same boundary errors as the other text reads. Do not cache resolved strings across language changes.

For vanilla Component.getVisualOrderText() behavior, use ClientHost::text_visual_order(&Text) -> Result<Vec<VisualTextCharacter>, TextFormError>. Each API-owned Wire record contains a Unicode scalar (scalar), its full resolved TextStyle, and the sink's source_index. Characters are already in visual order, including Arabic shaping and mirrored punctuation; do not apply bidi a second time. This read uses the engine's existing language and bidi pipeline, is available outside drawing including client setup, and is identical on native and wasm. It has no documented NeoForge hook counterpart.

Sink indices are UTF-16 offsets local to a constant-style substring within a directional run, not global component positions. For example, A😀B yields indices 0, 1, 3; Hebrew שלום yields 3, 2, 1, 0. A style or bidi run boundary restarts the index. Shaping can shorten the string, so these are not guaranteed to identify original input scalars. Use the records to re-layout existing tooltip lines without losing click, hover, font or other style information. Like the other reads, invalid component input returns its boundary error.

Action keybind IDs such as key.jump resolve through the client's current key binding to their assigned physical key display name, matching vanilla's KeybindContents. Physical key names resolve normally.