mirror of
https://github.com/emilk/egui.git
synced 2026-08-30 13:20:05 -04:00
Improve docs, especially of epaint, and add epaint/CHANGELOG.md
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
//! 2D graphics/rendering. Fonts, textures, color, geometry, tessellation etc.
|
||||
//! 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).
|
||||
|
||||
// Forbid warnings in release builds:
|
||||
#![cfg_attr(not(debug_assertions), deny(warnings))]
|
||||
@@ -91,8 +96,8 @@ pub use {
|
||||
shape::{CircleShape, PathShape, RectShape, Shape, TextShape},
|
||||
stats::PaintStats,
|
||||
stroke::Stroke,
|
||||
tessellator::{TessellationOptions, Tessellator},
|
||||
text::{Galley, TextStyle},
|
||||
tessellator::{tessellate_shapes, TessellationOptions, Tessellator},
|
||||
text::{Fonts, Galley, TextStyle},
|
||||
texture_atlas::{Texture, TextureAtlas},
|
||||
};
|
||||
|
||||
@@ -129,7 +134,7 @@ impl Default for TextureId {
|
||||
/// A [`Shape`] within a clip rectangle.
|
||||
///
|
||||
/// Everything is using logical points.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct ClippedShape(
|
||||
/// Clip / scissor rectangle.
|
||||
/// Only show the part of the [`Shape`] that falls within this.
|
||||
@@ -153,8 +158,8 @@ pub struct ClippedMesh(
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// An assert that is only active when `egui` is compiled with the `egui_assert` feature
|
||||
/// or with the `debug_egui_assert` feature in debug builds.
|
||||
/// 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.
|
||||
#[macro_export]
|
||||
macro_rules! epaint_assert {
|
||||
($($arg: tt)*) => {
|
||||
|
||||
@@ -123,6 +123,57 @@ impl Shape {
|
||||
pub fn galley(pos: Pos2, galley: std::sync::Arc<Galley>) -> Self {
|
||||
TextShape::new(pos, galley).into()
|
||||
}
|
||||
|
||||
pub fn mesh(mesh: Mesh) -> Self {
|
||||
crate::epaint_assert!(mesh.is_valid());
|
||||
Self::Mesh(mesh)
|
||||
}
|
||||
}
|
||||
|
||||
/// ## Inspection and transforms
|
||||
impl Shape {
|
||||
#[inline(always)]
|
||||
pub fn texture_id(&self) -> super::TextureId {
|
||||
if let Shape::Mesh(mesh) = self {
|
||||
mesh.texture_id
|
||||
} else {
|
||||
super::TextureId::Egui
|
||||
}
|
||||
}
|
||||
|
||||
/// Move the shape by this many points, in-place.
|
||||
pub fn translate(&mut self, delta: Vec2) {
|
||||
match self {
|
||||
Shape::Noop => {}
|
||||
Shape::Vec(shapes) => {
|
||||
for shape in shapes {
|
||||
shape.translate(delta);
|
||||
}
|
||||
}
|
||||
Shape::Circle(circle_shape) => {
|
||||
circle_shape.center += delta;
|
||||
}
|
||||
Shape::LineSegment { points, .. } => {
|
||||
for p in points {
|
||||
*p += delta;
|
||||
}
|
||||
}
|
||||
Shape::Path(path_shape) => {
|
||||
for p in &mut path_shape.points {
|
||||
*p += delta;
|
||||
}
|
||||
}
|
||||
Shape::Rect(rect_shape) => {
|
||||
rect_shape.rect = rect_shape.rect.translate(delta);
|
||||
}
|
||||
Shape::Text(text_shape) => {
|
||||
text_shape.pos += delta;
|
||||
}
|
||||
Shape::Mesh(mesh) => {
|
||||
mesh.translate(delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -398,54 +449,3 @@ fn dashes_from_line(
|
||||
position_on_segment -= segment_length;
|
||||
});
|
||||
}
|
||||
|
||||
/// ## Operations
|
||||
impl Shape {
|
||||
pub fn mesh(mesh: Mesh) -> Self {
|
||||
crate::epaint_assert!(mesh.is_valid());
|
||||
Self::Mesh(mesh)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn texture_id(&self) -> super::TextureId {
|
||||
if let Shape::Mesh(mesh) = self {
|
||||
mesh.texture_id
|
||||
} else {
|
||||
super::TextureId::Egui
|
||||
}
|
||||
}
|
||||
|
||||
/// Translate location by this much, in-place
|
||||
pub fn translate(&mut self, delta: Vec2) {
|
||||
match self {
|
||||
Shape::Noop => {}
|
||||
Shape::Vec(shapes) => {
|
||||
for shape in shapes {
|
||||
shape.translate(delta);
|
||||
}
|
||||
}
|
||||
Shape::Circle(circle_shape) => {
|
||||
circle_shape.center += delta;
|
||||
}
|
||||
Shape::LineSegment { points, .. } => {
|
||||
for p in points {
|
||||
*p += delta;
|
||||
}
|
||||
}
|
||||
Shape::Path(path_shape) => {
|
||||
for p in &mut path_shape.points {
|
||||
*p += delta;
|
||||
}
|
||||
}
|
||||
Shape::Rect(rect_shape) => {
|
||||
rect_shape.rect = rect_shape.rect.translate(delta);
|
||||
}
|
||||
Shape::Text(text_shape) => {
|
||||
text_shape.pos += delta;
|
||||
}
|
||||
Shape::Mesh(mesh) => {
|
||||
mesh.translate(delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,21 +257,30 @@ pub enum PathType {
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
pub struct TessellationOptions {
|
||||
/// Size of a point in pixels, e.g. 2.0. Used to snap text to pixel boundaries.
|
||||
/// Size of a point in pixels (DPI scaling), e.g. 2.0. Used to snap text to pixel boundaries.
|
||||
pub pixels_per_point: f32,
|
||||
/// Size of a pixel in points, e.g. 0.5, or larger if you want more blurry edges.
|
||||
|
||||
/// The size of a pixel (in points), used for anti-aliasing (smoothing of edges).
|
||||
/// This is normally the inverse of [`Self::pixels_per_point`],
|
||||
/// but you can make it larger if you want more blurry edges.
|
||||
pub aa_size: f32,
|
||||
|
||||
/// Anti-aliasing makes shapes appear smoother, but requires more triangles and is therefore slower.
|
||||
/// This setting does not affect text.
|
||||
/// Default: `true`.
|
||||
pub anti_alias: bool,
|
||||
/// If `true` (default) cull certain primitives before tessellating them
|
||||
|
||||
/// If `true` (default) cull certain primitives before tessellating them.
|
||||
/// This likely makes
|
||||
pub coarse_tessellation_culling: bool,
|
||||
/// Output the clip rectangles to be painted?
|
||||
|
||||
/// Output the clip rectangles to be painted.
|
||||
pub debug_paint_clip_rects: bool,
|
||||
/// Output the text-containing rectangles
|
||||
|
||||
/// Output the text-containing rectangles.
|
||||
pub debug_paint_text_rects: bool,
|
||||
/// If true, no clipping will be done
|
||||
|
||||
/// If true, no clipping will be done.
|
||||
pub debug_ignore_clip_rects: bool,
|
||||
}
|
||||
|
||||
@@ -503,7 +512,11 @@ fn mul_color(color: Color32, factor: f32) -> Color32 {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// Converts [`Shape`]s into [`Mesh`].
|
||||
/// Converts [`Shape`]s into triangles ([`Mesh`]).
|
||||
///
|
||||
/// For performance reasons it is smart to reuse the same `Tessellator`.
|
||||
///
|
||||
/// Se also [`tessellate_shapes`], a convenient wrapper around [`Tessellator`].
|
||||
pub struct Tessellator {
|
||||
options: TessellationOptions,
|
||||
/// Only used for culling
|
||||
@@ -513,6 +526,7 @@ pub struct Tessellator {
|
||||
}
|
||||
|
||||
impl Tessellator {
|
||||
/// Create a new [`Tessellator`].
|
||||
pub fn from_options(options: TessellationOptions) -> Self {
|
||||
Self {
|
||||
options,
|
||||
@@ -524,12 +538,9 @@ impl Tessellator {
|
||||
|
||||
/// Tessellate a single [`Shape`] into a [`Mesh`].
|
||||
///
|
||||
/// * `shape`: the shape to tessellate
|
||||
/// * `options`: tessellation quality
|
||||
/// * `tex_size`: size of the font texture (required to normalize glyph uv rectangles)
|
||||
/// * `out`: where the triangles are put
|
||||
/// * `scratchpad_path`: if you plan to run `tessellate_shape`
|
||||
/// many times, pass it a reference to the same `Path` to avoid excessive allocations.
|
||||
/// * `tex_size`: size of the font texture (required to normalize glyph uv rectangles).
|
||||
/// * `shape`: the shape to tessellate.
|
||||
/// * `out`: triangles are appended to this.
|
||||
pub fn tessellate_shape(&mut self, tex_size: [usize; 2], shape: Shape, out: &mut Mesh) {
|
||||
let clip_rect = self.clip_rect;
|
||||
let options = &self.options;
|
||||
@@ -776,13 +787,15 @@ impl Tessellator {
|
||||
|
||||
/// Turns [`Shape`]:s into sets of triangles.
|
||||
///
|
||||
/// The given shapes will be painted back-to-front (painters algorithm).
|
||||
/// The given shapes will tessellated in the same order as they are given.
|
||||
/// They will be batched together by clip rectangle.
|
||||
///
|
||||
/// * `shapes`: the shape to tessellate
|
||||
/// * `shapes`: what to tessellate
|
||||
/// * `options`: tessellation quality
|
||||
/// * `tex_size`: size of the font texture (required to normalize glyph uv rectangles)
|
||||
///
|
||||
/// The implementation uses a [`Tessellator`].
|
||||
///
|
||||
/// ## Returns
|
||||
/// A list of clip rectangles with matching [`Mesh`].
|
||||
pub fn tessellate_shapes(
|
||||
|
||||
@@ -201,6 +201,8 @@ impl Default for FontDefinitions {
|
||||
}
|
||||
|
||||
/// The collection of fonts used by `epaint`.
|
||||
///
|
||||
/// Required in order to paint text.
|
||||
pub struct Fonts {
|
||||
pixels_per_point: f32,
|
||||
definitions: FontDefinitions,
|
||||
@@ -214,6 +216,8 @@ pub struct Fonts {
|
||||
}
|
||||
|
||||
impl Fonts {
|
||||
/// Create a new [`Fonts`] for text layout.
|
||||
/// This call is expensive, so only create on [`Fonts`] and then reuse it.
|
||||
pub fn new(pixels_per_point: f32, definitions: FontDefinitions) -> Self {
|
||||
assert!(
|
||||
0.0 < pixels_per_point && pixels_per_point < 100.0,
|
||||
|
||||
@@ -11,12 +11,37 @@ use emath::*;
|
||||
///
|
||||
/// This supports mixing different fonts, color and formats (underline etc).
|
||||
///
|
||||
/// Pass this to [`Fonts::layout_job]` or [`crate::text::layout`].
|
||||
/// Pass this to [`crate::Fonts::layout_job`] or [`crate::text::layout`].
|
||||
///
|
||||
/// ## Example:
|
||||
/// ```
|
||||
/// use epaint::{Color32, text::{LayoutJob, TextFormat}, TextStyle};
|
||||
///
|
||||
/// let mut job = LayoutJob::default();
|
||||
/// job.append(
|
||||
/// "Hello ",
|
||||
/// 0.0,
|
||||
/// TextFormat {
|
||||
/// style: TextStyle::Body,
|
||||
/// color: Color32::WHITE,
|
||||
/// ..Default::default()
|
||||
/// },
|
||||
/// );
|
||||
/// job.append(
|
||||
/// "World!",
|
||||
/// 0.0,
|
||||
/// TextFormat {
|
||||
/// style: TextStyle::Monospace,
|
||||
/// color: Color32::BLACK,
|
||||
/// ..Default::default()
|
||||
/// },
|
||||
/// );
|
||||
/// ```
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub struct LayoutJob {
|
||||
/// The complete text of this job, referenced by `LayoutSection`.
|
||||
pub text: String, // TODO: Cow<'static, str>
|
||||
pub text: String,
|
||||
|
||||
/// The different section, which can have different fonts, colors, etc.
|
||||
pub sections: Vec<LayoutSection>,
|
||||
@@ -206,6 +231,9 @@ impl TextFormat {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// Text that has been layed out, ready for painting.
|
||||
///
|
||||
/// You can create a [`Galley`] using [`crate::Fonts::layout_job`];
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Galley {
|
||||
/// The job that this galley is the result of.
|
||||
|
||||
Reference in New Issue
Block a user