Coverage Report

Created: 2026-05-16 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibWeb/Painting/Command.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#pragma once
8
9
#include <AK/Forward.h>
10
#include <AK/NonnullRefPtr.h>
11
#include <AK/SegmentedVector.h>
12
#include <AK/Utf8View.h>
13
#include <AK/Vector.h>
14
#include <LibGfx/AntiAliasingPainter.h>
15
#include <LibGfx/Color.h>
16
#include <LibGfx/Forward.h>
17
#include <LibGfx/Gradients.h>
18
#include <LibGfx/GrayscaleBitmap.h>
19
#include <LibGfx/ImmutableBitmap.h>
20
#include <LibGfx/PaintStyle.h>
21
#include <LibGfx/Palette.h>
22
#include <LibGfx/Point.h>
23
#include <LibGfx/Rect.h>
24
#include <LibGfx/ScalingMode.h>
25
#include <LibGfx/Size.h>
26
#include <LibGfx/StylePainter.h>
27
#include <LibGfx/TextAlignment.h>
28
#include <LibGfx/TextDirection.h>
29
#include <LibGfx/TextElision.h>
30
#include <LibGfx/TextLayout.h>
31
#include <LibGfx/TextWrapping.h>
32
#include <LibWeb/CSS/Enums.h>
33
#include <LibWeb/Painting/BorderRadiiData.h>
34
#include <LibWeb/Painting/BorderRadiusCornerClipper.h>
35
#include <LibWeb/Painting/GradientData.h>
36
#include <LibWeb/Painting/PaintBoxShadowParams.h>
37
#include <LibWeb/Painting/PaintStyle.h>
38
39
namespace Web::Painting {
40
41
class DisplayList;
42
43
struct DrawGlyphRun {
44
    NonnullRefPtr<Gfx::GlyphRun> glyph_run;
45
    Color color;
46
    Gfx::IntRect rect;
47
    Gfx::FloatPoint translation;
48
    double scale { 1 };
49
50
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
51
52
    void translate_by(Gfx::IntPoint const& offset);
53
};
54
55
struct FillRect {
56
    Gfx::IntRect rect;
57
    Color color;
58
    RefPtr<DisplayList> text_clip;
59
60
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
61
0
    void translate_by(Gfx::IntPoint const& offset) { rect.translate_by(offset); }
62
};
63
64
struct DrawScaledBitmap {
65
    Gfx::IntRect dst_rect;
66
    NonnullRefPtr<Gfx::Bitmap> bitmap;
67
    Gfx::IntRect src_rect;
68
    Gfx::ScalingMode scaling_mode;
69
70
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return dst_rect; }
71
0
    void translate_by(Gfx::IntPoint const& offset) { dst_rect.translate_by(offset); }
72
};
73
74
struct DrawScaledImmutableBitmap {
75
    Gfx::IntRect dst_rect;
76
    NonnullRefPtr<Gfx::ImmutableBitmap> bitmap;
77
    Gfx::IntRect src_rect;
78
    Gfx::ScalingMode scaling_mode;
79
    RefPtr<DisplayList> text_clip;
80
81
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return dst_rect; }
82
0
    void translate_by(Gfx::IntPoint const& offset) { dst_rect.translate_by(offset); }
83
};
84
85
struct SetClipRect {
86
    Gfx::IntRect rect;
87
};
88
89
struct ClearClipRect { };
90
91
struct StackingContextTransform {
92
    Gfx::FloatPoint origin;
93
    Gfx::FloatMatrix4x4 matrix;
94
};
95
96
struct StackingContextMask {
97
    NonnullRefPtr<Gfx::Bitmap> mask_bitmap;
98
    Gfx::Bitmap::MaskKind mask_kind;
99
};
100
101
struct PushStackingContext {
102
    float opacity;
103
    bool is_fixed_position;
104
    // The bounding box of the source paintable (pre-transform).
105
    Gfx::IntRect source_paintable_rect;
106
    // A translation to be applied after the stacking context has been transformed.
107
    Gfx::IntPoint post_transform_translation;
108
    CSS::ImageRendering image_rendering;
109
    StackingContextTransform transform;
110
    Optional<StackingContextMask> mask = {};
111
112
    void translate_by(Gfx::IntPoint const& offset)
113
0
    {
114
0
        source_paintable_rect.translate_by(offset);
115
0
    }
116
};
117
118
struct PopStackingContext { };
119
120
struct PaintLinearGradient {
121
    Gfx::IntRect gradient_rect;
122
    LinearGradientData linear_gradient_data;
123
    RefPtr<DisplayList> text_clip;
124
125
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return gradient_rect; }
126
127
    void translate_by(Gfx::IntPoint const& offset)
