Preserve aspect ratio when scaling images

Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
Nathan Sobo 2021-09-14 16:39:35 -06:00
parent e0e0bdbc3a
commit b63b717eac
3 changed files with 25 additions and 17 deletions

View File

@ -24,7 +24,10 @@ pub use self::{
};
pub use crate::presenter::ChildView;
use crate::{
geometry::{rect::RectF, vector::Vector2F},
geometry::{
rect::RectF,
vector::{vec2f, Vector2F},
},
json, DebugContext, Event, EventContext, LayoutContext, PaintContext, SizeConstraint,
};
use core::panic;
@ -359,3 +362,13 @@ pub trait ParentElement<'a>: Extend<ElementBox> + Sized {
}
impl<'a, T> ParentElement<'a> for T where T: Extend<ElementBox> {}
fn constrain_size_preserving_aspect_ratio(max_size: Vector2F, size: Vector2F) -> Vector2F {
if max_size.x().is_infinite() && max_size.y().is_infinite() {
size
} else if max_size.x().is_infinite() || max_size.x() / max_size.y() > size.x() / size.y() {
vec2f(size.x() * max_size.y() / size.y(), max_size.y())
} else {
vec2f(max_size.x(), size.y() * max_size.x() / size.x())
}
}

View File

@ -6,6 +6,8 @@ use crate::{
};
use std::sync::Arc;
use super::constrain_size_preserving_aspect_ratio;
pub struct Image {
data: Arc<ImageData>,
border: Border,
@ -41,7 +43,9 @@ impl Element for Image {
constraint: SizeConstraint,
_: &mut LayoutContext,
) -> (Vector2F, Self::LayoutState) {
(constraint.max, ())
let size =
constrain_size_preserving_aspect_ratio(constraint.max, self.data.size().to_f32());
(size, ())
}
fn paint(

View File

@ -41,21 +41,10 @@ impl Element for Svg {
) -> (Vector2F, Self::LayoutState) {
match cx.asset_cache.svg(&self.path) {
Ok(tree) => {
let size = if constraint.max.x().is_infinite() && constraint.max.y().is_infinite() {
let rect = from_usvg_rect(tree.svg_node().view_box.rect);
rect.size()
} else {
let max_size = constraint.max;
let svg_size = from_usvg_rect(tree.svg_node().view_box.rect).size();
if max_size.x().is_infinite()
|| max_size.x() / max_size.y() > svg_size.x() / svg_size.y()
{
vec2f(svg_size.x() * max_size.y() / svg_size.y(), max_size.y())
} else {
vec2f(max_size.x(), svg_size.y() * max_size.x() / svg_size.x())
}
};
let size = constrain_size_preserving_aspect_ratio(
constraint.max,
from_usvg_rect(tree.svg_node().view_box.rect).size(),
);
(size, Some(tree))
}
Err(error) => {
@ -111,6 +100,8 @@ impl Element for Svg {
use crate::json::ToJson;
use super::constrain_size_preserving_aspect_ratio;
fn from_usvg_rect(rect: usvg::Rect) -> RectF {
RectF::new(
vec2f(rect.x() as f32, rect.y() as f32),