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:
parent
c2afa62696
commit
32c98223ac
6 changed files with 105 additions and 195 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue