mirror of
https://github.com/emilk/egui.git
synced 2026-08-31 05:40:03 -04:00
Track original SVG size (#7098)
This fixes bugs related to how an `Image` follows the size of an SVG. We track the "source size" of each image, i.e. the original width/height of the SVG, which can be different from whatever it was rasterized as.
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
use emath::Vec2;
|
||||
|
||||
use crate::{textures::TextureOptions, Color32};
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -47,18 +49,36 @@ impl ImageData {
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub struct ColorImage {
|
||||
/// width, height.
|
||||
/// width, height in texels.
|
||||
pub size: [usize; 2],
|
||||
|
||||
/// Size of the original SVG image (if any), or just the texel size of the image.
|
||||
pub source_size: Vec2,
|
||||
|
||||
/// The pixels, row by row, from top to bottom.
|
||||
pub pixels: Vec<Color32>,
|
||||
}
|
||||
|
||||
impl ColorImage {
|
||||
/// Create an image filled with the given color.
|
||||
pub fn new(size: [usize; 2], color: Color32) -> Self {
|
||||
pub fn new(size: [usize; 2], pixels: Vec<Color32>) -> Self {
|
||||
debug_assert!(
|
||||
size[0] * size[1] == pixels.len(),
|
||||
"size: {size:?}, pixels.len(): {}",
|
||||
pixels.len()
|
||||
);
|
||||
Self {
|
||||
size,
|
||||
source_size: Vec2::new(size[0] as f32, size[1] as f32),
|
||||
pixels,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an image filled with the given color.
|
||||
pub fn filled(size: [usize; 2], color: Color32) -> Self {
|
||||
Self {
|
||||
size,
|
||||
source_size: Vec2::new(size[0] as f32, size[1] as f32),
|
||||
pixels: vec![color; size[0] * size[1]],
|
||||
}
|
||||
}
|
||||
@@ -105,7 +125,7 @@ impl ColorImage {
|
||||
.chunks_exact(4)
|
||||
.map(|p| Color32::from_rgba_unmultiplied(p[0], p[1], p[2], p[3]))
|
||||
.collect();
|
||||
Self { size, pixels }
|
||||
Self::new(size, pixels)
|
||||
}
|
||||
|
||||
pub fn from_rgba_premultiplied(size: [usize; 2], rgba: &[u8]) -> Self {
|
||||
@@ -120,7 +140,7 @@ impl ColorImage {
|
||||
.chunks_exact(4)
|
||||
.map(|p| Color32::from_rgba_premultiplied(p[0], p[1], p[2], p[3]))
|
||||
.collect();
|
||||
Self { size, pixels }
|
||||
Self::new(size, pixels)
|
||||
}
|
||||
|
||||
/// Create a [`ColorImage`] from flat opaque gray data.
|
||||
@@ -135,7 +155,7 @@ impl ColorImage {
|
||||
gray.len()
|
||||
);
|
||||
let pixels = gray.iter().map(|p| Color32::from_gray(*p)).collect();
|
||||
Self { size, pixels }
|
||||
Self::new(size, pixels)
|
||||
}
|
||||
|
||||
/// Alternative method to `from_gray`.
|
||||
@@ -152,7 +172,7 @@ impl ColorImage {
|
||||
size,
|
||||
pixels.len()
|
||||
);
|
||||
Self { size, pixels }
|
||||
Self::new(size, pixels)
|
||||
}
|
||||
|
||||
/// A view of the underlying data as `&[u8]`
|
||||
@@ -185,14 +205,14 @@ impl ColorImage {
|
||||
.chunks_exact(3)
|
||||
.map(|p| Color32::from_rgb(p[0], p[1], p[2]))
|
||||
.collect();
|
||||
Self { size, pixels }
|
||||
Self::new(size, pixels)
|
||||
}
|
||||
|
||||
/// An example color image, useful for tests.
|
||||
pub fn example() -> Self {
|
||||
let width = 128;
|
||||
let height = 64;
|
||||
let mut img = Self::new([width, height], Color32::TRANSPARENT);
|
||||
let mut img = Self::filled([width, height], Color32::TRANSPARENT);
|
||||
for y in 0..height {
|
||||
for x in 0..width {
|
||||
let h = x as f32 / width as f32;
|
||||
@@ -205,6 +225,13 @@ impl ColorImage {
|
||||
img
|
||||
}
|
||||
|
||||
/// Set the source size of e.g. the original SVG image.
|
||||
#[inline]
|
||||
pub fn with_source_size(mut self, source_size: Vec2) -> Self {
|
||||
self.source_size = source_size;
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn width(&self) -> usize {
|
||||
self.size[0]
|
||||
@@ -242,10 +269,7 @@ impl ColorImage {
|
||||
&self.pixels[row * row_stride + min_x..row * row_stride + max_x],
|
||||
);
|
||||
}
|
||||
Self {
|
||||
size: [width, height],
|
||||
pixels: output,
|
||||
}
|
||||
Self::new([width, height], output)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user