diff --git a/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp b/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp index 78f9421211..abf61e5435 100644 --- a/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp +++ b/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp @@ -2377,47 +2377,8 @@ void LowLevelGraphicsSoftwareRenderer::drawHorizontalLine (const int y, float le } //============================================================================== -class LowLevelGraphicsSoftwareRenderer::CachedGlyph -{ -public: - CachedGlyph() : glyph (0), lastAccessCount (0) {} - - void draw (SavedState& state, float x, const float y) const - { - if (snapToIntegerCoordinate) - x = std::floor (x + 0.5f); - - if (edgeTable != nullptr) - state.fillEdgeTable (*edgeTable, x, roundToInt (y)); - } - - void generate (const Font& newFont, const int glyphNumber) - { - font = newFont; - snapToIntegerCoordinate = newFont.getTypeface()->isHinted(); - glyph = glyphNumber; - - const float fontHeight = font.getHeight(); - edgeTable = font.getTypeface()->getEdgeTableForGlyph (glyphNumber, - AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight) - #if JUCE_MAC || JUCE_IOS - .translated (0.0f, -0.5f) - #endif - ); - } - - Font font; - int glyph, lastAccessCount; - bool snapToIntegerCoordinate; - -private: - ScopedPointer edgeTable; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CachedGlyph); -}; - -//============================================================================== -class LowLevelGraphicsSoftwareRenderer::GlyphCache : private DeletedAtShutdown +template +class GlyphCache : private DeletedAtShutdown { public: GlyphCache() @@ -2428,27 +2389,35 @@ public: ~GlyphCache() { - clearSingletonInstance(); + getSingletonPointer() = nullptr; } - juce_DeclareSingleton_SingleThreaded_Minimal (GlyphCache); + static GlyphCache& getInstance() + { + GlyphCache*& g = getSingletonPointer(); + + if (g == nullptr) + g = new GlyphCache(); + + return *g; + } //============================================================================== - void drawGlyph (SavedState& state, const Font& font, const int glyphNumber, float x, float y) + void drawGlyph (RenderTargetType& target, const Font& font, const int glyphNumber, float x, float y) { ++accessCounter; int oldestCounter = std::numeric_limits::max(); - CachedGlyph* oldest = nullptr; + CachedGlyphType* oldest = nullptr; for (int i = glyphs.size(); --i >= 0;) { - CachedGlyph* const glyph = glyphs.getUnchecked (i); + CachedGlyphType* const glyph = glyphs.getUnchecked (i); if (glyph->glyph == glyphNumber && glyph->font == font) { ++hits; glyph->lastAccessCount = accessCounter; - glyph->draw (state, x, y); + glyph->draw (target, x, y); return; } @@ -2471,35 +2440,68 @@ public: jassert (oldest != nullptr); oldest->lastAccessCount = accessCounter; oldest->generate (font, glyphNumber); - oldest->draw (state, x, y); + oldest->draw (target, x, y); } private: - friend class OwnedArray ; - OwnedArray glyphs; + friend class OwnedArray ; + OwnedArray glyphs; int accessCounter, hits, misses; void addNewGlyphSlots (int num) { while (--num >= 0) - glyphs.add (new CachedGlyph()); + glyphs.add (new CachedGlyphType()); + } + + static GlyphCache*& getSingletonPointer() noexcept + { + static GlyphCache* g = nullptr; + return g; } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GlyphCache); }; -juce_ImplementSingleton_SingleThreaded (LowLevelGraphicsSoftwareRenderer::GlyphCache); +//============================================================================== +class CachedGlyphEdgeTable +{ +public: + CachedGlyphEdgeTable() : glyph (0), lastAccessCount (0) {} + void draw (LowLevelGraphicsSoftwareRenderer::SavedState& state, float x, const float y) const + { + if (snapToIntegerCoordinate) + x = std::floor (x + 0.5f); -void LowLevelGraphicsSoftwareRenderer::setFont (const Font& newFont) -{ - currentState->font = newFont; -} + if (edgeTable != nullptr) + state.fillEdgeTable (*edgeTable, x, roundToInt (y)); + } -Font LowLevelGraphicsSoftwareRenderer::getFont() -{ - return currentState->font; -} + void generate (const Font& newFont, const int glyphNumber) + { + font = newFont; + snapToIntegerCoordinate = newFont.getTypeface()->isHinted(); + glyph = glyphNumber; + + const float fontHeight = font.getHeight(); + edgeTable = font.getTypeface()->getEdgeTableForGlyph (glyphNumber, + AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight) + #if JUCE_MAC || JUCE_IOS + .translated (0.0f, -0.5f) + #endif + ); + } + + Font font; + int glyph, lastAccessCount; + bool snapToIntegerCoordinate; + +private: + ScopedPointer edgeTable; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CachedGlyphEdgeTable); +}; void LowLevelGraphicsSoftwareRenderer::drawGlyph (int glyphNumber, const AffineTransform& transform) { @@ -2507,18 +2509,23 @@ void LowLevelGraphicsSoftwareRenderer::drawGlyph (int glyphNumber, const AffineT if (transform.isOnlyTranslation() && currentState->isOnlyTranslated) { - GlyphCache::getInstance()->drawGlyph (*currentState, f, glyphNumber, - transform.getTranslationX(), - transform.getTranslationY()); + GlyphCache ::getInstance() + .drawGlyph (*currentState, f, glyphNumber, + transform.getTranslationX(), + transform.getTranslationY()); } else { const float fontHeight = f.getHeight(); - currentState->drawGlyph (f, glyphNumber, AffineTransform::scale (fontHeight * f.getHorizontalScale(), fontHeight) - .followedBy (transform)); + currentState->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; } + #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 ebf6f6c829..b388e10dbd 100644 --- a/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h +++ b/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h @@ -95,12 +95,11 @@ protected: //============================================================================== Image image; - class GlyphCache; - class CachedGlyph; - class SavedState; - friend class ScopedPointer ; - friend class OwnedArray ; - friend class OwnedArray ; + #ifndef DOXYGEN + public: class SavedState; + private: + #endif + ScopedPointer currentState; OwnedArray stateStack; diff --git a/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp b/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp index fea743ae0c..709c43ea69 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp @@ -177,8 +177,8 @@ namespace OpenGLGradientHelpers + 8.0f; const AffineTransform inverse (transform.inverted()); - const float renderingRadius = jmax (Point (screenRadius, 0.0f).transformedBy (inverse).getDistanceFromOrigin(), - Point (0.0f, screenRadius).transformedBy (inverse).getDistanceFromOrigin()); + const float sourceRadius = jmax (Point (screenRadius, 0.0f).transformedBy (inverse).getDistanceFromOrigin(), + Point (0.0f, screenRadius).transformedBy (inverse).getDistanceFromOrigin()); const int numDivisions = 80; GLfloat vertices [6 + numDivisions * 4]; @@ -186,7 +186,7 @@ namespace OpenGLGradientHelpers { const float originalRadius = grad.point1.getDistanceFrom (grad.point2); - const float texturePos = renderingRadius / originalRadius; + const float texturePos = sourceRadius / originalRadius; GLfloat* t = textureCoords; *t++ = 0.0f; @@ -205,18 +205,17 @@ namespace OpenGLGradientHelpers { GLfloat* v = vertices; - *v++ = centre.getX(); *v++ = centre.getY(); - const Point first (grad.point1.translated (renderingRadius, -renderingRadius).transformedBy (transform)); + const Point first (grad.point1.translated (sourceRadius, -sourceRadius).transformedBy (transform)); Point last (first); for (int i = 0; i < numDivisions; ++i) { const float angle = (i + 1) * (float_Pi * 4.0f / numDivisions); - const Point next (grad.point1.translated (std::sin (angle) * renderingRadius, - -std::cos (angle) * renderingRadius) + const Point next (grad.point1.translated (std::sin (angle) * sourceRadius, + std::cos (angle) * -sourceRadius) .transformedBy (transform)); *v++ = last.getX(); *v++ = last.getY();