Make `Image::paint_at` pixel-perfect crisp for SVG images (#7078)
This commit is contained in:
parent
b8334f365b
commit
ec8b41f7ec
|
|
@ -3114,6 +3114,8 @@ impl Context {
|
|||
));
|
||||
let max_preview_size = vec2(48.0, 32.0);
|
||||
|
||||
let pixels_per_point = self.pixels_per_point();
|
||||
|
||||
ui.group(|ui| {
|
||||
ScrollArea::vertical()
|
||||
.max_height(300.0)
|
||||
|
|
@ -3128,15 +3130,16 @@ impl Context {
|
|||
.show(ui, |ui| {
|
||||
for (&texture_id, meta) in textures {
|
||||
let [w, h] = meta.size;
|
||||
let point_size = vec2(w as f32, h as f32) / pixels_per_point;
|
||||
|
||||
let mut size = vec2(w as f32, h as f32);
|
||||
let mut size = point_size;
|
||||
size *= (max_preview_size.x / size.x).min(1.0);
|
||||
size *= (max_preview_size.y / size.y).min(1.0);
|
||||
ui.image(SizedTexture::new(texture_id, size))
|
||||
.on_hover_ui(|ui| {
|
||||
// show larger on hover
|
||||
let max_size = 0.5 * ui.ctx().screen_rect().size();
|
||||
let mut size = vec2(w as f32, h as f32);
|
||||
let mut size = point_size;
|
||||
size *= max_size.x / size.x.max(max_size.x);
|
||||
size *= max_size.y / size.y.max(max_size.y);
|
||||
ui.image(SizedTexture::new(texture_id, size));
|
||||
|
|
|
|||
|
|
@ -413,6 +413,8 @@ pub trait ImageLoader {
|
|||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct SizedTexture {
|
||||
pub id: TextureId,
|
||||
|
||||
/// Size in logical ui points.
|
||||
pub size: Vec2,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::{borrow::Cow, slice::Iter, sync::Arc, time::Duration};
|
||||
|
||||
use emath::{Align, Float as _, Rot2};
|
||||
use emath::{Align, Float as _, GuiRounding as _, NumExt as _, Rot2};
|
||||
use epaint::{
|
||||
text::{LayoutJob, TextFormat, TextWrapping},
|
||||
RectShape,
|
||||
|
|
@ -373,9 +373,23 @@ impl<'a> Image<'a> {
|
|||
/// ```
|
||||
#[inline]
|
||||
pub fn paint_at(&self, ui: &Ui, rect: Rect) {
|
||||
let pixels_per_point = ui.pixels_per_point();
|
||||
|
||||
let rect = rect.round_to_pixels(pixels_per_point);
|
||||
|
||||
// Load exactly the size of the rectangle we are painting to.
|
||||
// This is important for getting crisp SVG:s.
|
||||
let pixel_size = (pixels_per_point * rect.size()).round();
|
||||
|
||||
let texture = self.source(ui.ctx()).clone().load(
|
||||
ui.ctx(),
|
||||
self.texture_options,
|
||||
SizeHint::Size(pixel_size.x as _, pixel_size.y as _),
|
||||
);
|
||||
|
||||
paint_texture_load_result(
|
||||
ui,
|
||||
&self.load_for_size(ui.ctx(), rect.size()),
|
||||
&texture,
|
||||
rect,
|
||||
self.show_loading_spinner,
|
||||
&self.image_options,
|
||||
|
|
@ -467,19 +481,24 @@ impl ImageFit {
|
|||
impl ImageSize {
|
||||
/// Size hint for e.g. rasterizing an svg.
|
||||
pub fn hint(&self, available_size: Vec2, pixels_per_point: f32) -> SizeHint {
|
||||
let size = match self.fit {
|
||||
ImageFit::Original { scale } => return SizeHint::Scale(scale.ord()),
|
||||
let point_size = match self.fit {
|
||||
ImageFit::Original { scale } => {
|
||||
return SizeHint::Scale((pixels_per_point * scale).ord())
|
||||
}
|
||||
ImageFit::Fraction(fract) => available_size * fract,
|
||||
ImageFit::Exact(size) => size,
|
||||
};
|
||||
let size = size.min(self.max_size);
|
||||
let size = size * pixels_per_point;
|
||||
let point_size = point_size.at_most(self.max_size);
|
||||
|
||||
let pixel_size = pixels_per_point * point_size;
|
||||
|
||||
// `inf` on an axis means "any value"
|
||||
match (size.x.is_finite(), size.y.is_finite()) {
|
||||
(true, true) => SizeHint::Size(size.x.round() as u32, size.y.round() as u32),
|
||||
(true, false) => SizeHint::Width(size.x.round() as u32),
|
||||
(false, true) => SizeHint::Height(size.y.round() as u32),
|
||||
match (pixel_size.x.is_finite(), pixel_size.y.is_finite()) {
|
||||
(true, true) => {
|
||||
SizeHint::Size(pixel_size.x.round() as u32, pixel_size.y.round() as u32)
|
||||
}
|
||||
(true, false) => SizeHint::Width(pixel_size.x.round() as u32),
|
||||
(false, true) => SizeHint::Height(pixel_size.y.round() as u32),
|
||||
(false, false) => SizeHint::Scale(pixels_per_point.ord()),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue