2023-07-19 20:09:49 +02:00
|
|
|
#include "Region.hpp"
|
2023-09-23 14:31:37 +02:00
|
|
|
extern "C" {
|
2023-07-19 20:09:49 +02:00
|
|
|
#include <wlr/util/box.h>
|
2023-09-20 17:47:05 +02:00
|
|
|
#include <wlr/util/region.h>
|
2023-09-23 14:31:37 +02:00
|
|
|
}
|
2023-07-19 20:09:49 +02:00
|
|
|
|
|
|
|
CRegion::CRegion() {
|
|
|
|
pixman_region32_init(&m_rRegion);
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegion::CRegion(pixman_region32_t* ref) {
|
|
|
|
pixman_region32_init(&m_rRegion);
|
|
|
|
pixman_region32_copy(&m_rRegion, ref);
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegion::CRegion(double x, double y, double w, double h) {
|
|
|
|
pixman_region32_init_rect(&m_rRegion, x, y, w, h);
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegion::CRegion(wlr_box* box) {
|
|
|
|
pixman_region32_init_rect(&m_rRegion, box->x, box->y, box->width, box->height);
|
|
|
|
}
|
|
|
|
|
2023-07-20 18:27:28 +02:00
|
|
|
CRegion::CRegion(pixman_box32_t* box) {
|
|
|
|
pixman_region32_init_rect(&m_rRegion, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1);
|
|
|
|
}
|
|
|
|
|
2023-07-19 20:09:49 +02:00
|
|
|
CRegion::CRegion(const CRegion& other) {
|
|
|
|
pixman_region32_init(&m_rRegion);
|
|
|
|
pixman_region32_copy(&m_rRegion, const_cast<CRegion*>(&other)->pixman());
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegion::CRegion(CRegion&& other) {
|
|
|
|
pixman_region32_init(&m_rRegion);
|
|
|
|
pixman_region32_copy(&m_rRegion, other.pixman());
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegion::~CRegion() {
|
|
|
|
pixman_region32_fini(&m_rRegion);
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegion& CRegion::clear() {
|
|
|
|
pixman_region32_clear(&m_rRegion);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegion& CRegion::set(const CRegion& other) {
|
|
|
|
pixman_region32_copy(&m_rRegion, const_cast<CRegion*>(&other)->pixman());
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegion& CRegion::add(const CRegion& other) {
|
|
|
|
pixman_region32_union(&m_rRegion, &m_rRegion, const_cast<CRegion*>(&other)->pixman());
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegion& CRegion::add(double x, double y, double w, double h) {
|
|
|
|
pixman_region32_union_rect(&m_rRegion, &m_rRegion, x, y, w, h);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegion& CRegion::subtract(const CRegion& other) {
|
|
|
|
pixman_region32_subtract(&m_rRegion, &m_rRegion, const_cast<CRegion*>(&other)->pixman());
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegion& CRegion::intersect(const CRegion& other) {
|
|
|
|
pixman_region32_intersect(&m_rRegion, &m_rRegion, const_cast<CRegion*>(&other)->pixman());
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegion& CRegion::intersect(double x, double y, double w, double h) {
|
|
|
|
pixman_region32_intersect_rect(&m_rRegion, &m_rRegion, x, y, w, h);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegion& CRegion::invert(pixman_box32_t* box) {
|
|
|
|
pixman_region32_inverse(&m_rRegion, &m_rRegion, box);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegion& CRegion::translate(const Vector2D& vec) {
|
|
|
|
pixman_region32_translate(&m_rRegion, vec.x, vec.y);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2023-09-20 17:47:05 +02:00
|
|
|
CRegion& CRegion::scale(float scale) {
|
|
|
|
wlr_region_scale(&m_rRegion, &m_rRegion, scale);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2023-07-19 20:09:49 +02:00
|
|
|
std::vector<pixman_box32_t> CRegion::getRects() const {
|
|
|
|
std::vector<pixman_box32_t> result;
|
|
|
|
|
|
|
|
int rectsNum = 0;
|
|
|
|
const auto RECTSARR = pixman_region32_rectangles(&m_rRegion, &rectsNum);
|
|
|
|
|
|
|
|
result.assign(RECTSARR, RECTSARR + rectsNum);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2023-08-30 17:39:22 +02:00
|
|
|
wlr_box CRegion::getExtents() {
|
|
|
|
pixman_box32_t* box = pixman_region32_extents(&m_rRegion);
|
|
|
|
return {box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1};
|
|
|
|
}
|
|
|
|
|
2023-09-20 17:47:05 +02:00
|
|
|
bool CRegion::containsPoint(const Vector2D& vec) const {
|
2023-08-30 17:39:22 +02:00
|
|
|
return pixman_region32_contains_point(&m_rRegion, vec.x, vec.y, nullptr);
|
|
|
|
}
|
|
|
|
|
2023-09-20 17:47:05 +02:00
|
|
|
bool CRegion::empty() const {
|
2023-07-19 20:09:49 +02:00
|
|
|
return !pixman_region32_not_empty(&m_rRegion);
|
|
|
|
}
|
2023-09-04 17:34:19 +02:00
|
|
|
|
2023-09-20 17:47:05 +02:00
|
|
|
Vector2D CRegion::closestPoint(const Vector2D& vec) const {
|
2023-09-04 17:34:19 +02:00
|
|
|
double bestDist = __FLT_MAX__;
|
|
|
|
Vector2D leader = vec;
|
|
|
|
|
|
|
|
for (auto& box : getRects()) {
|
|
|
|
double x = 0, y = 0;
|
|
|
|
|
|
|
|
if (vec.x >= box.x2)
|
|
|
|
x = box.x2 - 1;
|
|
|
|
else if (vec.x < box.x1)
|
|
|
|
x = box.x1;
|
|
|
|
else
|
|
|
|
x = vec.x;
|
|
|
|
|
|
|
|
if (vec.y >= box.y2)
|
|
|
|
y = box.y2 - 1;
|
|
|
|
else if (vec.y < box.y1)
|
|
|
|
y = box.y1;
|
|
|
|
else
|
|
|
|
y = vec.y;
|
|
|
|
|
|
|
|
double distance = sqrt(pow(x, 2) + pow(y, 2));
|
|
|
|
if (distance < bestDist) {
|
|
|
|
bestDist = distance;
|
|
|
|
leader = {x, y};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return leader;
|
|
|
|
}
|