textutil

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 27, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AppendBoundsOfTextRange

func AppendBoundsOfTextRange(dst []image.Rectangle, p *TextLayoutParams, start, end int) []image.Rectangle

AppendBoundsOfTextRange appends the bounding rectangles covering the byte range [start, end) of the rendering text to dst and returns the extended slice, one rectangle per crossed visual line, in order. A visual line holding an empty part of the range appends nothing. Coordinates are relative to the text layout origin, rounded outward to integers. Endpoints outside the text are clamped.

func CachedVisualLineCount

func CachedVisualLineCount(width int, logicalLine string, wrapMode WrapMode, face font.Face, faceRuns []FaceRun, logicalLineStartInBytes int, tabWidth float64, keepTailingSpace bool) int

CachedVisualLineCount is VisualLineCountForLogicalLine backed by the content-keyed layout cache. For WrapModeNone (no packing) or a non-UTF-8 line it falls back to the uncached count. Use this for per-tick height measurement of a logical line whose wrap layout the other cached paths (draw, caret, hit-test) also touch, so they share one cache entry.

func CachedVisualLineMaxCaretX

func CachedVisualLineMaxCaretX(width int, logicalLine string, wrapMode WrapMode, face font.Face, faceRuns []FaceRun, logicalLineStartInBytes int, tabWidth float64, keepTailingSpace bool) float64

CachedVisualLineMaxCaretX returns the furthest caret position rendered on the logical line's visual lines, using the same content-keyed layout cache as CachedVisualLineCount.

func Draw

func Draw(bounds image.Rectangle, dst *ebiten.Image, str string, options *DrawOptions)

func FindWordBoundaries

func FindWordBoundaries(text string, idx int) (start, end int)

func FirstLineBreakPositionAndLen

func FirstLineBreakPositionAndLen(str string) (pos, length int)

func LastLineBreakPositionAndLen

func LastLineBreakPositionAndLen(str string) (pos, length int)

LastLineBreakPositionAndLen returns the position and the byte length of the last line break in str. If no line break is found, it returns (-1, 0).

func Measure

func Measure(width int, str string, wrapMode WrapMode, face font.Face, faceRuns []FaceRun, insertion Insertion, lineHeight float64, lineHeightMode LineHeightMode, tabWidth float64, keepTailingSpace bool, ellipsisString string) (float64, float64)

func MeasureHeight

func MeasureHeight(width int, str string, wrapMode WrapMode, face font.Face, faceRuns []FaceRun, insertion Insertion, lineHeight float64, lineHeightMode LineHeightMode, tabWidth float64, keepTailingSpace bool) float64

MeasureHeight is like Measure but only returns height. When width does not need to be computed, this avoids per-visual-line shaping calls and is dramatically cheaper for very long text (e.g. a multi-megabyte editor buffer).

func MeasureLogicalLine

func MeasureLogicalLine(width int, logicalLine string, wrapMode WrapMode, face font.Face, faceRuns []FaceRun, insertion Insertion, logicalLineStartInBytes int, lineHeight float64, lineHeightMode LineHeightMode, tabWidth float64, keepTailingSpace bool, ellipsisString string) (float64, float64)

MeasureLogicalLine returns the rendered width and height of one logical line at the given width. Per-logical-line counterpart of Measure.

func MeasureLogicalLineHeight

func MeasureLogicalLineHeight(width int, logicalLine string, wrapMode WrapMode, face font.Face, faceRuns []FaceRun, insertion Insertion, logicalLineStartInBytes int, lineHeight float64, lineHeightMode LineHeightMode, tabWidth float64, keepTailingSpace bool) float64

MeasureLogicalLineHeight returns the rendered height of one logical line at the given width. This is the per-logical-line counterpart of MeasureHeight and is used by virtualized layout to size lines one at a time without scanning the whole document.

func NextPositionOnGraphemes

func NextPositionOnGraphemes(str string, position int) int

func PrevPositionOnGraphemes

func PrevPositionOnGraphemes(str string, position int) int

func TextIndexFromPosition

func TextIndexFromPosition(p *TextLayoutParams, position image.Point) int

TextIndexFromPosition returns the byte offset in the rendering text closest to position. When p.PrecomputedLineByteOffsets is supplied, the visual-line walk is localized: it starts from (p.LogicalLineIndexHint, p.VisualLineIndexHint) and steps forward (or backward) one logical line at a time until the line covering position.Y is found. With the hint placed inside the viewport this costs O(visible lines) of typesetting per query, instead of the O(documentLen) full scan performed when no precomputed logical-line offsets are supplied.

