Break out mod paint into new crate epaint
This commit is contained in:
parent
c0041d032a
commit
26d576f510
42 changed files with 343 additions and 248 deletions
|
@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
* Tweak size and alignment of some emojis to match other text.
|
* Tweak size and alignment of some emojis to match other text.
|
||||||
* Rename `PaintCmd` to `Shape`.
|
* Rename `PaintCmd` to `Shape`.
|
||||||
* Rename feature "serde" to "persistence".
|
* Rename feature "serde" to "persistence".
|
||||||
|
* Break out the modules `math` and `paint` into separate crates `emath` and `epaint`.
|
||||||
|
|
||||||
### Fixed 🐛
|
### Fixed 🐛
|
||||||
|
|
||||||
|
|
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -640,11 +640,7 @@ dependencies = [
|
||||||
name = "egui"
|
name = "egui"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"epaint",
|
||||||
"atomic_refcell",
|
|
||||||
"emath",
|
|
||||||
"parking_lot",
|
|
||||||
"rusttype",
|
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -711,6 +707,18 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "epaint"
|
||||||
|
version = "0.7.0"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
"atomic_refcell",
|
||||||
|
"emath",
|
||||||
|
"parking_lot",
|
||||||
|
"rusttype",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "epi"
|
name = "epi"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
|
|
|
@ -6,6 +6,7 @@ members = [
|
||||||
"egui_web",
|
"egui_web",
|
||||||
"egui",
|
"egui",
|
||||||
"emath",
|
"emath",
|
||||||
|
"epaint",
|
||||||
"epi",
|
"epi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
2
check.sh
2
check.sh
|
@ -6,7 +6,7 @@ cargo check --workspace --all-targets --all-features
|
||||||
cargo check -p egui_demo_app --lib --target wasm32-unknown-unknown
|
cargo check -p egui_demo_app --lib --target wasm32-unknown-unknown
|
||||||
cargo check -p egui_demo_app --lib --target wasm32-unknown-unknown --all-features
|
cargo check -p egui_demo_app --lib --target wasm32-unknown-unknown --all-features
|
||||||
cargo fmt --all -- --check
|
cargo fmt --all -- --check
|
||||||
CARGO_INCREMENTAL=0 cargo clippy --workspace --all-targets --all-features -- -D warnings -W clippy::all #-W clippy::pedantic -W clippy::restriction -W clippy::nursery
|
CARGO_INCREMENTAL=0 cargo clippy --workspace --all-targets --all-features -- -D warnings -W clippy::all
|
||||||
cargo test --workspace --all-targets --all-features
|
cargo test --workspace --all-targets --all-features
|
||||||
cargo test --workspace --doc
|
cargo test --workspace --doc
|
||||||
|
|
||||||
|
|
|
@ -13,27 +13,22 @@ keywords = ["gui", "imgui", "immediate", "portable", "gamedev"]
|
||||||
include = [
|
include = [
|
||||||
"**/*.rs",
|
"**/*.rs",
|
||||||
"Cargo.toml",
|
"Cargo.toml",
|
||||||
"fonts/*.ttf",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
emath = { path = "../emath" }
|
epaint = { path = "../epaint", default-features = false }
|
||||||
|
|
||||||
ahash = { version = "0.6", features = ["std"], default-features = false }
|
|
||||||
atomic_refcell = { version = "0.1", optional = true } # Used instead of parking_lot when you are always using Egui in a single thread. About as fast as parking_lot. Panics on multi-threaded use of egui::Context.
|
|
||||||
parking_lot = { version = "0.11", optional = true } # Using parking_lot over std::sync::Mutex gives 50% speedups in some real-world scenarios
|
|
||||||
rusttype = "0.9"
|
|
||||||
serde = { version = "1", features = ["derive", "rc"], optional = true }
|
serde = { version = "1", features = ["derive", "rc"], optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["atomic_refcell", "default_fonts"]
|
default = ["default_fonts", "single_threaded"]
|
||||||
persistence = ["serde", "emath/serde"]
|
persistence = ["serde", "epaint/persistence"]
|
||||||
|
|
||||||
# If set, egui will use `include_bytes!` to bundle some fonts.
|
# If set, egui will use `include_bytes!` to bundle some fonts.
|
||||||
# If you plan on specifying your own fonts you may disable this feature.
|
# If you plan on specifying your own fonts you may disable this feature.
|
||||||
default_fonts = []
|
default_fonts = ["epaint/default_fonts"]
|
||||||
|
|
||||||
# Only needed if you plan to use the same egui::Context from multiple threads.
|
# Only needed if you plan to use the same egui::Context from multiple threads.
|
||||||
multi_threaded = ["parking_lot"]
|
single_threaded = ["epaint/single_threaded"]
|
||||||
|
multi_threaded = ["epaint/multi_threaded"]
|
||||||
|
|
|
@ -871,24 +871,3 @@ impl Context {
|
||||||
self.set_style(style);
|
self.set_style(style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl paint::TessellationOptions {
|
|
||||||
pub fn ui(&mut self, ui: &mut Ui) {
|
|
||||||
let Self {
|
|
||||||
aa_size: _,
|
|
||||||
anti_alias,
|
|
||||||
coarse_tessellation_culling,
|
|
||||||
debug_paint_clip_rects,
|
|
||||||
debug_paint_text_rects,
|
|
||||||
debug_ignore_clip_rects,
|
|
||||||
} = self;
|
|
||||||
ui.checkbox(anti_alias, "Antialias");
|
|
||||||
ui.checkbox(
|
|
||||||
coarse_tessellation_culling,
|
|
||||||
"Do coarse culling in the tessellator",
|
|
||||||
);
|
|
||||||
ui.checkbox(debug_ignore_clip_rects, "Ignore clip rectangles (debug)");
|
|
||||||
ui.checkbox(debug_paint_clip_rects, "Paint clip rectangles (debug)");
|
|
||||||
ui.checkbox(debug_paint_text_rects, "Paint text bounds (debug)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,69 +1,145 @@
|
||||||
//! uis for egui types.
|
//! uis for egui types.
|
||||||
use crate::{
|
use crate::*;
|
||||||
paint::{self, Shape, Texture, Triangles},
|
|
||||||
*,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl Texture {
|
impl Widget for &epaint::Texture {
|
||||||
pub fn ui(&self, ui: &mut Ui) {
|
fn ui(self, ui: &mut Ui) -> Response {
|
||||||
// Show font texture in demo Ui
|
use epaint::Triangles;
|
||||||
ui.label(format!(
|
|
||||||
"Texture size: {} x {} (hover to zoom)",
|
|
||||||
self.width, self.height
|
|
||||||
));
|
|
||||||
if self.width <= 1 || self.height <= 1 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let mut size = vec2(self.width as f32, self.height as f32);
|
|
||||||
if size.x > ui.available_width() {
|
|
||||||
size *= ui.available_width() / size.x;
|
|
||||||
}
|
|
||||||
let (rect, response) = ui.allocate_at_least(size, Sense::hover());
|
|
||||||
let mut triangles = Triangles::default();
|
|
||||||
triangles.add_rect_with_uv(
|
|
||||||
rect,
|
|
||||||
[pos2(0.0, 0.0), pos2(1.0, 1.0)].into(),
|
|
||||||
Color32::WHITE,
|
|
||||||
);
|
|
||||||
ui.painter().add(Shape::triangles(triangles));
|
|
||||||
|
|
||||||
let (tex_w, tex_h) = (self.width as f32, self.height as f32);
|
ui.vertical(|ui| {
|
||||||
|
// Show font texture in demo Ui
|
||||||
response.on_hover_ui(|ui| {
|
ui.label(format!(
|
||||||
let pos = ui
|
"Texture size: {} x {} (hover to zoom)",
|
||||||
.input()
|
self.width, self.height
|
||||||
.mouse
|
));
|
||||||
.pos
|
if self.width <= 1 || self.height <= 1 {
|
||||||
.unwrap_or_else(|| ui.min_rect().left_top());
|
return;
|
||||||
let (_id, zoom_rect) = ui.allocate_space(vec2(128.0, 128.0));
|
}
|
||||||
let u = remap_clamp(pos.x, rect.x_range(), 0.0..=tex_w);
|
let mut size = vec2(self.width as f32, self.height as f32);
|
||||||
let v = remap_clamp(pos.y, rect.y_range(), 0.0..=tex_h);
|
if size.x > ui.available_width() {
|
||||||
|
size *= ui.available_width() / size.x;
|
||||||
let texel_radius = 32.0;
|
}
|
||||||
let u = u.at_least(texel_radius).at_most(tex_w - texel_radius);
|
let (rect, response) = ui.allocate_at_least(size, Sense::hover());
|
||||||
let v = v.at_least(texel_radius).at_most(tex_h - texel_radius);
|
|
||||||
|
|
||||||
let uv_rect = Rect::from_min_max(
|
|
||||||
pos2((u - texel_radius) / tex_w, (v - texel_radius) / tex_h),
|
|
||||||
pos2((u + texel_radius) / tex_w, (v + texel_radius) / tex_h),
|
|
||||||
);
|
|
||||||
let mut triangles = Triangles::default();
|
let mut triangles = Triangles::default();
|
||||||
triangles.add_rect_with_uv(zoom_rect, uv_rect, Color32::WHITE);
|
triangles.add_rect_with_uv(
|
||||||
|
rect,
|
||||||
|
[pos2(0.0, 0.0), pos2(1.0, 1.0)].into(),
|
||||||
|
Color32::WHITE,
|
||||||
|
);
|
||||||
ui.painter().add(Shape::triangles(triangles));
|
ui.painter().add(Shape::triangles(triangles));
|
||||||
});
|
|
||||||
|
let (tex_w, tex_h) = (self.width as f32, self.height as f32);
|
||||||
|
|
||||||
|
response.on_hover_ui(|ui| {
|
||||||
|
let pos = ui
|
||||||
|
.input()
|
||||||
|
.mouse
|
||||||
|
.pos
|
||||||
|
.unwrap_or_else(|| ui.min_rect().left_top());
|
||||||
|
let (_id, zoom_rect) = ui.allocate_space(vec2(128.0, 128.0));
|
||||||
|
let u = remap_clamp(pos.x, rect.x_range(), 0.0..=tex_w);
|
||||||
|
let v = remap_clamp(pos.y, rect.y_range(), 0.0..=tex_h);
|
||||||
|
|
||||||
|
let texel_radius = 32.0;
|
||||||
|
let u = u.at_least(texel_radius).at_most(tex_w - texel_radius);
|
||||||
|
let v = v.at_least(texel_radius).at_most(tex_h - texel_radius);
|
||||||
|
|
||||||
|
let uv_rect = Rect::from_min_max(
|
||||||
|
pos2((u - texel_radius) / tex_w, (v - texel_radius) / tex_h),
|
||||||
|
pos2((u + texel_radius) / tex_w, (v + texel_radius) / tex_h),
|
||||||
|
);
|
||||||
|
let mut triangles = Triangles::default();
|
||||||
|
triangles.add_rect_with_uv(zoom_rect, uv_rect, Color32::WHITE);
|
||||||
|
ui.painter().add(Shape::triangles(triangles));
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl paint::text::FontDefinitions {
|
impl Widget for &mut epaint::text::FontDefinitions {
|
||||||
pub fn ui(&mut self, ui: &mut Ui) {
|
fn ui(self, ui: &mut Ui) -> Response {
|
||||||
for (text_style, (_family, size)) in self.family_and_size.iter_mut() {
|
ui.vertical(|ui| {
|
||||||
// TODO: radio button for family
|
for (text_style, (_family, size)) in self.family_and_size.iter_mut() {
|
||||||
ui.add(
|
// TODO: radio button for family
|
||||||
Slider::f32(size, 4.0..=40.0)
|
ui.add(
|
||||||
.max_decimals(0)
|
Slider::f32(size, 4.0..=40.0)
|
||||||
.text(format!("{:?}", text_style)),
|
.max_decimals(0)
|
||||||
);
|
.text(format!("{:?}", text_style)),
|
||||||
}
|
);
|
||||||
crate::reset_button(ui, self);
|
}
|
||||||
|
crate::reset_button(ui, self);
|
||||||
|
})
|
||||||
|
.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Widget for &epaint::stats::PaintStats {
|
||||||
|
fn ui(self, ui: &mut Ui) -> Response {
|
||||||
|
ui.vertical(|ui| {
|
||||||
|
ui.label(
|
||||||
|
"Egui generates intermediate level shapes like circles and text. \
|
||||||
|
These are later tessellated into triangles.",
|
||||||
|
);
|
||||||
|
ui.advance_cursor(10.0);
|
||||||
|
|
||||||
|
ui.style_mut().body_text_style = TextStyle::Monospace;
|
||||||
|
|
||||||
|
let epaint::stats::PaintStats {
|
||||||
|
shapes,
|
||||||
|
shape_text,
|
||||||
|
shape_path,
|
||||||
|
shape_mesh,
|
||||||
|
shape_vec,
|
||||||
|
jobs,
|
||||||
|
vertices,
|
||||||
|
indices,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
ui.label("Intermediate:");
|
||||||
|
label(ui, shapes, "shapes").on_hover_text("Boxes, circles, etc");
|
||||||
|
label(ui, shape_text, "text");
|
||||||
|
label(ui, shape_path, "paths");
|
||||||
|
label(ui, shape_mesh, "meshes");
|
||||||
|
label(ui, shape_vec, "nested");
|
||||||
|
ui.advance_cursor(10.0);
|
||||||
|
|
||||||
|
ui.label("Tessellated:");
|
||||||
|
label(ui, jobs, "jobs").on_hover_text("Number of separate clip rectangles");
|
||||||
|
label(ui, vertices, "vertices");
|
||||||
|
label(ui, indices, "indices").on_hover_text("Three 32-bit indices per triangles");
|
||||||
|
ui.advance_cursor(10.0);
|
||||||
|
|
||||||
|
// ui.label("Total:");
|
||||||
|
// ui.label(self.total().format(""));
|
||||||
|
})
|
||||||
|
.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn label(ui: &mut Ui, alloc_info: &epaint::stats::AllocInfo, what: &str) -> Response {
|
||||||
|
ui.add(Label::new(alloc_info.format(what)).multiline(false))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Widget for &mut epaint::TessellationOptions {
|
||||||
|
fn ui(self, ui: &mut Ui) -> Response {
|
||||||
|
ui.vertical(|ui| {
|
||||||
|
let epaint::TessellationOptions {
|
||||||
|
aa_size: _,
|
||||||
|
anti_alias,
|
||||||
|
coarse_tessellation_culling,
|
||||||
|
debug_paint_clip_rects,
|
||||||
|
debug_paint_text_rects,
|
||||||
|
debug_ignore_clip_rects,
|
||||||
|
} = self;
|
||||||
|
ui.checkbox(anti_alias, "Antialias");
|
||||||
|
ui.checkbox(
|
||||||
|
coarse_tessellation_culling,
|
||||||
|
"Do coarse culling in the tessellator",
|
||||||
|
);
|
||||||
|
ui.checkbox(debug_ignore_clip_rects, "Ignore clip rectangles (debug)");
|
||||||
|
ui.checkbox(debug_paint_clip_rects, "Paint clip rectangles (debug)");
|
||||||
|
ui.checkbox(debug_paint_text_rects, "Paint text bounds (debug)");
|
||||||
|
})
|
||||||
|
.1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use ahash::AHashMap;
|
use epaint::ahash::AHashMap;
|
||||||
|
|
||||||
use crate::{math::Rect, paint::Shape, Id, *};
|
use crate::{math::Rect, paint::Shape, Id, *};
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,6 @@ mod layers;
|
||||||
mod layout;
|
mod layout;
|
||||||
mod memory;
|
mod memory;
|
||||||
pub mod menu;
|
pub mod menu;
|
||||||
pub mod paint;
|
|
||||||
mod painter;
|
mod painter;
|
||||||
pub mod style;
|
pub mod style;
|
||||||
mod types;
|
mod types;
|
||||||
|
@ -97,6 +96,17 @@ pub mod util;
|
||||||
pub mod widgets;
|
pub mod widgets;
|
||||||
|
|
||||||
pub use emath as math;
|
pub use emath as math;
|
||||||
|
pub use epaint as paint;
|
||||||
|
pub use epaint::emath;
|
||||||
|
|
||||||
|
pub use emath::{
|
||||||
|
clamp, lerp, pos2, remap, remap_clamp, vec2, Align, Align2, NumExt, Pos2, Rect, Vec2,
|
||||||
|
};
|
||||||
|
pub use epaint::{
|
||||||
|
color, mutex,
|
||||||
|
text::{FontDefinitions, FontFamily, TextStyle},
|
||||||
|
Color32, PaintJobs, Rgba, Shape, Stroke, Texture, TextureId,
|
||||||
|
};
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
containers::*,
|
containers::*,
|
||||||
|
@ -105,18 +115,11 @@ pub use {
|
||||||
input::*,
|
input::*,
|
||||||
layers::*,
|
layers::*,
|
||||||
layout::*,
|
layout::*,
|
||||||
math::{clamp, lerp, pos2, remap, remap_clamp, vec2, Align, Align2, NumExt, Pos2, Rect, Vec2},
|
|
||||||
memory::Memory,
|
memory::Memory,
|
||||||
paint::{
|
|
||||||
color,
|
|
||||||
text::{FontDefinitions, FontFamily, TextStyle},
|
|
||||||
Color32, PaintJobs, Rgba, Shape, Stroke, Texture, TextureId,
|
|
||||||
},
|
|
||||||
painter::Painter,
|
painter::Painter,
|
||||||
style::Style,
|
style::Style,
|
||||||
types::*,
|
types::*,
|
||||||
ui::Ui,
|
ui::Ui,
|
||||||
util::mutex,
|
|
||||||
widgets::*,
|
widgets::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -178,7 +178,7 @@ impl Memory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn end_frame(&mut self, used_ids: &ahash::AHashMap<Id, Pos2>) {
|
pub(crate) fn end_frame(&mut self, used_ids: &epaint::ahash::AHashMap<Id, Pos2>) {
|
||||||
self.areas.end_frame();
|
self.areas.end_frame();
|
||||||
|
|
||||||
if let Some(kb_focus_id) = self.interaction.kb_focus_id {
|
if let Some(kb_focus_id) = self.interaction.kb_focus_id {
|
||||||
|
|
|
@ -448,7 +448,7 @@ impl Selection {
|
||||||
let Self { bg_fill, stroke } = self;
|
let Self { bg_fill, stroke } = self;
|
||||||
|
|
||||||
ui_color(ui, bg_fill, "bg_fill");
|
ui_color(ui, bg_fill, "bg_fill");
|
||||||
stroke.ui(ui, "stroke");
|
stroke_ui(ui, stroke, "stroke");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,10 +463,10 @@ impl WidgetVisuals {
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
ui_color(ui, bg_fill, "bg_fill");
|
ui_color(ui, bg_fill, "bg_fill");
|
||||||
bg_stroke.ui(ui, "bg_stroke");
|
stroke_ui(ui, bg_stroke, "bg_stroke");
|
||||||
ui.add(Slider::f32(corner_radius, 0.0..=10.0).text("corner_radius"));
|
ui.add(Slider::f32(corner_radius, 0.0..=10.0).text("corner_radius"));
|
||||||
ui_color(ui, fg_fill, "fg_fill");
|
ui_color(ui, fg_fill, "fg_fill");
|
||||||
fg_stroke.ui(ui, "fg_stroke (text)");
|
stroke_ui(ui, fg_stroke, "fg_stroke (text)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,7 +495,7 @@ impl Visuals {
|
||||||
ui_color(ui, dark_bg_color, "dark_bg_color");
|
ui_color(ui, dark_bg_color, "dark_bg_color");
|
||||||
ui_color(ui, hyperlink_color, "hyperlink_color");
|
ui_color(ui, hyperlink_color, "hyperlink_color");
|
||||||
ui.add(Slider::f32(window_corner_radius, 0.0..=20.0).text("window_corner_radius"));
|
ui.add(Slider::f32(window_corner_radius, 0.0..=20.0).text("window_corner_radius"));
|
||||||
window_shadow.ui(ui, "Window shadow:");
|
shadow_ui(ui, window_shadow, "Window shadow:");
|
||||||
ui.add(Slider::f32(resize_corner_size, 0.0..=20.0).text("resize_corner_size"));
|
ui.add(Slider::f32(resize_corner_size, 0.0..=20.0).text("resize_corner_size"));
|
||||||
ui.add(Slider::f32(text_cursor_width, 0.0..=2.0).text("text_cursor_width"));
|
ui.add(Slider::f32(text_cursor_width, 0.0..=2.0).text("text_cursor_width"));
|
||||||
ui.add(Slider::f32(clip_rect_margin, 0.0..=20.0).text("clip_rect_margin"));
|
ui.add(Slider::f32(clip_rect_margin, 0.0..=20.0).text("clip_rect_margin"));
|
||||||
|
@ -513,36 +513,6 @@ impl Visuals {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stroke {
|
|
||||||
pub fn ui(&mut self, ui: &mut crate::Ui, text: &str) {
|
|
||||||
let Self { width, color } = self;
|
|
||||||
ui.horizontal(|ui| {
|
|
||||||
ui.add(DragValue::f32(width).speed(0.1).range(0.0..=5.0))
|
|
||||||
.on_hover_text("Width");
|
|
||||||
ui.color_edit_button_srgba(color);
|
|
||||||
ui.label(text);
|
|
||||||
|
|
||||||
// stroke preview:
|
|
||||||
let (_id, stroke_rect) = ui.allocate_space(ui.style().spacing.interact_size);
|
|
||||||
let left = stroke_rect.left_center();
|
|
||||||
let right = stroke_rect.right_center();
|
|
||||||
ui.painter().line_segment([left, right], (*width, *color));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Shadow {
|
|
||||||
pub fn ui(&mut self, ui: &mut crate::Ui, text: &str) {
|
|
||||||
let Self { extrusion, color } = self;
|
|
||||||
ui.horizontal(|ui| {
|
|
||||||
ui.label(text);
|
|
||||||
ui.add(DragValue::f32(extrusion).speed(1.0).range(0.0..=100.0))
|
|
||||||
.on_hover_text("Extrusion");
|
|
||||||
ui.color_edit_button_srgba(color);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: improve and standardize ui_slider_vec2
|
// TODO: improve and standardize ui_slider_vec2
|
||||||
fn ui_slider_vec2(
|
fn ui_slider_vec2(
|
||||||
ui: &mut Ui,
|
ui: &mut Ui,
|
||||||
|
|
|
@ -3,13 +3,7 @@
|
||||||
use std::{hash::Hash, sync::Arc};
|
use std::{hash::Hash, sync::Arc};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
color::*,
|
color::*, containers::*, layout::*, mutex::MutexGuard, paint::text::Fonts, widgets::*, *,
|
||||||
containers::*,
|
|
||||||
layout::*,
|
|
||||||
mutex::MutexGuard,
|
|
||||||
paint::{text::Fonts, *},
|
|
||||||
widgets::*,
|
|
||||||
*,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This is what you use to place widgets.
|
/// This is what you use to place widgets.
|
||||||
|
@ -874,9 +868,9 @@ impl Ui {
|
||||||
/// If the user clicks the button, a full color picker is shown.
|
/// If the user clicks the button, a full color picker is shown.
|
||||||
/// The given color is in `sRGBA` space with premultiplied alpha
|
/// The given color is in `sRGBA` space with premultiplied alpha
|
||||||
pub fn color_edit_button_srgba_premultiplied(&mut self, srgba: &mut [u8; 4]) -> Response {
|
pub fn color_edit_button_srgba_premultiplied(&mut self, srgba: &mut [u8; 4]) -> Response {
|
||||||
let mut color = Color32(*srgba);
|
let mut color = Color32::from_rgba_premultiplied(srgba[0], srgba[1], srgba[2], srgba[3]);
|
||||||
let response = self.color_edit_button_srgba(&mut color);
|
let response = self.color_edit_button_srgba(&mut color);
|
||||||
*srgba = color.0;
|
*srgba = color.to_array();
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
pub(crate) mod cache;
|
pub(crate) mod cache;
|
||||||
mod history;
|
mod history;
|
||||||
pub mod mutex;
|
|
||||||
pub mod undoer;
|
pub mod undoer;
|
||||||
|
|
||||||
pub(crate) use cache::Cache;
|
pub(crate) use cache::Cache;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::ops::RangeInclusive;
|
use std::ops::RangeInclusive;
|
||||||
|
|
||||||
use crate::{paint::*, *};
|
use crate::*;
|
||||||
|
|
||||||
/// Combined into one function (rather than two) to make it easier
|
/// Combined into one function (rather than two) to make it easier
|
||||||
/// for the borrow checker.
|
/// for the borrow checker.
|
||||||
|
|
|
@ -44,3 +44,31 @@ pub fn reset_button<T: Default + PartialEq>(ui: &mut Ui, value: &mut T) {
|
||||||
*value = def;
|
*value = def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
pub fn stroke_ui(ui: &mut crate::Ui, stroke: &mut epaint::Stroke, text: &str) {
|
||||||
|
let epaint::Stroke { width, color } = stroke;
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.add(DragValue::f32(width).speed(0.1).range(0.0..=5.0))
|
||||||
|
.on_hover_text("Width");
|
||||||
|
ui.color_edit_button_srgba(color);
|
||||||
|
ui.label(text);
|
||||||
|
|
||||||
|
// stroke preview:
|
||||||
|
let (_id, stroke_rect) = ui.allocate_space(ui.style().spacing.interact_size);
|
||||||
|
let left = stroke_rect.left_center();
|
||||||
|
let right = stroke_rect.right_center();
|
||||||
|
ui.painter().line_segment([left, right], (*width, *color));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn shadow_ui(ui: &mut Ui, shadow: &mut epaint::Shadow, text: &str) {
|
||||||
|
let epaint::Shadow { extrusion, color } = shadow;
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.label(text);
|
||||||
|
ui.add(DragValue::f32(extrusion).speed(1.0).range(0.0..=100.0))
|
||||||
|
.on_hover_text("Extrusion");
|
||||||
|
ui.color_edit_button_srgba(color);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::ops::RangeInclusive;
|
use std::ops::RangeInclusive;
|
||||||
|
|
||||||
use crate::{paint::*, widgets::Label, *};
|
use crate::{widgets::Label, *};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ impl Default for Painting {
|
||||||
impl Painting {
|
impl Painting {
|
||||||
pub fn ui_control(&mut self, ui: &mut Ui) {
|
pub fn ui_control(&mut self, ui: &mut Ui) {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
self.stroke.ui(ui, "Stroke");
|
egui::stroke_ui(ui, &mut self.stroke, "Stroke");
|
||||||
ui.separator();
|
ui.separator();
|
||||||
if ui.button("Clear Painting").clicked {
|
if ui.button("Clear Painting").clicked {
|
||||||
self.lines.clear();
|
self.lines.clear();
|
||||||
|
|
41
epaint/Cargo.toml
Normal file
41
epaint/Cargo.toml
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
[package]
|
||||||
|
name = "epaint"
|
||||||
|
version = "0.7.0"
|
||||||
|
authors = ["Emil Ernerfeldt <emil.ernerfeldt@gmail.com>"]
|
||||||
|
description = "Minimal 2D graphics library for GUI work"
|
||||||
|
edition = "2018"
|
||||||
|
homepage = "https://github.com/emilk/egui"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
readme = "README.md"
|
||||||
|
repository = "https://github.com/emilk/egui"
|
||||||
|
categories = ["gui", "graphics"]
|
||||||
|
keywords = ["gui", "graphics"]
|
||||||
|
include = [
|
||||||
|
"**/*.rs",
|
||||||
|
"Cargo.toml",
|
||||||
|
"fonts/*.ttf",
|
||||||
|
]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
emath = { path = "../emath" }
|
||||||
|
|
||||||
|
ahash = { version = "0.6", features = ["std"], default-features = false }
|
||||||
|
atomic_refcell = { version = "0.1", optional = true } # Used instead of parking_lot when you are always using epaint in a single thread. About as fast as parking_lot. Panics on multi-threaded use.
|
||||||
|
parking_lot = { version = "0.11", optional = true } # Using parking_lot over std::sync::Mutex gives 50% speedups in some real-world scenarios.
|
||||||
|
rusttype = "0.9"
|
||||||
|
serde = { version = "1", features = ["derive"], optional = true }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["multi_threaded", "default_fonts"]
|
||||||
|
persistence = ["serde", "emath/serde"]
|
||||||
|
|
||||||
|
# If set, epaint will use `include_bytes!` to bundle some fonts.
|
||||||
|
# If you plan on specifying your own fonts you may disable this feature.
|
||||||
|
default_fonts = []
|
||||||
|
|
||||||
|
single_threaded = ["atomic_refcell"]
|
||||||
|
|
||||||
|
# Only needed if you plan to use the same fonts from multiple threads.
|
||||||
|
multi_threaded = ["parking_lot"]
|
5
epaint/README.md
Normal file
5
epaint/README.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# epaint - Egui Paint Library
|
||||||
|
|
||||||
|
A bare-bones 2D graphics library for turning simple 2D shapes and text into textured triangles.
|
||||||
|
|
||||||
|
Made for [`egui`](https://github.com/emilk/egui/).
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::math::clamp;
|
use emath::clamp;
|
||||||
|
|
||||||
/// This format is used for space-efficient color representation (32 bits).
|
/// This format is used for space-efficient color representation (32 bits).
|
||||||
///
|
///
|
|
@ -1,6 +1,51 @@
|
||||||
//! 2D graphics/rendering. Fonts, textures, color, geometry, tessellation etc.
|
//! 2D graphics/rendering. Fonts, textures, color, geometry, tessellation etc.
|
||||||
|
|
||||||
|
#![cfg_attr(not(debug_assertions), deny(warnings))] // Forbid warnings in release builds
|
||||||
|
#![forbid(unsafe_code)]
|
||||||
|
#![warn(
|
||||||
|
clippy::all,
|
||||||
|
clippy::await_holding_lock,
|
||||||
|
clippy::dbg_macro,
|
||||||
|
clippy::doc_markdown,
|
||||||
|
clippy::empty_enum,
|
||||||
|
clippy::enum_glob_use,
|
||||||
|
clippy::exit,
|
||||||
|
clippy::filter_map_next,
|
||||||
|
clippy::fn_params_excessive_bools,
|
||||||
|
clippy::if_let_mutex,
|
||||||
|
clippy::imprecise_flops,
|
||||||
|
clippy::inefficient_to_string,
|
||||||
|
clippy::linkedlist,
|
||||||
|
clippy::lossy_float_literal,
|
||||||
|
clippy::macro_use_imports,
|
||||||
|
clippy::match_on_vec_items,
|
||||||
|
clippy::match_wildcard_for_single_variants,
|
||||||
|
clippy::mem_forget,
|
||||||
|
clippy::mismatched_target_os,
|
||||||
|
clippy::missing_errors_doc,
|
||||||
|
clippy::missing_safety_doc,
|
||||||
|
clippy::needless_borrow,
|
||||||
|
clippy::needless_continue,
|
||||||
|
clippy::needless_pass_by_value,
|
||||||
|
clippy::option_option,
|
||||||
|
clippy::pub_enum_variant_names,
|
||||||
|
clippy::rest_pat_in_fully_bound_structs,
|
||||||
|
clippy::todo,
|
||||||
|
clippy::unimplemented,
|
||||||
|
clippy::unnested_or_patterns,
|
||||||
|
clippy::verbose_file_reads,
|
||||||
|
future_incompatible,
|
||||||
|
missing_crate_level_docs,
|
||||||
|
missing_doc_code_examples,
|
||||||
|
// missing_docs,
|
||||||
|
nonstandard_style,
|
||||||
|
rust_2018_idioms,
|
||||||
|
unused_doc_comments,
|
||||||
|
)]
|
||||||
|
#![allow(clippy::manual_range_contains)]
|
||||||
|
|
||||||
pub mod color;
|
pub mod color;
|
||||||
|
pub mod mutex;
|
||||||
mod shadow;
|
mod shadow;
|
||||||
pub mod shape;
|
pub mod shape;
|
||||||
pub mod stats;
|
pub mod stats;
|
||||||
|
@ -22,11 +67,14 @@ pub use {
|
||||||
triangles::{Triangles, Vertex},
|
triangles::{Triangles, Vertex},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub use ahash;
|
||||||
|
pub use emath;
|
||||||
|
|
||||||
/// The UV coordinate of a white region of the texture mesh.
|
/// The UV coordinate of a white region of the texture mesh.
|
||||||
/// The default Egui texture has the top-left corner pixel fully white.
|
/// The default Egui texture has the top-left corner pixel fully white.
|
||||||
/// You need need use a clamping texture sampler for this to work
|
/// You need need use a clamping texture sampler for this to work
|
||||||
/// (so it doesn't do bilinear blending with bottom right corner).
|
/// (so it doesn't do bilinear blending with bottom right corner).
|
||||||
pub const WHITE_UV: crate::Pos2 = crate::pos2(0.0, 0.0);
|
pub const WHITE_UV: emath::Pos2 = emath::pos2(0.0, 0.0);
|
||||||
|
|
||||||
/// What texture to use in a [`Triangles`] mesh.
|
/// What texture to use in a [`Triangles`] mesh.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
|
@ -47,7 +95,7 @@ impl Default for TextureId {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct PaintRect {
|
pub(crate) struct PaintRect {
|
||||||
pub rect: crate::Rect,
|
pub rect: emath::Rect,
|
||||||
/// How rounded the corners are. Use `0.0` for no rounding.
|
/// How rounded the corners are. Use `0.0` for no rounding.
|
||||||
pub corner_radius: f32,
|
pub corner_radius: f32,
|
||||||
pub fill: Color32,
|
pub fill: Color32,
|
|
@ -1,6 +1,6 @@
|
||||||
//! Helper module that wraps some Mutex types with different implementations.
|
//! Helper module that wraps some Mutex types with different implementations.
|
||||||
//! By default, Egui Mutexes will panic when used in a multi-threaded environment.
|
//!
|
||||||
//! To use the same [`crate::Context`] from different threads, enable the `multi_threaded` feature.
|
//! When the `single_threaded` feature is on the mutexes will panic when locked from different threads.
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
|
@ -25,12 +25,12 @@ impl Shadow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tessellate(&self, rect: crate::Rect, corner_radius: f32) -> Triangles {
|
pub fn tessellate(&self, rect: emath::Rect, corner_radius: f32) -> Triangles {
|
||||||
// tessellator.clip_rect = clip_rect; // TODO: culling
|
// tessellator.clip_rect = clip_rect; // TODO: culling
|
||||||
|
|
||||||
let Self { extrusion, color } = *self;
|
let Self { extrusion, color } = *self;
|
||||||
|
|
||||||
use crate::paint::tessellator::*;
|
use crate::tessellator::*;
|
||||||
let rect = PaintRect {
|
let rect = PaintRect {
|
||||||
rect: rect.expand(0.5 * extrusion),
|
rect: rect.expand(0.5 * extrusion),
|
||||||
corner_radius: corner_radius + 0.5 * extrusion,
|
corner_radius: corner_radius + 0.5 * extrusion,
|
|
@ -1,10 +1,8 @@
|
||||||
use {
|
use crate::{
|
||||||
super::{
|
text::{Fonts, Galley, TextStyle},
|
||||||
text::{Fonts, Galley, TextStyle},
|
Color32, Stroke, Triangles,
|
||||||
Color32, Triangles,
|
|
||||||
},
|
|
||||||
crate::*,
|
|
||||||
};
|
};
|
||||||
|
use emath::*;
|
||||||
|
|
||||||
/// A paint primitive such as a circle or a piece of text.
|
/// A paint primitive such as a circle or a piece of text.
|
||||||
/// Coordinates are all screen space points (not physical pixels).
|
/// Coordinates are all screen space points (not physical pixels).
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{paint::*, Rect};
|
use {crate::*, emath::*};
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
enum ElementSize {
|
enum ElementSize {
|
||||||
|
@ -129,24 +129,20 @@ impl AllocInfo {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn label(&self, ui: &mut crate::Ui, what: &str) -> crate::Response {
|
|
||||||
ui.add(crate::Label::new(self.format(what)).multiline(false))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Default)]
|
#[derive(Clone, Copy, Default)]
|
||||||
pub struct PaintStats {
|
pub struct PaintStats {
|
||||||
shapes: AllocInfo,
|
pub shapes: AllocInfo,
|
||||||
shape_text: AllocInfo,
|
pub shape_text: AllocInfo,
|
||||||
shape_path: AllocInfo,
|
pub shape_path: AllocInfo,
|
||||||
shape_mesh: AllocInfo,
|
pub shape_mesh: AllocInfo,
|
||||||
shape_vec: AllocInfo,
|
pub shape_vec: AllocInfo,
|
||||||
|
|
||||||
/// Number of separate clip rectangles
|
/// Number of separate clip rectangles
|
||||||
jobs: AllocInfo,
|
pub jobs: AllocInfo,
|
||||||
vertices: AllocInfo,
|
pub vertices: AllocInfo,
|
||||||
indices: AllocInfo,
|
pub indices: AllocInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PaintStats {
|
impl PaintStats {
|
||||||
|
@ -187,7 +183,7 @@ impl PaintStats {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_paint_jobs(mut self, paint_jobs: &[crate::paint::PaintJob]) -> Self {
|
pub fn with_paint_jobs(mut self, paint_jobs: &[crate::PaintJob]) -> Self {
|
||||||
self.jobs += AllocInfo::from_slice(paint_jobs);
|
self.jobs += AllocInfo::from_slice(paint_jobs);
|
||||||
for (_, indices) in paint_jobs {
|
for (_, indices) in paint_jobs {
|
||||||
self.vertices += AllocInfo::from_slice(&indices.vertices);
|
self.vertices += AllocInfo::from_slice(&indices.vertices);
|
||||||
|
@ -207,51 +203,6 @@ impl PaintStats {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PaintStats {
|
|
||||||
pub fn ui(&self, ui: &mut crate::Ui) {
|
|
||||||
ui.label(
|
|
||||||
"Egui generates intermediate level shapes like circles and text. \
|
|
||||||
These are later tessellated into triangles.",
|
|
||||||
);
|
|
||||||
ui.advance_cursor(10.0);
|
|
||||||
|
|
||||||
ui.style_mut().body_text_style = TextStyle::Monospace;
|
|
||||||
|
|
||||||
let Self {
|
|
||||||
shapes,
|
|
||||||
shape_text,
|
|
||||||
shape_path,
|
|
||||||
shape_mesh,
|
|
||||||
shape_vec,
|
|
||||||
jobs,
|
|
||||||
vertices,
|
|
||||||
indices,
|
|
||||||
} = self;
|
|
||||||
|
|
||||||
ui.label("Intermediate:");
|
|
||||||
shapes
|
|
||||||
.label(ui, "shapes")
|
|
||||||
.on_hover_text("Boxes, circles, etc");
|
|
||||||
shape_text.label(ui, "text");
|
|
||||||
shape_path.label(ui, "paths");
|
|
||||||
shape_mesh.label(ui, "meshes");
|
|
||||||
shape_vec.label(ui, "nested");
|
|
||||||
ui.advance_cursor(10.0);
|
|
||||||
|
|
||||||
ui.label("Tessellated:");
|
|
||||||
jobs.label(ui, "jobs")
|
|
||||||
.on_hover_text("Number of separate clip rectangles");
|
|
||||||
vertices.label(ui, "vertices");
|
|
||||||
indices
|
|
||||||
.label(ui, "indices")
|
|
||||||
.on_hover_text("Three 32-bit indices per triangles");
|
|
||||||
ui.advance_cursor(10.0);
|
|
||||||
|
|
||||||
// ui.label("Total:");
|
|
||||||
// ui.label(self.total().format(""));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn megabytes(size: usize) -> String {
|
fn megabytes(size: usize) -> String {
|
||||||
format!("{:.2} MB", size as f64 / 1e6)
|
format!("{:.2} MB", size as f64 / 1e6)
|
||||||
}
|
}
|
|
@ -5,11 +5,9 @@
|
||||||
|
|
||||||
#![allow(clippy::identity_op)]
|
#![allow(clippy::identity_op)]
|
||||||
|
|
||||||
use {
|
use crate::{text::Fonts, *};
|
||||||
super::{text::Fonts, *},
|
use emath::*;
|
||||||
crate::math::*,
|
use std::f32::consts::TAU;
|
||||||
std::f32::consts::TAU,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A clip triangle and some textured triangles.
|
/// A clip triangle and some textured triangles.
|
||||||
pub type PaintJob = (Rect, Triangles);
|
pub type PaintJob = (Rect, Triangles);
|
||||||
|
@ -133,7 +131,7 @@ impl Path {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod path {
|
pub mod path {
|
||||||
//! Helpers for constructing paths
|
//! Helpers for constructing paths
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -6,13 +6,11 @@ use {
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
math::{vec2, Vec2},
|
|
||||||
mutex::{Mutex, RwLock},
|
mutex::{Mutex, RwLock},
|
||||||
paint::{
|
text::galley::{Galley, Row},
|
||||||
text::galley::{Galley, Row},
|
TextureAtlas,
|
||||||
TextureAtlas,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
use emath::{vec2, Vec2};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
|
@ -4,9 +4,11 @@ use std::{
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::font::{Font, FontImpl};
|
use crate::{
|
||||||
use crate::mutex::Mutex;
|
mutex::Mutex,
|
||||||
use crate::paint::{Texture, TextureAtlas};
|
text::font::{Font, FontImpl},
|
||||||
|
Texture, TextureAtlas,
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: rename
|
// TODO: rename
|
||||||
/// One of a few categories of styles of text, e.g. body, button or heading.
|
/// One of a few categories of styles of text, e.g. body, button or heading.
|
||||||
|
@ -68,7 +70,7 @@ fn rusttype_font_from_font_data(name: &str, data: &FontData) -> rusttype::Font<'
|
||||||
///
|
///
|
||||||
/// Often you would start with [`FontDefinitions::default()`] and then add/change the contents.
|
/// Often you would start with [`FontDefinitions::default()`] and then add/change the contents.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ``` ignore
|
||||||
/// # let mut ctx = egui::CtxRef::default();
|
/// # let mut ctx = egui::CtxRef::default();
|
||||||
/// let mut fonts = egui::FontDefinitions::default();
|
/// let mut fonts = egui::FontDefinitions::default();
|
||||||
/// // Large button text:
|
/// // Large button text:
|
||||||
|
@ -115,22 +117,22 @@ impl Default for FontDefinitions {
|
||||||
// Use size 13 for this. NOTHING ELSE:
|
// Use size 13 for this. NOTHING ELSE:
|
||||||
font_data.insert(
|
font_data.insert(
|
||||||
"ProggyClean".to_owned(),
|
"ProggyClean".to_owned(),
|
||||||
std::borrow::Cow::Borrowed(include_bytes!("../../../fonts/ProggyClean.ttf")),
|
std::borrow::Cow::Borrowed(include_bytes!("../../fonts/ProggyClean.ttf")),
|
||||||
);
|
);
|
||||||
font_data.insert(
|
font_data.insert(
|
||||||
"Ubuntu-Light".to_owned(),
|
"Ubuntu-Light".to_owned(),
|
||||||
std::borrow::Cow::Borrowed(include_bytes!("../../../fonts/Ubuntu-Light.ttf")),
|
std::borrow::Cow::Borrowed(include_bytes!("../../fonts/Ubuntu-Light.ttf")),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Some good looking emojis. Use as first priority:
|
// Some good looking emojis. Use as first priority:
|
||||||
font_data.insert(
|
font_data.insert(
|
||||||
"NotoEmoji-Regular".to_owned(),
|
"NotoEmoji-Regular".to_owned(),
|
||||||
std::borrow::Cow::Borrowed(include_bytes!("../../../fonts/NotoEmoji-Regular.ttf")),
|
std::borrow::Cow::Borrowed(include_bytes!("../../fonts/NotoEmoji-Regular.ttf")),
|
||||||
);
|
);
|
||||||
// Bigger emojis, and more. <http://jslegers.github.io/emoji-icon-font/>:
|
// Bigger emojis, and more. <http://jslegers.github.io/emoji-icon-font/>:
|
||||||
font_data.insert(
|
font_data.insert(
|
||||||
"emoji-icon-font".to_owned(),
|
"emoji-icon-font".to_owned(),
|
||||||
std::borrow::Cow::Borrowed(include_bytes!("../../../fonts/emoji-icon-font.ttf")),
|
std::borrow::Cow::Borrowed(include_bytes!("../../fonts/emoji-icon-font.ttf")),
|
||||||
);
|
);
|
||||||
|
|
||||||
fonts_for_family.insert(
|
fonts_for_family.insert(
|
|
@ -20,7 +20,7 @@
|
||||||
//! [`CCursor::prefer_next_row`] etc selects which.
|
//! [`CCursor::prefer_next_row`] etc selects which.
|
||||||
|
|
||||||
use super::cursor::*;
|
use super::cursor::*;
|
||||||
use crate::math::{pos2, NumExt, Rect, Vec2};
|
use emath::{pos2, NumExt, Rect, Vec2};
|
||||||
|
|
||||||
/// A collection of text locked into place.
|
/// A collection of text locked into place.
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
|
@ -551,7 +551,7 @@ fn test_text_layout() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::paint::*;
|
use crate::*;
|
||||||
|
|
||||||
let pixels_per_point = 1.0;
|
let pixels_per_point = 1.0;
|
||||||
let fonts = text::Fonts::from_definitions(pixels_per_point, text::FontDefinitions::default());
|
let fonts = text::Fonts::from_definitions(pixels_per_point, text::FontDefinitions::default());
|
|
@ -1,5 +1,5 @@
|
||||||
use super::*;
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use emath::*;
|
||||||
|
|
||||||
/// The vertex type.
|
/// The vertex type.
|
||||||
///
|
///
|
Loading…
Reference in a new issue