### Inspect Rendered Lines and Hit Testing Source: https://context7.com/pop-os/cosmic-text/llms.txt Use `LayoutRun` to get information about shaped glyphs for a visual line, including selection highlights and cursor pixel positions. It also allows iterating through glyphs with their positions. ```rust use cosmic_text::{Attrs, Buffer, Cursor, FontSystem, Metrics, Shaping}; let mut font_system = FontSystem::new(); let mut buffer = Buffer::new(&mut font_system, Metrics::new(14.0, 20.0)); buffer.set_size(Some(300.0), Some(200.0)); buffer.set_text("Hello, BiDi مرحبا!", &Attrs::new(), Shaping::Advanced, None); buffer.shape_until_scroll(&mut font_system, false); let cursor_start = Cursor::new(0, 0); let cursor_end = Cursor::new(0, 5); // "Hello" for run in buffer.layout_runs() { // Selection highlight segments (multiple for mixed BiDi runs). for (x, width) in run.highlight(cursor_start, cursor_end) { println!("highlight rect: x={x:.1} width={width:.1} y={:.1} h={:.1}", run.line_top, run.line_height); } // Pixel x position of a specific cursor. if let Some(x) = run.cursor_position(&cursor_end) { println!("cursor x = {x:.1}"); } // Enumerate all glyphs with their positions. for glyph in run.glyphs { let cluster = &run.text[glyph.start..glyph.end]; println!(" '{cluster}' x={:.1} w={:.1}", glyph.x, glyph.w); } } ``` -------------------------------- ### Select Text Shaping Mode Source: https://context7.com/pop-os/cosmic-text/llms.txt Choose between `Shaping::Basic` for fast ASCII-centric text processing and `Shaping::Advanced` for full OpenType shaping, which is necessary for ligatures, bidirectional text, and complex scripts. This example shows setting text with both modes. ```rust use cosmic_text::{Attrs, Buffer, FontSystem, Metrics, Shaping}; let mut font_system = FontSystem::new(); let mut buffer = Buffer::new_empty(Metrics::new(14.0, 20.0)); let mut buf = buffer.borrow_with(&mut font_system); buf.set_size(Some(400.0), None); // Fast path: ASCII or Latin-1 only, no ligatures. buf.set_text("Hello world", &Attrs::new(), Shaping::Basic, None); // Full path: bidirectional, ligatures, complex scripts. buf.set_text( "fi fl — مرحبا — 日本語 — 🦀 Rust", &Attrs::new(), Shaping::Advanced, None, ); ``` -------------------------------- ### Configure Cosmic Text for no_std Environments Source: https://context7.com/pop-os/cosmic-text/llms.txt To use Cosmic Text in a `no_std` environment, disable default features and enable the `no_std` feature in `Cargo.toml`. Font data must be provided as `Binary` sources, as system font loading is not available. This example demonstrates loading font bytes directly. ```toml # Cargo.toml [dependencies] cosmic-text = { version = "0.19", default-features = false, features = ["no_std"] } ``` ```rust use cosmic_text::{Attrs, Buffer, FontSystem, Metrics, Shaping, fontdb}; // Provide font bytes at compile time. static FONT: &[u8] = include_bytes!("../fonts/Inter-Regular.ttf"); let mut db = fontdb::Database::new(); db.load_font_source(fontdb::Source::Binary( alloc::sync::Arc::new(FONT) )); let mut font_system = FontSystem::new_with_locale_and_db( "en-US".into(), db, ); let mut buffer = Buffer::new_empty(Metrics::new(12.0, 16.0)); buffer.set_text("no_std text", &Attrs::new(), Shaping::Advanced, None); buffer.shape_until_scroll(&mut font_system, false); ``` -------------------------------- ### Implement Custom Rendering with Renderer Trait Source: https://context7.com/pop-os/cosmic-text/llms.txt Implement the `Renderer` trait to decouple text layout from rendering and integrate with any graphics backend. This example shows a `MyRenderer` struct that handles drawing rectangles for decorations and rasterized glyphs onto a pixel buffer. ```rust use cosmic_text::{ Attrs, Buffer, Color, FontSystem, Metrics, PhysicalGlyph, Renderer, Shaping, SwashCache, render_decoration, }; struct MyRenderer<'a> { font_system: &'a mut FontSystem, swash: &'a mut SwashCache, pixels: &'a mut Vec, // RGBA flat buffer, width=200 width: u32, } impl Renderer for MyRenderer<'_> { fn rectangle(&mut self, x: i32, y: i32, w: u32, h: u32, color: Color) { // Fill axis-aligned rectangle with solid color. for row in 0..h as i32 { for col in 0..w as i32 { let idx = ((y + row) * self.width as i32 + (x + col)) as usize * 4; if idx + 3 < self.pixels.len() { let [r, g, b, a] = color.as_rgba(); self.pixels[idx..idx+4].copy_from_slice(&[r, g, b, a]); } } } } fn glyph(&mut self, physical_glyph: PhysicalGlyph, color: Color) { self.swash.with_pixels(self.font_system, physical_glyph.cache_key, color, |dx, dy, pixel_color| { let px = physical_glyph.x + dx; let py = physical_glyph.y + dy; let idx = (py * self.width as i32 + px) as usize * 4; if idx + 3 < self.pixels.len() { let [r, g, b, a] = pixel_color.as_rgba(); self.pixels[idx..idx+4].copy_from_slice(&[r, g, b, a]); } }); } } // Usage: let mut font_system = FontSystem::new(); let mut swash_cache = SwashCache::new(); let mut pixels = vec![0u8; 200 * 100 * 4]; let mut buffer = Buffer::new(&mut font_system, Metrics::new(14.0, 20.0)); buffer.set_size(Some(200.0), Some(100.0)); buffer.set_text("Custom renderer", &Attrs::new(), Shaping::Advanced, None); buffer.render( &mut font_system, &mut MyRenderer { font_system: &mut font_system, swash: &mut swash_cache, pixels: &mut pixels, width: 200, }, Color::rgb(0xFF, 0xFF, 0xFF), ); ``` -------------------------------- ### Rasterize Glyphs with SwashCache Source: https://context7.com/pop-os/cosmic-text/llms.txt Use SwashCache to rasterize LayoutGlyphs into alpha masks or RGBA bitmaps. It caches results keyed by CacheKey and should be created per application. This example shows iterating through laid-out glyphs and rasterizing them using `with_pixels` or retrieving cached images and outline commands. ```rust use cosmic_text::{Attrs, Buffer, Color, FontSystem, Metrics, Shaping, SwashCache}; let mut font_system = FontSystem::new(); let mut cache = SwashCache::new(); let mut buffer = Buffer::new(&mut font_system, Metrics::new(14.0, 20.0)); buffer.set_size(Some(200.0), Some(60.0)); buffer.set_text("Aa 🦀", &Attrs::new(), Shaping::Advanced, None); buffer.shape_until_scroll(&mut font_system, false); let text_color = Color::rgb(0xFF, 0xFF, 0xFF); // Iterate runs and rasterize each glyph via with_pixels. for run in buffer.layout_runs() { for glyph in run.glyphs { let physical = glyph.physical((0.0, run.line_y), 1.0); cache.with_pixels( &mut font_system, physical.cache_key, text_color, |dx, dy, color| { let px = physical.x + dx; let py = physical.y + dy; // Write `color` at pixel coordinate (px, py). let _ = (px, py, color); }, ); } } // Or get the raw SwashImage for a glyph (cached). for run in buffer.layout_runs() { for glyph in run.glyphs { let key = glyph.physical((0.0, run.line_y), 1.0).cache_key; if let Some(image) = cache.get_image(&mut font_system, key) { println!( "glyph image {}×{} content={{:?}}", image.placement.width, image.placement.height, image.content ); } } } // Get vector outline commands for a glyph (for vector/SVG rendering). for run in buffer.layout_runs() { for glyph in run.glyphs { let key = glyph.physical((0.0, run.line_y), 1.0).cache_key; if let Some(commands) = cache.get_outline_commands(&mut font_system, key) { println!("{} path commands", commands.len()); } } } ``` -------------------------------- ### Create Metrics Source: https://context7.com/pop-os/cosmic-text/llms.txt Shows how to create and scale Metrics for font size and line height, both explicitly and relatively. ```rust use cosmic_text::Metrics; // Explicit font size and line height in pixels. let metrics = Metrics::new(16.0, 22.0); // Line height derived as a multiple of font size. let metrics = Metrics::relative(16.0, 1.4); // line_height = 22.4 // Scale for HiDPI displays. let scale_factor = 2.0_f32; let scaled = metrics.scale(scale_factor); // font_size = 32.0, line_height = 44.8 println!("{}", scaled); // "32px / 44.8px" ``` -------------------------------- ### Initialize FontSystem Source: https://context7.com/pop-os/cosmic-text/llms.txt Demonstrates various ways to initialize a FontSystem, including loading system fonts, supplying custom font data, and specifying locales. ```rust use cosmic_text::{FontSystem, fontdb}; // Default: loads all system fonts, detects locale automatically. let mut font_system = FontSystem::new(); // Supply additional fonts from raw bytes (e.g., bundled in the binary). let font_bytes = include_bytes!("../fonts/InterVariable.ttf"); font_system.db_mut().load_font_data(font_bytes.to_vec()); // Supply font sources at construction time (skips system font loading). let custom = FontSystem::new_with_fonts([ fontdb::Source::Binary(std::sync::Arc::new(font_bytes.to_vec())), ]); // Build from a pre-populated fontdb and explicit locale. let mut db = fontdb::Database::new(); db.load_system_fonts(); db.load_font_data(font_bytes.to_vec()); let font_system = FontSystem::new_with_locale_and_db("en-US".to_string(), db); // Access the underlying fontdb for querying installed faces. for face in font_system.db().faces() { println!("{} — monospaced: {}", face.post_script_name, face.monospaced); } ``` -------------------------------- ### Build Attrs Source: https://context7.com/pop-os/cosmic-text/llms.txt Demonstrates how to construct Attrs for per-span text styling, including font family, weight, style, color, metrics, and decorations. ```rust use cosmic_text::{Attrs, Color, Family, FontFeatures, FeatureTag, Metrics, Style, UnderlineStyle, Weight}; // Default sans-serif, weight 400, style Normal. let base = Attrs::new(); // Bold italic serif at a custom size. let heading = Attrs::new() .family(Family::Serif) .weight(Weight::BOLD) .style(Style::Italic) .color(Color::rgb(0x22, 0x22, 0x22)) .metrics(Metrics::new(24.0, 30.0)); // Monospace with letter spacing and enabled small-caps feature. let mut features = FontFeatures::new(); features.enable(FeatureTag::SMALL_CAPS); let code = Attrs::new() .family(Family::Monospace) .letter_spacing(0.05) // 5% of 1 em .font_features(features); // Underline + strikethrough decoration. let decorated = Attrs::new() .underline(UnderlineStyle::Single) .strikethrough(); // Check if two Attrs can share the same shaping run. assert!(!heading.compatible(&code)); ``` -------------------------------- ### Interactive Text Editing with Editor Source: https://context7.com/pop-os/cosmic-text/llms.txt Demonstrates interactive text editing using the Editor struct, including cursor movement, text insertion, deletion, simulated mouse actions, and drawing the editor content. Requires FontSystem and SwashCache. ```rust use cosmic_text::{ Action, Attrs, Buffer, Color, Cursor, Edit, Editor, FontSystem, Metrics, Motion, Selection, Shaping, SwashCache, }; let mut font_system = FontSystem::new(); let mut swash_cache = SwashCache::new(); let mut buffer = Buffer::new_empty(Metrics::new(16.0, 22.0)); buffer.set_size(Some(400.0), Some(300.0)); buffer.set_text("Hello, editor!\nSecond line.", &Attrs::new(), Shaping::Advanced, None); let mut editor = Editor::new(buffer); let mut ed = editor.borrow_with(&mut font_system); // Move cursor to end of first line. ed.action(Action::Motion(Motion::End)); // Insert text at cursor. ed.action(Action::Insert(' ')); ed.action(Action::Insert('✏')); // Enter key creates a new line. ed.action(Action::Enter); // Backspace deletes behind the cursor. ed.action(Action::Backspace); // Simulate mouse click. ed.action(Action::Click { x: 50, y: 10 }); // Extend selection with drag. ed.action(Action::Drag { x: 120, y: 10 }); // Double-click selects a word; triple-click selects the line. ed.action(Action::DoubleClick { x: 50, y: 10 }); // Copy the current selection. if let Some(text) = ed.copy_selection() { println!("selected: {{text:?}}"); } // Query cursor position in pixels. if let Some((cx, cy)) = ed.cursor_position() { println!("cursor at ({{cx}}, {{cy}})"); } // Check if a redraw is needed before painting. ed.shape_as_needed(false); if ed.redraw() { ed.draw( &mut swash_cache, Color::rgb(0xFF, 0xFF, 0xFF), // text Color::rgb(0xFF, 0xFF, 0x00), // cursor Color::rgba(0x33, 0x99, 0xFF, 0x55), // selection background Color::rgb(0x00, 0x00, 0x00), // selected text |x, y, w, h, color| { let _ = (x, y, w, h, color); }, ); ed.set_redraw(false); } ``` -------------------------------- ### Configure Line Wrapping and Alignment Source: https://context7.com/pop-os/cosmic-text/llms.txt Set line wrapping modes (None, Glyph, Word, WordOrGlyph) and text alignment (Justified). Word wrapping is the default. ```rust use cosmic_text::{Align, Attrs, Buffer, FontSystem, Metrics, Shaping, Wrap}; let mut font_system = FontSystem::new(); let mut buffer = Buffer::new(&mut font_system, Metrics::new(16.0, 22.0)); let mut buf = buffer.borrow_with(&mut font_system); buf.set_size(Some(200.0), Some(400.0)); // Wrap::None — no wrapping; Wrap::Glyph — break at any glyph; // Wrap::Word — break only at word boundaries; // Wrap::WordOrGlyph (default) — word, falling back to glyph. buf.set_wrap(Wrap::Word); let long = "The quick brown fox jumps over the lazy dog. ".repeat(3); buf.set_text(&long, &Attrs::new(), Shaping::Advanced, Some(Align::Justified)); for run in buf.layout_runs() { println!("visual line width: {:.1}px", run.line_w); } ``` -------------------------------- ### Configuring and Laying Out Text with Buffer Source: https://context7.com/pop-os/cosmic-text/llms.txt The Buffer object manages lines of text, layout metrics, and text wrapping. It allows configuration of dimensions, wrapping, and text alignment, and provides methods for hit-testing and cursor positioning. ```rust use cosmic_text::{Align, Attrs, Buffer, Color, Ellipsize, EllipsizeHeightLimit, FontSystem, Hinting, Metrics, Shaping, SwashCache, Wrap}; let mut font_system = FontSystem::new(); let mut swash_cache = SwashCache::new(); // Create a buffer and borrow it alongside the font system. let mut buffer = Buffer::new(&mut font_system, Metrics::new(14.0, 20.0)); let mut buf = buffer.borrow_with(&mut font_system); // Configure dimensions and wrapping. buf.set_size(Some(400.0), Some(600.0)); buf.set_wrap(Wrap::WordOrGlyph); buf.set_ellipsize(Ellipsize::End(EllipsizeHeightLimit::Lines(3))); buf.set_tab_width(4); buf.set_hinting(Hinting::Enabled); // Set plain text (all lines share the same Attrs). let attrs = Attrs::new(); buf.set_text("Hello, 🌍!\nSecond line.", &attrs, Shaping::Advanced, Some(Align::Left)); // Inspect laid-out runs. for run in buf.layout_runs() { println!("line {}: y={:.1} rtl={}", run.line_i, run.line_y, run.rtl); for glyph in run.glyphs { println!(" glyph id={} x={:.1} w={:.1}", glyph.glyph_id, glyph.x, glyph.w); } } // Hit-test: convert pixel coordinates to a Cursor. if let Some(cursor) = buf.hit(120.0, 15.0) { println!("click → line={} index={}", cursor.line, cursor.index); } // Pixel cursor position. use cosmic_text::Cursor; let cursor = Cursor::new(0, 5); if let Some((x, y)) = buf.cursor_position(&cursor) { println!("cursor at ({x}, {y})"); } // Draw using a pixel callback (requires `swash` feature). buf.draw(&mut swash_cache, Color::rgb(0xFF, 0xFF, 0xFF), |x, y, w, h, color| { // paint rectangle of size w×h at (x,y) with the given color let _ = (x, y, w, h, color); }); ``` -------------------------------- ### Cursor Positioning and Navigation Source: https://context7.com/pop-os/cosmic-text/llms.txt Move the cursor within the buffer using predefined motions like Next, End, BufferStart, and NextWord. The `cursor_motion` function returns the new cursor position. ```rust use cosmic_text::{Attrs, Buffer, Cursor, FontSystem, Metrics, Motion, Shaping}; let mut font_system = FontSystem::new(); let mut buffer = Buffer::new(&mut font_system, Metrics::new(14.0, 20.0)); buffer.set_text("Hello\nWorld", &Attrs::new(), Shaping::Advanced, None); buffer.set_size(Some(200.0), Some(100.0)); buffer.shape_until_scroll(&mut font_system, false); let start = Cursor::new(0, 0); // Move one character forward. let (next, _x) = buffer .cursor_motion(&mut font_system, start, None, Motion::Next) .unwrap(); assert_eq!(next.index, 1); // Jump to end of current line. let (end, _) = buffer .cursor_motion(&mut font_system, start, None, Motion::End) .unwrap(); assert_eq!(end.index, 5); // "Hello".len() // Jump to beginning of buffer. let (top, _) = buffer .cursor_motion(&mut font_system, end, None, Motion::BufferStart) .unwrap(); assert_eq!((top.line, top.index), (0, 0)); // Word-level navigation. let (word_end, _) = buffer .cursor_motion(&mut font_system, start, None, Motion::NextWord) .unwrap(); println!("next word boundary at index {}", word_end.index); ``` -------------------------------- ### Managing Per-Character Attributes with AttrsList Source: https://context7.com/pop-os/cosmic-text/llms.txt Use AttrsList to apply and query styling attributes for specific byte ranges within a line. It supports adding, retrieving, and iterating over attribute spans. ```rust use cosmic_text::{Attrs, AttrsList, Color, Weight}; let default_attrs = Attrs::new(); let mut list = AttrsList::new(&default_attrs); // Make bytes 0..4 bold red. let bold_red = Attrs::new() .weight(Weight::BOLD) .color(Color::rgb(0xFF, 0x00, 0x00)); list.add_span(0..4, &bold_red); // Query attribute at a specific byte index. let at_2 = list.get_span(2); assert_eq!(at_2.weight, Weight::BOLD); // Iterate over all non-default spans. for (range, owned_attrs) in list.spans() { println!("{range:?} → weight {:?}", owned_attrs.weight); } // Split at byte 4: list keeps 0..4, new_list gets 4..end. let new_list = list.split_off(4); ``` -------------------------------- ### FontSystem Source: https://context7.com/pop-os/cosmic-text/llms.txt FontSystem is responsible for discovering and accessing system fonts. It manages font fallback and provides access to the font database. It's recommended to create a single FontSystem instance per application. ```APIDOC ## FontSystem ### Description `FontSystem` is the single source of truth for all font data. It loads system fonts at construction time, manages a font cache keyed by `(fontdb::ID, fontdb::Weight)`, handles font fallback, and owns the per-shaping scratch buffer. Create exactly one per application and share it via mutable reference. ### Usage Examples ```rust use cosmic_text::{FontSystem, fontdb}; // Default: loads all system fonts, detects locale automatically. let mut font_system = FontSystem::new(); // Supply additional fonts from raw bytes (e.g., bundled in the binary). let font_bytes = include_bytes!("../fonts/InterVariable.ttf"); font_system.db_mut().load_font_data(font_bytes.to_vec()); // Supply font sources at construction time (skips system font loading). let custom = FontSystem::new_with_fonts([ fontdb::Source::Binary(std::sync::Arc::new(font_bytes.to_vec())), ]); // Build from a pre-populated fontdb and explicit locale. let mut db = fontdb::Database::new(); db.load_system_fonts(); db.load_font_data(font_bytes.to_vec()); let font_system = FontSystem::new_with_locale_and_db("en-US".to_string(), db); // Access the underlying fontdb for querying installed faces. for face in font_system.db().faces() { println!("{} — monospaced: {}", face.post_script_name, face.monospaced); } ``` ``` -------------------------------- ### Metrics Source: https://context7.com/pop-os/cosmic-text/llms.txt Metrics bundles font size and line height. It is used when creating or updating text buffers and for styling text spans. ```APIDOC ## Metrics ### Description `Metrics` bundles the two fundamental layout parameters: font size and line height. It is accepted by `Buffer::new`, `Buffer::set_metrics`, and per-span `Attrs::metrics`. ### Usage Examples ```rust use cosmic_text::Metrics; // Explicit font size and line height in pixels. let metrics = Metrics::new(16.0, 22.0); // Line height derived as a multiple of font size. let metrics = Metrics::relative(16.0, 1.4); // line_height = 22.4 // Scale for HiDPI displays. let scale_factor = 2.0_f32; let scaled = metrics.scale(scale_factor); // font_size = 32.0, line_height = 44.8 println!("{}", scaled); // "32px / 44.8px" ``` ``` -------------------------------- ### Color Type Source: https://context7.com/pop-os/cosmic-text/llms.txt Illustrates the usage of the Color type for RGBA values, including construction and channel access. ```rust use cosmic_text::Color; let white = Color::rgb(0xFF, 0xFF, 0xFF); let red_50 = Color::rgba(0xFF, 0x00, 0x00, 0x80); // 50% alpha red let (r, g, b, a) = white.as_rgba_tuple(); // (255, 255, 255, 255) let [r, g, b, a] = red_50.as_rgba(); // [255, 0, 0, 128] assert_eq!(red_50.r(), 0xFF); assert_eq!(red_50.a(), 0x80); ``` -------------------------------- ### Apply Text Decorations and Font Features Source: https://context7.com/pop-os/cosmic-text/llms.txt Use Attrs to apply various text decorations like single/double underlines, strikethroughs, and overlines with custom colors. Configure FontFeatures to enable or disable specific OpenType features such as small caps and ligatures. This snippet demonstrates setting rich text with these attributes. ```rust use cosmic_text::{ Attrs, Buffer, Color, FeatureTag, FontFeatures, FontSystem, Metrics, Shaping, UnderlineStyle, }; let mut font_system = FontSystem::new(); let mut buffer = Buffer::new_empty(Metrics::new(16.0, 22.0)); let mut buf = buffer.borrow_with(&mut font_system); buf.set_size(Some(500.0), Some(100.0)); // Underline with custom color. let underlined = Attrs::new() .underline(UnderlineStyle::Single) .underline_color(Color::rgb(0xFF, 0x00, 0x00)); // Double underline. let double_ul = Attrs::new().underline(UnderlineStyle::Double); // Strikethrough. let strike = Attrs::new().strikethrough(); // Overline. let overline = Attrs::new().overline(); // OpenType small caps. let mut features = FontFeatures::new(); features.enable(FeatureTag::SMALL_CAPS); features.disable(FeatureTag::STANDARD_LIGATURES); let small_caps = Attrs::new().font_features(features); // OpenType discretionary ligatures. let mut dlig = FontFeatures::new(); dlig.enable(FeatureTag::DISCRETIONARY_LIGATURES); let ligatures = Attrs::new().font_features(dlig); buf.set_rich_text( [ ("Underlined ", underlined), ("Strike ", strike), ("SmallCaps ", small_caps), ("Ligatures", ligatures), ], &Attrs::new(), Shaping::Advanced, None, ); ``` -------------------------------- ### Editor Interface with Edit Trait Source: https://context7.com/pop-os/cosmic-text/llms.txt Illustrates the Edit trait's capabilities for cursor management, selection, text mutation, and change tracking within an Editor. Requires FontSystem. ```rust use cosmic_text::{ Action, Attrs, AttrsList, Buffer, Change, Cursor, Edit, Editor, FontSystem, Metrics, Motion, Selection, Shaping, }; let mut font_system = FontSystem::new(); let mut buffer = Buffer::new_empty(Metrics::new(14.0, 20.0)); buffer.set_size(Some(300.0), Some(200.0)); buffer.set_text("abc def ghi", &Attrs::new(), Shaping::Advanced, None); let mut editor = Editor::new(buffer); let mut ed = editor.borrow_with(&mut font_system); // --- Cursor --- ed.set_cursor(Cursor::new(0, 4)); // position after "abc " assert_eq!(ed.cursor().index, 4); // --- Selection --- ed.set_selection(Selection::Normal(Cursor::new(0, 0))); // selection_bounds returns (start, end) in logical order. let bounds = ed.selection_bounds(); println!("selection: {{bounds:?}}"); // Word selection on double-click. ed.set_selection(Selection::Word(Cursor::new(0, 0))); // Line selection on triple-click. ed.set_selection(Selection::Line(Cursor::new(0, 0))); // --- Mutation --- // Insert a string at cursor (replacing any selection). ed.insert_string("XYZ", None); // Insert at arbitrary position with custom attribute list. let attrs = Attrs::new(); let new_cursor = ed.insert_at(Cursor::new(0, 0), ">>", Some(AttrsList::new(&attrs))); // Delete a range. ed.delete_range(Cursor::new(0, 0), Cursor::new(0, 2)); // Delete the current selection. ed.delete_selection(); // --- Change tracking (undo/redo support) --- ed.start_change(); ed.insert_string("typed text", None); if let Some(change) = ed.finish_change() { println!("{{change.items.len()}} change items"); // Reverse and re-apply for undo. let mut undo = change.clone(); undo.reverse(); // ed.apply_change(&undo); } // Auto-indent on Enter. ed.set_auto_indent(true); ed.action(Action::Enter); ``` -------------------------------- ### Attrs Source: https://context7.com/pop-os/cosmic-text/llms.txt Attrs is used to define per-span text attributes, including font family, weight, style, color, metrics, and OpenType features. ```APIDOC ## Attrs ### Description `Attrs` is a lightweight, builder-style struct that describes how a span of text should be shaped and rendered. It carries font family, weight, style, stretch, optional color, optional per-span metrics, letter spacing, OpenType features, and text decorations. ### Usage Examples ```rust use cosmic_text::{Attrs, Color, Family, FontFeatures, FeatureTag, Metrics, Style, UnderlineStyle, Weight}; // Default sans-serif, weight 400, style Normal. let base = Attrs::new(); // Bold italic serif at a custom size. let heading = Attrs::new() .family(Family::Serif) .weight(Weight::BOLD) .style(Style::Italic) .color(Color::rgb(0x22, 0x22, 0x22)) .metrics(Metrics::new(24.0, 30.0)); // Monospace with letter spacing and enabled small-caps feature. let mut features = FontFeatures::new(); features.enable(FeatureTag::SMALL_CAPS); let code = Attrs::new() .family(Family::Monospace) .letter_spacing(0.05) // 5% of 1 em .font_features(features); // Underline + strikethrough decoration. let decorated = Attrs::new() .underline(UnderlineStyle::Single) .strikethrough(); // Check if two Attrs can share the same shaping run. assert!(!heading.compatible(&code)); ``` ``` -------------------------------- ### Color Source: https://context7.com/pop-os/cosmic-text/llms.txt Color represents an RGBA color value, stored as a packed u32. It provides constructors and channel accessors for use in rendering. ```APIDOC ## Color ### Description `Color` stores a packed `u32` in ARGB order and provides constructors and channel accessors used throughout the rendering pipeline. ### Usage Examples ```rust use cosmic_text::Color; let white = Color::rgb(0xFF, 0xFF, 0xFF); let red_50 = Color::rgba(0xFF, 0x00, 0x00, 0x80); // 50% alpha red let (r, g, b, a) = white.as_rgba_tuple(); // (255, 255, 255, 255) let [r, g, b, a] = red_50.as_rgba(); // [255, 0, 0, 128] assert_eq!(red_50.r(), 0xFF); assert_eq!(red_50.a(), 0x80); ``` ``` -------------------------------- ### Setting Rich Text with Multiple Spans Source: https://context7.com/pop-os/cosmic-text/llms.txt Use `set_rich_text` to populate a Buffer with text containing heterogeneous formatting. It accepts an iterator of string slices and their associated attributes, automatically handling line breaks and span assignments. ```rust use cosmic_text::{Attrs, Buffer, Family, FontSystem, Metrics, Shaping, Style, Weight}; let mut font_system = FontSystem::new(); let mut buffer = Buffer::new_empty(Metrics::new(18.0, 26.0)); let mut buf = buffer.borrow_with(&mut font_system); buf.set_size(Some(500.0), Some(300.0)); let default = Attrs::new(); let spans: &[(&str, Attrs)] = &[ ("Hello ", default.clone()), ("bold ", default.clone().weight(Weight::BOLD)), ("italic\n", default.clone().style(Style::Italic)), ("Serif ", default.clone().family(Family::Serif)), ("Mono", default.clone().family(Family::Monospace)), ]; buf.set_rich_text( spans.iter().map(|(s, a)| (*s, a.clone())), &default, Shaping::Advanced, None, ); // After set_rich_text the buffer has 2 BufferLines (split at \n). assert_eq!(buf.lines.len(), 2); ``` -------------------------------- ### Configure Text Truncation with Ellipsis Source: https://context7.com/pop-os/cosmic-text/llms.txt Truncate overflowing text with an ellipsis at the end or middle of lines, based on line count or pixel height limits. The default is to clip at the end of the last fitting line. ```rust use cosmic_text::{Attrs, Buffer, Ellipsize, EllipsizeHeightLimit, FontSystem, Metrics, Shaping}; let mut font_system = FontSystem::new(); let mut buffer = Buffer::new(&mut font_system, Metrics::new(14.0, 20.0)); let mut buf = buffer.borrow_with(&mut font_system); buf.set_size(Some(200.0), Some(60.0)); // only 3 lines fit // Clip at end of the last line that fits (most common). buf.set_ellipsize(Ellipsize::End(EllipsizeHeightLimit::Lines(3))); // Or clip at a pixel height limit. buf.set_ellipsize(Ellipsize::End(EllipsizeHeightLimit::Height(60.0))); // Truncate at the middle of a single long line. buf.set_ellipsize(Ellipsize::Middle(EllipsizeHeightLimit::Lines(1))); buf.set_text( "This is a very long line that will be truncated with an ellipsis.", &Attrs::new(), Shaping::Advanced, None, ); for run in buf.layout_runs() { let text: String = run.glyphs.iter() .map(|g| &run.text[g.start..g.end]) .collect(); println!("{text}"); } ```