mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-02 14:19:48 +00:00
LibWeb+LibGfx: Refactor CSS filters into LibGfx
CSS filters work similarly to canvas filters, so it makes sense to have Gfx::Filter that can be used by both libraries in an analogous way as Gfx::Color.
This commit is contained in:
parent
bc971a4ccc
commit
9fd1223992
Notes:
github-actions[bot]
2024-12-18 17:55:46 +00:00
Author: https://github.com/ananas-dev
Commit: 9fd1223992
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2876
Reviewed-by: https://github.com/kalenikaliaksandr
Reviewed-by: https://github.com/shlyakpavel
18 changed files with 365 additions and 367 deletions
|
@ -41,6 +41,7 @@ set(SOURCES
|
|||
ImageFormats/WebPWriterLossless.cpp
|
||||
ImageFormats/AVIFLoader.cpp
|
||||
ImmutableBitmap.cpp
|
||||
SkiaUtils.cpp
|
||||
PaintingSurface.cpp
|
||||
Palette.cpp
|
||||
Path.cpp
|
||||
|
|
43
Libraries/LibGfx/Filter.h
Normal file
43
Libraries/LibGfx/Filter.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Lucien Fiorini <lucienfiorini@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Variant.h>
|
||||
#include <LibGfx/Color.h>
|
||||
|
||||
namespace Gfx {
|
||||
|
||||
struct BlurFilter {
|
||||
float radius;
|
||||
};
|
||||
|
||||
struct DropShadowFilter {
|
||||
float offset_x;
|
||||
float offset_y;
|
||||
float radius;
|
||||
Gfx::Color color;
|
||||
};
|
||||
|
||||
struct HueRotateFilter {
|
||||
float angle_degrees;
|
||||
};
|
||||
|
||||
struct ColorFilter {
|
||||
enum class Type {
|
||||
Brightness,
|
||||
Contrast,
|
||||
Grayscale,
|
||||
Invert,
|
||||
Opacity,
|
||||
Saturate,
|
||||
Sepia
|
||||
} type;
|
||||
float amount;
|
||||
};
|
||||
|
||||
using Filter = Variant<BlurFilter, DropShadowFilter, HueRotateFilter, ColorFilter>;
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
#include <LibGfx/ImmutableBitmap.h>
|
||||
#include <LibGfx/PainterSkia.h>
|
||||
#include <LibGfx/PathSkia.h>
|
||||
#include <LibGfx/SkiaUtils.h>
|
||||
|
||||
#include <AK/TypeCasts.h>
|
||||
#include <core/SkCanvas.h>
|
||||
|
@ -34,30 +35,75 @@ struct PainterSkia::Impl {
|
|||
}
|
||||
};
|
||||
|
||||
static constexpr SkRect to_skia_rect(auto const& rect)
|
||||
static void apply_paint_style(SkPaint& paint, Gfx::PaintStyle const& style)
|
||||
{
|
||||
return SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height());
|
||||
}
|
||||
if (is<Gfx::SolidColorPaintStyle>(style)) {
|
||||
auto const& solid_color = static_cast<Gfx::SolidColorPaintStyle const&>(style);
|
||||
auto color = solid_color.sample_color(Gfx::IntPoint(0, 0));
|
||||
|
||||
static constexpr SkColor to_skia_color(Gfx::Color const& color)
|
||||
{
|
||||
return SkColorSetARGB(color.alpha(), color.red(), color.green(), color.blue());
|
||||
}
|
||||
paint.setColor(to_skia_color(color));
|
||||
} else if (is<Gfx::CanvasLinearGradientPaintStyle>(style)) {
|
||||
auto const& linear_gradient = static_cast<Gfx::CanvasLinearGradientPaintStyle const&>(style);
|
||||
auto const& color_stops = linear_gradient.color_stops();
|
||||
|
||||
static SkPath to_skia_path(Gfx::Path const& path)
|
||||
{
|
||||
return static_cast<PathImplSkia const&>(path.impl()).sk_path();
|
||||
}
|
||||
Vector<SkColor> colors;
|
||||
colors.ensure_capacity(color_stops.size());
|
||||
Vector<SkScalar> positions;
|
||||
positions.ensure_capacity(color_stops.size());
|
||||
for (auto const& color_stop : color_stops) {
|
||||
colors.append(to_skia_color(color_stop.color));
|
||||
positions.append(color_stop.position);
|
||||
}
|
||||
|
||||
static SkPathFillType to_skia_path_fill_type(Gfx::WindingRule winding_rule)
|
||||
{
|
||||
switch (winding_rule) {
|
||||
case Gfx::WindingRule::Nonzero:
|
||||
return SkPathFillType::kWinding;
|
||||
case Gfx::WindingRule::EvenOdd:
|
||||
return SkPathFillType::kEvenOdd;
|
||||
Array<SkPoint, 2> points;
|
||||
points[0] = to_skia_point(linear_gradient.start_point());
|
||||
points[1] = to_skia_point(linear_gradient.end_point());
|
||||
|
||||
SkMatrix matrix;
|
||||
auto shader = SkGradientShader::MakeLinear(points.data(), colors.data(), positions.data(), color_stops.size(), SkTileMode::kClamp, 0, &matrix);
|
||||
paint.setShader(shader);
|
||||
} else if (is<Gfx::CanvasRadialGradientPaintStyle>(style)) {
|
||||
auto const& radial_gradient = static_cast<Gfx::CanvasRadialGradientPaintStyle const&>(style);
|
||||
auto const& color_stops = radial_gradient.color_stops();
|
||||
|
||||
Vector<SkColor> colors;
|
||||
colors.ensure_capacity(color_stops.size());
|
||||
Vector<SkScalar> positions;
|
||||
positions.ensure_capacity(color_stops.size());
|
||||
for (auto const& color_stop : color_stops) {
|
||||
colors.append(to_skia_color(color_stop.color));
|
||||
positions.append(color_stop.position);
|
||||
}
|
||||
|
||||
auto start_center = radial_gradient.start_center();
|
||||
auto end_center = radial_gradient.end_center();
|
||||
auto start_radius = radial_gradient.start_radius();
|
||||
auto end_radius = radial_gradient.end_radius();
|
||||
|
||||
auto start_sk_point = to_skia_point(start_center);
|
||||
auto end_sk_point = to_skia_point(end_center);
|
||||
|
||||
SkMatrix matrix;
|
||||
auto shader = SkGradientShader::MakeTwoPointConical(start_sk_point, start_radius, end_sk_point, end_radius, colors.data(), positions.data(), color_stops.size(), SkTileMode::kClamp, 0, &matrix);
|
||||
paint.setShader(shader);
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
static void apply_filters(SkPaint& paint, ReadonlySpan<Gfx::Filter> filters)
|
||||
{
|
||||
for (auto const& filter : filters) {
|
||||
paint.setImageFilter(to_skia_image_filter(filter));
|
||||
}
|
||||
}
|
||||
|
||||
static SkPaint to_skia_paint(Gfx::PaintStyle const& style, ReadonlySpan<Gfx::Filter> filters)
|
||||
{
|
||||
SkPaint paint;
|
||||
|
||||
apply_paint_style(paint, style);
|
||||
apply_filters(paint, filters);
|
||||
|
||||
return paint;
|
||||
}
|
||||
|
||||
PainterSkia::PainterSkia(NonnullRefPtr<Gfx::PaintingSurface> painting_surface)
|
||||
|
@ -82,21 +128,6 @@ void PainterSkia::fill_rect(Gfx::FloatRect const& rect, Color color)
|
|||
impl().canvas()->drawRect(to_skia_rect(rect), paint);
|
||||
}
|
||||
|
||||
static SkSamplingOptions to_skia_sampling_options(Gfx::ScalingMode scaling_mode)
|
||||
{
|
||||
switch (scaling_mode) {
|
||||
case Gfx::ScalingMode::NearestNeighbor:
|
||||
return SkSamplingOptions(SkFilterMode::kNearest);
|
||||
case Gfx::ScalingMode::BilinearBlend:
|
||||
case Gfx::ScalingMode::SmoothPixels:
|
||||
return SkSamplingOptions(SkFilterMode::kLinear);
|
||||
case Gfx::ScalingMode::BoxSampling:
|
||||
return SkSamplingOptions(SkCubicResampler::Mitchell());
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
void PainterSkia::draw_bitmap(Gfx::FloatRect const& dst_rect, Gfx::ImmutableBitmap const& src_bitmap, Gfx::IntRect const& src_rect, Gfx::ScalingMode scaling_mode, float global_alpha)
|
||||
{
|
||||
SkPaint paint;
|
||||
|
@ -121,67 +152,6 @@ void PainterSkia::set_transform(Gfx::AffineTransform const& transform)
|
|||
impl().canvas()->setMatrix(matrix);
|
||||
}
|
||||
|
||||
static SkPoint to_skia_point(auto const& point)
|
||||
{
|
||||
return SkPoint::Make(point.x(), point.y());
|
||||
}
|
||||
|
||||
static SkPaint to_skia_paint(Gfx::PaintStyle const& style)
|
||||
{
|
||||
if (is<Gfx::CanvasLinearGradientPaintStyle>(style)) {
|
||||
auto const& linear_gradient = static_cast<Gfx::CanvasLinearGradientPaintStyle const&>(style);
|
||||
auto const& color_stops = linear_gradient.color_stops();
|
||||
|
||||
SkPaint paint;
|
||||
Vector<SkColor> colors;
|
||||
colors.ensure_capacity(color_stops.size());
|
||||
Vector<SkScalar> positions;
|
||||
positions.ensure_capacity(color_stops.size());
|
||||
for (auto const& color_stop : color_stops) {
|
||||
colors.append(to_skia_color(color_stop.color));
|
||||
positions.append(color_stop.position);
|
||||
}
|
||||
|
||||
Array<SkPoint, 2> points;
|
||||
points[0] = to_skia_point(linear_gradient.start_point());
|
||||
points[1] = to_skia_point(linear_gradient.end_point());
|
||||
|
||||
SkMatrix matrix;
|
||||
auto shader = SkGradientShader::MakeLinear(points.data(), colors.data(), positions.data(), color_stops.size(), SkTileMode::kClamp, 0, &matrix);
|
||||
paint.setShader(shader);
|
||||
return paint;
|
||||
}
|
||||
|
||||
if (is<Gfx::CanvasRadialGradientPaintStyle>(style)) {
|
||||
auto const& radial_gradient = static_cast<Gfx::CanvasRadialGradientPaintStyle const&>(style);
|
||||
auto const& color_stops = radial_gradient.color_stops();
|
||||
|
||||
SkPaint paint;
|
||||
Vector<SkColor> colors;
|
||||
colors.ensure_capacity(color_stops.size());
|
||||
Vector<SkScalar> positions;
|
||||
positions.ensure_capacity(color_stops.size());
|
||||
for (auto const& color_stop : color_stops) {
|
||||
colors.append(to_skia_color(color_stop.color));
|
||||
positions.append(color_stop.position);
|
||||
}
|
||||
|
||||
auto start_center = radial_gradient.start_center();
|
||||
auto end_center = radial_gradient.end_center();
|
||||
auto start_radius = radial_gradient.start_radius();
|
||||
auto end_radius = radial_gradient.end_radius();
|
||||
|
||||
auto start_sk_point = to_skia_point(start_center);
|
||||
auto end_sk_point = to_skia_point(end_center);
|
||||
|
||||
SkMatrix matrix;
|
||||
auto shader = SkGradientShader::MakeTwoPointConical(start_sk_point, start_radius, end_sk_point, end_radius, colors.data(), positions.data(), color_stops.size(), SkTileMode::kClamp, 0, &matrix);
|
||||
paint.setShader(shader);
|
||||
return paint;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void PainterSkia::stroke_path(Gfx::Path const& path, Gfx::Color color, float thickness)
|
||||
{
|
||||
// Skia treats zero thickness as a special case and will draw a hairline, while we want to draw nothing.
|
||||
|
@ -220,7 +190,7 @@ void PainterSkia::stroke_path(Gfx::Path const& path, Gfx::PaintStyle const& pain
|
|||
return;
|
||||
|
||||
auto sk_path = to_skia_path(path);
|
||||
auto paint = to_skia_paint(paint_style);
|
||||
auto paint = to_skia_paint(paint_style, {});
|
||||
paint.setAntiAlias(true);
|
||||
paint.setAlphaf(global_alpha);
|
||||
paint.setStyle(SkPaint::Style::kStroke_Style);
|
||||
|
@ -253,7 +223,7 @@ void PainterSkia::fill_path(Gfx::Path const& path, Gfx::PaintStyle const& paint_
|
|||
{
|
||||
auto sk_path = to_skia_path(path);
|
||||
sk_path.setFillType(to_skia_path_fill_type(winding_rule));
|
||||
auto paint = to_skia_paint(paint_style);
|
||||
auto paint = to_skia_paint(paint_style, {});
|
||||
paint.setAntiAlias(true);
|
||||
paint.setAlphaf(global_alpha);
|
||||
impl().canvas()->drawPath(sk_path, paint);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <LibGfx/Font/ScaledFont.h>
|
||||
#include <LibGfx/PathSkia.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <LibGfx/SkiaUtils.h>
|
||||
#include <core/SkFont.h>
|
||||
#include <core/SkPath.h>
|
||||
#include <core/SkPathMeasure.h>
|
||||
|
@ -205,17 +206,6 @@ Gfx::FloatRect PathImplSkia::bounding_box() const
|
|||
return { bounds.fLeft, bounds.fTop, bounds.fRight - bounds.fLeft, bounds.fBottom - bounds.fTop };
|
||||
}
|
||||
|
||||
static SkPathFillType to_skia_path_fill_type(Gfx::WindingRule winding_rule)
|
||||
{
|
||||
switch (winding_rule) {
|
||||
case Gfx::WindingRule::Nonzero:
|
||||
return SkPathFillType::kWinding;
|
||||
case Gfx::WindingRule::EvenOdd:
|
||||
return SkPathFillType::kEvenOdd;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
bool PathImplSkia::contains(FloatPoint point, Gfx::WindingRule winding_rule) const
|
||||
{
|
||||
SkPath temp_path = *m_path;
|
||||
|
|
143
Libraries/LibGfx/SkiaUtils.cpp
Normal file
143
Libraries/LibGfx/SkiaUtils.cpp
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Lucien Fiorini <lucienfiorini@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <LibGfx/Filter.h>
|
||||
#include <LibGfx/SkiaUtils.h>
|
||||
#include <core/SkColorFilter.h>
|
||||
#include <core/SkImageFilter.h>
|
||||
#include <effects/SkImageFilters.h>
|
||||
|
||||
namespace Gfx {
|
||||
|
||||
SkPath to_skia_path(Path const& path)
|
||||
{
|
||||
return static_cast<PathImplSkia const&>(path.impl()).sk_path();
|
||||
}
|
||||
|
||||
sk_sp<SkImageFilter> to_skia_image_filter(Gfx::Filter const& filter)
|
||||
{
|
||||
// See: https://drafts.fxtf.org/filter-effects-1/#supported-filter-functions
|
||||
return filter.visit(
|
||||
[&](Gfx::BlurFilter blur_filter) {
|
||||
return SkImageFilters::Blur(blur_filter.radius, blur_filter.radius, nullptr);
|
||||
},
|
||||
[&](Gfx::ColorFilter color_filter) {
|
||||
sk_sp<SkColorFilter> skia_color_filter;
|
||||
float amount = color_filter.amount;
|
||||
|
||||
// Matrices are taken from https://drafts.fxtf.org/filter-effects-1/#FilterPrimitiveRepresentation
|
||||
switch (color_filter.type) {
|
||||
case ColorFilter::Type::Grayscale: {
|
||||
float matrix[20] = {
|
||||
0.2126f + 0.7874f * (1 - amount), 0.7152f - 0.7152f * (1 - amount), 0.0722f - 0.0722f * (1 - amount), 0, 0,
|
||||
0.2126f - 0.2126f * (1 - amount), 0.7152f + 0.2848f * (1 - amount), 0.0722f - 0.0722f * (1 - amount), 0, 0,
|
||||
0.2126f - 0.2126f * (1 - amount), 0.7152f - 0.7152f * (1 - amount), 0.0722f + 0.9278f * (1 - amount), 0, 0,
|
||||
0, 0, 0, 1, 0
|
||||
};
|
||||
skia_color_filter = SkColorFilters::Matrix(matrix, SkColorFilters::Clamp::kYes);
|
||||
break;
|
||||
}
|
||||
case Gfx::ColorFilter::Type::Brightness: {
|
||||
float matrix[20] = {
|
||||
amount, 0, 0, 0, 0,
|
||||
0, amount, 0, 0, 0,
|
||||
0, 0, amount, 0, 0,
|
||||
0, 0, 0, 1, 0
|
||||
};
|
||||
skia_color_filter = SkColorFilters::Matrix(matrix, SkColorFilters::Clamp::kNo);
|
||||
break;
|
||||
}
|
||||
case Gfx::ColorFilter::Type::Contrast: {
|
||||
float intercept = -(0.5f * amount) + 0.5f;
|
||||
float matrix[20] = {
|
||||
amount, 0, 0, 0, intercept,
|
||||
0, amount, 0, 0, intercept,
|
||||
0, 0, amount, 0, intercept,
|
||||
0, 0, 0, 1, 0
|
||||
};
|
||||
skia_color_filter = SkColorFilters::Matrix(matrix, SkColorFilters::Clamp::kNo);
|
||||
break;
|
||||
}
|
||||
case Gfx::ColorFilter::Type::Invert: {
|
||||
float matrix[20] = {
|
||||
1 - 2 * amount, 0, 0, 0, amount,
|
||||
0, 1 - 2 * amount, 0, 0, amount,
|
||||
0, 0, 1 - 2 * amount, 0, amount,
|
||||
0, 0, 0, 1, 0
|
||||
};
|
||||
skia_color_filter = SkColorFilters::Matrix(matrix, SkColorFilters::Clamp::kYes);
|
||||
break;
|
||||
}
|
||||
case Gfx::ColorFilter::Type::Opacity: {
|
||||
float matrix[20] = {
|
||||
1, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 0, amount, 0
|
||||
};
|
||||
skia_color_filter = SkColorFilters::Matrix(matrix, SkColorFilters::Clamp::kYes);
|
||||
break;
|
||||
}
|
||||
case Gfx::ColorFilter::Type::Sepia: {
|
||||
float matrix[20] = {
|
||||
0.393f + 0.607f * (1 - amount), 0.769f - 0.769f * (1 - amount), 0.189f - 0.189f * (1 - amount), 0, 0,
|
||||
0.349f - 0.349f * (1 - amount), 0.686f + 0.314f * (1 - amount), 0.168f - 0.168f * (1 - amount), 0, 0,
|
||||
0.272f - 0.272f * (1 - amount), 0.534f - 0.534f * (1 - amount), 0.131f + 0.869f * (1 - amount), 0, 0,
|
||||
0, 0, 0, 1, 0
|
||||
};
|
||||
skia_color_filter = SkColorFilters::Matrix(matrix, SkColorFilters::Clamp::kYes);
|
||||
break;
|
||||
}
|
||||
case Gfx::ColorFilter::Type::Saturate: {
|
||||
float matrix[20] = {
|
||||
0.213f + 0.787f * amount, 0.715f - 0.715f * amount, 0.072f - 0.072f * amount, 0, 0,
|
||||
0.213f - 0.213f * amount, 0.715f + 0.285f * amount, 0.072f - 0.072f * amount, 0, 0,
|
||||
0.213f - 0.213f * amount, 0.715f - 0.715f * amount, 0.072f + 0.928f * amount, 0, 0,
|
||||
0, 0, 0, 1, 0
|
||||
};
|
||||
skia_color_filter = SkColorFilters::Matrix(matrix, SkColorFilters::Clamp::kNo);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
return SkImageFilters::ColorFilter(skia_color_filter, nullptr);
|
||||
},
|
||||
[&](Gfx::HueRotateFilter hue_rotate_filter) {
|
||||
float radians = AK::to_radians(hue_rotate_filter.angle_degrees);
|
||||
|
||||
auto cosA = cos(radians);
|
||||
auto sinA = sin(radians);
|
||||
|
||||
auto a00 = 0.213f + cosA * 0.787f - sinA * 0.213f;
|
||||
auto a01 = 0.715f - cosA * 0.715f - sinA * 0.715f;
|
||||
auto a02 = 0.072f - cosA * 0.072f + sinA * 0.928f;
|
||||
auto a10 = 0.213f - cosA * 0.213f + sinA * 0.143f;
|
||||
auto a11 = 0.715f + cosA * 0.285f + sinA * 0.140f;
|
||||
auto a12 = 0.072f - cosA * 0.072f - sinA * 0.283f;
|
||||
auto a20 = 0.213f - cosA * 0.213f - sinA * 0.787f;
|
||||
auto a21 = 0.715f - cosA * 0.715f + sinA * 0.715f;
|
||||
auto a22 = 0.072f + cosA * 0.928f + sinA * 0.072f;
|
||||
|
||||
float matrix[20] = {
|
||||
a00, a01, a02, 0, 0,
|
||||
a10, a11, a12, 0, 0,
|
||||
a20, a21, a22, 0, 0,
|
||||
0, 0, 0, 1, 0
|
||||
};
|
||||
|
||||
auto filter = SkColorFilters::Matrix(matrix, SkColorFilters::Clamp::kNo);
|
||||
return SkImageFilters::ColorFilter(filter, nullptr);
|
||||
},
|
||||
[&](Gfx::DropShadowFilter drop_shadow_filter) {
|
||||
auto shadow_color = to_skia_color(drop_shadow_filter.color);
|
||||
return SkImageFilters::DropShadow(drop_shadow_filter.offset_x, drop_shadow_filter.offset_y, drop_shadow_filter.radius, drop_shadow_filter.radius, shadow_color, nullptr);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Pavel Shliak <shlyakpavel@gmail.com>
|
||||
* Copyright (c) 2024, Lucien Fiorini <lucienfiorini@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -8,11 +9,19 @@
|
|||
|
||||
#include <AK/Assertions.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/Filter.h>
|
||||
#include <LibGfx/PathSkia.h>
|
||||
#include <LibGfx/ScalingMode.h>
|
||||
#include <LibGfx/WindingRule.h>
|
||||
#include <core/SkColor.h>
|
||||
#include <core/SkColorType.h>
|
||||
#include <core/SkImageFilter.h>
|
||||
#include <core/SkPath.h>
|
||||
#include <core/SkSamplingOptions.h>
|
||||
|
||||
namespace Gfx {
|
||||
|
||||
static SkColorType to_skia_color_type(Gfx::BitmapFormat format)
|
||||
constexpr SkColorType to_skia_color_type(Gfx::BitmapFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
case Gfx::BitmapFormat::Invalid:
|
||||
|
@ -28,4 +37,58 @@ static SkColorType to_skia_color_type(Gfx::BitmapFormat format)
|
|||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
constexpr SkRect to_skia_rect(auto const& rect)
|
||||
{
|
||||
return SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height());
|
||||
}
|
||||
|
||||
constexpr SkColor to_skia_color(Gfx::Color const& color)
|
||||
{
|
||||
return SkColorSetARGB(color.alpha(), color.red(), color.green(), color.blue());
|
||||
}
|
||||
|
||||
constexpr SkColor4f to_skia_color4f(Color const& color)
|
||||
{
|
||||
return {
|
||||
.fR = color.red() / 255.0f,
|
||||
.fG = color.green() / 255.0f,
|
||||
.fB = color.blue() / 255.0f,
|
||||
.fA = color.alpha() / 255.0f,
|
||||
};
|
||||
}
|
||||
|
||||
constexpr SkPoint to_skia_point(auto const& point)
|
||||
{
|
||||
return SkPoint::Make(point.x(), point.y());
|
||||
}
|
||||
|
||||
constexpr SkPathFillType to_skia_path_fill_type(Gfx::WindingRule winding_rule)
|
||||
{
|
||||
switch (winding_rule) {
|
||||
case Gfx::WindingRule::Nonzero:
|
||||
return SkPathFillType::kWinding;
|
||||
case Gfx::WindingRule::EvenOdd:
|
||||
return SkPathFillType::kEvenOdd;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
constexpr SkSamplingOptions to_skia_sampling_options(Gfx::ScalingMode scaling_mode)
|
||||
{
|
||||
switch (scaling_mode) {
|
||||
case Gfx::ScalingMode::NearestNeighbor:
|
||||
return SkSamplingOptions(SkFilterMode::kNearest);
|
||||
case Gfx::ScalingMode::BilinearBlend:
|
||||
case Gfx::ScalingMode::SmoothPixels:
|
||||
return SkSamplingOptions(SkFilterMode::kLinear);
|
||||
case Gfx::ScalingMode::BoxSampling:
|
||||
return SkSamplingOptions(SkCubicResampler::Mitchell());
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
SkPath to_skia_path(Path const& path);
|
||||
sk_sp<SkImageFilter> to_skia_image_filter(Gfx::Filter const& filter);
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue