moon_cosmic

MoonBit port of cosmic-text (text shaping, layout, and editor primitives) built on moon_swash.

text
layout
bidi
shaping
swash
cosmic-text
moon add Milky2018/moon_cosmic@0.3.3
Download zip
Author
Version
0.3.3
License
Apache-2.0
Last updated
2 months ago
Downloads
32K
README

#Milky2018/moon_cosmic

MoonBit port of Rust cosmic-text (text shaping, layout, and editor primitives), built on top of Milky2018/moon_swash.

The project keeps behavior aligned with upstream cosmic-text through automated tests where feasible.

#Features

  • Font system (in-memory): load TTF/OTF/TTC bytes; resolve fonts by family + weight; per-codepoint fallback.
  • Shaping: Shaping::Advanced uses moon_swash/shape to produce clustered glyphs and advances; tabs snap to stops.
  • Wrapping & layout: Wrap::{None,Glyph,Word,WordOrGlyph}, Align::{Left,Right,Center,Justified,Start,End}, hinting.
  • BiDi: paragraph iteration + embedding levels and visual reordering of glyph runs.
  • Raster cache: CacheKey + SwashCache backed by moon_swash/scale (variable wght axis support; fake-italic transform).
  • Editor primitives: Buffer, Editor, cursor/selection, hit-testing, and motion actions.

#Install

Add dependency:

moon add Milky2018/moon_cosmic

#Quick Start (Layout)

import Milky2018/moon_cosmic

fn main {
// Provide font bytes from your host app (file I/O is app-specific).
let font_bytes : Bytes = /* ... */

let font_system = FontSystem::new().load_font_data(font_bytes)
let metrics = Metrics::new(14.0F, 20.0F)

let attrs = Attrs::new().family(Family::Name("Inter"))
let attrs_list = AttrsList::new(attrs)

let buffer = Buffer::new(metrics)
.set_wrap(Wrap::WordOrGlyph)
.set_text("Hello world", attrs_list, Shaping::Advanced)
.set_size(Some(200.0F), None)
.layout_all_with_font_system(font_system)

for run in buffer.layout_runs() {
// `run.glyphs`: Array[LayoutGlyph]
// `run.line_w`: line width in pixels
ignore(run)
}
}

#Quick Start (Draw)

Buffer::draw renders via a callback (pixel-oriented for compatibility with the legacy renderer pattern).

import Milky2018/moon_cosmic

fn draw_demo(font_bytes : Bytes) -> Unit {
let font_system = FontSystem::new().load_font_data(font_bytes)
let cache = SwashCache::new()

let buffer = Buffer::new(Metrics::new(14.0F, 20.0F))
.set_text("Hi!", AttrsList::new(Attrs::new()), Shaping::Advanced)
.set_size(Some(200.0F), None)

let (_buffer, _cache) = buffer.draw(
font_system,
cache,
Color::rgb(0, 0, 0),
fn(_x, _y, _w, _h, _color) { () },
)
}

#Integration Notes

#Subpixel Cache Keys (Atlas Caching)

Downstream atlas caches should key by PhysicalGlyph.cache_key (includes x_bin/y_bin), not only (glyph_id, x, y).

#Font Collections (TTC / Multi-face)

FontSystem::load_font_data may load multiple faces from one file/collection. Each face gets its own font_id. Use FontSystem::get_font(font_id) / FontSystem::get_font_entry(font_id) to rasterize the correct face for a given LayoutGlyph.

#Dev Workflow

Common commands:

moon check # Lint/type-check moon test # Run tests moon fmt # Format moon info # Update .mbti moon info && moon fmt

#Test Font Blob

Some tests require real font metrics. This repo embeds Inter-Regular.ttf into src/test_fonts_test.mbt (base64).

To regenerate it (if test font data changes):

python3 scripts/gen_test_font_mbt.py moon fmt moon test

#License

Apache-2.0. Upstream cosmic-text is dual-licensed MIT OR Apache-2.0.

#
CacheKeyFlags

type CacheKeyFlags = UInt

Flags that change rendering.

#
Edit

pub(open) trait Edit {
fn editor(Self) -> Editor
fn set_editor(Self, Editor) -> Self
fn cursor(Self) -> Cursor
fn set_cursor(Self, Cursor) -> Self
fn selection(Self) -> Selection
fn set_selection(Self, Selection) -> Self
fn auto_indent(Self) -> Bool
fn set_auto_indent(Self, Bool) -> Self
fn tab_width(Self) -> Int
fn set_tab_width(Self, Int) -> Self
fn start_change(Self) -> Self
fn finish_change(Self) -> (Self, Change?)
fn copy_selection(Self) -> String?
fn delete_selection(Self) -> (Self, Bool)
fn delete_range(Self, Cursor, Cursor) -> Self
fn insert_string(Self, String, AttrsList?) -> Self
fn apply_change(Self, Change) -> (Self, Bool)
fn cursor_position(Self) -> (Int, Int)?
fn action(Self, Action) -> Self
}

Shared editable surface for Editor/SyntaxEditor/ViEditor.

#
Renderer

pub(open) trait Renderer {
fn rectangle(Self, x : Int, y : Int, w : UInt, h : UInt, color : Color) -> Unit
fn glyph(Self, physical_glyph : PhysicalGlyph, color : Color) -> Unit
}

Custom renderer for buffers and editors.

#
Action

pub(all) enum Action {
Motion(Motion)
Escape
Insert(Char)
Enter
Backspace
Delete
Indent
Unindent
Click(Int, Int)
DoubleClick(Int, Int)
TripleClick(Int, Int)
Drag(Int, Int)
Scroll(Float)
}

An action to perform on an editor.

#
Affinity

pub(all) enum Affinity {
Before
After
}

Whether to associate cursors placed at a boundary between runs with the run before or after it.
impl Eq for Affinity

#
Affinity::after

fn Affinity::after(self : Affinity) -> Bool

#
Affinity::before

fn Affinity::before(self : Affinity) -> Bool

#
Affinity::from_after

fn Affinity::from_after(after : Bool) -> Affinity

#
Affinity::from_before

fn Affinity::from_before(before : Bool) -> Affinity

#
Align

pub(all) enum Align {
Left
Right
Center
Justified
Start
End
}

Align or justify

#
Attrs

pub struct Attrs {
color_opt : Color?
metadata : Int
family : Family
weight : Weight
stretch :
Stretch

style :
Style

cache_key_flags : UInt
metrics_opt : CacheMetrics?
letter_spacing_opt : LetterSpacing?
font_features : FontFeatures
text_decoration : TextDecoration
}

impl Eq for Attrs
impl Hash for Attrs

#
Attrs::cache_key_flags

fn Attrs::cache_key_flags(self : Attrs, cache_key_flags : UInt) -> Attrs

#
Attrs::cache_key_flags_value

fn Attrs::cache_key_flags_value(self : Attrs) -> UInt

#
Attrs::color

fn Attrs::color(self : Attrs, color : Color) -> Attrs

#
Attrs::color_opt_value

fn Attrs::color_opt_value(self : Attrs) -> Color?

#
Attrs::compatible

fn Attrs::compatible(self : Attrs, other : Attrs) -> Bool

#
Attrs::family

fn Attrs::family(self : Attrs, family : Family) -> Attrs

#
Attrs::family_value

fn Attrs::family_value(self : Attrs) -> Family

#
Attrs::font_features

fn Attrs::font_features(self : Attrs, font_features : FontFeatures) -> Attrs

#
Attrs::font_features_value

fn Attrs::font_features_value(self : Attrs) -> FontFeatures

#
Attrs::letter_spacing

fn Attrs::letter_spacing(self : Attrs, letter_spacing : Float) -> Attrs

#
Attrs::letter_spacing_opt

fn Attrs::letter_spacing_opt(self : Attrs) -> Float?

#
Attrs::metadata

fn Attrs::metadata(self : Attrs) -> Int

#
Attrs::metrics

fn Attrs::metrics(self : Attrs, metrics : Metrics) -> Attrs

Set Metrics, overriding values in Buffer for this span.

#
Attrs::metrics_opt

