Skip to content

Commit

Permalink
Merge pull request #306 from mahkoh/jorth/fractional-scale-rounding
Browse files Browse the repository at this point in the history
fractional-scale: implement accurate rounding
  • Loading branch information
mahkoh authored Oct 22, 2024
2 parents cc426a0 + e2806a6 commit eff490a
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 14 deletions.
10 changes: 4 additions & 6 deletions src/renderer/renderer_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ impl RendererBase<'_> {

pub fn scale_point(&self, mut x: i32, mut y: i32) -> (i32, i32) {
if self.scaled {
x = (x as f64 * self.scalef).round() as _;
y = (y as f64 * self.scalef).round() as _;
[x, y] = self.scale.pixel_size([x, y]);
}
(x, y)
}
Expand All @@ -46,10 +45,9 @@ impl RendererBase<'_> {

pub fn scale_rect(&self, mut rect: Rect) -> Rect {
if self.scaled {
let x1 = (rect.x1() as f64 * self.scalef).round() as _;
let y1 = (rect.y1() as f64 * self.scalef).round() as _;
let x2 = (rect.x2() as f64 * self.scalef).round() as _;
let y2 = (rect.y2() as f64 * self.scalef).round() as _;
let [x1, y1, x2, y2] =
self.scale
.pixel_size([rect.x1(), rect.y1(), rect.x2(), rect.y2()]);
rect = Rect::new(x1, y1, x2, y2).unwrap();
}
rect
Expand Down
13 changes: 6 additions & 7 deletions src/scale.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::fmt::{Debug, Display, Formatter};

const BASE: u32 = 120;
const BASE64: i64 = BASE as i64;
const BASEF: f64 = BASE as f64;

#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
Expand Down Expand Up @@ -38,15 +39,13 @@ impl Scale {
self.0
}

pub fn pixel_size(self, width: i32, height: i32) -> (i32, i32) {
#[inline(always)]
pub fn pixel_size<const N: usize>(self, v: [i32; N]) -> [i32; N] {
if self == Scale::default() {
return (width, height);
return v;
}
let scale = self.to_f64();
(
(width as f64 * scale).round() as i32,
(height as f64 * scale).round() as i32,
)
let scale = self.0 as i64;
v.map(|v| ((v as i64 * scale + BASE64 / 2) / BASE64) as i32)
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/tree/toplevel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use {
PlaceholderNode, WorkspaceNode,
},
utils::{
array_to_tuple::ArrayToTuple,
clonecell::CloneCell,
copyhashmap::CopyHashMap,
hash_map_ext::HashMapExt,
Expand Down Expand Up @@ -608,7 +609,7 @@ impl ToplevelData {
let (dw, dh) = self.desired_extents.get().size();
if let Some(ws) = self.workspace.get() {
let scale = ws.output.get().global.persistent.scale.get();
return scale.pixel_size(dw, dh);
return scale.pixel_size([dw, dh]).to_tuple();
};
(0, 0)
}
Expand Down
1 change: 1 addition & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod activation_token;
pub mod array;
pub mod array_to_tuple;
pub mod asyncevent;
pub mod bindings;
pub mod bitfield;
Expand Down
28 changes: 28 additions & 0 deletions src/utils/array_to_tuple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
pub trait ArrayToTuple {
type Tuple;

fn to_tuple(self) -> Self::Tuple;
}

macro_rules! ignore {
($t:tt) => {
T
};
}

macro_rules! array_to_tuple {
($n:expr, $($field:ident,)*) => {
impl<T> ArrayToTuple for [T; $n] {
type Tuple = ($(ignore!($field),)*);

fn to_tuple(self) -> Self::Tuple {
let [$($field,)*] = self;
#[allow(clippy::allow_attributes)]
#[allow(clippy::unused_unit)]
($($field,)*)
}
}
};
}

array_to_tuple!(2, t1, t2,);

0 comments on commit eff490a

Please sign in to comment.