Browse Source

Using Range2D instead of Rectangle everywhere.

Encourages vectorization and generic usage even more. Some functions
were rewritten to make use of the new features, resulting in shorter and
more readable code. This also fixes the annoying naming collision with
WINAPI Rectangle() function.

The old Rectangle is now subclass of Range2D, is marked as deprecated
and will be removed in future release.
pull/34/head
Vladimír Vondruš 13 years ago
parent
commit
ee8f757419
  1. 7
      doc/types.dox
  2. 10
      src/AbstractFramebuffer.cpp
  3. 12
      src/AbstractFramebuffer.h
  4. 3
      src/CMakeLists.txt
  5. 4
      src/DefaultFramebuffer.cpp
  6. 4
      src/DefaultFramebuffer.h
  7. 4
      src/Framebuffer.cpp
  8. 6
      src/Framebuffer.h
  9. 4
      src/Implementation/FramebufferState.h
  10. 19
      src/Magnum.h
  11. 9
      src/Math/Geometry/CMakeLists.txt
  12. 166
      src/Math/Geometry/Rectangle.h
  13. 1
      src/Math/Geometry/Test/CMakeLists.txt
  14. 176
      src/Math/Geometry/Test/RectangleTest.cpp
  15. 38
      src/Math/Geometry/instantiation.cpp
  16. 2
      src/Math/Math.h
  17. 34
      src/Math/Test/RangeTest.cpp
  18. 12
      src/Math/instantiation.cpp
  19. 24
      src/Plugins/MagnumFont/MagnumFont.cpp
  20. 22
      src/Plugins/MagnumFont/Test/MagnumFontTest.cpp
  21. 6
      src/Plugins/MagnumFontConverter/MagnumFontConverter.cpp
  22. 6
      src/Renderer.cpp
  23. 2
      src/Renderer.h
  24. 4
      src/Text/AbstractFont.cpp
  25. 4
      src/Text/AbstractFont.h
  26. 2
      src/Text/DistanceFieldGlyphCache.cpp
  27. 8
      src/Text/GlyphCache.cpp
  28. 14
      src/Text/GlyphCache.h
  29. 22
      src/Text/Renderer.cpp
  30. 12
      src/Text/Renderer.h
  31. 32
      src/Text/Test/AbstractLayouterTest.cpp
  32. 10
      src/Text/Test/GlyphCacheGLTest.cpp
  33. 26
      src/Text/Test/RendererGLTest.cpp
  34. 10
      src/TextureTools/Atlas.cpp
  35. 2
      src/TextureTools/Atlas.h
  36. 6
      src/TextureTools/DistanceField.cpp
  37. 4
      src/TextureTools/DistanceField.h
  38. 26
      src/TextureTools/Test/AtlasTest.cpp
  39. 2
      src/TextureTools/distancefieldconverter.cpp

7
doc/types.dox

@ -90,9 +90,10 @@ equivalently (e.g. @ref Math::Vector or @ref Color3 instead of @ref Vector3).
Other types, which don't have their GLSL equivalent, are: Other types, which don't have their GLSL equivalent, are:
- @ref Rectangle, @ref Rectanglei or @ref Rectangled - @ref Complex or @ref Complexd, @ref DualComplex or @ref DualComplexd
- @ref Complex or @ref Complexd, @ref DualComplex or @ref DualComplexd - @ref Quaternion or @ref Quaterniond, @ref DualQuaternion or @ref DualQuaterniond
- @ref Quaternion or @ref Quaterniond, @ref DualQuaternion or @ref DualQuaterniond - @ref Range1D / @ref Range2D / @ref Range3D, @ref Range1Di / @ref Range2Di / @ref Range3Di or
@ref Range1Dd / @ref Range2Dd / @ref Range3Dd
These types can be used in GLSL either by extracting values from their These types can be used in GLSL either by extracting values from their
underlying structure or converting them to types supported by GLSL (e.g. underlying structure or converting them to types supported by GLSL (e.g.

10
src/AbstractFramebuffer.cpp

@ -139,7 +139,7 @@ FramebufferTarget AbstractFramebuffer::bindInternal() {
#endif #endif
} }
void AbstractFramebuffer::blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& sourceRectangle, const Rectanglei& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter) { void AbstractFramebuffer::blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter) {
source.bindInternal(FramebufferTarget::Read); source.bindInternal(FramebufferTarget::Read);
destination.bindInternal(FramebufferTarget::Draw); destination.bindInternal(FramebufferTarget::Draw);
/** @todo Get some extension wrangler instead to avoid undeclared glBlitFramebuffer() on ES2 */ /** @todo Get some extension wrangler instead to avoid undeclared glBlitFramebuffer() on ES2 */
@ -153,7 +153,7 @@ void AbstractFramebuffer::blit(AbstractFramebuffer& source, AbstractFramebuffer&
#endif #endif
} }
AbstractFramebuffer& AbstractFramebuffer::setViewport(const Rectanglei& rectangle) { AbstractFramebuffer& AbstractFramebuffer::setViewport(const Range2Di& rectangle) {
_viewport = rectangle; _viewport = rectangle;
/* Update the viewport if the framebuffer is currently bound */ /* Update the viewport if the framebuffer is currently bound */
@ -174,7 +174,7 @@ void AbstractFramebuffer::setViewportInternal() {
/* Update the state and viewport */ /* Update the state and viewport */
state->viewport = _viewport; state->viewport = _viewport;
glViewport(_viewport.left(), _viewport.bottom(), _viewport.width(), _viewport.height()); glViewport(_viewport.left(), _viewport.bottom(), _viewport.sizeX(), _viewport.sizeY());
} }
void AbstractFramebuffer::clear(FramebufferClearMask mask) { void AbstractFramebuffer::clear(FramebufferClearMask mask) {
@ -227,10 +227,10 @@ void AbstractFramebuffer::invalidateImplementation(GLsizei count, GLenum* attach
#endif #endif
} }
void AbstractFramebuffer::invalidateImplementation(GLsizei count, GLenum* attachments, const Rectanglei& rectangle) { void AbstractFramebuffer::invalidateImplementation(GLsizei count, GLenum* attachments, const Range2Di& rectangle) {
/** @todo Re-enable when extension wrangler is available for ES2 */ /** @todo Re-enable when extension wrangler is available for ES2 */
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
glInvalidateSubFramebuffer(GLenum(bindInternal()), count, attachments, rectangle.left(), rectangle.bottom(), rectangle.width(), rectangle.height()); glInvalidateSubFramebuffer(GLenum(bindInternal()), count, attachments, rectangle.left(), rectangle.bottom(), rectangle.sizeX(), rectangle.sizeY());
#else #else
//glDiscardSubFramebufferEXT(GLenum(bindInternal()), count, attachments, rectangle.left(), rectangle.bottom(), rectangle.width(), rectangle.height()); //glDiscardSubFramebufferEXT(GLenum(bindInternal()), count, attachments, rectangle.left(), rectangle.bottom(), rectangle.width(), rectangle.height());
static_cast<void>(count); static_cast<void>(count);

12
src/AbstractFramebuffer.h

@ -207,7 +207,7 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit} * @es_extension{NV,framebuffer_blit}
*/ */
static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& sourceRectangle, const Rectanglei& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter); static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter);
/** /**
* @brief Copy block of pixels * @brief Copy block of pixels
@ -224,7 +224,7 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit} * @es_extension{NV,framebuffer_blit}
*/ */
static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& rectangle, FramebufferBlitMask mask) { static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& rectangle, FramebufferBlitMask mask) {
blit(source, destination, rectangle, rectangle, mask, FramebufferBlitFilter::Nearest); blit(source, destination, rectangle, rectangle, mask, FramebufferBlitFilter::Nearest);
} }
@ -242,7 +242,7 @@ class MAGNUM_EXPORT AbstractFramebuffer {
void bind(FramebufferTarget target); void bind(FramebufferTarget target);
/** @brief Viewport rectangle */ /** @brief Viewport rectangle */
Rectanglei viewport() const { return _viewport; } Range2Di viewport() const { return _viewport; }
/** /**
* @brief Set viewport * @brief Set viewport
@ -253,7 +253,7 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* rectangle. * rectangle.
* @see @ref maxViewportSize(), @fn_gl{Viewport} * @see @ref maxViewportSize(), @fn_gl{Viewport}
*/ */
AbstractFramebuffer& setViewport(const Rectanglei& rectangle); AbstractFramebuffer& setViewport(const Range2Di& rectangle);
/** /**
* @brief Clear specified buffers in framebuffer * @brief Clear specified buffers in framebuffer
@ -330,10 +330,10 @@ class MAGNUM_EXPORT AbstractFramebuffer {
static ReadBufferImplementation readBufferImplementation; static ReadBufferImplementation readBufferImplementation;
void MAGNUM_LOCAL invalidateImplementation(GLsizei count, GLenum* attachments); void MAGNUM_LOCAL invalidateImplementation(GLsizei count, GLenum* attachments);
void MAGNUM_LOCAL invalidateImplementation(GLsizei count, GLenum* attachments, const Rectanglei& rectangle); void MAGNUM_LOCAL invalidateImplementation(GLsizei count, GLenum* attachments, const Range2Di& rectangle);
GLuint _id; GLuint _id;
Rectanglei _viewport; Range2Di _viewport;
private: private:
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context& context); static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context& context);

3
src/CMakeLists.txt

@ -160,8 +160,7 @@ endif()
# Files shared between main library and math unit test library # Files shared between main library and math unit test library
set(MagnumMath_SRCS set(MagnumMath_SRCS
Math/Functions.cpp Math/Functions.cpp
Math/instantiation.cpp Math/instantiation.cpp)
Math/Geometry/instantiation.cpp)
# Set shared library flags for the objects, as they will be part of shared lib # Set shared library flags for the objects, as they will be part of shared lib
# TODO: fix when CMake sets target_EXPORTS for OBJECT targets as well # TODO: fix when CMake sets target_EXPORTS for OBJECT targets as well

4
src/DefaultFramebuffer.cpp

@ -65,7 +65,7 @@ void DefaultFramebuffer::invalidate(std::initializer_list<InvalidationAttachment
invalidateImplementation(attachments.size(), _attachments); invalidateImplementation(attachments.size(), _attachments);
} }
void DefaultFramebuffer::invalidate(std::initializer_list<InvalidationAttachment> attachments, const Rectanglei& rectangle) { void DefaultFramebuffer::invalidate(std::initializer_list<InvalidationAttachment> attachments, const Range2Di& rectangle) {
/** @todo C++14: use VLA to avoid heap allocation */ /** @todo C++14: use VLA to avoid heap allocation */
Containers::Array<GLenum> _attachments(attachments.size()); Containers::Array<GLenum> _attachments(attachments.size());
for(std::size_t i = 0; i != attachments.size(); ++i) for(std::size_t i = 0; i != attachments.size(); ++i)
@ -80,7 +80,7 @@ void DefaultFramebuffer::initializeContextBasedFunctionality(Context& context) {
/* Initial framebuffer size */ /* Initial framebuffer size */
GLint viewport[4]; GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport); glGetIntegerv(GL_VIEWPORT, viewport);
defaultFramebuffer._viewport = state->viewport = Rectanglei::fromSize({viewport[0], viewport[1]}, {viewport[2], viewport[3]}); defaultFramebuffer._viewport = state->viewport = Range2Di::fromSize({viewport[0], viewport[1]}, {viewport[2], viewport[3]});
/* Fake initial glViewport() call for ApiTrace */ /* Fake initial glViewport() call for ApiTrace */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES

4
src/DefaultFramebuffer.h

@ -400,11 +400,11 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @requires_gles30 %Extension @es_extension{EXT,discard_framebuffer}. * @requires_gles30 %Extension @es_extension{EXT,discard_framebuffer}.
* Use clear() instead where the extension is not supported. * Use clear() instead where the extension is not supported.
*/ */
void invalidate(std::initializer_list<InvalidationAttachment> attachments, const Rectanglei& rectangle); void invalidate(std::initializer_list<InvalidationAttachment> attachments, const Range2Di& rectangle);
/* Overloads to remove WTF-factor from method chaining order */ /* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
DefaultFramebuffer& setViewport(const Rectanglei& rectangle) { DefaultFramebuffer& setViewport(const Range2Di& rectangle) {
AbstractFramebuffer::setViewport(rectangle); AbstractFramebuffer::setViewport(rectangle);
return *this; return *this;
} }

4
src/Framebuffer.cpp

@ -71,7 +71,7 @@ Int Framebuffer::maxColorAttachments() {
return value; return value;
} }
Framebuffer::Framebuffer(const Rectanglei& viewport) { Framebuffer::Framebuffer(const Range2Di& viewport) {
_viewport = viewport; _viewport = viewport;
glGenFramebuffers(1, &_id); glGenFramebuffers(1, &_id);
@ -112,7 +112,7 @@ void Framebuffer::invalidate(std::initializer_list<InvalidationAttachment> attac
invalidateImplementation(attachments.size(), _attachments); invalidateImplementation(attachments.size(), _attachments);
} }
void Framebuffer::invalidate(std::initializer_list<InvalidationAttachment> attachments, const Rectanglei& rectangle) { void Framebuffer::invalidate(std::initializer_list<InvalidationAttachment> attachments, const Range2Di& rectangle) {
/** @todo C++14: use VLA to avoid heap allocation */ /** @todo C++14: use VLA to avoid heap allocation */
Containers::Array<GLenum> _attachments(attachments.size()); Containers::Array<GLenum> _attachments(attachments.size());
for(std::size_t i = 0; i != attachments.size(); ++i) for(std::size_t i = 0; i != attachments.size(); ++i)

6
src/Framebuffer.h

@ -290,7 +290,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* Generates new OpenGL framebuffer. * Generates new OpenGL framebuffer.
* @see setViewport(), @fn_gl{GenFramebuffers} * @see setViewport(), @fn_gl{GenFramebuffers}
*/ */
explicit Framebuffer(const Rectanglei& viewport); explicit Framebuffer(const Range2Di& viewport);
/** /**
* @brief Destructor * @brief Destructor
@ -389,7 +389,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @requires_gles30 %Extension @es_extension{EXT,discard_framebuffer}. * @requires_gles30 %Extension @es_extension{EXT,discard_framebuffer}.
* Use clear() instead where the extension is not supported. * Use clear() instead where the extension is not supported.
*/ */
void invalidate(std::initializer_list<InvalidationAttachment> attachments, const Rectanglei& rectangle); void invalidate(std::initializer_list<InvalidationAttachment> attachments, const Range2Di& rectangle);
/** /**
* @brief Map given color attachment for reading * @brief Map given color attachment for reading
@ -503,7 +503,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
/* Overloads to remove WTF-factor from method chaining order */ /* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
Framebuffer& setViewport(const Rectanglei& rectangle) { Framebuffer& setViewport(const Range2Di& rectangle) {
AbstractFramebuffer::setViewport(rectangle); AbstractFramebuffer::setViewport(rectangle);
return *this; return *this;
} }

4
src/Implementation/FramebufferState.h

@ -24,7 +24,7 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
*/ */
#include "Math/Geometry/Rectangle.h" #include "Math/Range.h"
#include "Magnum.h" #include "Magnum.h"
#include "OpenGL.h" #include "OpenGL.h"
@ -42,7 +42,7 @@ struct FramebufferState {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
GLint maxDualSourceDrawBuffers; GLint maxDualSourceDrawBuffers;
#endif #endif
Rectanglei viewport; Range2Di viewport;
Vector2i maxViewportSize; Vector2i maxViewportSize;
}; };