When an active IME composition splices into the rendering text, the precomputed committed-text logical-line offsets are reused: byte/visual-line shifts derived from ComputeCompositionInfo map between committed and rendering coordinates without rebuilding the offsets. Falls back to the unrestricted whole-document walk when the composition crosses a logical-line boundary, when no precomputed logical-line offsets are supplied, or when the document is empty. The fallback is observationally equivalent to the fast path.

func TextIndexFromPositionInLogicalLine

func TextIndexFromPositionInLogicalLine(width int, position image.Point, logicalLine string, logicalLineStartInBytes int, style *Style) int

TextIndexFromPositionInLogicalLine returns the byte offset within one logical line closest to the given position. The position's Y is relative to the top of the logical line. style's face runs use whole-text byte offsets; logicalLineStartInBytes is logicalLine's start offset in that text. Counterpart of TextIndexFromPosition.

func TrimPartialUTF8Prefix

func TrimPartialUTF8Prefix(s string) string

TrimPartialUTF8Prefix drops any continuation bytes (10xxxxxx) at the start of s that would have belonged to a UTF-8 sequence sliced before s.

func TrimPartialUTF8Suffix

func TrimPartialUTF8Suffix(s string) string

TrimPartialUTF8Suffix drops a partial UTF-8 sequence at the end of s when the slice was cut before the sequence's continuation bytes were included.

func VisualLineCountForLogicalLine

func VisualLineCountForLogicalLine(width int, logicalLine string, wrapMode WrapMode, face font.Face, faceRuns []FaceRun, logicalLineStartInBytes int, tabWidth float64, keepTailingSpace bool) int

VisualLineCountForLogicalLine returns the number of visual lines one logical line wraps into at the given width. With wrapMode set to WrapModeNone (or when the line fits) the result is always 1. faceRuns use whole-text byte offsets; logicalLineStartInBytes is logicalLine's start offset in that text.

Types

type CompositionInfo

type CompositionInfo struct {
	// LineIndex is the logical-line index of the selection line.
	// Lines with index > LineIndex are "past the splice" and have
	// RenderingByteShift and RenderingYShift applied.
	LineIndex int

	// RenderingByteShift is added to a past-the-splice line's
	// committed byte offset to get its rendering byte offset. Equals
	// the composition's byte length minus the length of the committed
	// range it replaces, so it can be negative for selection-
	// replacement compositions.
	RenderingByteShift int

	// RenderingYShift is added to a past-the-splice line's committed
	// visual-Y (in pixels, top-of-line) to get its rendering visual-Y.
	// Non-zero only when WrapMode is not [WrapModeNone] and the composition
	// causes the selection line to wrap into a different number of visual
	// sub-lines.
	RenderingYShift int
}

CompositionInfo describes how an active IME composition shifts the document layout for the visible-range slicer. The zero value is safe to pass when no composition is active: the shifts are zero, so any "past the splice" comparison the slicer makes is harmless.

func ComputeCompositionInfo

func ComputeCompositionInfo(p *CompositionInfoParams) (CompositionInfo, bool)

ComputeCompositionInfo classifies an active composition and returns info that the textutil functions use to translate between committed and rendering byte/visual-line coordinates. ok is false when the splice changes the logical-line count - a hard line break inside the composition or a selection that straddles a logical line boundary - and the caller should fall back to drawing the unrestricted text.

type CompositionInfoParams

