diff --git a/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp b/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp index b15fac4acd..47254e892b 100644 --- a/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp +++ b/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp @@ -229,7 +229,7 @@ public: start = roundToInt ((y - yTerm) * grad); } - inline const PixelARGB getPixel (const int x) const noexcept + inline PixelARGB getPixel (const int x) const noexcept { return vertical ? linePix : lookupTable [jlimit (0, numEntries, (x * scale - start) >> (int) numScaleBits)]; @@ -271,7 +271,7 @@ public: dy *= dy; } - inline const PixelARGB getPixel (const int px) const noexcept + inline PixelARGB getPixel (const int px) const noexcept { double x = px - gx1; x *= x; @@ -308,7 +308,7 @@ public: lineYM11 = inverseTransform.mat11 * y + inverseTransform.mat12 - gy1; } - inline const PixelARGB getPixel (const int px) const noexcept + inline PixelARGB getPixel (const int px) const noexcept { double x = px; const double y = tM10 * x + lineYM11; @@ -1904,14 +1904,14 @@ public: return s; } - void endTransparencyLayer (SavedState& layerState) + void endTransparencyLayer (SavedState& finishedLayerState) { const Rectangle layerBounds (getUntransformedClipBounds()); const ScopedPointer g (image.createLowLevelContext()); - g->setOpacity (layerState.transparencyLayerAlpha); - g->drawImage (layerState.image, AffineTransform::translation ((float) layerBounds.getX(), - (float) layerBounds.getY()), false); + g->setOpacity (finishedLayerState.transparencyLayerAlpha); + g->drawImage (finishedLayerState.image, AffineTransform::translation ((float) layerBounds.getX(), + (float) layerBounds.getY()), false); } //============================================================================== @@ -2132,16 +2132,14 @@ private: //============================================================================== -LowLevelGraphicsSoftwareRenderer::LowLevelGraphicsSoftwareRenderer (const Image& image_) - : image (image_), - currentState (new SavedState (image_, image_.getBounds(), 0, 0)) +LowLevelGraphicsSoftwareRenderer::LowLevelGraphicsSoftwareRenderer (const Image& image) + : savedState (new SavedState (image, image.getBounds(), 0, 0)) { } -LowLevelGraphicsSoftwareRenderer::LowLevelGraphicsSoftwareRenderer (const Image& image_, const int xOffset, const int yOffset, +LowLevelGraphicsSoftwareRenderer::LowLevelGraphicsSoftwareRenderer (const Image& image, const int xOffset, const int yOffset, const RectangleList& initialClip) - : image (image_), - currentState (new SavedState (image_, initialClip, xOffset, yOffset)) + : savedState (new SavedState (image, initialClip, xOffset, yOffset)) { } @@ -2157,123 +2155,96 @@ bool LowLevelGraphicsSoftwareRenderer::isVectorDevice() const //============================================================================== void LowLevelGraphicsSoftwareRenderer::setOrigin (int x, int y) { - currentState->transform.setOrigin (x, y); + savedState->transform.setOrigin (x, y); } void LowLevelGraphicsSoftwareRenderer::addTransform (const AffineTransform& transform) { - currentState->transform.addTransform (transform); + savedState->transform.addTransform (transform); } float LowLevelGraphicsSoftwareRenderer::getScaleFactor() { - return currentState->transform.getScaleFactor(); + return savedState->transform.getScaleFactor(); } bool LowLevelGraphicsSoftwareRenderer::clipToRectangle (const Rectangle& r) { - return currentState->clipToRectangle (r); + return savedState->clipToRectangle (r); } bool LowLevelGraphicsSoftwareRenderer::clipToRectangleList (const RectangleList& clipRegion) { - return currentState->clipToRectangleList (clipRegion); + return savedState->clipToRectangleList (clipRegion); } void LowLevelGraphicsSoftwareRenderer::excludeClipRectangle (const Rectangle& r) { - currentState->excludeClipRectangle (r); + savedState->excludeClipRectangle (r); } void LowLevelGraphicsSoftwareRenderer::clipToPath (const Path& path, const AffineTransform& transform) { - currentState->clipToPath (path, transform); + savedState->clipToPath (path, transform); } void LowLevelGraphicsSoftwareRenderer::clipToImageAlpha (const Image& sourceImage, const AffineTransform& transform) { - currentState->clipToImageAlpha (sourceImage, transform); + savedState->clipToImageAlpha (sourceImage, transform); } bool LowLevelGraphicsSoftwareRenderer::clipRegionIntersects (const Rectangle& r) { - return currentState->clipRegionIntersects (r); + return savedState->clipRegionIntersects (r); } Rectangle LowLevelGraphicsSoftwareRenderer::getClipBounds() const { - return currentState->getClipBounds(); + return savedState->getClipBounds(); } bool LowLevelGraphicsSoftwareRenderer::isClipEmpty() const { - return currentState->clip == nullptr; + return savedState->clip == nullptr; } //============================================================================== -void LowLevelGraphicsSoftwareRenderer::saveState() -{ - stateStack.add (new SavedState (*currentState)); -} +void LowLevelGraphicsSoftwareRenderer::saveState() { savedState.save(); } +void LowLevelGraphicsSoftwareRenderer::restoreState() { savedState.restore(); } -void LowLevelGraphicsSoftwareRenderer::restoreState() -{ - SavedState* const top = stateStack.getLast(); - - if (top != nullptr) - { - currentState = top; - stateStack.removeLast (1, false); - } - else - { - jassertfalse; // trying to pop with an empty stack! - } -} - -void LowLevelGraphicsSoftwareRenderer::beginTransparencyLayer (float opacity) -{ - saveState(); - currentState = currentState->beginTransparencyLayer (opacity); -} - -void LowLevelGraphicsSoftwareRenderer::endTransparencyLayer() -{ - const ScopedPointer layer (currentState); - restoreState(); - currentState->endTransparencyLayer (*layer); -} +void LowLevelGraphicsSoftwareRenderer::beginTransparencyLayer (float opacity) { savedState.beginTransparencyLayer (opacity); } +void LowLevelGraphicsSoftwareRenderer::endTransparencyLayer() { savedState.endTransparencyLayer(); } //============================================================================== void LowLevelGraphicsSoftwareRenderer::setFill (const FillType& fillType) { - currentState->fillType = fillType; + savedState->fillType = fillType; } void LowLevelGraphicsSoftwareRenderer::setOpacity (float newOpacity) { - currentState->fillType.setOpacity (newOpacity); + savedState->fillType.setOpacity (newOpacity); } void LowLevelGraphicsSoftwareRenderer::setInterpolationQuality (Graphics::ResamplingQuality quality) { - currentState->interpolationQuality = quality; + savedState->interpolationQuality = quality; } //============================================================================== void LowLevelGraphicsSoftwareRenderer::fillRect (const Rectangle& r, const bool replaceExistingContents) { - currentState->fillRect (r, replaceExistingContents); + savedState->fillRect (r, replaceExistingContents); } void LowLevelGraphicsSoftwareRenderer::fillPath (const Path& path, const AffineTransform& transform) { - currentState->fillPath (path, transform); + savedState->fillPath (path, transform); } void LowLevelGraphicsSoftwareRenderer::drawImage (const Image& sourceImage, const AffineTransform& transform, const bool fillEntireClipAsTiles) { - currentState->renderImage (sourceImage, transform, fillEntireClipAsTiles ? currentState->clip : 0); + savedState->renderImage (sourceImage, transform, fillEntireClipAsTiles ? savedState->clip : 0); } void LowLevelGraphicsSoftwareRenderer::drawLine (const Line & line) @@ -2286,13 +2257,13 @@ void LowLevelGraphicsSoftwareRenderer::drawLine (const Line & line) void LowLevelGraphicsSoftwareRenderer::drawVerticalLine (const int x, float top, float bottom) { if (bottom > top) - currentState->fillRect (Rectangle ((float) x, top, 1.0f, bottom - top)); + savedState->fillRect (Rectangle ((float) x, top, 1.0f, bottom - top)); } void LowLevelGraphicsSoftwareRenderer::drawHorizontalLine (const int y, float left, float right) { if (right > left) - currentState->fillRect (Rectangle (left, (float) y, right - left, 1.0f)); + savedState->fillRect (Rectangle (left, (float) y, right - left, 1.0f)); } //============================================================================== @@ -2337,26 +2308,26 @@ private: void LowLevelGraphicsSoftwareRenderer::drawGlyph (int glyphNumber, const AffineTransform& transform) { - Font& f = currentState->font; + Font& f = savedState->font; - if (transform.isOnlyTranslation() && currentState->transform.isOnlyTranslated) + if (transform.isOnlyTranslation() && savedState->transform.isOnlyTranslated) { RenderingHelpers::GlyphCache ::getInstance() - .drawGlyph (*currentState, f, glyphNumber, + .drawGlyph (*savedState, f, glyphNumber, transform.getTranslationX(), transform.getTranslationY()); } else { const float fontHeight = f.getHeight(); - currentState->drawGlyph (f, glyphNumber, - AffineTransform::scale (fontHeight * f.getHorizontalScale(), fontHeight) - .followedBy (transform)); + savedState->drawGlyph (f, glyphNumber, + AffineTransform::scale (fontHeight * f.getHorizontalScale(), fontHeight) + .followedBy (transform)); } } -void LowLevelGraphicsSoftwareRenderer::setFont (const Font& newFont) { currentState->font = newFont; } -Font LowLevelGraphicsSoftwareRenderer::getFont() { return currentState->font; } +void LowLevelGraphicsSoftwareRenderer::setFont (const Font& newFont) { savedState->font = newFont; } +Font LowLevelGraphicsSoftwareRenderer::getFont() { return savedState->font; } #if JUCE_MSVC #pragma warning (pop) diff --git a/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h b/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h index b388e10dbd..d535ff7b21 100644 --- a/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h +++ b/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h @@ -28,6 +28,9 @@ #include "juce_LowLevelGraphicsContext.h" +#ifndef DOXYGEN +#include "../native/juce_RenderingHelpers.h" +#endif //============================================================================== /** @@ -90,22 +93,16 @@ public: void drawGlyph (int glyphNumber, float x, float y); void drawGlyph (int glyphNumber, const AffineTransform& transform); - -protected: //============================================================================== - Image image; - #ifndef DOXYGEN - public: class SavedState; - private: + class SavedState; #endif - ScopedPointer currentState; - OwnedArray stateStack; +protected: + RenderingHelpers::SavedStateStack savedState; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LowLevelGraphicsSoftwareRenderer); }; - #endif // __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__ diff --git a/modules/juce_graphics/juce_graphics.cpp b/modules/juce_graphics/juce_graphics.cpp index 89cc43344b..6b385bdf72 100644 --- a/modules/juce_graphics/juce_graphics.cpp +++ b/modules/juce_graphics/juce_graphics.cpp @@ -54,8 +54,6 @@ #endif //============================================================================== -#include "native/juce_RenderingHelpers.h" - // START_AUTOINCLUDE colour/*.cpp, geometry/*.cpp, placement/*.cpp, contexts/*.cpp, images/*.cpp, // image_formats/*.cpp, fonts/*.cpp, effects/*.cpp #include "colour/juce_Colour.cpp" diff --git a/modules/juce_graphics/native/juce_RenderingHelpers.h b/modules/juce_graphics/native/juce_RenderingHelpers.h index 8054980565..95ca7960fd 100644 --- a/modules/juce_graphics/native/juce_RenderingHelpers.h +++ b/modules/juce_graphics/native/juce_RenderingHelpers.h @@ -26,8 +26,6 @@ #ifndef __JUCE_RENDERINGHELPERS_JUCEHEADER__ #define __JUCE_RENDERINGHELPERS_JUCEHEADER__ -BEGIN_JUCE_NAMESPACE - namespace RenderingHelpers { @@ -223,8 +221,58 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GlyphCache); }; +//============================================================================== +template +class SavedStateStack +{ +public: + SavedStateStack (StateObjectType* const initialState) noexcept + : currentState (initialState) + {} + + inline StateObjectType* operator->() const noexcept { return currentState; } + inline StateObjectType& operator*() const noexcept { return *currentState; } + + void save() + { + stack.add (new StateObjectType (*currentState)); + } + + void restore() + { + StateObjectType* const top = stack.getLast(); + + if (top != nullptr) + { + currentState = top; + stack.removeLast (1, false); + } + else + { + jassertfalse; // trying to pop with an empty stack! + } + } + + void beginTransparencyLayer (float opacity) + { + save(); + currentState = currentState->beginTransparencyLayer (opacity); + } + + void endTransparencyLayer() + { + const ScopedPointer finishedTransparencyLayer (currentState); + restore(); + currentState->endTransparencyLayer (*finishedTransparencyLayer); + } + +private: + ScopedPointer currentState; + OwnedArray stack; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SavedStateStack); +}; + } -END_JUCE_NAMESPACE - #endif // __JUCE_RENDERINGHELPERS_JUCEHEADER__