19
src/Magnum.h

@ -327,11 +327,19 @@ typedef Math::Range2D<Int> Range2Di;
/** @brief Signed integer 3D range */ /** @brief Signed integer 3D range */
typedef Math::Range3D<Int> Range3Di; typedef Math::Range3D<Int> Range3Di;
/** @brief Float rectangle */ #ifdef MAGNUM_BUILD_DEPRECATED
/**
@copybrief Range2D
@deprecated Use @ref Magnum::Range2D instead.
*/
typedef Math::Geometry::Rectangle<Float> Rectangle; typedef Math::Geometry::Rectangle<Float> Rectangle;
/** @brief Signed integer rectangle */ /**
@copybrief Range2Di
@deprecated Use @ref Magnum::Range2Di instead.
*/
typedef Math::Geometry::Rectangle<Int> Rectanglei; typedef Math::Geometry::Rectangle<Int> Rectanglei;
#endif
/*@}*/ /*@}*/
@ -483,8 +491,13 @@ typedef Math::Range2D<Double> Range2Dd;
/** @brief Double 3D range */ /** @brief Double 3D range */
typedef Math::Range3D<Double> Range3Dd; typedef Math::Range3D<Double> Range3Dd;
/** @brief Double rectangle */ #ifdef MAGNUM_BUILD_DEPRECATED
/**
@copybrief Range2Dd
@deprecated Use @ref Magnum::Range2Dd instead.
*/
typedef Math::Geometry::Rectangle<Double> Rectangled; typedef Math::Geometry::Rectangle<Double> Rectangled;
#endif
/*@}*/ /*@}*/
#endif #endif

9
src/Math/Geometry/CMakeLists.txt