type CompositionInfoParams struct {
	// CompositionText is the active composition's bytes — the bytes
	// inserted into the rendering text at SelectionStart, replacing
	// committed[SelectionStart:SelectionEnd].
	CompositionText string

	// LineByteOffsets is the logical-line layout of the committed text.
	LineByteOffsets *LineByteOffsets

	// SelectionStart and SelectionEnd are byte offsets into the
	// committed text describing the range the composition replaces.
	// SelectionStart == SelectionEnd for a pure insertion.
	SelectionStart int
	SelectionEnd   int

	// WrapMode toggles the visual-Y delta measurement for the
	// selection line. When [WrapModeNone], RenderingYShift in the result
	// is always 0 and the fields below are ignored.
	WrapMode WrapMode

	// CommittedSelectionLine and RenderingSelectionLine are the bytes
	// of the logical line containing the selection (SelectionStart ..
	// SelectionEnd, which always lies within a single logical line —
	// the function rejects multi-line selections), in committed and
	// rendering coordinates respectively. Required when WrapMode is
	// not [WrapModeNone]; ignored otherwise.
	CommittedSelectionLine string
	RenderingSelectionLine string

	// Face, LineHeight, LineHeightMode, TabWidth, KeepTailingSpace are
	// passed through to [MeasureLogicalLineHeight] when WrapMode is not
	// [WrapModeNone].
	Face             font.Face
	LineHeight       float64
	LineHeightMode   LineHeightMode
	TabWidth         float64
	KeepTailingSpace bool

	// CommittedFaceRuns and RenderingFaceRuns override Face for byte
	// ranges of the selection line, in committed-text and rendering-text
	// whole-text byte offsets respectively. Consulted only when WrapMode
	// is not [WrapModeNone]; nil means no overrides.
	CommittedFaceRuns []FaceRun
	RenderingFaceRuns []FaceRun

	// SelectionLineStartInBytes is the selection line's whole-text start
	// offset. The line start precedes the splice, so the offset is the
	// same in the committed and rendering texts.
	SelectionLineStartInBytes int

	// WrapWidth is the pixel width at which logical lines wrap into
	// visual sublines. Values <= 0 are treated as math.MaxInt (no
	// wrapping).
	WrapWidth int
}

CompositionInfoParams describes the inputs for ComputeCompositionInfo.

type DrawOptions

type DrawOptions struct {
	Style

	// LayoutWidth is the width used to wrap and align text. When zero, the
	// drawing bounds width is used.
	LayoutWidth int

	TextColor color.Color

	DrawSelection  bool
	SelectionStart int
	SelectionEnd   int
	SelectionColor color.Color

	DrawComposition          bool
	CompositionStart         int
	CompositionEnd           int
	CompositionActiveStart   int
	CompositionActiveEnd     int
	InactiveCompositionColor color.Color
	ActiveCompositionColor   color.Color
	CompositionBorderWidth   float32

	// VisibleBounds restricts drawing to lines and glyphs that intersect this
	// rectangle. Lines fully above or below are skipped without shaping, and
	// glyphs whose drawn rectangle falls entirely outside are not submitted to
	// [(*ebiten.Image).DrawImage]. An empty rectangle draws nothing.
	VisibleBounds image.Rectangle

	// StyleRuns are paint-only style overrides applied to byte ranges of the
	// drawn string, sorted by Start and disjoint. An empty slice draws the
	// whole string uniformly.
	StyleRuns []StyleRun
}

type FaceRun

type FaceRun struct {
	// Start is the inclusive start of the range in bytes.
	Start int

	// End is the exclusive end of the range in bytes.
	End int

	// Face measures and draws the range.
	Face font.Face
}

FaceRun overrides the face used to measure and draw a byte range of the laid-out text.

type HorizontalAlign

type HorizontalAlign int
const (
	HorizontalAlignStart HorizontalAlign = iota
	HorizontalAlignCenter
	HorizontalAlignEnd
	HorizontalAlignLeft
	HorizontalAlignRight
)

type Insertion

type Insertion struct {
	// Face is the face the inserted text uses. The zero value means there is
	// no insertion.
	Face font.Face

	// IndexInBytes is the insertion's byte offset in the laid-out text.
	IndexInBytes int
}

Insertion is a zero-width position in the laid-out text carrying the face of the text that will be inserted there. It takes part in the height of the visual line holding it, as a character with that face would. A face is all it carries: nothing is drawn at the position, so the colors and decorations of a StyleRun would have nothing to apply to.

type LineByteOffsets

type LineByteOffsets struct {
	// contains filtered or unexported fields
}

LineByteOffsets holds the byte offsets where each logical line (segment separated by hard line breaks) begins within a source string. It is a precomputed logical-line offset index that enables O(log n) line<->byte-offset lookups without rescanning the text.

After a rebuild the first entry is always 0 and the entries are strictly increasing. A trailing line break in the source string creates an extra empty line at the end (e.g. "abc\n" has two logical lines).

func (*LineByteOffsets) ByteOffsetByLineIndex

func (l *LineByteOffsets) ByteOffsetByLineIndex(i int) int

ByteOffsetByLineIndex returns the byte offset of the start of the i-th logical line. Panics if i is out of range.

