Browse Source

Changed Rectangle::transformed to use getSmallestIntegerContainer on its result when used on a non-float rectangle type.

tags/2021-05-28
jules 12 years ago
parent
commit
cf01cae2ea
3 changed files with 67 additions and 44 deletions
  1. +2
    -2
      modules/juce_graphics/geometry/juce_Point.h
  2. +58
    -35
      modules/juce_graphics/geometry/juce_Rectangle.h
  3. +7
    -7
      modules/juce_graphics/native/juce_RenderingHelpers.h

+ 2
- 2
modules/juce_graphics/geometry/juce_Point.h View File

@@ -196,8 +196,8 @@ public:
/** Returns the position of this point, if it is transformed by a given AffineTransform. */
Point transformedBy (const AffineTransform& transform) const noexcept
{
return Point (transform.mat00 * x + transform.mat01 * y + transform.mat02,
transform.mat10 * x + transform.mat11 * y + transform.mat12);
return Point (static_cast<ValueType> (transform.mat00 * x + transform.mat01 * y + transform.mat02),
static_cast<ValueType> (transform.mat10 * x + transform.mat11 * y + transform.mat12));
}
//==============================================================================


+ 58
- 35
modules/juce_graphics/geometry/juce_Rectangle.h View File

@@ -587,8 +587,9 @@ public:
pos.y = newY;
return true;
}
else if (pos.y == other.pos.y && getBottom() == other.getBottom()
&& (other.getRight() >= pos.x && other.pos.x <= getRight()))
if (pos.y == other.pos.y && getBottom() == other.getBottom()
&& (other.getRight() >= pos.x && other.pos.x <= getRight()))
{
const ValueType newX = jmin (pos.x, other.pos.x);
w = jmax (getRight(), other.getRight()) - newX;
@@ -652,20 +653,24 @@ public:
*/
Rectangle transformed (const AffineTransform& transform) const noexcept
{
float x1 = pos.x, y1 = pos.y;
float x2 = pos.x + w, y2 = pos.y;
float x3 = pos.x, y3 = pos.y + h;
float x4 = x2, y4 = y3;
typedef typename TypeHelpers::SmallestFloatType<ValueType>::type FloatType;
FloatType x1 = static_cast<FloatType> (pos.x), y1 = static_cast<FloatType> (pos.y);
FloatType x2 = static_cast<FloatType> (pos.x + w), y2 = static_cast<FloatType> (pos.y);
FloatType x3 = static_cast<FloatType> (pos.x), y3 = static_cast<FloatType> (pos.y + h);
FloatType x4 = static_cast<FloatType> (x2), y4 = static_cast<FloatType> (y3);
transform.transformPoints (x1, y1, x2, y2);
transform.transformPoints (x3, y3, x4, y4);
const float rx = jmin (x1, x2, x3, x4);
const float ry = jmin (y1, y2, y3, y4);
const FloatType rx1 = jmin (x1, x2, x3, x4);
const FloatType rx2 = jmax (x1, x2, x3, x4);
const FloatType ry1 = jmin (y1, y2, y3, y4);
const FloatType ry2 = jmax (y1, y2, y3, y4);
return Rectangle (rx, ry,
jmax (x1, x2, x3, x4) - rx,
jmax (y1, y2, y3, y4) - ry);
Rectangle r;
Rectangle<FloatType> (rx1, ry1, rx2 - rx1, ry2 - ry1).copyWithRounding (r);
return r;
}
/** Returns the smallest integer-aligned rectangle that completely contains this one.
@@ -674,34 +679,22 @@ public:
*/
Rectangle<int> getSmallestIntegerContainer() const noexcept
{
const int x1 = static_cast <int> (std::floor (static_cast<float> (pos.x)));
const int y1 = static_cast <int> (std::floor (static_cast<float> (pos.y)));
const int x2 = static_cast <int> (std::ceil (static_cast<float> (pos.x + w)));
const int y2 = static_cast <int> (std::ceil (static_cast<float> (pos.y + h)));
return Rectangle<int> (x1, y1, x2 - x1, y2 - y1);
return getSmallestIntegerContainerWithType<int>();
}
/** Returns the smallest Rectangle that can contain a set of points. */
static Rectangle findAreaContainingPoints (const Point<ValueType>* const points, const int numPoints) noexcept
/** Returns the smallest integer-aligned rectangle that completely contains this one.
This is only relevent for floating-point rectangles, of course.
@see toFloat()
*/
template <typename IntType>
Rectangle<IntType> getSmallestIntegerContainerWithType() const noexcept
{
if (numPoints == 0)
return Rectangle();
ValueType minX (points[0].x);
ValueType maxX (minX);
ValueType minY (points[0].y);
ValueType maxY (minY);
const IntType x1 = static_cast <IntType> (std::floor (static_cast<float> (pos.x)));
const IntType y1 = static_cast <IntType> (std::floor (static_cast<float> (pos.y)));
const IntType x2 = static_cast <IntType> (std::ceil (static_cast<float> (pos.x + w)));
const IntType y2 = static_cast <IntType> (std::ceil (static_cast<float> (pos.y + h)));
for (int i = 1; i < numPoints; ++i)
{
minX = jmin (minX, points[i].x);
maxX = jmax (maxX, points[i].x);
minY = jmin (minY, points[i].y);
maxY = jmax (maxY, points[i].y);
}
return Rectangle (minX, minY, maxX - minX, maxY - minY);
return Rectangle<IntType> (x1, y1, x2 - x1, y2 - y1);
}
/** Casts this rectangle to a Rectangle<float>.
@@ -724,6 +717,28 @@ public:
static_cast<double> (w), static_cast<double> (h));
}
/** Returns the smallest Rectangle that can contain a set of points. */
static Rectangle findAreaContainingPoints (const Point<ValueType>* const points, const int numPoints) noexcept
{
if (numPoints == 0)
return Rectangle();
ValueType minX (points[0].x);
ValueType maxX (minX);
ValueType minY (points[0].y);
ValueType maxY (minY);
for (int i = 1; i < numPoints; ++i)
{
minX = jmin (minX, points[i].x);
maxX = jmax (maxX, points[i].x);
minY = jmin (minY, points[i].y);
maxY = jmax (maxY, points[i].y);
}
return Rectangle (minX, minY, maxX - minX, maxY - minY);
}
//==============================================================================
/** Static utility to intersect two sets of rectangular coordinates.
Returns false if the two regions didn't overlap.
@@ -789,6 +804,8 @@ public:
parseIntAfterSpace (toks[3]));
}
typedef ValueType Type;
private:
friend class RectangleList;
Point<ValueType> pos;
@@ -796,6 +813,12 @@ private:
static int parseIntAfterSpace (const String& s) noexcept
{ return s.getCharPointer().findEndOfWhitespace().getIntValue32(); }
template <typename OtherType> friend class Rectangle;
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(); }
};


+ 7
- 7
modules/juce_graphics/native/juce_RenderingHelpers.h View File

@@ -121,15 +121,15 @@ public:
}
template <typename Type>
Rectangle<float> transformed (const Rectangle<Type>& r) const noexcept
Rectangle<Type> transformed (const Rectangle<Type>& r) const noexcept
{
return r.toFloat().transformed (complexTransform);
return r.transformed (complexTransform);
}
Rectangle<int> deviceSpaceToUserSpace (const Rectangle<int>& r) const noexcept
{
return isOnlyTranslated ? r.translated (-xOffset, -yOffset)
: r.toFloat().transformed (complexTransform.inverted()).getSmallestIntegerContainer();
: r.transformed (complexTransform.inverted());
}
AffineTransform complexTransform;
@@ -2065,7 +2065,7 @@ public:
else if (transform.isIntegerScaling)
{
cloneClipIfMultiplyReferenced();
clip = clip->clipToRectangle (transform.transformed (r).getSmallestIntegerContainer());
clip = clip->clipToRectangle (transform.transformed (r));
}
else
{
@@ -2095,7 +2095,7 @@ public:
RectangleList scaledList;
for (const Rectangle<int>* i = r.begin(), * const e = r.end(); i != e; ++i)
scaledList.add (transform.transformed (*i).getSmallestIntegerContainer());
scaledList.add (transform.transformed (*i));
clip = clip->clipToRectangleList (scaledList);
}
@@ -2120,7 +2120,7 @@ public:
}
else if (transform.isIntegerScaling)
{
clip = clip->excludeClipRectangle (transform.transformed (r).getSmallestIntegerContainer());
clip = clip->excludeClipRectangle (transform.transformed (r));
}
else
{
@@ -2262,7 +2262,7 @@ public:
if (transform.isOnlyTranslated)
fillTargetRect (transform.translated (r), replaceContents);
else if (transform.isIntegerScaling)
fillTargetRect (transform.transformed (r).getSmallestIntegerContainer(), replaceContents);
fillTargetRect (transform.transformed (r), replaceContents);
else
fillRectAsPath (r);
}


Loading…
Cancel
Save