Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 54 additions & 5 deletions crates/egui/src/widgets/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use epaint::{
};

use crate::{
Color32, Context, CornerRadius, Id, Mesh, Painter, Rect, Response, Sense, Shape, Spinner,
Color32, Context, CornerRadius, Id, Mesh, Painter, Pos2, Rect, Response, Sense, Shape, Spinner,
TextStyle, TextureOptions, Ui, Vec2, Widget, WidgetInfo, WidgetType,
load::{Bytes, SizeHint, SizedTexture, TextureLoadResult, TexturePoll},
pos2,
Expand Down Expand Up @@ -298,12 +298,19 @@ impl<'a> Image<'a> {
#[inline]
pub fn calc_size(&self, available_size: Vec2, image_source_size: Option<Vec2>) -> Vec2 {
let image_source_size = image_source_size.unwrap_or(Vec2::splat(24.0)); // Fallback for still-loading textures, or failure to load.
self.size.calc_size(available_size, image_source_size)
self.size.calc_size(
available_size,
image_source_size,
self.image_options.rotation,
)
}

pub fn load_and_calc_size(&self, ui: &Ui, available_size: Vec2) -> Option<Vec2> {
let image_size = self.load_for_size(ui.ctx(), available_size).ok()?.size()?;
Some(self.size.calc_size(available_size, image_size))
Some(
self.size
.calc_size(available_size, image_size, self.image_options.rotation),
)
}

#[inline]
Expand Down Expand Up @@ -524,13 +531,28 @@ impl ImageSize {
}

/// Calculate the final on-screen size in points.
pub fn calc_size(&self, available_size: Vec2, image_source_size: Vec2) -> Vec2 {
pub fn calc_size(
&self,
available_size: Vec2,
image_source_size: Vec2,
rotation: Option<(Rot2, Vec2)>,
) -> Vec2 {
let image_source_size = match rotation {
Some((rot, _origin)) => {
let Vec2 { x, y } = rot * image_source_size;
Vec2 {
x: x.abs(),
y: y.abs(),
}
}
None => image_source_size,
};
let Self {
maintain_aspect_ratio,
max_size,
fit,
} = *self;
match fit {
let final_size = match fit {
ImageFit::Original { scale } => {
let image_size = scale * image_source_size;
if image_size.x <= max_size.x && image_size.y <= max_size.y {
Expand All @@ -547,6 +569,16 @@ impl ImageSize {
let scale_to_size = size.min(max_size);
scale_to_fit(image_source_size, scale_to_size, maintain_aspect_ratio)
}
};
match rotation {
Some((rot, _origin)) => {
let Vec2 { x, y } = rot.inverse() * final_size;
Vec2 {
x: x.abs(),
y: y.abs(),
}
}
None => final_size,
}
}
}
Expand Down Expand Up @@ -873,7 +905,24 @@ pub fn paint_texture_at(

let mut mesh = Mesh::with_texture(texture.id);
mesh.add_rect_with_uv(rect, options.uv, options.tint);
let Rect {
min:
Pos2 {
x: orig_xmin,
y: orig_ymin,
},
..
} = mesh.calc_bounds();
mesh.rotate(rot, rect.min + origin * rect.size());
let Rect {
min: Pos2 { x: xmin, y: ymin },
..
} = mesh.calc_bounds();
// Preserve coordinates of top-left
mesh.translate(Vec2 {
x: -xmin + orig_xmin,
y: -ymin + orig_ymin,
});
painter.add(Shape::mesh(mesh));
}
None => {
Expand Down
Loading