func (*LineByteOffsets) LineCount

func (l *LineByteOffsets) LineCount() int

LineCount returns the number of logical lines.

The empty string has one logical line. A trailing line break creates an extra empty line, so "abc\n" has two logical lines.

func (*LineByteOffsets) LineIndexForByteOffset

func (l *LineByteOffsets) LineIndexForByteOffset(byteOffset int) int

LineIndexForByteOffset returns the index of the logical line that contains byteOffset. byteOffset is clamped: negative values map to line 0 and values past the text map to the last line.

func (*LineByteOffsets) Rebuild

func (l *LineByteOffsets) Rebuild(scan func(io.Writer) error) error

Rebuild discards any current contents and rescans the bytes written by scan for logical-line starts. The io.Writer passed to scan accepts bytes in any number of chunks; the recorded offsets are the same as if the concatenated bytes had been scanned in a single pass. Any error from scan is returned unchanged after the trailing partial-break state has been flushed.

func (*LineByteOffsets) Replace

func (l *LineByteOffsets) Replace(newText string, start, end int, startCtx, endCtx string, atEOT bool)

Replace updates the offsets to reflect a splice that replaced the source text's [start, end) byte range with newText. The caller must invoke Replace immediately after applying the same splice to the underlying source.

startCtx is the up-to-2-byte slice of pre-splice text immediately before start (positions [max(0, start-2), start)); it is used to derive the scanner's entry state at start so a partial break ending at the splice boundary disambiguates correctly. endCtx is the up-to-3-byte slice of post-splice text immediately after newText (positions [start+len(newText), start+len(newText)+3)); it provides the lookahead the scanner needs for breaks formed at the splice's far boundary. atEOT must be true iff endCtx reaches end-of-text (i.e. start+len(newText)+3 ≥ post-splice length).

After Replace returns, the offsets describe the post-splice text.

func (*LineByteOffsets) Reset

func (l *LineByteOffsets) Reset()

Reset clears the offsets. After Reset, LineCount returns 0; callers that expect at least one line must rebuild first.

type LineHeightMode

type LineHeightMode int

LineHeightMode selects how a visual line's height responds to the font sizes on it. The basicwidget package mirrors this enum for its public API.

const (
	// LineHeightModeFixed gives every visual line the same height. Text
	// larger than the line height overflows into the adjacent lines.
	LineHeightModeFixed LineHeightMode = iota

	// LineHeightModeFlexible scales a visual line's height and baseline by
	// the largest font size on it, relative to the base face's size.
	LineHeightModeFlexible
)

type Style

type Style struct {
	WrapMode WrapMode
	Face     font.Face

	// FaceRuns overrides Face for byte ranges of the laid-out text, sorted
	// by Start and disjoint. An empty slice measures and draws the whole
	// text with Face.
	FaceRuns []FaceRun

	// Insertion is the pending insertion point of the laid-out text. The
	// zero value means there is none.
	Insertion Insertion

	LineHeight float64

	// LineHeightMode selects how LineHeight responds to the font sizes on a
	// visual line.
	LineHeightMode LineHeightMode

	HorizontalAlign  HorizontalAlign
	VerticalAlign    VerticalAlign
	TabWidth         float64
	KeepTailingSpace bool
	EllipsisString   string
}

type StyleRun

type StyleRun struct {
	// Start is the inclusive start of the range in bytes.
	Start int

	// End is the exclusive end of the range in bytes.
	End int

	// Color overrides the text and decoration color. Nil inherits
	// [DrawOptions.TextColor].
	Color color.Color

	// BackgroundColor fills the range's background. Nil draws no background.
	BackgroundColor color.Color

	// Underline draws a line under the text.
	Underline bool

	// Strikethrough draws a line through the text.
	Strikethrough bool
}

StyleRun is a paint-only style override applied to a byte range of the drawn string.

type TextLayoutParams

