LibGfx+LibWeb: Use Gfx gradient interpolation in display lists
Prep for moving display-list rasterization out of LibWeb. Display-list gradient commands should not expose CSS enum types to the playback side, so add the matching interpolation method types to LibGfx and convert CSS values while recording.
This commit is contained in:
parent
b50b7a41d7
commit
b25d3561d6
4 changed files with 148 additions and 45 deletions
54
Libraries/LibGfx/GradientInterpolation.h
Normal file
54
Libraries/LibGfx/GradientInterpolation.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2026, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Types.h>
|
||||
|
||||
namespace Gfx {
|
||||
|
||||
enum class RectangularColorSpace : u8 {
|
||||
Srgb,
|
||||
SrgbLinear,
|
||||
DisplayP3,
|
||||
DisplayP3Linear,
|
||||
A98Rgb,
|
||||
ProphotoRgb,
|
||||
Rec2020,
|
||||
Lab,
|
||||
Oklab,
|
||||
Xyz,
|
||||
XyzD50,
|
||||
XyzD65,
|
||||
};
|
||||
|
||||
enum class PolarColorSpace : u8 {
|
||||
Hsl,
|
||||
Hwb,
|
||||
Lch,
|
||||
Oklch,
|
||||
};
|
||||
|
||||
enum class HueInterpolationMethod : u8 {
|
||||
Shorter,
|
||||
Longer,
|
||||
Increasing,
|
||||
Decreasing,
|
||||
};
|
||||
|
||||
struct GradientInterpolationMethod {
|
||||
enum class Type : u8 {
|
||||
Rectangular,
|
||||
Polar,
|
||||
};
|
||||
|
||||
Type type { Type::Rectangular };
|
||||
RectangularColorSpace rectangular_color_space { RectangularColorSpace::Oklab };
|
||||
PolarColorSpace polar_color_space { PolarColorSpace::Oklch };
|
||||
HueInterpolationMethod hue_interpolation_method { HueInterpolationMethod::Shorter };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
#include <LibGfx/AffineTransform.h>
|
||||
#include <LibGfx/Color.h>
|
||||
#include <LibGfx/CompositingAndBlendingOperator.h>
|
||||
#include <LibGfx/GradientInterpolation.h>
|
||||
#include <LibGfx/InterpolationColorSpace.h>
|
||||
#include <LibGfx/LineStyle.h>
|
||||
#include <LibGfx/Path.h>
|
||||
|
|
@ -21,7 +22,6 @@
|
|||
#include <LibGfx/Rect.h>
|
||||
#include <LibGfx/ScalingMode.h>
|
||||
#include <LibGfx/Size.h>
|
||||
#include <LibWeb/CSS/ComputedValues.h>
|
||||
#include <LibWeb/Painting/AccumulatedVisualContext.h>
|
||||
#include <LibWeb/Painting/BorderRadiiData.h>
|
||||
#include <LibWeb/Painting/BorderRadiusCornerClipper.h>
|
||||
|
|
@ -78,18 +78,6 @@ struct DisplayListDataSpan {
|
|||
[[nodiscard]] bool is_empty() const { return size == 0; }
|
||||
};
|
||||
|
||||
struct DisplayListColorInterpolationMethod {
|
||||
enum class Type : u8 {
|
||||
Rectangular,
|
||||
Polar,
|
||||
};
|
||||
|
||||
Type type { Type::Rectangular };
|
||||
CSS::RectangularColorSpace rectangular_color_space { CSS::RectangularColorSpace::Oklab };
|
||||
CSS::PolarColorSpace polar_color_space { CSS::PolarColorSpace::Oklch };
|
||||
CSS::HueInterpolationMethod hue_interpolation_method { CSS::HueInterpolationMethod::Shorter };
|
||||
};
|
||||
|
||||
struct DisplayListGradientColorStops {
|
||||
DisplayListDataSpan colors;
|
||||
DisplayListDataSpan positions;
|
||||
|
|
@ -242,7 +230,7 @@ struct PaintLinearGradient {
|
|||
DisplayListGradientColorStops color_stops;
|
||||
float first_stop_position { 0.0f };
|
||||
float repeat_length { 1.0f };
|
||||
DisplayListColorInterpolationMethod interpolation_method;
|
||||
Gfx::GradientInterpolationMethod interpolation_method;
|
||||
|
||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return gradient_rect; }
|
||||
|
||||
|
|
@ -462,7 +450,7 @@ struct PaintRadialGradient {
|
|||
|
||||
Gfx::IntRect rect;
|
||||
DisplayListGradientColorStops color_stops;
|
||||
DisplayListColorInterpolationMethod interpolation_method;
|
||||
Gfx::GradientInterpolationMethod interpolation_method;
|
||||
Gfx::IntPoint center;
|
||||
Gfx::IntSize size;
|
||||
|
||||
|
|
@ -478,7 +466,7 @@ struct PaintConicGradient {
|
|||
Gfx::IntRect rect;
|
||||
float start_angle { 0.0f };
|
||||
DisplayListGradientColorStops color_stops;
|
||||
DisplayListColorInterpolationMethod interpolation_method;
|
||||
Gfx::GradientInterpolationMethod interpolation_method;
|
||||
Gfx::IntPoint position;
|
||||
|
||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
||||
|
|
|
|||
|
|
@ -299,72 +299,72 @@ void DisplayListPlayerSkia::translate(Translate const& command)
|
|||
canvas.translate(command.delta.x(), command.delta.y());
|
||||
}
|
||||
|
||||
static SkGradientShader::Interpolation to_skia_interpolation(DisplayListColorInterpolationMethod interpolation_method)
|
||||
static SkGradientShader::Interpolation to_skia_interpolation(Gfx::GradientInterpolationMethod interpolation_method)
|
||||
{
|
||||
SkGradientShader::Interpolation interpolation;
|
||||
|
||||
if (interpolation_method.type == DisplayListColorInterpolationMethod::Type::Rectangular) {
|
||||
if (interpolation_method.type == Gfx::GradientInterpolationMethod::Type::Rectangular) {
|
||||
switch (interpolation_method.rectangular_color_space) {
|
||||
case CSS::RectangularColorSpace::Srgb:
|
||||
case Gfx::RectangularColorSpace::Srgb:
|
||||
interpolation.fColorSpace = SkGradientShader::Interpolation::ColorSpace::kSRGB;
|
||||
break;
|
||||
case CSS::RectangularColorSpace::SrgbLinear:
|
||||
case Gfx::RectangularColorSpace::SrgbLinear:
|
||||
interpolation.fColorSpace = SkGradientShader::Interpolation::ColorSpace::kSRGBLinear;
|
||||
break;
|
||||
case CSS::RectangularColorSpace::Lab:
|
||||
case Gfx::RectangularColorSpace::Lab:
|
||||
interpolation.fColorSpace = SkGradientShader::Interpolation::ColorSpace::kLab;
|
||||
break;
|
||||
case CSS::RectangularColorSpace::Oklab:
|
||||
case Gfx::RectangularColorSpace::Oklab:
|
||||
interpolation.fColorSpace = SkGradientShader::Interpolation::ColorSpace::kOKLab;
|
||||
break;
|
||||
case CSS::RectangularColorSpace::DisplayP3:
|
||||
case Gfx::RectangularColorSpace::DisplayP3:
|
||||
interpolation.fColorSpace = SkGradientShader::Interpolation::ColorSpace::kDisplayP3;
|
||||
break;
|
||||
case CSS::RectangularColorSpace::A98Rgb:
|
||||
case Gfx::RectangularColorSpace::A98Rgb:
|
||||
interpolation.fColorSpace = SkGradientShader::Interpolation::ColorSpace::kA98RGB;
|
||||
break;
|
||||
case CSS::RectangularColorSpace::ProphotoRgb:
|
||||
case Gfx::RectangularColorSpace::ProphotoRgb:
|
||||
interpolation.fColorSpace = SkGradientShader::Interpolation::ColorSpace::kProphotoRGB;
|
||||
break;
|
||||
case CSS::RectangularColorSpace::Rec2020:
|
||||
case Gfx::RectangularColorSpace::Rec2020:
|
||||
interpolation.fColorSpace = SkGradientShader::Interpolation::ColorSpace::kRec2020;
|
||||
break;
|
||||
case CSS::RectangularColorSpace::DisplayP3Linear:
|
||||
case CSS::RectangularColorSpace::XyzD50:
|
||||
case CSS::RectangularColorSpace::XyzD65:
|
||||
case Gfx::RectangularColorSpace::DisplayP3Linear:
|
||||
case Gfx::RectangularColorSpace::XyzD50:
|
||||
case Gfx::RectangularColorSpace::XyzD65:
|
||||
dbgln("FIXME: Unsupported gradient color space");
|
||||
interpolation.fColorSpace = SkGradientShader::Interpolation::ColorSpace::kOKLab;
|
||||
break;
|
||||
case CSS::RectangularColorSpace::Xyz:
|
||||
case Gfx::RectangularColorSpace::Xyz:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
} else {
|
||||
switch (interpolation_method.polar_color_space) {
|
||||
case CSS::PolarColorSpace::Hsl:
|
||||
case Gfx::PolarColorSpace::Hsl:
|
||||
interpolation.fColorSpace = SkGradientShader::Interpolation::ColorSpace::kHSL;
|
||||
break;
|
||||
case CSS::PolarColorSpace::Hwb:
|
||||
case Gfx::PolarColorSpace::Hwb:
|
||||
interpolation.fColorSpace = SkGradientShader::Interpolation::ColorSpace::kHWB;
|
||||
break;
|
||||
case CSS::PolarColorSpace::Lch:
|
||||
case Gfx::PolarColorSpace::Lch:
|
||||
interpolation.fColorSpace = SkGradientShader::Interpolation::ColorSpace::kLCH;
|
||||
break;
|
||||
case CSS::PolarColorSpace::Oklch:
|
||||
case Gfx::PolarColorSpace::Oklch:
|
||||
interpolation.fColorSpace = SkGradientShader::Interpolation::ColorSpace::kOKLCH;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (interpolation_method.hue_interpolation_method) {
|
||||
case CSS::HueInterpolationMethod::Shorter:
|
||||
case Gfx::HueInterpolationMethod::Shorter:
|
||||
interpolation.fHueMethod = SkGradientShader::Interpolation::HueMethod::kShorter;
|
||||
break;
|
||||
case CSS::HueInterpolationMethod::Longer:
|
||||
case Gfx::HueInterpolationMethod::Longer:
|
||||
interpolation.fHueMethod = SkGradientShader::Interpolation::HueMethod::kLonger;
|
||||
break;
|
||||
case CSS::HueInterpolationMethod::Increasing:
|
||||
case Gfx::HueInterpolationMethod::Increasing:
|
||||
interpolation.fHueMethod = SkGradientShader::Interpolation::HueMethod::kIncreasing;
|
||||
break;
|
||||
case CSS::HueInterpolationMethod::Decreasing:
|
||||
case Gfx::HueInterpolationMethod::Decreasing:
|
||||
interpolation.fHueMethod = SkGradientShader::Interpolation::HueMethod::kDecreasing;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,19 +94,80 @@ private:
|
|||
Vector<u8> m_inline_payload;
|
||||
};
|
||||
|
||||
static DisplayListColorInterpolationMethod to_display_list_color_interpolation_method(
|
||||
static Gfx::RectangularColorSpace to_gfx_rectangular_color_space(CSS::RectangularColorSpace color_space)
|
||||
{
|
||||
switch (color_space) {
|
||||
case CSS::RectangularColorSpace::Srgb:
|
||||
return Gfx::RectangularColorSpace::Srgb;
|
||||
case CSS::RectangularColorSpace::SrgbLinear:
|
||||
return Gfx::RectangularColorSpace::SrgbLinear;
|
||||
case CSS::RectangularColorSpace::DisplayP3:
|
||||
return Gfx::RectangularColorSpace::DisplayP3;
|
||||
case CSS::RectangularColorSpace::DisplayP3Linear:
|
||||
return Gfx::RectangularColorSpace::DisplayP3Linear;
|
||||
case CSS::RectangularColorSpace::A98Rgb:
|
||||
return Gfx::RectangularColorSpace::A98Rgb;
|
||||
case CSS::RectangularColorSpace::ProphotoRgb:
|
||||
return Gfx::RectangularColorSpace::ProphotoRgb;
|
||||
case CSS::RectangularColorSpace::Rec2020:
|
||||
return Gfx::RectangularColorSpace::Rec2020;
|
||||
case CSS::RectangularColorSpace::Lab:
|
||||
return Gfx::RectangularColorSpace::Lab;
|
||||
case CSS::RectangularColorSpace::Oklab:
|
||||
return Gfx::RectangularColorSpace::Oklab;
|
||||
case CSS::RectangularColorSpace::Xyz:
|
||||
return Gfx::RectangularColorSpace::Xyz;
|
||||
case CSS::RectangularColorSpace::XyzD50:
|
||||
return Gfx::RectangularColorSpace::XyzD50;
|
||||
case CSS::RectangularColorSpace::XyzD65:
|
||||
return Gfx::RectangularColorSpace::XyzD65;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
static Gfx::PolarColorSpace to_gfx_polar_color_space(CSS::PolarColorSpace color_space)
|
||||
{
|
||||
switch (color_space) {
|
||||
case CSS::PolarColorSpace::Hsl:
|
||||
return Gfx::PolarColorSpace::Hsl;
|
||||
case CSS::PolarColorSpace::Hwb:
|
||||
return Gfx::PolarColorSpace::Hwb;
|
||||
case CSS::PolarColorSpace::Lch:
|
||||
return Gfx::PolarColorSpace::Lch;
|
||||
case CSS::PolarColorSpace::Oklch:
|
||||
return Gfx::PolarColorSpace::Oklch;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
static Gfx::HueInterpolationMethod to_gfx_hue_interpolation_method(CSS::HueInterpolationMethod hue_interpolation_method)
|
||||
{
|
||||
switch (hue_interpolation_method) {
|
||||
case CSS::HueInterpolationMethod::Shorter:
|
||||
return Gfx::HueInterpolationMethod::Shorter;
|
||||
case CSS::HueInterpolationMethod::Longer:
|
||||
return Gfx::HueInterpolationMethod::Longer;
|
||||
case CSS::HueInterpolationMethod::Increasing:
|
||||
return Gfx::HueInterpolationMethod::Increasing;
|
||||
case CSS::HueInterpolationMethod::Decreasing:
|
||||
return Gfx::HueInterpolationMethod::Decreasing;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
static Gfx::GradientInterpolationMethod to_display_list_color_interpolation_method(
|
||||
CSS::ColorInterpolationMethodStyleValue::ColorInterpolationMethod const& interpolation_method)
|
||||
{
|
||||
DisplayListColorInterpolationMethod result;
|
||||
Gfx::GradientInterpolationMethod result;
|
||||
interpolation_method.visit(
|
||||
[&](CSS::RectangularColorSpace color_space) {
|
||||
result.type = DisplayListColorInterpolationMethod::Type::Rectangular;
|
||||
result.rectangular_color_space = color_space;
|
||||
result.type = Gfx::GradientInterpolationMethod::Type::Rectangular;
|
||||
result.rectangular_color_space = to_gfx_rectangular_color_space(color_space);
|
||||
},
|
||||
[&](CSS::ColorInterpolationMethodStyleValue::PolarColorInterpolationMethod const& color_space) {
|
||||
result.type = DisplayListColorInterpolationMethod::Type::Polar;
|
||||
result.polar_color_space = color_space.color_space;
|
||||
result.hue_interpolation_method = color_space.hue_interpolation_method;
|
||||
result.type = Gfx::GradientInterpolationMethod::Type::Polar;
|
||||
result.polar_color_space = to_gfx_polar_color_space(color_space.color_space);
|
||||
result.hue_interpolation_method = to_gfx_hue_interpolation_method(color_space.hue_interpolation_method);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue