Fix Rect coordinate space
This commit is contained in:
parent
681b884b74
commit
eb32163b24
|
@ -305,10 +305,10 @@ impl DrawContext {
|
|||
rect
|
||||
};
|
||||
|
||||
let v1 = rect.bl;
|
||||
let v2 = Vec2::new(rect.bl.x, rect.tr.y);
|
||||
let v3 = Vec2::new(rect.tr.x, rect.bl.y);
|
||||
let v4 = rect.tr;
|
||||
let v1 = rect.tl;
|
||||
let v2 = Vec2::new(rect.tl.x, rect.br.y);
|
||||
let v3 = Vec2::new(rect.br.x, rect.tl.y);
|
||||
let v4 = rect.br;
|
||||
|
||||
self.draw_triangle_noclip(v1, v2, v3, color);
|
||||
self.draw_triangle_noclip(v2, v3, v4, color);
|
||||
|
@ -333,47 +333,48 @@ impl DrawContext {
|
|||
let mut inner_rect = rect;
|
||||
let inset = rect.inset(radius);
|
||||
|
||||
if corners.intersects(CornerFlags::TOP) {
|
||||
inner_rect.tl.y += radius;
|
||||
|
||||
let mut top_edge = Rect {
|
||||
tl: rect.tl,
|
||||
br: Vec2::new(rect.br.x, rect.tl.y + radius),
|
||||
};
|
||||
|
||||
if corners.contains(CornerFlags::TOP_LEFT) {
|
||||
top_edge.tl.x += radius;
|
||||
self.draw_quarter_circle(Corner::TopLeft, inset.tl, radius, color);
|
||||
}
|
||||
|
||||
if corners.contains(CornerFlags::TOP_RIGHT) {
|
||||
top_edge.br.x -= radius;
|
||||
self.draw_quarter_circle(Corner::TopRight, inset.tr(), radius, color);
|
||||
}
|
||||
|
||||
self.draw_rect(top_edge, color);
|
||||
}
|
||||
|
||||
if corners.intersects(CornerFlags::BOTTOM) {
|
||||
inner_rect.bl.y += radius;
|
||||
inner_rect.br.y -= radius;
|
||||
|
||||
let mut bottom_edge = Rect {
|
||||
bl: rect.bl,
|
||||
tr: Vec2::new(rect.tr.x, rect.bl.y + radius),
|
||||
tl: Vec2::new(rect.tl.x, rect.br.y - radius),
|
||||
br: rect.br,
|
||||
};
|
||||
|
||||
if corners.contains(CornerFlags::BOTTOM_LEFT) {
|
||||
bottom_edge.bl.x += radius;
|
||||
self.draw_quarter_circle(Corner::BottomLeft, inset.bl, radius, color);
|
||||
bottom_edge.tl.x += radius;
|
||||
self.draw_quarter_circle(Corner::BottomLeft, inset.bl(), radius, color);
|
||||
}
|
||||
|
||||
if corners.contains(CornerFlags::BOTTOM_RIGHT) {
|
||||
bottom_edge.tr.x -= radius;
|
||||
self.draw_quarter_circle(Corner::BottomRight, inset.br(), radius, color);
|
||||
bottom_edge.br.x -= radius;
|
||||
self.draw_quarter_circle(Corner::BottomRight, inset.br, radius, color);
|
||||
}
|
||||
|
||||
self.draw_rect(bottom_edge, color);
|
||||
}
|
||||
|
||||
if corners.intersects(CornerFlags::TOP) {
|
||||
inner_rect.tr.y -= radius;
|
||||
|
||||
let mut top_edge = Rect {
|
||||
bl: Vec2::new(rect.bl.x, rect.tr.y - radius),
|
||||
tr: rect.tr,
|
||||
};
|
||||
|
||||
if corners.contains(CornerFlags::TOP_LEFT) {
|
||||
top_edge.bl.x += radius;
|
||||
self.draw_quarter_circle(Corner::TopLeft, inset.tl(), radius, color);
|
||||
}
|
||||
|
||||
if corners.contains(CornerFlags::TOP_RIGHT) {
|
||||
top_edge.tr.x -= radius;
|
||||
self.draw_quarter_circle(Corner::TopRight, inset.tr, radius, color);
|
||||
}
|
||||
|
||||
self.draw_rect(top_edge, color);
|
||||
}
|
||||
|
||||
self.draw_rect(inner_rect, color);
|
||||
}
|
||||
|
|
|
@ -11,78 +11,78 @@ pub mod api;
|
|||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default, Pod, Zeroable)]
|
||||
pub struct Rect {
|
||||
pub bl: Vec2,
|
||||
pub tr: Vec2,
|
||||
pub tl: Vec2,
|
||||
pub br: Vec2,
|
||||
}
|
||||
|
||||
impl Rect {
|
||||
pub const NEG_INFINITY: Self = Self {
|
||||
bl: Vec2::splat(f32::INFINITY),
|
||||
tr: Vec2::splat(f32::NEG_INFINITY),
|
||||
tl: Vec2::splat(f32::INFINITY),
|
||||
br: Vec2::splat(f32::NEG_INFINITY),
|
||||
};
|
||||
|
||||
pub fn from_xy_size(xy: Vec2, size: Vec2) -> Self {
|
||||
Self {
|
||||
bl: xy,
|
||||
tr: xy + size,
|
||||
tl: xy,
|
||||
br: xy + size,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_circle_bounds(center: Vec2, radius: f32) -> Self {
|
||||
Self {
|
||||
bl: center - radius,
|
||||
tr: center + radius,
|
||||
tl: center - radius,
|
||||
br: center + radius,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_triangle_bounds(tri: &ColoredTriangle) -> Self {
|
||||
Self {
|
||||
bl: tri.v1.min(tri.v2).min(tri.v3),
|
||||
tr: tri.v1.max(tri.v2).max(tri.v3),
|
||||
tl: tri.v1.min(tri.v2).min(tri.v3),
|
||||
br: tri.v1.max(tri.v2).max(tri.v3),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inset(&self, d: f32) -> Self {
|
||||
Self {
|
||||
bl: self.bl + d,
|
||||
tr: self.tr - d,
|
||||
tl: self.tl + d,
|
||||
br: self.br - d,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tl(&self) -> Vec2 {
|
||||
Vec2::new(self.bl.x, self.tr.y)
|
||||
|
||||
pub fn bl(&self) -> Vec2 {
|
||||
Vec2::new(self.tl.x, self.br.y)
|
||||
}
|
||||
|
||||
pub fn br(&self) -> Vec2 {
|
||||
Vec2::new(self.tr.x, self.bl.y)
|
||||
pub fn tr(&self) -> Vec2 {
|
||||
Vec2::new(self.br.x, self.tl.y)
|
||||
}
|
||||
|
||||
pub fn offset(&self, offset: Vec2) -> Self {
|
||||
Self {
|
||||
bl: self.bl + offset,
|
||||
tr: self.tr + offset,
|
||||
tl: self.tl + offset,
|
||||
br: self.br + offset,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scale(&self, scale: f32) -> Self {
|
||||
Self {
|
||||
bl: self.bl * scale,
|
||||
tr: self.tr * scale,
|
||||
tl: self.tl * scale,
|
||||
br: self.br * scale,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_valid(&self) -> bool {
|
||||
self.bl.cmplt(self.tr).all()
|
||||
self.tl.cmplt(self.br).all()
|
||||
}
|
||||
|
||||
pub fn intersects_rect(&self, other: &Self) -> bool {
|
||||
self.bl.cmple(other.tr).all() && self.tr.cmpge(other.bl).all()
|
||||
self.tl.cmple(other.br).all() && self.br.cmpge(other.tl).all()
|
||||
}
|
||||
|
||||
pub fn intersection(&self, other: &Self) -> Option<Self> {
|
||||
let clipped = Self {
|
||||
bl: self.bl.max(other.bl),
|
||||
tr: self.tr.min(other.tr),
|
||||
tl: self.tl.max(other.tl),
|
||||
br: self.br.min(other.br),
|
||||
};
|
||||
|
||||
if clipped.is_valid() {
|
||||
|
@ -92,27 +92,41 @@ impl Rect {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn union(&self, other: &Self) -> Self {
|
||||
Self {
|
||||
tl: self.tl.min(other.tl),
|
||||
br: self.br.max(other.br),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn union_point(&self, point: Vec2) -> Self {
|
||||
Self {
|
||||
tl: self.tl.min(point),
|
||||
br: self.br.max(point),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn contains_rect(&self, other: &Self) -> bool {
|
||||
self.bl.x < other.bl.x
|
||||
&& self.bl.y < other.bl.y
|
||||
&& self.tr.x > other.tr.x
|
||||
&& self.tr.y > other.tr.y
|
||||
self.tl.x < other.tl.x
|
||||
&& self.tl.y < other.tl.y
|
||||
&& self.br.x > other.br.x
|
||||
&& self.br.y > other.br.y
|
||||
}
|
||||
|
||||
pub fn contains_point(&self, xy: Vec2) -> bool {
|
||||
self.bl.x < xy.x && self.bl.y < xy.y && self.tr.x > xy.x && self.tr.y > xy.y
|
||||
self.tl.x < xy.x && self.tl.y < xy.y && self.br.x > xy.x && self.br.y > xy.y
|
||||
}
|
||||
|
||||
pub fn size(&self) -> Vec2 {
|
||||
self.tr - self.bl
|
||||
self.br - self.tl
|
||||
}
|
||||
|
||||
pub fn width(&self) -> f32 {
|
||||
self.tr.x - self.bl.x
|
||||
self.br.x - self.tl.x
|
||||
}
|
||||
|
||||
pub fn height(&self) -> f32 {
|
||||
self.tr.y - self.bl.y
|
||||
self.br.y - self.tl.y
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -133,26 +133,8 @@ impl OutlineSink {
|
|||
|
||||
fn pf_vector_to_lyon(&mut self, v: &Vector2F) -> lyon::geom::Point<f32> {
|
||||
let point = lyon::geom::Point::<f32>::new(v.x(), -v.y()) / self.units_per_em;
|
||||
|
||||
// TODO clean this up with helper math methods?
|
||||
let bb = &mut self.bounding_box;
|
||||
|
||||
if point.x < bb.bl.x {
|
||||
bb.bl.x = point.x;
|
||||
}
|
||||
|
||||
if point.x > bb.tr.x {
|
||||
bb.tr.x = point.x;
|
||||
}
|
||||
|
||||
if point.y < bb.tr.y {
|
||||
bb.tr.y = point.y;
|
||||
}
|
||||
|
||||
if point.y > bb.bl.y {
|
||||
bb.bl.y = point.y;
|
||||
}
|
||||
|
||||
let glam_point = Vec2::new(point.x, point.y);
|
||||
self.bounding_box = self.bounding_box.union_point(glam_point);
|
||||
point
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,31 +73,9 @@ impl Font {
|
|||
xcur += position.hori_advance;
|
||||
ycur += position.vert_advance;
|
||||
|
||||
let xpos = xpos as f32 / units_per_em;
|
||||
let ypos = ypos as f32 / units_per_em;
|
||||
|
||||
let mut bb = glyphs.get(position.index as usize).unwrap().bounding_box;
|
||||
bb.bl.x = bb.bl.x + xpos;
|
||||
bb.bl.y = bb.bl.y + ypos;
|
||||
bb.tr.x = bb.tr.x + xpos;
|
||||
bb.tr.y = bb.tr.y + ypos;
|
||||
|
||||
// TODO use euclid instead
|
||||
if bounds.bl.x > bb.bl.x {
|
||||
bounds.bl.x = bb.bl.x;
|
||||
}
|
||||
|
||||
if bounds.bl.y > bb.bl.y {
|
||||
bounds.bl.y = bb.bl.y;
|
||||
}
|
||||
|
||||
if bounds.tr.x < bb.tr.x {
|
||||
bounds.tr.x = bb.tr.x;
|
||||
}
|
||||
|
||||
if bounds.tr.y < bb.tr.y {
|
||||
bounds.tr.y = bb.tr.y;
|
||||
}
|
||||
let pos = Vec2::new(xpos as f32, ypos as f32) / units_per_em;
|
||||
let bb = glyphs.get(position.index as usize).unwrap().bounding_box;
|
||||
bounds = bounds.union(&bb.offset(pos));
|
||||
}
|
||||
|
||||
TextLayout {
|
||||
|
|
Loading…
Reference in New Issue