@@ -147,7 +147,7 @@ | |||||
843796670EFBF357002A2725 /* MusicDeviceBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MusicDeviceBase.cpp; path = Examples/CoreAudio/AudioUnits/AUPublic/OtherBases/MusicDeviceBase.cpp; sourceTree = DEVELOPER_DIR; }; | 843796670EFBF357002A2725 /* MusicDeviceBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MusicDeviceBase.cpp; path = Examples/CoreAudio/AudioUnits/AUPublic/OtherBases/MusicDeviceBase.cpp; sourceTree = DEVELOPER_DIR; }; | ||||
843796680EFBF357002A2725 /* MusicDeviceBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MusicDeviceBase.h; path = Examples/CoreAudio/AudioUnits/AUPublic/OtherBases/MusicDeviceBase.h; sourceTree = DEVELOPER_DIR; }; | 843796680EFBF357002A2725 /* MusicDeviceBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MusicDeviceBase.h; path = Examples/CoreAudio/AudioUnits/AUPublic/OtherBases/MusicDeviceBase.h; sourceTree = DEVELOPER_DIR; }; | ||||
8437967D0EFBF5E4002A2725 /* juce_VST_Wrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_VST_Wrapper.cpp; path = ../../../wrapper/VST/juce_VST_Wrapper.cpp; sourceTree = SOURCE_ROOT; }; | 8437967D0EFBF5E4002A2725 /* juce_VST_Wrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_VST_Wrapper.cpp; path = ../../../wrapper/VST/juce_VST_Wrapper.cpp; sourceTree = SOURCE_ROOT; }; | ||||
8437967E0EFBF5E4002A2725 /* juce_VST_Wrapper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = juce_VST_Wrapper.mm; path = ../../../wrapper/VST/juce_VST_Wrapper.mm; sourceTree = SOURCE_ROOT; }; | |||||
8437967E0EFBF5E4002A2725 /* juce_VST_Wrapper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 2; name = juce_VST_Wrapper.mm; path = ../../../wrapper/VST/juce_VST_Wrapper.mm; sourceTree = SOURCE_ROOT; }; | |||||
843796D50EFBFD16002A2725 /* juce_RTAS_DigiCode1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_RTAS_DigiCode1.cpp; path = ../../../wrapper/RTAS/juce_RTAS_DigiCode1.cpp; sourceTree = SOURCE_ROOT; }; | 843796D50EFBFD16002A2725 /* juce_RTAS_DigiCode1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_RTAS_DigiCode1.cpp; path = ../../../wrapper/RTAS/juce_RTAS_DigiCode1.cpp; sourceTree = SOURCE_ROOT; }; | ||||
843796D60EFBFD16002A2725 /* juce_RTAS_DigiCode2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_RTAS_DigiCode2.cpp; path = ../../../wrapper/RTAS/juce_RTAS_DigiCode2.cpp; sourceTree = SOURCE_ROOT; }; | 843796D60EFBFD16002A2725 /* juce_RTAS_DigiCode2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_RTAS_DigiCode2.cpp; path = ../../../wrapper/RTAS/juce_RTAS_DigiCode2.cpp; sourceTree = SOURCE_ROOT; }; | ||||
843796D70EFBFD16002A2725 /* juce_RTAS_DigiCode3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_RTAS_DigiCode3.cpp; path = ../../../wrapper/RTAS/juce_RTAS_DigiCode3.cpp; sourceTree = SOURCE_ROOT; }; | 843796D70EFBFD16002A2725 /* juce_RTAS_DigiCode3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_RTAS_DigiCode3.cpp; path = ../../../wrapper/RTAS/juce_RTAS_DigiCode3.cpp; sourceTree = SOURCE_ROOT; }; | ||||
@@ -23331,6 +23331,8 @@ void AudioDeviceManager::stopDevice() | |||||
{ | { | ||||
if (currentAudioDevice != 0) | if (currentAudioDevice != 0) | ||||
currentAudioDevice->stop(); | currentAudioDevice->stop(); | ||||
deleteAndZero (testSound); | |||||
} | } | ||||
void AudioDeviceManager::closeAudioDevice() | void AudioDeviceManager::closeAudioDevice() | ||||
@@ -79837,6 +79839,15 @@ END_JUCE_NAMESPACE | |||||
BEGIN_JUCE_NAMESPACE | BEGIN_JUCE_NAMESPACE | ||||
Drawable::RenderingContext::RenderingContext (Graphics& g_, | |||||
const AffineTransform& transform_, | |||||
const float opacity_) throw() | |||||
: g (g_), | |||||
transform (transform_), | |||||
opacity (opacity_) | |||||
{ | |||||
} | |||||
Drawable::Drawable() | Drawable::Drawable() | ||||
{ | { | ||||
} | } | ||||
@@ -79845,6 +79856,13 @@ Drawable::~Drawable() | |||||
{ | { | ||||
} | } | ||||
void Drawable::draw (Graphics& g, | |||||
const AffineTransform& transform) const | |||||
{ | |||||
const RenderingContext context (g, transform, g.getCurrentColour().getFloatAlpha()); | |||||
draw (context); | |||||
} | |||||
void Drawable::drawAt (Graphics& g, const float x, const float y) const | void Drawable::drawAt (Graphics& g, const float x, const float y) const | ||||
{ | { | ||||
draw (g, AffineTransform::translation (x, y)); | draw (g, AffineTransform::translation (x, y)); | ||||
@@ -79984,14 +80002,45 @@ void DrawableComposite::bringToFront (const int index) | |||||
} | } | ||||
} | } | ||||
void DrawableComposite::draw (Graphics& g, const AffineTransform& transform) const | |||||
void DrawableComposite::draw (const Drawable::RenderingContext& context) const | |||||
{ | { | ||||
for (int i = 0; i < drawables.size(); ++i) | |||||
if (drawables.size() > 1) | |||||
{ | { | ||||
const AffineTransform* const t = transforms.getUnchecked(i); | |||||
Drawable::RenderingContext contextCopy (context); | |||||
if (context.opacity >= 1.0f) | |||||
{ | |||||
for (int i = 0; i < drawables.size(); ++i) | |||||
{ | |||||
const AffineTransform* const t = transforms.getUnchecked(i); | |||||
contextCopy.transform = (t == 0) ? context.transform | |||||
: t->followedBy (context.transform); | |||||
drawables.getUnchecked(i)->draw (context); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
// To correctly render a whole composite layer with an overall transparency, | |||||
// we need to render everything opaquely into a temp buffer, then blend that | |||||
// with the target opacity... | |||||
const Rectangle clipBounds (context.g.getClipBounds()); | |||||
Image tempImage (Image::ARGB, clipBounds.getWidth(), clipBounds.getHeight(), true); | |||||
{ | |||||
Graphics tempG (tempImage); | |||||
tempG.setOrigin (-clipBounds.getX(), -clipBounds.getY()); | |||||
Drawable::RenderingContext tempContext (tempG, context.transform, 1.0f); | |||||
draw (tempContext); | |||||
} | |||||
drawables.getUnchecked(i)->draw (g, t == 0 ? transform | |||||
: t->followedBy (transform)); | |||||
context.g.setOpacity (context.opacity); | |||||
context.g.drawImageAt (&tempImage, clipBounds.getX(), clipBounds.getY()); | |||||
} | |||||
} | |||||
else if (drawables.size() > 0) | |||||
{ | |||||
drawables.getUnchecked(0)->draw (context); | |||||
} | } | ||||
} | } | ||||
@@ -80112,31 +80161,25 @@ void DrawableImage::setOverlayColour (const Colour& newOverlayColour) | |||||
overlayColour = newOverlayColour; | overlayColour = newOverlayColour; | ||||
} | } | ||||
void DrawableImage::draw (Graphics& g, const AffineTransform& transform) const | |||||
void DrawableImage::draw (const Drawable::RenderingContext& context) const | |||||
{ | { | ||||
if (image != 0) | if (image != 0) | ||||
{ | { | ||||
const Colour oldColour (g.getCurrentColour()); // save this so we can restore it later | |||||
if (opacity > 0.0f && ! overlayColour.isOpaque()) | if (opacity > 0.0f && ! overlayColour.isOpaque()) | ||||
{ | { | ||||
g.setColour (oldColour.withMultipliedAlpha (opacity)); | |||||
g.drawImageTransformed (image, | |||||
0, 0, image->getWidth(), image->getHeight(), | |||||
transform, false); | |||||
context.g.setOpacity (context.opacity * opacity); | |||||
context.g.drawImageTransformed (image, | |||||
0, 0, image->getWidth(), image->getHeight(), | |||||
context.transform, false); | |||||
} | } | ||||
if (! overlayColour.isTransparent()) | if (! overlayColour.isTransparent()) | ||||
{ | { | ||||
g.setColour (overlayColour.withMultipliedAlpha (oldColour.getFloatAlpha())); | |||||
g.drawImageTransformed (image, | |||||
0, 0, image->getWidth(), image->getHeight(), | |||||
transform, true); | |||||
context.g.setColour (overlayColour.withMultipliedAlpha (context.opacity)); | |||||
context.g.drawImageTransformed (image, | |||||
0, 0, image->getWidth(), image->getHeight(), | |||||
context.transform, true); | |||||
} | } | ||||
g.setColour (oldColour); | |||||
} | } | ||||
} | } | ||||
@@ -80241,18 +80284,15 @@ void DrawablePath::setOutline (const PathStrokeType& strokeType_, const Brush& n | |||||
updateOutline(); | updateOutline(); | ||||
} | } | ||||
void DrawablePath::draw (Graphics& g, const AffineTransform& transform) const | |||||
void DrawablePath::draw (const Drawable::RenderingContext& context) const | |||||
{ | { | ||||
const Colour oldColour (g.getCurrentColour()); // save this so we can restore it later | |||||
const float currentOpacity = oldColour.getFloatAlpha(); | |||||
{ | { | ||||
Brush* const tempBrush = fillBrush->createCopy(); | Brush* const tempBrush = fillBrush->createCopy(); | ||||
tempBrush->applyTransform (transform); | |||||
tempBrush->multiplyOpacity (currentOpacity); | |||||
tempBrush->applyTransform (context.transform); | |||||
tempBrush->multiplyOpacity (context.opacity); | |||||
g.setBrush (tempBrush); | |||||
g.fillPath (path, transform); | |||||
context.g.setBrush (tempBrush); | |||||
context.g.fillPath (path, context.transform); | |||||
delete tempBrush; | delete tempBrush; | ||||
} | } | ||||
@@ -80260,16 +80300,14 @@ void DrawablePath::draw (Graphics& g, const AffineTransform& transform) const | |||||
if (strokeBrush != 0 && strokeType.getStrokeThickness() > 0.0f) | if (strokeBrush != 0 && strokeType.getStrokeThickness() > 0.0f) | ||||
{ | { | ||||
Brush* const tempBrush = strokeBrush->createCopy(); | Brush* const tempBrush = strokeBrush->createCopy(); | ||||
tempBrush->applyTransform (transform); | |||||
tempBrush->multiplyOpacity (currentOpacity); | |||||
tempBrush->applyTransform (context.transform); | |||||
tempBrush->multiplyOpacity (context.opacity); | |||||
g.setBrush (tempBrush); | |||||
g.fillPath (outline, transform); | |||||
context.g.setBrush (tempBrush); | |||||
context.g.fillPath (outline, context.transform); | |||||
delete tempBrush; | delete tempBrush; | ||||
} | } | ||||
g.setColour (oldColour); | |||||
} | } | ||||
void DrawablePath::updateOutline() | void DrawablePath::updateOutline() | ||||
@@ -80337,14 +80375,10 @@ void DrawableText::setColour (const Colour& newColour) | |||||
colour = newColour; | colour = newColour; | ||||
} | } | ||||
void DrawableText::draw (Graphics& g, const AffineTransform& transform) const | |||||
void DrawableText::draw (const Drawable::RenderingContext& context) const | |||||
{ | { | ||||
const Colour oldColour (g.getCurrentColour()); // save this so we can restore it later | |||||
g.setColour (colour.withMultipliedAlpha (oldColour.getFloatAlpha())); | |||||
text.draw (g, transform); | |||||
g.setColour (oldColour); | |||||
context.g.setColour (colour.withMultipliedAlpha (context.opacity)); | |||||
text.draw (context.g, context.transform); | |||||
} | } | ||||
void DrawableText::getBounds (float& x, float& y, float& width, float& height) const | void DrawableText::getBounds (float& x, float& y, float& width, float& height) const | ||||
@@ -38743,6 +38743,9 @@ public: | |||||
/** Destructor. */ | /** Destructor. */ | ||||
~GradientBrush() throw(); | ~GradientBrush() throw(); | ||||
/** Returns the current gradient information */ | |||||
const ColourGradient& getGradient() const throw() { return gradient; } | |||||
Brush* createCopy() const throw(); | Brush* createCopy() const throw(); | ||||
void applyTransform (const AffineTransform& transform) throw(); | void applyTransform (const AffineTransform& transform) throw(); | ||||
@@ -39056,6 +39059,18 @@ public: | |||||
/** Destructor. */ | /** Destructor. */ | ||||
~ImageBrush() throw(); | ~ImageBrush() throw(); | ||||
/** Returns the image currently being used. */ | |||||
Image* getImage() const throw() { return image; } | |||||
/** Returns the current anchor X position. */ | |||||
int getAnchorX() const throw() { return anchorX; } | |||||
/** Returns the current anchor Y position. */ | |||||
int getAnchorY() const throw() { return anchorY; } | |||||
/** Returns the current opacity. */ | |||||
float getOpacity() const throw() { return opacity; } | |||||
Brush* createCopy() const throw(); | Brush* createCopy() const throw(); | ||||
void applyTransform (const AffineTransform& transform) throw(); | void applyTransform (const AffineTransform& transform) throw(); | ||||
@@ -41135,13 +41150,10 @@ public: | |||||
virtual Drawable* createCopy() const = 0; | virtual Drawable* createCopy() const = 0; | ||||
/** Renders this Drawable object. | /** Renders this Drawable object. | ||||
This is the main rendering method you should call to render a Drawable. | |||||
@see drawWithin | @see drawWithin | ||||
*/ | */ | ||||
virtual void draw (Graphics& g, | |||||
const AffineTransform& transform = AffineTransform::identity) const = 0; | |||||
void draw (Graphics& g, | |||||
const AffineTransform& transform = AffineTransform::identity) const; | |||||
/** Renders the Drawable at a given offset within the Graphics context. | /** Renders the Drawable at a given offset within the Graphics context. | ||||
@@ -41177,6 +41189,24 @@ public: | |||||
const int destHeight, | const int destHeight, | ||||
const RectanglePlacement& placement) const; | const RectanglePlacement& placement) const; | ||||
/** Holds the information needed when telling a drawable to render itself. | |||||
@see Drawable::draw | |||||
*/ | |||||
class RenderingContext | |||||
{ | |||||
public: | |||||
RenderingContext (Graphics& g, const AffineTransform& transform, const float opacity) throw(); | |||||
Graphics& g; | |||||
AffineTransform transform; | |||||
float opacity; | |||||
}; | |||||
/** Renders this Drawable object. | |||||
@see drawWithin | |||||
*/ | |||||
virtual void draw (const RenderingContext& context) const = 0; | |||||
/** Returns the smallest rectangle that can contain this Drawable object. | /** Returns the smallest rectangle that can contain this Drawable object. | ||||
Co-ordinates are relative to the object's own origin. | Co-ordinates are relative to the object's own origin. | ||||
@@ -41345,7 +41375,7 @@ public: | |||||
void bringToFront (const int index); | void bringToFront (const int index); | ||||
/** @internal */ | /** @internal */ | ||||
void draw (Graphics& g, const AffineTransform& transform) const; | |||||
void draw (const Drawable::RenderingContext& context) const; | |||||
/** @internal */ | /** @internal */ | ||||
void getBounds (float& x, float& y, float& width, float& height) const; | void getBounds (float& x, float& y, float& width, float& height) const; | ||||
/** @internal */ | /** @internal */ | ||||
@@ -41440,7 +41470,7 @@ public: | |||||
const Colour& getOverlayColour() const throw() { return overlayColour; } | const Colour& getOverlayColour() const throw() { return overlayColour; } | ||||
/** @internal */ | /** @internal */ | ||||
void draw (Graphics& g, const AffineTransform& transform) const; | |||||
void draw (const Drawable::RenderingContext& context) const; | |||||
/** @internal */ | /** @internal */ | ||||
void getBounds (float& x, float& y, float& width, float& height) const; | void getBounds (float& x, float& y, float& width, float& height) const; | ||||
/** @internal */ | /** @internal */ | ||||
@@ -41540,7 +41570,7 @@ public: | |||||
Brush* getOutlineBrush() const throw() { return strokeBrush; } | Brush* getOutlineBrush() const throw() { return strokeBrush; } | ||||
/** @internal */ | /** @internal */ | ||||
void draw (Graphics& g, const AffineTransform& transform) const; | |||||
void draw (const Drawable::RenderingContext& context) const; | |||||
/** @internal */ | /** @internal */ | ||||
void getBounds (float& x, float& y, float& width, float& height) const; | void getBounds (float& x, float& y, float& width, float& height) const; | ||||
/** @internal */ | /** @internal */ | ||||
@@ -41608,7 +41638,7 @@ public: | |||||
const Colour& getColour() const throw() { return colour; } | const Colour& getColour() const throw() { return colour; } | ||||
/** @internal */ | /** @internal */ | ||||
void draw (Graphics& g, const AffineTransform& transform) const; | |||||
void draw (const Drawable::RenderingContext& context) const; | |||||
/** @internal */ | /** @internal */ | ||||
void getBounds (float& x, float& y, float& width, float& height) const; | void getBounds (float& x, float& y, float& width, float& height) const; | ||||
/** @internal */ | /** @internal */ | ||||
@@ -509,6 +509,8 @@ void AudioDeviceManager::stopDevice() | |||||
{ | { | ||||
if (currentAudioDevice != 0) | if (currentAudioDevice != 0) | ||||
currentAudioDevice->stop(); | currentAudioDevice->stop(); | ||||
deleteAndZero (testSound); | |||||
} | } | ||||
void AudioDeviceManager::closeAudioDevice() | void AudioDeviceManager::closeAudioDevice() | ||||
@@ -75,6 +75,10 @@ public: | |||||
/** Destructor. */ | /** Destructor. */ | ||||
~GradientBrush() throw(); | ~GradientBrush() throw(); | ||||
//============================================================================== | |||||
/** Returns the current gradient information */ | |||||
const ColourGradient& getGradient() const throw() { return gradient; } | |||||
//============================================================================== | //============================================================================== | ||||
Brush* createCopy() const throw(); | Brush* createCopy() const throw(); | ||||
@@ -54,6 +54,18 @@ public: | |||||
/** Destructor. */ | /** Destructor. */ | ||||
~ImageBrush() throw(); | ~ImageBrush() throw(); | ||||
//============================================================================== | |||||
/** Returns the image currently being used. */ | |||||
Image* getImage() const throw() { return image; } | |||||
/** Returns the current anchor X position. */ | |||||
int getAnchorX() const throw() { return anchorX; } | |||||
/** Returns the current anchor Y position. */ | |||||
int getAnchorY() const throw() { return anchorY; } | |||||
/** Returns the current opacity. */ | |||||
float getOpacity() const throw() { return opacity; } | |||||
//============================================================================== | //============================================================================== | ||||
Brush* createCopy() const throw(); | Brush* createCopy() const throw(); | ||||
@@ -33,6 +33,15 @@ BEGIN_JUCE_NAMESPACE | |||||
#include "../../../text/juce_XmlDocument.h" | #include "../../../text/juce_XmlDocument.h" | ||||
#include "../../../io/files/juce_FileInputStream.h" | #include "../../../io/files/juce_FileInputStream.h" | ||||
//============================================================================== | |||||
Drawable::RenderingContext::RenderingContext (Graphics& g_, | |||||
const AffineTransform& transform_, | |||||
const float opacity_) throw() | |||||
: g (g_), | |||||
transform (transform_), | |||||
opacity (opacity_) | |||||
{ | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
Drawable::Drawable() | Drawable::Drawable() | ||||
@@ -43,6 +52,13 @@ Drawable::~Drawable() | |||||
{ | { | ||||
} | } | ||||
void Drawable::draw (Graphics& g, | |||||
const AffineTransform& transform) const | |||||
{ | |||||
const RenderingContext context (g, transform, g.getCurrentColour().getFloatAlpha()); | |||||
draw (context); | |||||
} | |||||
void Drawable::drawAt (Graphics& g, const float x, const float y) const | void Drawable::drawAt (Graphics& g, const float x, const float y) const | ||||
{ | { | ||||
draw (g, AffineTransform::translation (x, y)); | draw (g, AffineTransform::translation (x, y)); | ||||
@@ -59,13 +59,10 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
/** Renders this Drawable object. | /** Renders this Drawable object. | ||||
This is the main rendering method you should call to render a Drawable. | |||||
@see drawWithin | @see drawWithin | ||||
*/ | */ | ||||
virtual void draw (Graphics& g, | |||||
const AffineTransform& transform = AffineTransform::identity) const = 0; | |||||
void draw (Graphics& g, | |||||
const AffineTransform& transform = AffineTransform::identity) const; | |||||
/** Renders the Drawable at a given offset within the Graphics context. | /** Renders the Drawable at a given offset within the Graphics context. | ||||
@@ -102,6 +99,25 @@ public: | |||||
const RectanglePlacement& placement) const; | const RectanglePlacement& placement) const; | ||||
//============================================================================== | |||||
/** Holds the information needed when telling a drawable to render itself. | |||||
@see Drawable::draw | |||||
*/ | |||||
class RenderingContext | |||||
{ | |||||
public: | |||||
RenderingContext (Graphics& g, const AffineTransform& transform, const float opacity) throw(); | |||||
Graphics& g; | |||||
AffineTransform transform; | |||||
float opacity; | |||||
}; | |||||
/** Renders this Drawable object. | |||||
@see drawWithin | |||||
*/ | |||||
virtual void draw (const RenderingContext& context) const = 0; | |||||
//============================================================================== | //============================================================================== | ||||
/** Returns the smallest rectangle that can contain this Drawable object. | /** Returns the smallest rectangle that can contain this Drawable object. | ||||
@@ -27,8 +27,8 @@ | |||||
BEGIN_JUCE_NAMESPACE | BEGIN_JUCE_NAMESPACE | ||||
#include "juce_DrawableComposite.h" | #include "juce_DrawableComposite.h" | ||||
#include "../imaging/juce_Image.h" | |||||
//============================================================================== | //============================================================================== | ||||
@@ -84,14 +84,45 @@ void DrawableComposite::bringToFront (const int index) | |||||
} | } | ||||
} | } | ||||
void DrawableComposite::draw (Graphics& g, const AffineTransform& transform) const | |||||
void DrawableComposite::draw (const Drawable::RenderingContext& context) const | |||||
{ | { | ||||
for (int i = 0; i < drawables.size(); ++i) | |||||
if (drawables.size() > 1) | |||||
{ | { | ||||
const AffineTransform* const t = transforms.getUnchecked(i); | |||||
Drawable::RenderingContext contextCopy (context); | |||||
drawables.getUnchecked(i)->draw (g, t == 0 ? transform | |||||
: t->followedBy (transform)); | |||||
if (context.opacity >= 1.0f) | |||||
{ | |||||
for (int i = 0; i < drawables.size(); ++i) | |||||
{ | |||||
const AffineTransform* const t = transforms.getUnchecked(i); | |||||
contextCopy.transform = (t == 0) ? context.transform | |||||
: t->followedBy (context.transform); | |||||
drawables.getUnchecked(i)->draw (context); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
// To correctly render a whole composite layer with an overall transparency, | |||||
// we need to render everything opaquely into a temp buffer, then blend that | |||||
// with the target opacity... | |||||
const Rectangle clipBounds (context.g.getClipBounds()); | |||||
Image tempImage (Image::ARGB, clipBounds.getWidth(), clipBounds.getHeight(), true); | |||||
{ | |||||
Graphics tempG (tempImage); | |||||
tempG.setOrigin (-clipBounds.getX(), -clipBounds.getY()); | |||||
Drawable::RenderingContext tempContext (tempG, context.transform, 1.0f); | |||||
draw (tempContext); | |||||
} | |||||
context.g.setOpacity (context.opacity); | |||||
context.g.drawImageAt (&tempImage, clipBounds.getX(), clipBounds.getY()); | |||||
} | |||||
} | |||||
else if (drawables.size() > 0) | |||||
{ | |||||
drawables.getUnchecked(0)->draw (context); | |||||
} | } | ||||
} | } | ||||
@@ -130,7 +130,7 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
/** @internal */ | /** @internal */ | ||||
void draw (Graphics& g, const AffineTransform& transform) const; | |||||
void draw (const Drawable::RenderingContext& context) const; | |||||
/** @internal */ | /** @internal */ | ||||
void getBounds (float& x, float& y, float& width, float& height) const; | void getBounds (float& x, float& y, float& width, float& height) const; | ||||
/** @internal */ | /** @internal */ | ||||
@@ -86,31 +86,25 @@ void DrawableImage::setOverlayColour (const Colour& newOverlayColour) | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
void DrawableImage::draw (Graphics& g, const AffineTransform& transform) const | |||||
void DrawableImage::draw (const Drawable::RenderingContext& context) const | |||||
{ | { | ||||
if (image != 0) | if (image != 0) | ||||
{ | { | ||||
const Colour oldColour (g.getCurrentColour()); // save this so we can restore it later | |||||
if (opacity > 0.0f && ! overlayColour.isOpaque()) | if (opacity > 0.0f && ! overlayColour.isOpaque()) | ||||
{ | { | ||||
g.setColour (oldColour.withMultipliedAlpha (opacity)); | |||||
g.drawImageTransformed (image, | |||||
0, 0, image->getWidth(), image->getHeight(), | |||||
transform, false); | |||||
context.g.setOpacity (context.opacity * opacity); | |||||
context.g.drawImageTransformed (image, | |||||
0, 0, image->getWidth(), image->getHeight(), | |||||
context.transform, false); | |||||
} | } | ||||
if (! overlayColour.isTransparent()) | if (! overlayColour.isTransparent()) | ||||
{ | { | ||||
g.setColour (overlayColour.withMultipliedAlpha (oldColour.getFloatAlpha())); | |||||
g.drawImageTransformed (image, | |||||
0, 0, image->getWidth(), image->getHeight(), | |||||
transform, true); | |||||
context.g.setColour (overlayColour.withMultipliedAlpha (context.opacity)); | |||||
context.g.drawImageTransformed (image, | |||||
0, 0, image->getWidth(), image->getHeight(), | |||||
context.transform, true); | |||||
} | } | ||||
g.setColour (oldColour); | |||||
} | } | ||||
} | } | ||||
@@ -100,7 +100,7 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
/** @internal */ | /** @internal */ | ||||
void draw (Graphics& g, const AffineTransform& transform) const; | |||||
void draw (const Drawable::RenderingContext& context) const; | |||||
/** @internal */ | /** @internal */ | ||||
void getBounds (float& x, float& y, float& width, float& height) const; | void getBounds (float& x, float& y, float& width, float& height) const; | ||||
/** @internal */ | /** @internal */ | ||||
@@ -83,18 +83,15 @@ void DrawablePath::setOutline (const PathStrokeType& strokeType_, const Brush& n | |||||
//============================================================================== | //============================================================================== | ||||
void DrawablePath::draw (Graphics& g, const AffineTransform& transform) const | |||||
void DrawablePath::draw (const Drawable::RenderingContext& context) const | |||||
{ | { | ||||
const Colour oldColour (g.getCurrentColour()); // save this so we can restore it later | |||||
const float currentOpacity = oldColour.getFloatAlpha(); | |||||
{ | { | ||||
Brush* const tempBrush = fillBrush->createCopy(); | Brush* const tempBrush = fillBrush->createCopy(); | ||||
tempBrush->applyTransform (transform); | |||||
tempBrush->multiplyOpacity (currentOpacity); | |||||
tempBrush->applyTransform (context.transform); | |||||
tempBrush->multiplyOpacity (context.opacity); | |||||
g.setBrush (tempBrush); | |||||
g.fillPath (path, transform); | |||||
context.g.setBrush (tempBrush); | |||||
context.g.fillPath (path, context.transform); | |||||
delete tempBrush; | delete tempBrush; | ||||
} | } | ||||
@@ -102,16 +99,14 @@ void DrawablePath::draw (Graphics& g, const AffineTransform& transform) const | |||||
if (strokeBrush != 0 && strokeType.getStrokeThickness() > 0.0f) | if (strokeBrush != 0 && strokeType.getStrokeThickness() > 0.0f) | ||||
{ | { | ||||
Brush* const tempBrush = strokeBrush->createCopy(); | Brush* const tempBrush = strokeBrush->createCopy(); | ||||
tempBrush->applyTransform (transform); | |||||
tempBrush->multiplyOpacity (currentOpacity); | |||||
tempBrush->applyTransform (context.transform); | |||||
tempBrush->multiplyOpacity (context.opacity); | |||||
g.setBrush (tempBrush); | |||||
g.fillPath (outline, transform); | |||||
context.g.setBrush (tempBrush); | |||||
context.g.fillPath (outline, context.transform); | |||||
delete tempBrush; | delete tempBrush; | ||||
} | } | ||||
g.setColour (oldColour); | |||||
} | } | ||||
void DrawablePath::updateOutline() | void DrawablePath::updateOutline() | ||||
@@ -104,7 +104,7 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
/** @internal */ | /** @internal */ | ||||
void draw (Graphics& g, const AffineTransform& transform) const; | |||||
void draw (const Drawable::RenderingContext& context) const; | |||||
/** @internal */ | /** @internal */ | ||||
void getBounds (float& x, float& y, float& width, float& height) const; | void getBounds (float& x, float& y, float& width, float& height) const; | ||||
/** @internal */ | /** @internal */ | ||||
@@ -59,14 +59,10 @@ void DrawableText::setColour (const Colour& newColour) | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
void DrawableText::draw (Graphics& g, const AffineTransform& transform) const | |||||
void DrawableText::draw (const Drawable::RenderingContext& context) const | |||||
{ | { | ||||
const Colour oldColour (g.getCurrentColour()); // save this so we can restore it later | |||||
g.setColour (colour.withMultipliedAlpha (oldColour.getFloatAlpha())); | |||||
text.draw (g, transform); | |||||
g.setColour (oldColour); | |||||
context.g.setColour (colour.withMultipliedAlpha (context.opacity)); | |||||
text.draw (context.g, context.transform); | |||||
} | } | ||||
void DrawableText::getBounds (float& x, float& y, float& width, float& height) const | void DrawableText::getBounds (float& x, float& y, float& width, float& height) const | ||||
@@ -70,7 +70,7 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
/** @internal */ | /** @internal */ | ||||
void draw (Graphics& g, const AffineTransform& transform) const; | |||||
void draw (const Drawable::RenderingContext& context) const; | |||||
/** @internal */ | /** @internal */ | ||||
void getBounds (float& x, float& y, float& width, float& height) const; | void getBounds (float& x, float& y, float& width, float& height) const; | ||||
/** @internal */ | /** @internal */ | ||||