mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-24 01:54:22 +00:00
Created a new method Graphics::beginTransparencyLayer(), to help with compositing semi-transparent rendering.
This commit is contained in:
parent
640a335537
commit
1629f9f66a
20 changed files with 1202 additions and 993 deletions
1576
juce_amalgamated.cpp
1576
juce_amalgamated.cpp
File diff suppressed because it is too large
Load diff
|
|
@ -64,7 +64,7 @@
|
|||
*/
|
||||
#define JUCE_MAJOR_VERSION 1
|
||||
#define JUCE_MINOR_VERSION 52
|
||||
#define JUCE_BUILDNUMBER 95
|
||||
#define JUCE_BUILDNUMBER 97
|
||||
|
||||
/** Current Juce version number.
|
||||
|
||||
|
|
@ -4764,7 +4764,7 @@ public:
|
|||
if (howManyToRemove > numUsed)
|
||||
howManyToRemove = numUsed;
|
||||
|
||||
for (int i = 0; i < howManyToRemove; ++i)
|
||||
for (int i = 1; i <= howManyToRemove; ++i)
|
||||
data.elements [numUsed - i].~ElementType();
|
||||
|
||||
numUsed -= howManyToRemove;
|
||||
|
|
@ -19586,11 +19586,12 @@ public:
|
|||
float pivotX, float pivotY) throw();
|
||||
|
||||
/** Returns a transform which is the same as this one followed by a shear.
|
||||
|
||||
The shear is centred around the origin (0, 0).
|
||||
*/
|
||||
const AffineTransform sheared (float shearX,
|
||||
float shearY) const throw();
|
||||
const AffineTransform sheared (float shearX, float shearY) const throw();
|
||||
|
||||
/** Returns a shear transform, centred around the origin (0, 0). */
|
||||
static const AffineTransform shear (float shearX, float shearY) throw();
|
||||
|
||||
/** Returns a matrix which is the inverse operation of this one.
|
||||
|
||||
|
|
@ -19648,11 +19649,6 @@ public:
|
|||
float mat10, mat11, mat12;
|
||||
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
private:
|
||||
|
||||
const AffineTransform followedBy (float mat00, float mat01, float mat02,
|
||||
float mat10, float mat11, float mat12) const throw();
|
||||
};
|
||||
|
||||
#endif // __JUCE_AFFINETRANSFORM_JUCEHEADER__
|
||||
|
|
@ -24949,6 +24945,23 @@ public:
|
|||
*/
|
||||
void restoreState();
|
||||
|
||||
/** Begins rendering to an off-screen bitmap which will later be flattened onto the current
|
||||
context with the given opacity.
|
||||
|
||||
The context uses an internal stack of temporary image layers to do this. When you've
|
||||
finished drawing to the layer, call endTransparencyLayer() to complete the operation and
|
||||
composite the finished layer. Every call to beginTransparencyLayer() MUST be matched
|
||||
by a corresponding call to endTransparencyLayer()!
|
||||
|
||||
This call also saves the current state, and endTransparencyLayer() restores it.
|
||||
*/
|
||||
void beginTransparencyLayer (float layerOpacity);
|
||||
|
||||
/** Completes a drawing operation to a temporary semi-transparent buffer.
|
||||
See beginTransparencyLayer() for more details.
|
||||
*/
|
||||
void endTransparencyLayer();
|
||||
|
||||
/** Moves the position of the context's origin.
|
||||
|
||||
This changes the position that the context considers to be (0, 0) to
|
||||
|
|
@ -26182,6 +26195,15 @@ public:
|
|||
*/
|
||||
const Rectangle<int> getLocalBounds() const throw();
|
||||
|
||||
/** Returns the area of this component's parent which this component covers.
|
||||
|
||||
The returned area is relative to the parent's coordinate space.
|
||||
If the component has an affine transform specified, then the resulting area will be
|
||||
the smallest rectangle that fully covers the component's transformed bounding box.
|
||||
If this component has no parent, the return value will simply be the same as getBounds().
|
||||
*/
|
||||
const Rectangle<int> getBoundsInParent() const throw();
|
||||
|
||||
/** Returns the region of this component that's not obscured by other, opaque components.
|
||||
|
||||
The RectangleList that is returned represents the area of this component
|
||||
|
|
@ -27136,7 +27158,18 @@ public:
|
|||
*/
|
||||
virtual void enablementChanged();
|
||||
|
||||
/** Changes the transparency of this component.
|
||||
When painted, the entire component and all its children will be rendered
|
||||
with this as the overall opacity level, where 0 is completely invisible, and
|
||||
1.0 is fully opaque (i.e. normal).
|
||||
|
||||
@see getAlpha
|
||||
*/
|
||||
void setAlpha (float newAlpha);
|
||||
|
||||
/** Returns the component's current transparancy level.
|
||||
See setAlpha() for more details.
|
||||
*/
|
||||
float getAlpha() const;
|
||||
|
||||
/** Changes the mouse cursor shape to use when the mouse is over this component.
|
||||
|
|
@ -37094,14 +37127,15 @@ public:
|
|||
This is the same as show(), but uses a specific location (in global screen
|
||||
co-ordinates) rather than the current mouse position.
|
||||
|
||||
Note that the co-ordinates don't specify the top-left of the menu - they
|
||||
indicate a point of interest, and the menu will position itself nearby to
|
||||
this point, trying to keep it fully on-screen.
|
||||
The screenAreaToAttachTo parameter indicates a screen area to which the menu
|
||||
will be adjacent. Depending on where this is, the menu will decide which edge to
|
||||
attach itself to, in order to fit itself fully on-screen. If you just want to
|
||||
trigger a menu at a specific point, you can pass in a rectangle of size (0, 0)
|
||||
with the position that you want.
|
||||
|
||||
@see show()
|
||||
*/
|
||||
int showAt (int screenX,
|
||||
int screenY,
|
||||
int showAt (const Rectangle<int>& screenAreaToAttachTo,
|
||||
int itemIdThatMustBeVisible = 0,
|
||||
int minimumWidth = 0,
|
||||
int maximumNumColumns = 0,
|
||||
|
|
@ -37229,14 +37263,9 @@ private:
|
|||
|
||||
void addSeparatorIfPending();
|
||||
|
||||
int showMenu (const Rectangle<int>& target,
|
||||
int itemIdThatMustBeVisible,
|
||||
int minimumWidth,
|
||||
int maximumNumColumns,
|
||||
int standardItemHeight,
|
||||
bool alignToRectangle,
|
||||
Component* componentAttachedTo,
|
||||
ModalComponentManager::Callback* callback);
|
||||
int showMenu (const Rectangle<int>& target, int itemIdThatMustBeVisible,
|
||||
int minimumWidth, int maximumNumColumns, int standardItemHeight,
|
||||
Component* componentAttachedTo, ModalComponentManager::Callback* callback);
|
||||
};
|
||||
|
||||
#endif // __JUCE_POPUPMENU_JUCEHEADER__
|
||||
|
|
@ -40605,6 +40634,12 @@ public:
|
|||
/** The name of the plugin. */
|
||||
String name;
|
||||
|
||||
/** A more descriptive name for the plugin.
|
||||
This may be the same as the 'name' field, but some plugins may provide an
|
||||
alternative name.
|
||||
*/
|
||||
String descriptiveName;
|
||||
|
||||
/** The plugin format, e.g. "VST", "AudioUnit", etc.
|
||||
*/
|
||||
String pluginFormatName;
|
||||
|
|
@ -44814,7 +44849,7 @@ class DrawableComposite;
|
|||
|
||||
@see DrawableComposite, DrawableImage, DrawablePath, DrawableText
|
||||
*/
|
||||
class JUCE_API Drawable
|
||||
class JUCE_API Drawable : public Component
|
||||
{
|
||||
protected:
|
||||
|
||||
|
|
@ -44835,6 +44870,11 @@ public:
|
|||
virtual Drawable* createCopy() const = 0;
|
||||
|
||||
/** Renders this Drawable object.
|
||||
|
||||
Note that the preferred way to render a drawable in future is by using it
|
||||
as a component and adding it to a parent, so you might want to consider that
|
||||
before using this method.
|
||||
|
||||
@see drawWithin
|
||||
*/
|
||||
void draw (Graphics& g, float opacity,
|
||||
|
|
@ -44848,10 +44888,12 @@ public:
|
|||
@code
|
||||
draw (g, AffineTransform::translation (x, y)).
|
||||
@endcode
|
||||
|
||||
Note that the preferred way to render a drawable in future is by using it
|
||||
as a component and adding it to a parent, so you might want to consider that
|
||||
before using this method.
|
||||
*/
|
||||
void drawAt (Graphics& g,
|
||||
float x, float y,
|
||||
float opacity) const;
|
||||
void drawAt (Graphics& g, float x, float y, float opacity) const;
|
||||
|
||||
/** Renders the Drawable within a rectangle, scaling it to fit neatly inside without
|
||||
changing its aspect-ratio.
|
||||
|
|
@ -44859,6 +44901,10 @@ public:
|
|||
The object can placed arbitrarily within the rectangle based on a Justification type,
|
||||
and can either be made as big as possible, or just reduced to fit.
|
||||
|
||||
Note that the preferred way to render a drawable in future is by using it
|
||||
as a component and adding it to a parent, so you might want to consider that
|
||||
before using this method.
|
||||
|
||||
@param g the graphics context to render onto
|
||||
@param destArea the target rectangle to fit the drawable into
|
||||
@param placement defines the alignment and rescaling to use to fit
|
||||
|
|
@ -44870,49 +44916,18 @@ public:
|
|||
const RectanglePlacement& placement,
|
||||
float opacity) const;
|
||||
|
||||
/** Holds the information needed when telling a drawable to render itself.
|
||||
@see Drawable::draw
|
||||
/** Resets any transformations on this drawable, and positions its origin within
|
||||
its parent component.
|
||||
*/
|
||||
class RenderingContext
|
||||
{
|
||||
public:
|
||||
RenderingContext (Graphics& g, const AffineTransform& transform, float opacity) throw();
|
||||
void setOriginWithOriginalSize (const Point<float>& originWithinParent);
|
||||
|
||||
Graphics& g;
|
||||
AffineTransform transform;
|
||||
float opacity;
|
||||
|
||||
private:
|
||||
RenderingContext& operator= (const RenderingContext&);
|
||||
};
|
||||
|
||||
/** Renders this Drawable object.
|
||||
@see draw
|
||||
/** Sets a transform for this drawable that will position it within the specified
|
||||
area of its parent component.
|
||||
*/
|
||||
virtual void render (const RenderingContext& context) const = 0;
|
||||
|
||||
/** Returns the smallest rectangle that can contain this Drawable object.
|
||||
|
||||
Co-ordinates are relative to the object's own origin.
|
||||
*/
|
||||
virtual const Rectangle<float> getBounds() const = 0;
|
||||
|
||||
/** Returns true if the given point is somewhere inside this Drawable.
|
||||
|
||||
Co-ordinates are relative to the object's own origin.
|
||||
*/
|
||||
virtual bool hitTest (float x, float y) const = 0;
|
||||
|
||||
/** Returns the name given to this drawable.
|
||||
@see setName
|
||||
*/
|
||||
const String& getName() const throw() { return name; }
|
||||
|
||||
/** Assigns a name to this drawable. */
|
||||
void setName (const String& newName) throw() { name = newName; }
|
||||
void setTransformToFit (const Rectangle<float>& areaInParent, const RectanglePlacement& placement);
|
||||
|
||||
/** Returns the DrawableComposite that contains this object, if there is one. */
|
||||
DrawableComposite* getParent() const throw() { return parent; }
|
||||
DrawableComposite* getParent() const;
|
||||
|
||||
/** Tries to turn some kind of image file into a drawable.
|
||||
|
||||
|
|
@ -44982,7 +44997,7 @@ public:
|
|||
/** Tries to refresh a Drawable from the same ValueTree that was used to create it.
|
||||
@returns the damage rectangle that will need repainting due to any changes that were made.
|
||||
*/
|
||||
virtual const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) = 0;
|
||||
virtual void refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) = 0;
|
||||
|
||||
/** Creates a ValueTree to represent this Drawable.
|
||||
The VarTree that is returned can be turned back into a Drawable with
|
||||
|
|
@ -44995,6 +45010,12 @@ public:
|
|||
/** Returns the tag ID that is used for a ValueTree that stores this type of drawable. */
|
||||
virtual const Identifier getValueTreeType() const = 0;
|
||||
|
||||
/** Returns the area that this drawble covers.
|
||||
The result is expressed in this drawable's own coordinate space, and does not take
|
||||
into account any transforms that may be applied to the component.
|
||||
*/
|
||||
virtual const Rectangle<float> getDrawableBounds() const = 0;
|
||||
|
||||
/** Internal class used to manage ValueTrees that represent Drawables. */
|
||||
class ValueTreeWrapperBase
|
||||
{
|
||||
|
|
@ -45015,15 +45036,23 @@ public:
|
|||
|
||||
protected:
|
||||
friend class DrawableComposite;
|
||||
/** @internal */
|
||||
DrawableComposite* parent;
|
||||
/** @internal */
|
||||
virtual void invalidatePoints() = 0;
|
||||
friend class DrawableShape;
|
||||
|
||||
/** @internal */
|
||||
static Drawable* createChildFromValueTree (DrawableComposite* parent, const ValueTree& tree, ImageProvider* imageProvider);
|
||||
/** @internal */
|
||||
void transformContextToCorrectOrigin (Graphics& g);
|
||||
/** @internal */
|
||||
void markerHasMoved();
|
||||
/** @internal */
|
||||
void parentHierarchyChanged();
|
||||
/** @internal */
|
||||
void setBoundsToEnclose (const Rectangle<float>& area);
|
||||
|
||||
Point<int> originRelativeToComponent;
|
||||
|
||||
private:
|
||||
String name;
|
||||
void nonConstDraw (Graphics& g, float opacity, const AffineTransform& transform);
|
||||
|
||||
Drawable (const Drawable&);
|
||||
Drawable& operator= (const Drawable&);
|
||||
|
|
@ -45143,10 +45172,10 @@ public:
|
|||
void setEdgeIndent (int numPixelsIndent);
|
||||
|
||||
/** Returns the image that the button is currently displaying. */
|
||||
const Drawable* getCurrentImage() const throw();
|
||||
const Drawable* getNormalImage() const throw();
|
||||
const Drawable* getOverImage() const throw();
|
||||
const Drawable* getDownImage() const throw();
|
||||
Drawable* getCurrentImage() const throw();
|
||||
Drawable* getNormalImage() const throw();
|
||||
Drawable* getOverImage() const throw();
|
||||
Drawable* getDownImage() const throw();
|
||||
|
||||
/** A set of colour IDs to use to change the colour of various aspects of the link.
|
||||
|
||||
|
|
@ -45167,16 +45196,20 @@ protected:
|
|||
void paintButton (Graphics& g,
|
||||
bool isMouseOverButton,
|
||||
bool isButtonDown);
|
||||
/** @internal */
|
||||
void buttonStateChanged();
|
||||
/** @internal */
|
||||
void resized();
|
||||
|
||||
private:
|
||||
|
||||
ButtonStyle style;
|
||||
ScopedPointer <Drawable> normalImage, overImage, downImage, disabledImage;
|
||||
ScopedPointer <Drawable> normalImageOn, overImageOn, downImageOn, disabledImageOn;
|
||||
Drawable* currentImage;
|
||||
Colour backgroundOff, backgroundOn;
|
||||
int edgeIndent;
|
||||
|
||||
void deleteImages();
|
||||
DrawableButton (const DrawableButton&);
|
||||
DrawableButton& operator= (const DrawableButton&);
|
||||
};
|
||||
|
|
@ -46347,11 +46380,20 @@ public:
|
|||
void paintButtonArea (Graphics& g, int width, int height, bool isMouseOver, bool isMouseDown);
|
||||
/** @internal */
|
||||
void contentAreaChanged (const Rectangle<int>& newBounds);
|
||||
/** @internal */
|
||||
void buttonStateChanged();
|
||||
/** @internal */
|
||||
void resized();
|
||||
/** @internal */
|
||||
void enablementChanged();
|
||||
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
private:
|
||||
ScopedPointer <Drawable> normalImage, toggledOnImage;
|
||||
ScopedPointer<Drawable> normalImage, toggledOnImage;
|
||||
Drawable* currentImage;
|
||||
|
||||
void updateDrawable();
|
||||
|
||||
ToolbarButton (const ToolbarButton&);
|
||||
ToolbarButton& operator= (const ToolbarButton&);
|
||||
|
|
@ -59940,10 +59982,10 @@ public:
|
|||
/** Destructor. */
|
||||
~EdgeTable();
|
||||
|
||||
void clipToRectangle (const Rectangle<int>& r) throw();
|
||||
void excludeRectangle (const Rectangle<int>& r) throw();
|
||||
void clipToRectangle (const Rectangle<int>& r);
|
||||
void excludeRectangle (const Rectangle<int>& r);
|
||||
void clipToEdgeTable (const EdgeTable& other);
|
||||
void clipLineToMask (int x, int y, const uint8* mask, int maskStride, int numPixels) throw();
|
||||
void clipLineToMask (int x, int y, const uint8* mask, int maskStride, int numPixels);
|
||||
bool isEmpty() throw();
|
||||
const Rectangle<int>& getMaximumBounds() const throw() { return bounds; }
|
||||
void translate (float dx, int dy) throw();
|
||||
|
|
@ -59953,7 +59995,7 @@ public:
|
|||
This will shrink the table down to use as little memory as possible - useful for
|
||||
read-only tables that get stored and re-used for rendering.
|
||||
*/
|
||||
void optimiseTable() throw();
|
||||
void optimiseTable();
|
||||
|
||||
/** Iterates the lines in the table, for rendering.
|
||||
|
||||
|
|
@ -60061,9 +60103,9 @@ private:
|
|||
int maxEdgesPerLine, lineStrideElements;
|
||||
bool needToCheckEmptinesss;
|
||||
|
||||
void addEdgePoint (int x, int y, int winding) throw();
|
||||
void remapTableForNumEdges (int newNumEdgesPerLine) throw();
|
||||
void intersectWithEdgeTableLine (int y, const int* otherLine) throw();
|
||||
void addEdgePoint (int x, int y, int winding);
|
||||
void remapTableForNumEdges (int newNumEdgesPerLine);
|
||||
void intersectWithEdgeTableLine (int y, const int* otherLine);
|
||||
void clipEdgeTableLineToRange (int* line, int x1, int x2) throw();
|
||||
void sanitiseLevels (bool useNonZeroWinding) throw();
|
||||
static void copyEdgeTableData (int* dest, int destLineStride, const int* src, int srcLineStride, int numLines) throw();
|
||||
|
|
@ -60247,6 +60289,9 @@ public:
|
|||
virtual void saveState() = 0;
|
||||
virtual void restoreState() = 0;
|
||||
|
||||
virtual void beginTransparencyLayer (float opacity) = 0;
|
||||
virtual void endTransparencyLayer() = 0;
|
||||
|
||||
virtual void setFill (const FillType& fillType) = 0;
|
||||
virtual void setOpacity (float newOpacity) = 0;
|
||||
virtual void setInterpolationQuality (Graphics::ResamplingQuality quality) = 0;
|
||||
|
|
@ -60305,6 +60350,9 @@ public:
|
|||
void saveState();
|
||||
void restoreState();
|
||||
|
||||
void beginTransparencyLayer (float opacity);
|
||||
void endTransparencyLayer();
|
||||
|
||||
bool clipRegionIntersects (const Rectangle<int>& r);
|
||||
const Rectangle<int> getClipBounds() const;
|
||||
bool isClipEmpty() const;
|
||||
|
|
@ -60407,6 +60455,9 @@ public:
|
|||
void saveState();
|
||||
void restoreState();
|
||||
|
||||
void beginTransparencyLayer (float opacity);
|
||||
void endTransparencyLayer();
|
||||
|
||||
void setFill (const FillType& fillType);
|
||||
void setOpacity (float opacity);
|
||||
void setInterpolationQuality (Graphics::ResamplingQuality quality);
|
||||
|
|
@ -60524,7 +60575,7 @@ public:
|
|||
|
||||
@see getDrawable
|
||||
*/
|
||||
int getNumDrawables() const throw() { return drawables.size(); }
|
||||
int getNumDrawables() const throw();
|
||||
|
||||
/** Returns one of the drawables that are contained in this one.
|
||||
|
||||
|
|
@ -60536,7 +60587,7 @@ public:
|
|||
|
||||
@see getNumDrawables
|
||||
*/
|
||||
Drawable* getDrawable (int index) const throw() { return drawables [index]; }
|
||||
Drawable* getDrawable (int index) const;
|
||||
|
||||
/** Looks for a child drawable with the specified name. */
|
||||
Drawable* getDrawableWithName (const String& name) const throw();
|
||||
|
|
@ -60549,20 +60600,6 @@ public:
|
|||
*/
|
||||
void bringToFront (int index);
|
||||
|
||||
/** Returns the main content rectangle.
|
||||
The content area is actually defined by the markers named "left", "right", "top" and
|
||||
"bottom", but this method is a shortcut that returns them all at once.
|
||||
@see contentLeftMarkerName, contentRightMarkerName, contentTopMarkerName, contentBottomMarkerName
|
||||
*/
|
||||
const RelativeRectangle getContentArea() const;
|
||||
|
||||
/** Changes the main content area.
|
||||
The content area is actually defined by the markers named "left", "right", "top" and
|
||||
"bottom", but this method is a shortcut that sets them all at once.
|
||||
@see setBoundingBox, contentLeftMarkerName, contentRightMarkerName, contentTopMarkerName, contentBottomMarkerName
|
||||
*/
|
||||
void setContentArea (const RelativeRectangle& newArea);
|
||||
|
||||
/** Sets the parallelogram that defines the target position of the content rectangle when the drawable is rendered.
|
||||
@see setContentArea
|
||||
*/
|
||||
|
|
@ -60578,6 +60615,20 @@ public:
|
|||
*/
|
||||
void resetBoundingBoxToContentArea();
|
||||
|
||||
/** Returns the main content rectangle.
|
||||
The content area is actually defined by the markers named "left", "right", "top" and
|
||||
"bottom", but this method is a shortcut that returns them all at once.
|
||||
@see contentLeftMarkerName, contentRightMarkerName, contentTopMarkerName, contentBottomMarkerName
|
||||
*/
|
||||
const RelativeRectangle getContentArea() const;
|
||||
|
||||
/** Changes the main content area.
|
||||
The content area is actually defined by the markers named "left", "right", "top" and
|
||||
"bottom", but this method is a shortcut that sets them all at once.
|
||||
@see setBoundingBox, contentLeftMarkerName, contentRightMarkerName, contentTopMarkerName, contentBottomMarkerName
|
||||
*/
|
||||
void setContentArea (const RelativeRectangle& newArea);
|
||||
|
||||
/** Resets the content area and the bounding transform to fit around the area occupied
|
||||
by the child components (ignoring any markers).
|
||||
*/
|
||||
|
|
@ -60610,18 +60661,10 @@ public:
|
|||
/** The name of the marker that defines the bottom edge of the content area. */
|
||||
static const char* const contentBottomMarkerName;
|
||||
|
||||
/** @internal */
|
||||
void render (const Drawable::RenderingContext& context) const;
|
||||
/** @internal */
|
||||
const Rectangle<float> getBounds() const;
|
||||
/** @internal */
|
||||
bool hitTest (float x, float y) const;
|
||||
/** @internal */
|
||||
Drawable* createCopy() const;
|
||||
/** @internal */
|
||||
void invalidatePoints();
|
||||
/** @internal */
|
||||
const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider);
|
||||
void refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider);
|
||||
/** @internal */
|
||||
const ValueTree createValueTree (ImageProvider* imageProvider) const;
|
||||
/** @internal */
|
||||
|
|
@ -60630,6 +60673,16 @@ public:
|
|||
const Identifier getValueTreeType() const { return valueTreeType; }
|
||||
/** @internal */
|
||||
const Expression getSymbolValue (const String& symbol, const String& member) const;
|
||||
/** @internal */
|
||||
const Rectangle<float> getDrawableBounds() const;
|
||||
/** @internal */
|
||||
void markerHasMoved();
|
||||
/** @internal */
|
||||
void childBoundsChanged (Component*);
|
||||
/** @internal */
|
||||
void childrenChanged();
|
||||
/** @internal */
|
||||
void parentHierarchyChanged();
|
||||
|
||||
/** Internally-used class for wrapping a DrawableComposite's state into a ValueTree. */
|
||||
class ValueTreeWrapper : public Drawable::ValueTreeWrapperBase
|
||||
|
|
@ -60674,12 +60727,12 @@ public:
|
|||
juce_UseDebuggingNewOperator
|
||||
|
||||
private:
|
||||
OwnedArray <Drawable> drawables;
|
||||
RelativeParallelogram bounds;
|
||||
OwnedArray <Marker> markersX, markersY;
|
||||
bool updateBoundsReentrant;
|
||||
|
||||
const Rectangle<float> getUntransformedBounds (bool includeMarkers) const;
|
||||
const AffineTransform calculateTransform() const;
|
||||
void refreshTransformFromBounds();
|
||||
void updateBoundsToFitChildren();
|
||||
|
||||
DrawableComposite& operator= (const DrawableComposite&);
|
||||
};
|
||||
|
|
@ -60746,17 +60799,15 @@ public:
|
|||
const RelativeParallelogram& getBoundingBox() const throw() { return bounds; }
|
||||
|
||||
/** @internal */
|
||||
void render (const Drawable::RenderingContext& context) const;
|
||||
void paint (Graphics& g);
|
||||
/** @internal */
|
||||
const Rectangle<float> getBounds() const;
|
||||
/** @internal */
|
||||
bool hitTest (float x, float y) const;
|
||||
bool hitTest (int x, int y) const;
|
||||
/** @internal */
|
||||
Drawable* createCopy() const;
|
||||
/** @internal */
|
||||
void invalidatePoints();
|
||||
const Rectangle<float> getDrawableBounds() const;
|
||||
/** @internal */
|
||||
const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider);
|
||||
void refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider);
|
||||
/** @internal */
|
||||
const ValueTree createValueTree (ImageProvider* imageProvider) const;
|
||||
/** @internal */
|
||||
|
|
@ -60796,7 +60847,7 @@ private:
|
|||
Colour overlayColour;
|
||||
RelativeParallelogram bounds;
|
||||
|
||||
const AffineTransform calculateTransform() const;
|
||||
void refreshTransformFromBounds();
|
||||
|
||||
DrawableImage& operator= (const DrawableImage&);
|
||||
};
|
||||
|
|
@ -60910,13 +60961,11 @@ public:
|
|||
};
|
||||
|
||||
/** @internal */
|
||||
void invalidatePoints();
|
||||
const Rectangle<float> getDrawableBounds() const;
|
||||
/** @internal */
|
||||
void render (const Drawable::RenderingContext& context) const;
|
||||
void paint (Graphics& g);
|
||||
/** @internal */
|
||||
const Rectangle<float> getBounds() const;
|
||||
/** @internal */
|
||||
bool hitTest (float x, float y) const;
|
||||
bool hitTest (int x, int y) const;
|
||||
|
||||
protected:
|
||||
|
||||
|
|
@ -60939,19 +60988,11 @@ protected:
|
|||
/** Writes the stroke and fill details to a FillAndStrokeState object. */
|
||||
void writeTo (FillAndStrokeState& state, ImageProvider* imageProvider, UndoManager* undoManager) const;
|
||||
|
||||
/** Returns the current cached path outline. */
|
||||
const Path& getCachedPath() const;
|
||||
/** Returns the current cached stroke outline. */
|
||||
const Path& getCachedStrokePath() const;
|
||||
|
||||
PathStrokeType strokeType;
|
||||
mutable Path cachedPath, cachedStroke;
|
||||
Path path, strokePath;
|
||||
|
||||
private:
|
||||
FillType mainFill, strokeFill;
|
||||
mutable bool pathNeedsUpdating, strokeNeedsUpdating;
|
||||
|
||||
static void setBrush (const Drawable::RenderingContext& context, const FillType& type);
|
||||
|
||||
DrawableShape& operator= (const DrawableShape&);
|
||||
};
|
||||
|
|
@ -60991,7 +61032,7 @@ public:
|
|||
/** @internal */
|
||||
Drawable* createCopy() const;
|
||||
/** @internal */
|
||||
const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider);
|
||||
void refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider);
|
||||
/** @internal */
|
||||
const ValueTree createValueTree (ImageProvider* imageProvider) const;
|
||||
/** @internal */
|
||||
|
|
@ -61105,7 +61146,7 @@ public:
|
|||
/** @internal */
|
||||
Drawable* createCopy() const;
|
||||
/** @internal */
|
||||
const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider);
|
||||
void refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider);
|
||||
/** @internal */
|
||||
const ValueTree createValueTree (ImageProvider* imageProvider) const;
|
||||
/** @internal */
|
||||
|
|
@ -61211,23 +61252,19 @@ public:
|
|||
void setFontSizeControlPoint (const RelativePoint& newPoint);
|
||||
|
||||
/** @internal */
|
||||
void render (const Drawable::RenderingContext& context) const;
|
||||
/** @internal */
|
||||
const Rectangle<float> getBounds() const;
|
||||
/** @internal */
|
||||
bool hitTest (float x, float y) const;
|
||||
void paint (Graphics& g);
|
||||
/** @internal */
|
||||
Drawable* createCopy() const;
|
||||
/** @internal */
|
||||
void invalidatePoints();
|
||||
/** @internal */
|
||||
const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider);
|
||||
void refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider);
|
||||
/** @internal */
|
||||
const ValueTree createValueTree (ImageProvider* imageProvider) const;
|
||||
/** @internal */
|
||||
static const Identifier valueTreeType;
|
||||
/** @internal */
|
||||
const Identifier getValueTreeType() const { return valueTreeType; }
|
||||
/** @internal */
|
||||
const Rectangle<float> getDrawableBounds() const;
|
||||
|
||||
/** Internally-used class for wrapping a DrawableText's state into a ValueTree. */
|
||||
class ValueTreeWrapper : public Drawable::ValueTreeWrapperBase
|
||||
|
|
@ -61268,6 +61305,8 @@ private:
|
|||
Colour colour;
|
||||
Justification justification;
|
||||
|
||||
void refreshBounds();
|
||||
|
||||
DrawableText& operator= (const DrawableText&);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -779,7 +779,7 @@ public:
|
|||
if (howManyToRemove > numUsed)
|
||||
howManyToRemove = numUsed;
|
||||
|
||||
for (int i = 0; i < howManyToRemove; ++i)
|
||||
for (int i = 1; i <= howManyToRemove; ++i)
|
||||
data.elements [numUsed - i].~ElementType();
|
||||
|
||||
numUsed -= howManyToRemove;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
#define JUCE_MAJOR_VERSION 1
|
||||
#define JUCE_MINOR_VERSION 52
|
||||
#define JUCE_BUILDNUMBER 96
|
||||
#define JUCE_BUILDNUMBER 97
|
||||
|
||||
/** Current Juce version number.
|
||||
|
||||
|
|
|
|||
|
|
@ -431,7 +431,7 @@ void Button::mouseUp (const MouseEvent& e)
|
|||
internalClickCallback (e.mods);
|
||||
}
|
||||
|
||||
void Button::mouseDrag (const MouseEvent& e)
|
||||
void Button::mouseDrag (const MouseEvent&)
|
||||
{
|
||||
const ButtonState oldState = buttonState;
|
||||
updateState (isMouseOver(), true);
|
||||
|
|
|
|||
|
|
@ -1836,7 +1836,7 @@ void Component::paintComponentAndChildren (Graphics& g)
|
|||
g.saveState();
|
||||
g.addTransform (*child.affineTransform_);
|
||||
|
||||
if (child.flags.dontClipGraphicsFlag || g.reduceClipRegion (child.getBounds()))
|
||||
if ((child.flags.dontClipGraphicsFlag && ! g.isClipEmpty()) || g.reduceClipRegion (child.getBounds()))
|
||||
child.paintWithinParentContext (g);
|
||||
|
||||
g.restoreState();
|
||||
|
|
@ -1904,17 +1904,9 @@ void Component::paintEntireComponent (Graphics& g, const bool ignoreAlphaLevel)
|
|||
{
|
||||
if (componentTransparency < 255)
|
||||
{
|
||||
Image temp (flags.opaqueFlag ? Image::RGB : Image::ARGB,
|
||||
getWidth(), getHeight(), ! flags.opaqueFlag, Image::NativeImage);
|
||||
|
||||
{
|
||||
Graphics tempG (temp);
|
||||
tempG.reduceClipRegion (g.getClipBounds());
|
||||
paintEntireComponent (tempG, true);
|
||||
}
|
||||
|
||||
g.setColour (Colours::black.withAlpha (getAlpha()));
|
||||
g.drawImageAt (temp, 0, 0);
|
||||
g.beginTransparencyLayer (getAlpha());
|
||||
paintComponentAndChildren (g);
|
||||
g.endTransparencyLayer();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ void EdgeTable::sanitiseLevels (const bool useNonZeroWinding) throw()
|
|||
}
|
||||
}
|
||||
|
||||
void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine) throw()
|
||||
void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine)
|
||||
{
|
||||
if (newNumEdgesPerLine != maxEdgesPerLine)
|
||||
{
|
||||
|
|
@ -347,7 +347,7 @@ void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine) throw()
|
|||
}
|
||||
}
|
||||
|
||||
void EdgeTable::optimiseTable() throw()
|
||||
void EdgeTable::optimiseTable()
|
||||
{
|
||||
int maxLineElements = 0;
|
||||
|
||||
|
|
@ -357,7 +357,7 @@ void EdgeTable::optimiseTable() throw()
|
|||
remapTableForNumEdges (maxLineElements);
|
||||
}
|
||||
|
||||
void EdgeTable::addEdgePoint (const int x, const int y, const int winding) throw()
|
||||
void EdgeTable::addEdgePoint (const int x, const int y, const int winding)
|
||||
{
|
||||
jassert (y >= 0 && y < bounds.getHeight());
|
||||
|
||||
|
|
@ -421,7 +421,7 @@ void EdgeTable::translate (float dx, const int dy) throw()
|
|||
}
|
||||
}
|
||||
|
||||
void EdgeTable::intersectWithEdgeTableLine (const int y, const int* otherLine) throw()
|
||||
void EdgeTable::intersectWithEdgeTableLine (const int y, const int* otherLine)
|
||||
{
|
||||
jassert (y >= 0 && y < bounds.getHeight());
|
||||
|
||||
|
|
@ -588,7 +588,7 @@ void EdgeTable::clipEdgeTableLineToRange (int* dest, const int x1, const int x2)
|
|||
|
||||
|
||||
//==============================================================================
|
||||
void EdgeTable::clipToRectangle (const Rectangle<int>& r) throw()
|
||||
void EdgeTable::clipToRectangle (const Rectangle<int>& r)
|
||||
{
|
||||
const Rectangle<int> clipped (r.getIntersection (bounds));
|
||||
|
||||
|
|
@ -630,7 +630,7 @@ void EdgeTable::clipToRectangle (const Rectangle<int>& r) throw()
|
|||
}
|
||||
}
|
||||
|
||||
void EdgeTable::excludeRectangle (const Rectangle<int>& r) throw()
|
||||
void EdgeTable::excludeRectangle (const Rectangle<int>& r)
|
||||
{
|
||||
const Rectangle<int> clipped (r.getIntersection (bounds));
|
||||
|
||||
|
|
@ -689,7 +689,7 @@ void EdgeTable::clipToEdgeTable (const EdgeTable& other)
|
|||
}
|
||||
}
|
||||
|
||||
void EdgeTable::clipLineToMask (int x, int y, const uint8* mask, int maskStride, int numPixels) throw()
|
||||
void EdgeTable::clipLineToMask (int x, int y, const uint8* mask, int maskStride, int numPixels)
|
||||
{
|
||||
y -= bounds.getY();
|
||||
|
||||
|
|
|
|||
|
|
@ -79,10 +79,10 @@ public:
|
|||
~EdgeTable();
|
||||
|
||||
//==============================================================================
|
||||
void clipToRectangle (const Rectangle<int>& r) throw();
|
||||
void excludeRectangle (const Rectangle<int>& r) throw();
|
||||
void clipToRectangle (const Rectangle<int>& r);
|
||||
void excludeRectangle (const Rectangle<int>& r);
|
||||
void clipToEdgeTable (const EdgeTable& other);
|
||||
void clipLineToMask (int x, int y, const uint8* mask, int maskStride, int numPixels) throw();
|
||||
void clipLineToMask (int x, int y, const uint8* mask, int maskStride, int numPixels);
|
||||
bool isEmpty() throw();
|
||||
const Rectangle<int>& getMaximumBounds() const throw() { return bounds; }
|
||||
void translate (float dx, int dy) throw();
|
||||
|
|
@ -92,7 +92,7 @@ public:
|
|||
This will shrink the table down to use as little memory as possible - useful for
|
||||
read-only tables that get stored and re-used for rendering.
|
||||
*/
|
||||
void optimiseTable() throw();
|
||||
void optimiseTable();
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -203,9 +203,9 @@ private:
|
|||
int maxEdgesPerLine, lineStrideElements;
|
||||
bool needToCheckEmptinesss;
|
||||
|
||||
void addEdgePoint (int x, int y, int winding) throw();
|
||||
void remapTableForNumEdges (int newNumEdgesPerLine) throw();
|
||||
void intersectWithEdgeTableLine (int y, const int* otherLine) throw();
|
||||
void addEdgePoint (int x, int y, int winding);
|
||||
void remapTableForNumEdges (int newNumEdgesPerLine);
|
||||
void intersectWithEdgeTableLine (int y, const int* otherLine);
|
||||
void clipEdgeTableLineToRange (int* line, int x1, int x2) throw();
|
||||
void sanitiseLevels (bool useNonZeroWinding) throw();
|
||||
static void copyEdgeTableData (int* dest, int destLineStride, const int* src, int srcLineStride, int numLines) throw();
|
||||
|
|
|
|||
|
|
@ -176,6 +176,17 @@ bool Graphics::clipRegionIntersects (const Rectangle<int>& area) const
|
|||
return context->clipRegionIntersects (area);
|
||||
}
|
||||
|
||||
void Graphics::beginTransparencyLayer (float layerOpacity)
|
||||
{
|
||||
saveStateIfPending();
|
||||
context->beginTransparencyLayer (layerOpacity);
|
||||
}
|
||||
|
||||
void Graphics::endTransparencyLayer()
|
||||
{
|
||||
context->endTransparencyLayer();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void Graphics::setColour (const Colour& newColour)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -613,6 +613,23 @@ public:
|
|||
*/
|
||||
void restoreState();
|
||||
|
||||
/** Begins rendering to an off-screen bitmap which will later be flattened onto the current
|
||||
context with the given opacity.
|
||||
|
||||
The context uses an internal stack of temporary image layers to do this. When you've
|
||||
finished drawing to the layer, call endTransparencyLayer() to complete the operation and
|
||||
composite the finished layer. Every call to beginTransparencyLayer() MUST be matched
|
||||
by a corresponding call to endTransparencyLayer()!
|
||||
|
||||
This call also saves the current state, and endTransparencyLayer() restores it.
|
||||
*/
|
||||
void beginTransparencyLayer (float layerOpacity);
|
||||
|
||||
/** Completes a drawing operation to a temporary semi-transparent buffer.
|
||||
See beginTransparencyLayer() for more details.
|
||||
*/
|
||||
void endTransparencyLayer();
|
||||
|
||||
/** Moves the position of the context's origin.
|
||||
|
||||
This changes the position that the context considers to be (0, 0) to
|
||||
|
|
|
|||
|
|
@ -81,6 +81,9 @@ public:
|
|||
virtual void saveState() = 0;
|
||||
virtual void restoreState() = 0;
|
||||
|
||||
virtual void beginTransparencyLayer (float opacity) = 0;
|
||||
virtual void endTransparencyLayer() = 0;
|
||||
|
||||
//==============================================================================
|
||||
virtual void setFill (const FillType& fillType) = 0;
|
||||
virtual void setOpacity (float newOpacity) = 0;
|
||||
|
|
|
|||
|
|
@ -192,6 +192,14 @@ void LowLevelGraphicsPostScriptRenderer::restoreState()
|
|||
stateStack.removeLast();
|
||||
}
|
||||
|
||||
void LowLevelGraphicsPostScriptRenderer::beginTransparencyLayer (float)
|
||||
{
|
||||
}
|
||||
|
||||
void LowLevelGraphicsPostScriptRenderer::endTransparencyLayer()
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void LowLevelGraphicsPostScriptRenderer::writeClip()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@ public:
|
|||
void saveState();
|
||||
void restoreState();
|
||||
|
||||
void beginTransparencyLayer (float opacity);
|
||||
void endTransparencyLayer();
|
||||
|
||||
bool clipRegionIntersects (const Rectangle<int>& r);
|
||||
const Rectangle<int> getClipBounds() const;
|
||||
bool isClipEmpty() const;
|
||||
|
|
|
|||
|
|
@ -1045,6 +1045,7 @@ public:
|
|||
virtual const Ptr clipToPath (const Path& p, const AffineTransform& transform) = 0;
|
||||
virtual const Ptr clipToEdgeTable (const EdgeTable& et) = 0;
|
||||
virtual const Ptr clipToImageAlpha (const Image& image, const AffineTransform& t, const bool betterQuality) = 0;
|
||||
virtual const Ptr translated (const Point<int>& delta) = 0;
|
||||
|
||||
virtual bool clipRegionIntersects (const Rectangle<int>& r) const = 0;
|
||||
virtual const Rectangle<int> getClipBounds() const = 0;
|
||||
|
|
@ -1327,6 +1328,12 @@ public:
|
|||
return edgeTable.isEmpty() ? 0 : this;
|
||||
}
|
||||
|
||||
const Ptr translated (const Point<int>& delta)
|
||||
{
|
||||
edgeTable.translate ((float) delta.getX(), delta.getY());
|
||||
return edgeTable.isEmpty() ? 0 : this;
|
||||
}
|
||||
|
||||
bool clipRegionIntersects (const Rectangle<int>& r) const
|
||||
{
|
||||
return edgeTable.getMaximumBounds().intersects (r);
|
||||
|
|
@ -1479,6 +1486,12 @@ public:
|
|||
return Ptr (new ClipRegion_EdgeTable (clip))->clipToImageAlpha (image, transform, betterQuality);
|
||||
}
|
||||
|
||||
const Ptr translated (const Point<int>& delta)
|
||||
{
|
||||
clip.offsetAll (delta.getX(), delta.getY());
|
||||
return clip.isEmpty() ? 0 : this;
|
||||
}
|
||||
|
||||
bool clipRegionIntersects (const Rectangle<int>& r) const
|
||||
{
|
||||
return clip.intersects (r);
|
||||
|
|
@ -1788,21 +1801,25 @@ private:
|
|||
class LowLevelGraphicsSoftwareRenderer::SavedState
|
||||
{
|
||||
public:
|
||||
SavedState (const Rectangle<int>& clip_, const int xOffset_, const int yOffset_)
|
||||
: clip (new SoftwareRendererClasses::ClipRegion_RectangleList (clip_)),
|
||||
xOffset (xOffset_), yOffset (yOffset_), isOnlyTranslated (true), interpolationQuality (Graphics::mediumResamplingQuality)
|
||||
SavedState (const Image& image_, const Rectangle<int>& clip_, const int xOffset_, const int yOffset_)
|
||||
: image (image_), clip (new SoftwareRendererClasses::ClipRegion_RectangleList (clip_)),
|
||||
xOffset (xOffset_), yOffset (yOffset_), compositionAlpha (1.0f),
|
||||
isOnlyTranslated (true), interpolationQuality (Graphics::mediumResamplingQuality)
|
||||
{
|
||||
}
|
||||
|
||||
SavedState (const RectangleList& clip_, const int xOffset_, const int yOffset_)
|
||||
: clip (new SoftwareRendererClasses::ClipRegion_RectangleList (clip_)),
|
||||
xOffset (xOffset_), yOffset (yOffset_), isOnlyTranslated (true), interpolationQuality (Graphics::mediumResamplingQuality)
|
||||
SavedState (const Image& image_, const RectangleList& clip_, const int xOffset_, const int yOffset_)
|
||||
: image (image_), clip (new SoftwareRendererClasses::ClipRegion_RectangleList (clip_)),
|
||||
xOffset (xOffset_), yOffset (yOffset_), compositionAlpha (1.0f),
|
||||
isOnlyTranslated (true), interpolationQuality (Graphics::mediumResamplingQuality)
|
||||
{
|
||||
}
|
||||
|
||||
SavedState (const SavedState& other)
|
||||
: clip (other.clip), complexTransform (other.complexTransform), xOffset (other.xOffset), yOffset (other.yOffset),
|
||||
isOnlyTranslated (other.isOnlyTranslated), font (other.font), fillType (other.fillType), interpolationQuality (other.interpolationQuality)
|
||||
: image (other.image), clip (other.clip), complexTransform (other.complexTransform),
|
||||
xOffset (other.xOffset), yOffset (other.yOffset), compositionAlpha (other.compositionAlpha),
|
||||
isOnlyTranslated (other.isOnlyTranslated), font (other.font), fillType (other.fillType),
|
||||
interpolationQuality (other.interpolationQuality)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -1937,6 +1954,11 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
const Rectangle<int> getUntransformedClipBounds() const
|
||||
{
|
||||
return clip != 0 ? clip->getClipBounds() : Rectangle<int>();
|
||||
}
|
||||
|
||||
const Rectangle<int> getClipBounds() const
|
||||
{
|
||||
if (clip != 0)
|
||||
|
|
@ -1950,8 +1972,41 @@ public:
|
|||
return Rectangle<int>();
|
||||
}
|
||||
|
||||
SavedState* beginTransparencyLayer (float opacity)
|
||||
{
|
||||
const Rectangle<int> clip (getUntransformedClipBounds());
|
||||
|
||||
SavedState* s = new SavedState (*this);
|
||||
s->image = Image (Image::ARGB, clip.getWidth(), clip.getHeight(), true);
|
||||
s->compositionAlpha = opacity;
|
||||
|
||||
if (s->isOnlyTranslated)
|
||||
{
|
||||
s->xOffset -= clip.getX();
|
||||
s->yOffset -= clip.getY();
|
||||
}
|
||||
else
|
||||
{
|
||||
s->complexTransform = s->complexTransform.followedBy (AffineTransform::translation ((float) -clip.getX(), (float) -clip.getY()));
|
||||
}
|
||||
|
||||
s->cloneClipIfMultiplyReferenced();
|
||||
s->clip = s->clip->translated (-clip.getPosition());
|
||||
return s;
|
||||
}
|
||||
|
||||
void endTransparencyLayer (SavedState& layerState)
|
||||
{
|
||||
const Rectangle<int> clip (getUntransformedClipBounds());
|
||||
|
||||
const ScopedPointer<LowLevelGraphicsContext> g (image.createLowLevelContext());
|
||||
g->setOpacity (layerState.compositionAlpha);
|
||||
g->drawImage (layerState.image, AffineTransform::translation ((float) clip.getX(),
|
||||
(float) clip.getY()), false);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void fillRect (Image& image, const Rectangle<int>& r, const bool replaceContents)
|
||||
void fillRect (const Rectangle<int>& r, const bool replaceContents)
|
||||
{
|
||||
if (clip != 0)
|
||||
{
|
||||
|
|
@ -1968,19 +2023,19 @@ public:
|
|||
const Rectangle<int> clipped (totalClip.getIntersection (r.translated (xOffset, yOffset)));
|
||||
|
||||
if (! clipped.isEmpty())
|
||||
fillShape (image, new SoftwareRendererClasses::ClipRegion_RectangleList (clipped), false);
|
||||
fillShape (new SoftwareRendererClasses::ClipRegion_RectangleList (clipped), false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Path p;
|
||||
p.addRectangle (r);
|
||||
fillPath (image, p, AffineTransform::identity);
|
||||
fillPath (p, AffineTransform::identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fillRect (Image& image, const Rectangle<float>& r)
|
||||
void fillRect (const Rectangle<float>& r)
|
||||
{
|
||||
if (clip != 0)
|
||||
{
|
||||
|
|
@ -1997,25 +2052,25 @@ public:
|
|||
const Rectangle<float> clipped (totalClip.getIntersection (r.translated ((float) xOffset, (float) yOffset)));
|
||||
|
||||
if (! clipped.isEmpty())
|
||||
fillShape (image, new SoftwareRendererClasses::ClipRegion_EdgeTable (clipped), false);
|
||||
fillShape (new SoftwareRendererClasses::ClipRegion_EdgeTable (clipped), false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Path p;
|
||||
p.addRectangle (r);
|
||||
fillPath (image, p, AffineTransform::identity);
|
||||
fillPath (p, AffineTransform::identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fillPath (Image& image, const Path& path, const AffineTransform& transform)
|
||||
void fillPath (const Path& path, const AffineTransform& transform)
|
||||
{
|
||||
if (clip != 0)
|
||||
fillShape (image, new SoftwareRendererClasses::ClipRegion_EdgeTable (clip->getClipBounds(), path, getTransformWith (transform)), false);
|
||||
fillShape (new SoftwareRendererClasses::ClipRegion_EdgeTable (clip->getClipBounds(), path, getTransformWith (transform)), false);
|
||||
}
|
||||
|
||||
void fillEdgeTable (Image& image, const EdgeTable& edgeTable, const float x, const int y)
|
||||
void fillEdgeTable (const EdgeTable& edgeTable, const float x, const int y)
|
||||
{
|
||||
jassert (isOnlyTranslated);
|
||||
|
||||
|
|
@ -2024,11 +2079,11 @@ public:
|
|||
SoftwareRendererClasses::ClipRegion_EdgeTable* edgeTableClip = new SoftwareRendererClasses::ClipRegion_EdgeTable (edgeTable);
|
||||
SoftwareRendererClasses::ClipRegionBase::Ptr shapeToFill (edgeTableClip);
|
||||
edgeTableClip->edgeTable.translate (x + xOffset, y + yOffset);
|
||||
fillShape (image, shapeToFill, false);
|
||||
fillShape (shapeToFill, false);
|
||||
}
|
||||
}
|
||||
|
||||
void fillShape (Image& image, SoftwareRendererClasses::ClipRegionBase::Ptr shapeToFill, const bool replaceContents)
|
||||
void fillShape (SoftwareRendererClasses::ClipRegionBase::Ptr shapeToFill, const bool replaceContents)
|
||||
{
|
||||
jassert (clip != 0);
|
||||
|
||||
|
|
@ -2060,7 +2115,7 @@ public:
|
|||
}
|
||||
else if (fillType.isTiledImage())
|
||||
{
|
||||
renderImage (image, fillType.image, fillType.transform, shapeToFill);
|
||||
renderImage (fillType.image, fillType.transform, shapeToFill);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2070,11 +2125,11 @@ public:
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
void renderImage (Image& destImage, const Image& sourceImage, const AffineTransform& t, const SoftwareRendererClasses::ClipRegionBase* const tiledFillClipRegion)
|
||||
void renderImage (const Image& sourceImage, const AffineTransform& t, const SoftwareRendererClasses::ClipRegionBase* const tiledFillClipRegion)
|
||||
{
|
||||
const AffineTransform transform (getTransformWith (t));
|
||||
|
||||
const Image::BitmapData destData (destImage, true);
|
||||
const Image::BitmapData destData (image, true);
|
||||
const Image::BitmapData srcData (sourceImage, false);
|
||||
const int alpha = fillType.colour.getAlpha();
|
||||
const bool betterQuality = (interpolationQuality != Graphics::lowResamplingQuality);
|
||||
|
|
@ -2096,7 +2151,7 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
SoftwareRendererClasses::ClipRegionBase::Ptr c (new SoftwareRendererClasses::ClipRegion_EdgeTable (Rectangle<int> (tx, ty, sourceImage.getWidth(), sourceImage.getHeight()).getIntersection (destImage.getBounds())));
|
||||
SoftwareRendererClasses::ClipRegionBase::Ptr c (new SoftwareRendererClasses::ClipRegion_EdgeTable (Rectangle<int> (tx, ty, sourceImage.getWidth(), sourceImage.getHeight()).getIntersection (image.getBounds())));
|
||||
c = clip->applyClipTo (c);
|
||||
|
||||
if (c != 0)
|
||||
|
|
@ -2128,11 +2183,13 @@ public:
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
Image image;
|
||||
SoftwareRendererClasses::ClipRegionBase::Ptr clip;
|
||||
|
||||
private:
|
||||
AffineTransform complexTransform;
|
||||
int xOffset, yOffset;
|
||||
float compositionAlpha;
|
||||
|
||||
public:
|
||||
bool isOnlyTranslated;
|
||||
|
|
@ -2170,16 +2227,16 @@ private:
|
|||
|
||||
//==============================================================================
|
||||
LowLevelGraphicsSoftwareRenderer::LowLevelGraphicsSoftwareRenderer (const Image& image_)
|
||||
: image (image_)
|
||||
: image (image_),
|
||||
currentState (new SavedState (image_, image_.getBounds(), 0, 0))
|
||||
{
|
||||
currentState = new SavedState (image_.getBounds(), 0, 0);
|
||||
}
|
||||
|
||||
LowLevelGraphicsSoftwareRenderer::LowLevelGraphicsSoftwareRenderer (const Image& image_, const int xOffset, const int yOffset,
|
||||
const RectangleList& initialClip)
|
||||
: image (image_)
|
||||
: image (image_),
|
||||
currentState (new SavedState (image_, initialClip, xOffset, yOffset))
|
||||
{
|
||||
currentState = new SavedState (initialClip, xOffset, yOffset);
|
||||
}
|
||||
|
||||
LowLevelGraphicsSoftwareRenderer::~LowLevelGraphicsSoftwareRenderer()
|
||||
|
|
@ -2263,6 +2320,19 @@ void LowLevelGraphicsSoftwareRenderer::restoreState()
|
|||
}
|
||||
}
|
||||
|
||||
void LowLevelGraphicsSoftwareRenderer::beginTransparencyLayer (float opacity)
|
||||
{
|
||||
saveState();
|
||||
currentState = currentState->beginTransparencyLayer (opacity);
|
||||
}
|
||||
|
||||
void LowLevelGraphicsSoftwareRenderer::endTransparencyLayer()
|
||||
{
|
||||
const ScopedPointer<SavedState> layer (currentState);
|
||||
restoreState();
|
||||
currentState->endTransparencyLayer (*layer);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void LowLevelGraphicsSoftwareRenderer::setFill (const FillType& fillType)
|
||||
{
|
||||
|
|
@ -2282,18 +2352,17 @@ void LowLevelGraphicsSoftwareRenderer::setInterpolationQuality (Graphics::Resamp
|
|||
//==============================================================================
|
||||
void LowLevelGraphicsSoftwareRenderer::fillRect (const Rectangle<int>& r, const bool replaceExistingContents)
|
||||
{
|
||||
currentState->fillRect (image, r, replaceExistingContents);
|
||||
currentState->fillRect (r, replaceExistingContents);
|
||||
}
|
||||
|
||||
void LowLevelGraphicsSoftwareRenderer::fillPath (const Path& path, const AffineTransform& transform)
|
||||
{
|
||||
currentState->fillPath (image, path, transform);
|
||||
currentState->fillPath (path, transform);
|
||||
}
|
||||
|
||||
void LowLevelGraphicsSoftwareRenderer::drawImage (const Image& sourceImage, const AffineTransform& transform, const bool fillEntireClipAsTiles)
|
||||
{
|
||||
currentState->renderImage (image, sourceImage, transform,
|
||||
fillEntireClipAsTiles ? currentState->clip : 0);
|
||||
currentState->renderImage (sourceImage, transform, fillEntireClipAsTiles ? currentState->clip : 0);
|
||||
}
|
||||
|
||||
void LowLevelGraphicsSoftwareRenderer::drawLine (const Line <float>& line)
|
||||
|
|
@ -2306,13 +2375,13 @@ void LowLevelGraphicsSoftwareRenderer::drawLine (const Line <float>& line)
|
|||
void LowLevelGraphicsSoftwareRenderer::drawVerticalLine (const int x, float top, float bottom)
|
||||
{
|
||||
if (bottom > top)
|
||||
currentState->fillRect (image, Rectangle<float> ((float) x, top, 1.0f, bottom - top));
|
||||
currentState->fillRect (Rectangle<float> ((float) x, top, 1.0f, bottom - top));
|
||||
}
|
||||
|
||||
void LowLevelGraphicsSoftwareRenderer::drawHorizontalLine (const int y, float left, float right)
|
||||
{
|
||||
if (right > left)
|
||||
currentState->fillRect (image, Rectangle<float> (left, (float) y, right - left, 1.0f));
|
||||
currentState->fillRect (Rectangle<float> (left, (float) y, right - left, 1.0f));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -2322,10 +2391,10 @@ public:
|
|||
CachedGlyph() : glyph (0), lastAccessCount (0) {}
|
||||
~CachedGlyph() {}
|
||||
|
||||
void draw (SavedState& state, Image& image, const float x, const float y) const
|
||||
void draw (SavedState& state, const float x, const float y) const
|
||||
{
|
||||
if (edgeTable != 0)
|
||||
state.fillEdgeTable (image, *edgeTable, x, roundToInt (y));
|
||||
state.fillEdgeTable (*edgeTable, x, roundToInt (y));
|
||||
}
|
||||
|
||||
void generate (const Font& newFont, const int glyphNumber)
|
||||
|
|
@ -2383,7 +2452,7 @@ public:
|
|||
juce_DeclareSingleton_SingleThreaded_Minimal (GlyphCache);
|
||||
|
||||
//==============================================================================
|
||||
void drawGlyph (SavedState& state, Image& image, const Font& font, const int glyphNumber, float x, float y)
|
||||
void drawGlyph (SavedState& state, const Font& font, const int glyphNumber, float x, float y)
|
||||
{
|
||||
++accessCounter;
|
||||
int oldestCounter = std::numeric_limits<int>::max();
|
||||
|
|
@ -2397,7 +2466,7 @@ public:
|
|||
{
|
||||
++hits;
|
||||
glyph->lastAccessCount = accessCounter;
|
||||
glyph->draw (state, image, x, y);
|
||||
glyph->draw (state, x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2423,7 +2492,7 @@ public:
|
|||
jassert (oldest != 0);
|
||||
oldest->lastAccessCount = accessCounter;
|
||||
oldest->generate (font, glyphNumber);
|
||||
oldest->draw (state, image, x, y);
|
||||
oldest->draw (state, x, y);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -2457,7 +2526,7 @@ void LowLevelGraphicsSoftwareRenderer::drawGlyph (int glyphNumber, const AffineT
|
|||
|
||||
if (transform.isOnlyTranslation() && currentState->isOnlyTranslated)
|
||||
{
|
||||
GlyphCache::getInstance()->drawGlyph (*currentState, image, f, glyphNumber,
|
||||
GlyphCache::getInstance()->drawGlyph (*currentState, f, glyphNumber,
|
||||
transform.getTranslationX(),
|
||||
transform.getTranslationY());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,9 @@ public:
|
|||
void saveState();
|
||||
void restoreState();
|
||||
|
||||
void beginTransparencyLayer (float opacity);
|
||||
void endTransparencyLayer();
|
||||
|
||||
//==============================================================================
|
||||
void setFill (const FillType& fillType);
|
||||
void setOpacity (float opacity);
|
||||
|
|
|
|||
|
|
@ -61,8 +61,8 @@ void Drawable::nonConstDraw (Graphics& g, float opacity, const AffineTransform&
|
|||
g.saveState();
|
||||
const float oldOpacity = getAlpha();
|
||||
setAlpha (opacity);
|
||||
g.addTransform (AffineTransform::translation (-originRelativeToComponent.getX(),
|
||||
-originRelativeToComponent.getY())
|
||||
g.addTransform (AffineTransform::translation ((float) -originRelativeToComponent.getX(),
|
||||
(float) -originRelativeToComponent.getY())
|
||||
.followedBy (getTransform())
|
||||
.followedBy (transform));
|
||||
|
||||
|
|
|
|||
|
|
@ -216,19 +216,22 @@ void DrawableComposite::childrenChanged()
|
|||
updateBoundsToFitChildren();
|
||||
}
|
||||
|
||||
struct RentrancyCheckSetter
|
||||
{
|
||||
RentrancyCheckSetter (bool& b_) : b (b_) { b_ = true; }
|
||||
~RentrancyCheckSetter() { b = false; }
|
||||
|
||||
private:
|
||||
bool& b;
|
||||
|
||||
RentrancyCheckSetter (const RentrancyCheckSetter&);
|
||||
RentrancyCheckSetter& operator= (const RentrancyCheckSetter&);
|
||||
};
|
||||
|
||||
void DrawableComposite::updateBoundsToFitChildren()
|
||||
{
|
||||
if (! updateBoundsReentrant)
|
||||
{
|
||||
struct RentrancyCheckSetter
|
||||
{
|
||||
RentrancyCheckSetter (bool& b_) : b (b_) { b_ = true; }
|
||||
~RentrancyCheckSetter() { b = false; }
|
||||
|
||||
private:
|
||||
bool& b;
|
||||
};
|
||||
|
||||
const RentrancyCheckSetter checkSetter (updateBoundsReentrant);
|
||||
|
||||
Rectangle<int> childArea;
|
||||
|
|
|
|||
|
|
@ -151,8 +151,8 @@ const Rectangle<float> DrawableShape::getDrawableBounds() const
|
|||
|
||||
bool DrawableShape::hitTest (int x, int y) const
|
||||
{
|
||||
const float globalX = x - originRelativeToComponent.getX();
|
||||
const float globalY = y - originRelativeToComponent.getY();
|
||||
const float globalX = (float) (x - originRelativeToComponent.getX());
|
||||
const float globalY = (float) (y - originRelativeToComponent.getY());
|
||||
|
||||
return path.contains (globalX, globalY)
|
||||
|| (isStrokeVisible() && strokePath.contains (globalX, globalY));
|
||||
|
|
|
|||
|
|
@ -325,6 +325,19 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void beginTransparencyLayer (float opacity)
|
||||
{
|
||||
saveState();
|
||||
CGContextSetAlpha (context, opacity);
|
||||
CGContextBeginTransparencyLayer (context, 0);
|
||||
}
|
||||
|
||||
void endTransparencyLayer()
|
||||
{
|
||||
CGContextEndTransparencyLayer (context);
|
||||
restoreState();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void setFill (const FillType& fillType)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -182,6 +182,16 @@ public:
|
|||
currentState = states.getLast();
|
||||
}
|
||||
|
||||
void beginTransparencyLayer (float opacity)
|
||||
{
|
||||
jassertfalse; //xxx todo
|
||||
}
|
||||
|
||||
void endTransparencyLayer()
|
||||
{
|
||||
jassertfalse; //xxx todo
|
||||
}
|
||||
|
||||
void setFill (const FillType& fillType)
|
||||
{
|
||||
currentState->setFill (fillType);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue