Expand description
rich_text — a styled rich-text document model, command engine, layout
engine, and the widgets (RichTextView, RichTextEdit) that render and
edit it. This is the toolkit for embedding a real text editor in your
agg-gui app, not a fixed demo widget: you own the document, supply the
fonts, and drive formatting through commands.
§Module layout
model— the document types (RichDoc,Block,TextRun,InlineStyle,ListKind), positions/ranges (DocPos,DocRange), and the structural edit primitives (insert / remove / split / merge / normalize).commands—RichCommandplusapply_command, with toolbar-state helpers (style_at,range_common_style,CommonStyle).layout— width-constrained, per-run-font layout producing paint-ready line/fragment geometry (DocLayout). Catalog-agnostic: it asks a resolver (SharedResolver) to map each run’s style to aFont.view—RichTextView, a read-only display widget, plus thesingle_font_resolverhelper.editor—RichTextEdit, the interactive editor, and the cheapRichEditHandlea formatting toolbar drives it through.
§Embedding an editor
Everything a functional editor needs is public here. A resolver maps run
styles to concrete fonts (see single_font_resolver for the full
contract); RichTextEdit::handle hands a toolbar a cheap, cloneable driver
that shares the very editor being rendered.
use std::sync::Arc;
use agg_gui::Font;
use agg_gui::widgets::rich_text::{
single_font_resolver, Block, InlineStyle, RichCommand, RichDoc, RichTextEdit, TextRun,
};
// 1. Load a font. Any `Arc<Font>` works; here we read the crate's bundled
// face so this example is a real, runnable doc-test.
let bytes = std::fs::read(concat!(
env!("CARGO_MANIFEST_DIR"),
"/assets/fonts/NotoSans-Regular.ttf",
))
.expect("bundled font readable");
let font = Arc::new(Font::from_slice(&bytes).expect("valid font"));
// 2. Build a document from styled runs (or `RichDoc::new()` for a blank one).
let bold = InlineStyle { bold: true, ..Default::default() };
let doc = RichDoc::from_blocks(vec![Block {
runs: vec![
TextRun::new("Hello, ", InlineStyle::default()),
TextRun::new("world", bold),
],
..Block::new()
}]);
// 3. One font -> a working resolver -> a functional editor in one line each.
let resolver = single_font_resolver(font);
let mut editor = RichTextEdit::new(doc, resolver).with_font_size(18.0);
// 4. A cheap handle drives the same editor from a toolbar (clone freely).
let toolbar = editor.handle();
// 5. Apply formatting commands (a real selection comes from mouse/keyboard
// input dispatched to `editor.on_event`; a collapsed caret arms the format
// for the next typed run).
toolbar.exec(&RichCommand::ToggleItalic);
// 6. Read toolbar state: what styles the current selection shares.
let style = editor.common_style_of_selection();
let _ = style.bold; // Option<bool>: Some(v) = all agree, None = mixed.
// 7. Undo / redo flow through the shared core (also on the handle).
if editor.can_undo() {
editor.undo();
}
toolbar.redo();
assert!(editor.plain_text().starts_with("Hello"));To display a document without editing, use RichTextView the same way.
For a multi-font resolver with real bold/italic faces backed by a system-font
catalog, see make_resolver in demo-ui/src/windows/rich_text_demo.
§Asynchronous font loading
The editor caches its layout against (width, document revision) and does
not observe an app’s font catalog. If your app loads faces
asynchronously, call RichTextEdit::invalidate_layout when a newly-arrived
font should be picked up (e.g. on each advance of your font-cache epoch), so
the doc reshapes and the cached backbuffer re-rasters.
Re-exports§
pub use commands::apply_command;pub use commands::range_common_style;pub use commands::style_at;pub use commands::CommonStyle;pub use commands::RichCommand;pub use commands::MAX_INDENT;pub use editor::RichEditCore;pub use editor::RichEditHandle;pub use editor::RichTextEdit;pub use layout::layout_doc;pub use layout::BlockLayout;pub use layout::DocLayout;pub use layout::FontResolver;pub use layout::LineFragment;pub use layout::LineLayout;pub use layout::INDENT_PX;pub use layout::LINE_SPACING;pub use layout::LIST_GUTTER_PX;pub use layout::MARKER_GAP_PX;pub use model::insert_text;pub use model::merge_block_with_prev;pub use model::remove_range;pub use model::split_block;pub use model::Block;pub use model::DocPos;pub use model::DocRange;pub use model::InlineStyle;pub use model::ListKind;pub use model::RichDoc;pub use model::TextRun;pub use toolbar::RichTextToolbar;pub use toolbar::Variant;pub use view::single_font_resolver;pub use view::uniform_resolver;pub use view::RichTextView;
Modules§
- commands
- Rich-text command engine — applies editor commands to a
RichDocover a selectionDocRange. - editor
RichTextEdit— the interactive rich-text editor widget.- layout
- Rich-text layout engine — wraps a
RichDocto a fixed width with per-run fonts and sizes, producing paint-ready line/fragment geometry. - model
- Rich-text document model and structural editing primitives.
- rich_
clipboard - Process-wide rich clipboard slot for
RichTextEdit. - toolbar
RichTextToolbar— a configurable, batteries-included formatting toolbar driven by aRichEditHandle.- view
RichTextView— a read-only widget that paints a laid-outRichDoc.