epaint/lib.rs
1//! A simple 2D graphics library for turning simple 2D shapes and text into textured triangles.
2//!
3//! Made for [`egui`](https://github.com/emilk/egui/).
4//!
5//! Create some [`Shape`]:s and pass them to [`Tessellator::tessellate_shapes`] to generate [`Mesh`]:es
6//! that you can then paint using some graphics API of your choice (e.g. OpenGL).
7//!
8//! ## Coordinate system
9//! The left-top corner of the screen is `(0.0, 0.0)`,
10//! with X increasing to the right and Y increasing downwards.
11//!
12//! `epaint` uses logical _points_ as its coordinate system.
13//! Those related to physical _pixels_ by the `pixels_per_point` scale factor.
14//! For example, a high-dpi screen can have `pixels_per_point = 2.0`,
15//! meaning there are two physical screen pixels for each logical point.
16//!
17//! Angles are in radians, and are measured clockwise from the X-axis, which has angle=0.
18//!
19//! ## Feature flags
20#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
21//!
22
23#![expect(clippy::float_cmp)]
24#![expect(clippy::manual_range_contains)]
25
26mod brush;
27pub mod color;
28mod corner_radius;
29mod corner_radius_f32;
30mod direction;
31pub mod image;
32mod margin;
33mod margin_f32;
34mod mesh;
35pub mod mutex;
36mod shadow;
37pub mod shape_transform;
38mod shapes;
39pub mod stats;
40mod stroke;
41pub mod tessellator;
42pub mod text;
43mod texture_atlas;
44mod texture_handle;
45pub mod textures;
46pub mod util;
47mod viewport;
48
49pub use self::{
50 brush::Brush,
51 color::ColorMode,
52 corner_radius::CornerRadius,
53 corner_radius_f32::CornerRadiusF32,
54 direction::Direction,
55 image::{ColorImage, FontColorTransferFunction, ImageData, ImageDelta},
56 margin::Margin,
57 margin_f32::*,
58 mesh::{Mesh, Mesh16, Vertex},
59 shadow::Shadow,
60 shapes::{
61 CircleShape, CubicBezierShape, EllipseShape, PaintCallback, PaintCallbackInfo, PathShape,
62 QuadraticBezierShape, RectShape, Shape, TextShape,
63 },
64 stats::PaintStats,
65 stroke::{PathStroke, Stroke, StrokeKind},
66 tessellator::{TessellationOptions, Tessellator},
67 text::{FontFamily, FontId, Fonts, FontsView, Galley, TextOptions},
68 texture_atlas::TextureAtlas,
69 texture_handle::TextureHandle,
70 textures::TextureManager,
71 viewport::ViewportInPixels,
72};
73
74pub use ecolor::{Color32, Hsva, HsvaGamma, Rgba};
75pub use emath::{Pos2, Rect, Vec2, pos2, vec2};
76
77pub use ecolor;
78pub use emath;
79
80#[cfg(feature = "color-hex")]
81pub use ecolor::hex_color;
82
83/// The UV coordinate of a white region of the texture mesh.
84///
85/// The default egui texture has the top-left corner pixel fully white.
86/// You need need use a clamping texture sampler for this to work
87/// (so it doesn't do bilinear blending with bottom right corner).
88pub const WHITE_UV: emath::Pos2 = emath::pos2(0.0, 0.0);
89
90/// What texture to use in a [`Mesh`] mesh.
91///
92/// If you don't want to use a texture, use `TextureId::Managed(0)` and the [`WHITE_UV`] for uv-coord.
93#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
94#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
95pub enum TextureId {
96 /// Textures allocated using [`TextureManager`].
97 ///
98 /// The first texture (`TextureId::Managed(0)`) is used for the font data.
99 Managed(u64),
100
101 /// Your own texture, defined in any which way you want.
102 /// The backend renderer will presumably use this to look up what texture to use.
103 User(u64),
104}
105
106impl Default for TextureId {
107 /// The epaint font texture.
108 fn default() -> Self {
109 Self::Managed(0)
110 }
111}
112
113/// A [`Shape`] within a clip rectangle.
114///
115/// Everything is using logical points.
116#[derive(Clone, Debug, PartialEq)]
117pub struct ClippedShape {
118 /// Clip / scissor rectangle.
119 /// Only show the part of the [`Shape`] that falls within this.
120 pub clip_rect: emath::Rect,
121
122 /// The shape
123 pub shape: Shape,
124}
125
126impl ClippedShape {
127 /// Transform (move/scale) the shape in-place.
128 ///
129 /// If using a [`PaintCallback`], note that only the rect is scaled as opposed
130 /// to other shapes where the stroke is also scaled.
131 pub fn transform(&mut self, transform: emath::TSTransform) {
132 let Self { clip_rect, shape } = self;
133 *clip_rect = transform * *clip_rect;
134 shape.transform(transform);
135 }
136}
137
138/// A [`Mesh`] or [`PaintCallback`] within a clip rectangle.
139///
140/// Everything is using logical points.
141#[derive(Clone, Debug)]
142pub struct ClippedPrimitive {
143 /// Clip / scissor rectangle.
144 /// Only show the part of the [`Mesh`] that falls within this.
145 pub clip_rect: emath::Rect,
146
147 /// What to paint - either a [`Mesh`] or a [`PaintCallback`].
148 pub primitive: Primitive,
149}
150
151/// A rendering primitive - either a [`Mesh`] or a [`PaintCallback`].
152#[derive(Clone, Debug)]
153pub enum Primitive {
154 Mesh(Mesh),
155 Callback(PaintCallback),
156}
157
158// ---------------------------------------------------------------------------
159
160/// Was epaint compiled with the `rayon` feature?
161pub const HAS_RAYON: bool = cfg!(feature = "rayon");