diff --git a/Base/res/html/misc/image-rendering.html b/Base/res/html/misc/image-rendering.html
new file mode 100644
index 0000000000..d0d2641052
--- /dev/null
+++ b/Base/res/html/misc/image-rendering.html
@@ -0,0 +1,16 @@
+
+
+
+
+ image-rendering property
+
+
+ image-rendering property
+ This image should be blurred:
+
+ This image should be blurred:
+
+ This image should be pixelated:
+
+
+
diff --git a/Base/res/html/misc/welcome.html b/Base/res/html/misc/welcome.html
index e4518ad0eb..3cd6292dd1 100644
--- a/Base/res/html/misc/welcome.html
+++ b/Base/res/html/misc/welcome.html
@@ -117,6 +117,7 @@
Floating boxes with overflow=hidden
Float clearing
Overflow
+ image-rendering property
Features
Basic functionality
css colors
diff --git a/Userland/Libraries/LibWeb/CSS/ComputedValues.h b/Userland/Libraries/LibWeb/CSS/ComputedValues.h
index b82d66099c..b7e73e80bb 100644
--- a/Userland/Libraries/LibWeb/CSS/ComputedValues.h
+++ b/Userland/Libraries/LibWeb/CSS/ComputedValues.h
@@ -29,6 +29,7 @@ public:
static CSS::ListStyleType list_style_type() { return CSS::ListStyleType::Disc; }
static CSS::FlexDirection flex_direction() { return CSS::FlexDirection::Row; }
static CSS::FlexWrap flex_wrap() { return CSS::FlexWrap::Nowrap; }
+ static CSS::ImageRendering image_rendering() { return CSS::ImageRendering::Auto; }
static CSS::JustifyContent justify_content() { return CSS::JustifyContent::FlexStart; }
static CSS::AlignItems align_items() { return CSS::AlignItems::Stretch; }
static CSS::Overflow overflow() { return CSS::Overflow::Visible; }
@@ -105,6 +106,7 @@ public:
float flex_shrink() const { return m_noninherited.flex_shrink; }
CSS::AlignItems align_items() const { return m_noninherited.align_items; }
float opacity() const { return m_noninherited.opacity; }
+ CSS::ImageRendering image_rendering() const { return m_inherited.image_rendering; }
CSS::JustifyContent justify_content() const { return m_noninherited.justify_content; }
Vector const& box_shadow() const { return m_noninherited.box_shadow; }
CSS::BoxSizing box_sizing() const { return m_noninherited.box_sizing; }
@@ -155,6 +157,7 @@ protected:
struct {
Color color { InitialValues::color() };
CSS::Cursor cursor { InitialValues::cursor() };
+ CSS::ImageRendering image_rendering { InitialValues::image_rendering() };
CSS::PointerEvents pointer_events { InitialValues::pointer_events() };
CSS::TextAlign text_align { InitialValues::text_align() };
CSS::TextTransform text_transform { InitialValues::text_transform() };
@@ -216,6 +219,7 @@ class MutableComputedValues final : public ComputedValues {
public:
void set_color(const Color& color) { m_inherited.color = color; }
void set_cursor(CSS::Cursor cursor) { m_inherited.cursor = cursor; }
+ void set_image_rendering(CSS::ImageRendering value) { m_inherited.image_rendering = value; }
void set_pointer_events(CSS::PointerEvents value) { m_inherited.pointer_events = value; }
void set_background_color(const Color& color) { m_noninherited.background_color = color; }
void set_background_layers(Vector&& layers) { m_noninherited.background_layers = move(layers); }
diff --git a/Userland/Libraries/LibWeb/CSS/Identifiers.json b/Userland/Libraries/LibWeb/CSS/Identifiers.json
index 65f1753af4..5a2451a5af 100644
--- a/Userland/Libraries/LibWeb/CSS/Identifiers.json
+++ b/Userland/Libraries/LibWeb/CSS/Identifiers.json
@@ -156,6 +156,7 @@
"outside",
"overline",
"padding-box",
+ "pixelated",
"pointer",
"pre",
"pre-line",
diff --git a/Userland/Libraries/LibWeb/CSS/Properties.json b/Userland/Libraries/LibWeb/CSS/Properties.json
index 9bb799a67e..76b2980fee 100644
--- a/Userland/Libraries/LibWeb/CSS/Properties.json
+++ b/Userland/Libraries/LibWeb/CSS/Properties.json
@@ -748,6 +748,14 @@
"unitless-length"
]
},
+ "image-rendering": {
+ "inherited": true,
+ "initial": "auto",
+ "valid-identifiers": [
+ "auto",
+ "pixelated"
+ ]
+ },
"justify-content": {
"inherited": false,
"initial": "flex-start",
diff --git a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp
index 752c637665..fc496310db 100644
--- a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp
+++ b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp
@@ -358,6 +358,17 @@ static CSS::ValueID to_css_value_id(CSS::FlexWrap value)
VERIFY_NOT_REACHED();
}
+static CSS::ValueID to_css_value_id(CSS::ImageRendering value)
+{
+ switch (value) {
+ case ImageRendering::Auto:
+ return CSS::ValueID::Auto;
+ case ImageRendering::Pixelated:
+ return CSS::ValueID::Pixelated;
+ }
+ VERIFY_NOT_REACHED();
+}
+
static CSS::ValueID to_css_value_id(CSS::JustifyContent value)
{
switch (value) {
@@ -515,6 +526,8 @@ RefPtr ResolvedCSSStyleDeclaration::style_value_for_property(Layout:
return NumericStyleValue::create_float(layout_node.computed_values().flex_shrink());
case CSS::PropertyID::Opacity:
return NumericStyleValue::create_float(layout_node.computed_values().opacity());
+ case CSS::PropertyID::ImageRendering:
+ return IdentifierStyleValue::create(to_css_value_id(layout_node.computed_values().image_rendering()));
case CSS::PropertyID::JustifyContent:
return IdentifierStyleValue::create(to_css_value_id(layout_node.computed_values().justify_content()));
case CSS::PropertyID::BoxShadow: {
diff --git a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp
index e86721850d..1ae062b8d1 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp
+++ b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp
@@ -269,6 +269,21 @@ float StyleProperties::flex_shrink() const
return value.value()->to_number();
}
+Optional StyleProperties::image_rendering() const
+{
+ auto value = property(CSS::PropertyID::ImageRendering);
+ if (!value.has_value())
+ return {};
+ switch (value.value()->to_identifier()) {
+ case CSS::ValueID::Auto:
+ return CSS::ImageRendering::Auto;
+ case CSS::ValueID::Pixelated:
+ return CSS::ImageRendering::Pixelated;
+ default:
+ return {};
+ }
+}
+
Optional StyleProperties::justify_content() const
{
auto value = property(CSS::PropertyID::JustifyContent);
diff --git a/Userland/Libraries/LibWeb/CSS/StyleProperties.h b/Userland/Libraries/LibWeb/CSS/StyleProperties.h
index 09263ce1ba..f0790a04ac 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleProperties.h
+++ b/Userland/Libraries/LibWeb/CSS/StyleProperties.h
@@ -62,6 +62,7 @@ public:
float flex_shrink() const;
Optional align_items() const;
float opacity() const;
+ Optional image_rendering() const;
Optional justify_content() const;
Optional overflow_x() const;
Optional overflow_y() const;
diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h
index 88f320c8c2..03bc0c48e6 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleValue.h
+++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h
@@ -140,6 +140,11 @@ enum class Float {
Right,
};
+enum class ImageRendering {
+ Auto,
+ Pixelated
+};
+
enum class JustifyContent {
FlexStart,
FlexEnd,
diff --git a/Userland/Libraries/LibWeb/Layout/ImageBox.cpp b/Userland/Libraries/LibWeb/Layout/ImageBox.cpp
index c1123467f8..e9dc183fd7 100644
--- a/Userland/Libraries/LibWeb/Layout/ImageBox.cpp
+++ b/Userland/Libraries/LibWeb/Layout/ImageBox.cpp
@@ -7,6 +7,8 @@
#include
#include
#include
+#include
+#include
#include
#include
@@ -91,7 +93,9 @@ void ImageBox::paint(PaintContext& context, PaintPhase phase)
alt = image_element.src();
context.painter().draw_text(enclosing_int_rect(absolute_rect()), alt, Gfx::TextAlignment::Center, computed_values().color(), Gfx::TextElision::Right);
} else if (auto bitmap = m_image_loader.bitmap(m_image_loader.current_frame_index())) {
- context.painter().draw_scaled_bitmap(rounded_int_rect(absolute_rect()), *bitmap, bitmap->rect(), 1.0f, Gfx::Painter::ScalingMode::BilinearBlend);
+ // FIXME: Support 'crisp-edges', 'smooth' and 'high-quality'
+ auto scaling_mode = computed_values().image_rendering() == CSS::ImageRendering::Pixelated ? Gfx::Painter::ScalingMode::NearestNeighbor : Gfx::Painter::ScalingMode::BilinearBlend;
+ context.painter().draw_scaled_bitmap(rounded_int_rect(absolute_rect()), *bitmap, bitmap->rect(), 1.0f, scaling_mode);
}
}
}
diff --git a/Userland/Libraries/LibWeb/Layout/Node.cpp b/Userland/Libraries/LibWeb/Layout/Node.cpp
index 98239a1f37..d8da6e9be3 100644
--- a/Userland/Libraries/LibWeb/Layout/Node.cpp
+++ b/Userland/Libraries/LibWeb/Layout/Node.cpp
@@ -396,6 +396,10 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& specified_style)
if (cursor.has_value())
computed_values.set_cursor(cursor.value());
+ auto image_rendering = specified_style.image_rendering();
+ if (image_rendering.has_value())
+ computed_values.set_image_rendering(image_rendering.value());
+
auto pointer_events = specified_style.pointer_events();
if (pointer_events.has_value())
computed_values.set_pointer_events(pointer_events.value());