-
Notifications
You must be signed in to change notification settings - Fork 644
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
swrenderer: refactor image drawing algorithm
For tiling, we will need to know the actual source size in addition to the scaling factor that can be different. So store the scaling factors in the scene command, as well as an offset where to start. This is more accurate in case of clipping and rotation. For rotation that doesn't matter (appart from the fact that the testing can now be more strict) But for clipping this prevent glitches with partial rendering where it would seem like the image are moving a bit by a pixel when it is redrawn with a different clip
- Loading branch information
Showing
8 changed files
with
309 additions
and
167 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
// Copyright © SixtyFPS GmbH <info@slint.dev> | ||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial | ||
|
||
/// A Fixed point, represented with the T underlying type, and shifted by so many bits | ||
#[derive(Default, Clone, Copy, Debug)] | ||
pub struct Fixed<T, const SHIFT: usize>(T); | ||
|
||
impl< | ||
T: Copy | ||
+ core::ops::Shl<usize, Output = T> | ||
+ core::ops::Shr<usize, Output = T> | ||
+ core::ops::Div<Output = T> | ||
+ core::ops::Add<Output = T> | ||
+ core::ops::Rem<Output = T>, | ||
const SHIFT: usize, | ||
> Fixed<T, SHIFT> | ||
{ | ||
/// Create a fixed point from an integer value | ||
pub fn from_integer(value: T) -> Self { | ||
Self(value << SHIFT) | ||
} | ||
|
||
/// Get the integer part of the fixed point value | ||
pub fn truncate(self) -> T { | ||
self.0 >> SHIFT | ||
} | ||
|
||
pub fn from_fixed< | ||
T2: core::ops::Shl<usize, Output = T2> + core::ops::Shr<usize, Output = T2> + Into<T>, | ||
const SHIFT2: usize, | ||
>( | ||
value: Fixed<T2, SHIFT2>, | ||
) -> Self { | ||
if SHIFT > SHIFT2 { | ||
let s: T = value.0.into(); | ||
Self(s << (SHIFT - SHIFT2)) | ||
} else { | ||
Self((value.0 >> (SHIFT2 - SHIFT)).into()) | ||
} | ||
} | ||
pub fn try_from_fixed< | ||
T2: core::ops::Shl<usize, Output = T2> + core::ops::Shr<usize, Output = T2> + TryInto<T>, | ||
const SHIFT2: usize, | ||
>( | ||
value: Fixed<T2, SHIFT2>, | ||
) -> Result<Self, T2::Error> { | ||
Ok(if SHIFT > SHIFT2 { | ||
let s: T = value.0.try_into()?; | ||
Self(s << (SHIFT - SHIFT2)) | ||
} else { | ||
Self((value.0 >> (SHIFT2 - SHIFT)).try_into()?) | ||
}) | ||
} | ||
|
||
pub(crate) fn from_f32(value: f32) -> Option<Self> | ||
where | ||
T: num_traits::FromPrimitive, | ||
{ | ||
Some(Self(T::from_f32(value * (1 << SHIFT) as f32)?)) | ||
} | ||
} | ||
|
||
impl<T: core::ops::Add<Output = T>, const SHIFT: usize> core::ops::Add for Fixed<T, SHIFT> { | ||
type Output = Self; | ||
fn add(self, rhs: Self) -> Self::Output { | ||
Self(self.0.add(rhs.0)) | ||
} | ||
} | ||
|
||
impl<T: core::ops::Sub<Output = T>, const SHIFT: usize> core::ops::Sub for Fixed<T, SHIFT> { | ||
type Output = Self; | ||
fn sub(self, rhs: Self) -> Self::Output { | ||
Self(self.0.sub(rhs.0)) | ||
} | ||
} | ||
|
||
impl<T: core::ops::AddAssign, const SHIFT: usize> core::ops::AddAssign for Fixed<T, SHIFT> { | ||
fn add_assign(&mut self, rhs: Self) { | ||
self.0.add_assign(rhs.0) | ||
} | ||
} | ||
|
||
impl<T: core::ops::SubAssign, const SHIFT: usize> core::ops::SubAssign for Fixed<T, SHIFT> { | ||
fn sub_assign(&mut self, rhs: Self) { | ||
self.0.sub_assign(rhs.0) | ||
} | ||
} | ||
|
||
impl<T: core::ops::Mul<Output = T>, const SHIFT: usize> core::ops::Mul<T> for Fixed<T, SHIFT> { | ||
type Output = Self; | ||
fn mul(self, rhs: T) -> Self::Output { | ||
Self(self.0.mul(rhs)) | ||
} | ||
} | ||
|
||
impl<T: core::ops::Neg<Output = T>, const SHIFT: usize> core::ops::Neg for Fixed<T, SHIFT> { | ||
type Output = Self; | ||
fn neg(self) -> Self::Output { | ||
Self(-self.0) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file modified
BIN
+22 Bytes
(100%)
tests/screenshots/references/software/basic/border-image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters