🐛 Fix keep aspect ratio support

This commit is contained in:
Alejandro Alonso 2025-05-26 11:04:10 +02:00 committed by Alonso Torres
parent 327db5a1a3
commit c7c8e91183
4 changed files with 52 additions and 26 deletions

View file

@ -23,14 +23,18 @@ fn draw_image_fill(
let width = size.0 as f32; let width = size.0 as f32;
let height = size.1 as f32; let height = size.1 as f32;
let image_aspect_ratio = width / height;
// Container size // Container size
let container_width = container.width(); let container_width = container.width();
let container_height = container.height(); let container_height = container.height();
let container_aspect_ratio = container_width / container_height;
let mut scaled_width = container_width;
let mut scaled_height = container_height;
if image_fill.keep_aspect_ratio() {
// Calculate scale to ensure the image covers the container // Calculate scale to ensure the image covers the container
let image_aspect_ratio = width / height;
let container_aspect_ratio = container_width / container_height;
let scale = if image_aspect_ratio > container_aspect_ratio { let scale = if image_aspect_ratio > container_aspect_ratio {
// Image is wider, scale based on height to cover container // Image is wider, scale based on height to cover container
container_height / height container_height / height
@ -38,10 +42,10 @@ fn draw_image_fill(
// Image is taller, scale based on width to cover container // Image is taller, scale based on width to cover container
container_width / width container_width / width
}; };
// Scaled size of the image // Scaled size of the image
let scaled_width = width * scale; scaled_width = width * scale;
let scaled_height = height * scale; scaled_height = height * scale;
}
let dest_rect = MathRect::from_xywh( let dest_rect = MathRect::from_xywh(
container.left - (scaled_width - container_width) / 2.0, container.left - (scaled_width - container_width) / 2.0,

View file

@ -326,23 +326,33 @@ fn draw_triangle_cap(
canvas.draw_path(&path, paint); canvas.draw_path(&path, paint);
} }
fn calculate_scaled_rect(size: (i32, i32), container: &Rect, delta: f32) -> Rect { fn calculate_scaled_rect(
size: (i32, i32),
container: &Rect,
delta: f32,
keep_aspect_ratio: bool,
) -> Rect {
let (width, height) = (size.0 as f32, size.1 as f32); let (width, height) = (size.0 as f32, size.1 as f32);
let image_aspect_ratio = width / height;
// Container size // Container size
let container_width = container.width(); let container_width = container.width();
let container_height = container.height(); let container_height = container.height();
let container_aspect_ratio = container_width / container_height;
let mut scaled_width = container_width;
let mut scaled_height = container_height;
if keep_aspect_ratio {
let image_aspect_ratio = width / height;
let container_aspect_ratio = container_width / container_height;
let scale = if image_aspect_ratio > container_aspect_ratio { let scale = if image_aspect_ratio > container_aspect_ratio {
container_height / height container_height / height
} else { } else {
container_width / width container_width / width
}; };
let scaled_width = width * scale; scaled_width = width * scale;
let scaled_height = height * scale; scaled_height = height * scale;
}
Rect::from_xywh( Rect::from_xywh(
container.left - delta - (scaled_width - container_width) / 2.0, container.left - delta - (scaled_width - container_width) / 2.0,
@ -457,7 +467,12 @@ fn draw_image_stroke_in_container(
image_paint.set_anti_alias(antialias); image_paint.set_anti_alias(antialias);
// Compute scaled rect and clip to it // Compute scaled rect and clip to it
let dest_rect = calculate_scaled_rect(size, container, stroke.delta()); let dest_rect = calculate_scaled_rect(
size,
container,
stroke.delta(),
image_fill.keep_aspect_ratio(),
);
canvas.clip_rect(dest_rect, skia::ClipOp::Intersect, antialias); canvas.clip_rect(dest_rect, skia::ClipOp::Intersect, antialias);
canvas.draw_image_rect_with_sampling_options( canvas.draw_image_rect_with_sampling_options(
image.unwrap(), image.unwrap(),

View file

@ -101,15 +101,17 @@ pub struct ImageFill {
opacity: u8, opacity: u8,
width: i32, width: i32,
height: i32, height: i32,
keep_aspect_ratio: bool,
} }
impl ImageFill { impl ImageFill {
pub fn new(id: Uuid, opacity: u8, width: i32, height: i32) -> Self { pub fn new(id: Uuid, opacity: u8, width: i32, height: i32, keep_aspect_ratio: bool) -> Self {
Self { Self {
id, id,
opacity, opacity,
width, width,
height, height,
keep_aspect_ratio,
} }
} }
@ -124,6 +126,10 @@ impl ImageFill {
pub fn opacity(&self) -> u8 { pub fn opacity(&self) -> u8 {
self.opacity self.opacity
} }
pub fn keep_aspect_ratio(&self) -> bool {
self.keep_aspect_ratio
}
} }
#[derive(Debug, Clone, PartialEq, Copy)] #[derive(Debug, Clone, PartialEq, Copy)]

View file

@ -18,6 +18,7 @@ impl From<RawImageFillData> for ImageFill {
let id = uuid_from_u32_quartet(value.a, value.b, value.c, value.d); let id = uuid_from_u32_quartet(value.a, value.b, value.c, value.d);
let opacity = (value.opacity * 255.).floor() as u8; let opacity = (value.opacity * 255.).floor() as u8;
Self::new(id, opacity, value.width, value.height) // TODO: read keep_aspect_ratio from RawImageFillData when implemented
Self::new(id, opacity, value.width, value.height, true)
} }
} }