@ -24,11 +24,16 @@
set(MagnumMathGeometry_HEADERS set(MagnumMathGeometry_HEADERS
Distance.h Distance.h
Intersection.h Intersection.h)
Rectangle.h)
install(FILES ${MagnumMathGeometry_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Math/Geometry) install(FILES ${MagnumMathGeometry_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Math/Geometry)
# Deprecated headers
if(BUILD_DEPRECATED)
set(MagnumMathGeometry_HEADERS ${MagnumMathGeometry_HEADERS}
Rectangle.h)
endif()
if(BUILD_TESTS) if(BUILD_TESTS)
add_subdirectory(Test) add_subdirectory(Test)
endif() endif()

166
src/Math/Geometry/Rectangle.h

@ -25,162 +25,46 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::Geometry::Rectangle * @brief Class @ref Magnum::Math::Geometry::Rectangle
* @deprecated Use @ref Math/Range.h instead.
*/ */
#include "Math/Vector2.h" #include "Math/Range.h"
#ifdef MAGNUM_BUILD_DEPRECATED
namespace Magnum { namespace Math { namespace Geometry { namespace Magnum { namespace Math { namespace Geometry {
/** /**
@brief %Rectangle @copybrief Math::Range2D
@deprecated Use @ref Math::Range2D instead.
Helper class for storing axis-aligned rectangles consisting of bottom left and
top right corner positions with origin in bottom left. Bottom/left positions
are inclusive, while top/right positions are exclusive.
@see Magnum::Rectangle, Magnum::Rectanglei, Magnum::Rectangled
@todo rename to Range, make it generic for one, two and three dimensions, add translated(), padded()...
@todo move outside Math?
*/ */
template<class T> class Rectangle { template<class T> class Rectangle: public Range2D<T> {
template<class> friend class Rectangle;
public: public:
/** /** @copydoc Range2D() */
* Create rectangle from position and size constexpr Rectangle() = default;
* @param bottomLeft Bottom left rectangle corner
* @param size %Rectangle size
*/
static Rectangle<T> fromSize(const Vector2<T>& bottomLeft, const Vector2<T>& size) {
return {bottomLeft, bottomLeft+size};
}
/**
* @brief Construct zero rectangle
*
* Construct zero-area rectangle positioned at origin.
*/
constexpr Rectangle() {}
/** @brief Construct rectangle from two corners */
constexpr Rectangle(const Vector2<T>& bottomLeft, const Vector2<T>& topRight): _bottomLeft(bottomLeft), _topRight(topRight) {}
/**
* @brief Construct rectangle from another of different type
*
* Performs only default casting on the values, no rounding or
* anything else. Example usage:
* @code
* Rectangle<Float> floatingPoint({1.3f, 2.7f}, {-15.0f, 7.0f});
* Rectangle<Byte> integral(floatingPoint); // {{1, 2}, {-15, 7}}
* @endcode
*/
template<class U> constexpr explicit Rectangle(const Rectangle<U>& other): _bottomLeft(other._bottomLeft), _topRight(other._topRight) {}
/** @brief Copy constructor */
constexpr Rectangle(const Rectangle<T>&) = default;
/** @brief Assignment operator */
Rectangle<T>& operator=(const Rectangle<T>&) = default;
/** @brief Equality operator */
constexpr bool operator==(const Rectangle<T>& other) const {
return _bottomLeft == other._bottomLeft && _topRight == other._topRight;
}
/** @brief Non-equality operator */
constexpr bool operator!=(const Rectangle<T>& other) const {
return !operator==(other);
}
/** @brief Bottom left corner */
Vector2<T>& bottomLeft() { return _bottomLeft; }
constexpr Vector2<T> bottomLeft() const { return _bottomLeft; } /**< @overload */
/** @brief Bottom right corner */
constexpr Vector2<T> bottomRight() const { return {_topRight.x(), _bottomLeft.y()}; } /**< @overload */
/** @brief Top left corner */
constexpr Vector2<T> topLeft() const { return {_bottomLeft.x(), _topRight.y()}; } /**< @overload */
/** @brief Top right corner */
Vector2<T>& topRight() { return _topRight; }
constexpr Vector2<T> topRight() const { return _topRight; } /**< @overload */
/** @brief Bottom edge */
T& bottom() { return _bottomLeft.y(); }
constexpr T bottom() const { return _bottomLeft.y(); } /**< @overload */
/** @brief Top edge */
T& top() { return _topRight.y(); }
constexpr T top() const { return _topRight.y(); } /**< @overload */
/** @brief Left edge */
T& left() { return _bottomLeft.x(); }
constexpr T left() const { return _bottomLeft.x(); } /**< @overload */
/** @brief Right edge */
T& right() { return _topRight.x(); }
constexpr T right() const { return _topRight.x(); } /**< @overload */
/** @brief %Rectangle size */
constexpr Vector2<T> size() const { return _topRight-_bottomLeft; }
/** @brief %Rectangle width */
constexpr T width() const { return _topRight.x() - _bottomLeft.x(); }
/** @brief %Rectangle height */
constexpr T height() const { return _topRight.y() - _bottomLeft.y(); }
/** @brief Translated rectangle */
Rectangle<T> translated(const Vector2<T>& vec) {
return {_bottomLeft + vec, _topRight + vec};
};
private:
Vector2<T> _bottomLeft;
Vector2<T> _topRight;
};
/** @debugoperator{Magnum::Math::Geometry::Rectangle} */ /** @copydoc Range2D(const VectorType&, const VectorType&) */
template<class T> Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Rectangle<T>& value) { constexpr Rectangle(const Vector2<T>& min, const Vector2<T>& max): Range2D<T>(min, max) {}
debug << "Rectangle({";
debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, false);
debug << value.left() << ", " << value.bottom() << "}, {" << value.right() << ", " << value.top() << "})";
debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, true);
return debug;
}
}}} /** @copydoc Range2D(const Range&) */
constexpr Rectangle(const Range<2, T>& other): Range2D<T>(other) {}
namespace Corrade { namespace Utility { /** @copydoc Range2D(const Range<dimensions, U>&) */
template<class U> constexpr explicit Rectangle(const Range2D<U>& other): Range2D<T>(other) {}
/** @copydoc Range2D::sizeX() */
T width() const { return Range2D<T>::sizeX(); }
/** @configurationvalue{Magnum::Math::Geometry::Rectangle} */ /** @copydoc Range2D::sizeY() */
template<class T> struct ConfigurationValue<Magnum::Math::Geometry::Rectangle<T>> { T height() const { return Range2D<T>::sizeY(); }
ConfigurationValue() = delete;
/** @brief Writes elements separated with spaces */
static std::string toString(const Magnum::Math::Geometry::Rectangle<T>& value, const ConfigurationValueFlags flags) {
return ConfigurationValue<Magnum::Math::Vector<4, T>>::toString(
reinterpret_cast<const Magnum::Math::Vector<4, T>&>(value), flags);
}
/** @brief Reads elements separated with whitespace */
static Magnum::Math::Geometry::Rectangle<T> fromString(const std::string& stringValue, const ConfigurationValueFlags flags) {
const auto vec = ConfigurationValue<Magnum::Math::Vector<4, T>>::fromString(stringValue, flags);
return {{vec[0], vec[1]}, {vec[2], vec[3]}};
}
}; };
#ifndef DOXYGEN_GENERATING_OUTPUT }}}
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::Geometry::Rectangle<Magnum::Float>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::Geometry::Rectangle<Magnum::Int>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::Geometry::Rectangle<Magnum::UnsignedInt>>;
#ifndef MAGNUM_TARGET_GLES
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::Geometry::Rectangle<Magnum::Double>>;
#endif
#endif
namespace Corrade { namespace Utility {
/** @configurationvalue{Magnum::Math::Geometry::Rectangle} */
template<class T> struct ConfigurationValue<Magnum::Math::Geometry::Rectangle<T>>: public ConfigurationValue<Magnum::Math::Range2D<T>> {};
}} }}
#endif
#endif #endif

1
src/Math/Geometry/Test/CMakeLists.txt

@ -24,4 +24,3 @@
corrade_add_test(MathGeometryDistanceTest DistanceTest.cpp) corrade_add_test(MathGeometryDistanceTest DistanceTest.cpp)
corrade_add_test(MathGeometryIntersectionTest IntersectionTest.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathGeometryIntersectionTest IntersectionTest.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathGeometryRectangleTest RectangleTest.cpp LIBRARIES MagnumMathTestLib)

176
src/Math/Geometry/Test/RectangleTest.cpp

@ -1,176 +0,0 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <sstream>
#include <TestSuite/Tester.h>
#include <Utility/Configuration.h>
#include "Math/Geometry/Rectangle.h"
namespace Magnum { namespace Math { namespace Geometry { namespace Test {
class RectangleTest: public Corrade::TestSuite::Tester {
public:
RectangleTest();
void construct();
void constructDefault();
void constructFromSize();
void constructConversion();
void constructCopy();
void access();
void compare();
void size();
void translated();
void debug();
void configuration();
};
typedef Geometry::Rectangle<Float> Rectangle;
typedef Geometry::Rectangle<Int> Rectanglei;
typedef Vector2<Int> Vector2i;
RectangleTest::RectangleTest() {
addTests({&RectangleTest::construct,
&RectangleTest::constructDefault,
&RectangleTest::constructFromSize,
&RectangleTest::constructConversion,
&RectangleTest::constructCopy,
&RectangleTest::access,
&RectangleTest::compare,
&RectangleTest::size,
&RectangleTest::translated,
&RectangleTest::debug,
&RectangleTest::configuration});
}
void RectangleTest::construct() {
constexpr Rectanglei a({3, 5}, {23, 78});
CORRADE_COMPARE(a, Rectanglei({3, 5}, {23, 78}));
}
void RectangleTest::constructDefault() {
constexpr Rectanglei a;
CORRADE_COMPARE(a, Rectanglei({0, 0}, {0, 0}));
}
void RectangleTest::constructFromSize() {
CORRADE_COMPARE(Rectanglei::fromSize({3, 5}, {23, 78}), Rectanglei({3, 5}, {26, 83}));
}
void RectangleTest::constructConversion() {
constexpr Rectangle a({1.3f, 2.7f}, {-15.0f, 7.0f});
#ifndef CORRADE_GCC46_COMPATIBILITY
constexpr /* Not constexpr under GCC < 4.7 */
#endif
Rectanglei b(a);
CORRADE_COMPARE(b, Rectanglei({1, 2}, {-15, 7}));
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Rectangle, Rectanglei>::value));
}
void RectangleTest::constructCopy() {
constexpr Rectanglei a({3, 5}, {23, 78});
constexpr Rectanglei b(a);
CORRADE_COMPARE(b, Rectanglei({3, 5}, {23, 78}));
}
void RectangleTest::access() {
Rectanglei rect({34, 23}, {47, 30});
constexpr Rectanglei crect({34, 23}, {47, 30});
CORRADE_COMPARE(rect.bottomLeft(), Vector2i(34, 23));
CORRADE_COMPARE(rect.topRight(), Vector2i(47, 30));
CORRADE_COMPARE(rect.bottom(), 23);
CORRADE_COMPARE(rect.top(), 30);
CORRADE_COMPARE(rect.left(), 34);
CORRADE_COMPARE(rect.right(), 47);
CORRADE_COMPARE(rect.bottomLeft(), Vector2i(34, 23));
CORRADE_COMPARE(rect.topRight(), Vector2i(47, 30));
constexpr Int bottom = crect.bottom();
constexpr Int top = crect.top();
constexpr Int left = crect.left();
constexpr Int right = crect.right();
CORRADE_COMPARE(bottom, 23);
CORRADE_COMPARE(top, 30);
CORRADE_COMPARE(left, 34);
CORRADE_COMPARE(right, 47);
constexpr Vector2i bottomLeft = crect.bottomLeft();
constexpr Vector2i topRight = crect.topRight();
CORRADE_COMPARE(bottomLeft, Vector2i(34, 23));
CORRADE_COMPARE(topRight, Vector2i(47, 30));
CORRADE_COMPARE(rect.topLeft(), Vector2i(34, 30));
CORRADE_COMPARE(rect.bottomRight(), Vector2i(47, 23));
}
void RectangleTest::compare() {
CORRADE_VERIFY(Rectanglei({34, 23}, {47, 30}) == Rectanglei({34, 23}, {47, 30}));
CORRADE_VERIFY(Rectanglei({34, 23}, {47, 30}) != Rectanglei({34, 23}, {48, 30}));
CORRADE_VERIFY(Rectanglei({34, 23}, {47, 30}) != Rectanglei({35, 23}, {47, 30}));
}
void RectangleTest::size() {
Rectanglei rect({34, 23}, {47, 30});
CORRADE_COMPARE(rect.size(), Vector2i(13, 7));
CORRADE_COMPARE(rect.width(), 13);
CORRADE_COMPARE(rect.height(), 7);
}
void RectangleTest::translated() {
CORRADE_COMPARE(Rectanglei({34, 23}, {47, 30}).translated({-17, 40}),
Rectanglei({17, 63}, {30, 70}));
}
void RectangleTest::debug() {
std::ostringstream o;
Debug(&o) << Rectanglei({34, 23}, {47, 30});
CORRADE_COMPARE(o.str(), "Rectangle({34, 23}, {47, 30})\n");
}
void RectangleTest::configuration() {
Corrade::Utility::Configuration c;
Rectangle rect({3.0f, 3.125f}, {9.0f, 9.55f});
std::string value("3 3.125 9 9.55");
c.setValue("rectangle", rect);
CORRADE_COMPARE(c.value("rectangle"), value);
CORRADE_COMPARE(c.value<Rectangle>("rectangle"), rect);
}
}}}}
CORRADE_TEST_MAIN(Magnum::Math::Geometry::Test::RectangleTest)

38
src/Math/Geometry/instantiation.cpp

@ -1,38 +0,0 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "Math/Geometry/Rectangle.h"
namespace Corrade { namespace Utility {
#ifndef DOXYGEN_GENERATING_OUTPUT
template struct ConfigurationValue<Magnum::Math::Geometry::Rectangle<Magnum::Float>>;
template struct ConfigurationValue<Magnum::Math::Geometry::Rectangle<Magnum::Int>>;
template struct ConfigurationValue<Magnum::Math::Geometry::Rectangle<Magnum::UnsignedInt>>;
#ifndef MAGNUM_TARGET_GLES
template struct ConfigurationValue<Magnum::Math::Geometry::Rectangle<Magnum::Double>>;
#endif
#endif
}}

2
src/Math/Math.h

@ -82,9 +82,11 @@ template<class T> using Range1D = Range<1, T>;
template<class> class Range2D; template<class> class Range2D;
template<class> class Range3D; template<class> class Range3D;
#ifdef MAGNUM_BUILD_DEPRECATED
namespace Geometry { namespace Geometry {
template<class> class Rectangle; template<class> class Rectangle;
} }
#endif
}} }}

34
src/Math/Test/RangeTest.cpp