128
0
    {
129
0
        gradient_rect.translate_by(offset);
130
0
    }
131
};
132
133
struct PaintOuterBoxShadow {
134
    PaintBoxShadowParams box_shadow_params;
135
136
    [[nodiscard]] Gfx::IntRect bounding_rect() const;
137
    void translate_by(Gfx::IntPoint const& offset);
138
};
139
140
struct PaintInnerBoxShadow {
141
    PaintBoxShadowParams box_shadow_params;
142
143
    [[nodiscard]] Gfx::IntRect bounding_rect() const;
144
    void translate_by(Gfx::IntPoint const& offset);
145
};
146
147
struct PaintTextShadow {
148
    int blur_radius;
149
    Gfx::IntRect shadow_bounding_rect;
150
    Gfx::IntRect text_rect;
151
    NonnullRefPtr<Gfx::GlyphRun> glyph_run;
152
    double glyph_run_scale { 1 };
153
    Color color;
154
    Gfx::IntPoint draw_location;
155
156
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return { draw_location, shadow_bounding_rect.size() }; }
157
0
    void translate_by(Gfx::IntPoint const& offset) { draw_location.translate_by(offset); }
158
};
159
160
struct FillRectWithRoundedCorners {
161
    Gfx::IntRect rect;
162
    Color color;
163
    CornerRadii corner_radii;
164
    RefPtr<DisplayList> text_clip;
165
166
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
167
0
    void translate_by(Gfx::IntPoint const& offset) { rect.translate_by(offset); }
168
};
169
170
struct FillPathUsingColor {
171
    Gfx::IntRect path_bounding_rect;
172
    Gfx::Path path;
173
    Color color;
174
    Gfx::WindingRule winding_rule;
175
    Gfx::FloatPoint aa_translation;
176
177
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return path_bounding_rect; }
178
179
    void translate_by(Gfx::IntPoint const& offset)
180
0
    {
181
0
        path_bounding_rect.translate_by(offset);
182
0
        aa_translation.translate_by(offset.to_type<float>());
183
0
    }
184
};
185
186
struct FillPathUsingPaintStyle {
187
    Gfx::IntRect path_bounding_rect;
188
    Gfx::Path path;
189
    PaintStyle paint_style;
190
    Gfx::WindingRule winding_rule;
191
    float opacity;
192
    Gfx::FloatPoint aa_translation;
193
194
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return path_bounding_rect; }
195
196
    void translate_by(Gfx::IntPoint const& offset)
197
0
    {
198
0
        path_bounding_rect.translate_by(offset);
199
0
        aa_translation.translate_by(offset.to_type<float>());
200
0
    }
201
};
202
203
struct StrokePathUsingColor {
204
    Gfx::Path::CapStyle cap_style;
205
    Gfx::Path::JoinStyle join_style;
206
    float miter_limit;
207
    Gfx::IntRect path_bounding_rect;
208
    Gfx::Path path;
209
    Color color;
210
    float thickness;
211
    Gfx::FloatPoint aa_translation;
212
213
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return path_bounding_rect; }
214
215
    void translate_by(Gfx::IntPoint const& offset)
216
0
    {
217
0
        path_bounding_rect.translate_by(offset);
218
0
        aa_translation.translate_by(offset.to_type<float>());
219
0
    }
220
};
221
222
struct StrokePathUsingPaintStyle {
223
    Gfx::Path::CapStyle cap_style;
224
    Gfx::Path::JoinStyle join_style;
225
    float miter_limit;
226
    Gfx::IntRect path_bounding_rect;
227
    Gfx::Path path;
228
    PaintStyle paint_style;
229
    float thickness;
230
    float opacity = 1.0f;
231
    Gfx::FloatPoint aa_translation;
232
233
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return path_bounding_rect; }
234
235
    void translate_by(Gfx::IntPoint const& offset)
236
0
    {
237
0
        path_bounding_rect.translate_by(offset);
238
0
        aa_translation.translate_by(offset.to_type<float>());
239
0
    }
