1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Rectangle: Add string conversion functions for floats and doubles

This commit is contained in:
reuk 2021-11-17 18:01:19 +00:00
parent ca4bdb6b3a
commit 44b34be183
No known key found for this signature in database
GPG key ID: FCB43929F012EE5C
3 changed files with 94 additions and 21 deletions

View file

@ -26,6 +26,34 @@
namespace juce
{
#ifndef DOXYGEN
namespace detail
{
template <typename> struct Tag {};
inline auto getNumericValue (StringRef s, Tag<int>) { return s.text.getIntValue32(); }
inline auto getNumericValue (StringRef s, Tag<double>) { return s.text.getDoubleValue(); }
inline auto getNumericValue (StringRef s, Tag<float>) { return static_cast<float> (s.text.getDoubleValue()); }
template <typename ValueType>
ValueType parseAfterSpace (StringRef s) noexcept
{
return static_cast<ValueType> (getNumericValue (s.text.findEndOfWhitespace(),
Tag<ValueType>{}));
}
inline int floorAsInt (int n) noexcept { return n; }
inline int floorAsInt (float n) noexcept { return n > (float) std::numeric_limits<int>::min() ? (int) std::floor (n) : std::numeric_limits<int>::min(); }
inline int floorAsInt (double n) noexcept { return n > (double) std::numeric_limits<int>::min() ? (int) std::floor (n) : std::numeric_limits<int>::min(); }
inline int ceilAsInt (int n) noexcept { return n; }
inline int ceilAsInt (float n) noexcept { return n < (float) std::numeric_limits<int>::max() ? (int) std::ceil (n) : std::numeric_limits<int>::max(); }
inline int ceilAsInt (double n) noexcept { return n < (double) std::numeric_limits<int>::max() ? (int) std::ceil (n) : std::numeric_limits<int>::max(); }
} // namespace detail
#endif
//==============================================================================
/**
Manages a rectangle and allows geometric operations to be performed on it.
@ -811,10 +839,10 @@ public:
*/
Rectangle<int> getSmallestIntegerContainer() const noexcept
{
return Rectangle<int>::leftTopRightBottom (floorAsInt (pos.x),
floorAsInt (pos.y),
ceilAsInt (pos.x + w),
ceilAsInt (pos.y + h));
return Rectangle<int>::leftTopRightBottom (detail::floorAsInt (pos.x),
detail::floorAsInt (pos.y),
detail::ceilAsInt (pos.x + w),
detail::ceilAsInt (pos.y + h));
}
/** Casts this rectangle to a Rectangle<int>.
@ -937,7 +965,7 @@ public:
/** Parses a string containing a rectangle's details.
The string should contain 4 integer tokens, in the form "x y width height". They
The string should contain 4 numeric tokens, in the form "x y width height". They
can be comma or whitespace separated.
This method is intended to go with the toString() method, to form an easy way
@ -950,10 +978,10 @@ public:
StringArray toks;
toks.addTokens (stringVersion.text.findEndOfWhitespace(), ",; \t\r\n", "");
return { parseIntAfterSpace (toks[0]),
parseIntAfterSpace (toks[1]),
parseIntAfterSpace (toks[2]),
parseIntAfterSpace (toks[3]) };
return { detail::parseAfterSpace<ValueType> (toks[0]),
detail::parseAfterSpace<ValueType> (toks[1]),
detail::parseAfterSpace<ValueType> (toks[2]),
detail::parseAfterSpace<ValueType> (toks[3]) };
}
#ifndef DOXYGEN
@ -967,19 +995,9 @@ private:
Point<ValueType> pos;
ValueType w {}, h {};
static ValueType parseIntAfterSpace (StringRef s) noexcept
{ return static_cast<ValueType> (s.text.findEndOfWhitespace().getIntValue32()); }
void copyWithRounding (Rectangle<int>& result) const noexcept { result = getSmallestIntegerContainer(); }
void copyWithRounding (Rectangle<float>& result) const noexcept { result = toFloat(); }
void copyWithRounding (Rectangle<int>& result) const noexcept { result = getSmallestIntegerContainer(); }
void copyWithRounding (Rectangle<float>& result) const noexcept { result = toFloat(); }
void copyWithRounding (Rectangle<double>& result) const noexcept { result = toDouble(); }
static int floorAsInt (int n) noexcept { return n; }
static int floorAsInt (float n) noexcept { return n > (float) std::numeric_limits<int>::min() ? (int) std::floor (n) : std::numeric_limits<int>::min(); }
static int floorAsInt (double n) noexcept { return n > (double) std::numeric_limits<int>::min() ? (int) std::floor (n) : std::numeric_limits<int>::min(); }
static int ceilAsInt (int n) noexcept { return n; }
static int ceilAsInt (float n) noexcept { return n < (float) std::numeric_limits<int>::max() ? (int) std::ceil (n) : std::numeric_limits<int>::max(); }
static int ceilAsInt (double n) noexcept { return n < (double) std::numeric_limits<int>::max() ? (int) std::ceil (n) : std::numeric_limits<int>::max(); }
};
} // namespace juce

View file

@ -0,0 +1,51 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
struct RectangleUnitTest : public UnitTest
{
RectangleUnitTest() : UnitTest ("Rectangle", UnitTestCategories::graphics) {}
void runTest() override
{
beginTest ("Rectangle/string conversions can be round-tripped");
{
const Rectangle<float> a (0.1f, 0.2f, 0.3f, 0.4f);
expect (Rectangle<float>::fromString (a.toString()) == a);
const Rectangle<double> b (0.1, 0.2, 0.3, 0.4);
expect (Rectangle<double>::fromString (b.toString()) == b);
const Rectangle<int> c (1, 2, 3, 4);
expect (Rectangle<int>::fromString (c.toString()) == c);
}
}
};
static RectangleUnitTest rectangleUnitTest;
} // namespace juce