From 667a18712f34825449ed8eaf03273f03cbecde06 Mon Sep 17 00:00:00 2001 From: jules Date: Thu, 15 Nov 2012 13:58:49 +0000 Subject: [PATCH] Added begin()/end() iterators to RectangleList. You should use these in preference to RectangleList::Iterator, as they're faster. --- ...uce_LowLevelGraphicsPostScriptRenderer.cpp | 14 ++--- .../juce_graphics/geometry/juce_EdgeTable.cpp | 4 +- .../geometry/juce_RectangleList.h | 10 +++- .../native/juce_RenderingHelpers.h | 60 ++++++++++++------- .../components/juce_Component.cpp | 4 +- .../native/juce_linux_Windowing.cpp | 13 ++-- .../native/juce_win32_Windowing.cpp | 20 ++----- 7 files changed, 65 insertions(+), 60 deletions(-) diff --git a/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp b/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp index faec1c8a66..57d7371b08 100644 --- a/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp +++ b/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp @@ -205,7 +205,7 @@ void LowLevelGraphicsPostScriptRenderer::writeClip() int itemsOnLine = 0; - for (RectangleList::Iterator i (stateStack.getLast()->clip); i.next();) + for (const Rectangle* i = stateStack.getLast()->clip.begin(), * const e = stateStack.getLast()->clip.end(); i != e; ++i) { if (++itemsOnLine == 6) { @@ -213,10 +213,8 @@ void LowLevelGraphicsPostScriptRenderer::writeClip() out << '\n'; } - const Rectangle& r = *i.getRectangle(); - - out << r.getX() << ' ' << -r.getY() << ' ' - << r.getWidth() << ' ' << -r.getHeight() << " pr "; + out << i->getX() << ' ' << -i->getY() << ' ' + << i->getWidth() << ' ' << -i->getHeight() << " pr "; } out << "endclip\n"; @@ -479,7 +477,7 @@ void LowLevelGraphicsPostScriptRenderer::drawImage (const Image& sourceImage, co out << "newpath "; int itemsOnLine = 0; - for (RectangleList::Iterator i (imageClip); i.next();) + for (const Rectangle* i = imageClip.begin(), * const e = imageClip.end(); i != e; ++i) { if (++itemsOnLine == 6) { @@ -487,9 +485,7 @@ void LowLevelGraphicsPostScriptRenderer::drawImage (const Image& sourceImage, co itemsOnLine = 0; } - const Rectangle& r = *i.getRectangle(); - - out << r.getX() << ' ' << r.getY() << ' ' << r.getWidth() << ' ' << r.getHeight() << " pr "; + out << i->getX() << ' ' << i->getY() << ' ' << i->getWidth() << ' ' << i->getHeight() << " pr "; } out << " clip newpath\n"; diff --git a/modules/juce_graphics/geometry/juce_EdgeTable.cpp b/modules/juce_graphics/geometry/juce_EdgeTable.cpp index b8cac78157..af9781a362 100644 --- a/modules/juce_graphics/geometry/juce_EdgeTable.cpp +++ b/modules/juce_graphics/geometry/juce_EdgeTable.cpp @@ -140,10 +140,8 @@ EdgeTable::EdgeTable (const RectangleList& rectanglesToAdd) t += lineStrideElements; } - for (RectangleList::Iterator iter (rectanglesToAdd); iter.next();) + for (const Rectangle* r = rectanglesToAdd.begin(), * const e = rectanglesToAdd.end(); r != e; ++r) { - const Rectangle* const r = iter.getRectangle(); - const int x1 = r->getX() << 8; const int x2 = r->getRight() << 8; int y = r->getY() - bounds.getY(); diff --git a/modules/juce_graphics/geometry/juce_RectangleList.h b/modules/juce_graphics/geometry/juce_RectangleList.h index c7c4cb8f91..4ab9e8e2bb 100644 --- a/modules/juce_graphics/geometry/juce_RectangleList.h +++ b/modules/juce_graphics/geometry/juce_RectangleList.h @@ -216,9 +216,17 @@ public: /** Creates a Path object to represent this region. */ Path toPath() const; + //============================================================================== + /** Standard method for iterating the rectangles in the list. */ + const Rectangle* begin() const noexcept { return rects.begin(); } + /** Standard method for iterating the rectangles in the list. */ + const Rectangle* end() const noexcept { return rects.end(); } //============================================================================== - /** An iterator for accessing all the rectangles in a RectangleList. */ + /** An iterator for accessing all the rectangles in a RectangleList. + Note that this class is deprectated in favour of just using the standard + RectangleList::begin() and RectangleList::end() methods, which are more efficient. + */ class JUCE_API Iterator { public: diff --git a/modules/juce_graphics/native/juce_RenderingHelpers.h b/modules/juce_graphics/native/juce_RenderingHelpers.h index 11b4653248..0f8f796f52 100644 --- a/modules/juce_graphics/native/juce_RenderingHelpers.h +++ b/modules/juce_graphics/native/juce_RenderingHelpers.h @@ -41,14 +41,14 @@ class TranslationOrTransform { public: TranslationOrTransform (int x, int y) noexcept - : xOffset (x), yOffset (y), isOnlyTranslated (true) + : xOffset (x), yOffset (y), isOnlyTranslated (true), isIntegerScaling (true) { } TranslationOrTransform (const TranslationOrTransform& other) noexcept : complexTransform (other.complexTransform), xOffset (other.xOffset), yOffset (other.yOffset), - isOnlyTranslated (other.isOnlyTranslated) + isOnlyTranslated (other.isOnlyTranslated), isIntegerScaling (other.isIntegerScaling) { } @@ -91,6 +91,7 @@ public: { complexTransform = getTransformWith (t); isOnlyTranslated = false; + isIntegerScaling = isIntegerScale (complexTransform); } } @@ -120,6 +121,12 @@ public: static_cast (yOffset)); } + template + Rectangle transformed (const Rectangle& r) const noexcept + { + return r.transformed (complexTransform); + } + Rectangle deviceSpaceToUserSpace (const Rectangle& r) const noexcept { return isOnlyTranslated ? r.translated (-xOffset, -yOffset) @@ -128,7 +135,7 @@ public: AffineTransform complexTransform; int xOffset, yOffset; - bool isOnlyTranslated; + bool isOnlyTranslated, isIntegerScaling; private: static inline bool isIntegerTranslation (const AffineTransform& t) noexcept @@ -137,6 +144,19 @@ private: const int ty = (int) (t.getTranslationY() * 256.0f); return ((tx | ty) & 0xf8) == 0; } + + static inline bool isIntegerScale (const AffineTransform& t) noexcept + { + if (t.mat01 != 0 || t.mat10 != 0) + return false; + + const int tx = (int) (t.getTranslationX() * 256.0f); + const int ty = (int) (t.getTranslationY() * 256.0f); + const int txs = (int) (t.mat00 * 256.0f); + const int tys = (int) (t.mat11 * 256.0f); + + return ((tx | ty | txs | tys) & 0xf8) == 0; + } }; //============================================================================== @@ -1664,8 +1684,8 @@ namespace ClipRegions RectangleList inverse (edgeTable.getMaximumBounds()); if (inverse.subtract (r)) - for (RectangleList::Iterator iter (inverse); iter.next();) - edgeTable.excludeRectangle (*iter.getRectangle()); + for (const Rectangle* i = inverse.begin(), * const e = inverse.end(); i != e; ++i) + edgeTable.excludeRectangle (*i); return edgeTable.isEmpty() ? nullptr : this; } @@ -1947,17 +1967,14 @@ namespace ClipRegions template void iterate (Renderer& r) const noexcept { - RectangleList::Iterator iter (clip); - - while (iter.next()) + for (const Rectangle* i = clip.begin(), * const e = clip.end(); i != e; ++i) { - const Rectangle rect (*iter.getRectangle()); - const int x = rect.getX(); - const int w = rect.getWidth(); + const int x = i->getX(); + const int w = i->getWidth(); jassert (w > 0); - const int bottom = rect.getBottom(); + const int bottom = i->getBottom(); - for (int y = rect.getY(); y < bottom; ++y) + for (int y = i->getY(); y < bottom; ++y) { r.setEdgeTableYPos (y); r.handleEdgeTableLineFull (x, w); @@ -1977,11 +1994,9 @@ namespace ClipRegions template void iterate (Renderer& r) const noexcept { - RectangleList::Iterator iter (clip); - - while (iter.next()) + for (const Rectangle* i = clip.begin(), * const e = clip.end(); i != e; ++i) { - const Rectangle rect (iter.getRectangle()->getIntersection (area)); + const Rectangle rect (i->getIntersection (area)); if (! rect.isEmpty()) { @@ -2018,14 +2033,13 @@ namespace ClipRegions void iterate (Renderer& r) const noexcept { const RenderingHelpers::FloatRectangleRasterisingInfo f (area); - RectangleList::Iterator iter (clip); - while (iter.next()) + for (const Rectangle* i = clip.begin(), * const e = clip.end(); i != e; ++i) { - const int clipLeft = iter.getRectangle()->getX(); - const int clipRight = iter.getRectangle()->getRight(); - const int clipTop = iter.getRectangle()->getY(); - const int clipBottom = iter.getRectangle()->getBottom(); + const int clipLeft = i->getX(); + const int clipRight = i->getRight(); + const int clipTop = i->getY(); + const int clipBottom = i->getBottom(); if (f.totalBottom > clipTop && f.totalTop < clipBottom && f.totalRight > clipLeft && f.totalLeft < clipRight) { diff --git a/modules/juce_gui_basics/components/juce_Component.cpp b/modules/juce_gui_basics/components/juce_Component.cpp index 8fc2b1ee44..a63b93f1a9 100644 --- a/modules/juce_gui_basics/components/juce_Component.cpp +++ b/modules/juce_gui_basics/components/juce_Component.cpp @@ -696,8 +696,8 @@ public: Graphics imG (image); LowLevelGraphicsContext& lg = imG.getInternalContext(); - for (RectangleList::Iterator i (validArea); i.next();) - lg.excludeClipRectangle (*i.getRectangle()); + for (const Rectangle* i = validArea.begin(), * const e = validArea.end(); i != e; ++i) + lg.excludeClipRectangle (*i); if (! lg.isClipEmpty()) { diff --git a/modules/juce_gui_basics/native/juce_linux_Windowing.cpp b/modules/juce_gui_basics/native/juce_linux_Windowing.cpp index 2d3605b139..02fd43966b 100644 --- a/modules/juce_gui_basics/native/juce_linux_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_linux_Windowing.cpp @@ -1881,10 +1881,8 @@ private: if (peer->depth == 32) { - RectangleList::Iterator i (originalRepaintRegion); - - while (i.next()) - image.clear (*i.getRectangle() - totalArea.getPosition()); + for (const Rectangle* i = originalRepaintRegion.begin(), * const e = originalRepaintRegion.end(); i != e; ++i) + image.clear (*i - totalArea.getPosition()); } { @@ -1896,17 +1894,16 @@ private: if (! peer->maskedRegion.isEmpty()) originalRepaintRegion.subtract (peer->maskedRegion); - for (RectangleList::Iterator i (originalRepaintRegion); i.next();) + for (const Rectangle* i = originalRepaintRegion.begin(), * const e = originalRepaintRegion.end(); i != e; ++i) { #if JUCE_USE_XSHM shmCompletedDrawing = false; #endif - const Rectangle& r = *i.getRectangle(); static_cast (image.getPixelData()) ->blitToWindow (peer->windowH, - r.getX(), r.getY(), r.getWidth(), r.getHeight(), - r.getX() - totalArea.getX(), r.getY() - totalArea.getY()); + i->getX(), i->getY(), i->getWidth(), i->getHeight(), + i->getX() - totalArea.getX(), i->getY() - totalArea.getY()); } } diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index 95c21c02f4..0a3b9a9bd7 100644 --- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -297,11 +297,8 @@ public: { if (! maskedRegion.isEmpty()) { - for (RectangleList::Iterator i (maskedRegion); i.next();) - { - const Rectangle& r = *i.getRectangle(); - ExcludeClipRect (hdc, r.getX(), r.getY(), r.getRight(), r.getBottom()); - } + for (const Rectangle* i = maskedRegion.begin(), * const e = maskedRegion.end(); i != e; ++i) + ExcludeClipRect (hdc, i->getX(), i->getY(), i->getRight(), i->getBottom()); } RECT windowBounds; @@ -328,11 +325,8 @@ public: { savedDC = SaveDC (dc); - for (RectangleList::Iterator i (maskedRegion); i.next();) - { - const Rectangle& r = *i.getRectangle(); - ExcludeClipRect (dc, r.getX(), r.getY(), r.getRight(), r.getBottom()); - } + for (const Rectangle* i = maskedRegion.begin(), * const e = maskedRegion.end(); i != e; ++i) + ExcludeClipRect (dc, i->getX(), i->getY(), i->getRight(), i->getBottom()); } StretchDIBits (dc, @@ -1497,10 +1491,8 @@ private: if (transparent) { - RectangleList::Iterator i (contextClip); - - while (i.next()) - offscreenImage.clear (*i.getRectangle()); + for (const Rectangle* i = contextClip.begin(), * const e = contextClip.end(); i != e; ++i) + offscreenImage.clear (*i); } // if the component's not opaque, this won't draw properly unless the platform can support this