240
};
241
242
struct DrawEllipse {
243
    Gfx::IntRect rect;
244
    Color color;
245
    int thickness;
246
247
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
248
249
    void translate_by(Gfx::IntPoint const& offset)
250
0
    {
251
0
        rect.translate_by(offset);
252
0
    }
253
};
254
255
struct FillEllipse {
256
    Gfx::IntRect rect;
257
    Color color;
258
259
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
260
261
    void translate_by(Gfx::IntPoint const& offset)
262
0
    {
263
0
        rect.translate_by(offset);
264
0
    }
265
};
266
267
struct DrawLine {
268
    Color color;
269
    Gfx::IntPoint from;
270
    Gfx::IntPoint to;
271
    int thickness;
272
    Gfx::LineStyle style;
273
    Color alternate_color;
274
275
    void translate_by(Gfx::IntPoint const& offset)
276
0
    {
277
0
        from.translate_by(offset);
278
0
        to.translate_by(offset);
279
0
    }
280
};
281
282
struct ApplyBackdropFilter {
283
    Gfx::IntRect backdrop_region;
284
    BorderRadiiData border_radii_data;
285
    CSS::ResolvedFilter backdrop_filter;
286
287
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return backdrop_region; }
288
289
    void translate_by(Gfx::IntPoint const& offset)
290
0
    {
291
0
        backdrop_region.translate_by(offset);
292
0
    }
293
};
294
295
struct DrawRect {
296
    Gfx::IntRect rect;
297
    Color color;
298
    bool rough;
299
300
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
301
302
0
    void translate_by(Gfx::IntPoint const& offset) { rect.translate_by(offset); }
303
};
304
305
struct PaintRadialGradient {
306
    Gfx::IntRect rect;
307
    RadialGradientData radial_gradient_data;
308
    Gfx::IntPoint center;
309
    Gfx::IntSize size;
310
    RefPtr<DisplayList> text_clip;
311
312
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
313
314
0
    void translate_by(Gfx::IntPoint const& offset) { rect.translate_by(offset); }
315
};
316
317
struct PaintConicGradient {
318
    Gfx::IntRect rect;
319
    ConicGradientData conic_gradient_data;
320
    Gfx::IntPoint position;
321
    RefPtr<DisplayList> text_clip;
322
323
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return rect; }
324
325
0
    void translate_by(Gfx::IntPoint const& offset) { rect.translate_by(offset); }
326
};
327
328
struct DrawTriangleWave {
329
    Gfx::IntPoint p1;
330
    Gfx::IntPoint p2;
331
    Color color;
332
    int amplitude;
333
    int thickness;
334
335
    void translate_by(Gfx::IntPoint const& offset)
336
0
    {
337
0
        p1.translate_by(offset);
338
0
        p2.translate_by(offset);
339
0
    }
340
};
341
342
struct SampleUnderCorners {
343
    u32 id;
344
    CornerRadii corner_radii;
345
    Gfx::IntRect border_rect;
346
    CornerClip corner_clip;
347
348
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return border_rect; }
349
350
0
    void translate_by(Gfx::IntPoint const& offset) { border_rect.translate_by(offset); }
351
};
352
353
struct BlitCornerClipping {
354
    u32 id;
355
    Gfx::IntRect border_rect;
356
357
0
    [[nodiscard]] Gfx::IntRect bounding_rect() const { return border_rect; }
358
359
0
    void translate_by(Gfx::IntPoint const& offset) { border_rect.translate_by(offset); }
360
};
361
362
using Command = Variant<
363
    DrawGlyphRun,
364
    FillRect,
365
    DrawScaledBitmap,
366
    DrawScaledImmutableBitmap,
367
    SetClipRect,
368
    ClearClipRect,
369
    PushStackingContext,
370
    PopStackingContext,
371
    PaintLinearGradient,
372
    PaintRadialGradient,
373
    PaintConicGradient,
374
    PaintOuterBoxShadow,
375
    PaintInnerBoxShadow,
376
    PaintTextShadow,
377
    FillRectWithRoundedCorners,
378
    FillPathUsingColor,
379
    FillPathUsingPaintStyle,
380
    StrokePathUsingColor,
381
    StrokePathUsingPaintStyle,
382
    DrawEllipse,
383
    FillEllipse,
384
    DrawLine,
385
    ApplyBackdropFilter,
386
    DrawRect,
387
    DrawTriangleWave,
388
    SampleUnderCorners,
389
    BlitCornerClipping>;
390
391
}