1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 02:27:43 +00:00

LibGfx: Add Painter::blit_filtered() and blit_brightened()

blit_filtered() can be used to easily implement per-pixel filtered blit
functions. All you need to do is provide a callback that can compute
the Color for each pixel based on the original Color.
This commit is contained in:
Andreas Kling 2020-03-30 19:39:37 +02:00
parent fb2be5c404
commit 7976ef7a79
2 changed files with 20 additions and 3 deletions

View file

@ -29,6 +29,7 @@
#include "Emoji.h" #include "Emoji.h"
#include "Font.h" #include "Font.h"
#include <AK/Assertions.h> #include <AK/Assertions.h>
#include <AK/Function.h>
#include <AK/Memory.h> #include <AK/Memory.h>
#include <AK/StdLibExtras.h> #include <AK/StdLibExtras.h>
#include <AK/StringBuilder.h> #include <AK/StringBuilder.h>
@ -377,7 +378,7 @@ void Painter::blit_with_opacity(const Point& position, const Gfx::Bitmap& source
} }
} }
void Painter::blit_dimmed(const Point& position, const Gfx::Bitmap& source, const Rect& src_rect) void Painter::blit_filtered(const Point& position, const Gfx::Bitmap& source, const Rect& src_rect, Function<Color(Color)> filter)
{ {
Rect safe_src_rect = src_rect.intersected(source.rect()); Rect safe_src_rect = src_rect.intersected(source.rect());
auto dst_rect = Rect(position, safe_src_rect.size()).translated(translation()); auto dst_rect = Rect(position, safe_src_rect.size()).translated(translation());
@ -397,17 +398,31 @@ void Painter::blit_dimmed(const Point& position, const Gfx::Bitmap& source, cons
for (int x = 0; x <= (last_column - first_column); ++x) { for (int x = 0; x <= (last_column - first_column); ++x) {
u8 alpha = Color::from_rgba(src[x]).alpha(); u8 alpha = Color::from_rgba(src[x]).alpha();
if (alpha == 0xff) if (alpha == 0xff)
dst[x] = Color::from_rgba(src[x]).to_grayscale().lightened().value(); dst[x] = filter(Color::from_rgba(src[x])).value();
else if (!alpha) else if (!alpha)
continue; continue;
else else
dst[x] = Color::from_rgba(dst[x]).blend(Color::from_rgba(src[x]).to_grayscale().lightened()).value(); dst[x] = Color::from_rgba(dst[x]).blend(filter(Color::from_rgba(src[x]))).value();
} }
dst += dst_skip; dst += dst_skip;
src += src_skip; src += src_skip;
} }
} }
void Painter::blit_brightened(const Point& position, const Gfx::Bitmap& source, const Rect& src_rect)
{
return blit_filtered(position, source, src_rect, [](Color src) {
return src.lightened();
});
}
void Painter::blit_dimmed(const Point& position, const Gfx::Bitmap& source, const Rect& src_rect)
{
return blit_filtered(position, source, src_rect, [](Color src) {
return src.to_grayscale().lightened();
});
}
void Painter::draw_tiled_bitmap(const Rect& a_dst_rect, const Gfx::Bitmap& source) void Painter::draw_tiled_bitmap(const Rect& a_dst_rect, const Gfx::Bitmap& source)
{ {
auto dst_rect = a_dst_rect.translated(translation()); auto dst_rect = a_dst_rect.translated(translation());

View file

@ -56,6 +56,8 @@ public:
void draw_scaled_bitmap(const Rect& dst_rect, const Gfx::Bitmap&, const Rect& src_rect); void draw_scaled_bitmap(const Rect& dst_rect, const Gfx::Bitmap&, const Rect& src_rect);
void blit(const Point&, const Gfx::Bitmap&, const Rect& src_rect, float opacity = 1.0f); void blit(const Point&, const Gfx::Bitmap&, const Rect& src_rect, float opacity = 1.0f);
void blit_dimmed(const Point&, const Gfx::Bitmap&, const Rect& src_rect); void blit_dimmed(const Point&, const Gfx::Bitmap&, const Rect& src_rect);
void blit_brightened(const Point&, const Gfx::Bitmap&, const Rect& src_rect);
void blit_filtered(const Point&, const Gfx::Bitmap&, const Rect& src_rect, Function<Color(Color)>);
void draw_tiled_bitmap(const Rect& dst_rect, const Gfx::Bitmap&); void draw_tiled_bitmap(const Rect& dst_rect, const Gfx::Bitmap&);
void blit_offset(const Point&, const Gfx::Bitmap&, const Rect& src_rect, const Point&); void blit_offset(const Point&, const Gfx::Bitmap&, const Rect& src_rect, const Point&);
void blit_scaled(const Rect&, const Gfx::Bitmap&, const Rect&, float, float); void blit_scaled(const Rect&, const Gfx::Bitmap&, const Rect&, float, float);