type TextLayoutParams struct {
	// RenderingTextRange returns rendering[start:end), where the
	// rendering text is the committed text with any active composition
	// spliced in. RenderingTextLength is the total byte length of the
	// rendering text. Required: all reads of the rendering text — both
	// the fast path and the slow-path fallback — go through this
	// callback so the caller never has to materialize the full
	// document.
	RenderingTextRange  func(start, end int) string
	RenderingTextLength int

	// Width is the rendering width.
	Width int

	// Style carries face, lineHeight, wrap mode, alignment, tab
	// width, etc. Style.FaceRuns uses rendering-text byte offsets.
	Style Style

	// CommittedTextRange returns committed[start:end). Required when
	// CompositionLen > 0; ignored otherwise.
	CommittedTextRange func(start, end int) string

	// CommittedFaceRuns carries the same face overrides as Style.FaceRuns
	// in committed-text byte offsets. Consulted only when CompositionLen
	// > 0; nil means no overrides.
	CommittedFaceRuns []FaceRun

	// PrecomputedLineByteOffsets is the logical-line layout of the committed text.
	// Optional; when nil the query falls back to an O(documentLen) walk
	// of every visual line.
	PrecomputedLineByteOffsets *LineByteOffsets

	// SelectionStart, SelectionEnd, CompositionLen describe an active
	// IME composition: bytes [SelectionStart, SelectionEnd) in the
	// committed text are replaced with bytes [SelectionStart,
	// SelectionStart+CompositionLen) in the rendering text.
	// CompositionLen == 0 means no active composition; the other
	// fields are ignored in that case.
	SelectionStart int
	SelectionEnd   int
	CompositionLen int

	// LogicalLineIndexHint / VisualLineIndexHint define the visual-line
	// coordinate system the walk starts from: the logical line at
	// LogicalLineIndexHint is treated as starting at visual-line index
	// VisualLineIndexHint, and the walk steps forward (or backward)
	// from there to the line the query resolves to. The result is
	// therefore expressed in the caller's coordinate system — (0, 0)
	// measures from line 0 (the document top); (firstLogicalLineInViewport, 0)
	// measures from the first visible line's top, used by virtualized
	// text.
	//
	// The walk is bounded by the logical-line distance between the
	// hint and the resolved line, so a caller that pins the hint inside
	// its viewport pays only O(visible) typesetting per query. The zero
	// value walks from the document top. Used only when
	// PrecomputedLineByteOffsets is set.
	LogicalLineIndexHint int
	VisualLineIndexHint  int
}

TextLayoutParams carries the text-layout context shared by TextIndexFromPosition, TextPositionFromIndex, and PositionWithinLogicalLine. The first group of fields is always required; the second group is optional state that enables the fast path backed by the precomputed logical-line offsets.

type TextPosition

type TextPosition struct {
	X      float64
	Top    float64
	Bottom float64
}

func PositionWithinLogicalLine

func PositionWithinLogicalLine(p *TextLayoutParams, index int) (lineIdx int, position0, position1 TextPosition, count int)

PositionWithinLogicalLine returns the caret's logical-line index and its visual position(s). pos.Top / pos.Bottom are measured from the start of the line at lineIdx, not the document top.

count==0 when the result is unavailable: index out of range, no precomputed logical-line offsets, empty document, or composition straddling a logical-line boundary. Callers needing the slow whole-document fallback in that case should call TextPositionFromIndex.

func TextPositionFromIndex

func TextPositionFromIndex(p *TextLayoutParams, index int) (position0, position1 TextPosition, count int)

TextPositionFromIndex returns the visual position(s) for index in the rendering text. The Y origin is the visual line at (p.LogicalLineIndexHint, p.VisualLineIndexHint); count is 1, or 2 at line- break boundaries.

func TextPositionFromIndexInLogicalLine

func TextPositionFromIndexInLogicalLine(width int, logicalLine string, logicalLineStartInBytes, index int, style *Style) (position0, position1 TextPosition, count int)

