/* * DSFML - SFML Library wrapper for the D programming language. * Copyright (C) 2008 Julien Dagorn (sirjulio13@gmail.com) * Copyright (C) 2010 Andreas Hollandt * * This software is provided 'as-is', without any express or * implied warranty. In no event will the authors be held * liable for any damages arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute * it freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; * you must not claim that you wrote the original software. * If you use this software in a product, an acknowledgment * in the product documentation would be appreciated but * is not required. * * 2. Altered source versions must be plainly marked as such, * and must not be misrepresented as being the original software. * * 3. This notice may not be removed or altered from any * source distribution. */ module dsfml.graphics.rect; struct sfFloatRect { float Left; float Top; float Right; float Bottom; } struct sfIntRect { int Left; int Top; int Right; int Bottom; } version (Tango) { import tango.core.Traits; } else { template isIntegerType(T) { const bool isIntegerType = is (T == byte) || is (T == short) || is (T == int) || is (T == long); } template isRealType(T) { const bool isRealType = is (T == float) || is (T == double) || is (T == real); } } /** * Rect is an utility class for manipulating rectangles. * Template parameter defines the type of coordinates (integer float, ...) */ class Rect (T) { private: T m_Left; // Left coordinate of the rectangle T m_Top; // Top coordinate of the rectangle T m_Right; // Right coordinate of the rectangle T m_Bottom; // Bottom coordinate of the rectangle public: static if (!isIntegerType!(T) && !isRealType!(T)) { static assert (0, "This type is not supported by Rectangle"); } T min(T)(T i, T j) { return i < j ? i : j; } T max(T)(T i, T j) { return i > j ? i : j; } /** * Default constructor */ this() { m_Left = 0; m_Top = 0; m_Right = 0; m_Bottom = 0; } /** * Construct the rectangle from its coordinates * * Params: * leftCoord = Left coordinate of the rectangle * topCoord = Top coordinate of the rectangle * rightCoord = Right coordinate of the rectangle * bottomCoord = Bottom coordinate of the rectangle */ this(T leftCoord, T topCoord, T rightCoord, T bottomCoord) { m_Left = leftCoord; m_Top = topCoord; m_Right = rightCoord; m_Bottom = bottomCoord; } /** * Get the width of the rectangle * * Returns: * Width of rectangle */ T getWidth() { return m_Right - m_Left; } /** * Get the height of the rectangle * * Returns: * Height of rectangle */ T getHeight() { return m_Bottom - m_Top; } /** * Move the whole rectangle by the given offset * * Params: * offsetX = Horizontal offset * offsetY = Vertical offset */ void offset(T offsetX, T offsetY) { m_Left += offsetX; m_Right += offsetX; m_Top += offsetY; m_Bottom += offsetY; } /** * Check if a point is inside the rectangle's area * * Params: * x = X coordinate of the point to test * y = Y coordinate of the point to test * * Returns: * True if the point is inside */ bool contains(T x, T y) { return (x >= m_Left) && (x <= m_Right) && (y >= m_Top) && (y <= m_Bottom); } /** * Check intersection between two rectangles * * Params: * rectangle = Rectangle to test * overlappingRect = Rectangle to be filled with overlapping rect (NULL by default) * * Returns: * True if rectangles overlap */ bool intersects(Rect!(T) rectangle, out Rect!(T) overlappingRect = null) { // Compute overlapping rect Rect!(T) overlapping = new Rect!(T)( max(m_Left, rectangle.getLeft), max(m_Top, rectangle.getTop), min(m_Right, rectangle.getRight), min(m_Bottom, rectangle.getBottom) ); // If overlapping rect is valid, then there is intersection if ((overlapping.getLeft() < overlapping.getRight() ) && (overlapping.getTop() < overlapping.getBottom())) { overlappingRect = overlapping; return true; } else { overlappingRect = new Rect!(T)(); return false; } } /** * Set left Coordinate */ void setLeft(T left) { m_Left = left; } /** * Set top Coordinate */ void setTop(T top) { m_Top = top; } /** * Set right Coordinate */ void setRight(T right) { m_Right = right; } /** * Set bottom Coordinate */ void setBottom(T bottom) { m_Bottom = bottom; } /** * Get left Coordinate */ T getLeft() { return m_Left; } /** * Get top Coordinate */ T getTop() { return m_Top; } /** * Get right Coordinate */ T getRight() { return m_Right; } /** * Get bottom Coordinate */ T getBottom() { return m_Bottom; } package: sfFloatRect toCFloatRect() { return sfFloatRect(m_Left, m_Top, m_Right, m_Bottom); } sfIntRect toCIntRect() { return sfIntRect(cast(int)m_Left, cast(int)m_Top, cast(int)m_Right, cast(int)m_Bottom); } } ///Alias alias Rect!(int) IntRect; ///ditto alias Rect!(float) FloatRect;