mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-27 17:18:53 +00:00
162 lines
3.6 KiB
C++
162 lines
3.6 KiB
C++
/*
|
|
* \brief Geometric primitives
|
|
* \author Norman Feske
|
|
* \date 2006-08-05
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2006-2011 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU General Public License version 2.
|
|
*/
|
|
|
|
#ifndef _INCLUDE__NITPICKER_GFX__GEOMETRY_H_
|
|
#define _INCLUDE__NITPICKER_GFX__GEOMETRY_H_
|
|
|
|
#include "miscmath.h"
|
|
|
|
class Point
|
|
{
|
|
private:
|
|
|
|
int _x, _y;
|
|
|
|
public:
|
|
|
|
Point(int x, int y): _x(x), _y(y) { }
|
|
Point(): _x(0), _y(0) { }
|
|
|
|
int x() { return _x; }
|
|
int y() { return _y; }
|
|
|
|
/**
|
|
* Operator for adding points
|
|
*/
|
|
Point operator + (Point p) { return Point(_x + p.x(), _y + p.y()); }
|
|
|
|
/**
|
|
* Operator for subtracting points
|
|
*/
|
|
Point operator - (Point p) { return Point(_x - p.x(), _y - p.y()); }
|
|
|
|
/**
|
|
* Operator for testing non-equality of two points
|
|
*/
|
|
bool operator != (Point p) { return p.x() != _x || p.y() != _y; }
|
|
};
|
|
|
|
|
|
class Area
|
|
{
|
|
private:
|
|
|
|
int _w, _h;
|
|
|
|
public:
|
|
|
|
Area(int w, int h): _w(w), _h(h) { }
|
|
Area(): _w(0), _h(0) { }
|
|
|
|
int w() { return _w; }
|
|
int h() { return _h; }
|
|
|
|
bool valid() { return _w > 0 && _h > 0; }
|
|
|
|
int num_pixels() { return _w*_h; }
|
|
};
|
|
|
|
|
|
/*
|
|
* A valid rectangle consists of two points wheras point 2 has
|
|
* higher or equal coordinates than point 1. All other cases
|
|
* are threated as invalid rectangles.
|
|
*/
|
|
class Rect
|
|
{
|
|
private:
|
|
|
|
Point _p1, _p2;
|
|
|
|
public:
|
|
|
|
/**
|
|
* Constructors
|
|
*/
|
|
Rect(Point p1, Point p2): _p1(p1), _p2(p2) { }
|
|
|
|
Rect(Point p, Area a):
|
|
_p1(p), _p2(p.x() + a.w() - 1, p.y() + a.h() - 1) { }
|
|
|
|
Rect() { }
|
|
|
|
/**
|
|
* Assign new coordinates
|
|
*/
|
|
void rect(Rect r) { _p1 = r.p1(); _p2 = r.p2(); }
|
|
|
|
/**
|
|
* Accessors
|
|
*/
|
|
int x1() { return _p1.x(); }
|
|
int y1() { return _p1.y(); }
|
|
int x2() { return _p2.x(); }
|
|
int y2() { return _p2.y(); }
|
|
int w() { return _p2.x() - _p1.x() + 1; }
|
|
int h() { return _p2.y() - _p1.y() + 1; }
|
|
Point p1() { return _p1; }
|
|
Point p2() { return _p2; }
|
|
Area area() { return Area(w(), h()); }
|
|
|
|
/**
|
|
* Return true if rectangle area is greater than zero
|
|
*/
|
|
bool valid() { return _p1.x() <= _p2.x() && _p1.y() <= _p2.y(); }
|
|
|
|
/**
|
|
* Return true if area fits in rectangle
|
|
*/
|
|
bool fits(Area area) { return w() >= area.w() && h() >= area.h(); }
|
|
|
|
/**
|
|
* Create new rectangle by intersecting two rectangles
|
|
*/
|
|
static Rect intersect(Rect r1, Rect r2) {
|
|
return Rect(Point(max(r1.x1(), r2.x1()), max(r1.y1(), r2.y1())),
|
|
Point(min(r1.x2(), r2.x2()), min(r1.y2(), r2.y2()))); }
|
|
|
|
/**
|
|
* Compute compounding rectangle of two rectangles
|
|
*/
|
|
static Rect compound(Rect r1, Rect r2) {
|
|
return Rect(Point(min(r1.x1(), r2.x1()), min(r1.y1(), r2.y1())),
|
|
Point(max(r1.x2(), r2.x2()), max(r1.y2(), r2.y2()))); }
|
|
|
|
/**
|
|
* Cut out rectangle from rectangle
|
|
*
|
|
* \param r rectangle to cut out
|
|
*
|
|
* In the worst case (if we cut a hole into the rectangle) we get
|
|
* four valid resulting rectangles.
|
|
*/
|
|
void cut(Rect r, Rect *top, Rect *left, Rect *right, Rect *bottom)
|
|
{
|
|
/* limit the cut-out area to the actual rectangle */
|
|
r = intersect(r, *this);
|
|
|
|
*top = Rect(Point(x1(), y1()), Point(x2(), r.y1() - 1));
|
|
*left = Rect(Point(x1(), r.y1()), Point(r.x1() - 1, r.y2()));
|
|
*right = Rect(Point(r.x2() + 1, r.y1()), Point(x2(), r.y2()));
|
|
*bottom = Rect(Point(x1(), r.y2() + 1), Point(x2(), y2()));
|
|
}
|
|
|
|
/**
|
|
* Return position of an area when centered within the rectangle
|
|
*/
|
|
Point center(Area area) {
|
|
return Point((w() - area.w())/2, (h() - area.h())/2) + p1(); }
|
|
};
|
|
|
|
#endif /* _INCLUDE__NITPICKER_GFX__GEOMETRY_H_ */
|