fn Attrs::metrics_opt(self : Attrs) -> Metrics?

Return optional Metrics override.

#
Attrs::new

fn Attrs::new() -> Attrs

#
Attrs::overline

fn Attrs::overline(self : Attrs) -> Attrs

#
Attrs::overline_color

fn Attrs::overline_color(self : Attrs, color : Color) -> Attrs

#
Attrs::stretch

fn Attrs::stretch(self : Attrs, stretch :
Stretch
) -> Attrs

#
Attrs::stretch_value

fn Attrs::stretch_value(self : Attrs) ->
Stretch

#
Attrs::strikethrough

fn Attrs::strikethrough(self : Attrs) -> Attrs

#
Attrs::strikethrough_color

fn Attrs::strikethrough_color(self : Attrs, color : Color) -> Attrs

#
Attrs::style

fn Attrs::style(self : Attrs, style :
Style
) -> Attrs

#
Attrs::style_value

fn Attrs::style_value(self : Attrs) ->
Style

#
Attrs::text_decoration

fn Attrs::text_decoration(self : Attrs, text_decoration : TextDecoration) -> Attrs

#
Attrs::text_decoration_value

fn Attrs::text_decoration_value(self : Attrs) -> TextDecoration

#
Attrs::underline

fn Attrs::underline(self : Attrs, style : UnderlineStyle) -> Attrs

#
Attrs::underline_color

fn Attrs::underline_color(self : Attrs, color : Color) -> Attrs

#
Attrs::weight

fn Attrs::weight(self : Attrs, weight : Weight) -> Attrs

#
Attrs::weight_value

fn Attrs::weight_value(self : Attrs) -> Weight

#
Attrs::with_metadata

fn Attrs::with_metadata(metadata : Int) -> Attrs

#
AttrsList

pub struct AttrsList {
defaults : Attrs
spans : Array[AttrsSpan]
}

impl Eq for AttrsList
impl Hash for AttrsList

#
AttrsList::add_span

fn AttrsList::add_span(self : AttrsList, start : Int, end : Int, attrs : Attrs) -> AttrsList

#
AttrsList::defaults

fn AttrsList::defaults(self : AttrsList) -> Attrs

#
AttrsList::eq

fn AttrsList::eq(self : AttrsList, other : AttrsList) -> Bool

#
AttrsList::get_span

fn AttrsList::get_span(self : AttrsList, pos : Int) -> Attrs

#
AttrsList::new

fn AttrsList::new(defaults : Attrs) -> AttrsList

#
AttrsList::spans_iter

fn AttrsList::spans_iter(self : AttrsList) -> Array[AttrsSpan]

#
AttrsList::split_off

fn AttrsList::split_off(self : AttrsList, index : Int) -> (AttrsList, AttrsList)

Splits spans at index and returns (left, right).

#
AttrsSpan

pub struct AttrsSpan {
start : Int
end : Int
attrs : Attrs
}

impl Eq for AttrsSpan
impl Hash for AttrsSpan

#
BidiInfo

pub struct BidiInfo {
text : String
original_classes : Array[
BidiClass
]
levels : Array[Int]
paragraphs : Array[ParagraphInfo]
}

BiDi analysis result aligned with unicode-bidi / cosmic-text flow.

original_classes and levels are indexed by UTF-16 code-unit offset.

#
BidiInfo::adjusted_levels

fn BidiInfo::adjusted_levels(self : BidiInfo) -> Array[Int]

#
BidiInfo::levels

fn BidiInfo::levels(self : BidiInfo) -> Array[Int]

#
BidiInfo::new

fn BidiInfo::new(text : String) -> BidiInfo

#
BidiInfo::new_with_para_level

fn BidiInfo::new_with_para_level(text : String, default_para_level : Int?) -> BidiInfo

#
BidiInfo::paragraphs

fn BidiInfo::paragraphs(self : BidiInfo) -> Array[ParagraphInfo]

#
BidiInfo::rtl

fn BidiInfo::rtl(self : BidiInfo) -> Bool

#
BidiInfo::text

fn BidiInfo::text(self : BidiInfo) -> String

#
BidiParagraphs

pub struct BidiParagraphs {
text : String
ranges : Array[(Int, Int)]
cursor : Int
pos : Int
}

An iterator over paragraphs in input text.

Behavior follows unicode-bidi paragraph ranges: paragraph separator characters (BidiClass::B) remain in the paragraph range but are trimmed from the returned paragraph text.

#
BidiParagraphs::iter

fn BidiParagraphs::iter(self : BidiParagraphs) -> Iter[String]

#
BidiParagraphs::new

fn BidiParagraphs::new(text : String) -> BidiParagraphs

#
BidiParagraphs::next

fn BidiParagraphs::next(self : BidiParagraphs) -> (BidiParagraphs, String)?

Returns (next, paragraph_text) if any.

#
Buffer

pub struct Buffer {
lines : Array[BufferLine]
metrics : Metrics
width_opt : Float?
height_opt : Float?
scroll : Scroll
redraw : Bool
wrap : Wrap
ellipsize : Ellipsize
monospace_width : Float?
tab_width : Int
hinting : Hinting
dirty_relayout : Bool
dirty_tab_shape : Bool
dirty_text_set : Bool
dirty_scroll : Bool
}

Minimal Buffer port scaffold from cosmic-text/src/buffer.rs.

#
Buffer::cursor_motion

fn Buffer::cursor_motion(self : Buffer, cursor : Cursor, cursor_x_opt : Int?, motion : Motion) -> (Cursor, Int?)?

Cursor motion based on current layout runs.

This uses visual lines from layout_runs() for vertical movement.

#
Buffer::draw

fn Buffer::draw(self : Buffer, font_system : FontSystem, swash_cache : SwashCache, text_color : Color, f : (Int, Int, UInt, UInt, Color) -> Unit) -> (Buffer, SwashCache)

Draw the buffer with a font system and swash cache.