@ -56,6 +56,10 @@ class RangeTest: public Corrade::TestSuite::Tester {
void subclassTypes(); void subclassTypes();
void subclass(); void subclass();
#ifdef MAGNUM_BUILD_DEPRECATED
void deprecated();
#endif
void debug(); void debug();
void configuration(); void configuration();
}; };
@ -88,6 +92,10 @@ RangeTest::RangeTest() {
&RangeTest::subclassTypes, &RangeTest::subclassTypes,
&RangeTest::subclass, &RangeTest::subclass,
#ifdef MAGNUM_BUILD_DEPRECATED
&RangeTest::deprecated,
#endif
&RangeTest::debug, &RangeTest::debug,
&RangeTest::configuration}); &RangeTest::configuration});
} }
@ -339,6 +347,32 @@ void RangeTest::debug() {
CORRADE_COMPARE(o.str(), "Range({34, 23}, {47, 30})\n"); CORRADE_COMPARE(o.str(), "Range({34, 23}, {47, 30})\n");
} }
#ifdef MAGNUM_BUILD_DEPRECATED
void RangeTest::deprecated() {
typedef Geometry::Rectangle<Float> Rectangle;
typedef Geometry::Rectangle<Int> Rectanglei;
Rectanglei a({45, 23}, {-17, 35});
CORRADE_COMPARE(Rectanglei(), Range2Di({0, 0}, {0, 0}));
CORRADE_COMPARE(a, Range2Di({45, 23}, {-17, 35}));
CORRADE_COMPARE(Rectanglei(a), Range2Di({45, 23}, {-17, 35}));
CORRADE_COMPARE(Rectangle(a), Range2D({45.0f, 23.0f}, {-17.0f, 35.0f}));
CORRADE_COMPARE(a.width(), -62);
CORRADE_COMPARE(a.height(), 12);
CORRADE_VERIFY(!(std::is_convertible<Rectangle, Rectanglei>::value));
Corrade::Utility::Configuration c;
Rectangle rect({3.0f, 3.125f}, {9.0f, 9.55f});
std::string value("3 3.125 9 9.55");
c.setValue("rectangle", rect);
CORRADE_COMPARE(c.value("rectangle"), value);
CORRADE_COMPARE(c.value<Rectangle>("rectangle"), rect);
}
#endif
void RangeTest::configuration() { void RangeTest::configuration() {
Corrade::Utility::Configuration c; Corrade::Utility::Configuration c;

12
src/Math/instantiation.cpp

@ -53,32 +53,20 @@ template struct ConfigurationValue<Magnum::Math::RectangularMatrix<3, 4, Magnum:
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<4, 3, Magnum::Double>>; template struct ConfigurationValue<Magnum::Math::RectangularMatrix<4, 3, Magnum::Double>>;
#endif #endif
/* For some reason mingw's GCC instantiates ConfigurationValue<Magnum::Math::Geometry::Rectangle<...>>
(which depends on ConfigurationValue<Magnum::Math::Vector<4, ...>) before
these and then loudly complains about multiple definitions. WTF. */
template struct ConfigurationValue<Magnum::Math::Vector<2, Magnum::Float>>; template struct ConfigurationValue<Magnum::Math::Vector<2, Magnum::Float>>;
template struct ConfigurationValue<Magnum::Math::Vector<3, Magnum::Float>>; template struct ConfigurationValue<Magnum::Math::Vector<3, Magnum::Float>>;
#ifndef __MINGW32__
template struct ConfigurationValue<Magnum::Math::Vector<4, Magnum::Float>>; template struct ConfigurationValue<Magnum::Math::Vector<4, Magnum::Float>>;
#endif
template struct ConfigurationValue<Magnum::Math::Vector<2, Magnum::Int>>; template struct ConfigurationValue<Magnum::Math::Vector<2, Magnum::Int>>;
template struct ConfigurationValue<Magnum::Math::Vector<3, Magnum::Int>>; template struct ConfigurationValue<Magnum::Math::Vector<3, Magnum::Int>>;
#ifndef __MINGW32__
template struct ConfigurationValue<Magnum::Math::Vector<4, Magnum::Int>>; template struct ConfigurationValue<Magnum::Math::Vector<4, Magnum::Int>>;
#endif
template struct ConfigurationValue<Magnum::Math::Vector<2, Magnum::UnsignedInt>>; template struct ConfigurationValue<Magnum::Math::Vector<2, Magnum::UnsignedInt>>;
template struct ConfigurationValue<Magnum::Math::Vector<3, Magnum::UnsignedInt>>; template struct ConfigurationValue<Magnum::Math::Vector<3, Magnum::UnsignedInt>>;
#ifndef __MINGW32__
template struct ConfigurationValue<Magnum::Math::Vector<4, Magnum::UnsignedInt>>; template struct ConfigurationValue<Magnum::Math::Vector<4, Magnum::UnsignedInt>>;
#endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
template struct ConfigurationValue<Magnum::Math::Vector<2, Magnum::Double>>; template struct ConfigurationValue<Magnum::Math::Vector<2, Magnum::Double>>;
template struct ConfigurationValue<Magnum::Math::Vector<3, Magnum::Double>>; template struct ConfigurationValue<Magnum::Math::Vector<3, Magnum::Double>>;
#ifndef __MINGW32__
template struct ConfigurationValue<Magnum::Math::Vector<4, Magnum::Double>>; template struct ConfigurationValue<Magnum::Math::Vector<4, Magnum::Double>>;
#endif #endif
#endif
template struct ConfigurationValue<Magnum::Math::Range<2, Magnum::Float>>; template struct ConfigurationValue<Magnum::Math::Range<2, Magnum::Float>>;
template struct ConfigurationValue<Magnum::Math::Range<2, Magnum::Int>>; template struct ConfigurationValue<Magnum::Math::Range<2, Magnum::Int>>;

24
src/Plugins/MagnumFont/MagnumFont.cpp

@ -52,7 +52,7 @@ namespace {
explicit MagnumFontLayouter(const std::vector<Vector2>& glyphAdvance, const GlyphCache& cache, Float fontSize, Float textSize, std::vector<UnsignedInt>&& glyphs); explicit MagnumFontLayouter(const std::vector<Vector2>& glyphAdvance, const GlyphCache& cache, Float fontSize, Float textSize, std::vector<UnsignedInt>&& glyphs);
private: private:
std::tuple<Rectangle, Rectangle, Vector2> doRenderGlyph(UnsignedInt i) override; std::tuple<Range2D, Range2D, Vector2> doRenderGlyph(UnsignedInt i) override;
const std::vector<Vector2>& glyphAdvance; const std::vector<Vector2>& glyphAdvance;
const GlyphCache& cache; const GlyphCache& cache;
@ -196,7 +196,7 @@ std::unique_ptr<GlyphCache> MagnumFont::doCreateGlyphCache() {
/* Fill glyph map */ /* Fill glyph map */
const std::vector<Utility::ConfigurationGroup*> glyphs = _opened->conf.groups("glyph"); const std::vector<Utility::ConfigurationGroup*> glyphs = _opened->conf.groups("glyph");
for(std::size_t i = 0; i != glyphs.size(); ++i) for(std::size_t i = 0; i != glyphs.size(); ++i)
cache->insert(i, glyphs[i]->value<Vector2i>("position"), glyphs[i]->value<Rectanglei>("rectangle")); cache->insert(i, glyphs[i]->value<Vector2i>("position"), glyphs[i]->value<Range2Di>("rectangle"));
return cache; return cache;
} }
@ -219,27 +219,23 @@ namespace {
MagnumFontLayouter::MagnumFontLayouter(const std::vector<Vector2>& glyphAdvance, const GlyphCache& cache, const Float fontSize, const Float textSize, std::vector<UnsignedInt>&& glyphs): AbstractLayouter(glyphs.size()), glyphAdvance(glyphAdvance), cache(cache), fontSize(fontSize), textSize(textSize), glyphs(std::move(glyphs)) {} MagnumFontLayouter::MagnumFontLayouter(const std::vector<Vector2>& glyphAdvance, const GlyphCache& cache, const Float fontSize, const Float textSize, std::vector<UnsignedInt>&& glyphs): AbstractLayouter(glyphs.size()), glyphAdvance(glyphAdvance), cache(cache), fontSize(fontSize), textSize(textSize), glyphs(std::move(glyphs)) {}
std::tuple<Rectangle, Rectangle, Vector2> MagnumFontLayouter::doRenderGlyph(const UnsignedInt i) { std::tuple<Range2D, Range2D, Vector2> MagnumFontLayouter::doRenderGlyph(const UnsignedInt i) {
/* Position of the texture in the resulting glyph, texture coordinates */ /* Position of the texture in the resulting glyph, texture coordinates */
Vector2i position; Vector2i position;
Rectanglei rectangle; Range2Di rectangle;
std::tie(position, rectangle) = cache[glyphs[i]]; std::tie(position, rectangle) = cache[glyphs[i]];
const Rectangle texturePosition = Rectangle::fromSize(Vector2(position)/fontSize, /* Normalized texture coordinates */
Vector2(rectangle.size())/fontSize); const auto textureCoordinates = Range2D(rectangle).scaled(1.0f/Vector2(cache.textureSize()));
const Rectangle textureCoordinates(Vector2(rectangle.bottomLeft())/Vector2(cache.textureSize()),
Vector2(rectangle.topRight())/Vector2(cache.textureSize()));
/* Absolute quad position, composed from cursor position, glyph offset /* Quad rectangle, computed from texture rectangle, denormalized to
and texture position, denormalized to requested text size */ requested text size */
Rectangle quadPosition = Rectangle::fromSize( const auto quadRectangle = Range2D(Range2Di::fromSize(position, rectangle.size())).scaled(Vector2(textSize/fontSize));
Vector2(texturePosition.left(), texturePosition.bottom())*textSize,
texturePosition.size()*textSize);
/* Advance for given glyph, denormalized to requested text size */ /* Advance for given glyph, denormalized to requested text size */
const Vector2 advance = glyphAdvance[glyphs[i]]*textSize/fontSize; const Vector2 advance = glyphAdvance[glyphs[i]]*textSize/fontSize;
return std::make_tuple(quadPosition, textureCoordinates, advance); return std::make_tuple(quadRectangle, textureCoordinates, advance);
} }
} }

22
src/Plugins/MagnumFont/Test/MagnumFontTest.cpp

@ -68,33 +68,33 @@ void MagnumFontTest::layout() {
CORRADE_VERIFY(layouter); CORRADE_VERIFY(layouter);
CORRADE_COMPARE(layouter->glyphCount(), 4); CORRADE_COMPARE(layouter->glyphCount(), 4);
Rectangle rectangle; Range2D rectangle;
Rectangle position; Range2D position;
Rectangle textureCoordinates; Range2D textureCoordinates;
/* 'W' */ /* 'W' */
Vector2 cursorPosition; Vector2 cursorPosition;
std::tie(position, textureCoordinates) = layouter->renderGlyph(0, cursorPosition = {}, rectangle); std::tie(position, textureCoordinates) = layouter->renderGlyph(0, cursorPosition = {}, rectangle);
CORRADE_COMPARE(position, Rectangle({0.78125f, 1.0625f}, {1.28125f, 4.8125f})); CORRADE_COMPARE(position, Range2D({0.78125f, 1.0625f}, {1.28125f, 4.8125f}));
CORRADE_COMPARE(textureCoordinates, Rectangle({0, 0.03125f}, {0.0625f, 0.5f})); CORRADE_COMPARE(textureCoordinates, Range2D({0, 0.03125f}, {0.0625f, 0.5f}));
CORRADE_COMPARE(cursorPosition, Vector2(0.71875f, 0.0f)); CORRADE_COMPARE(cursorPosition, Vector2(0.71875f, 0.0f));
/* 'a' (not found) */ /* 'a' (not found) */
std::tie(position, textureCoordinates) = layouter->renderGlyph(1, cursorPosition = {}, rectangle); std::tie(position, textureCoordinates) = layouter->renderGlyph(1, cursorPosition = {}, rectangle);
CORRADE_COMPARE(position, Rectangle()); CORRADE_COMPARE(position, Range2D());
CORRADE_COMPARE(textureCoordinates, Rectangle()); CORRADE_COMPARE(textureCoordinates, Range2D());
CORRADE_COMPARE(cursorPosition, Vector2(0.25f, 0.0f)); CORRADE_COMPARE(cursorPosition, Vector2(0.25f, 0.0f));
/* 'v' (not found) */ /* 'v' (not found) */
std::tie(position, textureCoordinates) = layouter->renderGlyph(2, cursorPosition = {}, rectangle); std::tie(position, textureCoordinates) = layouter->renderGlyph(2, cursorPosition = {}, rectangle);
CORRADE_COMPARE(position, Rectangle()); CORRADE_COMPARE(position, Range2D());
CORRADE_COMPARE(textureCoordinates, Rectangle()); CORRADE_COMPARE(textureCoordinates, Range2D());
CORRADE_COMPARE(cursorPosition, Vector2(0.25f, 0.0f)); CORRADE_COMPARE(cursorPosition, Vector2(0.25f, 0.0f));
/* 'e' */ /* 'e' */
std::tie(position, textureCoordinates) = layouter->renderGlyph(3, cursorPosition = {}, rectangle); std::tie(position, textureCoordinates) = layouter->renderGlyph(3, cursorPosition = {}, rectangle);
CORRADE_COMPARE(position, Rectangle({0.78125f, 0.375f}, {2.28125f, 1.25f})); CORRADE_COMPARE(position, Range2D({0.78125f, 0.375f}, {2.28125f, 1.25f}));
CORRADE_COMPARE(textureCoordinates, Rectangle({0.0625f, 0.015625f}, {0.25f, 0.125f})); CORRADE_COMPARE(textureCoordinates, Range2D({0.0625f, 0.015625f}, {0.25f, 0.125f}));
CORRADE_COMPARE(cursorPosition, Vector2(0.375f, 0.0f)); CORRADE_COMPARE(cursorPosition, Vector2(0.375f, 0.0f));
} }

6
src/Plugins/MagnumFontConverter/MagnumFontConverter.cpp