TextPositionFromIndexInLogicalLine returns the visual position(s) within one logical line corresponding to the given byte index inside that line. The Y values are relative to the top of the logical line (so the caller can offset them by the line's origin Y). Counterpart of TextPositionFromIndex.

index is a byte offset in [0, len(logicalLine)]. style's face runs use whole-text byte offsets; logicalLineStartInBytes is logicalLine's start offset in that text. Out-of-range values yield (TextPosition{}, TextPosition{}, 0).

type VerticalAlign

type VerticalAlign int
const (
	VerticalAlignTop VerticalAlign = iota
	VerticalAlignMiddle
	VerticalAlignBottom
)

type VisibleRange

type VisibleRange struct {
	// FirstLine and LastLine are the inclusive range of logical-line
	// indices the caller should draw.
	FirstLine, LastLine int

	// StartInBytes and EndInBytes are the byte range of the rendering
	// text the caller should draw: rendering[StartInBytes:EndInBytes].
	StartInBytes, EndInBytes int

	// YShift is added to the drawing-origin Y so the first sliced line
	// lands at its original screen Y. Already includes the alignment-
	// specific portion of the original Y offset, so the caller forces
	// [VerticalAlignTop] when calling [Draw].
	YShift int
}

VisibleRange is the result of VisibleRangeInViewport when its ok return is true.

func VisibleRangeInViewport

func VisibleRangeInViewport(p *VisibleRangeInViewportParams) (VisibleRange, bool)

VisibleRangeInViewport returns the byte range and logical-line indices that cover the visible region when the widget is positioned so FirstLogicalLineInViewport sits at widget-local Y=0. The walk steps forward from FirstLogicalLineInViewport, measuring each logical line's wrap count on the fly, so a caller pinned to the topmost visible line pays only O(visible) typesetting per query. Composition splices on lines past the splice are handled by reading rendering-text bytes for the composition's selection line.

ok is false when the document is empty.

VerticalAlign is intentionally not part of the input: when the caller pins the viewport at a non-zero logical line, the document is assumed to overflow the viewport (the case where alignment matters), so YShift is always 0 and the caller's bounds positioning carries any needed offset itself.

type VisibleRangeInViewportParams

type VisibleRangeInViewportParams struct {
	// FirstLogicalLineInViewport is the logical line whose top sits
	// at the widget-local origin (Y=0). The caller's bounds-positioning
	// places this line at the top of the rendered output, so the
	// returned VisibleRange.FirstLine is always this index (clamped to
	// the document) and YShift is always 0.
	FirstLogicalLineInViewport int

	// LineByteOffsets is the logical-line layout of the committed
	// text. The number of logical lines comes from its LineCount.
	LineByteOffsets *LineByteOffsets

	// RenderingTextRange returns rendering[start:end). The walker
	// reads each measured line through this callback so the caller
	// never has to materialize the full rendering text. Required when
	// WrapMode is not [WrapModeNone] (so the walker can shape per-line
	// content); for [WrapModeNone] only RenderingTextLength is consulted.
	RenderingTextRange func(start, end int) string

	// RenderingTextLength is the total byte length of the rendering
	// text.
	RenderingTextLength int

	// ViewportSize describes the rendering box the walker operates
	// against: X is the wrap width passed through to
	// [VisualLineCountForLogicalLine] when WrapMode is not
	// [WrapModeNone], and Y is the distance below
	// FirstLogicalLineInViewport's top that the visible region extends
	// downward. The walk stops once cumulative line heights exceed Y,
	// leaving one line of slack so the caller's inner Y clip can handle
	// off-by-one rounding.
	ViewportSize image.Point

	// Face, LineHeight, LineHeightMode, TabWidth, KeepTailingSpace are
	// passed through to [VisualLineCountForLogicalLine] when WrapMode is
	// not [WrapModeNone].
	Face             font.Face
	LineHeight       float64
	LineHeightMode   LineHeightMode
	TabWidth         float64
	KeepTailingSpace bool

	// FaceRuns are the per-range face overrides of the rendering text,
	// sorted by Start and disjoint.
	FaceRuns []FaceRun

	// Insertion is the pending insertion point of the rendering text. The
	// zero value means there is none.
	Insertion Insertion

	// WrapMode toggles between a per-line shaping walk (any wrapping
	// mode) and a flat LineHeight*idx arithmetic ([WrapModeNone]).
	WrapMode WrapMode

	// Composition is the splice info from [ComputeCompositionInfo].
	// The zero value means "no active composition".
	Composition CompositionInfo
}

VisibleRangeInViewportParams describes the inputs for VisibleRangeInViewport. The walk steps forward from FirstLogicalLineInViewport measuring per-line heights via VisualLineCountForLogicalLine until cumulative height covers Height, so the cost is O(visible logical lines) — the prefix [0, FirstLogicalLineInViewport) is never measured.

type WrapMode

type WrapMode int

WrapMode selects how visual lines wrap when text exceeds the available width. The basicwidget package mirrors this enum for its public API.

const (
	// WrapModeNone disables automatic wrapping.
	WrapModeNone WrapMode = iota
	// WrapModeNormal wraps at Unicode line break opportunities.
	WrapModeNormal
	// WrapModeAnywhere wraps at any grapheme cluster boundary.
	WrapModeAnywhere
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL