aseprite/src/gfx/region.cpp
2015-03-05 15:19:00 -03:00

177 lines
3.6 KiB
C++

// Aseprite Gfx Library
// Copyright (C) 2001-2013, 2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <pixman.h>
#include "gfx/point.h"
#include "gfx/region.h"
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
namespace gfx {
inline Rect to_rect(const pixman_box32& extends)
{
return Rect(
extends.x1, extends.y1,
extends.x2 - extends.x1,
extends.y2 - extends.y1);
}
Region::Region()
{
pixman_region32_init(&m_region);
}
Region::Region(const Region& copy)
{
pixman_region32_init(&m_region);
pixman_region32_copy(&m_region, &copy.m_region);
}
Region::Region(const Rect& rect)
{
if (!rect.isEmpty())
pixman_region32_init_rect(&m_region, rect.x, rect.y, rect.w, rect.h);
else
pixman_region32_init(&m_region);
}
Region::~Region()
{
pixman_region32_fini(&m_region);
}
Region& Region::operator=(const Rect& rect)
{
if (!rect.isEmpty()) {
pixman_box32 box = { rect.x, rect.y, rect.x2(), rect.y2() };
pixman_region32_reset(&m_region, &box);
}
else
pixman_region32_clear(&m_region);
return *this;
}
Region& Region::operator=(const Region& copy)
{
pixman_region32_copy(&m_region, &copy.m_region);
return *this;
}
Region::iterator Region::begin()
{
iterator it;
it.m_ptr = pixman_region32_rectangles(&m_region, NULL);
return it;
}
Region::iterator Region::end()
{
iterator it;
it.m_ptr = pixman_region32_rectangles(&m_region, NULL) + size();
return it;
}
Region::const_iterator Region::begin() const
{
const_iterator it;
it.m_ptr = pixman_region32_rectangles(&m_region, NULL);
return it;
}
Region::const_iterator Region::end() const
{
const_iterator it;
it.m_ptr = pixman_region32_rectangles(&m_region, NULL) + size();
return it;
}
bool Region::isEmpty() const
{
return pixman_region32_not_empty(&m_region) ? false: true;
}
Rect Region::bounds() const
{
return to_rect(*pixman_region32_extents(&m_region));
}
std::size_t Region::size() const
{
return pixman_region32_n_rects(&m_region);
}
void Region::clear()
{
pixman_region32_clear(&m_region);
}
void Region::offset(int dx, int dy)
{
pixman_region32_translate(&m_region, dx, dy);
}
void Region::offset(const PointT<int>& delta)
{
pixman_region32_translate(&m_region, delta.x, delta.y);
}
Region& Region::createIntersection(const Region& a, const Region& b)
{
pixman_region32_intersect(&m_region, &a.m_region, &b.m_region);
return *this;
}
Region& Region::createUnion(const Region& a, const Region& b)
{
pixman_region32_union(&m_region, &a.m_region, &b.m_region);
return *this;
}
Region& Region::createSubtraction(const Region& a, const Region& b)
{
pixman_region32_subtract(&m_region, &a.m_region, &b.m_region);
return *this;
}
bool Region::contains(const PointT<int>& pt) const
{
return pixman_region32_contains_point(&m_region, pt.x, pt.y, NULL) ? true: false;
}
Region::Overlap Region::contains(const Rect& rect) const
{
static_assert(
int(Out) == int(PIXMAN_REGION_OUT) &&
int(In) == int(PIXMAN_REGION_IN) &&
int(Part) == int(PIXMAN_REGION_PART), "Pixman constants have changed");
pixman_box32 box = { rect.x, rect.y, rect.x2(), rect.y2() };
return (Region::Overlap)pixman_region32_contains_rectangle(&m_region, &box);
}
Rect Region::operator[](int i)
{
assert(i >= 0 && i < (int)size());
return to_rect(pixman_region32_rectangles(&m_region, NULL)[i]);
}
const Rect Region::operator[](int i) const
{
assert(i >= 0 && i < (int)size());
return to_rect(pixman_region32_rectangles(&m_region, NULL)[i]);
}
} // namespace gfx