From 679ee9a2ce569dce1729c20aa70466a912dd898b Mon Sep 17 00:00:00 2001 From: griffi-gh <prasol258@gmail.com> Date: Mon, 3 Mar 2025 18:16:07 +0100 Subject: [PATCH] more crappy code --- hui-painter-wip/src/paint/command.rs | 3 +- hui-painter-wip/src/paint/command/list.rs | 21 ++++++++--- .../src/paint/command/rectangle.rs | 29 ++++++++++----- hui-painter-wip/src/paint/command/text.rs | 10 +++-- .../src/paint/command/transform.rs | 37 +++++++++++++++++-- hui-shared/src/rect/rect.rs | 12 ++++++ 6 files changed, 91 insertions(+), 21 deletions(-) diff --git a/hui-painter-wip/src/paint/command.rs b/hui-painter-wip/src/paint/command.rs index 265e5b2..749649e 100644 --- a/hui-painter-wip/src/paint/command.rs +++ b/hui-painter-wip/src/paint/command.rs @@ -1,6 +1,7 @@ use std::hash::Hash; use glam::Vec2; +use hui_shared::rect::Rect; use crate::{paint::buffer::PaintBuffer, PainterInstance}; // mod root; @@ -37,7 +38,7 @@ pub trait PaintCommand { /// Must be unique for each possilbe combination of parameters fn cache_hash(&self) -> u64; - fn size(&self, ctx: &PainterInstance) -> Vec2; + fn bounds(&self, ctx: &PainterInstance) -> Rect; } // TODO move paint_root to PaintCommand instead of separate trait? diff --git a/hui-painter-wip/src/paint/command/list.rs b/hui-painter-wip/src/paint/command/list.rs index 57f4ba0..15e2c26 100644 --- a/hui-painter-wip/src/paint/command/list.rs +++ b/hui-painter-wip/src/paint/command/list.rs @@ -1,5 +1,7 @@ use std::hash::Hasher; +use hui_shared::rect::Rect; + use crate::PainterInstance; use super::PaintCommand; @@ -53,11 +55,20 @@ impl PaintCommand for PaintList { hasher.finish() } - fn size(&self, ctx: &PainterInstance) -> glam::Vec2 { - let mut size = glam::Vec2::ZERO; - for command in &self.commands { - size = size.max(command.size(ctx)); + fn bounds(&self, ctx: &PainterInstance) -> Rect { + if self.commands.is_empty() { + return Rect::ZERO; + } + let mut position = glam::Vec2::splat(f32::MAX); + let mut size = glam::Vec2::splat(f32::MIN); + for command in &self.commands { + let bounds = command.bounds(ctx); + position = position.min(bounds.position); + size = size.max(bounds.size); + } + Rect { + position, + size, } - size } } \ No newline at end of file diff --git a/hui-painter-wip/src/paint/command/rectangle.rs b/hui-painter-wip/src/paint/command/rectangle.rs index 0f52390..42672d2 100644 --- a/hui-painter-wip/src/paint/command/rectangle.rs +++ b/hui-painter-wip/src/paint/command/rectangle.rs @@ -1,6 +1,6 @@ use std::{hash::Hasher, num::NonZeroU16}; use glam::{vec2, Vec2}; -use hui_shared::{color, rect::{Corners, FillColor}}; +use hui_shared::{color, rect::{Corners, FillColor, Rect}}; use crate::{ paint::{ buffer::{PaintBuffer, Vertex}, @@ -94,6 +94,11 @@ impl PaintRectangle { impl PaintCommand for PaintRectangle { fn paint(&self, ctx: &mut PainterInstance, into: &mut PaintBuffer) { + // Offset from (0, 0) to the actual origin + // We calculate positions in the range of [0, size] for simplicity + // And then subtract this offset to get the actual position of a rectangle centered at (0, 0) + // let origin_offset = self.size / 2.; + // If texture is set: // - Get texture UV // - Map local UVs to texture UV coords @@ -166,22 +171,22 @@ impl PaintCommand for PaintRectangle { ]); into.vertices.extend([ Vertex { - position: vec2(0., 0.) * self.size, + position: vec2(0., 0.) * self.size, // - origin_offset, uv: uvs.top_left, color: colors.top_left, }, Vertex { - position: vec2(1., 0.) * self.size, + position: vec2(1., 0.) * self.size, // - origin_offset, uv: uvs.top_right, color: colors.top_right, }, Vertex { - position: vec2(0., 1.) * self.size, + position: vec2(0., 1.) * self.size, // - origin_offset, uv: uvs.bottom_left, color: colors.bottom_left, }, Vertex { - position: vec2(1., 1.) * self.size, + position: vec2(1., 1.) * self.size, // - origin_offset, uv: uvs.bottom_right, color: colors.bottom_right, }, @@ -208,7 +213,7 @@ impl PaintCommand for PaintRectangle { uvs.bottom_left * (1. - point_uv.x) * point_uv.y + uvs.top_left * (1. - point_uv.x) * (1. - point_uv.y); Vertex { - position: point, + position: point, // - origin_offset, color: color_at_point, uv: uv_at_point, } @@ -276,8 +281,15 @@ impl PaintCommand for PaintRectangle { } } - fn size(&self, ctx: &PainterInstance) -> Vec2 { - self.size + fn bounds(&self, _: &PainterInstance) -> Rect { + // Rect { + // position: -self.size / 2., + // size: self.size / 2., + // } + Rect { + position: Vec2::ZERO, + size: self.size, + } } fn cache_hash(&self) -> u64 { @@ -288,5 +300,4 @@ impl PaintCommand for PaintRectangle { } hasher.finish() } - } diff --git a/hui-painter-wip/src/paint/command/text.rs b/hui-painter-wip/src/paint/command/text.rs index e07dbad..74e10e6 100644 --- a/hui-painter-wip/src/paint/command/text.rs +++ b/hui-painter-wip/src/paint/command/text.rs @@ -1,6 +1,7 @@ use std::{borrow::Cow, hash::{Hash, Hasher}}; use fontdue::layout::{CoordinateSystem, Layout}; use glam::{vec2, Vec2}; +use hui_shared::rect::Rect; use crate::{ paint::{ buffer::PaintBuffer, @@ -76,10 +77,10 @@ impl PaintCommand for PaintText { // todo!() - // TODO text rendering + // TODO_IMPORTANT text rendering } - fn size(&self, ctx: &PainterInstance) -> Vec2 { + fn bounds(&self, ctx: &PainterInstance) -> Rect { let font_array = self.build_font_array(ctx); let layout = self.build_layout(&font_array); @@ -91,7 +92,10 @@ impl PaintCommand for PaintText { }).unwrap_or(0.); let height = layout.height(); - vec2(width, height) + Rect { + position: vec2(0., 0.), + size: vec2(width, height), + } } fn cache_hash(&self) -> u64 { diff --git a/hui-painter-wip/src/paint/command/transform.rs b/hui-painter-wip/src/paint/command/transform.rs index c2192f8..400d378 100644 --- a/hui-painter-wip/src/paint/command/transform.rs +++ b/hui-painter-wip/src/paint/command/transform.rs @@ -1,5 +1,8 @@ use std::hash::Hasher; +use glam::vec2; +use hui_shared::rect::Rect; + use crate::{ PainterInstance, paint::{ @@ -25,6 +28,11 @@ impl<T: PaintCommand + 'static> PaintCommand for PaintTransform<T> { // paint children node self.child.paint(ctx, into); + if starting_index == into.vertices.len() { + // no vertices were added, no need to transform + return; + } + let mut min_point = glam::Vec2::splat(f32::MAX); let mut max_point = glam::Vec2::splat(f32::MIN); for vtx in &into.vertices[starting_index..] { @@ -52,8 +60,31 @@ impl<T: PaintCommand + 'static> PaintCommand for PaintTransform<T> { hasher.finish() } - fn size(&self, ctx: &PainterInstance) -> glam::Vec2 { - // TODO take transform into account - self.child.size(ctx) + fn bounds(&self, ctx: &PainterInstance) -> Rect { + let Rect { position, size } = self.child.bounds(ctx); + + // XXX: to match the behavior above, transform the corners around the center + // FIXME: the behavior may not actually match? + + let half = size / 2.0; + let center = position + half; + let points = [ + self.transform.transform_point2(vec2(-half.x, -half.y)) + center, + self.transform.transform_point2(vec2( half.x, -half.y)) + center, + self.transform.transform_point2(vec2(-half.x, half.y)) + center, + self.transform.transform_point2(vec2( half.x, half.y)) + center, + ]; + + let mut min_point = glam::Vec2::splat(f32::MAX); + let mut max_point = glam::Vec2::splat(f32::MIN); + for point in points { + min_point = min_point.min(point); + max_point = max_point.max(point); + } + + Rect { + position: min_point, + size: max_point - min_point, + } } } diff --git a/hui-shared/src/rect/rect.rs b/hui-shared/src/rect/rect.rs index 988ae3f..d4e2e8d 100644 --- a/hui-shared/src/rect/rect.rs +++ b/hui-shared/src/rect/rect.rs @@ -11,6 +11,18 @@ pub struct Rect { } impl Rect { + /// A rect with both position and size set to zero. + pub const ZERO: Self = Self { + position: Vec2::ZERO, + size: Vec2::ZERO, + }; + + /// A rect with size of 1x1 and position of zero. + pub const UNIT: Self = Self { + position: Vec2::ZERO, + size: Vec2::ONE, + }; + pub const fn new(position: Vec2, size: Vec2) -> Self { Self { position, size } }