LibWeb: Draw elements with opacity in a separate stacking context

This commit is contained in:
Egor Ananyin 2021-07-23 13:19:16 +03:00 committed by Ali Mohammad Pur
parent 0e6ba6e1d3
commit f567414f65
Notes: sideshowbarker 2024-07-18 08:23:46 +09:00
3 changed files with 27 additions and 1 deletions

View File

@ -77,6 +77,9 @@ bool Node::establishes_stacking_context() const
auto position = computed_values().position();
if (position == CSS::Position::Absolute || position == CSS::Position::Relative || position == CSS::Position::Fixed || position == CSS::Position::Sticky)
return true;
auto opacity = computed_values().opacity();
if (opacity.has_value() && opacity.value() != 1.0f)
return true;
return false;
}

View File

@ -6,6 +6,7 @@
#include <AK/QuickSort.h>
#include <AK/StringBuilder.h>
#include <LibGfx/Painter.h>
#include <LibWeb/DOM/Node.h>
#include <LibWeb/Layout/Box.h>
#include <LibWeb/Layout/InitialContainingBlockBox.h>
@ -71,7 +72,7 @@ void StackingContext::paint_descendants(PaintContext& context, Node& box, Stacki
});
}
void StackingContext::paint(PaintContext& context)
void StackingContext::paint_internal(PaintContext& context)
{
// For a more elaborate description of the algorithm, see CSS 2.1 Appendix E
// Draw the background and borders for the context root (steps 1, 2)
@ -101,6 +102,26 @@ void StackingContext::paint(PaintContext& context)
paint_descendants(context, m_box, StackingContextPaintPhase::FocusAndOverlay);
}
void StackingContext::paint(PaintContext& context)
{
auto opacity = m_box.computed_values().opacity();
if (opacity.has_value() && opacity.value() == 0.0f)
return;
if (opacity.has_value() && opacity.value() != 1.0f) {
auto bitmap = context.painter().target();
auto new_bitmap = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, bitmap->size());
if (!new_bitmap)
return;
Gfx::Painter painter(*new_bitmap);
PaintContext paint_context(painter, context.palette(), context.scroll_offset());
paint_internal(paint_context);
context.painter().blit(Gfx::IntPoint(m_box.absolute_position()), *new_bitmap, Gfx::IntRect(m_box.absolute_rect()), opacity.value());
} else {
paint_internal(context);
}
}
HitTestResult StackingContext::hit_test(const Gfx::IntPoint& position, HitTestType type) const
{
HitTestResult result;

View File

@ -35,6 +35,8 @@ private:
Box& m_box;
StackingContext* const m_parent { nullptr };
Vector<StackingContext*> m_children;
void paint_internal(PaintContext&);
};
}