mirror of
https://github.com/rust-windowing/winit.git
synced 2026-09-03 23:30:05 -04:00
win32: Copy icon pixels to BGRA instead of mutating the shared buffer
This commit is contained in:
@@ -20,7 +20,7 @@ use winit_core::icon::*;
|
|||||||
use super::util;
|
use super::util;
|
||||||
use crate::WinIcon;
|
use crate::WinIcon;
|
||||||
|
|
||||||
pub(crate) const PIXEL_SIZE: usize = mem::size_of::<Pixel>();
|
pub(crate) const PIXEL_SIZE: usize = mem::size_of::<u32>();
|
||||||
|
|
||||||
unsafe impl Send for WinIcon {}
|
unsafe impl Send for WinIcon {}
|
||||||
|
|
||||||
@@ -96,14 +96,11 @@ impl WinIcon {
|
|||||||
pub(crate) fn from_rgba(rgba: &RgbaIcon) -> Result<Self, BadIcon> {
|
pub(crate) fn from_rgba(rgba: &RgbaIcon) -> Result<Self, BadIcon> {
|
||||||
let pixel_count = rgba.buffer().len() / PIXEL_SIZE;
|
let pixel_count = rgba.buffer().len() / PIXEL_SIZE;
|
||||||
let mut and_mask = Vec::with_capacity(pixel_count);
|
let mut and_mask = Vec::with_capacity(pixel_count);
|
||||||
let pixels = unsafe {
|
let mut bgra = Vec::with_capacity(rgba.buffer().len());
|
||||||
std::slice::from_raw_parts_mut(rgba.buffer().as_ptr() as *mut Pixel, pixel_count)
|
for pixel in rgba.buffer().chunks_exact(PIXEL_SIZE) {
|
||||||
};
|
and_mask.push(pixel[3].wrapping_sub(u8::MAX)); // invert alpha channel
|
||||||
for pixel in pixels {
|
bgra.extend_from_slice(&[pixel[2], pixel[1], pixel[0], pixel[3]]);
|
||||||
and_mask.push(pixel.a.wrapping_sub(u8::MAX)); // invert alpha channel
|
|
||||||
pixel.convert_to_bgra();
|
|
||||||
}
|
}
|
||||||
assert_eq!(and_mask.len(), pixel_count);
|
|
||||||
let handle = unsafe {
|
let handle = unsafe {
|
||||||
CreateIcon(
|
CreateIcon(
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
@@ -112,7 +109,7 @@ impl WinIcon {
|
|||||||
1,
|
1,
|
||||||
(PIXEL_SIZE * 8) as u8,
|
(PIXEL_SIZE * 8) as u8,
|
||||||
and_mask.as_ptr(),
|
and_mask.as_ptr(),
|
||||||
rgba.buffer().as_ptr(),
|
bgra.as_ptr(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
if !handle.is_null() {
|
if !handle.is_null() {
|
||||||
@@ -135,12 +132,6 @@ impl fmt::Debug for WinIcon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pixel {
|
|
||||||
fn convert_to_bgra(&mut self) {
|
|
||||||
mem::swap(&mut self.r, &mut self.b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum IconType {
|
pub enum IconType {
|
||||||
Small = ICON_SMALL as isize,
|
Small = ICON_SMALL as isize,
|
||||||
@@ -252,12 +243,3 @@ impl RaiiCursor {
|
|||||||
self.handle
|
self.handle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub(crate) struct Pixel {
|
|
||||||
pub(crate) r: u8,
|
|
||||||
pub(crate) g: u8,
|
|
||||||
pub(crate) b: u8,
|
|
||||||
pub(crate) a: u8,
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -117,6 +117,9 @@ changelog entry.
|
|||||||
`DefWindowProc` for normal propagation.
|
`DefWindowProc` for normal propagation.
|
||||||
- On Windows, fix getting the window's DPI internally leaks `HDC` handles.
|
- On Windows, fix getting the window's DPI internally leaks `HDC` handles.
|
||||||
Also only call `GetDC` when on < Windows 8.1 which improves its performance.
|
Also only call `GetDC` when on < Windows 8.1 which improves its performance.
|
||||||
|
- On Windows, fix window icons rendering with red and blue swapped when the same `Icon` is
|
||||||
|
applied more than once (e.g. sharing one icon between the window and the taskbar). The RGBA
|
||||||
|
to BGRA conversion no longer mutates the shared pixel buffer.
|
||||||
- On Redox, handle `EINTR` when reading from `event_socket` instead of panicking.
|
- On Redox, handle `EINTR` when reading from `event_socket` instead of panicking.
|
||||||
- On X11, fix all pointer input being dropped for absolute pointing devices
|
- On X11, fix all pointer input being dropped for absolute pointing devices
|
||||||
without pressure or tilt axes, such as the emulated tablets of
|
without pressure or tilt axes, such as the emulated tablets of
|
||||||
|
|||||||
Reference in New Issue
Block a user