diff options
Diffstat (limited to 'libraries/pake/source/dirtiable-image.cpp')
-rw-r--r-- | libraries/pake/source/dirtiable-image.cpp | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/libraries/pake/source/dirtiable-image.cpp b/libraries/pake/source/dirtiable-image.cpp new file mode 100644 index 0000000..9e5c979 --- /dev/null +++ b/libraries/pake/source/dirtiable-image.cpp @@ -0,0 +1,80 @@ +#include <pake/dirtiable-image.hpp> + +namespace pake { + + struct dirty_region_builder { + + std::vector<region> regions_not_on_bottom; + std::list<region> regions_on_bottom; + + void add_row(const std::vector<region> &row) { + + std::list<region> new_regions_on_bottom; + + for (auto i = row.begin(); i < row.end(); ++i) { + bool expanded = false; + for (auto j = regions_on_bottom.begin(); j != regions_on_bottom.end(); ++j) + if (i->start_x == j->start_x && i->width == j->width) { + j->height += i->height; + new_regions_on_bottom.push_back(*j); + regions_on_bottom.erase(j); + expanded = true; + break; + } + if (!expanded) + new_regions_on_bottom.push_back(*i); + } + + for (auto i = regions_on_bottom.begin(); i != regions_on_bottom.end(); ++i) + regions_not_on_bottom.push_back(*i); + + regions_on_bottom = std::move(new_regions_on_bottom); + + } + + }; + + std::vector<region> dirtiable_image::get_dirty_regions() { + + dirty_region_builder builder; + + std::vector<region> row; + + for (int y = 0; y < dirty.height; ++y) { + + int r = 0; + for (int x = 0; x < dirty.width; ++x) + if (!dirty.at(x, y)) { + if (r != x) + row.push_back({ + .start_x = r, .start_y = y, + .width = x - r, .height = 1 + }); + r = x + 1; + } + if (r != dirty.width) + row.push_back({ + .start_x = r, .start_y = y, + .width = dirty.width - r, .height = 1 + }); + + builder.add_row(row); + row.clear(); + + } + + builder.add_row(row); + return builder.regions_not_on_bottom; + + } + + void dirtiable_image::clear_dirty() { + dirty.fill(false); + } + + dirtiable_image::dirtiable_image(int width, int height) + : image(width, height), dirty(width, height) { + dirty.fill(false); + } + +} |