mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 09:51:57 -05:00
LibWeb/Painting: Add ClippableAndScrollable mixin
Moves code that was duplicated across PaintableBox and InlinePaintable into separate class.
This commit is contained in:
parent
56e0cd0b1a
commit
cd07249482
8 changed files with 103 additions and 92 deletions
|
@ -527,6 +527,7 @@ set(SOURCES
|
|||
Painting/CommandExecutorCPU.cpp
|
||||
Painting/CommandList.cpp
|
||||
Painting/CheckBoxPaintable.cpp
|
||||
Painting/ClippableAndScrollable.cpp
|
||||
Painting/GradientPainting.cpp
|
||||
Painting/FilterPainting.cpp
|
||||
Painting/ImagePaintable.cpp
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <LibWeb/Layout/Viewport.h>
|
||||
#include <LibWeb/Painting/BackgroundPainting.h>
|
||||
#include <LibWeb/Painting/InlinePaintable.h>
|
||||
#include <LibWeb/Painting/PaintableBox.h>
|
||||
|
||||
namespace Web::Painting {
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Painting/ClippableAndScrollable.h>
|
||||
|
||||
namespace Web::Painting {
|
||||
|
||||
Optional<int> ClippableAndScrollable::scroll_frame_id() const
|
||||
{
|
||||
if (m_enclosing_scroll_frame)
|
||||
return m_enclosing_scroll_frame->id;
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<CSSPixelPoint> ClippableAndScrollable::enclosing_scroll_frame_offset() const
|
||||
{
|
||||
if (m_enclosing_scroll_frame)
|
||||
return m_enclosing_scroll_frame->offset;
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<CSSPixelRect> ClippableAndScrollable::clip_rect() const
|
||||
{
|
||||
if (m_enclosing_clip_frame) {
|
||||
auto rect = m_enclosing_clip_frame->rect();
|
||||
// NOTE: Since the painting command executor applies a CSS transform and the clip rect is calculated
|
||||
// with this transform taken into account, we need to remove the transform from the clip rect.
|
||||
// Otherwise, the transform will be applied twice to the clip rect.
|
||||
// Similarly, for hit-testing, the transform must be removed from the clip rectangle since the position
|
||||
// includes the transform.
|
||||
auto combined_transform = compute_combined_css_transform_for_clippable_and_scrollable();
|
||||
rect.translate_by(-combined_transform.translation().to_type<CSSPixels>());
|
||||
return rect;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Span<BorderRadiiClip const> ClippableAndScrollable::border_radii_clips() const
|
||||
{
|
||||
if (m_enclosing_clip_frame)
|
||||
return m_enclosing_clip_frame->border_radii_clips();
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
37
Userland/Libraries/LibWeb/Painting/ClippableAndScrollable.h
Normal file
37
Userland/Libraries/LibWeb/Painting/ClippableAndScrollable.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/Painting/ClipFrame.h>
|
||||
|
||||
namespace Web::Painting {
|
||||
|
||||
struct ScrollFrame : public RefCounted<ScrollFrame> {
|
||||
i32 id { -1 };
|
||||
CSSPixelPoint offset;
|
||||
};
|
||||
|
||||
class ClippableAndScrollable {
|
||||
public:
|
||||
virtual ~ClippableAndScrollable() = default;
|
||||
|
||||
void set_enclosing_scroll_frame(RefPtr<ScrollFrame> scroll_frame) { m_enclosing_scroll_frame = scroll_frame; }
|
||||
void set_enclosing_clip_frame(RefPtr<ClipFrame> clip_frame) { m_enclosing_clip_frame = clip_frame; }
|
||||
|
||||
[[nodiscard]] Optional<int> scroll_frame_id() const;
|
||||
[[nodiscard]] Optional<CSSPixelPoint> enclosing_scroll_frame_offset() const;
|
||||
[[nodiscard]] Optional<CSSPixelRect> clip_rect() const;
|
||||
[[nodiscard]] Span<BorderRadiiClip const> border_radii_clips() const;
|
||||
|
||||
virtual Gfx::AffineTransform compute_combined_css_transform_for_clippable_and_scrollable() const = 0;
|
||||
|
||||
private:
|
||||
RefPtr<ScrollFrame const> m_enclosing_scroll_frame;
|
||||
RefPtr<ClipFrame const> m_enclosing_clip_frame;
|
||||
};
|
||||
|
||||
}
|
|
@ -30,35 +30,6 @@ Layout::InlineNode const& InlinePaintable::layout_node() const
|
|||
return static_cast<Layout::InlineNode const&>(Paintable::layout_node());
|
||||
}
|
||||
|
||||
Optional<int> InlinePaintable::scroll_frame_id() const
|
||||
{
|
||||
if (m_enclosing_scroll_frame)
|
||||
return m_enclosing_scroll_frame->id;
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<CSSPixelPoint> InlinePaintable::enclosing_scroll_frame_offset() const
|
||||
{
|
||||
if (m_enclosing_scroll_frame)
|
||||
return m_enclosing_scroll_frame->offset;
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<CSSPixelRect> InlinePaintable::clip_rect() const
|
||||
{
|
||||
if (m_enclosing_clip_frame) {
|
||||
auto rect = m_enclosing_clip_frame->rect();
|
||||
|
||||
// NOTE: Since the painting command executor applies a CSS transform and the clip rect is calculated
|
||||
// with this transform taken into account, we need to remove the transform from the clip rect.
|
||||
// Otherwise, the transform will be applied twice to the clip rect.
|
||||
auto combined_transform = compute_combined_css_transform();
|
||||
rect.translate_by(-combined_transform.translation().to_type<CSSPixels>());
|
||||
return rect;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void InlinePaintable::before_paint(PaintContext& context, PaintPhase) const
|
||||
{
|
||||
if (scroll_frame_id().has_value()) {
|
||||
|
@ -218,7 +189,7 @@ void InlinePaintable::for_each_fragment(Callback callback) const
|
|||
|
||||
TraversalDecision InlinePaintable::hit_test(CSSPixelPoint position, HitTestType type, Function<TraversalDecision(HitTestResult)> const& callback) const
|
||||
{
|
||||
if (m_clip_rect.has_value() && !m_clip_rect.value().contains(position))
|
||||
if (clip_rect().has_value() && !clip_rect().value().contains(position))
|
||||
return TraversalDecision::Continue;
|
||||
|
||||
auto position_adjusted_by_scroll_offset = position;
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibWeb/Layout/InlineNode.h>
|
||||
#include <LibWeb/Painting/PaintableBox.h>
|
||||
#include <LibWeb/Painting/ClippableAndScrollable.h>
|
||||
#include <LibWeb/Painting/Paintable.h>
|
||||
#include <LibWeb/Painting/PaintableFragment.h>
|
||||
|
||||
namespace Web::Painting {
|
||||
|
||||
class InlinePaintable final : public Paintable {
|
||||
class InlinePaintable final : public Paintable
|
||||
, public ClippableAndScrollable {
|
||||
JS_CELL(InlinePaintable, Paintable);
|
||||
JS_DECLARE_ALLOCATOR(InlinePaintable);
|
||||
|
||||
|
@ -44,12 +46,10 @@ public:
|
|||
void set_outline_offset(CSSPixels outline_offset) { m_outline_offset = outline_offset; }
|
||||
CSSPixels outline_offset() const { return m_outline_offset; }
|
||||
|
||||
void set_enclosing_scroll_frame(RefPtr<ScrollFrame> scroll_frame) { m_enclosing_scroll_frame = scroll_frame; }
|
||||
void set_enclosing_clip_frame(RefPtr<ClipFrame> clip_frame) { m_enclosing_clip_frame = clip_frame; }
|
||||
|
||||
Optional<int> scroll_frame_id() const;
|
||||
Optional<CSSPixelPoint> enclosing_scroll_frame_offset() const;
|
||||
Optional<CSSPixelRect> clip_rect() const;
|
||||
virtual Gfx::AffineTransform compute_combined_css_transform_for_clippable_and_scrollable() const override
|
||||
{
|
||||
return compute_combined_css_transform();
|
||||
}
|
||||
|
||||
private:
|
||||
InlinePaintable(Layout::InlineNode const&);
|
||||
|
@ -57,10 +57,6 @@ private:
|
|||
template<typename Callback>
|
||||
void for_each_fragment(Callback) const;
|
||||
|
||||
Optional<CSSPixelRect> m_clip_rect;
|
||||
RefPtr<ScrollFrame const> m_enclosing_scroll_frame;
|
||||
RefPtr<ClipFrame const> m_enclosing_clip_frame;
|
||||
|
||||
Vector<ShadowData> m_box_shadow_data;
|
||||
Optional<BordersData> m_outline_data;
|
||||
CSSPixels m_outline_offset { 0 };
|
||||
|
|
|
@ -209,43 +209,6 @@ Optional<CSSPixelRect> PaintableBox::get_clip_rect() const
|
|||
return {};
|
||||
}
|
||||
|
||||
Optional<int> PaintableBox::scroll_frame_id() const
|
||||
{
|
||||
if (m_enclosing_scroll_frame)
|
||||
return m_enclosing_scroll_frame->id;
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<CSSPixelPoint> PaintableBox::enclosing_scroll_frame_offset() const
|
||||
{
|
||||
if (m_enclosing_scroll_frame)
|
||||
return m_enclosing_scroll_frame->offset;
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<CSSPixelRect> PaintableBox::clip_rect() const
|
||||
{
|
||||
if (m_enclosing_clip_frame) {
|
||||
auto rect = m_enclosing_clip_frame->rect();
|
||||
// NOTE: Since the painting command executor applies a CSS transform and the clip rect is calculated
|
||||
// with this transform in account, we need to remove the transform from the clip rect.
|
||||
// Otherwise, the transform will be applied twice to the clip rect.
|
||||
// Similarly, for hit-testing, the transform must be removed from the clip rectangle since the position
|
||||
// includes the transform.
|
||||
auto combined_transform = compute_combined_css_transform();
|
||||
rect.translate_by(-combined_transform.translation().to_type<CSSPixels>());
|
||||
return rect;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Span<BorderRadiiClip const> PaintableBox::border_radii_clips() const
|
||||
{
|
||||
if (m_enclosing_clip_frame)
|
||||
return m_enclosing_clip_frame->border_radii_clips();
|
||||
return {};
|
||||
}
|
||||
|
||||
void PaintableBox::before_paint(PaintContext& context, [[maybe_unused]] PaintPhase phase) const
|
||||
{
|
||||
if (!is_visible())
|
||||
|
|
|
@ -9,18 +9,15 @@
|
|||
#include <LibWeb/Painting/BorderPainting.h>
|
||||
#include <LibWeb/Painting/BorderRadiusCornerClipper.h>
|
||||
#include <LibWeb/Painting/ClipFrame.h>
|
||||
#include <LibWeb/Painting/ClippableAndScrollable.h>
|
||||
#include <LibWeb/Painting/Paintable.h>
|
||||
#include <LibWeb/Painting/PaintableFragment.h>
|
||||
#include <LibWeb/Painting/ShadowPainting.h>
|
||||
|
||||
namespace Web::Painting {
|
||||
|
||||
struct ScrollFrame : public RefCounted<ScrollFrame> {
|
||||
i32 id { -1 };
|
||||
CSSPixelPoint offset;
|
||||
};
|
||||
|
||||
class PaintableBox : public Paintable {
|
||||
class PaintableBox : public Paintable
|
||||
, public ClippableAndScrollable {
|
||||
JS_CELL(PaintableBox, Paintable);
|
||||
|
||||
public:
|
||||
|
@ -206,13 +203,10 @@ public:
|
|||
|
||||
Optional<CSSPixelRect> get_clip_rect() const;
|
||||
|
||||
void set_enclosing_scroll_frame(RefPtr<ScrollFrame> scroll_frame) { m_enclosing_scroll_frame = scroll_frame; }
|
||||
void set_enclosing_clip_frame(RefPtr<ClipFrame> clip_frame) { m_enclosing_clip_frame = clip_frame; }
|
||||
|
||||
Optional<int> scroll_frame_id() const;
|
||||
Optional<CSSPixelPoint> enclosing_scroll_frame_offset() const;
|
||||
Optional<CSSPixelRect> clip_rect() const;
|
||||
Span<BorderRadiiClip const> border_radii_clips() const;
|
||||
virtual Gfx::AffineTransform compute_combined_css_transform_for_clippable_and_scrollable() const override
|
||||
{
|
||||
return compute_combined_css_transform();
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit PaintableBox(Layout::Box const&);
|
||||
|
|
Loading…
Add table
Reference in a new issue