@ -68,7 +68,7 @@ std::vector<std::pair<std::string, Containers::Array<unsigned char>>> MagnumFont
#else #else
glyphIdMap.insert({0, 0}); glyphIdMap.insert({0, 0});
#endif #endif
for(const std::pair<UnsignedInt, std::pair<Vector2i, Rectanglei>>& glyph: cache) for(const std::pair<UnsignedInt, std::pair<Vector2i, Range2Di>>& glyph: cache)
#ifndef CORRADE_GCC46_COMPATIBILITY #ifndef CORRADE_GCC46_COMPATIBILITY
glyphIdMap.emplace(glyph.first, glyphIdMap.size()); glyphIdMap.emplace(glyph.first, glyphIdMap.size());
#else #else
@ -97,11 +97,11 @@ std::vector<std::pair<std::string, Containers::Array<unsigned char>>> MagnumFont
from the values so they aren't added twice when using the font later */ from the values so they aren't added twice when using the font later */
/** @todo Some better way to handle this padding stuff */ /** @todo Some better way to handle this padding stuff */
for(UnsignedInt oldGlyphId: inverseGlyphIdMap) { for(UnsignedInt oldGlyphId: inverseGlyphIdMap) {
std::pair<Vector2i, Rectanglei> glyph = cache[oldGlyphId]; std::pair<Vector2i, Range2Di> glyph = cache[oldGlyphId];
Utility::ConfigurationGroup* group = configuration.addGroup("glyph"); Utility::ConfigurationGroup* group = configuration.addGroup("glyph");
group->setValue("advance", font.glyphAdvance(oldGlyphId)); group->setValue("advance", font.glyphAdvance(oldGlyphId));
group->setValue("position", glyph.first+cache.padding()); group->setValue("position", glyph.first+cache.padding());
group->setValue("rectangle", Rectanglei(glyph.second.bottomLeft()+cache.padding(), group->setValue("rectangle", Range2Di(glyph.second.bottomLeft()+cache.padding(),
glyph.second.topRight()-cache.padding())); glyph.second.topRight()-cache.padding()));
} }

6
src/Renderer.cpp

