2017-11-04 07:03:53 +01:00
|
|
|
|
/***********************************************************************
|
|
|
|
|
* frect.cpp - Rectangle with position and size *
|
|
|
|
|
* *
|
|
|
|
|
* This file is part of the Final Cut widget toolkit *
|
|
|
|
|
* *
|
2019-01-16 16:00:15 +01:00
|
|
|
|
* Copyright 2014-2019 Markus Gans *
|
2017-11-04 07:03:53 +01:00
|
|
|
|
* *
|
|
|
|
|
* The Final Cut is free software; you can redistribute it and/or *
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public License *
|
|
|
|
|
* as published by the Free Software Foundation; either version 3 of *
|
|
|
|
|
* the License, or (at your option) any later version. *
|
|
|
|
|
* *
|
|
|
|
|
* The Final Cut is distributed in the hope that it will be useful, *
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
|
* GNU Lesser General Public License for more details. *
|
|
|
|
|
* *
|
|
|
|
|
* You should have received a copy of the GNU Lesser General Public *
|
|
|
|
|
* License along with this program. If not, see *
|
|
|
|
|
* <http://www.gnu.org/licenses/>. *
|
|
|
|
|
***********************************************************************/
|
2015-05-23 13:35:12 +02:00
|
|
|
|
|
2017-09-11 03:06:02 +02:00
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
2019-07-21 23:31:21 +02:00
|
|
|
|
#include "final/fpoint.h"
|
2017-09-17 21:32:46 +02:00
|
|
|
|
#include "final/frect.h"
|
2019-07-21 23:31:21 +02:00
|
|
|
|
#include "final/fsize.h"
|
2015-05-23 13:35:12 +02:00
|
|
|
|
|
2018-09-20 23:59:01 +02:00
|
|
|
|
namespace finalcut
|
|
|
|
|
{
|
|
|
|
|
|
2015-05-23 13:35:12 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
// class FRect
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// constructor and destructor
|
2019-01-16 16:00:15 +01:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FRect::FRect (const FPoint& p, const FSize& s)
|
|
|
|
|
: X1(p.getX())
|
|
|
|
|
, Y1(p.getY())
|
|
|
|
|
, X2(p.getX() + int(s.getWidth()) - 1)
|
|
|
|
|
, Y2(p.getY() + int(s.getHeight()) - 1)
|
|
|
|
|
{ }
|
|
|
|
|
|
2015-05-23 13:35:12 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FRect::FRect (const FPoint& p1, const FPoint& p2)
|
2018-11-21 22:15:14 +01:00
|
|
|
|
: X1(p1.getX())
|
|
|
|
|
, Y1(p1.getY())
|
|
|
|
|
, X2(p2.getX())
|
|
|
|
|
, Y2(p2.getY())
|
2015-09-20 05:44:50 +02:00
|
|
|
|
{ }
|
2015-05-23 13:35:12 +02:00
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FRect::~FRect() // destructor
|
2015-09-22 04:18:20 +02:00
|
|
|
|
{ }
|
2015-05-23 13:35:12 +02:00
|
|
|
|
|
2017-09-11 03:06:02 +02:00
|
|
|
|
|
2015-05-23 13:35:12 +02:00
|
|
|
|
// public methods of FRect
|
|
|
|
|
//----------------------------------------------------------------------
|
2019-01-16 16:00:15 +01:00
|
|
|
|
bool FRect::isEmpty() const
|
2015-05-23 13:35:12 +02:00
|
|
|
|
{
|
2017-08-27 09:50:30 +02:00
|
|
|
|
return X2 == X1 - 1 && Y2 == Y1 - 1;
|
2015-05-23 13:35:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-07-21 23:31:21 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FPoint FRect::getPos() const
|
|
|
|
|
{
|
|
|
|
|
return FPoint(X1, Y1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FPoint FRect::getUpperLeftPos() const
|
|
|
|
|
{
|
|
|
|
|
return FPoint(X1, Y1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FPoint FRect::getUpperRightPos() const
|
|
|
|
|
{
|
|
|
|
|
return FPoint(X2, Y1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FPoint FRect::getLowerLeftPos() const
|
|
|
|
|
{ return FPoint(X1, Y2); }
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FPoint FRect::getLowerRightPos() const
|
|
|
|
|
{
|
|
|
|
|
return FPoint(X2, Y2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FSize FRect::getSize() const
|
|
|
|
|
{
|
|
|
|
|
return FSize(getWidth(), getHeight());
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-23 13:35:12 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FRect::setX1 (int n)
|
|
|
|
|
{
|
2018-11-21 22:15:14 +01:00
|
|
|
|
X1 = n;
|
2015-05-23 13:35:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FRect::setY1 (int n)
|
|
|
|
|
{
|
2018-11-21 22:15:14 +01:00
|
|
|
|
Y1 = n;
|
2015-05-23 13:35:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FRect::setX2 (int n)
|
|
|
|
|
{
|
2018-11-21 22:15:14 +01:00
|
|
|
|
X2 = n;
|
2015-05-23 13:35:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FRect::setY2 (int n)
|
|
|
|
|
{
|
2018-11-21 22:15:14 +01:00
|
|
|
|
Y2 = n;
|
2015-05-23 13:35:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FRect::setX (int n)
|
|
|
|
|
{
|
2018-11-21 22:15:14 +01:00
|
|
|
|
int dX = X2 - X1;
|
|
|
|
|
X1 = n;
|
|
|
|
|
X2 = X1 + dX;
|
2015-05-23 13:35:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FRect::setY (int n)
|
|
|
|
|
{
|
2018-11-21 22:15:14 +01:00
|
|
|
|
int dY = Y2 - Y1;
|
|
|
|
|
Y1 = n;
|
|
|
|
|
Y2 = Y1 + dY;
|
2015-05-23 13:35:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-27 16:00:13 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FRect::setPos (int x, int y)
|
|
|
|
|
{
|
2018-11-21 22:15:14 +01:00
|
|
|
|
int dX = X2 - X1;
|
|
|
|
|
int dY = Y2 - Y1;
|
|
|
|
|
X1 = x;
|
|
|
|
|
Y1 = y;
|
|
|
|
|
X2 = X1 + dX;
|
|
|
|
|
Y2 = Y1 + dY;
|
2015-09-27 16:00:13 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FRect::setPos (const FPoint& p)
|
|
|
|
|
{
|
2018-11-21 22:15:14 +01:00
|
|
|
|
int dX = X2 - X1;
|
|
|
|
|
int dY = Y2 - Y1;
|
|
|
|
|
X1 = p.getX();
|
|
|
|
|
Y1 = p.getY();
|
|
|
|
|
X2 = X1 + dX;
|
|
|
|
|
Y2 = Y1 + dY;
|
2015-09-27 16:00:13 +02:00
|
|
|
|
}
|
|
|
|
|
|
2015-05-23 13:35:12 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
2018-10-14 06:25:33 +02:00
|
|
|
|
void FRect::setWidth (std::size_t w)
|
2015-05-23 13:35:12 +02:00
|
|
|
|
{
|
2018-11-21 22:15:14 +01:00
|
|
|
|
X2 = X1 + int(w) - 1;
|
2015-05-23 13:35:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2018-10-14 06:25:33 +02:00
|
|
|
|
void FRect::setHeight (std::size_t h)
|
2015-05-23 13:35:12 +02:00
|
|
|
|
{
|
2018-11-21 22:15:14 +01:00
|
|
|
|
Y2 = Y1 + int(h) - 1;
|
2015-05-23 13:35:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
2016-09-29 04:29:12 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
2019-08-11 18:15:57 +02:00
|
|
|
|
void FRect::setSize (std::size_t width, std::size_t height)
|
2016-09-29 04:29:12 +02:00
|
|
|
|
{
|
2019-08-11 18:15:57 +02:00
|
|
|
|
X2 = X1 + int(width) - 1;
|
|
|
|
|
Y2 = Y1 + int(height) - 1;
|
2016-09-29 04:29:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-01-16 16:00:15 +01:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FRect::setSize (const FSize& s)
|
|
|
|
|
{
|
|
|
|
|
X2 = X1 + int(s.getWidth()) - 1;
|
|
|
|
|
Y2 = Y1 + int(s.getHeight()) - 1;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-23 13:35:12 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FRect::setRect (const FRect& r)
|
|
|
|
|
{
|
2019-01-21 03:42:18 +01:00
|
|
|
|
X1 = r.X1;
|
|
|
|
|
Y1 = r.Y1;
|
|
|
|
|
X2 = r.X2;
|
|
|
|
|
Y2 = r.Y2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FRect::setRect (const FPoint& p, const FSize& s)
|
|
|
|
|
{
|
|
|
|
|
X1 = p.getX();
|
|
|
|
|
Y1 = p.getY();
|
|
|
|
|
X2 = p.getX() + int(s.getWidth()) - 1;
|
|
|
|
|
Y2 = p.getY() + int(s.getHeight()) - 1;
|
2015-05-23 13:35:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2018-10-14 06:25:33 +02:00
|
|
|
|
void FRect::setRect (int x, int y, std::size_t width, std::size_t height)
|
2015-05-23 13:35:12 +02:00
|
|
|
|
{
|
2018-11-21 22:15:14 +01:00
|
|
|
|
X1 = x;
|
|
|
|
|
Y1 = y;
|
|
|
|
|
X2 = x + int(width) - 1;
|
|
|
|
|
Y2 = y + int(height) - 1;
|
2015-05-23 13:35:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
2016-09-25 23:53:48 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FRect::setCoordinates (const FPoint& p1, const FPoint& p2)
|
|
|
|
|
{
|
|
|
|
|
setCoordinates (p1.getX(), p1.getY(), p2.getX(), p2.getY());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FRect::setCoordinates (int x1, int y1, int x2, int y2)
|
|
|
|
|
{
|
2018-11-21 22:15:14 +01:00
|
|
|
|
X1 = x1;
|
|
|
|
|
Y1 = y1;
|
|
|
|
|
X2 = x2;
|
|
|
|
|
Y2 = y2;
|
2016-09-25 23:53:48 +02:00
|
|
|
|
}
|
|
|
|
|
|
2015-05-23 13:35:12 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FRect::move (int dx, int dy)
|
|
|
|
|
{
|
2018-11-21 22:15:14 +01:00
|
|
|
|
X1 = X1 + dx;
|
|
|
|
|
Y1 = Y1 + dy;
|
|
|
|
|
X2 = X2 + dx;
|
|
|
|
|
Y2 = Y2 + dy;
|
2015-05-23 13:35:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2018-11-21 22:15:14 +01:00
|
|
|
|
void FRect::move (const FPoint& d)
|
2015-05-23 13:35:12 +02:00
|
|
|
|
{
|
2018-11-21 22:15:14 +01:00
|
|
|
|
X1 = X1 + d.getX();
|
|
|
|
|
Y1 = Y1 + d.getY();
|
|
|
|
|
X2 = X2 + d.getX();
|
|
|
|
|
Y2 = Y2 + d.getY();
|
2015-05-23 13:35:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-11 18:15:57 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FRect::scaleBy (int dx, int dy)
|
|
|
|
|
{
|
|
|
|
|
X2 += dx;
|
|
|
|
|
Y2 += dy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FRect::scaleBy (const FPoint& d)
|
|
|
|
|
{
|
|
|
|
|
X2 += d.getX();
|
|
|
|
|
Y2 += d.getY();
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-23 13:35:12 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
bool FRect::contains (int x, int y) const
|
|
|
|
|
{
|
|
|
|
|
return x >= X1 && x <= X2
|
|
|
|
|
&& y >= Y1 && y <= Y2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
bool FRect::contains (const FPoint& p) const
|
|
|
|
|
{
|
|
|
|
|
return p.getX() >= X1 && p.getX() <= X2
|
|
|
|
|
&& p.getY() >= Y1 && p.getY() <= Y2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
bool FRect::contains (const FRect& r) const
|
|
|
|
|
{
|
|
|
|
|
return r.X1 >= X1 && r.X2 <= X2
|
|
|
|
|
&& r.Y1 >= Y1 && r.Y2 <= Y2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
bool FRect::overlap (const FRect &r) const
|
|
|
|
|
{
|
2016-12-18 23:34:11 +01:00
|
|
|
|
return ( std::max(X1, r.X1) <= std::min(X2, r.X2)
|
2017-11-26 22:37:18 +01:00
|
|
|
|
&& std::max(Y1, r.Y1) <= std::min(Y2, r.Y2) );
|
2015-05-23 13:35:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FRect FRect::intersect (const FRect& r) const
|
|
|
|
|
{
|
|
|
|
|
// intersection: this ∩ r
|
2019-08-25 22:16:00 +02:00
|
|
|
|
FRect new_rect{};
|
2015-05-23 13:35:12 +02:00
|
|
|
|
new_rect.X1 = std::max(X1, r.X1);
|
|
|
|
|
new_rect.Y1 = std::max(Y1, r.Y1);
|
|
|
|
|
new_rect.X2 = std::min(X2, r.X2);
|
|
|
|
|
new_rect.Y2 = std::min(Y2, r.Y2);
|
|
|
|
|
return new_rect;
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-12 00:29:56 +01:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FRect FRect::combined (const FRect& r) const
|
|
|
|
|
{
|
|
|
|
|
// Union: this ∪ r
|
2019-08-25 22:16:00 +02:00
|
|
|
|
FRect new_rect{};
|
2017-03-12 00:29:56 +01:00
|
|
|
|
new_rect.X1 = std::min(X1, r.X1);
|
|
|
|
|
new_rect.Y1 = std::min(Y1, r.Y1);
|
|
|
|
|
new_rect.X2 = std::max(X2, r.X2);
|
|
|
|
|
new_rect.Y2 = std::max(Y2, r.Y2);
|
|
|
|
|
return new_rect;
|
|
|
|
|
}
|
2017-09-03 18:32:43 +02:00
|
|
|
|
|
2016-09-25 23:53:48 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FRect& FRect::operator = (const FRect& r)
|
|
|
|
|
{
|
2019-07-31 23:57:35 +02:00
|
|
|
|
X1 = r.X1;
|
|
|
|
|
Y1 = r.Y1;
|
|
|
|
|
X2 = r.X2;
|
|
|
|
|
Y2 = r.Y2;
|
2016-09-25 23:53:48 +02:00
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-29 02:34:58 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FRect& FRect::operator = (FRect&& r)
|
|
|
|
|
{
|
2019-07-31 23:57:35 +02:00
|
|
|
|
X1 = r.X1;
|
|
|
|
|
Y1 = r.Y1;
|
|
|
|
|
X2 = r.X2;
|
|
|
|
|
Y2 = r.Y2;
|
|
|
|
|
r.X1 = r.Y1 = 0;
|
|
|
|
|
r.X2 = r.Y2 = -1;
|
2019-07-29 02:34:58 +02:00
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-23 13:35:12 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
2019-01-16 16:00:15 +01:00
|
|
|
|
FRect operator + (const FRect& r, const FSize& s)
|
2015-05-23 13:35:12 +02:00
|
|
|
|
{
|
2015-10-10 04:01:22 +02:00
|
|
|
|
return FRect ( r.X1
|
|
|
|
|
, r.Y1
|
2019-01-16 16:00:15 +01:00
|
|
|
|
, std::size_t(r.X2 - r.X1) + 1 + s.getWidth()
|
|
|
|
|
, std::size_t(r.Y2 - r.Y1) + 1 + s.getHeight() );
|
2015-05-23 13:35:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2019-01-16 16:00:15 +01:00
|
|
|
|
FRect operator - (const FRect& r, const FSize& s)
|
2015-05-23 13:35:12 +02:00
|
|
|
|
{
|
2015-10-10 04:01:22 +02:00
|
|
|
|
return FRect ( r.X1
|
|
|
|
|
, r.Y1
|
2019-09-09 19:13:38 +02:00
|
|
|
|
, std::size_t(r.X2 - r.X1) + 1 - s.getWidth()
|
|
|
|
|
, std::size_t(r.Y2 - r.Y1) + 1 - s.getHeight() );
|
2015-05-23 13:35:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
bool operator == (const FRect& r1, const FRect& r2)
|
|
|
|
|
{
|
|
|
|
|
return r1.X1 == r2.X1
|
|
|
|
|
&& r1.Y1 == r2.Y1
|
|
|
|
|
&& r1.X2 == r2.X2
|
|
|
|
|
&& r1.Y2 == r2.Y2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
bool operator != (const FRect& r1, const FRect& r2)
|
|
|
|
|
{
|
|
|
|
|
return r1.X1 != r2.X1
|
|
|
|
|
|| r1.Y1 != r2.Y1
|
|
|
|
|
|| r1.X2 != r2.X2
|
|
|
|
|
|| r1.Y2 != r2.Y2;
|
|
|
|
|
}
|
2018-04-16 02:24:37 +02:00
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
std::ostream& operator << (std::ostream& outstr, const FRect& r)
|
|
|
|
|
{
|
2019-01-21 03:42:18 +01:00
|
|
|
|
outstr << r.X1 << " "
|
|
|
|
|
<< r.Y1 << " "
|
|
|
|
|
<< r.X2 << " "
|
|
|
|
|
<< r.Y2;
|
2018-04-16 02:24:37 +02:00
|
|
|
|
return outstr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
std::istream& operator >> (std::istream& instr, FRect& r)
|
|
|
|
|
{
|
2019-10-01 23:14:00 +02:00
|
|
|
|
int x1{}, y1{}, x2{}, y2{};
|
2018-04-16 02:24:37 +02:00
|
|
|
|
instr >> x1;
|
|
|
|
|
instr >> y1;
|
|
|
|
|
instr >> x2;
|
|
|
|
|
instr >> y2;
|
|
|
|
|
r.setCoordinates (x1, y1, x2, y2);
|
|
|
|
|
return instr;
|
|
|
|
|
}
|
2018-09-20 23:59:01 +02:00
|
|
|
|
|
|
|
|
|
} // namespace finalcut
|