Serenity Operating System
1/*
2 * Copyright (c) 2021, Davipb <daviparca@gmail.com>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include "Mask.h"
8
9namespace PixelPaint {
10
11Mask::Mask(Gfx::IntRect bounding_rect, u8 default_value)
12 : m_bounding_rect(bounding_rect)
13{
14 auto data_size = bounding_rect.size().area();
15 m_data.resize(data_size);
16
17 for (auto& x : m_data) {
18 x = default_value;
19 }
20}
21
22Mask Mask::with_bounding_rect(Gfx::IntRect inner_rect) const
23{
24 auto result = Mask::empty(inner_rect);
25
26 result.for_each_pixel([&](int x, int y) {
27 result.set(x, y, get(x, y));
28 });
29
30 return result;
31}
32
33void Mask::shrink_to_fit()
34{
35 int topmost = NumericLimits<int>::max();
36 int bottommost = NumericLimits<int>::min();
37 int leftmost = NumericLimits<int>::max();
38 int rightmost = NumericLimits<int>::min();
39
40 bool empty = true;
41 for_each_pixel([&](auto x, auto y) {
42 if (get(x, y) == 0) {
43 return;
44 }
45
46 empty = false;
47
48 topmost = min(topmost, y);
49 bottommost = max(bottommost, y);
50
51 leftmost = min(leftmost, x);
52 rightmost = max(rightmost, x);
53 });
54
55 if (empty) {
56 m_bounding_rect = {};
57 m_data.clear();
58 return;
59 }
60
61 Gfx::IntRect new_bounding_rect(
62 leftmost,
63 topmost,
64 rightmost - leftmost + 1,
65 bottommost - topmost + 1);
66
67 *this = with_bounding_rect(new_bounding_rect);
68}
69
70void Mask::invert()
71{
72 for_each_pixel([&](int x, int y) {
73 set(x, y, 0xFF - get(x, y));
74 });
75}
76
77void Mask::add(Mask const& other)
78{
79 combine(other, [](int a, int b) { return a + b; });
80}
81
82void Mask::subtract(Mask const& other)
83{
84 combine(other, [](int a, int b) { return a - b; });
85}
86
87void Mask::intersect(Mask const& other)
88{
89 combinef(other, [](float a, float b) { return a * b; });
90}
91
92}