mirror of
https://github.com/griffi-gh/hUI.git
synced 2024-11-21 22:58:42 -06:00
Compare commits
2 commits
108deeab34
...
121e667bdb
Author | SHA1 | Date | |
---|---|---|---|
griffi-gh | 121e667bdb | ||
griffi-gh | 8baa85998b |
|
@ -1,17 +1,19 @@
|
||||||
pub mod paint;
|
pub mod paint;
|
||||||
pub mod texture;
|
pub mod texture;
|
||||||
pub mod text;
|
pub mod text;
|
||||||
|
pub mod util;
|
||||||
|
|
||||||
use text::FontManager;
|
use text::FontManager;
|
||||||
use texture::TextureAtlas;
|
use texture::TextureAtlas;
|
||||||
|
|
||||||
|
/// Painter instance, stores textures and fonts needed for rendering
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Painter {
|
pub struct PainterInstance {
|
||||||
pub atlas: TextureAtlas,
|
pub atlas: TextureAtlas,
|
||||||
pub fonts: FontManager,
|
pub fonts: FontManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Painter {
|
impl PainterInstance {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
use glam::Vec2;
|
use glam::Vec2;
|
||||||
use crate::{paint::buffer::PaintBuffer, Painter};
|
use crate::{paint::buffer::PaintBuffer, PainterInstance};
|
||||||
|
|
||||||
// mod root;
|
// mod root;
|
||||||
// pub use root::RootCommand;
|
// pub use root::RootCommand;
|
||||||
|
|
||||||
|
mod list;
|
||||||
|
pub use list::PaintList;
|
||||||
|
|
||||||
mod transform;
|
mod transform;
|
||||||
pub use transform::PaintTransform;
|
pub use transform::PaintTransform;
|
||||||
|
|
||||||
|
@ -19,15 +22,30 @@ pub trait PaintCommand {
|
||||||
///
|
///
|
||||||
/// Make sure to propagate this call to children!
|
/// Make sure to propagate this call to children!
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn pre_paint(&self, ctx: &mut Painter) {}
|
fn pre_paint(&self, ctx: &mut PainterInstance) {}
|
||||||
|
|
||||||
/// Paint the command into the buffer
|
/// Paint the command into the buffer
|
||||||
///
|
///
|
||||||
/// Do not allocate new textures or cache glyphs here, use `pre_paint` instead!\
|
/// Do not allocate new textures or cache glyphs here, use `pre_paint` instead!\
|
||||||
/// (Doing this WILL lead to atlas corruption flicker for a single frame if it's forced to resize!)
|
/// (Doing this WILL lead to atlas corruption flicker for a single frame if it's forced to resize!)
|
||||||
fn paint(&self, ctx: &mut Painter, into: &mut PaintBuffer);
|
fn paint(&self, ctx: &mut PainterInstance, into: &mut PaintBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Measurable: PaintCommand {
|
pub trait Measurable: PaintCommand {
|
||||||
fn size(&self, ctx: &Painter) -> Vec2;
|
fn size(&self, ctx: &PainterInstance) -> Vec2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO move paint_root to PaintCommand instead of separate trait?
|
||||||
|
|
||||||
|
pub trait PaintRoot: PaintCommand {
|
||||||
|
/// Paint the root command, calling `pre_paint` before painting
|
||||||
|
///
|
||||||
|
/// This is a convenience method for painting the root command
|
||||||
|
/// Do not use this inside the `paint` method of a command!
|
||||||
|
fn paint_root(&self, ctx: &mut PainterInstance, into: &mut PaintBuffer) {
|
||||||
|
self.pre_paint(ctx);
|
||||||
|
self.paint(ctx, into);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: PaintCommand> PaintRoot for T {}
|
||||||
|
|
45
hui-painter/src/paint/command/list.rs
Normal file
45
hui-painter/src/paint/command/list.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
use crate::PainterInstance;
|
||||||
|
|
||||||
|
use super::PaintCommand;
|
||||||
|
|
||||||
|
pub struct PaintList {
|
||||||
|
pub commands: Vec<Box<dyn PaintCommand>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PaintList {
|
||||||
|
pub fn new(commands: Vec<Box<dyn PaintCommand>>) -> Self {
|
||||||
|
Self {
|
||||||
|
commands
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_empty() -> Self {
|
||||||
|
Self {
|
||||||
|
commands: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(&mut self, command: impl PaintCommand + 'static) {
|
||||||
|
self.commands.push(Box::new(command));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PaintList {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new_empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PaintCommand for PaintList {
|
||||||
|
fn pre_paint(&self, ctx: &mut PainterInstance) {
|
||||||
|
for command in &self.commands {
|
||||||
|
command.pre_paint(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn paint(&self, ctx: &mut crate::PainterInstance, into: &mut crate::paint::buffer::PaintBuffer) {
|
||||||
|
for command in &self.commands {
|
||||||
|
command.paint(ctx, into);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
command::PaintCommand,
|
command::PaintCommand,
|
||||||
},
|
},
|
||||||
texture::TextureHandle,
|
texture::TextureHandle,
|
||||||
Painter
|
PainterInstance
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Calculate the number of points based on the maximum corner radius
|
/// Calculate the number of points based on the maximum corner radius
|
||||||
|
@ -92,7 +92,7 @@ impl PaintRectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PaintCommand for PaintRectangle {
|
impl PaintCommand for PaintRectangle {
|
||||||
fn paint(&self, ctx: &mut Painter, into: &mut PaintBuffer) {
|
fn paint(&self, ctx: &mut PainterInstance, into: &mut PaintBuffer) {
|
||||||
// If texture is set:
|
// If texture is set:
|
||||||
// - Get texture UV
|
// - Get texture UV
|
||||||
// - Map local UVs to texture UV coords
|
// - Map local UVs to texture UV coords
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use std::{borrow::Cow, sync::Arc};
|
use std::borrow::Cow;
|
||||||
use fontdue::layout::{self, CoordinateSystem, GlyphRasterConfig, Layout};
|
use fontdue::layout::{CoordinateSystem, Layout};
|
||||||
use glam::{vec2, Vec2};
|
use glam::{vec2, Vec2};
|
||||||
use crate::{
|
use crate::{
|
||||||
paint::{
|
paint::{
|
||||||
buffer::PaintBuffer,
|
buffer::PaintBuffer,
|
||||||
command::PaintCommand,
|
command::PaintCommand,
|
||||||
}, text::FontHandle, Painter
|
}, text::FontHandle, PainterInstance
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::Measurable;
|
use super::Measurable;
|
||||||
|
@ -34,7 +34,7 @@ impl PaintText {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_font_array<'a>(&self, ctx: &'a Painter) -> Vec<&'a fontdue::Font> {
|
fn build_font_array<'a>(&self, ctx: &'a PainterInstance) -> Vec<&'a fontdue::Font> {
|
||||||
let font = ctx.fonts.get_fontdue_font(self.text.font)
|
let font = ctx.fonts.get_fontdue_font(self.text.font)
|
||||||
.expect("FontHandle is invalid");
|
.expect("FontHandle is invalid");
|
||||||
vec![&font]
|
vec![&font]
|
||||||
|
@ -55,7 +55,7 @@ impl PaintText {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PaintCommand for PaintText {
|
impl PaintCommand for PaintText {
|
||||||
fn pre_paint(&self, ctx: &mut Painter) {
|
fn pre_paint(&self, ctx: &mut PainterInstance) {
|
||||||
let font_array = self.build_font_array(ctx);
|
let font_array = self.build_font_array(ctx);
|
||||||
let layout = self.build_layout(&font_array);
|
let layout = self.build_layout(&font_array);
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ impl PaintCommand for PaintText {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint(&self, ctx: &mut Painter, into: &mut PaintBuffer) {
|
fn paint(&self, ctx: &mut PainterInstance, into: &mut PaintBuffer) {
|
||||||
// let font_array = self.build_font_array(ctx);
|
// let font_array = self.build_font_array(ctx);
|
||||||
// let layout = self.build_layout(&font_array);
|
// let layout = self.build_layout(&font_array);
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ impl PaintCommand for PaintText {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Measurable for PaintText {
|
impl Measurable for PaintText {
|
||||||
fn size(&self, ctx: &Painter) -> Vec2 {
|
fn size(&self, ctx: &PainterInstance) -> Vec2 {
|
||||||
let font_array = self.build_font_array(ctx);
|
let font_array = self.build_font_array(ctx);
|
||||||
let layout = self.build_layout(&font_array);
|
let layout = self.build_layout(&font_array);
|
||||||
|
|
||||||
|
|
|
@ -1,31 +1,27 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
Painter,
|
PainterInstance,
|
||||||
paint::{
|
paint::{
|
||||||
buffer::PaintBuffer,
|
buffer::PaintBuffer,
|
||||||
command::PaintCommand,
|
command::PaintCommand,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct PaintTransform {
|
pub struct PaintTransform<T: PaintCommand + 'static> {
|
||||||
pub transform: glam::Affine2,
|
pub transform: glam::Affine2,
|
||||||
pub children: Vec<Box<dyn PaintCommand>>,
|
pub child: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PaintCommand for PaintTransform {
|
impl<T: PaintCommand + 'static> PaintCommand for PaintTransform<T> {
|
||||||
fn pre_paint(&self, ctx: &mut Painter) {
|
fn pre_paint(&self, ctx: &mut PainterInstance) {
|
||||||
for child in &self.children {
|
self.child.pre_paint(ctx);
|
||||||
child.pre_paint(ctx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint(&self, ctx: &mut Painter, into: &mut PaintBuffer) {
|
fn paint(&self, ctx: &mut PainterInstance, into: &mut PaintBuffer) {
|
||||||
// remember the starting index
|
// remember the starting index
|
||||||
let starting_index = into.vertices.len();
|
let starting_index = into.vertices.len();
|
||||||
|
|
||||||
// paint children nodes
|
// paint children node
|
||||||
for child in &self.children {
|
self.child.paint(ctx, into);
|
||||||
child.paint(ctx, into);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut min_point = glam::Vec2::splat(f32::MAX);
|
let mut min_point = glam::Vec2::splat(f32::MAX);
|
||||||
let mut max_point = glam::Vec2::splat(f32::MIN);
|
let mut max_point = glam::Vec2::splat(f32::MIN);
|
||||||
|
|
|
@ -23,7 +23,7 @@ impl FontManager {
|
||||||
///
|
///
|
||||||
/// Panics:
|
/// Panics:
|
||||||
/// - If the font data is invalid.
|
/// - If the font data is invalid.
|
||||||
pub fn add_font(&mut self, data: &[u8]) -> FontHandle {
|
pub fn add(&mut self, data: &[u8]) -> FontHandle {
|
||||||
let font = self.fonts.add_font(data);
|
let font = self.fonts.add_font(data);
|
||||||
self.ftm.init_font(font);
|
self.ftm.init_font(font);
|
||||||
font
|
font
|
||||||
|
@ -33,7 +33,7 @@ impl FontManager {
|
||||||
///
|
///
|
||||||
/// Panics:
|
/// Panics:
|
||||||
/// - If the font handle is invalid.
|
/// - If the font handle is invalid.
|
||||||
pub fn remove_font(&mut self, font: FontHandle, atlas: &mut TextureAtlas) {
|
pub fn remove(&mut self, font: FontHandle, atlas: &mut TextureAtlas) {
|
||||||
self.ftm.drop_font(font, atlas);
|
self.ftm.drop_font(font, atlas);
|
||||||
self.fonts.remove_font(font);
|
self.fonts.remove_font(font);
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,6 +141,9 @@ pub struct TextureAtlas {
|
||||||
/// Deallocated allocations that can be reused, sorted by size
|
/// Deallocated allocations that can be reused, sorted by size
|
||||||
//TODO: use binary heap or btreeset for reuse_allocations instead, but this works for now
|
//TODO: use binary heap or btreeset for reuse_allocations instead, but this works for now
|
||||||
reuse_allocations: Vec<TextureAllocation>,
|
reuse_allocations: Vec<TextureAllocation>,
|
||||||
|
|
||||||
|
/// Version of the texture atlas, incremented every time the atlas is modified
|
||||||
|
version: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextureAtlas {
|
impl TextureAtlas {
|
||||||
|
@ -158,9 +161,19 @@ impl TextureAtlas {
|
||||||
next_id: 0,
|
next_id: 0,
|
||||||
allocations: HashMap::default(),
|
allocations: HashMap::default(),
|
||||||
reuse_allocations: Vec::new(),
|
reuse_allocations: Vec::new(),
|
||||||
|
version: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn version(&self) -> u64 {
|
||||||
|
self.version
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mark_modified(&mut self) {
|
||||||
|
// XXX: wrapping_add? will this *ever* overflow?
|
||||||
|
self.version = self.version.wrapping_add(1);
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the next handle
|
/// Get the next handle
|
||||||
///
|
///
|
||||||
/// Does not allocate a texture associated with it
|
/// Does not allocate a texture associated with it
|
||||||
|
@ -303,6 +316,8 @@ impl TextureAtlas {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.mark_modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocate a texture in the atlas, returning a handle to it.\
|
/// Allocate a texture in the atlas, returning a handle to it.\
|
||||||
|
|
0
hui-painter/src/util.rs
Normal file
0
hui-painter/src/util.rs
Normal file
|
@ -18,7 +18,7 @@ include = [
|
||||||
[dependencies]
|
[dependencies]
|
||||||
hui-derive = { version = "0.1.0-alpha.5", path = "../hui-derive", optional = true }
|
hui-derive = { version = "0.1.0-alpha.5", path = "../hui-derive", optional = true }
|
||||||
hui-shared = { version = "0.1.0-alpha.5", path = "../hui-shared" }
|
hui-shared = { version = "0.1.0-alpha.5", path = "../hui-shared" }
|
||||||
hui-painter = { version = "0.1.0-alpha.5", path = "../hui-painter" }
|
# hui-painter = { version = "0.1.0-alpha.5", path = "../hui-painter" }
|
||||||
hashbrown = "0.14"
|
hashbrown = "0.14"
|
||||||
nohash-hasher = "0.2"
|
nohash-hasher = "0.2"
|
||||||
glam = "0.28.0"
|
glam = "0.28.0"
|
||||||
|
|
Loading…
Reference in a new issue