diff --git a/Libraries/LibGfx/ScalingMode.h b/Libraries/LibGfx/ScalingMode.h index 1567fa283d..d315ba9e97 100644 --- a/Libraries/LibGfx/ScalingMode.h +++ b/Libraries/LibGfx/ScalingMode.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2024, Andreas Kling + * Copyright (c) 2025, Jelle Raaijmakers * * SPDX-License-Identifier: BSD-2-Clause */ @@ -9,11 +10,10 @@ namespace Gfx { enum class ScalingMode { - NearestNeighbor, - SmoothPixels, - BilinearBlend, - BoxSampling, None, + Bilinear, + BilinearMipmap, + NearestNeighbor, }; } diff --git a/Libraries/LibGfx/SkiaUtils.h b/Libraries/LibGfx/SkiaUtils.h index 950056de82..3f66871faa 100644 --- a/Libraries/LibGfx/SkiaUtils.h +++ b/Libraries/LibGfx/SkiaUtils.h @@ -118,19 +118,19 @@ constexpr SkPathFillType to_skia_path_fill_type(Gfx::WindingRule winding_rule) VERIFY_NOT_REACHED(); } -constexpr SkSamplingOptions to_skia_sampling_options(Gfx::ScalingMode scaling_mode) +constexpr SkSamplingOptions to_skia_sampling_options(ScalingMode scaling_mode) { switch (scaling_mode) { - case Gfx::ScalingMode::NearestNeighbor: - case Gfx::ScalingMode::SmoothPixels: - return SkSamplingOptions(SkFilterMode::kNearest); - case Gfx::ScalingMode::BilinearBlend: + case ScalingMode::None: + return SkSamplingOptions(); + case ScalingMode::Bilinear: return SkSamplingOptions(SkFilterMode::kLinear); - case Gfx::ScalingMode::BoxSampling: - return SkSamplingOptions(SkCubicResampler::Mitchell()); - default: - VERIFY_NOT_REACHED(); + case ScalingMode::BilinearMipmap: + return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear); + case ScalingMode::NearestNeighbor: + return SkSamplingOptions(SkFilterMode::kNearest); } + VERIFY_NOT_REACHED(); } SkPath to_skia_path(Path const& path); diff --git a/Libraries/LibWeb/CSS/ComputedValues.h b/Libraries/LibWeb/CSS/ComputedValues.h index e2a5327dcd..a666ef5c6d 100644 --- a/Libraries/LibWeb/CSS/ComputedValues.h +++ b/Libraries/LibWeb/CSS/ComputedValues.h @@ -455,17 +455,19 @@ struct TextDecorationThickness { // FIXME: Find a better place for this helper. inline Gfx::ScalingMode to_gfx_scaling_mode(ImageRendering css_value, Gfx::IntRect source, Gfx::IntRect target) { + if (source.size() == target.size()) + return Gfx::ScalingMode::None; + switch (css_value) { case ImageRendering::Auto: case ImageRendering::HighQuality: case ImageRendering::Smooth: - if (target.width() < source.width() || target.height() < source.height()) - return Gfx::ScalingMode::BoxSampling; - return Gfx::ScalingMode::BilinearBlend; + if (target.width() < source.width() && target.height() < source.height()) + return Gfx::ScalingMode::BilinearMipmap; + return Gfx::ScalingMode::Bilinear; case ImageRendering::CrispEdges: - return Gfx::ScalingMode::NearestNeighbor; case ImageRendering::Pixelated: - return Gfx::ScalingMode::SmoothPixels; + return Gfx::ScalingMode::NearestNeighbor; } VERIFY_NOT_REACHED(); } diff --git a/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp b/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp index 9617e00522..09484ccb04 100644 --- a/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp +++ b/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp @@ -188,7 +188,7 @@ WebIDL::ExceptionOr CanvasRenderingContext2D::draw_image_internal(CanvasIm auto scaling_mode = Gfx::ScalingMode::NearestNeighbor; if (drawing_state().image_smoothing_enabled) { // FIXME: Honor drawing_state().image_smoothing_quality - scaling_mode = Gfx::ScalingMode::BilinearBlend; + scaling_mode = Gfx::ScalingMode::BilinearMipmap; } if (auto* painter = this->painter()) { diff --git a/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp b/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp index 2f74904e6b..34e6410fed 100644 --- a/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp +++ b/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp @@ -214,11 +214,11 @@ static ErrorOr> crop_to_the_source_rectangle_with_for // The "high" value indicates a preference for a high level of image interpolation quality. High-quality image interpolation may be more computationally expensive than lower settings. case Bindings::ResizeQuality::Medium: // The "medium" value indicates a preference for a medium level of image interpolation quality. - scaling_passes.append(ScalingPass { .mode = Gfx::ScalingMode::BoxSampling, .width = output_width, .height = output_height }); + scaling_passes.append(ScalingPass { .mode = Gfx::ScalingMode::BilinearMipmap, .width = output_width, .height = output_height }); break; case Bindings::ResizeQuality::Low: // The "low" value indicates a preference for a low level of image interpolation quality. Low-quality image interpolation may be more computationally efficient than higher settings. - scaling_passes.append(ScalingPass { .mode = Gfx::ScalingMode::BilinearBlend, .width = output_width, .height = output_height }); + scaling_passes.append(ScalingPass { .mode = Gfx::ScalingMode::Bilinear, .width = output_width, .height = output_height }); break; case Bindings::ResizeQuality::Pixelated: { // The "pixelated" value indicates a preference for scaling the image to preserve the pixelation of the original as much as possible, with minor smoothing as necessary to avoid distorting the image when the target size is not a clean multiple of the original. @@ -237,7 +237,7 @@ static ErrorOr> crop_to_the_source_rectangle_with_for scaling_passes.append(ScalingPass { .mode = Gfx::ScalingMode::NearestNeighbor, .width = source_width * width_multiple, .height = source_height * height_multiple }); // then scale it the rest of the way to the target size using bilinear interpolation. - scaling_passes.append(ScalingPass { .mode = Gfx::ScalingMode::BilinearBlend, .width = output_width, .height = output_height }); + scaling_passes.append(ScalingPass { .mode = Gfx::ScalingMode::Bilinear, .width = output_width, .height = output_height }); } break; } for (ScalingPass& scaling_pass : scaling_passes) { diff --git a/Tests/LibWeb/Screenshot/data/angled-stripes.png b/Tests/LibWeb/Screenshot/data/angled-stripes.png new file mode 100644 index 0000000000..a0554648d8 Binary files /dev/null and b/Tests/LibWeb/Screenshot/data/angled-stripes.png differ diff --git a/Tests/LibWeb/Screenshot/expected/canvas-filters-ref.html b/Tests/LibWeb/Screenshot/expected/canvas-filters-ref.html index 8f59a5deba..5ff3d5e540 100644 --- a/Tests/LibWeb/Screenshot/expected/canvas-filters-ref.html +++ b/Tests/LibWeb/Screenshot/expected/canvas-filters-ref.html @@ -8,4 +8,4 @@ background-color: white; } - + diff --git a/Tests/LibWeb/Screenshot/expected/image-downscaling-ref.html b/Tests/LibWeb/Screenshot/expected/image-downscaling-ref.html new file mode 100644 index 0000000000..bf2c238f0b --- /dev/null +++ b/Tests/LibWeb/Screenshot/expected/image-downscaling-ref.html @@ -0,0 +1,16 @@ + + + + diff --git a/Tests/LibWeb/Screenshot/expected/object-fit-position-ref.html b/Tests/LibWeb/Screenshot/expected/object-fit-position-ref.html index 299be3b883..7a67e27210 100644 --- a/Tests/LibWeb/Screenshot/expected/object-fit-position-ref.html +++ b/Tests/LibWeb/Screenshot/expected/object-fit-position-ref.html @@ -13,4 +13,4 @@ 2. Right click > "Take Full Screenshot" 3. Update the image below: --> - + diff --git a/Tests/LibWeb/Screenshot/images/border-radius-ref.png b/Tests/LibWeb/Screenshot/images/border-radius-ref.png index 0367221382..35a3d2b91b 100644 Binary files a/Tests/LibWeb/Screenshot/images/border-radius-ref.png and b/Tests/LibWeb/Screenshot/images/border-radius-ref.png differ diff --git a/Tests/LibWeb/Screenshot/images/canvas-filters-ref.png b/Tests/LibWeb/Screenshot/images/canvas-filters-ref.png new file mode 100644 index 0000000000..0fcabe32a2 Binary files /dev/null and b/Tests/LibWeb/Screenshot/images/canvas-filters-ref.png differ diff --git a/Tests/LibWeb/Screenshot/images/canvas-filters.png b/Tests/LibWeb/Screenshot/images/canvas-filters.png deleted file mode 100644 index fc9fa96c82..0000000000 Binary files a/Tests/LibWeb/Screenshot/images/canvas-filters.png and /dev/null differ diff --git a/Tests/LibWeb/Screenshot/images/css-backgrounds-ref.png b/Tests/LibWeb/Screenshot/images/css-backgrounds-ref.png index 3c582b242b..b030a736a1 100644 Binary files a/Tests/LibWeb/Screenshot/images/css-backgrounds-ref.png and b/Tests/LibWeb/Screenshot/images/css-backgrounds-ref.png differ diff --git a/Tests/LibWeb/Screenshot/images/css-filter-ref.png b/Tests/LibWeb/Screenshot/images/css-filter-ref.png index 04adaba073..802c2f53cb 100644 Binary files a/Tests/LibWeb/Screenshot/images/css-filter-ref.png and b/Tests/LibWeb/Screenshot/images/css-filter-ref.png differ diff --git a/Tests/LibWeb/Screenshot/images/image-downscaling-ref.png b/Tests/LibWeb/Screenshot/images/image-downscaling-ref.png new file mode 100644 index 0000000000..107b77eb5a Binary files /dev/null and b/Tests/LibWeb/Screenshot/images/image-downscaling-ref.png differ diff --git a/Tests/LibWeb/Screenshot/images/object-fit-position-ref.png b/Tests/LibWeb/Screenshot/images/object-fit-position-ref.png new file mode 100644 index 0000000000..96601118b7 Binary files /dev/null and b/Tests/LibWeb/Screenshot/images/object-fit-position-ref.png differ diff --git a/Tests/LibWeb/Screenshot/images/object-fit-position.png b/Tests/LibWeb/Screenshot/images/object-fit-position.png deleted file mode 100644 index e6372654b4..0000000000 Binary files a/Tests/LibWeb/Screenshot/images/object-fit-position.png and /dev/null differ diff --git a/Tests/LibWeb/Screenshot/input/border-radius.html b/Tests/LibWeb/Screenshot/input/border-radius.html index 2223fe3d4d..2ffa1fea34 100644 --- a/Tests/LibWeb/Screenshot/input/border-radius.html +++ b/Tests/LibWeb/Screenshot/input/border-radius.html @@ -1,7 +1,7 @@ - + + + + diff --git a/Tests/LibWeb/Screenshot/input/object-fit-position.html b/Tests/LibWeb/Screenshot/input/object-fit-position.html index 0d16e88f81..1b56a9a3a1 100644 --- a/Tests/LibWeb/Screenshot/input/object-fit-position.html +++ b/Tests/LibWeb/Screenshot/input/object-fit-position.html @@ -1,6 +1,6 @@ - +