cosmic_text/lib.rs
1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! # COSMIC Text
4//!
5//! This library provides advanced text handling in a generic way. It provides abstractions for
6//! shaping, font discovery, font fallback, layout, rasterization, and editing. Shaping utilizes
7//! rustybuzz, font discovery utilizes fontdb, and the rasterization is optional and utilizes
8//! swash. The other features are developed internal to this library.
9//!
10//! It is recommended that you start by creating a [`FontSystem`], after which you can create a
11//! [`Buffer`], provide it with some text, and then inspect the layout it produces. At this
12//! point, you can use the `SwashCache` to rasterize glyphs into either images or pixels.
13//!
14//! ```
15//! use cosmic_text::{Attrs, Color, FontSystem, SwashCache, Buffer, Metrics, Shaping};
16//!
17//! // A FontSystem provides access to detected system fonts, create one per application
18//! let mut font_system = FontSystem::new();
19//!
20//! // A SwashCache stores rasterized glyphs, create one per application
21//! let mut swash_cache = SwashCache::new();
22//!
23//! // Text metrics indicate the font size and line height of a buffer
24//! let metrics = Metrics::new(14.0, 20.0);
25//!
26//! // A Buffer provides shaping and layout for a UTF-8 string, create one per text widget
27//! let mut buffer = Buffer::new(&mut font_system, metrics);
28//!
29//! // Borrow buffer together with the font system for more convenient method calls
30//! let mut buffer = buffer.borrow_with(&mut font_system);
31//!
32//! // Set a size for the text buffer, in pixels
33//! buffer.set_size(Some(80.0), Some(25.0));
34//!
35//! // Attributes indicate what font to choose
36//! let attrs = Attrs::new();
37//!
38//! // Add some text!
39//! buffer.set_text("Hello, Rust! 🦀\n", attrs, Shaping::Advanced);
40//!
41//! // Perform shaping as desired
42//! buffer.shape_until_scroll(true);
43//!
44//! // Inspect the output runs
45//! for run in buffer.layout_runs() {
46//! for glyph in run.glyphs.iter() {
47//! println!("{:#?}", glyph);
48//! }
49//! }
50//!
51//! // Create a default text color
52//! let text_color = Color::rgb(0xFF, 0xFF, 0xFF);
53//!
54//! // Draw the buffer (for performance, instead use SwashCache directly)
55//! buffer.draw(&mut swash_cache, text_color, |x, y, w, h, color| {
56//! // Fill in your code here for drawing rectangles
57//! });
58//! ```
59
60// Not interested in these lints
61#![allow(clippy::new_without_default)]
62// TODO: address occurrences and then deny
63//
64// Overflows can produce unpredictable results and are only checked in debug builds
65#![allow(clippy::arithmetic_side_effects)]
66// Indexing a slice can cause panics and that is something we always want to avoid
67#![allow(clippy::indexing_slicing)]
68// Soundness issues
69//
70// Dereferencing unaligned pointers may be undefined behavior
71#![deny(clippy::cast_ptr_alignment)]
72// Avoid panicking in without information about the panic. Use expect
73#![deny(clippy::unwrap_used)]
74// Ensure all types have a debug impl
75#![deny(missing_debug_implementations)]
76// This is usually a serious issue - a missing import of a define where it is interpreted
77// as a catch-all variable in a match, for example
78#![deny(unreachable_patterns)]
79// Ensure that all must_use results are used
80#![deny(unused_must_use)]
81// Style issues
82//
83// Documentation not ideal
84#![warn(clippy::doc_markdown)]
85// Document possible errors
86#![warn(clippy::missing_errors_doc)]
87// Document possible panics
88#![warn(clippy::missing_panics_doc)]
89// Ensure semicolons are present
90#![warn(clippy::semicolon_if_nothing_returned)]
91// Ensure numbers are readable
92#![warn(clippy::unreadable_literal)]
93#![cfg_attr(not(feature = "std"), no_std)]
94extern crate alloc;
95
96#[cfg(not(any(feature = "std", feature = "no_std")))]
97compile_error!("Either the `std` or `no_std` feature must be enabled");
98
99pub use self::attrs::*;
100mod attrs;
101
102pub use self::bidi_para::*;
103mod bidi_para;
104
105pub use self::buffer::*;
106mod buffer;
107
108pub use self::buffer_line::*;
109mod buffer_line;
110
111pub use self::cached::*;
112mod cached;
113
114pub use self::glyph_cache::*;
115mod glyph_cache;
116
117pub use self::cursor::*;
118mod cursor;
119
120pub use self::edit::*;
121mod edit;
122
123pub use self::font::*;
124mod font;
125
126pub use self::layout::*;
127mod layout;
128
129pub use self::line_ending::*;
130mod line_ending;
131
132pub use self::shape::*;
133mod shape;
134
135pub use self::shape_run_cache::*;
136mod shape_run_cache;
137
138#[cfg(feature = "swash")]
139pub use self::swash::*;
140#[cfg(feature = "swash")]
141mod swash;
142
143mod math;
144
145type BuildHasher = core::hash::BuildHasherDefault<rustc_hash::FxHasher>;
146
147#[cfg(feature = "std")]
148type HashMap<K, V> = std::collections::HashMap<K, V, BuildHasher>;
149#[cfg(not(feature = "std"))]
150type HashMap<K, V> = hashbrown::HashMap<K, V, BuildHasher>;