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

Minor bits of refactoring.

This commit is contained in:
jules 2011-10-08 19:04:43 +01:00
parent 58580fc792
commit c3492b99e3
3 changed files with 112 additions and 107 deletions

View file

@ -2377,12 +2377,99 @@ void LowLevelGraphicsSoftwareRenderer::drawHorizontalLine (const int y, float le
}
//==============================================================================
class LowLevelGraphicsSoftwareRenderer::CachedGlyph
template <class CachedGlyphType, class RenderTargetType>
class GlyphCache : private DeletedAtShutdown
{
public:
CachedGlyph() : glyph (0), lastAccessCount (0) {}
GlyphCache()
: accessCounter (0), hits (0), misses (0)
{
addNewGlyphSlots (120);
}
void draw (SavedState& state, float x, const float y) const
~GlyphCache()
{
getSingletonPointer() = nullptr;
}
static GlyphCache& getInstance()
{
GlyphCache*& g = getSingletonPointer();
if (g == nullptr)
g = new GlyphCache();
return *g;
}
//==============================================================================
void drawGlyph (RenderTargetType& target, const Font& font, const int glyphNumber, float x, float y)
{
++accessCounter;
int oldestCounter = std::numeric_limits<int>::max();
CachedGlyphType* oldest = nullptr;
for (int i = glyphs.size(); --i >= 0;)
{
CachedGlyphType* const glyph = glyphs.getUnchecked (i);
if (glyph->glyph == glyphNumber && glyph->font == font)
{
++hits;
glyph->lastAccessCount = accessCounter;
glyph->draw (target, x, y);
return;
}
if (glyph->lastAccessCount <= oldestCounter)
{
oldestCounter = glyph->lastAccessCount;
oldest = glyph;
}
}
if (hits + ++misses > (glyphs.size() << 4))
{
if (misses * 2 > hits)
addNewGlyphSlots (32);
hits = misses = 0;
oldest = glyphs.getLast();
}
jassert (oldest != nullptr);
oldest->lastAccessCount = accessCounter;
oldest->generate (font, glyphNumber);
oldest->draw (target, x, y);
}
private:
friend class OwnedArray <CachedGlyphType>;
OwnedArray <CachedGlyphType> glyphs;
int accessCounter, hits, misses;
void addNewGlyphSlots (int num)
{
while (--num >= 0)
glyphs.add (new CachedGlyphType());
}
static GlyphCache*& getSingletonPointer() noexcept
{
static GlyphCache* g = nullptr;
return g;
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (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);
@ -2413,112 +2500,32 @@ public:
private:
ScopedPointer <EdgeTable> edgeTable;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CachedGlyph);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CachedGlyphEdgeTable);
};
//==============================================================================
class LowLevelGraphicsSoftwareRenderer::GlyphCache : private DeletedAtShutdown
{
public:
GlyphCache()
: accessCounter (0), hits (0), misses (0)
{
addNewGlyphSlots (120);
}
~GlyphCache()
{
clearSingletonInstance();
}
juce_DeclareSingleton_SingleThreaded_Minimal (GlyphCache);
//==============================================================================
void drawGlyph (SavedState& state, const Font& font, const int glyphNumber, float x, float y)
{
++accessCounter;
int oldestCounter = std::numeric_limits<int>::max();
CachedGlyph* oldest = nullptr;
for (int i = glyphs.size(); --i >= 0;)
{
CachedGlyph* const glyph = glyphs.getUnchecked (i);
if (glyph->glyph == glyphNumber && glyph->font == font)
{
++hits;
glyph->lastAccessCount = accessCounter;
glyph->draw (state, x, y);
return;
}
if (glyph->lastAccessCount <= oldestCounter)
{
oldestCounter = glyph->lastAccessCount;
oldest = glyph;
}
}
if (hits + ++misses > (glyphs.size() << 4))
{
if (misses * 2 > hits)
addNewGlyphSlots (32);
hits = misses = 0;
oldest = glyphs.getLast();
}
jassert (oldest != nullptr);
oldest->lastAccessCount = accessCounter;
oldest->generate (font, glyphNumber);
oldest->draw (state, x, y);
}
private:
friend class OwnedArray <CachedGlyph>;
OwnedArray <CachedGlyph> glyphs;
int accessCounter, hits, misses;
void addNewGlyphSlots (int num)
{
while (--num >= 0)
glyphs.add (new CachedGlyph());
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GlyphCache);
};
juce_ImplementSingleton_SingleThreaded (LowLevelGraphicsSoftwareRenderer::GlyphCache);
void LowLevelGraphicsSoftwareRenderer::setFont (const Font& newFont)
{
currentState->font = newFont;
}
Font LowLevelGraphicsSoftwareRenderer::getFont()
{
return currentState->font;
}
void LowLevelGraphicsSoftwareRenderer::drawGlyph (int glyphNumber, const AffineTransform& transform)
{
Font& f = currentState->font;
if (transform.isOnlyTranslation() && currentState->isOnlyTranslated)
{
GlyphCache::getInstance()->drawGlyph (*currentState, f, glyphNumber,
transform.getTranslationX(),
transform.getTranslationY());
GlyphCache <CachedGlyphEdgeTable, SavedState>::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)

View file

@ -95,12 +95,11 @@ protected:
//==============================================================================
Image image;
class GlyphCache;
class CachedGlyph;
class SavedState;
friend class ScopedPointer <SavedState>;
friend class OwnedArray <SavedState>;
friend class OwnedArray <CachedGlyph>;
#ifndef DOXYGEN
public: class SavedState;
private:
#endif
ScopedPointer <SavedState> currentState;
OwnedArray <SavedState> stateStack;

View file

@ -177,8 +177,8 @@ namespace OpenGLGradientHelpers
+ 8.0f;
const AffineTransform inverse (transform.inverted());
const float renderingRadius = jmax (Point<float> (screenRadius, 0.0f).transformedBy (inverse).getDistanceFromOrigin(),
Point<float> (0.0f, screenRadius).transformedBy (inverse).getDistanceFromOrigin());
const float sourceRadius = jmax (Point<float> (screenRadius, 0.0f).transformedBy (inverse).getDistanceFromOrigin(),
Point<float> (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<float> first (grad.point1.translated (renderingRadius, -renderingRadius).transformedBy (transform));
const Point<float> first (grad.point1.translated (sourceRadius, -sourceRadius).transformedBy (transform));
Point<float> last (first);
for (int i = 0; i < numDivisions; ++i)
{
const float angle = (i + 1) * (float_Pi * 4.0f / numDivisions);
const Point<float> next (grad.point1.translated (std::sin (angle) * renderingRadius,
-std::cos (angle) * renderingRadius)
const Point<float> next (grad.point1.translated (std::sin (angle) * sourceRadius,
std::cos (angle) * -sourceRadius)
.transformedBy (transform));
*v++ = last.getX();
*v++ = last.getY();