1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-23 23:21:08 +03:00

use euclid crate for point/rect

This commit is contained in:
Wez Furlong 2019-09-21 13:05:50 -07:00
parent c7c25025ed
commit 709990b9e7
3 changed files with 42 additions and 126 deletions

View File

@ -1,5 +1,5 @@
use crate::bitmaps::{BitmapImage, Texture2d};
use crate::{Point, Rect};
use crate::{Point, Rect, Size};
use failure::{ensure, Fallible};
use failure_derive::*;
use std::rc::Rc;
@ -88,14 +88,10 @@ impl Atlas {
});
}
let rect = Rect {
top_left: Point {
x: self.left as isize + 1,
y: self.bottom as isize + 1,
},
width,
height,
};
let rect = Rect::new(
Point::new(self.left as isize + 1, self.bottom as isize + 1),
Size::new(width as isize, height as isize),
);
self.texture.write(rect, im);
@ -139,7 +135,7 @@ impl Sprite {
/// This is 0 for the first slice and increases by the slice_width
/// as we work through the slices.
pub fn left_pix(&self, slice: &SpriteSlice) -> f32 {
let width = self.coords.width as f32 * slice.scale;
let width = self.coords.size.width as f32 * slice.scale;
if slice.num_cells == 1 || slice.cell_idx == 0 {
0.0
} else {
@ -162,7 +158,7 @@ impl Sprite {
/// This is nominally the cell_width but can be modified by being the first
/// or last in a sequence of potentially oversized sprite slices.
pub fn slice_width(&self, slice: &SpriteSlice) -> f32 {
let width = self.coords.width as f32 * slice.scale;
let width = self.coords.size.width as f32 * slice.scale;
if slice.num_cells == 1 {
width
@ -182,14 +178,14 @@ impl Sprite {
/// Returns the left coordinate for a slice in texture coordinate space
#[inline]
pub fn left(&self, slice: &SpriteSlice) -> f32 {
let left = self.coords.left() as f32 + (self.left_pix(slice) / slice.scale);
let left = self.coords.min_x() as f32 + (self.left_pix(slice) / slice.scale);
left / self.texture.width() as f32
}
/// Returns the right coordinate for a slice in texture coordinate space
#[inline]
pub fn right(&self, slice: &SpriteSlice) -> f32 {
let right = self.coords.left() as f32
let right = self.coords.min_x() as f32
+ ((self.left_pix(slice) + self.slice_width(slice)) as f32 / slice.scale);
right / self.texture.width() as f32
}
@ -197,13 +193,14 @@ impl Sprite {
/// Returns the top coordinate for a slice in texture coordinate space
#[inline]
pub fn top(&self, _slice: &SpriteSlice) -> f32 {
self.coords.bottom() as f32 / self.texture.height() as f32
self.coords.max_y() as f32 / self.texture.height() as f32
}
/// Returns the bottom coordinate for a slice in texture coordinate space
#[inline]
pub fn bottom(&self, _slice: &SpriteSlice) -> f32 {
(self.coords.bottom() + self.coords.height as isize) as f32 / self.texture.height() as f32
(self.coords.max_y() + self.coords.size.height as isize) as f32
/ self.texture.height() as f32
}
/// Returns the top-left coordinate for a slice in texture coordinate space

View File

@ -1,5 +1,5 @@
use crate::color::Color;
use crate::{Operator, Point, Rect};
use crate::{Operator, Point, Rect, Size};
use palette::Srgba;
pub mod atlas;
@ -95,11 +95,11 @@ pub trait BitmapImage {
fn clear_rect(&mut self, rect: Rect, color: Color) {
let (dim_width, dim_height) = self.image_dimensions();
let max_x = (rect.top_left.x + rect.width as isize).min(dim_width as isize) as usize;
let max_y = (rect.top_left.y + rect.height as isize).min(dim_height as isize) as usize;
let max_x = (rect.origin.x + rect.size.width as isize).min(dim_width as isize) as usize;
let max_y = (rect.origin.y + rect.size.height as isize).min(dim_height as isize) as usize;
let dest_x = rect.top_left.x.max(0) as usize;
let dest_y = rect.top_left.y.max(0) as usize;
let dest_x = rect.origin.x.max(0) as usize;
let dest_y = rect.origin.y.max(0) as usize;
for y in dest_y..max_y {
let range = self.horizontal_pixel_range_mut(dest_x, max_x, y);
@ -137,42 +137,30 @@ pub trait BitmapImage {
/// Draw a 1-pixel wide rectangle
fn draw_rect(&mut self, rect: Rect, color: Color, operator: Operator) {
let bottom_right = rect.bottom_right();
let bottom_right = rect.origin.add_size(&rect.size);
// Draw the vertical lines down either side
self.draw_line(
rect.top_left,
Point {
x: rect.top_left.x,
y: bottom_right.y,
},
rect.origin,
Point::new(rect.origin.x, bottom_right.y),
color,
operator,
);
self.draw_line(
Point {
x: bottom_right.x,
y: rect.top_left.y,
},
Point::new(bottom_right.x, rect.origin.y),
bottom_right,
color,
operator,
);
// And the horizontals for the top and bottom
self.draw_line(
rect.top_left,
Point {
x: bottom_right.x,
y: rect.top_left.y,
},
rect.origin,
Point::new(bottom_right.x, rect.origin.y),
color,
operator,
);
self.draw_line(
Point {
x: rect.top_left.x,
y: bottom_right.y,
},
Point::new(rect.origin.x, bottom_right.y),
bottom_right,
color,
operator,
@ -187,31 +175,30 @@ pub trait BitmapImage {
operator: Operator,
) {
let (im_width, im_height) = im.image_dimensions();
let src_rect = src_rect.unwrap_or_else(|| Rect {
top_left: Point { x: 0, y: 0 },
width: im_width,
height: im_height,
});
let src_rect = src_rect
.unwrap_or_else(|| Rect::from_size(Size::new(im_width as isize, im_height as isize)));
let (dim_width, dim_height) = self.image_dimensions();
debug_assert!(src_rect.width <= im_width && src_rect.height <= im_height);
for y in src_rect.top_left.y as usize..src_rect.top_left.y as usize + src_rect.height {
let dest_y = y as isize + dest_top_left.y - src_rect.top_left.y as isize;
debug_assert!(
src_rect.size.width <= im_width as isize && src_rect.size.height <= im_height as isize
);
for y in src_rect.origin.y..src_rect.origin.y + src_rect.size.height {
let dest_y = y as isize + dest_top_left.y - src_rect.origin.y as isize;
if dest_y < 0 {
continue;
}
if dest_y as usize >= dim_height {
break;
}
for x in src_rect.top_left.x as usize..src_rect.top_left.x as usize + src_rect.width {
let dest_x = x as isize + dest_top_left.x - src_rect.top_left.x as isize;
for x in src_rect.origin.x..src_rect.origin.x + src_rect.size.width {
let dest_x = x as isize + dest_top_left.x - src_rect.origin.x as isize;
if dest_x < 0 {
continue;
}
if dest_x as usize >= dim_width {
break;
}
let src = Color(*im.pixel(x, y));
let src = Color(*im.pixel(x as usize, y as usize));
let dst = self.pixel_mut(dest_x as usize, dest_y as usize);
*dst = src.composite(Color(*dst), &operator).0;
}

View File

@ -43,77 +43,10 @@ pub struct Dimensions {
pub dpi: usize,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub struct Point {
pub x: isize,
pub y: isize,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub struct Rect {
pub top_left: Point,
pub width: usize,
pub height: usize,
}
fn value_in_range(value: isize, min: isize, max: isize) -> bool {
value >= min && value <= max
}
impl Rect {
#[inline]
pub fn bottom_right(&self) -> Point {
Point {
x: self.right(),
y: self.bottom(),
}
}
#[inline]
pub fn left(&self) -> isize {
self.top_left.x
}
#[inline]
pub fn top(&self) -> isize {
self.top_left.y
}
#[inline]
pub fn right(&self) -> isize {
self.top_left.x + self.width as isize
}
#[inline]
pub fn bottom(&self) -> isize {
self.top_left.y + self.height as isize
}
pub fn enclosing_boundary_with(&self, other: &Rect) -> Self {
let left = self.left().min(other.left());
let right = self.right().max(other.right());
let top = self.top().min(other.top());
let bottom = self.bottom().max(other.bottom());
Self {
top_left: Point { x: left, y: top },
width: (right - left as isize) as usize,
height: (bottom - top as isize) as usize,
}
}
// https://stackoverflow.com/a/306379/149111
pub fn intersects_with(&self, other: &Rect) -> bool {
let x_overlaps = value_in_range(self.left(), other.left(), other.right())
|| value_in_range(other.left(), self.left(), self.right());
let y_overlaps = value_in_range(self.top(), other.top(), other.bottom())
|| value_in_range(other.top(), self.top(), self.bottom());
x_overlaps && y_overlaps
}
}
pub struct PixelUnit;
pub type Point = euclid::Point2D<isize, PixelUnit>;
pub type Rect = euclid::Rect<isize, PixelUnit>;
pub type Size = euclid::Size2D<isize, PixelUnit>;
pub trait PaintContext {
fn get_dimensions(&self) -> Dimensions;
@ -122,11 +55,10 @@ pub trait PaintContext {
fn clear(&mut self, color: Color) {
let dims = self.get_dimensions();
self.clear_rect(
Rect {
top_left: Point { x: 0, y: 0 },
width: dims.pixel_width,
height: dims.pixel_height,
},
Rect::from_size(Size::new(
dims.pixel_width as isize,
dims.pixel_height as isize,
)),
color,
);
}