1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-29 02:40:05 +00:00

Refactored some lowlevelgraphicscontext classes to remove duplicated code.

This commit is contained in:
jules 2013-07-30 09:59:03 +01:00
parent c2afa62696
commit 32c98223ac
6 changed files with 105 additions and 195 deletions

View file

@ -46,6 +46,8 @@ public:
//==============================================================================
/** Creates a WaitableEvent object.
The object is initially in an unsignalled state.
@param manualReset If this is false, the event will be reset automatically when the wait()
method is called. If manualReset is true, then once the event is signalled,
the only way to reset it will be by calling the reset() method.

View file

@ -23,126 +23,16 @@
*/
LowLevelGraphicsSoftwareRenderer::LowLevelGraphicsSoftwareRenderer (const Image& image)
: savedState (new RenderingHelpers::SoftwareRendererSavedState (image, image.getBounds()))
: RenderingHelpers::StackBasedLowLevelGraphicsContext<RenderingHelpers::SoftwareRendererSavedState>
(new RenderingHelpers::SoftwareRendererSavedState (image, image.getBounds()))
{
}
LowLevelGraphicsSoftwareRenderer::LowLevelGraphicsSoftwareRenderer (const Image& image, Point<int> origin,
const RectangleList<int>& initialClip)
: savedState (new RenderingHelpers::SoftwareRendererSavedState (image, initialClip, origin.x, origin.y))
: RenderingHelpers::StackBasedLowLevelGraphicsContext<RenderingHelpers::SoftwareRendererSavedState>
(new RenderingHelpers::SoftwareRendererSavedState (image, initialClip, origin.x, origin.y))
{
}
LowLevelGraphicsSoftwareRenderer::~LowLevelGraphicsSoftwareRenderer() {}
//==============================================================================
bool LowLevelGraphicsSoftwareRenderer::isVectorDevice() const { return false; }
void LowLevelGraphicsSoftwareRenderer::setOrigin (int x, int y) { savedState->transform.setOrigin (x, y); }
void LowLevelGraphicsSoftwareRenderer::addTransform (const AffineTransform& t) { savedState->transform.addTransform (t); }
float LowLevelGraphicsSoftwareRenderer::getScaleFactor() { return savedState->transform.getScaleFactor(); }
Rectangle<int> LowLevelGraphicsSoftwareRenderer::getClipBounds() const { return savedState->getClipBounds(); }
bool LowLevelGraphicsSoftwareRenderer::isClipEmpty() const { return savedState->clip == nullptr; }
bool LowLevelGraphicsSoftwareRenderer::clipToRectangle (const Rectangle<int>& r) { return savedState->clipToRectangle (r); }
bool LowLevelGraphicsSoftwareRenderer::clipToRectangleList (const RectangleList<int>& r) { return savedState->clipToRectangleList (r); }
void LowLevelGraphicsSoftwareRenderer::excludeClipRectangle (const Rectangle<int>& r) { savedState->excludeClipRectangle (r); }
void LowLevelGraphicsSoftwareRenderer::clipToPath (const Path& path, const AffineTransform& transform)
{
savedState->clipToPath (path, transform);
}
void LowLevelGraphicsSoftwareRenderer::clipToImageAlpha (const Image& sourceImage, const AffineTransform& transform)
{
savedState->clipToImageAlpha (sourceImage, transform);
}
bool LowLevelGraphicsSoftwareRenderer::clipRegionIntersects (const Rectangle<int>& r)
{
return savedState->clipRegionIntersects (r);
}
//==============================================================================
void LowLevelGraphicsSoftwareRenderer::saveState() { savedState.save(); }
void LowLevelGraphicsSoftwareRenderer::restoreState() { savedState.restore(); }
void LowLevelGraphicsSoftwareRenderer::beginTransparencyLayer (float opacity) { savedState.beginTransparencyLayer (opacity); }
void LowLevelGraphicsSoftwareRenderer::endTransparencyLayer() { savedState.endTransparencyLayer(); }
//==============================================================================
void LowLevelGraphicsSoftwareRenderer::setFill (const FillType& fillType)
{
savedState->fillType = fillType;
}
void LowLevelGraphicsSoftwareRenderer::setOpacity (float newOpacity)
{
savedState->fillType.setOpacity (newOpacity);
}
void LowLevelGraphicsSoftwareRenderer::setInterpolationQuality (Graphics::ResamplingQuality quality)
{
savedState->interpolationQuality = quality;
}
//==============================================================================
void LowLevelGraphicsSoftwareRenderer::fillRect (const Rectangle<int>& r, const bool replaceExistingContents)
{
savedState->fillRect (r, replaceExistingContents);
}
void LowLevelGraphicsSoftwareRenderer::fillPath (const Path& path, const AffineTransform& transform)
{
savedState->fillPath (path, transform);
}
void LowLevelGraphicsSoftwareRenderer::drawImage (const Image& sourceImage, const AffineTransform& transform)
{
savedState->renderImage (sourceImage, transform, nullptr);
}
void LowLevelGraphicsSoftwareRenderer::drawLine (const Line <float>& line)
{
Path p;
p.addLineSegment (line, 1.0f);
fillPath (p, AffineTransform::identity);
}
void LowLevelGraphicsSoftwareRenderer::drawVerticalLine (const int x, const float top, const float bottom)
{
if (bottom > top)
savedState->fillRect (Rectangle<float> ((float) x, top, 1.0f, bottom - top));
}
void LowLevelGraphicsSoftwareRenderer::drawHorizontalLine (const int y, const float left, const float right)
{
if (right > left)
savedState->fillRect (Rectangle<float> (left, (float) y, right - left, 1.0f));
}
void LowLevelGraphicsSoftwareRenderer::drawGlyph (int glyphNumber, const AffineTransform& transform)
{
const Font& f = savedState->font;
if (transform.isOnlyTranslation() && savedState->transform.isOnlyTranslated)
{
using namespace RenderingHelpers;
GlyphCache <CachedGlyphEdgeTable <SoftwareRendererSavedState>, SoftwareRendererSavedState>::getInstance()
.drawGlyph (*savedState, f, glyphNumber,
transform.getTranslationX(),
transform.getTranslationY());
}
else
{
const float fontHeight = f.getHeight();
savedState->drawGlyph (f, glyphNumber,
AffineTransform::scale (fontHeight * f.getHorizontalScale(), fontHeight)
.followedBy (transform));
}
}
void LowLevelGraphicsSoftwareRenderer::setFont (const Font& newFont) { savedState->font = newFont; }
const Font& LowLevelGraphicsSoftwareRenderer::getFont() { return savedState->font; }

View file

@ -36,57 +36,21 @@
User code is not supposed to create instances of this class directly - do all your
rendering via the Graphics class instead.
*/
class JUCE_API LowLevelGraphicsSoftwareRenderer : public LowLevelGraphicsContext
class JUCE_API LowLevelGraphicsSoftwareRenderer : public RenderingHelpers::StackBasedLowLevelGraphicsContext<RenderingHelpers::SoftwareRendererSavedState>
{
public:
//==============================================================================
/** Creates a context to render into an image. */
LowLevelGraphicsSoftwareRenderer (const Image& imageToRenderOnto);
/** Creates a context to render into a clipped subsection of an image. */
LowLevelGraphicsSoftwareRenderer (const Image& imageToRenderOnto, Point<int> origin,
const RectangleList<int>& initialClip);
/** Destructor. */
~LowLevelGraphicsSoftwareRenderer();
bool isVectorDevice() const override;
void setOrigin (int x, int y) override;
void addTransform (const AffineTransform&) override;
float getScaleFactor() override;
bool clipToRectangle (const Rectangle<int>&) override;
bool clipToRectangleList (const RectangleList<int>&) override;
void excludeClipRectangle (const Rectangle<int>&) override;
void clipToPath (const Path&, const AffineTransform&) override;
void clipToImageAlpha (const Image&, const AffineTransform&) override;
bool clipRegionIntersects (const Rectangle<int>&) override;
Rectangle<int> getClipBounds() const override;
bool isClipEmpty() const override;
void saveState() override;
void restoreState() override;
void beginTransparencyLayer (float opacity) override;
void endTransparencyLayer() override;
void setFill (const FillType&) override;
void setOpacity (float opacity) override;
void setInterpolationQuality (Graphics::ResamplingQuality) override;
void fillRect (const Rectangle<int>&, bool replaceExistingContents) override;
void fillPath (const Path&, const AffineTransform&) override;
void drawImage (const Image&, const AffineTransform&) override;
void drawLine (const Line <float>&) override;
void drawVerticalLine (int x, float top, float bottom) override;
void drawHorizontalLine (int x, float top, float bottom) override;
void setFont (const Font&) override;
const Font& getFont() override;
void drawGlyph (int glyphNumber, const AffineTransform&) override;
const Image& getImage() const noexcept { return savedState->image; }
const RenderingHelpers::TranslationOrTransform& getTransform() const noexcept { return savedState->transform; }
protected:
RenderingHelpers::SavedStateStack <RenderingHelpers::SoftwareRendererSavedState> savedState;
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LowLevelGraphicsSoftwareRenderer)
};

View file

@ -25,9 +25,9 @@
const int juce_edgeTableDefaultEdgesPerLine = 32;
//==============================================================================
EdgeTable::EdgeTable (const Rectangle<int>& bounds_,
EdgeTable::EdgeTable (const Rectangle<int>& area,
const Path& path, const AffineTransform& transform)
: bounds (bounds_),
: bounds (area),
maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine),
lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1),
needToCheckEmptinesss (true)

View file

@ -2216,6 +2216,11 @@ public:
}
//==============================================================================
void setFillType (const FillType& newFill)
{
fillType = newFill;
}
void fillTargetRect (const Rectangle<int>& r, const bool replaceContents)
{
if (fillType.isColour())
@ -2301,6 +2306,24 @@ public:
}
}
void drawGlyph (int glyphNumber, const AffineTransform& trans)
{
if (trans.isOnlyTranslation() && transform.isOnlyTranslated)
{
GlyphCache <CachedGlyphEdgeTable <SoftwareRendererSavedState>, SoftwareRendererSavedState>::getInstance()
.drawGlyph (*this, font, glyphNumber,
trans.getTranslationX(),
trans.getTranslationY());
}
else
{
const float fontHeight = font.getHeight();
drawGlyph (font, glyphNumber,
AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight)
.followedBy (trans));
}
}
void drawGlyph (const Font& f, int glyphNumber, const AffineTransform& t)
{
if (clip != nullptr)
@ -2353,7 +2376,19 @@ public:
}
}
void drawLine (const Line <float>& line)
{
Path p;
p.addLineSegment (line, 1.0f);
fillPath (p, AffineTransform::identity);
}
//==============================================================================
void drawImage (const Image& sourceImage, const AffineTransform& trans)
{
renderImage (sourceImage, trans, nullptr);
}
void renderImage (const Image& sourceImage, const AffineTransform& trans,
const ClipRegions::Base* const tiledFillClipRegion)
{
@ -2445,6 +2480,13 @@ public:
: currentState (initialState)
{}
SavedStateStack() noexcept {}
void initialise (StateObjectType* state)
{
currentState = state;
}
inline StateObjectType* operator->() const noexcept { return currentState; }
inline StateObjectType& operator*() const noexcept { return *currentState; }
@ -2486,6 +2528,47 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SavedStateStack)
};
//==============================================================================
template <class SavedStateType>
class StackBasedLowLevelGraphicsContext : public LowLevelGraphicsContext
{
public:
bool isVectorDevice() const override { return false; }
void setOrigin (int x, int y) override { stack->transform.setOrigin (x, y); }
void addTransform (const AffineTransform& t) override { stack->transform.addTransform (t); }
float getScaleFactor() override { return stack->transform.getScaleFactor(); }
Rectangle<int> getClipBounds() const override { return stack->getClipBounds(); }
bool isClipEmpty() const override { return stack->clip == nullptr; }
bool clipRegionIntersects (const Rectangle<int>& r) override { return stack->clipRegionIntersects (r); }
bool clipToRectangle (const Rectangle<int>& r) override { return stack->clipToRectangle (r); }
bool clipToRectangleList (const RectangleList<int>& r) override { return stack->clipToRectangleList (r); }
void excludeClipRectangle (const Rectangle<int>& r) override { stack->excludeClipRectangle (r); }
void clipToPath (const Path& path, const AffineTransform& t) override { stack->clipToPath (path, t); }
void clipToImageAlpha (const Image& im, const AffineTransform& t) override { stack->clipToImageAlpha (im, t); }
void saveState() override { stack.save(); }
void restoreState() override { stack.restore(); }
void beginTransparencyLayer (float opacity) override { stack.beginTransparencyLayer (opacity); }
void endTransparencyLayer() override { stack.endTransparencyLayer(); }
void setFill (const FillType& fillType) override { stack->setFillType (fillType); }
void setOpacity (float newOpacity) override { stack->fillType.setOpacity (newOpacity); }
void setInterpolationQuality (Graphics::ResamplingQuality quality) override { stack->interpolationQuality = quality; }
void fillRect (const Rectangle<int>& r, bool replace) override { stack->fillRect (r, replace); }
void fillPath (const Path& path, const AffineTransform& t) override { stack->fillPath (path, t); }
void drawImage (const Image& im, const AffineTransform& t) override { stack->drawImage (im, t); }
void drawVerticalLine (int x, float top, float bottom) override { if (top < bottom) stack->fillRect (Rectangle<float> ((float) x, top, 1.0f, bottom - top)); }
void drawHorizontalLine (int y, float left, float right) override { if (left < right) stack->fillRect (Rectangle<float> (left, (float) y, right - left, 1.0f)); }
void drawGlyph (int glyphNumber, const AffineTransform& t) override { stack->drawGlyph (glyphNumber, t); }
void drawLine (const Line <float>& line) override { stack->drawLine (line); }
void setFont (const Font& newFont) override { stack->font = newFont; }
const Font& getFont() override { return stack->font; }
protected:
StackBasedLowLevelGraphicsContext (SavedStateType* initialState) : stack (initialState) {}
StackBasedLowLevelGraphicsContext() {}
RenderingHelpers::SavedStateStack<SavedStateType> stack;
};
}
#if JUCE_MSVC

