mirror of
https://github.com/penpot/penpot.git
synced 2025-07-19 14:27:21 +02:00
🐛 Fix keep aspect ratio support
This commit is contained in:
parent
327db5a1a3
commit
c7c8e91183
4 changed files with 52 additions and 26 deletions
|
@ -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,
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue