Control letter spacing, line height, and paragraph spacing in text blocks using the Block API.
CE.SDK provides three text spacing properties — text/letterSpacing, text/lineHeight, and text/paragraphSpacing — controlled via engine.block.setFloat(_:property:value:) and engine.block.getFloat(_:property:). In addition, engine.block.setTextLineHeight(_:lineHeight:paragraphIndex:) and engine.block.getTextLineHeight(_:paragraphIndex:) let you set per-paragraph line height overrides on top of the block-level value.
Letter Spacing#
Control the horizontal space between characters with the text/letterSpacing property. Positive values spread characters apart; negative values tighten them.
// Set letter spacing — positive values spread characters, negative values tighten themtry engine.block.setFloat(text, property: "text/letterSpacing", value: Float(0.1))
// Read the current letter spacing_ = try engine.block.getFloat(text, property: "text/letterSpacing")Letter spacing (also called tracking) adjusts text density for improved readability or visual effect.
Line Height#
Control the vertical distance between lines with the text/lineHeight property. The value is a multiplier of the font size — for example, 1.5 means 150% of the font size.
// Set the block-level line height multiplier — applies to all paragraphs by defaulttry engine.block.setFloat(text, property: "text/lineHeight", value: Float(1.5))
// Read the current block-level line height_ = try engine.block.getFloat(text, property: "text/lineHeight")This block-level value applies to all paragraphs unless overridden at the paragraph level.
Per-Paragraph Line Height#
Override the line height for individual paragraphs using setTextLineHeight(_:lineHeight:paragraphIndex:) with a paragraphIndex. Passing nil for lineHeight clears the override and reverts that paragraph to the block-level value. Calling setTextLineHeight(_:lineHeight:) without a paragraphIndex sets the block-level line height and clears all paragraph overrides at once.
getTextLineHeight(_:paragraphIndex:) returns the effective line height for a given paragraph — the per-paragraph override if one is set, otherwise the block-level value.
// Set a per-paragraph line height override for paragraph 0 (first paragraph)try engine.block.setTextLineHeight(text, lineHeight: 2.0, paragraphIndex: 0)
// Read the line height for a specific paragraph// Returns the override if set, otherwise falls back to the block-level value_ = try engine.block.getTextLineHeight(text, paragraphIndex: 0)_ = try engine.block.getTextLineHeight(text, paragraphIndex: 1)
// Clear a paragraph's override by passing nil — it reverts to the block-level valuetry engine.block.setTextLineHeight(text, lineHeight: nil, paragraphIndex: 0)
// Set the block-level line height and clear all paragraph overrides at oncetry engine.block.setTextLineHeight(text, lineHeight: 1.8)para0LineHeightreturns2.0(the override).para1LineHeightreturns the block-level value because paragraph 1 has no override.- After the final
setTextLineHeight(text, lineHeight: 1.8)call, all paragraph overrides are cleared and the block-level value becomes1.8.
Paragraph Spacing#
Add vertical space between paragraphs using the text/paragraphSpacing property. The value is added after each paragraph break (newline character).
// Set paragraph spacing — adds space after each paragraph breaktry engine.block.setFloat(text, property: "text/paragraphSpacing", value: Float(20))
// Read the current paragraph spacing_ = try engine.block.getFloat(text, property: "text/paragraphSpacing")Paragraph spacing only affects text with actual paragraph breaks. Single-paragraph text won’t show a visible difference.
Full Code#
Here’s the full code:
import Foundationimport IMGLYEngine
@MainActorfunc textAdjustSpacing(engine: Engine) async throws { let scene = try engine.scene.create() let text = try engine.block.create(.text) try engine.block.appendChild(to: scene, child: text) try engine.block.setWidthMode(text, mode: .auto) try engine.block.setHeightMode(text, mode: .auto) try engine.block.replaceText(text, text: "Hello\nWorld\nCE.SDK")
// Set letter spacing — positive values spread characters, negative values tighten them try engine.block.setFloat(text, property: "text/letterSpacing", value: Float(0.1))
// Read the current letter spacing _ = try engine.block.getFloat(text, property: "text/letterSpacing")
// Set the block-level line height multiplier — applies to all paragraphs by default try engine.block.setFloat(text, property: "text/lineHeight", value: Float(1.5))
// Read the current block-level line height _ = try engine.block.getFloat(text, property: "text/lineHeight")
// Set a per-paragraph line height override for paragraph 0 (first paragraph) try engine.block.setTextLineHeight(text, lineHeight: 2.0, paragraphIndex: 0)
// Read the line height for a specific paragraph // Returns the override if set, otherwise falls back to the block-level value _ = try engine.block.getTextLineHeight(text, paragraphIndex: 0) _ = try engine.block.getTextLineHeight(text, paragraphIndex: 1)
// Clear a paragraph's override by passing nil — it reverts to the block-level value try engine.block.setTextLineHeight(text, lineHeight: nil, paragraphIndex: 0)
// Set the block-level line height and clear all paragraph overrides at once try engine.block.setTextLineHeight(text, lineHeight: 1.8)
// Set paragraph spacing — adds space after each paragraph break try engine.block.setFloat(text, property: "text/paragraphSpacing", value: Float(20))
// Read the current paragraph spacing _ = try engine.block.getFloat(text, property: "text/paragraphSpacing")}