From e77552519e3d89813a41af7722946e7245cd13d3 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 29 Mar 2023 18:35:02 +0200 Subject: [PATCH] LibWeb: Implement CRC2D.imageSmoothingEnabled We now select between nearest neighbor and bilinear filtering when scaling images in CRC2D.drawImage(). This patch also adds CRC2D.imageSmoothingQuality but it's ignored for now as we don't have a bunch of different quality levels to map it to. Work towards #17993 (Ruffle Flash Player) --- Userland/Libraries/LibWeb/Forward.h | 1 + .../LibWeb/HTML/Canvas/CanvasImageSmoothing.h | 27 ++++++++++++++++++ .../HTML/Canvas/CanvasImageSmoothing.idl | 6 ++++ .../LibWeb/HTML/Canvas/CanvasState.h | 3 ++ .../LibWeb/HTML/CanvasRenderingContext2D.cpp | 28 ++++++++++++++++++- .../LibWeb/HTML/CanvasRenderingContext2D.h | 7 +++++ .../LibWeb/HTML/CanvasRenderingContext2D.idl | 5 +++- 7 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 Userland/Libraries/LibWeb/HTML/Canvas/CanvasImageSmoothing.h create mode 100644 Userland/Libraries/LibWeb/HTML/Canvas/CanvasImageSmoothing.idl diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index b46ef749902..a5d52e689ec 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -530,6 +530,7 @@ enum class CanPlayTypeResult; enum class CanvasFillRule; enum class EndingType; enum class DOMParserSupportedType; +enum class ImageSmoothingQuality; enum class ReferrerPolicy; enum class RequestDestination; enum class RequestMode; diff --git a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasImageSmoothing.h b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasImageSmoothing.h new file mode 100644 index 00000000000..f9e3d97593c --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasImageSmoothing.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Web::HTML { + +// https://html.spec.whatwg.org/multipage/canvas.html#canvasimagesmoothing +class CanvasImageSmoothing { +public: + virtual ~CanvasImageSmoothing() = default; + + virtual bool image_smoothing_enabled() const = 0; + virtual void set_image_smoothing_enabled(bool) = 0; + virtual Bindings::ImageSmoothingQuality image_smoothing_quality() const = 0; + virtual void set_image_smoothing_quality(Bindings::ImageSmoothingQuality) = 0; + +protected: + CanvasImageSmoothing() = default; +}; + +} diff --git a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasImageSmoothing.idl b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasImageSmoothing.idl new file mode 100644 index 00000000000..77d752efcb0 --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasImageSmoothing.idl @@ -0,0 +1,6 @@ +// https://html.spec.whatwg.org/multipage/canvas.html#canvasimagesmoothing +interface mixin CanvasImageSmoothing { + // image smoothing + attribute boolean imageSmoothingEnabled; // (default true) + attribute ImageSmoothingQuality imageSmoothingQuality; // (default low) +}; diff --git a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasState.h b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasState.h index 3c9723c6cde..fe7eeb58d6e 100644 --- a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasState.h +++ b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasState.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -74,6 +75,8 @@ public: FillOrStrokeStyle fill_style { Gfx::Color::Black }; FillOrStrokeStyle stroke_style { Gfx::Color::Black }; float line_width { 1 }; + bool image_smoothing_enabled { true }; + Bindings::ImageSmoothingQuality image_smoothing_quality { Bindings::ImageSmoothingQuality::Low }; }; DrawingState& drawing_state() { return m_drawing_state; } DrawingState const& drawing_state() const { return m_drawing_state; } diff --git a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp index 84032ea058a..c42f8d995f1 100644 --- a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp +++ b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -173,7 +174,12 @@ WebIDL::ExceptionOr CanvasRenderingContext2D::draw_image_internal(CanvasIm if (!painter) return {}; - painter->draw_scaled_bitmap_with_transform(destination_rect.to_rounded(), *bitmap, source_rect, drawing_state().transform, 1.0f, Gfx::Painter::ScalingMode::BilinearBlend); + auto scaling_mode = Gfx::Painter::ScalingMode::NearestNeighbor; + if (drawing_state().image_smoothing_enabled) { + // FIXME: Honor drawing_state().image_smoothing_quality + scaling_mode = Gfx::Painter::ScalingMode::BilinearBlend; + } + painter->draw_scaled_bitmap_with_transform(destination_rect.to_rounded(), *bitmap, source_rect, drawing_state().transform, 1.0f, scaling_mode); // 7. If image is not origin-clean, then set the CanvasRenderingContext2D's origin-clean flag to false. if (image_is_not_origin_clean(image)) @@ -560,4 +566,24 @@ bool image_is_not_origin_clean(CanvasImageSource const& image) }); } +bool CanvasRenderingContext2D::image_smoothing_enabled() const +{ + return drawing_state().image_smoothing_enabled; +} + +void CanvasRenderingContext2D::set_image_smoothing_enabled(bool enabled) +{ + drawing_state().image_smoothing_enabled = enabled; +} + +Bindings::ImageSmoothingQuality CanvasRenderingContext2D::image_smoothing_quality() const +{ + return drawing_state().image_smoothing_quality; +} + +void CanvasRenderingContext2D::set_image_smoothing_quality(Bindings::ImageSmoothingQuality quality) +{ + drawing_state().image_smoothing_quality = quality; +} + } diff --git a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.h b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.h index 00fc7c003c9..cbc6c26da52 100644 --- a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.h +++ b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,7 @@ class CanvasRenderingContext2D , public CanvasText , public CanvasDrawImage , public CanvasImageData + , public CanvasImageSmoothing , public CanvasPathDrawingStyles { WEB_PLATFORM_OBJECT(CanvasRenderingContext2D, Bindings::PlatformObject); @@ -84,6 +86,11 @@ public: virtual void clip() override; + virtual bool image_smoothing_enabled() const override; + virtual void set_image_smoothing_enabled(bool) override; + virtual Bindings::ImageSmoothingQuality image_smoothing_quality() const override; + virtual void set_image_smoothing_quality(Bindings::ImageSmoothingQuality) override; + private: explicit CanvasRenderingContext2D(JS::Realm&, HTMLCanvasElement&); diff --git a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.idl b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.idl index cb2dee24b72..2bcf9e06bc9 100644 --- a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.idl +++ b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.idl @@ -3,6 +3,7 @@ #import #import #import +#import #import #import #import @@ -10,6 +11,8 @@ #import #import +enum ImageSmoothingQuality { "low", "medium", "high" }; + // https://html.spec.whatwg.org/multipage/canvas.html#canvasrenderingcontext2d [Exposed=Window] interface CanvasRenderingContext2D { @@ -19,7 +22,7 @@ interface CanvasRenderingContext2D { CanvasRenderingContext2D includes CanvasState; CanvasRenderingContext2D includes CanvasTransform; // FIXME: CanvasRenderingContext2D includes CanvasCompositing; -// FIXME: CanvasRenderingContext2D includes CanvasImageSmoothing; +CanvasRenderingContext2D includes CanvasImageSmoothing; CanvasRenderingContext2D includes CanvasFillStrokeStyles; // FIXME: CanvasRenderingContext2D includes CanvasShadowStyles; // FIXME: CanvasRenderingContext2D includes CanvasFilters;