This is a naming-aligned convenience wrapper (matches upstream's Buffer::draw intent).

#
Buffer::draw_with_font_system

fn Buffer::draw_with_font_system(self : Buffer, font_system : FontSystem, swash_cache : SwashCache, text_color : Color, f : (Int, Int, UInt, UInt, Color) -> Unit) -> (Buffer, SwashCache)

Draw the buffer using a SwashCache.

For compatibility with upstream's legacy renderer helper, the callback is called per pixel (w = 1, h = 1).

#
Buffer::ellipsize

fn Buffer::ellipsize(self : Buffer) -> Ellipsize

#
Buffer::hinting

fn Buffer::hinting(self : Buffer) -> Hinting

#
Buffer::hit

fn Buffer::hit(self : Buffer, x : Float, y : Float) -> Cursor?

Hit-testing: map a physical x/y position to a cursor.

#
Buffer::layout_all

fn Buffer::layout_all(self : Buffer) -> Buffer

Layout all lines using the built-in shaping (no font system).

#
Buffer::layout_all_with_font_system

fn Buffer::layout_all_with_font_system(self : Buffer, font_system : FontSystem) -> Buffer

Layout all lines using a provided FontSystem (best-effort).

#
Buffer::layout_cursor

fn Buffer::layout_cursor(self : Buffer, font_system : FontSystem, cursor : Cursor) -> LayoutCursor?

#
Buffer::layout_runs

fn Buffer::layout_runs(self : Buffer) -> Iter[LayoutRun]

#
Buffer::line_layout

fn Buffer::line_layout(self : Buffer, font_system : FontSystem, line_i : Int) -> Array[LayoutLine]?

#
Buffer::line_shape

fn Buffer::line_shape(self : Buffer, font_system : FontSystem, line_i : Int) -> ShapeLine?

#
Buffer::lines

fn Buffer::lines(self : Buffer) -> Array[BufferLine]

#
Buffer::metrics

fn Buffer::metrics(self : Buffer) -> Metrics

#
Buffer::new

fn Buffer::new(metrics : Metrics) -> Buffer

#
Buffer::new_empty

fn Buffer::new_empty(metrics : Metrics) -> Buffer

Create an empty Buffer with the provided Metrics.

Panics (fails) if metrics.line_height is zero (aligned with upstream).

#
Buffer::redraw

fn Buffer::redraw(self : Buffer) -> Bool

#
Buffer::scroll

fn Buffer::scroll(self : Buffer) -> Scroll

#
Buffer::set_ellipsize

fn Buffer::set_ellipsize(self : Buffer, ellipsize : Ellipsize) -> Buffer

#
Buffer::set_hinting

fn Buffer::set_hinting(self : Buffer, hinting : Hinting) -> Buffer

#
Buffer::set_metrics

fn Buffer::set_metrics(self : Buffer, metrics : Metrics) -> Buffer

#
Buffer::set_metrics_and_size

fn Buffer::set_metrics_and_size(self : Buffer, metrics : Metrics, width_opt : Float?, height_opt : Float?) -> Buffer

#
Buffer::set_monospace_width

fn Buffer::set_monospace_width(self : Buffer, monospace_width : Float?) -> Buffer

#
Buffer::set_redraw

fn Buffer::set_redraw(self : Buffer, redraw : Bool) -> Buffer

#
Buffer::set_rich_text

fn Buffer::set_rich_text(self : Buffer, spans : Array[(String, Attrs)], default_attrs : Attrs, shaping : Shaping, alignment : Align?) -> Buffer

Set rich text of buffer using styled spans (pairs of text and attrs).

This mirrors cosmic-text's Buffer::set_rich_text behavior:
  • Concatenates spans into one string.
  • Splits into paragraphs using BidiParagraphs.
  • Builds per-line AttrsList spans relative to each line.
  • Uses LineEnding::default() for all lines.

#
Buffer::set_scroll

fn Buffer::set_scroll(self : Buffer, scroll : Scroll) -> Buffer

#
Buffer::set_size

fn Buffer::set_size(self : Buffer, width_opt : Float?, height_opt : Float?) -> Buffer

#
Buffer::set_tab_width

fn Buffer::set_tab_width(self : Buffer, tab_width : Int) -> Buffer

#
Buffer::set_text

fn Buffer::set_text(self : Buffer, text : String, attrs_list : AttrsList, shaping : Shaping) -> Buffer

Set full text of buffer.

NOTE: attrs_list is copied per line (upstream spans are per line).

#
Buffer::set_wrap

fn Buffer::set_wrap(self : Buffer, wrap : Wrap) -> Buffer

#
Buffer::shape_all_with_font_system

fn Buffer::shape_all_with_font_system(self : Buffer, font_system : FontSystem) -> Buffer

Shape all lines using a provided FontSystem (best-effort).

This is a coarse-grained helper for clients that do not want to manage per-line shaping manually yet.

#
Buffer::shape_until_cursor

fn Buffer::shape_until_cursor(self : Buffer, font_system : FontSystem, cursor : Cursor, prune : Bool) -> Buffer

#
Buffer::shape_until_scroll

fn Buffer::shape_until_scroll(self : Buffer, font_system : FontSystem, prune : Bool) -> Buffer

#
Buffer::size

fn Buffer::size(self : Buffer) -> (Float?, Float?)

#
Buffer::wrap

fn Buffer::wrap(self : Buffer) -> Wrap

#
BufferLine

pub struct BufferLine {
text : String
ending : LineEnding
attrs_list : AttrsList
align : Align?
shape_opt : Cached[ShapeLine]
layout_opt : Cached[Array[LayoutLine]]
shaping : Shaping
metadata : Int?
}

#
BufferLine::align

fn BufferLine::align(self : BufferLine) -> Align?

#
BufferLine::append

fn BufferLine::append(self : BufferLine, other : BufferLine) -> BufferLine

Append other to self (consumes both, returns updated line).

#
BufferLine::attrs_list

fn BufferLine::attrs_list(self : BufferLine) -> AttrsList

#
BufferLine::ending

fn BufferLine::ending(self : BufferLine) -> LineEnding

#
BufferLine::into_text

fn BufferLine::into_text(self : BufferLine) -> String

#
BufferLine::layout

fn BufferLine::layout(self : BufferLine, font_size : Float, width_opt : Float?, wrap : Wrap, ellipsize : Ellipsize, match_mono_width : Float?, tab_width : Int, hinting : Hinting) -> BufferLine

#
BufferLine::layout_opt

fn BufferLine::layout_opt(self : BufferLine) -> Array[LayoutLine]?

#
BufferLine::layout_runs

fn BufferLine::layout_runs(self : BufferLine, height_opt : Float?, line_height : Float) -> Iter[LayoutRun]

#
BufferLine::layout_with_font_system

fn BufferLine::layout_with_font_system(self : BufferLine, font_system : FontSystem, font_size : Float, width_opt : Float?, wrap : Wrap, ellipsize : Ellipsize, match_mono_width : Float?, tab_width : Int, hinting : Hinting) -> BufferLine

Layout using a provided FontSystem (best-effort).

#
BufferLine::metadata

fn BufferLine::metadata(self : BufferLine) -> Int?

#
BufferLine::new

fn BufferLine::new(text : String, ending : LineEnding, attrs_list : AttrsList, shaping : Shaping) -> BufferLine

#
BufferLine::reset

fn BufferLine::reset(self : BufferLine) -> BufferLine

#
BufferLine::reset_layout

fn BufferLine::reset_layout(self : BufferLine) -> BufferLine

#
BufferLine::reset_shaping

fn BufferLine::reset_shaping(self : BufferLine) -> BufferLine

#
BufferLine::set_align

fn BufferLine::set_align(self : BufferLine, align : Align?) -> (BufferLine, Bool)

#
BufferLine::set_attrs_list

fn BufferLine::set_attrs_list(self : BufferLine, attrs_list : AttrsList) -> (BufferLine, Bool)

#
BufferLine::set_ending

fn BufferLine::set_ending(self : BufferLine, ending : LineEnding) -> BufferLine

#
BufferLine::set_metadata

fn BufferLine::set_metadata(self : BufferLine, metadata : Int) -> BufferLine

#
BufferLine::set_text

fn BufferLine::set_text(self : BufferLine, text : String, ending : LineEnding, attrs_list : AttrsList) -> (BufferLine, Bool)

#
BufferLine::shape

fn BufferLine::shape(self : BufferLine, tab_width : Int) -> BufferLine

#
BufferLine::shape_opt

fn BufferLine::shape_opt(self : BufferLine) -> ShapeLine?

#
BufferLine::shape_with_font_system

fn BufferLine::shape_with_font_system(self : BufferLine, font_system : FontSystem, tab_width : Int) -> BufferLine

Shape using a provided FontSystem (best-effort).

This is an incremental step towards upstream cosmic-text: we keep the same cache behavior, but build glyph advances from the font.

#
BufferLine::split_off

fn BufferLine::split_off(self : BufferLine, index : Int) -> (BufferLine, BufferLine)

Split off new line at index. Returns (left, right).

#
BufferLine::text

fn BufferLine::text(self : BufferLine) -> String

#
CacheKey

pub struct CacheKey {
font_id : Int
glyph_id : Int
font_size_bits : UInt
x_bin : SubpixelBin
y_bin : SubpixelBin
font_weight : Int
flags : UInt
}

Key for building a glyph cache.

NOTE: we keep this as a plain struct (instead of bitfields) to match the conceptual model of cosmic-text.
impl Eq for CacheKey
impl Hash for CacheKey
impl Show for CacheKey

#
CacheKey::has_disable_hinting

fn CacheKey::has_disable_hinting(self : CacheKey) -> Bool

#
CacheKey::has_fake_italic

fn CacheKey::has_fake_italic(self : CacheKey) -> Bool

#
CacheKey::has_pixel_font

fn CacheKey::has_pixel_font(self : CacheKey) -> Bool

#
CacheKey::new

fn CacheKey::new(font_id : Int, glyph_id : Int, font_size : Float, pos : (Float, Float), font_weight : Int, flags : UInt) -> (CacheKey, Int, Int)

#
CacheKey::x_bin

fn CacheKey::x_bin(self : CacheKey) -> SubpixelBin

#
CacheKey::y_bin

fn CacheKey::y_bin(self : CacheKey) -> SubpixelBin

#
CacheMetrics

pub struct CacheMetrics {
font_size_bits : UInt
line_height_bits : UInt
}

Metrics, but implementing Eq and Hash using u32 representation of f32.

This mirrors upstream cosmic-text CacheMetrics, enabling per-span metrics overrides (font size / line height) while keeping Attrs hashable.
impl Eq for CacheMetrics

#
CacheMetrics::font_size

fn CacheMetrics::font_size(self : CacheMetrics) -> Float

#
CacheMetrics::from_metrics

fn CacheMetrics::from_metrics(metrics : Metrics) -> CacheMetrics

#
CacheMetrics::line_height

fn CacheMetrics::line_height(self : CacheMetrics) -> Float

#
CacheMetrics::to_metrics

fn CacheMetrics::to_metrics(self : CacheMetrics) -> Metrics

#
Cached

pub(all) enum Cached[T] {
Empty
Unused(T)
Used(T)
}

Ported from cosmic-text/src/cached.rs (cosmic-text is dual-licensed MIT OR Apache-2.0).

MoonBit version is implemented in a functional style (returns updated Cached), but keeps the same state machine semantics as the upstream &mut self API.

#
Cached::get

fn[T] Cached::get(self : Cached[T]) -> T?

#
Cached::is_unused

fn[T] Cached::is_unused(self : Cached[T]) -> Bool

#
Cached::is_used

fn[T] Cached::is_used(self : Cached[T]) -> Bool

#
Cached::set_unused

fn[T] Cached::set_unused(self : Cached[T]) -> Cached[T]

#
Cached::set_used

fn[T] Cached::set_used(_self : Cached[T], val : T) -> Cached[T]

#
Cached::take_unused

fn[T] Cached::take_unused(self : Cached[T]) -> (Cached[T], T?)

#
Cached::take_used

fn[T] Cached::take_used(self : Cached[T]) -> (Cached[T], T?)

#
CachedLine

pub struct CachedLine {
text : String
state_in : LineState
state_out : LineState
spans : Array[TokenSpan]
}

#
Change

pub(all) struct Change {
items : Array[ChangeItem]
}

A set of change items grouped into one logical change.

#
Change::default

fn Change::default() -> Change

#
Change::reverse

fn Change::reverse(self : Change) -> Change

#
ChangeItem

pub(all) struct ChangeItem {
start : Cursor
end : Cursor
text : String
insert : Bool
}

A unique change to an editor.

#
ChangeItem::reverse

fn ChangeItem::reverse(self : ChangeItem) -> ChangeItem

#
Color

pub struct Color {
value : UInt
}

Text color (ARGB packed, aligned with upstream).
impl Eq for Color
impl Hash for Color

#
Color::a

fn Color::a(self : Color) -> Byte

#
Color::as_rgba

fn Color::as_rgba(self : Color) -> (Byte, Byte, Byte, Byte)

#
Color::b

fn Color::b(self : Color) -> Byte

#
Color::g

fn Color::g(self : Color) -> Byte

#
Color::r

fn Color::r(self : Color) -> Byte

#
Color::rgb

fn Color::rgb(r : Byte, g : Byte, b : Byte) -> Color

#
Color::rgba

fn Color::rgba(r : Byte, g : Byte, b : Byte, a : Byte) -> Color

#
Cursor

pub struct Cursor {
line : Int
index : Int
affinity : Affinity
}

Current cursor location
impl Eq for Cursor

#
Cursor::new

fn Cursor::new(line : Int, index : Int) -> Cursor

#
Cursor::new_with_affinity

fn Cursor::new_with_affinity(line : Int, index : Int, affinity : Affinity) -> Cursor

#
DecorationMetrics

pub struct DecorationMetrics {
offset : Float
thickness : Float
}

#
DecorationMetrics::new

fn DecorationMetrics::new(offset : Float, thickness : Float) -> DecorationMetrics

#
DecorationSpan

pub struct DecorationSpan {
glyph_start : Int
glyph_end : Int
data : GlyphDecorationData
color_opt : Color?
font_size : Float
}

A span of consecutive glyphs sharing the same text decoration.

#
Editor

pub struct Editor {
buffer : Buffer
cursor : Cursor
cursor_x_opt : Int?
selection : Selection
cursor_moved : Bool
auto_indent : Bool
change_opt : Change?
}

impl Edit for Editor

#
Editor::action

fn Editor::action(self : Editor, action : Action) -> Editor

Perform an action on the editor.

#
Editor::apply_change

fn Editor::apply_change(self : Editor, change : Change) -> (Editor, Bool)

#
Editor::auto_indent

fn Editor::auto_indent(self : Editor) -> Bool

#
Editor::buffer

fn Editor::buffer(self : Editor) -> Buffer

#
Editor::copy_selection

fn Editor::copy_selection(self : Editor) -> String?

#
Editor::cursor

fn Editor::cursor(self : Editor) -> Cursor

#
Editor::cursor_position

fn Editor::cursor_position(self : Editor) -> (Int, Int)?

Get X and Y position of the top-left corner of the cursor.

#
Editor::delete_range

fn Editor::delete_range(self : Editor, start : Cursor, end : Cursor) -> Editor

Delete text starting at start cursor and ending at end cursor.

#
Editor::delete_selection

fn Editor::delete_selection(self : Editor) -> (Editor, Bool)

#
Editor::finish_change

fn Editor::finish_change(self : Editor) -> (Editor, Change?)

#
Editor::insert_at

fn Editor::insert_at(self : Editor, cursor : Cursor, data : String, attrs_list_opt : AttrsList?) -> (Editor, Cursor)

Insert data at the specified cursor, returning the updated editor and the new cursor.

NOTE: attrs_list_opt is applied to inserted text; when None, we use the previous character's attrs as defaults.

#
Editor::insert_string

fn Editor::insert_string(self : Editor, data : String, attrs_list_opt : AttrsList?) -> Editor

Insert string at current cursor, replacing selection if present.

#
Editor::new

fn Editor::new(buffer : Buffer) -> Editor

#
Editor::render

fn[R : Renderer] Editor::render(self : Editor, renderer : R, text_color : Color, cursor_color : Color, selection_color : Color, selected_text_color : Color) -> Unit

Render editor contents with selection and cursor highlights.

#
Editor::selection

fn Editor::selection(self : Editor) -> Selection

#
Editor::selection_bounds

fn Editor::selection_bounds(self : Editor) -> (Cursor, Cursor)?

Get the bounds of the current selection (line/word selection is expanded).

#
Editor::set_auto_indent

fn Editor::set_auto_indent(self : Editor, auto_indent : Bool) -> Editor

#
Editor::set_cursor

fn Editor::set_cursor(self : Editor, cursor : Cursor) -> Editor

#
Editor::set_selection

fn Editor::set_selection(self : Editor, selection : Selection) -> Editor

#
Editor::set_tab_width

fn Editor::set_tab_width(self : Editor, tab_width : Int) -> Editor

Set tab width in spaces. A value of 0 is ignored (matches upstream).

#
Editor::start_change

fn Editor::start_change(self : Editor) -> Editor

#
Editor::tab_width

fn Editor::tab_width(self : Editor) -> Int

#
Ellipsize

pub(all) enum Ellipsize {
None
Start(EllipsizeHeightLimit)
Middle(EllipsizeHeightLimit)
End(EllipsizeHeightLimit)
}

#
EllipsizeHeightLimit

pub(all) enum EllipsizeHeightLimit {
Lines(Int)
Height(Float)
}

#
FallbackMissingKind

pub(all) enum FallbackMissingKind {
Exhausted
PresetFallback
ScriptFallback
}

#
FallbackProfile

pub(all) enum FallbackProfile {
Unix
MacOS
Windows
Other
}

#
Family

pub(all) enum Family {
Name(String)
Serif
SansSerif
Cursive
Fantasy
Monospace
SystemUi
UiSerif
UiSansSerif
UiMonospace
UiRounded
Emoji
Math
FangSong
}

Font family selector.

This mirrors the generic families exposed by cosmic-text and extends them with the CSS/Bevy generic families required by modern text stacks.
impl Eq for Family
impl Hash for Family
impl Show for Family

#
Feature

pub struct Feature {
tag : FeatureTag
value : UInt
}

impl Eq for Feature
impl Hash for Feature

#
Feature::new

fn Feature::new(tag : FeatureTag, value : UInt) -> Feature

#
Feature::tag

fn Feature::tag(self : Feature) -> FeatureTag

#
Feature::value

fn Feature::value(self : Feature) -> UInt

#
FeatureTag

pub struct FeatureTag {
value : UInt
}

impl Eq for FeatureTag
impl Hash for FeatureTag

#
FeatureTag::as_tag

fn FeatureTag::as_tag(self : FeatureTag) -> UInt

#
FeatureTag::from_tag

fn FeatureTag::from_tag(tag : UInt) -> FeatureTag

#
FeatureTag::new

fn FeatureTag::new(tag : String) -> FeatureTag

#
FontCachedCodepointSupportInfo

type FontCachedCodepointSupportInfo

#
FontEntry

pub struct FontEntry {
id : Int
family_name : String
postscript_name : String
source_data : Bytes
source_index : Int
font :
FontRef

charmap_proxy :
CharmapProxy

attributes :
Attributes

is_monospace : Bool
not_emoji : Bool
}

Minimal font system wrapper for the MoonBit cosmic-text port.

Upstream cosmic-text uses fontdb for font discovery. In this MoonBit port we start with an in-memory font list backed by moon_swash.

#
FontEntry::attributes

#
FontEntry::charmap_proxy

#
FontEntry::family_name

fn FontEntry::family_name(self : FontEntry) -> String

#
FontEntry::id

fn FontEntry::id(self : FontEntry) -> Int

#
FontEntry::is_monospace

fn FontEntry::is_monospace(self : FontEntry) -> Bool

#
FontEntry::not_emoji

fn FontEntry::not_emoji(self : FontEntry) -> Bool

#
FontEntry::postscript_name

fn FontEntry::postscript_name(self : FontEntry) -> String

#
FontEntry::source_data

fn FontEntry::source_data(self : FontEntry) -> Bytes

#
FontEntry::source_index

fn FontEntry::source_index(self : FontEntry) -> Int

#
FontFeatures

pub struct FontFeatures {
features : Array[Feature]
}

impl Eq for FontFeatures

#
FontFeatures::disable

fn FontFeatures::disable(self : FontFeatures, tag : FeatureTag) -> FontFeatures

#
FontFeatures::enable

fn FontFeatures::enable(self : FontFeatures, tag : FeatureTag) -> FontFeatures

#
FontFeatures::features

fn FontFeatures::features(self : FontFeatures) -> Array[Feature]

#
FontFeatures::new

#
FontFeatures::set

fn FontFeatures::set(self : FontFeatures, tag : FeatureTag, value : UInt) -> FontFeatures

#
FontMatchAttrs

pub struct FontMatchAttrs {
family : Family
weight : Weight
stretch :
Stretch

style :
Style

}

#
FontSystem

pub struct FontSystem {
locale : String
fonts : Array[FontEntry]
font_matches_cache :
HashMap
[FontMatchAttrs, Array[Int]]
codepoint_support_cache :
HashMap
[Int, FontCachedCodepointSupportInfo]
hb_font_cache :
HashMap
[Int,
Font
]
hb_shape_buffer :
Buffer

shape_run_cache : ShapeRunCache
// private fields
}

#
FontSystem::clear_fallback_profile

fn FontSystem::clear_fallback_profile(self : FontSystem) -> FontSystem

#
FontSystem::clear_fallback_warning_handler

fn FontSystem::clear_fallback_warning_handler(self : FontSystem) -> FontSystem

#
FontSystem::count_supported_codepoints

fn FontSystem::count_supported_codepoints(self : FontSystem, font_id : Int, codepoints : Array[UInt]) -> Int

#
FontSystem::font_matches

fn FontSystem::font_matches(self : FontSystem, attrs : Attrs) -> Array[Int]

Get ordered font match candidates for attrs (cached).

#
FontSystem::font_matches_for_script

fn FontSystem::font_matches_for_script(self : FontSystem, attrs : Attrs, script :
Script
) -> Array[Int]

#
FontSystem::font_matches_for_scripts

fn FontSystem::font_matches_for_scripts(self : FontSystem, attrs : Attrs, scripts : Array[
Script
]) -> Array[Int]

#
FontSystem::font_matches_for_scripts_with_codepoints

fn FontSystem::font_matches_for_scripts_with_codepoints(self : FontSystem, attrs : Attrs, scripts : Array[
Script
], codepoints : Array[UInt]) -> Array[Int]

#
FontSystem::fonts

fn FontSystem::fonts(self : FontSystem) -> Array[FontEntry]

#
FontSystem::get_font

fn FontSystem::get_font(self : FontSystem, font_id : Int) ->
FontRef
?

#
FontSystem::get_font_entry

fn FontSystem::get_font_entry(self : FontSystem, font_id : Int) -> FontEntry?

Get the full FontEntry for a font_id (useful for downstream rasterization with TTC collections).

#
FontSystem::load_font_data

fn FontSystem::load_font_data(self : FontSystem, data : Bytes) -> FontSystem

Load font data (TTF/OTF/TTC bytes) into the system.

If the bytes do not parse as a font/collection, this is a no-op.

#
FontSystem::locale

fn FontSystem::locale(self : FontSystem) -> String

#
FontSystem::new

fn FontSystem::new() -> FontSystem

#
FontSystem::new_with_locale

fn FontSystem::new_with_locale(locale : String) -> FontSystem

#
FontSystem::resolve

fn FontSystem::resolve(self : FontSystem, attrs : Attrs) -> Int?

Resolve a font ID for the given attrs (best-effort).

#
FontSystem::resolve_for_codepoint

fn FontSystem::resolve_for_codepoint(self : FontSystem, attrs : Attrs, codepoint : UInt) -> Int?

Resolve a font ID for a specific codepoint (best-effort).

This prefers the requested family (when present) and then minimizes weight difference, falling back to any loaded font that supports the codepoint.

#
FontSystem::select_family

fn FontSystem::select_family(self : FontSystem, family : Family) -> Int?

Find a font ID that matches the family selector (best-effort).

#
FontSystem::set_fallback_profile

fn FontSystem::set_fallback_profile(self : FontSystem, profile : FallbackProfile) -> FontSystem

#
FontSystem::set_fallback_warning_handler

fn FontSystem::set_fallback_warning_handler(self : FontSystem, handler : (String) -> Unit) -> FontSystem

#
GlyphDecorationData

pub struct GlyphDecorationData {
text_decoration : TextDecoration
underline_metrics : DecorationMetrics
strikethrough_metrics : DecorationMetrics
ascent : Float
}

#
Hinting

pub(all) enum Hinting {
Disabled
Enabled
}

Metrics hinting strategy

#
Justify

pub(all) enum Justify {
Left
Right
Center
Justified
Start
End
}

#
LayoutCursor

pub struct LayoutCursor {
line : Int
layout : Int
glyph : Int
}

The position of a cursor within a Buffer.
impl Eq for LayoutCursor

#
LayoutCursor::new

fn LayoutCursor::new(line : Int, layout : Int, glyph : Int) -> LayoutCursor

#
LayoutGlyph

pub struct LayoutGlyph {
start : Int
end : Int
font_size : Float
font_id : Int
font_weight : Int
glyph_id : Int
x : Float
y : Float
w : Float
level : Int
line_height_opt : Float?
x_offset : Float
y_offset : Float
color_opt : Color?
metadata : Int
cache_key_flags : UInt
}

A laid out glyph.

#
LayoutGlyph::new

fn LayoutGlyph::new(start : Int, end : Int, font_size : Float, font_id : Int, font_weight : Int, glyph_id : Int, x : Float, y : Float, w : Float, metadata : Int) -> LayoutGlyph

Convenience constructor (fills optional fields with defaults).

#
LayoutGlyph::physical

fn LayoutGlyph::physical(self : LayoutGlyph, offset : (Float, Float), scale : Float) -> PhysicalGlyph

#
LayoutLine

pub struct LayoutLine {
start : Int
end : Int
w : Float
max_ascent : Float
max_descent : Float
line_height_opt : Float?
glyphs : Array[LayoutGlyph]
decorations : Array[DecorationSpan]
}

A line of laid out glyphs.

#
LayoutRun

pub struct LayoutRun {
line_i : Int
line_y : Float
line_top : Float
line_height : Float
text : String
rtl : Bool
glyphs : Array[LayoutGlyph]
decorations : Array[DecorationSpan]
line_w : Float
}

A line of visible text for rendering.

#
LayoutRun::highlight

fn LayoutRun::highlight(self : LayoutRun, cursor_start : Cursor, cursor_end : Cursor) -> (Float, Float)?

Return highlighted x-span (x_left, width) intersecting this run.

#
LegacyRenderer

pub struct LegacyRenderer {
font_system : FontSystem
cache : SwashCache
callback : (Int, Int, UInt, UInt, Color) -> Unit
}

Helper to migrate from the legacy callback-based renderer.

This matches upstream LegacyRenderer: rectangles are forwarded to the callback, and glyphs are rasterized through SwashCache::with_pixels.

#
LegacyRenderer::new

fn LegacyRenderer::new(font_system : FontSystem, cache : SwashCache, callback : (Int, Int, UInt, UInt, Color) -> Unit) -> LegacyRenderer

#
LetterSpacing

pub struct LetterSpacing {
bits : UInt
}

impl Eq for LetterSpacing

#
LetterSpacing::new

fn LetterSpacing::new(value : Float) -> LetterSpacing

#
LetterSpacing::value

fn LetterSpacing::value(self : LetterSpacing) -> Float

#
LineBreak

pub(all) enum LineBreak {
NoWrap
AnyCharacter
WordBoundary
}

Compatibility layer for Bevy-style Text2d concepts.

Upstream cosmic-text uses Wrap + Align. Bevy exposes similar concepts as line-break and justification; we provide a small mapping layer here.

#
LineEnding

pub(all) enum LineEnding {
Lf
CrLf
Cr
LfCr
None
}

Ported from cosmic-text/src/line_ending.rs (cosmic-text is dual-licensed MIT OR Apache-2.0).

#
LineEnding::as_str

fn LineEnding::as_str(self : LineEnding) -> String

#
LineEnding::default

fn LineEnding::default() -> LineEnding

Default line ending (matches upstream: LF).

#
LineIter

pub struct LineIter {
string : String
start : Int
end : Int
}

#
LineIter::new

fn LineIter::new(string : String) -> LineIter

#
LineIter::next

fn LineIter::next(self : LineIter) -> (LineIter, (Int, Int, LineEnding)?)

Returns (start, end, ending) where [start,end) is the line content range.

#
LineState

pub struct LineState {
block_comment_depth : Int
markup_comment_open : Bool
markup_tag_open : Bool
ruby_block_comment_open : Bool
shell_heredoc_delim_opt : String?
shell_heredoc_strip_tabs : Bool
lua_long_eq_count_opt : Int?
lua_long_is_comment : Bool
string_delim_opt : Char?
string_is_triple : Bool
raw_hash_count_opt : Int?
markdown_fence_char_opt : Char?
clike_preproc_continuation : Bool
}

impl Eq for LineState

#
LineState::new

fn LineState::new() -> LineState

#
Metrics

pub struct Metrics {
font_size : Float
line_height : Float
}

Ported from cosmic-text/src/buffer.rs (cosmic-text is dual-licensed MIT OR Apache-2.0).

#
Metrics::new

fn Metrics::new(font_size : Float, line_height : Float) -> Metrics

#
Metrics::relative

fn Metrics::relative(font_size : Float, line_height_scale : Float) -> Metrics

Create metrics with given font size and calculate line height using relative scale.

#
Metrics::scale

fn Metrics::scale(self : Metrics, scale : Float) -> Metrics

Scale font size and line height.

#
Motion

pub(all) enum Motion {
LayoutCursor(LayoutCursor)
Previous
Next
Left
Right
Up
Down
Home
SoftHome
End
ParagraphStart
ParagraphEnd
PageUp
PageDown
Vertical(Int)
PreviousWord
NextWord
LeftWord
RightWord
BufferStart
BufferEnd
GotoLine(Int)
}

A motion to perform on a Cursor
impl Eq for Motion

#
ParagraphInfo

pub struct ParagraphInfo {
range_start : Int
range_end : Int
level : Int
}

Paragraph metadata for BiDi processing.

Indices are UTF-16 code-unit offsets in the source text.

#
ParagraphInfo::is_rtl

fn ParagraphInfo::is_rtl(self : ParagraphInfo) -> Bool

#
ParagraphInfo::level

fn ParagraphInfo::level(self : ParagraphInfo) -> Int

#
ParagraphInfo::range_end

fn ParagraphInfo::range_end(self : ParagraphInfo) -> Int

#
ParagraphInfo::range_start

fn ParagraphInfo::range_start(self : ParagraphInfo) -> Int

#
PhysicalGlyph

pub struct PhysicalGlyph {
cache_key : CacheKey
x : Int
y : Int
}

A laid out glyph in physical/pixel coordinates, ready for rasterization.

#
Scroll

pub struct Scroll {
line : Int
vertical : Float
horizontal : Float
}

Scroll position in Buffer

#
Scroll::default

fn Scroll::default() -> Scroll

#
Scroll::new

fn Scroll::new(line : Int, vertical : Float, horizontal : Float) -> Scroll

#
Selection

pub(all) enum Selection {
None
Normal(Cursor)
Line(Cursor)
Word(Cursor)
}

Selection mode.
impl Eq for Selection

#
ShapeGlyph

pub struct ShapeGlyph {
start : Int
end : Int
x_advance : Float
y_advance : Float
x_offset : Float
y_offset : Float
ascent : Float
descent : Float
font_id : Int
font_weight : Int
glyph_id : Int
color_opt : Color?
metadata : Int
cache_key_flags : UInt
text_decoration : TextDecoration
underline_metrics : DecorationMetrics
strikethrough_metrics : DecorationMetrics
level : Int
metrics_opt : Metrics?
}

#
ShapeGlyph::new

fn ShapeGlyph::new(start : Int, end : Int, x_advance : Float, y_advance : Float, x_offset : Float, y_offset : Float, font_id : Int, glyph_id : Int, metadata : Int) -> ShapeGlyph

#
ShapeGlyph::width

fn ShapeGlyph::width(self : ShapeGlyph, font_size : Float) -> Float

#
ShapeGlyph::with_ascent_descent

fn ShapeGlyph::with_ascent_descent(self : ShapeGlyph, ascent : Float, descent : Float) -> ShapeGlyph

#
ShapeLine

pub struct ShapeLine {
text : String
rtl : Bool
glyphs : Array[ShapeGlyph]
}

#
ShapeLine::build

fn ShapeLine::build(_self : ShapeLine, text : String, attrs_list : AttrsList, shaping : Shaping, tab_width : Int) -> ShapeLine

Build a shaped line from text and attributes list.

#
ShapeLine::build_with_font_system

fn ShapeLine::build_with_font_system(_self : ShapeLine, font_system : FontSystem, text : String, attrs_list : AttrsList, shaping : Shaping, tab_width : Int) -> ShapeLine

Build a shaped line using a FontSystem (best-effort).

Advanced mode follows upstream shape_run/shape_fallback flow on top of moon_swash: BiDi runs, per-run script/fallback selection, cluster-aware glyph ranges, and run-cache reuse.

#
ShapeLine::empty

fn ShapeLine::empty() -> ShapeLine

#
ShapeLine::layout

fn ShapeLine::layout(self : ShapeLine, font_size : Float, width_opt : Float?, wrap : Wrap, ellipsize : Ellipsize, align : Align?, match_mono_width : Float?, hinting : Hinting) -> Array[LayoutLine]

#
ShapeLine::layout_to_buffer

fn ShapeLine::layout_to_buffer(self : ShapeLine, font_size : Float, width_opt : Float?, wrap : Wrap, ellipsize : Ellipsize, align : Align?, layout_lines : Array[LayoutLine], match_mono_width : Float?, hinting : Hinting) -> Unit

#
ShapeLine::new

fn ShapeLine::new(rtl : Bool, glyphs : Array[ShapeGlyph]) -> ShapeLine

#
ShapeLine::width

fn ShapeLine::width(self : ShapeLine, font_size : Float) -> Float

#
ShapeRunCache

pub struct ShapeRunCache {
age : UInt64
cache :
HashMap
[ShapeRunKey, (UInt64, Array[ShapeGlyph])]
}

A helper structure for caching shape runs.

#
ShapeRunCache::clear

fn ShapeRunCache::clear(self : ShapeRunCache) -> Unit

Clear all cached runs.

#
ShapeRunCache::get

Get a cache item, updating age if found.

#
ShapeRunCache::insert

fn ShapeRunCache::insert(self : ShapeRunCache, key : ShapeRunKey, glyphs : Array[ShapeGlyph]) -> Unit

Insert a cache item with current age.

#
ShapeRunCache::new

#
ShapeRunCache::peek

Peek a cache item without updating its age.

#
ShapeRunCache::trim

fn ShapeRunCache::trim(self : ShapeRunCache, keep_ages : UInt64) -> Unit

Remove anything in the cache with an age older than keep_ages.

#
ShapeRunKey

pub struct ShapeRunKey {
text : String
default_attrs : Attrs
attrs_spans : Array[(Int, Int, Attrs)]
}

Key for caching shape runs.
impl Eq for ShapeRunKey
impl Hash for ShapeRunKey

#
ShapeRunKey::new

fn ShapeRunKey::new(text : String, attrs_list : AttrsList) -> ShapeRunKey

#
Shaping

pub(all) enum Shaping {
Basic
Advanced
}

Shaping primitives ported from cosmic-text/src/shape.rs.

#
SubpixelBin

pub enum SubpixelBin {
Zero
One
Two
Three
}

Binning of subpixel position for cache optimization.
impl Eq for SubpixelBin
impl Hash for SubpixelBin
impl Show for SubpixelBin

#
SubpixelBin::as_float

fn SubpixelBin::as_float(self : SubpixelBin) -> Float

#
SubpixelBin::new

fn SubpixelBin::new(pos : Float) -> (Int, SubpixelBin)

Returns (integral pixel position, bin for fractional part).

Matches upstream cosmic-text binning behavior, including negative positions.

#
SwashCache

#
SwashCache::get_image

fn SwashCache::get_image(self : SwashCache, font_system : FontSystem, cache_key : CacheKey) ->
Image
?

#
SwashCache::get_image_uncached

fn SwashCache::get_image_uncached(self : SwashCache, font_system : FontSystem, cache_key : CacheKey) ->
Image
?

#
SwashCache::get_outline_commands

fn SwashCache::get_outline_commands(self : SwashCache, font_system : FontSystem, cache_key : CacheKey) -> (Array[
Vector
], Array[
Verb
])?

Create outline commands (path data) from a cache key, caching results.

This matches upstream SwashCache::get_outline_commands.

#
SwashCache::get_outline_commands_uncached

fn SwashCache::get_outline_commands_uncached(self : SwashCache, font_system : FontSystem, cache_key : CacheKey) -> (Array[
Vector
], Array[
Verb
])?

Create outline commands (path data) from a cache key, without caching results.

This matches upstream SwashCache::get_outline_commands_uncached.

#
SwashCache::new

fn SwashCache::new() -> SwashCache

#
SwashCache::with_pixels

fn SwashCache::with_pixels(self : SwashCache, font_system : FontSystem, cache_key : CacheKey, base : Color, f : (Int, Int, Color) -> Unit) -> Unit

Enumerate pixels in a cached glyph image.

#
SyntaxEditor

pub struct SyntaxEditor {
editor : Editor
syntax_system : SyntaxSystem
syntax_name : String
theme : SyntaxTheme
cache : Array[CachedLine]
}

#
SyntaxEditor::action

fn SyntaxEditor::action(self : SyntaxEditor, action : Action) -> SyntaxEditor

#
SyntaxEditor::apply_change

fn SyntaxEditor::apply_change(self : SyntaxEditor, change : Change) -> (SyntaxEditor, Bool)

#
SyntaxEditor::auto_indent

fn SyntaxEditor::auto_indent(self : SyntaxEditor) -> Bool

#
SyntaxEditor::background_color

fn SyntaxEditor::background_color(self : SyntaxEditor) -> Color

#
SyntaxEditor::copy_selection

fn SyntaxEditor::copy_selection(self : SyntaxEditor) -> String?

#
SyntaxEditor::cursor

fn SyntaxEditor::cursor(self : SyntaxEditor) -> Cursor

#
SyntaxEditor::cursor_color

fn SyntaxEditor::cursor_color(self : SyntaxEditor) -> Color

#
SyntaxEditor::cursor_position

fn SyntaxEditor::cursor_position(self : SyntaxEditor) -> (Int, Int)?

#
SyntaxEditor::delete_range

fn SyntaxEditor::delete_range(self : SyntaxEditor, start : Cursor, end : Cursor) -> SyntaxEditor

#
SyntaxEditor::delete_selection

fn SyntaxEditor::delete_selection(self : SyntaxEditor) -> (SyntaxEditor, Bool)

#
SyntaxEditor::editor

fn SyntaxEditor::editor(self : SyntaxEditor) -> Editor

#
SyntaxEditor::finish_change

fn SyntaxEditor::finish_change(self : SyntaxEditor) -> (SyntaxEditor, Change?)

#
SyntaxEditor::foreground_color

fn SyntaxEditor::foreground_color(self : SyntaxEditor) -> Color

#
SyntaxEditor::insert_string

fn SyntaxEditor::insert_string(self : SyntaxEditor, data : String, attrs_list_opt : AttrsList?) -> SyntaxEditor

#
SyntaxEditor::new

fn SyntaxEditor::new(editor : Editor, syntax_system : SyntaxSystem, theme_name : String) -> SyntaxEditor?

#
SyntaxEditor::rehighlight

fn SyntaxEditor::rehighlight(self : SyntaxEditor) -> SyntaxEditor

#
SyntaxEditor::render

fn[R : Renderer] SyntaxEditor::render(self : SyntaxEditor, renderer : R) -> Unit

#
SyntaxEditor::selection

fn SyntaxEditor::selection(self : SyntaxEditor) -> Selection

#
SyntaxEditor::selection_color

fn SyntaxEditor::selection_color(self : SyntaxEditor) -> Color

#
SyntaxEditor::set_auto_indent

fn SyntaxEditor::set_auto_indent(self : SyntaxEditor, auto_indent : Bool) -> SyntaxEditor

#
SyntaxEditor::set_cursor

fn SyntaxEditor::set_cursor(self : SyntaxEditor, cursor : Cursor) -> SyntaxEditor

#
SyntaxEditor::set_editor

fn SyntaxEditor::set_editor(self : SyntaxEditor, editor : Editor) -> SyntaxEditor

#
SyntaxEditor::set_selection

fn SyntaxEditor::set_selection(self : SyntaxEditor, selection : Selection) -> SyntaxEditor

#
SyntaxEditor::set_tab_width

fn SyntaxEditor::set_tab_width(self : SyntaxEditor, tab_width : Int) -> SyntaxEditor

#
SyntaxEditor::start_change

fn SyntaxEditor::start_change(self : SyntaxEditor) -> SyntaxEditor

#
SyntaxEditor::syntax_by_extension

fn SyntaxEditor::syntax_by_extension(self : SyntaxEditor, extension : String) -> SyntaxEditor

#
SyntaxEditor::syntax_name

fn SyntaxEditor::syntax_name(self : SyntaxEditor) -> String

#
SyntaxEditor::tab_width

fn SyntaxEditor::tab_width(self : SyntaxEditor) -> Int

#
SyntaxEditor::theme

#
SyntaxEditor::update_theme

fn SyntaxEditor::update_theme(self : SyntaxEditor, theme_name : String) -> (SyntaxEditor, Bool)

#
SyntaxSystem

pub struct SyntaxSystem {
}

#
SyntaxSystem::new

#
SyntaxSystem::plain_text_syntax

fn SyntaxSystem::plain_text_syntax(_self : SyntaxSystem) -> String

#
SyntaxSystem::syntax_for_extension

fn SyntaxSystem::syntax_for_extension(_self : SyntaxSystem, extension : String) -> String?

#
SyntaxSystem::theme

fn SyntaxSystem::theme(_self : SyntaxSystem, theme_name : String) -> SyntaxTheme?

#
SyntaxTheme

pub struct SyntaxTheme {
name : String
background : Color
foreground : Color
cursor_opt : Color?
selection_opt : Color?
keyword : Color
type_name : Color
string_lit : Color
comment : Color
number : Color
}

Internal syntax-highlighting editor layer inspired by cosmic-text/src/edit/syntect.rs.

#
SyntaxTheme::background

fn SyntaxTheme::background(self : SyntaxTheme) -> Color

#
SyntaxTheme::cursor

fn SyntaxTheme::cursor(self : SyntaxTheme) -> Color

#
SyntaxTheme::foreground

fn SyntaxTheme::foreground(self : SyntaxTheme) -> Color

#
SyntaxTheme::name

fn SyntaxTheme::name(self : SyntaxTheme) -> String

#
SyntaxTheme::selection

fn SyntaxTheme::selection(self : SyntaxTheme) -> Color

#
TextDecoration

pub struct TextDecoration {
underline : UnderlineStyle
underline_color_opt : Color?
strikethrough : Bool
strikethrough_color_opt : Color?
overline : Bool
overline_color_opt : Color?
}

#
TextDecoration::has_decoration

fn TextDecoration::has_decoration(self : TextDecoration) -> Bool

#
TextDecoration::new

#
TokenClass

pub(all) enum TokenClass {
Keyword
TypeName
StringLit
Comment
Number
}

#
TokenSpan

pub struct TokenSpan {
start : Int
end : Int
class : TokenClass
}

#
UnderlineStyle

pub(all) enum UnderlineStyle {
None
Single
Double
}

#
ViEditor

pub struct ViEditor {
editor : Editor
mode : ViMode
pending_operator : ViOperator?
passthrough : Bool
history : Array[Change]
history_index : Int
save_pivot_opt : Int?
changed : Bool
search_opt : (String, Bool)?
search_input_opt : String?
search_input_forwards : Bool
pending_find_opt : (Bool, Bool, Int)?
last_find_opt : (Bool, Bool, Char)?
pending_replace_char : Bool
pending_text_object_opt : (ViOperator, Bool)?
pending_g : Bool
pending_count_opt : Int?
pending_register_prefix : Bool
active_register_opt : Char?
registers : Array[(Char, Selection, String)]
register_opt : String?
}

impl Edit for ViEditor

#
ViEditor::changed

fn ViEditor::changed(self : ViEditor) -> Bool

#
ViEditor::editor

fn ViEditor::editor(self : ViEditor) -> Editor

#
ViEditor::escape

fn ViEditor::escape(self : ViEditor) -> ViEditor

#
ViEditor::feed_char

fn ViEditor::feed_char(self : ViEditor, key : Char) -> ViEditor

#
ViEditor::feed_string

fn ViEditor::feed_string(self : ViEditor, keys : String) -> ViEditor

#
ViEditor::mode

fn ViEditor::mode(self : ViEditor) -> ViMode

#
ViEditor::new

fn ViEditor::new(editor : Editor) -> ViEditor

#
ViEditor::redo

fn ViEditor::redo(self : ViEditor) -> ViEditor

#
ViEditor::save_point

fn ViEditor::save_point(self : ViEditor) -> ViEditor

#
ViEditor::set_changed

fn ViEditor::set_changed(self : ViEditor, changed : Bool) -> ViEditor

#
ViEditor::set_editor

fn ViEditor::set_editor(self : ViEditor, editor : Editor) -> ViEditor

#
ViEditor::set_passthrough

fn ViEditor::set_passthrough(self : ViEditor, passthrough : Bool) -> ViEditor

#
ViEditor::undo

fn ViEditor::undo(self : ViEditor) -> ViEditor

#
ViMode

pub(all) enum ViMode {
Normal
Insert
Replace
Visual
VisualLine
Search
}

Internal Vi-style editor layer on top of moon_cosmic.Editor.

#
ViOperator

pub(all) enum ViOperator {
Delete
Change
Yank
ShiftLeft
ShiftRight
}

#
Weight

pub struct Weight {
value : Int
}

Font weight (1..=1000). This is a simplified stand-in for fontdb::Weight.
impl Eq for Weight
impl Hash for Weight
impl Show for Weight

#
Weight::bold

fn Weight::bold() -> Weight

#
Weight::new

fn Weight::new(value : Int) -> Weight

#
Weight::normal

fn Weight::normal() -> Weight

#
Weight::value

fn Weight::value(self : Weight) -> Int

#
Wrap

pub(all) enum Wrap {
None
Glyph
Word
WordOrGlyph
}

Wrapping mode

#
CACHE_KEY_FLAG_DISABLE_HINTING

let CACHE_KEY_FLAG_DISABLE_HINTING : UInt

#
CACHE_KEY_FLAG_FAKE_ITALIC

let CACHE_KEY_FLAG_FAKE_ITALIC : UInt

#
CACHE_KEY_FLAG_PIXEL_FONT

let CACHE_KEY_FLAG_PIXEL_FONT : UInt

#
apply_align

fn apply_align(text : String, lines : Array[LayoutLine], width : Float, align : Align) -> Array[LayoutLine]

Apply Align to precomputed layout lines assuming LTR paragraph direction.

#
apply_align_with_rtl

fn apply_align_with_rtl(text : String, lines : Array[LayoutLine], width : Float, align : Align, rtl : Bool) -> Array[LayoutLine]

Apply Align to precomputed layout lines (requires a finite width).

#
cosmic_text_version

fn cosmic_text_version() -> String

Port scaffold for cosmic-text (MIT OR Apache-2.0).

The port is implemented incrementally while keeping data-flow behavior aligned.

#
floorf

fn floorf(x : Float) -> Float

#
grapheme_indices_uax29

fn grapheme_indices_uax29(s : String) -> Array[(Int, Int)]

#
justify_to_align

fn justify_to_align(j : Justify) -> Align

#
layout_ascii

fn layout_ascii(text : String, glyph_w : Float, width_opt : Float?, wrap : Wrap) -> Array[LayoutLine]

ASCII-only layout for wrap tests.

Semantics:
  • Treat each code unit as one glyph.
  • glyph_w is a monospace advance in pixels.

#
layout_from_shape

fn layout_from_shape(text : String, shape : ShapeLine, font_size : Float, cell_w : Float, width_opt : Float?, wrap : Wrap) -> Array[LayoutLine]

Layout from ShapeLine.

cell_w is the pixel width per "advance cell" (ShapeGlyph.x_advance is in cells).

#
line_break_to_wrap

fn line_break_to_wrap(lb : LineBreak) -> Wrap

#
render_decoration

fn[R : Renderer] render_decoration(renderer : R, run : LayoutRun, default_color : Color) -> Unit

Draw text decoration lines (underline, strikethrough, overline) for a layout run.

#
roundf

fn roundf(x : Float) -> Float

#
truncf

fn truncf(x : Float) -> Float

#
word_indices_uax29

fn word_indices_uax29(s : String) -> Array[(Int, Int)]

#
word_indices_whitespace

fn word_indices_whitespace(s : String) -> Array[(Int, Int)]

Compatibility wrappers for segmentation APIs.

Implementations are hosted in the linebreak internal subpackage.

#
wrap_word_segments

fn wrap_word_segments(s : String) -> Array[(Int, Int, Bool)]