Skip to main content

ratatui_wgpu/
lib.rs

1//! # Getting Started
2//! Check out the [examples](https://github.com/Jesterhearts/ratatui-wgpu/tree/main/examples)
3//! for a number of programs using `winit` for both native and web.
4//!
5//! A [`WgpuBackend`] can be constructed using a [`Builder`] and then provided
6//! to a [`Terminal`](ratatui::Terminal). After that, rendering can be done as
7//! normal using the ratatui library. If you need custom shader post-processing,
8//! see the [`PostProcessor`] trait or the
9//! [`DefaultPostProcessor`](shaders::DefaultPostProcessor) implementation for
10//! guidance.
11//!
12//! Here's a short example using winit on native with the default post processor
13//! implementation:
14//! ```
15//! # use std::{
16//! #     num::NonZeroU32,
17//! #     sync::Arc,
18//! # };
19//! #
20//! # use chrono::Local;
21//! # use ratatui::{
22//! #     prelude::*,
23//! #     widgets::*,
24//! # };
25//! # use ratatui_wgpu::{
26//! #     Builder,
27//! #     Font,
28//! #     WgpuBackend,
29//! #     Dimensions,
30//! # };
31//! # use winit::{
32//! #     application::ApplicationHandler,
33//! #     event::WindowEvent,
34//! #     event_loop::EventLoop,
35//! #     window::{
36//! #         Window,
37//! #         WindowAttributes,
38//! #     },
39//! # };
40//! #
41//! pub struct App {
42//!     window: Option<Arc<Window>>,
43//!     backend: Option<Terminal<WgpuBackend<'static, 'static>>>,
44//! }
45//!
46//! impl ApplicationHandler for App {
47//!     fn resumed(
48//!         &mut self,
49//!         event_loop: &winit::event_loop::ActiveEventLoop,
50//!     ) {
51//!         self.window = Some(Arc::new(
52//!             event_loop
53//!                 .create_window(WindowAttributes::default())
54//!                 .unwrap(),
55//!         ));
56//!
57//!         let size = self.window.as_ref().unwrap().inner_size();
58//!
59//!         self.backend = Some(
60//!             Terminal::new(
61//!                 futures_lite::future::block_on(
62//!                     Builder::from_font(
63//!                         Font::new(include_bytes!("backend/fonts/CascadiaMono-Regular.ttf"))
64//!                             .unwrap(),
65//!                     )
66//!                     .with_width_and_height(Dimensions {
67//!                         width: NonZeroU32::new(size.width).unwrap(),
68//!                         height: NonZeroU32::new(size.height).unwrap(),
69//!                     })
70//!                     .build_with_target(self.window.as_ref().unwrap().clone()),
71//!                 )
72//!                 .unwrap(),
73//!             )
74//!             .unwrap(),
75//!         );
76//!
77//!         self.window.as_ref().unwrap().request_redraw();
78//!     }
79//!
80//!     fn window_event(
81//!         &mut self,
82//!         event_loop: &winit::event_loop::ActiveEventLoop,
83//!         _window_id: winit::window::WindowId,
84//!         event: winit::event::WindowEvent,
85//!     ) {
86//!         if let WindowEvent::CloseRequested = event {
87//!             event_loop.exit();
88//!             return;
89//!         }
90//!
91//!         let Some(terminal) = self.backend.as_mut() else {
92//!             return;
93//!         };
94//!
95//!         if let WindowEvent::Resized(size) = event {
96//!             terminal.backend_mut().resize(size.width, size.height);
97//!         }
98//!
99//!         terminal
100//!             .draw(|f| {
101//!                 f.render_widget(
102//!                     Paragraph::new(Line::from("Hello World!")).block(Block::bordered()),
103//!                     f.area(),
104//!                 );
105//!             })
106//!             .unwrap();
107//!
108//!         self.window.as_ref().unwrap().request_redraw();
109//!     }
110//! }
111//! ```
112//!
113//! # Limitations
114//! 1. No cursor rendering.
115//!     - The location of the cursor is tracked, and operations using it should
116//!       behave as expected, but the cursor is not rendered to the screen.
117//! 2. Attempting to render more unique (utf8 character * BOLD|ITALIC)
118//!    characters than can fit in the cache in a single draw call will cause
119//!    incorrect rendering. This is ~3750 characters at the default font size
120//!    with most fonts. If you need more than this, file a bug and I'll do the
121//!    work to make rendering handle an unbounded number of unique characters.
122//!    To put that in perspective, rendering every printable ascii character in
123//!    every combination of styles would take (95 * 4) 380 cache entries or ~10%
124//!    of the cache.
125
126pub(crate) mod backend;
127pub(crate) mod colors;
128pub(crate) mod fonts;
129pub mod shaders;
130pub(crate) mod utils;
131
132pub use ratatui_core;
133use thiserror::Error;
134pub use wgpu;
135
136#[macro_use]
137extern crate log;
138
139/// Represents the various errors that can occur during operation.
140#[derive(Debug, Error)]
141pub enum Error {
142    /// Backend creation failed because the device request failed.
143    #[error("{0}")]
144    DeviceRequestFailed(wgpu::RequestDeviceError),
145    /// Backend creation failed because creating the surface failed.
146    #[error("{0}")]
147    SurfaceCreationFailed(wgpu::CreateSurfaceError),
148    /// Backend creation failed because wgpu didn't provide an
149    /// [`Adapter`](wgpu::Adapter)
150    #[error("{0}")]
151    AdapterRequestFailed(wgpu::RequestAdapterError),
152    /// Backend creation failed because the default surface configuration
153    /// couldn't be loaded.
154    #[error("Failed to get default Surface configuration from wgpu.")]
155    SurfaceConfigurationRequestFailed,
156}
157
158pub type Result<T> = ::std::result::Result<T, Error>;
159
160#[cfg(feature = "ahash")]
161type RandomState = ahash::RandomState;
162#[cfg(not(feature = "ahash"))]
163type RandomState = std::hash::RandomState;
164
165pub use backend::builder::Builder;
166pub use backend::wgpu_backend::WgpuBackend;
167pub use backend::Dimensions;
168pub use backend::PostProcessor;
169pub use backend::RenderSurface;
170pub use backend::RenderTexture;
171pub use backend::Viewport;
172pub use colors::ColorTable;
173pub use fonts::Font;
174pub use fonts::Fonts;