Add class-local allocation macros for operator new/delete through AK's malloc helpers. The macros can optionally choose a HeapPartition. Add Layout and Painting partitions, plus basic partition stats helpers. Use the new partitions for LibWeb layout and painting object hierarchies and layout-state side data.
187 lines
6.5 KiB
C++
187 lines
6.5 KiB
C++
/*
|
|
* Copyright (c) 2022-2023, Andreas Kling <andreas@ladybird.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/RefCounted.h>
|
|
#include <AK/WeakPtr.h>
|
|
#include <AK/Weakable.h>
|
|
#include <AK/kmalloc.h>
|
|
#include <LibGC/Ptr.h>
|
|
#include <LibWeb/CSS/ComputedValues.h>
|
|
#include <LibWeb/CSS/Display.h>
|
|
#include <LibWeb/Export.h>
|
|
#include <LibWeb/Forward.h>
|
|
#include <LibWeb/InvalidateDisplayList.h>
|
|
#include <LibWeb/Painting/ChromeWidget.h>
|
|
#include <LibWeb/Painting/HitTestResult.h>
|
|
#include <LibWeb/Painting/ShadowData.h>
|
|
#include <LibWeb/PixelUnits.h>
|
|
#include <LibWeb/RefCountedTreeNode.h>
|
|
|
|
namespace Web::Painting {
|
|
|
|
enum class PaintPhase {
|
|
Background,
|
|
Border,
|
|
TableCollapsedBorder,
|
|
Foreground,
|
|
Outline,
|
|
Overlay,
|
|
};
|
|
|
|
class WEB_API Paintable
|
|
: public RefCounted<Paintable>
|
|
, public Weakable<Paintable>
|
|
, public RefCountedTreeNode<Paintable> {
|
|
|
|
public:
|
|
AK_ALLOC_WITH_KMALLOC_PARTITION(HeapPartition::Painting);
|
|
|
|
virtual ~Paintable();
|
|
|
|
virtual StringView class_name() const { return "Paintable"sv; }
|
|
|
|
[[nodiscard]] bool is_visible() const
|
|
{
|
|
auto const& cv = computed_values();
|
|
return cv.visibility() == CSS::Visibility::Visible && cv.opacity() != 0;
|
|
}
|
|
[[nodiscard]] bool is_positioned() const { return m_positioned; }
|
|
[[nodiscard]] bool is_fixed_position() const { return m_fixed_position; }
|
|
[[nodiscard]] bool is_sticky_position() const { return m_sticky_position; }
|
|
[[nodiscard]] bool is_absolutely_positioned() const { return m_absolutely_positioned; }
|
|
[[nodiscard]] bool is_floating() const { return m_floating; }
|
|
[[nodiscard]] bool is_inline() const { return m_inline; }
|
|
[[nodiscard]] CSS::Display display() const { return m_display; }
|
|
|
|
bool has_stacking_context() const;
|
|
RefPtr<StackingContext> enclosing_stacking_context();
|
|
|
|
virtual void paint(DisplayListRecordingContext&, PaintPhase) const { }
|
|
void paint_inspector_overlay(DisplayListRecordingContext&) const;
|
|
|
|
virtual bool forms_unconnected_subtree() const { return false; }
|
|
|
|
virtual bool handle_mousewheel(Badge<EventHandler>, CSSPixelPoint, unsigned buttons, unsigned modifiers, double wheel_delta_x, double wheel_delta_y);
|
|
|
|
Layout::Node const& layout_node() const
|
|
{
|
|
VERIFY(m_layout_node);
|
|
return *m_layout_node;
|
|
}
|
|
Layout::Node& layout_node() { return const_cast<Layout::Node&>(const_cast<Paintable const&>(*this).layout_node()); }
|
|
|
|
[[nodiscard]] GC::Ptr<DOM::Node> dom_node();
|
|
[[nodiscard]] GC::Ptr<DOM::Node const> dom_node() const;
|
|
void set_dom_node(GC::Ptr<DOM::Node>);
|
|
|
|
CSS::ImmutableComputedValues const& computed_values() const;
|
|
|
|
bool visible_for_hit_testing() const;
|
|
|
|
GC::Ptr<HTML::Navigable> navigable() const;
|
|
|
|
virtual void set_needs_repaint(InvalidateDisplayList = InvalidateDisplayList::Yes);
|
|
|
|
RefPtr<PaintableBox> containing_block() const;
|
|
|
|
template<typename T>
|
|
bool fast_is() const = delete;
|
|
|
|
[[nodiscard]] virtual bool is_navigable_container_viewport_paintable() const { return false; }
|
|
[[nodiscard]] virtual bool is_viewport_paintable() const { return false; }
|
|
[[nodiscard]] virtual bool is_paintable_box() const { return false; }
|
|
[[nodiscard]] virtual bool is_paintable_with_lines() const { return false; }
|
|
[[nodiscard]] virtual bool is_svg_paintable() const { return false; }
|
|
[[nodiscard]] virtual bool is_svg_svg_paintable() const { return false; }
|
|
[[nodiscard]] virtual bool is_svg_path_paintable() const { return false; }
|
|
[[nodiscard]] virtual bool is_svg_graphics_paintable() const { return false; }
|
|
[[nodiscard]] virtual bool is_text_paintable() const { return false; }
|
|
|
|
DOM::Document const& document() const;
|
|
DOM::Document& document();
|
|
|
|
CSSPixelPoint box_type_agnostic_position() const;
|
|
|
|
void scroll_ancestor_to_offset_into_view(size_t offset);
|
|
|
|
enum class SelectionState : u8 {
|
|
None, // No selection
|
|
Start, // Selection starts in this Node
|
|
End, // Selection ends in this Node
|
|
StartAndEnd, // Selection starts and ends in this Node
|
|
Full, // Selection starts before and ends after this Node
|
|
};
|
|
|
|
SelectionState selection_state() const { return m_selection_state; }
|
|
void set_selection_state(SelectionState state);
|
|
|
|
// https://drafts.csswg.org/css-pseudo-4/#highlight-styling
|
|
struct TextDecorationStyle {
|
|
Vector<CSS::TextDecorationLine> line;
|
|
CSS::TextDecorationStyle style;
|
|
Color color;
|
|
};
|
|
struct SelectionStyle {
|
|
Color background_color;
|
|
Optional<Color> text_color;
|
|
Optional<Vector<ShadowData>> text_shadow;
|
|
Optional<TextDecorationStyle> text_decoration;
|
|
|
|
bool has_styling() const
|
|
{
|
|
return background_color.alpha() > 0 || text_color.has_value() || text_shadow.has_value() || text_decoration.has_value();
|
|
}
|
|
};
|
|
[[nodiscard]] SelectionStyle selection_style() const;
|
|
|
|
[[nodiscard]] String debug_description() const;
|
|
|
|
friend class Layout::Node;
|
|
|
|
protected:
|
|
explicit Paintable(Layout::Node const&);
|
|
|
|
void paint_with_inspector_overlay_context(DisplayListRecordingContext&, Function<void()> const&) const;
|
|
bool has_layout_node() const { return m_layout_node; }
|
|
|
|
virtual void paint_inspector_overlay_internal(DisplayListRecordingContext&) const { }
|
|
Optional<WeakPtr<PaintableBox>> mutable m_containing_block;
|
|
|
|
private:
|
|
void detach_from_layout_node(Badge<Layout::Node>)
|
|
{
|
|
m_containing_block.clear();
|
|
m_layout_node.clear();
|
|
}
|
|
|
|
GC::Weak<DOM::Node> m_dom_node;
|
|
WeakPtr<Layout::Node const> m_layout_node;
|
|
|
|
SelectionState m_selection_state { SelectionState::None };
|
|
|
|
bool m_positioned : 1 { false };
|
|
bool m_fixed_position : 1 { false };
|
|
bool m_sticky_position : 1 { false };
|
|
bool m_absolutely_positioned : 1 { false };
|
|
bool m_floating : 1 { false };
|
|
bool m_inline : 1 { false };
|
|
CSS::Display m_display;
|
|
};
|
|
|
|
template<>
|
|
inline bool Paintable::fast_is<PaintableBox>() const { return is_paintable_box(); }
|
|
|
|
template<>
|
|
inline bool Paintable::fast_is<PaintableWithLines>() const { return is_paintable_with_lines(); }
|
|
|
|
template<>
|
|
inline bool Paintable::fast_is<TextPaintable>() const { return is_text_paintable(); }
|
|
|
|
WEB_API Painting::BorderRadiiData normalize_border_radii_data(Layout::Node const& node, CSSPixelRect const& border_rect, CSSPixelRect const& reference_rect, CSS::BorderRadiusData const& top_left_radius, CSS::BorderRadiusData const& top_right_radius, CSS::BorderRadiusData const& bottom_right_radius, CSS::BorderRadiusData const& bottom_left_radius);
|
|
|
|
}
|