Merge pull request #306 from mahkoh/jorth/fractional-scale-rounding
fractional-scale: implement accurate rounding
This commit is contained in:
commit
eff490a653
5 changed files with 41 additions and 14 deletions
|
|
@ -30,8 +30,7 @@ impl RendererBase<'_> {
|
||||||
|
|
||||||
pub fn scale_point(&self, mut x: i32, mut y: i32) -> (i32, i32) {
|
pub fn scale_point(&self, mut x: i32, mut y: i32) -> (i32, i32) {
|
||||||
if self.scaled {
|
if self.scaled {
|
||||||
x = (x as f64 * self.scalef).round() as _;
|
[x, y] = self.scale.pixel_size([x, y]);
|
||||||
y = (y as f64 * self.scalef).round() as _;
|
|
||||||
}
|
}
|
||||||
(x, y)
|
(x, y)
|
||||||
}
|
}
|
||||||
|
|
@ -46,10 +45,9 @@ impl RendererBase<'_> {
|
||||||
|
|
||||||
pub fn scale_rect(&self, mut rect: Rect) -> Rect {
|
pub fn scale_rect(&self, mut rect: Rect) -> Rect {
|
||||||
if self.scaled {
|
if self.scaled {
|
||||||
let x1 = (rect.x1() as f64 * self.scalef).round() as _;
|
let [x1, y1, x2, y2] =
|
||||||
let y1 = (rect.y1() as f64 * self.scalef).round() as _;
|
self.scale
|
||||||
let x2 = (rect.x2() as f64 * self.scalef).round() as _;
|
.pixel_size([rect.x1(), rect.y1(), rect.x2(), rect.y2()]);
|
||||||
let y2 = (rect.y2() as f64 * self.scalef).round() as _;
|
|
||||||
rect = Rect::new(x1, y1, x2, y2).unwrap();
|
rect = Rect::new(x1, y1, x2, y2).unwrap();
|
||||||
}
|
}
|
||||||
rect
|
rect
|
||||||
|
|
|
||||||
13
src/scale.rs
13
src/scale.rs
|
|
@ -1,6 +1,7 @@
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
|
|
||||||
const BASE: u32 = 120;
|
const BASE: u32 = 120;
|
||||||
|
const BASE64: i64 = BASE as i64;
|
||||||
const BASEF: f64 = BASE as f64;
|
const BASEF: f64 = BASE as f64;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
|
|
@ -38,15 +39,13 @@ impl Scale {
|
||||||
self.0
|
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() {
|
if self == Scale::default() {
|
||||||
return (width, height);
|
return v;
|
||||||
}
|
}
|
||||||
let scale = self.to_f64();
|
let scale = self.0 as i64;
|
||||||
(
|
v.map(|v| ((v as i64 * scale + BASE64 / 2) / BASE64) as i32)
|
||||||
(width as f64 * scale).round() as i32,
|
|
||||||
(height as f64 * scale).round() as i32,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ use {
|
||||||
PlaceholderNode, WorkspaceNode,
|
PlaceholderNode, WorkspaceNode,
|
||||||
},
|
},
|
||||||
utils::{
|
utils::{
|
||||||
|
array_to_tuple::ArrayToTuple,
|
||||||
clonecell::CloneCell,
|
clonecell::CloneCell,
|
||||||
copyhashmap::CopyHashMap,
|
copyhashmap::CopyHashMap,
|
||||||
hash_map_ext::HashMapExt,
|
hash_map_ext::HashMapExt,
|
||||||
|
|
@ -608,7 +609,7 @@ impl ToplevelData {
|
||||||
let (dw, dh) = self.desired_extents.get().size();
|
let (dw, dh) = self.desired_extents.get().size();
|
||||||
if let Some(ws) = self.workspace.get() {
|
if let Some(ws) = self.workspace.get() {
|
||||||
let scale = ws.output.get().global.persistent.scale.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)
|
(0, 0)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
pub mod activation_token;
|
pub mod activation_token;
|
||||||
pub mod array;
|
pub mod array;
|
||||||
|
pub mod array_to_tuple;
|
||||||
pub mod asyncevent;
|
pub mod asyncevent;
|
||||||
pub mod bindings;
|
pub mod bindings;
|
||||||
pub mod bitfield;
|
pub mod bitfield;
|
||||||
|
|
|
||||||
28
src/utils/array_to_tuple.rs
Normal file
28
src/utils/array_to_tuple.rs
Normal 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,);
|
||||||
Loading…
Add table
Add a link
Reference in a new issue