2021-10-10 13:35:13 +00:00
|
|
|
//! A simple 2D graphics library for turning simple 2D shapes and text into textured triangles.
|
|
|
|
//!
|
|
|
|
//! Made for [`egui`](https://github.com/emilk/egui/).
|
|
|
|
//!
|
|
|
|
//! Create some [`Shape`]:s and pass them to [`tessellate_shapes`] to generate [`Mesh`]:es
|
|
|
|
//! that you can then paint using some graphics API of your choice (e.g. OpenGL).
|
2022-06-09 13:27:22 +00:00
|
|
|
//!
|
|
|
|
//! ## Feature flags
|
2022-06-09 15:41:37 +00:00
|
|
|
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
|
2022-06-09 13:27:22 +00:00
|
|
|
//!
|
2020-08-09 15:24:32 +00:00
|
|
|
|
2021-05-09 12:00:53 +00:00
|
|
|
#![allow(clippy::float_cmp)]
|
2021-01-10 14:42:46 +00:00
|
|
|
#![allow(clippy::manual_range_contains)]
|
|
|
|
|
2022-01-31 19:26:31 +00:00
|
|
|
mod bezier;
|
2022-01-15 12:59:52 +00:00
|
|
|
pub mod image;
|
2021-01-25 20:23:24 +00:00
|
|
|
mod mesh;
|
2021-01-10 14:42:46 +00:00
|
|
|
pub mod mutex;
|
2020-12-29 00:13:14 +00:00
|
|
|
mod shadow;
|
2021-01-17 09:52:01 +00:00
|
|
|
mod shape;
|
2021-02-07 09:55:45 +00:00
|
|
|
pub mod shape_transform;
|
2020-10-17 08:57:25 +00:00
|
|
|
pub mod stats;
|
2021-01-10 13:39:03 +00:00
|
|
|
mod stroke;
|
2020-07-23 08:27:21 +00:00
|
|
|
pub mod tessellator;
|
2021-01-10 13:39:03 +00:00
|
|
|
pub mod text;
|
2020-05-19 20:28:57 +00:00
|
|
|
mod texture_atlas;
|
2022-01-15 12:59:52 +00:00
|
|
|
mod texture_handle;
|
|
|
|
pub mod textures;
|
2021-09-25 09:22:34 +00:00
|
|
|
pub mod util;
|
2020-05-19 20:28:57 +00:00
|
|
|
|
|
|
|
pub use {
|
2022-01-31 19:26:31 +00:00
|
|
|
bezier::{CubicBezierShape, QuadraticBezierShape},
|
2022-03-23 15:49:49 +00:00
|
|
|
image::{ColorImage, FontImage, ImageData, ImageDelta},
|
2021-01-25 21:06:06 +00:00
|
|
|
mesh::{Mesh, Mesh16, Vertex},
|
2020-12-29 00:13:14 +00:00
|
|
|
shadow::Shadow,
|
2022-03-22 22:11:27 +00:00
|
|
|
shape::{
|
|
|
|
CircleShape, PaintCallback, PaintCallbackInfo, PathShape, RectShape, Rounding, Shape,
|
|
|
|
TextShape,
|
|
|
|
},
|
2020-10-17 08:57:25 +00:00
|
|
|
stats::PaintStats,
|
2021-01-10 13:39:03 +00:00
|
|
|
stroke::Stroke,
|
2021-10-10 13:35:13 +00:00
|
|
|
tessellator::{tessellate_shapes, TessellationOptions, Tessellator},
|
2022-01-24 13:32:36 +00:00
|
|
|
text::{FontFamily, FontId, Fonts, Galley},
|
2022-01-22 10:23:12 +00:00
|
|
|
texture_atlas::TextureAtlas,
|
2022-01-15 12:59:52 +00:00
|
|
|
texture_handle::TextureHandle,
|
|
|
|
textures::TextureManager,
|
2020-05-19 20:28:57 +00:00
|
|
|
};
|
2020-12-29 00:13:14 +00:00
|
|
|
|
2022-12-06 19:42:25 +00:00
|
|
|
pub use ecolor::{Color32, Hsva, HsvaGamma, Rgba};
|
2021-09-20 19:36:56 +00:00
|
|
|
pub use emath::{pos2, vec2, Pos2, Rect, Vec2};
|
|
|
|
|
2021-01-10 14:42:46 +00:00
|
|
|
pub use ahash;
|
2022-12-06 19:42:25 +00:00
|
|
|
pub use ecolor;
|
2021-01-10 14:42:46 +00:00
|
|
|
pub use emath;
|
|
|
|
|
2022-05-16 14:38:14 +00:00
|
|
|
#[cfg(feature = "color-hex")]
|
2022-12-06 19:42:25 +00:00
|
|
|
pub use ecolor::hex_color;
|
2022-05-15 15:07:30 +00:00
|
|
|
|
2021-01-10 13:39:03 +00:00
|
|
|
/// The UV coordinate of a white region of the texture mesh.
|
2021-01-17 13:48:59 +00:00
|
|
|
/// The default egui texture has the top-left corner pixel fully white.
|
2021-01-10 13:39:03 +00:00
|
|
|
/// You need need use a clamping texture sampler for this to work
|
|
|
|
/// (so it doesn't do bilinear blending with bottom right corner).
|
2021-01-10 14:42:46 +00:00
|
|
|
pub const WHITE_UV: emath::Pos2 = emath::pos2(0.0, 0.0);
|
2021-01-10 13:39:03 +00:00
|
|
|
|
2021-01-25 20:23:24 +00:00
|
|
|
/// What texture to use in a [`Mesh`] mesh.
|
2022-01-15 12:59:52 +00:00
|
|
|
///
|
|
|
|
/// If you don't want to use a texture, use `TextureId::Epaint(0)` and the [`WHITE_UV`] for uv-coord.
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
2021-09-29 06:45:13 +00:00
|
|
|
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
2021-01-10 13:39:03 +00:00
|
|
|
pub enum TextureId {
|
2022-01-15 12:59:52 +00:00
|
|
|
/// Textures allocated using [`TextureManager`].
|
|
|
|
///
|
|
|
|
/// The first texture (`TextureId::Epaint(0)`) is used for the font data.
|
|
|
|
Managed(u64),
|
2021-01-10 13:39:03 +00:00
|
|
|
|
|
|
|
/// Your own texture, defined in any which way you want.
|
2022-01-15 12:59:52 +00:00
|
|
|
/// The backend renderer will presumably use this to look up what texture to use.
|
2021-01-10 13:39:03 +00:00
|
|
|
User(u64),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for TextureId {
|
2022-01-15 12:59:52 +00:00
|
|
|
/// The epaint font texture.
|
2021-01-10 13:39:03 +00:00
|
|
|
fn default() -> Self {
|
2022-01-15 12:59:52 +00:00
|
|
|
Self::Managed(0)
|
2021-01-10 13:39:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-17 00:35:14 +00:00
|
|
|
/// A [`Shape`] within a clip rectangle.
|
|
|
|
///
|
|
|
|
/// Everything is using logical points.
|
2021-10-10 13:35:13 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
2021-01-17 00:35:14 +00:00
|
|
|
pub struct ClippedShape(
|
|
|
|
/// Clip / scissor rectangle.
|
2021-01-17 09:52:01 +00:00
|
|
|
/// Only show the part of the [`Shape`] that falls within this.
|
2021-01-17 00:35:14 +00:00
|
|
|
pub emath::Rect,
|
|
|
|
/// The shape
|
|
|
|
pub Shape,
|
|
|
|
);
|
|
|
|
|
2022-03-14 12:25:11 +00:00
|
|
|
/// A [`Mesh`] or [`PaintCallback`] within a clip rectangle.
|
2021-01-25 20:43:17 +00:00
|
|
|
///
|
|
|
|
/// Everything is using logical points.
|
|
|
|
#[derive(Clone, Debug)]
|
2022-03-14 12:25:11 +00:00
|
|
|
pub struct ClippedPrimitive {
|
2021-01-25 20:43:17 +00:00
|
|
|
/// Clip / scissor rectangle.
|
|
|
|
/// Only show the part of the [`Mesh`] that falls within this.
|
2022-03-14 12:25:11 +00:00
|
|
|
pub clip_rect: emath::Rect,
|
2022-08-02 15:26:33 +00:00
|
|
|
|
2022-03-14 12:25:11 +00:00
|
|
|
/// What to paint - either a [`Mesh`] or a [`PaintCallback`].
|
|
|
|
pub primitive: Primitive,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A rendering primitive - either a [`Mesh`] or a [`PaintCallback`].
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub enum Primitive {
|
|
|
|
Mesh(Mesh),
|
|
|
|
Callback(PaintCallback),
|
|
|
|
}
|
2021-05-17 20:34:29 +00:00
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
2021-10-10 13:35:13 +00:00
|
|
|
/// An assert that is only active when `epaint` is compiled with the `extra_asserts` feature
|
|
|
|
/// or with the `extra_debug_asserts` feature in debug builds.
|
2021-05-17 20:34:29 +00:00
|
|
|
#[macro_export]
|
|
|
|
macro_rules! epaint_assert {
|
2021-10-02 19:08:00 +00:00
|
|
|
($($arg: tt)*) => {
|
2021-05-17 20:34:29 +00:00
|
|
|
if cfg!(any(
|
|
|
|
feature = "extra_asserts",
|
|
|
|
all(feature = "extra_debug_asserts", debug_assertions),
|
|
|
|
)) {
|
|
|
|
assert!($($arg)*);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
New text layout (#682)
This PR introduces a completely rewritten text layout engine which is simpler and more powerful. It allows mixing different text styles (heading, body, etc) and formats (color, underlining, strikethrough, …) in the same layout pass, and baked into the same `Galley`.
This opens up the door to having a syntax-highlighed code editor, or a WYSIWYG markdown editor.
One major change is the color is now baked in at layout time. However, many widgets changes text color on hovered. But we need to do the text layout before we know if it is hovered. Therefor the painter has an option to override the text color of a galley.
## Performance
Text layout alone is about 20% slower, but a lot of that is because more tessellation is done upfront. Text tessellation is now a lot faster, but text layout + tessellation still lands at a net loss of 5-10% in performance. There are however a few tricks to speed it up (like using `smallvec`) which I am saving for later. Text layout is also cached, meaning that in most cases (when all text isn't changing each frame) text tessellation is actually more important (and that's more than 2x faster!).
Sadly, the actual text cache lookup is significantly slower (300ns -> 600ns). That's because the `TextLayoutJob` is a lot bigger (it has more options, like underlining, fonts etc), so it is slower to hash and compare. I have an idea how to speed this up, but I need to do some other work before I can implement that.
All in all, the performance impact on `demo_with_tesselate__realistic` is about 5-6% in the red. Not great; not terrible. The benefits are worth it, but I also think with some work I can get that down significantly, hopefully down to the old levels.
2021-09-03 16:18:00 +00:00
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
pub(crate) fn f32_hash<H: std::hash::Hasher>(state: &mut H, f: f32) {
|
|
|
|
if f == 0.0 {
|
2021-10-20 14:43:40 +00:00
|
|
|
state.write_u8(0);
|
New text layout (#682)
This PR introduces a completely rewritten text layout engine which is simpler and more powerful. It allows mixing different text styles (heading, body, etc) and formats (color, underlining, strikethrough, …) in the same layout pass, and baked into the same `Galley`.
This opens up the door to having a syntax-highlighed code editor, or a WYSIWYG markdown editor.
One major change is the color is now baked in at layout time. However, many widgets changes text color on hovered. But we need to do the text layout before we know if it is hovered. Therefor the painter has an option to override the text color of a galley.
## Performance
Text layout alone is about 20% slower, but a lot of that is because more tessellation is done upfront. Text tessellation is now a lot faster, but text layout + tessellation still lands at a net loss of 5-10% in performance. There are however a few tricks to speed it up (like using `smallvec`) which I am saving for later. Text layout is also cached, meaning that in most cases (when all text isn't changing each frame) text tessellation is actually more important (and that's more than 2x faster!).
Sadly, the actual text cache lookup is significantly slower (300ns -> 600ns). That's because the `TextLayoutJob` is a lot bigger (it has more options, like underlining, fonts etc), so it is slower to hash and compare. I have an idea how to speed this up, but I need to do some other work before I can implement that.
All in all, the performance impact on `demo_with_tesselate__realistic` is about 5-6% in the red. Not great; not terrible. The benefits are worth it, but I also think with some work I can get that down significantly, hopefully down to the old levels.
2021-09-03 16:18:00 +00:00
|
|
|
} else if f.is_nan() {
|
2021-10-20 14:43:40 +00:00
|
|
|
state.write_u8(1);
|
New text layout (#682)
This PR introduces a completely rewritten text layout engine which is simpler and more powerful. It allows mixing different text styles (heading, body, etc) and formats (color, underlining, strikethrough, …) in the same layout pass, and baked into the same `Galley`.
This opens up the door to having a syntax-highlighed code editor, or a WYSIWYG markdown editor.
One major change is the color is now baked in at layout time. However, many widgets changes text color on hovered. But we need to do the text layout before we know if it is hovered. Therefor the painter has an option to override the text color of a galley.
## Performance
Text layout alone is about 20% slower, but a lot of that is because more tessellation is done upfront. Text tessellation is now a lot faster, but text layout + tessellation still lands at a net loss of 5-10% in performance. There are however a few tricks to speed it up (like using `smallvec`) which I am saving for later. Text layout is also cached, meaning that in most cases (when all text isn't changing each frame) text tessellation is actually more important (and that's more than 2x faster!).
Sadly, the actual text cache lookup is significantly slower (300ns -> 600ns). That's because the `TextLayoutJob` is a lot bigger (it has more options, like underlining, fonts etc), so it is slower to hash and compare. I have an idea how to speed this up, but I need to do some other work before I can implement that.
All in all, the performance impact on `demo_with_tesselate__realistic` is about 5-6% in the red. Not great; not terrible. The benefits are worth it, but I also think with some work I can get that down significantly, hopefully down to the old levels.
2021-09-03 16:18:00 +00:00
|
|
|
} else {
|
|
|
|
use std::hash::Hash;
|
2021-10-20 14:43:40 +00:00
|
|
|
f.to_bits().hash(state);
|
New text layout (#682)
This PR introduces a completely rewritten text layout engine which is simpler and more powerful. It allows mixing different text styles (heading, body, etc) and formats (color, underlining, strikethrough, …) in the same layout pass, and baked into the same `Galley`.
This opens up the door to having a syntax-highlighed code editor, or a WYSIWYG markdown editor.
One major change is the color is now baked in at layout time. However, many widgets changes text color on hovered. But we need to do the text layout before we know if it is hovered. Therefor the painter has an option to override the text color of a galley.
## Performance
Text layout alone is about 20% slower, but a lot of that is because more tessellation is done upfront. Text tessellation is now a lot faster, but text layout + tessellation still lands at a net loss of 5-10% in performance. There are however a few tricks to speed it up (like using `smallvec`) which I am saving for later. Text layout is also cached, meaning that in most cases (when all text isn't changing each frame) text tessellation is actually more important (and that's more than 2x faster!).
Sadly, the actual text cache lookup is significantly slower (300ns -> 600ns). That's because the `TextLayoutJob` is a lot bigger (it has more options, like underlining, fonts etc), so it is slower to hash and compare. I have an idea how to speed this up, but I need to do some other work before I can implement that.
All in all, the performance impact on `demo_with_tesselate__realistic` is about 5-6% in the red. Not great; not terrible. The benefits are worth it, but I also think with some work I can get that down significantly, hopefully down to the old levels.
2021-09-03 16:18:00 +00:00
|
|
|
}
|
|
|
|
}
|
2021-12-11 12:52:23 +00:00
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
pub(crate) fn f64_hash<H: std::hash::Hasher>(state: &mut H, f: f64) {
|
|
|
|
if f == 0.0 {
|
|
|
|
state.write_u8(0);
|
|
|
|
} else if f.is_nan() {
|
|
|
|
state.write_u8(1);
|
|
|
|
} else {
|
|
|
|
use std::hash::Hash;
|
|
|
|
f.to_bits().hash(state);
|
|
|
|
}
|
|
|
|
}
|