View file

@ -2109,45 +2109,16 @@ private:
};
//==============================================================================
class ShaderContext : public LowLevelGraphicsContext
class ShaderContext : public RenderingHelpers::StackBasedLowLevelGraphicsContext <SavedState>
{
public:
ShaderContext (const Target& target)
: glState (target), stack (new SavedState (&glState))
{}
bool isVectorDevice() const { return false; }
void setOrigin (int x, int y) { stack->transform.setOrigin (x, y); }
void addTransform (const AffineTransform& t) { stack->transform.addTransform (t); }
float getScaleFactor() { return stack->transform.getScaleFactor(); }
Rectangle<int> getClipBounds() const { return stack->getClipBounds(); }
bool isClipEmpty() const { return stack->clip == nullptr; }
bool clipRegionIntersects (const Rectangle<int>& r) { return stack->clipRegionIntersects (r); }
bool clipToRectangle (const Rectangle<int>& r) { return stack->clipToRectangle (r); }
bool clipToRectangleList (const RectangleList<int>& r) { return stack->clipToRectangleList (r); }
void excludeClipRectangle (const Rectangle<int>& r) { stack->excludeClipRectangle (r); }
void clipToPath (const Path& path, const AffineTransform& t) { stack->clipToPath (path, t); }
void clipToImageAlpha (const Image& im, const AffineTransform& t) { stack->clipToImageAlpha (im, t); }
void saveState() { stack.save(); }
void restoreState() { stack.restore(); }
void beginTransparencyLayer (float opacity) { stack.beginTransparencyLayer (opacity); }
void endTransparencyLayer() { stack.endTransparencyLayer(); }
void setFill (const FillType& fillType) { stack->setFillType (fillType); }
void setOpacity (float newOpacity) { stack->fillType.setOpacity (newOpacity); }
void setInterpolationQuality (Graphics::ResamplingQuality quality) { stack->interpolationQuality = quality; }
void fillRect (const Rectangle<int>& r, bool replace) { stack->fillRect (r, replace); }
void fillPath (const Path& path, const AffineTransform& t) { stack->fillPath (path, t); }
void drawImage (const Image& im, const AffineTransform& t) { stack->drawImage (im, t); }
void drawVerticalLine (int x, float top, float bottom) { if (top < bottom) stack->fillRect (Rectangle<float> ((float) x, top, 1.0f, bottom - top)); }
void drawHorizontalLine (int y, float left, float right) { if (left < right) stack->fillRect (Rectangle<float> (left, (float) y, right - left, 1.0f)); }
void drawGlyph (int glyphNumber, const AffineTransform& t) { stack->drawGlyph (glyphNumber, t); }
void drawLine (const Line <float>& line) { stack->drawLine (line); }
void setFont (const Font& newFont) { stack->font = newFont; }
const Font& getFont() { return stack->font; }
ShaderContext (const Target& target) : glState (target)
{
stack.initialise (new SavedState (&glState));
}
private:
GLState glState;
RenderingHelpers::SavedStateStack<SavedState> stack;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ShaderContext)
};
@ -2157,8 +2128,8 @@ private:
class NonShaderContext : public LowLevelGraphicsSoftwareRenderer
{
public:
NonShaderContext (const Target& target_, const Image& image_)
: LowLevelGraphicsSoftwareRenderer (image_), target (target_), image (image_)
NonShaderContext (const Target& t, const Image& im)
: LowLevelGraphicsSoftwareRenderer (im), target (t), image (im)
{}
~NonShaderContext()