1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//! `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`] — [`RichCommand`] plus [`apply_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 a
//! [`Font`](crate::text::Font).
//! * [`view`] — [`RichTextView`], a read-only display widget, plus the
//! [`single_font_resolver`] helper.
//! * [`editor`] — [`RichTextEdit`], the interactive editor, and the cheap
//! [`RichEditHandle`] a 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.
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;