mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 17:27:34 +00:00
PixelPaint: Split bitmap() of Layer into {content, display}_bitmap
This is in preparation to support masking of Layers. We now distinguish between the "display_bitmap" which will be the whole Layer with every effect applied and the "content_bitmap" which contains the actual unmodified pixels in the Layer.
This commit is contained in:
parent
b6510f8e76
commit
31a9196bfe
14 changed files with 73 additions and 42 deletions
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2022, Tobias Christiansen <tobyase@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -37,7 +38,7 @@ ErrorOr<NonnullRefPtr<Layer>> Layer::try_create_with_bitmap(Image& image, Nonnul
|
|||
|
||||
ErrorOr<NonnullRefPtr<Layer>> Layer::try_create_snapshot(Image& image, Layer const& layer)
|
||||
{
|
||||
auto bitmap = TRY(layer.bitmap().clone());
|
||||
auto bitmap = TRY(layer.content_bitmap().clone());
|
||||
auto snapshot = TRY(try_create_with_bitmap(image, move(bitmap), layer.name()));
|
||||
|
||||
/*
|
||||
|
@ -57,13 +58,15 @@ ErrorOr<NonnullRefPtr<Layer>> Layer::try_create_snapshot(Image& image, Layer con
|
|||
Layer::Layer(Image& image, NonnullRefPtr<Gfx::Bitmap> bitmap, String name)
|
||||
: m_image(image)
|
||||
, m_name(move(name))
|
||||
, m_bitmap(move(bitmap))
|
||||
, m_content_bitmap(move(bitmap))
|
||||
, m_cached_display_bitmap(m_content_bitmap)
|
||||
{
|
||||
}
|
||||
|
||||
void Layer::did_modify_bitmap(Gfx::IntRect const& rect)
|
||||
{
|
||||
m_image.layer_did_modify_bitmap({}, *this, rect);
|
||||
update_cached_bitmap();
|
||||
}
|
||||
|
||||
void Layer::set_visible(bool visible)
|
||||
|
@ -110,12 +113,12 @@ RefPtr<Gfx::Bitmap> Layer::try_copy_bitmap(Selection const& selection) const
|
|||
auto layer_point = image_point - m_location;
|
||||
auto result_point = image_point - selection_rect.top_left();
|
||||
|
||||
if (!m_bitmap->physical_rect().contains(layer_point)) {
|
||||
if (!m_content_bitmap->physical_rect().contains(layer_point)) {
|
||||
result->set_pixel(result_point, Gfx::Color::Transparent);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto pixel = m_bitmap->get_pixel(layer_point);
|
||||
auto pixel = m_content_bitmap->get_pixel(layer_point);
|
||||
|
||||
// Widen to int before multiplying to avoid overflow issues
|
||||
auto pixel_alpha = static_cast<int>(pixel.alpha());
|
||||
|
@ -132,11 +135,28 @@ RefPtr<Gfx::Bitmap> Layer::try_copy_bitmap(Selection const& selection) const
|
|||
|
||||
void Layer::erase_selection(Selection const& selection)
|
||||
{
|
||||
Gfx::Painter painter { bitmap() };
|
||||
Gfx::Painter painter { content_bitmap() };
|
||||
auto const image_and_selection_intersection = m_image.rect().intersected(selection.bounding_rect());
|
||||
auto const translated_to_layer_space = image_and_selection_intersection.translated(-location());
|
||||
painter.clear_rect(translated_to_layer_space, Color::Transparent);
|
||||
did_modify_bitmap(translated_to_layer_space);
|
||||
}
|
||||
|
||||
void Layer::set_content_bitmap(NonnullRefPtr<Gfx::Bitmap> bitmap)
|
||||
{
|
||||
m_content_bitmap = move(bitmap);
|
||||
update_cached_bitmap();
|
||||
}
|
||||
|
||||
void Layer::update_cached_bitmap()
|
||||
{
|
||||
if (!is_masked()) {
|
||||
if (m_content_bitmap.ptr() == m_cached_display_bitmap.ptr())
|
||||
return;
|
||||
|
||||
m_cached_display_bitmap = m_content_bitmap;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue