mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 04:57:44 +00:00
LibWeb: Add object-fit support to HTMLImageElement
This patch adds handling of the 'object-fit' CSS property to the painting of HTML Image Elements. This is achieved by first calculating the rect which the image would need if it were to fully expand into open space and then adequately cropping it to fit into the image's box. scale-down is not supported for now.
This commit is contained in:
parent
5fc6bff582
commit
8709369d43
1 changed files with 65 additions and 2 deletions
|
@ -64,8 +64,71 @@ void ImagePaintable::paint(PaintContext& context, PaintPhase phase) const
|
|||
context.painter().draw_text(enclosing_rect, alt, Gfx::TextAlignment::Center, computed_values().color(), Gfx::TextElision::Right);
|
||||
} else if (auto bitmap = layout_box().image_provider().current_image_bitmap(image_rect.size().to_type<int>())) {
|
||||
ScopedCornerRadiusClip corner_clip { context, context.painter(), image_rect, normalized_border_radii_data(ShrinkRadiiForBorders::Yes) };
|
||||
auto scaling_mode = to_gfx_scaling_mode(computed_values().image_rendering(), bitmap->rect(), image_rect.to_type<int>());
|
||||
context.painter().draw_scaled_bitmap(image_rect.to_type<int>(), *bitmap, bitmap->rect(), 1.f, scaling_mode);
|
||||
auto image_int_rect = image_rect.to_type<int>();
|
||||
auto bitmap_rect = bitmap->rect();
|
||||
auto scaling_mode = to_gfx_scaling_mode(computed_values().image_rendering(), bitmap_rect, image_int_rect);
|
||||
auto& dom_element = verify_cast<DOM::Element>(*dom_node());
|
||||
auto object_fit = dom_element.computed_css_values()->object_fit();
|
||||
auto bitmap_aspect_ratio = bitmap_rect.height() / bitmap_rect.width();
|
||||
auto image_aspect_ratio = (float)image_rect.height().value() / image_rect.width().value();
|
||||
|
||||
auto scale_x = 0.0f;
|
||||
auto scale_y = 0.0f;
|
||||
Gfx::IntRect bitmap_intersect = bitmap_rect;
|
||||
|
||||
auto object_fit_value = CSS::InitialValues::object_fit();
|
||||
|
||||
if (object_fit.has_value())
|
||||
object_fit_value = object_fit.value();
|
||||
|
||||
switch (object_fit_value) {
|
||||
case CSS::ObjectFit::Fill:
|
||||
scale_x = (float)image_int_rect.width() / bitmap_rect.width();
|
||||
scale_y = (float)image_int_rect.height() / bitmap_rect.height();
|
||||
bitmap_intersect = bitmap_rect;
|
||||
break;
|
||||
case CSS::ObjectFit::Contain:
|
||||
if (bitmap_aspect_ratio >= image_aspect_ratio) {
|
||||
scale_x = (float)image_int_rect.height() / bitmap_rect.height();
|
||||
scale_y = scale_x;
|
||||
} else {
|
||||
scale_x = (float)image_int_rect.width() / bitmap_rect.width();
|
||||
scale_y = scale_x;
|
||||
}
|
||||
break;
|
||||
case CSS::ObjectFit::Cover:
|
||||
if (bitmap_aspect_ratio >= image_aspect_ratio) {
|
||||
scale_x = (float)image_int_rect.width() / bitmap_rect.width();
|
||||
scale_y = scale_x;
|
||||
bitmap_intersect.set_height(bitmap_rect.width() * image_aspect_ratio);
|
||||
} else {
|
||||
scale_x = (float)image_int_rect.height() / bitmap_rect.height();
|
||||
scale_y = scale_x;
|
||||
bitmap_intersect.set_width(bitmap_rect.height() / image_aspect_ratio);
|
||||
}
|
||||
break;
|
||||
case CSS::ObjectFit::ScaleDown:
|
||||
// FIXME: Implement
|
||||
case CSS::ObjectFit::None:
|
||||
scale_x = 1;
|
||||
scale_y = 1;
|
||||
bitmap_intersect.set_size(image_int_rect.size());
|
||||
}
|
||||
|
||||
bitmap_intersect.set_x((bitmap_rect.width() - bitmap_intersect.width()) / 2);
|
||||
bitmap_intersect.set_y((bitmap_rect.height() - bitmap_intersect.height()) / 2);
|
||||
|
||||
auto offset_x = (image_int_rect.width() - bitmap_rect.width() * scale_x) / 2;
|
||||
auto offset_y = (image_int_rect.height() - bitmap_rect.height() * scale_y) / 2;
|
||||
|
||||
Gfx::IntRect draw_rect = {
|
||||
image_int_rect.x() + offset_x,
|
||||
image_int_rect.y() + offset_y,
|
||||
bitmap_rect.width() * scale_x,
|
||||
bitmap_rect.height() * scale_y
|
||||
};
|
||||
|
||||
context.painter().draw_scaled_bitmap(draw_rect.intersected(image_int_rect), *bitmap, bitmap_rect.intersected(bitmap_intersect), 1.f, scaling_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue