mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 04:09:13 +00:00
LibWeb: Add internals
call to dump display list
It's useful to have tests that dump display list items, so we can more easily see how changes to the display list recording process affect the output. Even the small sample test added in this commit shows that we currently record an unnecessary AddClipRect item for empty paint phases. For now, the dump doesn't include every single property of an item, but we can shape it to include more useful information as we iterate on it.
This commit is contained in:
parent
6be559f639
commit
8ae7417445
Notes:
github-actions[bot]
2025-07-13 17:16:19 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 8ae7417445
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5390
Reviewed-by: https://github.com/gmta ✅
11 changed files with 332 additions and 10 deletions
|
@ -6622,6 +6622,15 @@ ElementByIdMap& Document::element_by_id() const
|
|||
return *m_element_by_id;
|
||||
}
|
||||
|
||||
String Document::dump_display_list()
|
||||
{
|
||||
update_layout(UpdateLayoutReason::DumpDisplayList);
|
||||
auto display_list = record_display_list(HTML::PaintConfig {});
|
||||
if (!display_list)
|
||||
return {};
|
||||
return display_list->dump();
|
||||
}
|
||||
|
||||
GC::Ptr<Element> ElementByIdMap::get(FlyString const& element_id) const
|
||||
{
|
||||
if (auto elements = m_map.get(element_id); elements.has_value() && !elements->is_empty()) {
|
||||
|
|
|
@ -71,6 +71,7 @@ enum class InvalidateLayoutTreeReason {
|
|||
X(DocumentElementsFromPoint) \
|
||||
X(DocumentFindMatchingText) \
|
||||
X(DocumentSetDesignMode) \
|
||||
X(DumpDisplayList) \
|
||||
X(ElementCheckVisibility) \
|
||||
X(ElementClientHeight) \
|
||||
X(ElementClientLeft) \
|
||||
|
@ -903,6 +904,8 @@ public:
|
|||
auto& script_blocking_style_sheet_set() { return m_script_blocking_style_sheet_set; }
|
||||
auto const& script_blocking_style_sheet_set() const { return m_script_blocking_style_sheet_set; }
|
||||
|
||||
String dump_display_list();
|
||||
|
||||
protected:
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
|
|
@ -257,4 +257,9 @@ bool Internals::headless()
|
|||
return page().client().is_headless();
|
||||
}
|
||||
|
||||
String Internals::dump_display_list()
|
||||
{
|
||||
return window().associated_document().dump_display_list();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,6 +62,8 @@ public:
|
|||
|
||||
bool headless();
|
||||
|
||||
String dump_display_list();
|
||||
|
||||
private:
|
||||
explicit Internals(JS::Realm&);
|
||||
|
||||
|
|
|
@ -50,4 +50,6 @@ interface Internals {
|
|||
undefined setBrowserZoom(double factor);
|
||||
|
||||
readonly attribute boolean headless;
|
||||
|
||||
DOMString dumpDisplayList();
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
* Copyright (c) 2024-2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -41,4 +41,194 @@ void PaintInnerBoxShadow::translate_by(Gfx::IntPoint const& offset)
|
|||
box_shadow_params.device_content_rect.translate_by(offset);
|
||||
}
|
||||
|
||||
void DrawGlyphRun::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("DrawGlyphRun rect={} translation={} color={} scale={}", rect, translation, color, scale);
|
||||
}
|
||||
|
||||
void FillRect::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("FillRect rect={} color={}", rect, color);
|
||||
}
|
||||
|
||||
void DrawPaintingSurface::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("DrawPaintingSurface dst_rect={} src_rect={}", dst_rect, src_rect);
|
||||
}
|
||||
|
||||
void DrawScaledImmutableBitmap::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("DrawScaledImmutableBitmap dst_rect={} clip_rect={}", dst_rect, clip_rect);
|
||||
}
|
||||
|
||||
void DrawRepeatedImmutableBitmap::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("DrawRepeatedImmutableBitmap dst_rect={} clip_rect={}", dst_rect, clip_rect);
|
||||
}
|
||||
|
||||
void Save::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("Save");
|
||||
}
|
||||
|
||||
void SaveLayer::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("SaveLayer");
|
||||
}
|
||||
|
||||
void Restore::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("Restore");
|
||||
}
|
||||
|
||||
void Translate::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("Translate delta={}", delta);
|
||||
}
|
||||
|
||||
void AddClipRect::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("AddClipRect rect={}", rect);
|
||||
}
|
||||
|
||||
void PushStackingContext::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("PushStackingContext");
|
||||
}
|
||||
|
||||
void PopStackingContext::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("PopStackingContext");
|
||||
}
|
||||
|
||||
void PaintLinearGradient::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("PaintLinearGradient rect={}", gradient_rect);
|
||||
}
|
||||
|
||||
void PaintRadialGradient::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("PaintRadialGradient rect={} center={} size={}", rect, center, size);
|
||||
}
|
||||
|
||||
void PaintConicGradient::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("PaintConicGradient rect={} position={} angle={}", rect, position, conic_gradient_data.start_angle);
|
||||
}
|
||||
|
||||
void PaintOuterBoxShadow::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("PaintOuterBoxShadow content_rect={} offset=({},{}) blur_radius={} spread_distance={} color={}", box_shadow_params.device_content_rect, box_shadow_params.offset_x, box_shadow_params.offset_y, box_shadow_params.blur_radius, box_shadow_params.spread_distance, box_shadow_params.color);
|
||||
}
|
||||
|
||||
void PaintInnerBoxShadow::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("PaintInnerBoxShadow content_rect={} offset=({},{}) blur_radius={} spread_distance={} color={}", box_shadow_params.device_content_rect, box_shadow_params.offset_x, box_shadow_params.offset_y, box_shadow_params.blur_radius, box_shadow_params.spread_distance, box_shadow_params.color);
|
||||
}
|
||||
|
||||
void PaintTextShadow::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("PaintTextShadow shadow_rect={} text_rect={} draw_location={} blur_radius={} color={} scale={}", shadow_bounding_rect, text_rect, draw_location, blur_radius, color, glyph_run_scale);
|
||||
}
|
||||
|
||||
void FillRectWithRoundedCorners::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("FillRectWithRoundedCorners rect={} color={}", rect, color);
|
||||
}
|
||||
|
||||
void FillPathUsingColor::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("FillPathUsingColor");
|
||||
}
|
||||
|
||||
void FillPathUsingPaintStyle::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("FillPathUsingPaintStyle");
|
||||
}
|
||||
|
||||
void StrokePathUsingColor::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("StrokePathUsingColor");
|
||||
}
|
||||
|
||||
void StrokePathUsingPaintStyle::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("StrokePathUsingPaintStyle");
|
||||
}
|
||||
|
||||
void DrawEllipse::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("DrawEllipse rect={} color={} thickness={}", rect, color, thickness);
|
||||
}
|
||||
|
||||
void FillEllipse::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("FillEllipse rect={} color={}", rect, color);
|
||||
}
|
||||
|
||||
void DrawLine::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("DrawLine from={} to={} color={} thickness={}", from, to, color, thickness);
|
||||
}
|
||||
|
||||
void ApplyBackdropFilter::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("ApplyBackdropFilter backdrop_region={}", backdrop_region);
|
||||
}
|
||||
|
||||
void DrawRect::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("DrawRect rect={} color={} rough={}", rect, color, rough);
|
||||
}
|
||||
|
||||
void DrawTriangleWave::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("DrawTriangleWave p1={} p2={} color={} amplitude={} thickness={}", p1, p2, color, amplitude, thickness);
|
||||
}
|
||||
|
||||
void AddRoundedRectClip::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("AddRoundedRectClip rect={}", border_rect);
|
||||
}
|
||||
|
||||
void AddMask::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("AddMask rect={} has_display_list={}", rect, display_list != nullptr);
|
||||
}
|
||||
|
||||
void PaintNestedDisplayList::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("PaintNestedDisplayList rect={}", rect);
|
||||
}
|
||||
|
||||
void PaintScrollBar::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("PaintScrollBar");
|
||||
}
|
||||
|
||||
void ApplyOpacity::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("ApplyOpacity opacity={}", opacity);
|
||||
}
|
||||
|
||||
void ApplyCompositeAndBlendingOperator::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("ApplyCompositeAndBlendingOperator");
|
||||
}
|
||||
|
||||
void ApplyFilter::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("ApplyFilter");
|
||||
}
|
||||
|
||||
void ApplyTransform::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("ApplyTransform");
|
||||
}
|
||||
|
||||
void ApplyMaskBitmap::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("ApplyMaskBitmap");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
* Copyright (c) 2024-2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include <AK/Forward.h>
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <AK/Utf8View.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibGfx/Color.h>
|
||||
#include <LibGfx/CompositingAndBlendingOperator.h>
|
||||
|
@ -17,16 +16,13 @@
|
|||
#include <LibGfx/LineStyle.h>
|
||||
#include <LibGfx/PaintStyle.h>
|
||||
#include <LibGfx/PaintingSurface.h>
|
||||
#include <LibGfx/Palette.h>
|
||||
#include <LibGfx/Path.h>
|
||||
#include <LibGfx/Point.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <LibGfx/ScalingMode.h>
|
||||
#include <LibGfx/Size.h>
|
||||
#include <LibGfx/TextAlignment.h>
|
||||
#include <LibGfx/TextLayout.h>
|
||||
#include <LibWeb/CSS/ComputedValues.h>
|
||||
#include <LibWeb/CSS/Enums.h>
|
||||
#include <LibWeb/Painting/BorderRadiiData.h>
|
||||
#include <LibWeb/Painting/BorderRadiusCornerClipper.h>
|
||||
#include <LibWeb/Painting/DisplayListRecorder.h>
|
||||
|
@ -48,6 +44,7 @@ struct DrawGlyphRun {
|
|||
Gfx::Orientation orientation { Gfx::Orientation::Horizontal };
|
||||
|
||||
void translate_by(Gfx::IntPoint const& offset);
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct FillRect {
|
||||
|
@ -56,6 +53,7 @@ struct FillRect {
|
|||
|
||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
||||
void translate_by(Gfx::IntPoint const& offset) { rect.translate_by(offset); }
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct DrawPaintingSurface {
|
||||
|
@ -66,6 +64,7 @@ struct DrawPaintingSurface {
|
|||
|
||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return dst_rect; }
|
||||
void translate_by(Gfx::IntPoint const& offset) { dst_rect.translate_by(offset); }
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct DrawScaledImmutableBitmap {
|
||||
|
@ -80,6 +79,7 @@ struct DrawScaledImmutableBitmap {
|
|||
dst_rect.translate_by(offset);
|
||||
clip_rect.translate_by(offset);
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct DrawRepeatedImmutableBitmap {
|
||||
|
@ -95,16 +95,26 @@ struct DrawRepeatedImmutableBitmap {
|
|||
Repeat repeat;
|
||||
|
||||
void translate_by(Gfx::IntPoint const& offset) { dst_rect.translate_by(offset); }
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct Save { };
|
||||
struct SaveLayer { };
|
||||
struct Restore { };
|
||||
struct Save {
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct SaveLayer {
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct Restore {
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct Translate {
|
||||
Gfx::IntPoint delta;
|
||||
|
||||
void translate_by(Gfx::IntPoint const& offset) { delta.translate_by(offset); }
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct AddClipRect {
|
||||
|
@ -113,6 +123,7 @@ struct AddClipRect {
|
|||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
||||
bool is_clip_or_mask() const { return true; }
|
||||
void translate_by(Gfx::IntPoint const& offset) { rect.translate_by(offset); }
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct PushStackingContext {
|
||||
|
@ -133,9 +144,12 @@ struct PushStackingContext {
|
|||
clip_path.value().transform(Gfx::AffineTransform().translate(offset.to_type<float>()));
|
||||
}
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct PopStackingContext { };
|
||||
struct PopStackingContext {
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct PaintLinearGradient {
|
||||
Gfx::IntRect gradient_rect;
|
||||
|
@ -147,6 +161,7 @@ struct PaintLinearGradient {
|
|||
{
|
||||
gradient_rect.translate_by(offset);
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct PaintOuterBoxShadow {
|
||||
|
@ -154,6 +169,7 @@ struct PaintOuterBoxShadow {
|
|||
|
||||
[[nodiscard]] Gfx::IntRect bounding_rect() const;
|
||||
void translate_by(Gfx::IntPoint const& offset);
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct PaintInnerBoxShadow {
|
||||
|
@ -161,6 +177,7 @@ struct PaintInnerBoxShadow {
|
|||
|
||||
[[nodiscard]] Gfx::IntRect bounding_rect() const;
|
||||
void translate_by(Gfx::IntPoint const& offset);
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct PaintTextShadow {
|
||||
|
@ -174,6 +191,7 @@ struct PaintTextShadow {
|
|||
|
||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return { draw_location.to_type<int>(), shadow_bounding_rect.size() }; }
|
||||
void translate_by(Gfx::IntPoint const& offset) { draw_location.translate_by(offset.to_type<float>()); }
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct FillRectWithRoundedCorners {
|
||||
|
@ -183,6 +201,7 @@ struct FillRectWithRoundedCorners {
|
|||
|
||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
||||
void translate_by(Gfx::IntPoint const& offset) { rect.translate_by(offset); }
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct FillPathUsingColor {
|
||||
|
@ -199,6 +218,7 @@ struct FillPathUsingColor {
|
|||
path_bounding_rect.translate_by(offset);
|
||||
aa_translation.translate_by(offset.to_type<float>());
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct FillPathUsingPaintStyle {
|
||||
|
@ -216,6 +236,7 @@ struct FillPathUsingPaintStyle {
|
|||
path_bounding_rect.translate_by(offset);
|
||||
aa_translation.translate_by(offset.to_type<float>());
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct StrokePathUsingColor {
|
||||
|
@ -237,6 +258,7 @@ struct StrokePathUsingColor {
|
|||
path_bounding_rect.translate_by(offset);
|
||||
aa_translation.translate_by(offset.to_type<float>());
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct StrokePathUsingPaintStyle {
|
||||
|
@ -259,6 +281,7 @@ struct StrokePathUsingPaintStyle {
|
|||
path_bounding_rect.translate_by(offset);
|
||||
aa_translation.translate_by(offset.to_type<float>());
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct DrawEllipse {
|
||||
|
@ -272,6 +295,7 @@ struct DrawEllipse {
|
|||
{
|
||||
rect.translate_by(offset);
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct FillEllipse {
|
||||
|
@ -284,6 +308,7 @@ struct FillEllipse {
|
|||
{
|
||||
rect.translate_by(offset);
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct DrawLine {
|
||||
|
@ -299,6 +324,7 @@ struct DrawLine {
|
|||
from.translate_by(offset);
|
||||
to.translate_by(offset);
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct ApplyBackdropFilter {
|
||||
|
@ -312,6 +338,7 @@ struct ApplyBackdropFilter {
|
|||
{
|
||||
backdrop_region.translate_by(offset);
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct DrawRect {
|
||||
|
@ -322,6 +349,7 @@ struct DrawRect {
|
|||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
||||
|
||||
void translate_by(Gfx::IntPoint const& offset) { rect.translate_by(offset); }
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct PaintRadialGradient {
|
||||
|
@ -333,6 +361,7 @@ struct PaintRadialGradient {
|
|||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
||||
|
||||
void translate_by(Gfx::IntPoint const& offset) { rect.translate_by(offset); }
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct PaintConicGradient {
|
||||
|
@ -343,6 +372,7 @@ struct PaintConicGradient {
|
|||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
|
||||
|
||||
void translate_by(Gfx::IntPoint const& offset) { rect.translate_by(offset); }
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct DrawTriangleWave {
|
||||
|
@ -357,6 +387,7 @@ struct DrawTriangleWave {
|
|||
p1.translate_by(offset);
|
||||
p2.translate_by(offset);
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct AddRoundedRectClip {
|
||||
|
@ -368,6 +399,7 @@ struct AddRoundedRectClip {
|
|||
bool is_clip_or_mask() const { return true; }
|
||||
|
||||
void translate_by(Gfx::IntPoint const& offset) { border_rect.translate_by(offset); }
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct AddMask {
|
||||
|
@ -381,6 +413,8 @@ struct AddMask {
|
|||
{
|
||||
rect.translate_by(offset);
|
||||
}
|
||||
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct PaintNestedDisplayList {
|
||||
|
@ -394,6 +428,7 @@ struct PaintNestedDisplayList {
|
|||
{
|
||||
rect.translate_by(offset);
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct PaintScrollBar {
|
||||
|
@ -410,18 +445,22 @@ struct PaintScrollBar {
|
|||
gutter_rect.translate_by(offset);
|
||||
thumb_rect.translate_by(offset);
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct ApplyOpacity {
|
||||
float opacity;
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct ApplyCompositeAndBlendingOperator {
|
||||
Gfx::CompositingAndBlendingOperator compositing_and_blending_operator;
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct ApplyFilter {
|
||||
Gfx::Filter filter;
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct ApplyTransform {
|
||||
|
@ -432,6 +471,7 @@ struct ApplyTransform {
|
|||
{
|
||||
origin.translate_by(offset.to_type<float>());
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct ApplyMaskBitmap {
|
||||
|
@ -443,6 +483,7 @@ struct ApplyMaskBitmap {
|
|||
{
|
||||
origin.translate_by(offset);
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
using Command = Variant<
|
||||
|
|
|
@ -13,6 +13,16 @@ void DisplayList::append(Command&& command, Optional<i32> scroll_frame_id)
|
|||
m_commands.append({ scroll_frame_id, move(command) });
|
||||
}
|
||||
|
||||
String DisplayList::dump() const
|
||||
{
|
||||
StringBuilder builder;
|
||||
for (auto const& command : m_commands) {
|
||||
command.command.visit([&builder](auto const& cmd) { cmd.dump(builder); });
|
||||
builder.appendff("\n");
|
||||
}
|
||||
return builder.to_string_without_validation();
|
||||
}
|
||||
|
||||
static Optional<Gfx::IntRect> command_bounding_rectangle(Command const& command)
|
||||
{
|
||||
return command.visit(
|
||||
|
|
|
@ -96,6 +96,8 @@ public:
|
|||
void set_device_pixels_per_css_pixel(double device_pixels_per_css_pixel) { m_device_pixels_per_css_pixel = device_pixels_per_css_pixel; }
|
||||
double device_pixels_per_css_pixel() const { return m_device_pixels_per_css_pixel; }
|
||||
|
||||
String dump() const;
|
||||
|
||||
private:
|
||||
DisplayList() = default;
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
SaveLayer
|
||||
PushStackingContext
|
||||
PushStackingContext
|
||||
Save
|
||||
AddClipRect rect=[10,10 200x100]
|
||||
Restore
|
||||
FillPathUsingColor
|
||||
Save
|
||||
AddClipRect rect=[10,10 200x100]
|
||||
Restore
|
||||
Save
|
||||
AddClipRect rect=[10,10 200x100]
|
||||
FillRect rect=[10,10 300x150] color=rgb(240, 128, 128)
|
||||
Restore
|
||||
Save
|
||||
AddClipRect rect=[10,10 200x100]
|
||||
Restore
|
||||
Save
|
||||
AddClipRect rect=[10,10 200x100]
|
||||
DrawGlyphRun rect=[10,10 38x18] translation=[10,23.796875] color=rgb(0, 0, 0) scale=1
|
||||
Restore
|
||||
Save
|
||||
AddClipRect rect=[10,10 200x100]
|
||||
Restore
|
||||
PopStackingContext
|
||||
PopStackingContext
|
||||
Restore
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../include.js"></script>
|
||||
<style>
|
||||
.container {
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
border: 2px solid black;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.inner-box {
|
||||
width: 300px;
|
||||
height: 150px;
|
||||
background: lightcoral;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="inner-box">Text</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
test(() => {
|
||||
println(internals.dumpDisplayList());
|
||||
});
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue