@@ -33,11 +33,7 @@ struct CommandExecutionState {
33
33
34
34
CommandResult FillRectWithRoundedCorners::execute (CommandExecutionState& state) const
35
35
{
36
- if (state.would_be_fully_clipped_by_painter (rect))
37
- return CommandResult::Continue;
38
-
39
36
auto & painter = state.painter ();
40
-
41
37
Gfx::AntiAliasingPainter aa_painter (painter);
42
38
if (aa_translation.has_value ())
43
39
aa_painter.translate (*aa_translation);
@@ -75,8 +71,6 @@ CommandResult DrawTextRun::execute(CommandExecutionState& state) const
75
71
76
72
CommandResult FillPathUsingColor::execute (CommandExecutionState& state) const
77
73
{
78
- if (state.would_be_fully_clipped_by_painter (bounding_rect))
79
- return CommandResult::Continue;
80
74
auto & painter = state.painter ();
81
75
Gfx::AntiAliasingPainter aa_painter (painter);
82
76
if (aa_translation.has_value ())
@@ -87,8 +81,6 @@ CommandResult FillPathUsingColor::execute(CommandExecutionState& state) const
87
81
88
82
CommandResult FillPathUsingPaintStyle::execute (CommandExecutionState& state) const
89
83
{
90
- if (state.would_be_fully_clipped_by_painter (bounding_rect))
91
- return CommandResult::Continue;
92
84
auto & painter = state.painter ();
93
85
Gfx::AntiAliasingPainter aa_painter (painter);
94
86
if (aa_translation.has_value ())
@@ -99,8 +91,6 @@ CommandResult FillPathUsingPaintStyle::execute(CommandExecutionState& state) con
99
91
100
92
CommandResult StrokePathUsingColor::execute (CommandExecutionState& state) const
101
93
{
102
- if (state.would_be_fully_clipped_by_painter (bounding_rect))
103
- return CommandResult::Continue;
104
94
auto & painter = state.painter ();
105
95
Gfx::AntiAliasingPainter aa_painter (painter);
106
96
if (aa_translation.has_value ())
@@ -111,8 +101,6 @@ CommandResult StrokePathUsingColor::execute(CommandExecutionState& state) const
111
101
112
102
CommandResult StrokePathUsingPaintStyle::execute (CommandExecutionState& state) const
113
103
{
114
- if (state.would_be_fully_clipped_by_painter (bounding_rect))
115
- return CommandResult::Continue;
116
104
auto & painter = state.painter ();
117
105
Gfx::AntiAliasingPainter aa_painter (painter);
118
106
if (aa_translation.has_value ())
@@ -123,17 +111,13 @@ CommandResult StrokePathUsingPaintStyle::execute(CommandExecutionState& state) c
123
111
124
112
CommandResult FillRect::execute (CommandExecutionState& state) const
125
113
{
126
- if (state.would_be_fully_clipped_by_painter (rect))
127
- return CommandResult::Continue;
128
114
auto & painter = state.painter ();
129
115
painter.fill_rect (rect, color);
130
116
return CommandResult::Continue;
131
117
}
132
118
133
119
CommandResult DrawScaledBitmap::execute (CommandExecutionState& state) const
134
120
{
135
- if (state.would_be_fully_clipped_by_painter (dst_rect))
136
- return CommandResult::Continue;
137
121
auto & painter = state.painter ();
138
122
painter.draw_scaled_bitmap (dst_rect, bitmap, src_rect, opacity, scaling_mode);
139
123
return CommandResult::Continue;
@@ -290,8 +274,6 @@ CommandResult PopStackingContextWithMask::execute(CommandExecutionState& state)
290
274
291
275
CommandResult PaintLinearGradient::execute (CommandExecutionState& state) const
292
276
{
293
- if (state.would_be_fully_clipped_by_painter (gradient_rect))
294
- return CommandResult::Continue;
295
277
auto const & data = linear_gradient_data;
296
278
state.painter ().fill_rect_with_linear_gradient (
297
279
gradient_rect, data.color_stops .list ,
@@ -301,27 +283,25 @@ CommandResult PaintLinearGradient::execute(CommandExecutionState& state) const
301
283
302
284
CommandResult PaintRadialGradient::execute (CommandExecutionState& state) const
303
285
{
304
- if (state.would_be_fully_clipped_by_painter (rect))
305
- return CommandResult::Continue;
306
286
auto & painter = state.painter ();
307
287
painter.fill_rect_with_radial_gradient (rect, radial_gradient_data.color_stops .list , center, size, radial_gradient_data.color_stops .repeat_length );
308
288
return CommandResult::Continue;
309
289
}
310
290
311
291
CommandResult PaintConicGradient::execute (CommandExecutionState& state) const
312
292
{
313
- if (state.would_be_fully_clipped_by_painter (rect))
314
- return CommandResult::Continue;
315
293
auto & painter = state.painter ();
316
294
painter.fill_rect_with_conic_gradient (rect, conic_gradient_data.color_stops .list , position, conic_gradient_data.start_angle , conic_gradient_data.color_stops .repeat_length );
317
295
return CommandResult::Continue;
318
296
}
319
297
298
+ Gfx::IntRect PaintOuterBoxShadow::bounding_rect () const
299
+ {
300
+ return get_outer_box_shadow_bounding_rect (outer_box_shadow_params);
301
+ }
302
+
320
303
CommandResult PaintOuterBoxShadow::execute (CommandExecutionState& state) const
321
304
{
322
- auto bounding_rect = get_outer_box_shadow_bounding_rect (outer_box_shadow_params);
323
- if (state.would_be_fully_clipped_by_painter (bounding_rect))
324
- return CommandResult::Continue;
325
305
auto & painter = state.painter ();
326
306
paint_outer_box_shadow (painter, outer_box_shadow_params);
327
307
return CommandResult::Continue;
@@ -340,9 +320,9 @@ CommandResult PaintTextShadow::execute(CommandExecutionState& state) const
340
320
return CommandResult::Continue;
341
321
342
322
// FIXME: Figure out the maximum bitmap size for all shadows and then allocate it once and reuse it?
343
- auto maybe_shadow_bitmap = Gfx::Bitmap::create (Gfx::BitmapFormat::BGRA8888, bounding_rect .size ());
323
+ auto maybe_shadow_bitmap = Gfx::Bitmap::create (Gfx::BitmapFormat::BGRA8888, shadow_bounding_rect .size ());
344
324
if (maybe_shadow_bitmap.is_error ()) {
345
- dbgln (" Unable to allocate temporary bitmap {} for text-shadow rendering: {}" , bounding_rect .size (), maybe_shadow_bitmap.error ());
325
+ dbgln (" Unable to allocate temporary bitmap {} for text-shadow rendering: {}" , shadow_bounding_rect .size (), maybe_shadow_bitmap.error ());
346
326
return CommandResult::Continue;
347
327
}
348
328
auto shadow_bitmap = maybe_shadow_bitmap.release_value ();
@@ -357,14 +337,12 @@ CommandResult PaintTextShadow::execute(CommandExecutionState& state) const
357
337
filter.process_rgba (blur_radius, color);
358
338
359
339
auto & painter = state.painter ();
360
- painter.blit (draw_location, *shadow_bitmap, bounding_rect );
340
+ painter.blit (draw_location, *shadow_bitmap, shadow_bounding_rect );
361
341
return CommandResult::Continue;
362
342
}
363
343
364
344
CommandResult DrawEllipse::execute (CommandExecutionState& state) const
365
345
{
366
- if (state.would_be_fully_clipped_by_painter (rect))
367
- return CommandResult::Continue;
368
346
auto & painter = state.painter ();
369
347
Gfx::AntiAliasingPainter aa_painter (painter);
370
348
aa_painter.draw_ellipse (rect, color, thickness);
@@ -373,8 +351,6 @@ CommandResult DrawEllipse::execute(CommandExecutionState& state) const
373
351
374
352
CommandResult FillElipse::execute (CommandExecutionState& state) const
375
353
{
376
- if (state.would_be_fully_clipped_by_painter (rect))
377
- return CommandResult::Continue;
378
354
auto & painter = state.painter ();
379
355
Gfx::AntiAliasingPainter aa_painter (painter);
380
356
aa_painter.fill_ellipse (rect, color, blend_mode);
@@ -394,8 +370,6 @@ CommandResult DrawLine::execute(CommandExecutionState& state) const
394
370
395
371
CommandResult DrawSignedDistanceField::execute (CommandExecutionState& state) const
396
372
{
397
- if (state.would_be_fully_clipped_by_painter (rect))
398
- return CommandResult::Continue;
399
373
auto & painter = state.painter ();
400
374
painter.draw_signed_distance_field (rect, color, sdf, smoothing);
401
375
return CommandResult::Continue;
@@ -455,8 +429,6 @@ CommandResult ApplyBackdropFilter::execute(CommandExecutionState& state) const
455
429
456
430
CommandResult DrawRect::execute (CommandExecutionState& state) const
457
431
{
458
- if (state.would_be_fully_clipped_by_painter (rect))
459
- return CommandResult::Continue;
460
432
auto & painter = state.painter ();
461
433
painter.draw_rect (rect, color, rough);
462
434
return CommandResult::Continue;
@@ -469,19 +441,25 @@ CommandResult DrawTriangleWave::execute(CommandExecutionState& state) const
469
441
return CommandResult::Continue;
470
442
}
471
443
444
+ Gfx::IntRect SampleUnderCorners::bounding_rect () const
445
+ {
446
+ return corner_clipper->border_rect ().to_type <int >();
447
+ }
448
+
472
449
CommandResult SampleUnderCorners::execute (CommandExecutionState& state) const
473
450
{
474
- if (state.would_be_fully_clipped_by_painter (corner_clipper->border_rect ().to_type <int >()))
475
- return CommandResult::Continue;
476
451
auto & painter = state.painter ();
477
452
corner_clipper->sample_under_corners (painter);
478
453
return CommandResult::Continue;
479
454
}
480
455
456
+ Gfx::IntRect BlitCornerClipping::bounding_rect () const
457
+ {
458
+ return corner_clipper->border_rect ().to_type <int >();
459
+ }
460
+
481
461
CommandResult BlitCornerClipping::execute (CommandExecutionState& state) const
482
462
{
483
- if (state.would_be_fully_clipped_by_painter (corner_clipper->border_rect ().to_type <int >()))
484
- return CommandResult::Continue;
485
463
auto & painter = state.painter ();
486
464
corner_clipper->blit_corner_clipping (painter);
487
465
return CommandResult::Continue;
@@ -507,9 +485,9 @@ void RecordingPainter::fill_rect(Gfx::IntRect const& rect, Color color)
507
485
508
486
void RecordingPainter::fill_path (FillPathUsingColorParams params)
509
487
{
510
- auto bounding_rect = params.path .bounding_box ().translated (params.translation .value_or ({})).to_type <int >();
488
+ auto path_bounding_rect = params.path .bounding_box ().translated (params.translation .value_or ({})).to_type <int >();
511
489
push_command (FillPathUsingColor {
512
- .bounding_rect = bounding_rect ,
490
+ .path_bounding_rect = path_bounding_rect ,
513
491
.path = params.path ,
514
492
.color = params.color ,
515
493
.winding_rule = params.winding_rule ,
@@ -519,9 +497,9 @@ void RecordingPainter::fill_path(FillPathUsingColorParams params)
519
497
520
498
void RecordingPainter::fill_path (FillPathUsingPaintStyleParams params)
521
499
{
522
- auto bounding_rect = params.path .bounding_box ().translated (params.translation .value_or ({})).to_type <int >();
500
+ auto path_bounding_rect = params.path .bounding_box ().translated (params.translation .value_or ({})).to_type <int >();
523
501
push_command (FillPathUsingPaintStyle {
524
- .bounding_rect = bounding_rect ,
502
+ .path_bounding_rect = path_bounding_rect ,
525
503
.path = params.path ,
526
504
.paint_style = params.paint_style ,
527
505
.winding_rule = params.winding_rule ,
@@ -532,9 +510,9 @@ void RecordingPainter::fill_path(FillPathUsingPaintStyleParams params)
532
510
533
511
void RecordingPainter::stroke_path (StrokePathUsingColorParams params)
534
512
{
535
- auto bounding_rect = params.path .bounding_box ().translated (params.translation .value_or ({})).to_type <int >();
513
+ auto path_bounding_rect = params.path .bounding_box ().translated (params.translation .value_or ({})).to_type <int >();
536
514
push_command (StrokePathUsingColor {
537
- .bounding_rect = bounding_rect ,
515
+ .path_bounding_rect = path_bounding_rect ,
538
516
.path = params.path ,
539
517
.color = params.color ,
540
518
.thickness = params.thickness ,
@@ -544,9 +522,9 @@ void RecordingPainter::stroke_path(StrokePathUsingColorParams params)
544
522
545
523
void RecordingPainter::stroke_path (StrokePathUsingPaintStyleParams params)
546
524
{
547
- auto bounding_rect = params.path .bounding_box ().translated (params.translation .value_or ({})).to_type <int >();
525
+ auto path_bounding_rect = params.path .bounding_box ().translated (params.translation .value_or ({})).to_type <int >();
548
526
push_command (StrokePathUsingPaintStyle {
549
- .bounding_rect = bounding_rect ,
527
+ .path_bounding_rect = path_bounding_rect ,
550
528
.path = params.path ,
551
529
.paint_style = params.paint_style ,
552
530
.thickness = params.thickness ,
@@ -780,7 +758,7 @@ void RecordingPainter::paint_text_shadow(int blur_radius, Gfx::IntRect bounding_
780
758
{
781
759
push_command (PaintTextShadow {
782
760
.blur_radius = blur_radius,
783
- .bounding_rect = bounding_rect,
761
+ .shadow_bounding_rect = bounding_rect,
784
762
.text_rect = text_rect,
785
763
.text = String::from_utf8 (text.as_string ()).release_value_but_fixme_should_propagate_errors (),
786
764
.font = font,
@@ -839,6 +817,17 @@ void RecordingPainter::draw_triangle_wave(Gfx::IntPoint a_p1, Gfx::IntPoint a_p2
839
817
.thickness = thickness });
840
818
}
841
819
820
+ static Optional<Gfx::IntRect> command_bounding_rectangle (PaintingCommand const & command)
821
+ {
822
+ return command.visit (
823
+ [&](auto const & command) -> Optional<Gfx::IntRect> {
824
+ if constexpr (requires { command.bounding_rect (); })
825
+ return command.bounding_rect ();
826
+ else
827
+ return {};
828
+ });
829
+ }
830
+
842
831
void RecordingPainter::execute (Gfx::Bitmap& bitmap)
843
832
{
844
833
CommandExecutionState state;
@@ -851,8 +840,10 @@ void RecordingPainter::execute(Gfx::Bitmap& bitmap)
851
840
size_t next_command_index = 0 ;
852
841
while (next_command_index < m_painting_commands.size ()) {
853
842
auto & command = m_painting_commands[next_command_index++];
843
+ auto bounding_rect = command_bounding_rectangle (command);
844
+ if (bounding_rect.has_value () && state.would_be_fully_clipped_by_painter (*bounding_rect))
845
+ continue ;
854
846
auto result = command.visit ([&](auto const & command) { return command.execute (state); });
855
-
856
847
if (result == CommandResult::SkipStackingContext) {
857
848
auto stacking_context_nesting_level = 1 ;
858
849
while (next_command_index < m_painting_commands.size ()) {
0 commit comments