1
0
Fork 0
forked from wry/wry

Merge pull request #306 from mahkoh/jorth/fractional-scale-rounding

fractional-scale: implement accurate rounding
This commit is contained in:
mahkoh 2024-10-22 11:13:26 +02:00 committed by GitHub
commit eff490a653
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 41 additions and 14 deletions

View file

@ -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)
}
@ -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

View file

@ -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)]
@ -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)
}
}

View file

@ -17,6 +17,7 @@ use {
PlaceholderNode, WorkspaceNode,
},
utils::{
array_to_tuple::ArrayToTuple,
clonecell::CloneCell,
copyhashmap::CopyHashMap,
hash_map_ext::HashMapExt,
@ -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)
}

View file

@ -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;

View file

@ -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,);