@ -24,8 +24,8 @@
#include "Renderer.h" #include "Renderer.h"
#include "Math/Range.h"
#include "Color.h" #include "Color.h"
#include "Math/Geometry/Rectangle.h"
#include "Context.h" #include "Context.h"
#include "Extensions.h" #include "Extensions.h"
#include "Implementation/State.h" #include "Implementation/State.h"
@ -94,8 +94,8 @@ void Renderer::setPointSize(const Float size) {
} }
#endif #endif
void Renderer::setScissor(const Rectanglei& rectangle) { void Renderer::setScissor(const Range2Di& rectangle) {
glScissor(rectangle.left(), rectangle.bottom(), rectangle.width(), rectangle.height()); glScissor(rectangle.left(), rectangle.bottom(), rectangle.sizeX(), rectangle.sizeY());
} }
void Renderer::setStencilFunction(const PolygonFacing facing, const StencilFunction function, const Int referenceValue, const UnsignedInt mask) { void Renderer::setStencilFunction(const PolygonFacing facing, const StencilFunction function, const Int referenceValue, const UnsignedInt mask) {

2
src/Renderer.h

@ -414,7 +414,7 @@ class MAGNUM_EXPORT Renderer {
* *
* @see @ref Feature::ScissorTest, @fn_gl{Scissor} * @see @ref Feature::ScissorTest, @fn_gl{Scissor}
*/ */
static void setScissor(const Rectanglei& rectangle); static void setScissor(const Range2Di& rectangle);
/*@}*/ /*@}*/

4
src/Text/AbstractFont.cpp

@ -166,11 +166,11 @@ AbstractLayouter::AbstractLayouter(UnsignedInt glyphCount): _glyphCount(glyphCou
AbstractLayouter::~AbstractLayouter() {} AbstractLayouter::~AbstractLayouter() {}
std::pair<Rectangle, Rectangle> AbstractLayouter::renderGlyph(const UnsignedInt i, Vector2& cursorPosition, Rectangle& rectangle) { std::pair<Range2D, Range2D> AbstractLayouter::renderGlyph(const UnsignedInt i, Vector2& cursorPosition, Range2D& rectangle) {
CORRADE_ASSERT(i < glyphCount(), "Text::AbstractLayouter::renderGlyph(): glyph index out of bounds", {}); CORRADE_ASSERT(i < glyphCount(), "Text::AbstractLayouter::renderGlyph(): glyph index out of bounds", {});
/* Render the glyph */ /* Render the glyph */
Rectangle quadPosition, textureCoordinates; Range2D quadPosition, textureCoordinates;
Vector2 advance; Vector2 advance;
std::tie(quadPosition, textureCoordinates, advance) = doRenderGlyph(i); std::tie(quadPosition, textureCoordinates, advance) = doRenderGlyph(i);

4
src/Text/AbstractFont.h

@ -314,7 +314,7 @@ class MAGNUM_TEXT_EXPORT AbstractLayouter {
* advances @p cursorPosition to next character and updates @p rectangle * advances @p cursorPosition to next character and updates @p rectangle
* with extended bounds. * with extended bounds.
*/ */
std::pair<Rectangle, Rectangle> renderGlyph(UnsignedInt i, Vector2& cursorPosition, Rectangle& rectangle); std::pair<Range2D, Range2D> renderGlyph(UnsignedInt i, Vector2& cursorPosition, Range2D& rectangle);
protected: protected:
/** /**
@ -335,7 +335,7 @@ class MAGNUM_TEXT_EXPORT AbstractLayouter {
* Return quad position (relative to current cursor position), texture * Return quad position (relative to current cursor position), texture
* coordinates and advance to next glyph. * coordinates and advance to next glyph.
*/ */
virtual std::tuple<Rectangle, Rectangle, Vector2> doRenderGlyph(UnsignedInt i) = 0; virtual std::tuple<Range2D, Range2D, Vector2> doRenderGlyph(UnsignedInt i) = 0;
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
private: private:

2
src/Text/DistanceFieldGlyphCache.cpp

@ -80,7 +80,7 @@ void DistanceFieldGlyphCache::setImage(const Vector2i& offset, const ImageRefere
.setImage(0, internalFormat, image); .setImage(0, internalFormat, image);
/* Create distance field from input texture */ /* Create distance field from input texture */
TextureTools::distanceField(input, texture(), Rectanglei::fromSize(offset*scale, image.size()*scale), radius, image.size()); TextureTools::distanceField(input, texture(), Range2Di::fromSize(offset*scale, image.size()*scale), radius, image.size());
} }
void DistanceFieldGlyphCache::setDistanceFieldImage(const Vector2i& offset, const ImageReference2D& image) { void DistanceFieldGlyphCache::setDistanceFieldImage(const Vector2i& offset, const ImageReference2D& image) {

8
src/Text/GlyphCache.cpp

@ -78,14 +78,14 @@ void GlyphCache::initialize(const TextureFormat internalFormat, const Vector2i&
glyphs.insert({0, {}}); glyphs.insert({0, {}});
} }
std::vector<Rectanglei> GlyphCache::reserve(const std::vector<Vector2i>& sizes) { std::vector<Range2Di> GlyphCache::reserve(const std::vector<Vector2i>& sizes) {
CORRADE_ASSERT((glyphs.size() == 1 && glyphs.at(0) == std::pair<Vector2i, Rectanglei>()), CORRADE_ASSERT((glyphs.size() == 1 && glyphs.at(0) == std::pair<Vector2i, Range2Di>()),
"Text::GlyphCache::reserve(): reserving space in non-empty cache is not yet implemented", std::vector<Rectanglei>{}); "Text::GlyphCache::reserve(): reserving space in non-empty cache is not yet implemented", std::vector<Range2Di>{});
glyphs.reserve(glyphs.size() + sizes.size()); glyphs.reserve(glyphs.size() + sizes.size());
return TextureTools::atlas(_size, sizes, _padding); return TextureTools::atlas(_size, sizes, _padding);
} }
void GlyphCache::insert(const UnsignedInt glyph, Vector2i position, Rectanglei rectangle) { void GlyphCache::insert(const UnsignedInt glyph, Vector2i position, Range2Di rectangle) {
position -= _padding; position -= _padding;
rectangle.bottomLeft() -= _padding; rectangle.bottomLeft() -= _padding;
rectangle.topRight() += _padding; rectangle.topRight() += _padding;

14
src/Text/GlyphCache.h

@ -31,7 +31,7 @@
#include <vector> #include <vector>
#include <unordered_map> #include <unordered_map>
#include "Math/Geometry/Rectangle.h" #include "Math/Range.h"
#include "Texture.h" #include "Texture.h"
#include "Text/magnumTextVisibility.h" #include "Text/magnumTextVisibility.h"
@ -130,18 +130,18 @@ class MAGNUM_TEXT_EXPORT GlyphCache {
* to some meaningful value in @ref insert(). * to some meaningful value in @ref insert().
* @see @ref padding() * @see @ref padding()
*/ */
std::pair<Vector2i, Rectanglei> operator[](UnsignedInt glyph) const { std::pair<Vector2i, Range2Di> operator[](UnsignedInt glyph) const {
auto it = glyphs.find(glyph); auto it = glyphs.find(glyph);
return it == glyphs.end() ? glyphs.at(0) : it->second; return it == glyphs.end() ? glyphs.at(0) : it->second;
} }
/** @brief Iterator access to cache data */ /** @brief Iterator access to cache data */
std::unordered_map<UnsignedInt, std::pair<Vector2i, Rectanglei>>::const_iterator begin() const { std::unordered_map<UnsignedInt, std::pair<Vector2i, Range2Di>>::const_iterator begin() const {
return glyphs.begin(); return glyphs.begin();
} }
/** @brief Iterator access to cache data */ /** @brief Iterator access to cache data */
std::unordered_map<UnsignedInt, std::pair<Vector2i, Rectanglei>>::const_iterator end() const { std::unordered_map<UnsignedInt, std::pair<Vector2i, Range2Di>>::const_iterator end() const {
return glyphs.end(); return glyphs.end();
} }
@ -159,7 +159,7 @@ class MAGNUM_TEXT_EXPORT GlyphCache {
* glyphs. * glyphs.
* @see @ref padding() * @see @ref padding()
*/ */
std::vector<Rectanglei> reserve(const std::vector<Vector2i>& sizes); std::vector<Range2Di> reserve(const std::vector<Vector2i>& sizes);
/** /**
* @brief Insert glyph to cache * @brief Insert glyph to cache
@ -176,7 +176,7 @@ class MAGNUM_TEXT_EXPORT GlyphCache {
* See also @ref setImage() to upload glyph image. * See also @ref setImage() to upload glyph image.
* @see @ref padding() * @see @ref padding()
*/ */
void insert(UnsignedInt glyph, Vector2i position, Rectanglei rectangle); void insert(UnsignedInt glyph, Vector2i position, Range2Di rectangle);
/** /**
* @brief Set cache image * @brief Set cache image
@ -193,7 +193,7 @@ class MAGNUM_TEXT_EXPORT GlyphCache {
Vector2i _size, _padding; Vector2i _size, _padding;
Texture2D _texture; Texture2D _texture;
std::unordered_map<UnsignedInt, std::pair<Vector2i, Rectanglei>> glyphs; std::unordered_map<UnsignedInt, std::pair<Vector2i, Range2Di>> glyphs;
}; };
}} }}

22
src/Text/Renderer.cpp

@ -58,7 +58,7 @@ struct Vertex {
Vector2 position, textureCoordinates; Vector2 position, textureCoordinates;
}; };
std::tuple<std::vector<Vertex>, Rectangle> renderVerticesInternal(AbstractFont& font, const GlyphCache& cache, Float size, const std::string& text, const Alignment alignment) { std::tuple<std::vector<Vertex>, Range2D> renderVerticesInternal(AbstractFont& font, const GlyphCache& cache, Float size, const std::string& text, const Alignment alignment) {
/* Output data, reserve memory as when the text would be ASCII-only. In /* Output data, reserve memory as when the text would be ASCII-only. In
reality the actual vertex count will be smaller, but allocating more at reality the actual vertex count will be smaller, but allocating more at
once is better than reallocating many times later. */ once is better than reallocating many times later. */
@ -66,7 +66,7 @@ std::tuple<std::vector<Vertex>, Rectangle> renderVerticesInternal(AbstractFont&
vertices.reserve(text.size()*4); vertices.reserve(text.size()*4);
/* Total rendered bounds, intial line position, last+1 vertex on previous line */ /* Total rendered bounds, intial line position, last+1 vertex on previous line */
Rectangle rectangle; Range2D rectangle;
Vector2 linePosition; Vector2 linePosition;
std::size_t lastLineLastVertex = 0; std::size_t lastLineLastVertex = 0;
@ -98,12 +98,12 @@ std::tuple<std::vector<Vertex>, Rectangle> renderVerticesInternal(AbstractFont&
CORRADE_INTERNAL_ASSERT(vertices.size()+vertexCount <= vertices.capacity()); CORRADE_INTERNAL_ASSERT(vertices.size()+vertexCount <= vertices.capacity());
/* Bounds of rendered line */ /* Bounds of rendered line */
Rectangle lineRectangle; Range2D lineRectangle;
/* Render all glyphs */ /* Render all glyphs */
Vector2 cursorPosition(linePosition); Vector2 cursorPosition(linePosition);
for(UnsignedInt i = 0; i != layouter->glyphCount(); ++i) { for(UnsignedInt i = 0; i != layouter->glyphCount(); ++i) {
Rectangle quadPosition, textureCoordinates; Range2D quadPosition, textureCoordinates;
std::tie(quadPosition, textureCoordinates) = layouter->renderGlyph(i, cursorPosition, lineRectangle); std::tie(quadPosition, textureCoordinates) = layouter->renderGlyph(i, cursorPosition, lineRectangle);
/* 0---2 /* 0---2
@ -125,7 +125,7 @@ std::tuple<std::vector<Vertex>, Rectangle> renderVerticesInternal(AbstractFont&
/* Horizontally align the rendered line */ /* Horizontally align the rendered line */
Float alignmentOffsetX = 0.0f; Float alignmentOffsetX = 0.0f;
if((UnsignedByte(alignment) & Implementation::AlignmentHorizontal) == Implementation::AlignmentCenter) if((UnsignedByte(alignment) & Implementation::AlignmentHorizontal) == Implementation::AlignmentCenter)
alignmentOffsetX = -lineRectangle.left()-lineRectangle.width()*0.5f; alignmentOffsetX = -lineRectangle.centerX();
else if((UnsignedByte(alignment) & Implementation::AlignmentHorizontal) == Implementation::AlignmentRight) else if((UnsignedByte(alignment) & Implementation::AlignmentHorizontal) == Implementation::AlignmentRight)
alignmentOffsetX = -lineRectangle.right(); alignmentOffsetX = -lineRectangle.right();
@ -153,7 +153,7 @@ std::tuple<std::vector<Vertex>, Rectangle> renderVerticesInternal(AbstractFont&
/* Vertically align the rendered text */ /* Vertically align the rendered text */
Float alignmentOffsetY = 0.0f; Float alignmentOffsetY = 0.0f;
if((UnsignedByte(alignment) & Implementation::AlignmentVertical) == Implementation::AlignmentMiddle) if((UnsignedByte(alignment) & Implementation::AlignmentVertical) == Implementation::AlignmentMiddle)
alignmentOffsetY = -rectangle.bottom()-rectangle.height()*0.5f; alignmentOffsetY = -rectangle.centerY();
else if((UnsignedByte(alignment) & Implementation::AlignmentVertical) == Implementation::AlignmentTop) else if((UnsignedByte(alignment) & Implementation::AlignmentVertical) == Implementation::AlignmentTop)
alignmentOffsetY = -rectangle.top(); alignmentOffsetY = -rectangle.top();
@ -191,10 +191,10 @@ std::pair<Containers::Array<unsigned char>, Mesh::IndexType> renderIndicesIntern
return {std::move(indices), indexType}; return {std::move(indices), indexType};
} }
std::tuple<Mesh, Rectangle> renderInternal(AbstractFont& font, const GlyphCache& cache, Float size, const std::string& text, Buffer& vertexBuffer, Buffer& indexBuffer, BufferUsage usage, Alignment alignment) { std::tuple<Mesh, Range2D> renderInternal(AbstractFont& font, const GlyphCache& cache, Float size, const std::string& text, Buffer& vertexBuffer, Buffer& indexBuffer, BufferUsage usage, Alignment alignment) {
/* Render vertices and upload them */ /* Render vertices and upload them */
std::vector<Vertex> vertices; std::vector<Vertex> vertices;
Rectangle rectangle; Range2D rectangle;
std::tie(vertices, rectangle) = renderVerticesInternal(font, cache, size, text, alignment); std::tie(vertices, rectangle) = renderVerticesInternal(font, cache, size, text, alignment);
vertexBuffer.setData(vertices, usage); vertexBuffer.setData(vertices, usage);
@ -220,10 +220,10 @@ std::tuple<Mesh, Rectangle> renderInternal(AbstractFont& font, const GlyphCache&
} }
std::tuple<std::vector<Vector2>, std::vector<Vector2>, std::vector<UnsignedInt>, Rectangle> AbstractRenderer::render(AbstractFont& font, const GlyphCache& cache, Float size, const std::string& text, Alignment alignment) { std::tuple<std::vector<Vector2>, std::vector<Vector2>, std::vector<UnsignedInt>, Range2D> AbstractRenderer::render(AbstractFont& font, const GlyphCache& cache, Float size, const std::string& text, Alignment alignment) {
/* Render vertices */ /* Render vertices */
std::vector<Vertex> vertices; std::vector<Vertex> vertices;
Rectangle rectangle; Range2D rectangle;
std::tie(vertices, rectangle) = renderVerticesInternal(font, cache, size, text, alignment); std::tie(vertices, rectangle) = renderVerticesInternal(font, cache, size, text, alignment);
/* Deinterleave the vertices */ /* Deinterleave the vertices */
@ -243,7 +243,7 @@ std::tuple<std::vector<Vector2>, std::vector<Vector2>, std::vector<UnsignedInt>,
return std::make_tuple(std::move(positions), std::move(textureCoordinates), std::move(indices), rectangle); return std::make_tuple(std::move(positions), std::move(textureCoordinates), std::move(indices), rectangle);
} }
template<UnsignedInt dimensions> std::tuple<Mesh, Rectangle> Renderer<dimensions>::render(AbstractFont& font, const GlyphCache& cache, Float size, const std::string& text, Buffer& vertexBuffer, Buffer& indexBuffer, BufferUsage usage, Alignment alignment) { template<UnsignedInt dimensions> std::tuple<Mesh, Range2D> Renderer<dimensions>::render(AbstractFont& font, const GlyphCache& cache, Float size, const std::string& text, Buffer& vertexBuffer, Buffer& indexBuffer, BufferUsage usage, Alignment alignment) {
/* Finalize mesh configuration and return the result */ /* Finalize mesh configuration and return the result */
auto r = renderInternal(font, cache, size, text, vertexBuffer, indexBuffer, usage, alignment); auto r = renderInternal(font, cache, size, text, vertexBuffer, indexBuffer, usage, alignment);
Mesh& mesh = std::get<0>(r); Mesh& mesh = std::get<0>(r);

12
src/Text/Renderer.h

@ -32,7 +32,7 @@
#include <tuple> #include <tuple>
#include <vector> #include <vector>
#include "Math/Geometry/Rectangle.h" #include "Math/Range.h"
#include "Buffer.h" #include "Buffer.h"
#include "DimensionTraits.h" #include "DimensionTraits.h"
#include "Mesh.h" #include "Mesh.h"
@ -62,7 +62,7 @@ class MAGNUM_TEXT_EXPORT AbstractRenderer {
* Returns tuple with vertex positions, texture coordinates, indices * Returns tuple with vertex positions, texture coordinates, indices
* and rectangle spanning the rendered text. * and rectangle spanning the rendered text.
*/ */
static std::tuple<std::vector<Vector2>, std::vector<Vector2>, std::vector<UnsignedInt>, Rectangle> render(AbstractFont& font, const GlyphCache& cache, Float size, const std::string& text, Alignment alignment = Alignment::LineLeft); static std::tuple<std::vector<Vector2>, std::vector<Vector2>, std::vector<UnsignedInt>, Range2D> render(AbstractFont& font, const GlyphCache& cache, Float size, const std::string& text, Alignment alignment = Alignment::LineLeft);
/** /**
* @brief Capacity for rendered glyphs * @brief Capacity for rendered glyphs
@ -72,7 +72,7 @@ class MAGNUM_TEXT_EXPORT AbstractRenderer {
UnsignedInt capacity() const { return _capacity; } UnsignedInt capacity() const { return _capacity; }
/** @brief Rectangle spanning the rendered text */ /** @brief Rectangle spanning the rendered text */
Rectangle rectangle() const { return _rectangle; } Range2D rectangle() const { return _rectangle; }
/** @brief Vertex buffer */ /** @brief Vertex buffer */
Buffer& vertexBuffer() { return _vertexBuffer; } Buffer& vertexBuffer() { return _vertexBuffer; }
@ -131,7 +131,7 @@ class MAGNUM_TEXT_EXPORT AbstractRenderer {
Float size; Float size;
Alignment _alignment; Alignment _alignment;
UnsignedInt _capacity; UnsignedInt _capacity;
Rectangle _rectangle; Range2D _rectangle;
#if defined(MAGNUM_TARGET_GLES2) && !defined(CORRADE_TARGET_EMSCRIPTEN) #if defined(MAGNUM_TARGET_GLES2) && !defined(CORRADE_TARGET_EMSCRIPTEN)
typedef void*(*BufferMapImplementation)(Buffer&, GLsizeiptr); typedef void*(*BufferMapImplementation)(Buffer&, GLsizeiptr);
@ -184,7 +184,7 @@ Buffer vertexBuffer, indexBuffer;
Mesh mesh; Mesh mesh;
// Render the text // Render the text
Rectangle rectangle; Range2D rectangle;
std::tie(mesh, rectangle) = Text::Renderer2D::render(*font, cache, 0.15f, std::tie(mesh, rectangle) = Text::Renderer2D::render(*font, cache, 0.15f,
"Hello World!", vertexBuffer, indexBuffer, Buffer::Usage::StaticDraw); "Hello World!", vertexBuffer, indexBuffer, Buffer::Usage::StaticDraw);
@ -250,7 +250,7 @@ template<UnsignedInt dimensions> class MAGNUM_TEXT_EXPORT Renderer: public Abstr
* Returns mesh prepared for use with @ref Shaders::AbstractVector * Returns mesh prepared for use with @ref Shaders::AbstractVector
* subclasses and rectangle spanning the rendered text. * subclasses and rectangle spanning the rendered text.
*/ */
static std::tuple<Mesh, Rectangle> render(AbstractFont& font, const GlyphCache& cache, Float size, const std::string& text, Buffer& vertexBuffer, Buffer& indexBuffer, BufferUsage usage, Alignment alignment = Alignment::LineLeft); static std::tuple<Mesh, Range2D> render(AbstractFont& font, const GlyphCache& cache, Float size, const std::string& text, Buffer& vertexBuffer, Buffer& indexBuffer, BufferUsage usage, Alignment alignment = Alignment::LineLeft);
/** /**
* @brief Constructor * @brief Constructor

32
src/Text/Test/AbstractLayouterTest.cpp

@ -24,7 +24,7 @@
#include <TestSuite/Tester.h> #include <TestSuite/Tester.h>
#include "Math/Geometry/Rectangle.h" #include "Math/Range.h"
#include "Text/AbstractFont.h" #include "Text/AbstractFont.h"
namespace Magnum { namespace Text { namespace Test { namespace Magnum { namespace Text { namespace Test {
@ -46,38 +46,38 @@ void AbstractLayouterTest::renderGlyph() {
explicit Layouter(): AbstractLayouter(3) {} explicit Layouter(): AbstractLayouter(3) {}
private: private:
std::tuple<Rectangle, Rectangle, Vector2> doRenderGlyph(UnsignedInt) override { std::tuple<Range2D, Range2D, Vector2> doRenderGlyph(UnsignedInt) override {
return std::make_tuple(Rectangle({1.0f, 0.5f}, {1.1f, 1.0f}), return std::make_tuple(Range2D({1.0f, 0.5f}, {1.1f, 1.0f}),
Rectangle({0.3f, 1.1f}, {-0.5f, 0.7f}), Range2D({0.3f, 1.1f}, {-0.5f, 0.7f}),
Vector2(2.0f, -1.0f)); Vector2(2.0f, -1.0f));
} }
}; };
/* Rectangle of zero size shouldn't be merged, but replaced */ /* Rectangle of zero size shouldn't be merged, but replaced */
Rectangle rectangle({-1.0f, -1.0f}, {-1.0f, -1.0f}); Range2D rectangle({-1.0f, -1.0f}, {-1.0f, -1.0f});
Vector2 cursorPosition(1.0f, 2.0f); Vector2 cursorPosition(1.0f, 2.0f);
Layouter l; Layouter l;
Rectangle quadPosition; Range2D quadPosition;
Rectangle textureCoords; Range2D textureCoords;
std::tie(quadPosition, textureCoords) = l.renderGlyph(0, cursorPosition, rectangle); std::tie(quadPosition, textureCoords) = l.renderGlyph(0, cursorPosition, rectangle);
CORRADE_COMPARE(quadPosition, Rectangle({2.0f, 2.5f}, {2.1f, 3.0f})); CORRADE_COMPARE(quadPosition, Range2D({2.0f, 2.5f}, {2.1f, 3.0f}));
CORRADE_COMPARE(textureCoords, Rectangle({0.3f, 1.1f}, {-0.5f, 0.7f})); CORRADE_COMPARE(textureCoords, Range2D({0.3f, 1.1f}, {-0.5f, 0.7f}));
CORRADE_COMPARE(cursorPosition, Vector2(3.0f, 1.0f)); CORRADE_COMPARE(cursorPosition, Vector2(3.0f, 1.0f));
CORRADE_COMPARE(rectangle, Rectangle({2.0f, 2.5f}, {2.1f, 3.0f})); CORRADE_COMPARE(rectangle, Range2D({2.0f, 2.5f}, {2.1f, 3.0f}));
std::tie(quadPosition, textureCoords) = l.renderGlyph(1, cursorPosition, rectangle); std::tie(quadPosition, textureCoords) = l.renderGlyph(1, cursorPosition, rectangle);
CORRADE_COMPARE(quadPosition, Rectangle({4.0f, 1.5f}, {4.1f, 2.0f})); CORRADE_COMPARE(quadPosition, Range2D({4.0f, 1.5f}, {4.1f, 2.0f}));
CORRADE_COMPARE(textureCoords, Rectangle({0.3f, 1.1f}, {-0.5f, 0.7f})); CORRADE_COMPARE(textureCoords, Range2D({0.3f, 1.1f}, {-0.5f, 0.7f}));
CORRADE_COMPARE(cursorPosition, Vector2(5.0f, 0.0f)); CORRADE_COMPARE(cursorPosition, Vector2(5.0f, 0.0f));
CORRADE_COMPARE(rectangle, Rectangle({2.0f, 1.5f}, {4.1f, 3.0f})); CORRADE_COMPARE(rectangle, Range2D({2.0f, 1.5f}, {4.1f, 3.0f}));
std::tie(quadPosition, textureCoords) = l.renderGlyph(2, cursorPosition, rectangle); std::tie(quadPosition, textureCoords) = l.renderGlyph(2, cursorPosition, rectangle);
CORRADE_COMPARE(quadPosition, Rectangle({6.0f, 0.5f}, {6.1f, 1.0f})); CORRADE_COMPARE(quadPosition, Range2D({6.0f, 0.5f}, {6.1f, 1.0f}));
CORRADE_COMPARE(textureCoords, Rectangle({0.3f, 1.1f}, {-0.5f, 0.7f})); CORRADE_COMPARE(textureCoords, Range2D({0.3f, 1.1f}, {-0.5f, 0.7f}));
CORRADE_COMPARE(cursorPosition, Vector2(7.0f, -1.0f)); CORRADE_COMPARE(cursorPosition, Vector2(7.0f, -1.0f));
CORRADE_COMPARE(rectangle, Rectangle({2.0f, 0.5f}, {6.1f, 3.0f})); CORRADE_COMPARE(rectangle, Range2D({2.0f, 0.5f}, {6.1f, 3.0f}));
} }
}}} }}}

10
src/Text/Test/GlyphCacheGLTest.cpp

@ -54,32 +54,32 @@ void GlyphCacheGLTest::initialize() {
void GlyphCacheGLTest::access() { void GlyphCacheGLTest::access() {
Text::GlyphCache cache(Vector2i(236)); Text::GlyphCache cache(Vector2i(236));
Vector2i position; Vector2i position;
Rectanglei rectangle; Range2Di rectangle;
/* Default "Not Found" glyph */ /* Default "Not Found" glyph */
CORRADE_COMPARE(cache.glyphCount(), 1); CORRADE_COMPARE(cache.glyphCount(), 1);
std::tie(position, rectangle) = cache[0]; std::tie(position, rectangle) = cache[0];
CORRADE_COMPARE(position, Vector2i(0, 0)); CORRADE_COMPARE(position, Vector2i(0, 0));
CORRADE_COMPARE(rectangle, Rectanglei({0, 0}, {0, 0})); CORRADE_COMPARE(rectangle, Range2Di({0, 0}, {0, 0}));
/* Overwrite "Not Found" glyph */ /* Overwrite "Not Found" glyph */
cache.insert(0, {3, 5}, {{10, 10}, {23, 45}}); cache.insert(0, {3, 5}, {{10, 10}, {23, 45}});
CORRADE_COMPARE(cache.glyphCount(), 1); CORRADE_COMPARE(cache.glyphCount(), 1);
std::tie(position, rectangle) = cache[0]; std::tie(position, rectangle) = cache[0];
CORRADE_COMPARE(position, Vector2i(3, 5)); CORRADE_COMPARE(position, Vector2i(3, 5));
CORRADE_COMPARE(rectangle, Rectanglei({10, 10}, {23, 45})); CORRADE_COMPARE(rectangle, Range2Di({10, 10}, {23, 45}));
/* Querying available glyph */ /* Querying available glyph */
cache.insert(25, {3, 4}, {{15, 30}, {45, 35}}); cache.insert(25, {3, 4}, {{15, 30}, {45, 35}});
CORRADE_COMPARE(cache.glyphCount(), 2); CORRADE_COMPARE(cache.glyphCount(), 2);
std::tie(position, rectangle) = cache[25]; std::tie(position, rectangle) = cache[25];
CORRADE_COMPARE(position, Vector2i(3, 4)); CORRADE_COMPARE(position, Vector2i(3, 4));
CORRADE_COMPARE(rectangle, Rectanglei({15, 30}, {45, 35})); CORRADE_COMPARE(rectangle, Range2Di({15, 30}, {45, 35}));
/* Querying not available glyph falls back to "Not Found" */ /* Querying not available glyph falls back to "Not Found" */
std::tie(position, rectangle) = cache[42]; std::tie(position, rectangle) = cache[42];
CORRADE_COMPARE(position, Vector2i(3, 5)); CORRADE_COMPARE(position, Vector2i(3, 5));
CORRADE_COMPARE(rectangle, Rectanglei({10, 10}, {23, 45})); CORRADE_COMPARE(rectangle, Range2Di({10, 10}, {23, 45}));
} }
void GlyphCacheGLTest::reserve() { void GlyphCacheGLTest::reserve() {

26
src/Text/Test/RendererGLTest.cpp

@ -54,10 +54,10 @@ class TestLayouter: public Text::AbstractLayouter {
explicit TestLayouter(Float size, std::size_t glyphCount): AbstractLayouter(glyphCount), _size(size) {} explicit TestLayouter(Float size, std::size_t glyphCount): AbstractLayouter(glyphCount), _size(size) {}
private: private:
std::tuple<Rectangle, Rectangle, Vector2> doRenderGlyph(UnsignedInt i) override { std::tuple<Range2D, Range2D, Vector2> doRenderGlyph(UnsignedInt i) override {
return std::make_tuple( return std::make_tuple(
Rectangle({}, Vector2(3.0f, 2.0f)*((i+1)*_size)), Range2D({}, Vector2(3.0f, 2.0f)*((i+1)*_size)),
Rectangle::fromSize({i*6.0f, 0.0f}, {6.0f, 10.0f}), Range2D::fromSize({i*6.0f, 0.0f}, {6.0f, 10.0f}),
(Vector2::xAxis((i+1)*3.0f)+Vector2(1.0f, -1.0f))*_size (Vector2::xAxis((i+1)*3.0f)+Vector2(1.0f, -1.0f))*_size
); );
} }
@ -86,7 +86,7 @@ void RendererGLTest::renderData() {
std::vector<Vector2> positions; std::vector<Vector2> positions;
std::vector<Vector2> textureCoordinates; std::vector<Vector2> textureCoordinates;
std::vector<UnsignedInt> indices; std::vector<UnsignedInt> indices;
Rectangle bounds; Range2D bounds;
std::tie(positions, textureCoordinates, indices, bounds) = Text::AbstractRenderer::render(font, *static_cast<GlyphCache*>(nullptr), 0.25f, "abc", Alignment::MiddleRightIntegral); std::tie(positions, textureCoordinates, indices, bounds) = Text::AbstractRenderer::render(font, *static_cast<GlyphCache*>(nullptr), 0.25f, "abc", Alignment::MiddleRightIntegral);
/* Three glyphs, three quads -> 12 vertices, 18 indices */ /* Three glyphs, three quads -> 12 vertices, 18 indices */
@ -98,7 +98,7 @@ void RendererGLTest::renderData() {
const Vector2 offset{-5.0f, 0.0f}; const Vector2 offset{-5.0f, 0.0f};
/* Bounds */ /* Bounds */
CORRADE_COMPARE(bounds, Rectangle({0.0f, -0.5f}, {5.0f, 1.0f}).translated(offset)); CORRADE_COMPARE(bounds, Range2D({0.0f, -0.5f}, {5.0f, 1.0f}).translated(offset));
/* Vertex positions and texture coordinates /* Vertex positions and texture coordinates
0---2 0---2
@ -168,7 +168,7 @@ void RendererGLTest::renderMesh() {
TestFont font; TestFont font;
Mesh mesh; Mesh mesh;
Buffer vertexBuffer, indexBuffer; Buffer vertexBuffer, indexBuffer;
Rectangle bounds; Range2D bounds;
std::tie(mesh, bounds) = Text::Renderer3D::render(font, *static_cast<GlyphCache*>(nullptr), 0.25f, "abc", vertexBuffer, indexBuffer, BufferUsage::StaticDraw, Alignment::TopCenter); std::tie(mesh, bounds) = Text::Renderer3D::render(font, *static_cast<GlyphCache*>(nullptr), 0.25f, "abc", vertexBuffer, indexBuffer, BufferUsage::StaticDraw, Alignment::TopCenter);
MAGNUM_VERIFY_NO_ERROR(); MAGNUM_VERIFY_NO_ERROR();
@ -176,7 +176,7 @@ void RendererGLTest::renderMesh() {
const Vector2 offset{-2.5f, -1.0f}; const Vector2 offset{-2.5f, -1.0f};
/* Bounds */ /* Bounds */
CORRADE_COMPARE(bounds, Rectangle({0.0f, -0.5f}, {5.0f, 1.0f}).translated(offset)); CORRADE_COMPARE(bounds, Range2D({0.0f, -0.5f}, {5.0f, 1.0f}).translated(offset));
/** @todo How to verify this on ES? */ /** @todo How to verify this on ES? */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
@ -213,7 +213,7 @@ void RendererGLTest::mutableText() {
Text::Renderer2D renderer(font, *static_cast<GlyphCache*>(nullptr), 0.25f); Text::Renderer2D renderer(font, *static_cast<GlyphCache*>(nullptr), 0.25f);
MAGNUM_VERIFY_NO_ERROR(); MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(renderer.capacity(), 0); CORRADE_COMPARE(renderer.capacity(), 0);
CORRADE_COMPARE(renderer.rectangle(), Rectangle()); CORRADE_COMPARE(renderer.rectangle(), Range2D());
/* Reserve some capacity */ /* Reserve some capacity */
renderer.reserve(4, BufferUsage::StaticDraw, BufferUsage::StaticDraw); renderer.reserve(4, BufferUsage::StaticDraw, BufferUsage::StaticDraw);
@ -235,7 +235,7 @@ void RendererGLTest::mutableText() {
MAGNUM_VERIFY_NO_ERROR(); MAGNUM_VERIFY_NO_ERROR();
/* Updated bounds */ /* Updated bounds */
CORRADE_COMPARE(renderer.rectangle(), Rectangle({0.0f, -0.5f}, {5.0f, 1.0f})); CORRADE_COMPARE(renderer.rectangle(), Range2D({0.0f, -0.5f}, {5.0f, 1.0f}));
/* Aligned to line/left, no offset needed */ /* Aligned to line/left, no offset needed */
@ -267,8 +267,8 @@ void RendererGLTest::multiline() {
explicit Layouter(UnsignedInt glyphs): AbstractLayouter(glyphs) {} explicit Layouter(UnsignedInt glyphs): AbstractLayouter(glyphs) {}
private: private:
std::tuple<Rectangle, Rectangle, Vector2> doRenderGlyph(UnsignedInt) override { std::tuple<Range2D, Range2D, Vector2> doRenderGlyph(UnsignedInt) override {
return std::make_tuple(Rectangle({}, Vector2(1.0f)), Rectangle({}, Vector2(1.0f)), Vector2::xAxis(2.0f)); return std::make_tuple(Range2D({}, Vector2(1.0f)), Range2D({}, Vector2(1.0f)), Vector2::xAxis(2.0f));
} }
}; };
@ -299,14 +299,14 @@ void RendererGLTest::multiline() {
Font font; Font font;
font.openFile({}, 0.0f); font.openFile({}, 0.0f);
Rectangle rectangle; Range2D rectangle;
std::vector<UnsignedInt> indices; std::vector<UnsignedInt> indices;
std::vector<Vector2> positions, textureCoordinates; std::vector<Vector2> positions, textureCoordinates;
std::tie(positions, textureCoordinates, indices, rectangle) = Text::Renderer2D::render(font, std::tie(positions, textureCoordinates, indices, rectangle) = Text::Renderer2D::render(font,
*static_cast<GlyphCache*>(nullptr), 0.0f, "abcd\nef\n\nghi", Alignment::MiddleCenter); *static_cast<GlyphCache*>(nullptr), 0.0f, "abcd\nef\n\nghi", Alignment::MiddleCenter);
/* Bounds */ /* Bounds */
CORRADE_COMPARE(rectangle, Rectangle({-3.5f, -5.0f}, {3.5f, 5.0f})); CORRADE_COMPARE(rectangle, Range2D({-3.5f, -5.0f}, {3.5f, 5.0f}));
/* Vertices /* Vertices
[a] [b] [c] [d] [a] [b] [c] [d]

10
src/TextureTools/Atlas.cpp

@ -25,19 +25,19 @@
#include "Atlas.h" #include "Atlas.h"
#include "Math/Functions.h" #include "Math/Functions.h"
#include "Math/Geometry/Rectangle.h" #include "Math/Range.h"
namespace Magnum { namespace TextureTools { namespace Magnum { namespace TextureTools {
std::vector<Rectanglei> atlas(const Vector2i& atlasSize, const std::vector<Vector2i>& sizes, const Vector2i& padding) { std::vector<Range2Di> atlas(const Vector2i& atlasSize, const std::vector<Vector2i>& sizes, const Vector2i& padding) {
if(sizes.empty()) return std::vector<Rectanglei>{}; if(sizes.empty()) return std::vector<Range2Di>{};
/* Size of largest texture */ /* Size of largest texture */
Vector2i maxSize; Vector2i maxSize;
for(const Vector2i& size: sizes) for(const Vector2i& size: sizes)
maxSize = Math::max(maxSize, size); maxSize = Math::max(maxSize, size);
std::vector<Rectanglei> atlas; std::vector<Range2Di> atlas;
/* Columns and rows */ /* Columns and rows */
const Vector2i paddedSize = maxSize+2*padding; const Vector2i paddedSize = maxSize+2*padding;
@ -53,7 +53,7 @@ std::vector<Rectanglei> atlas(const Vector2i& atlasSize, const std::vector<Vecto
atlas.reserve(sizes.size()); atlas.reserve(sizes.size());
for(std::size_t i = 0; i != sizes.size(); ++i) for(std::size_t i = 0; i != sizes.size(); ++i)
atlas.push_back(Rectanglei::fromSize(Vector2i(i%gridSize.x(), i/gridSize.x())*paddedSize+padding, sizes[i])); atlas.push_back(Range2Di::fromSize(Vector2i(i%gridSize.x(), i/gridSize.x())*paddedSize+padding, sizes[i]));
return atlas; return atlas;
} }

2
src/TextureTools/Atlas.h

@ -50,7 +50,7 @@ Padding is added twice to each size and the atlas is laid out so the padding
don't overlap. Returned sizes are the same as original sizes, i.e. without the don't overlap. Returned sizes are the same as original sizes, i.e. without the
padding. padding.
*/ */
std::vector<Rectanglei> MAGNUM_TEXTURETOOLS_EXPORT atlas(const Vector2i& atlasSize, const std::vector<Vector2i>& sizes, const Vector2i& padding = Vector2i()); std::vector<Range2Di> MAGNUM_TEXTURETOOLS_EXPORT atlas(const Vector2i& atlasSize, const std::vector<Vector2i>& sizes, const Vector2i& padding = Vector2i());
}} }}

6
src/TextureTools/DistanceField.cpp

@ -26,7 +26,7 @@
#include <Utility/Resource.h> #include <Utility/Resource.h>
#include "Math/Geometry/Rectangle.h" #include "Math/Range.h"
#include "AbstractShaderProgram.h" #include "AbstractShaderProgram.h"
#include "Buffer.h" #include "Buffer.h"
#include "Extensions.h" #include "Extensions.h"
@ -131,9 +131,9 @@ DistanceFieldShader::DistanceFieldShader(): radiusUniform(0), scalingUniform(1)
} }
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void distanceField(Texture2D& input, Texture2D& output, const Rectanglei& rectangle, const Int radius, const Vector2i&) void distanceField(Texture2D& input, Texture2D& output, const Range2Di& rectangle, const Int radius, const Vector2i&)
#else #else
void distanceField(Texture2D& input, Texture2D& output, const Rectanglei& rectangle, const Int radius, const Vector2i& imageSize) void distanceField(Texture2D& input, Texture2D& output, const Range2Di& rectangle, const Int radius, const Vector2i& imageSize)
#endif #endif
{ {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES

4
src/TextureTools/DistanceField.h

@ -85,9 +85,9 @@ http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnifica
(jaggies, visible e.g. when rendering outlined fonts) (jaggies, visible e.g. when rendering outlined fonts)
*/ */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void MAGNUM_TEXTURETOOLS_EXPORT distanceField(Texture2D& input, Texture2D& output, const Rectanglei& rectangle, Int radius, const Vector2i& imageSize = Vector2i()); void MAGNUM_TEXTURETOOLS_EXPORT distanceField(Texture2D& input, Texture2D& output, const Range2Di& rectangle, Int radius, const Vector2i& imageSize = Vector2i());
#else #else
void MAGNUM_TEXTURETOOLS_EXPORT distanceField(Texture2D& input, Texture2D& output, const Rectanglei& rectangle, Int radius, const Vector2i& imageSize); void MAGNUM_TEXTURETOOLS_EXPORT distanceField(Texture2D& input, Texture2D& output, const Range2Di& rectangle, Int radius, const Vector2i& imageSize);
#endif #endif
}} }}

26
src/TextureTools/Test/AtlasTest.cpp

@ -25,7 +25,7 @@
#include <sstream> #include <sstream>
#include <TestSuite/Tester.h> #include <TestSuite/Tester.h>
#include "Math/Geometry/Rectangle.h" #include "Math/Range.h"
#include "TextureTools/Atlas.h" #include "TextureTools/Atlas.h"
namespace Magnum { namespace TextureTools { namespace Test { namespace Magnum { namespace TextureTools { namespace Test {
@ -48,35 +48,35 @@ AtlasTest::AtlasTest() {
} }
void AtlasTest::create() { void AtlasTest::create() {
std::vector<Rectanglei> atlas = TextureTools::atlas({64, 64}, { std::vector<Range2Di> atlas = TextureTools::atlas({64, 64}, {
{12, 18}, {12, 18},
{32, 15}, {32, 15},
{23, 25} {23, 25}
}); });
CORRADE_COMPARE(atlas.size(), 3); CORRADE_COMPARE(atlas.size(), 3);
CORRADE_COMPARE(atlas, (std::vector<Rectanglei>{ CORRADE_COMPARE(atlas, (std::vector<Range2Di>{
Rectanglei::fromSize({0, 0}, {12, 18}), Range2Di::fromSize({0, 0}, {12, 18}),
Rectanglei::fromSize({32, 0}, {32, 15}), Range2Di::fromSize({32, 0}, {32, 15}),
Rectanglei::fromSize({0, 25}, {23, 25})})); Range2Di::fromSize({0, 25}, {23, 25})}));
} }
void AtlasTest::createPadding() { void AtlasTest::createPadding() {
std::vector<Rectanglei> atlas = TextureTools::atlas({64, 64}, { std::vector<Range2Di> atlas = TextureTools::atlas({64, 64}, {
{8, 16}, {8, 16},
{28, 13}, {28, 13},
{19, 23} {19, 23}
}, {2, 1}); }, {2, 1});
CORRADE_COMPARE(atlas.size(), 3); CORRADE_COMPARE(atlas.size(), 3);
CORRADE_COMPARE(atlas, (std::vector<Rectanglei>{ CORRADE_COMPARE(atlas, (std::vector<Range2Di>{
Rectanglei::fromSize({2, 1}, {8, 16}), Range2Di::fromSize({2, 1}, {8, 16}),
Rectanglei::fromSize({34, 1}, {28, 13}), Range2Di::fromSize({34, 1}, {28, 13}),
Rectanglei::fromSize({2, 26}, {19, 23})})); Range2Di::fromSize({2, 26}, {19, 23})}));
} }
void AtlasTest::createEmpty() { void AtlasTest::createEmpty() {
std::vector<Rectanglei> atlas = TextureTools::atlas({}, std::vector<Vector2i>{}); std::vector<Range2Di> atlas = TextureTools::atlas({}, std::vector<Vector2i>{});
CORRADE_VERIFY(atlas.empty()); CORRADE_VERIFY(atlas.empty());
} }
@ -84,7 +84,7 @@ void AtlasTest::createTooSmall() {
std::ostringstream o; std::ostringstream o;
Error::setOutput(&o); Error::setOutput(&o);
std::vector<Rectanglei> atlas = TextureTools::atlas({64, 32}, { std::vector<Range2Di> atlas = TextureTools::atlas({64, 32}, {
{8, 16}, {8, 16},
{21, 13}, {21, 13},
{19, 29} {19, 29}

2
src/TextureTools/distancefieldconverter.cpp

@ -25,7 +25,7 @@
#include <Utility/Arguments.h> #include <Utility/Arguments.h>
#include <PluginManager/Manager.h> #include <PluginManager/Manager.h>
#include "Math/Geometry/Rectangle.h" #include "Math/Range.h"
#include "ColorFormat.h" #include "ColorFormat.h"
#include "Image.h" #include "Image.h"
#include "Renderer.h" #include "Renderer.h"

Loading…
Cancel
Save