/src/serenity/Userland/Libraries/LibGfx/PathClipper.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2023, MacDue <macdue@dueutil.tech> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #include <LibGfx/AntiAliasingPainter.h> |
8 | | #include <LibGfx/Painter.h> |
9 | | #include <LibGfx/PathClipper.h> |
10 | | |
11 | | namespace Gfx { |
12 | | |
13 | | // FIXME: This pretty naive, we should be able to cut down the allocations here |
14 | | // (especially for the paint style which is a bit sad). |
15 | | |
16 | | ErrorOr<PathClipper> PathClipper::create(Painter& painter, ClipPath const& clip_path) |
17 | 0 | { |
18 | 0 | auto bounding_box = enclosing_int_rect(clip_path.path.bounding_box()); |
19 | 0 | IntRect actual_save_rect {}; |
20 | 0 | auto maybe_bitmap = painter.get_region_bitmap(bounding_box, BitmapFormat::BGRA8888, actual_save_rect); |
21 | 0 | RefPtr<Bitmap> saved_clip_region; |
22 | 0 | if (!maybe_bitmap.is_error()) { |
23 | 0 | saved_clip_region = maybe_bitmap.release_value(); |
24 | 0 | } else if (actual_save_rect.is_empty()) { |
25 | | // This is okay, no need to report an error. |
26 | 0 | } else { |
27 | 0 | return maybe_bitmap.release_error(); |
28 | 0 | } |
29 | 0 | painter.save(); |
30 | 0 | painter.add_clip_rect(bounding_box); |
31 | 0 | return PathClipper(move(saved_clip_region), bounding_box, clip_path); |
32 | 0 | } |
33 | | |
34 | | ErrorOr<void> PathClipper::apply_clip(Painter& painter) |
35 | 0 | { |
36 | 0 | painter.restore(); |
37 | 0 | if (!m_saved_clip_region) |
38 | 0 | return {}; |
39 | 0 | IntRect actual_save_rect {}; |
40 | 0 | auto clip_area = TRY(painter.get_region_bitmap(m_bounding_box, BitmapFormat::BGRA8888, actual_save_rect)); |
41 | 0 | painter.blit(actual_save_rect.location(), *m_saved_clip_region, m_saved_clip_region->rect(), 1.0f, false); |
42 | 0 | AntiAliasingPainter aa_painter { painter }; |
43 | 0 | auto fill_offset = m_bounding_box.location() - actual_save_rect.location(); |
44 | 0 | aa_painter.fill_path(m_clip_path.path, TRY(BitmapPaintStyle::create(clip_area, fill_offset)), 1.0f, m_clip_path.winding_rule); |
45 | 0 | return {}; |
46 | 0 | } |
47 | | } |