| @@ -237,7 +237,7 @@ void PaintElement::paint (Graphics& g) | |||
| Rectangle<int> area (((PaintRoutineEditor*) getParentComponent())->getComponentArea()); | |||
| g.saveState(); | |||
| g.setOrigin (area.getX() - getX(), area.getY() - getY()); | |||
| g.setOrigin (area.getPosition() - Component::getPosition()); | |||
| area.setPosition (0, 0); | |||
| g.saveState(); | |||
| @@ -127,11 +127,8 @@ public: | |||
| void convertToPath() | |||
| { | |||
| const Rectangle<int> r (getCurrentAbsoluteBounds()); | |||
| Path path; | |||
| path.addRectangle ((float) r.getX(), (float) r.getY(), (float) r.getWidth(), (float) r.getHeight()); | |||
| path.addRectangle (getCurrentAbsoluteBounds()); | |||
| convertToNewPathElement (path); | |||
| } | |||
| @@ -76,8 +76,8 @@ void PaintRoutineEditor::paint (Graphics& g) | |||
| { | |||
| const Rectangle<int> clip (getComponentArea()); | |||
| g.setOrigin (clip.getX(), clip.getY()); | |||
| g.reduceClipRegion (0, 0, clip.getWidth(), clip.getHeight()); | |||
| g.reduceClipRegion (clip); | |||
| g.setOrigin (clip.getPosition()); | |||
| graphics.fillWithBackground (g, true); | |||
| grid.draw (g, &graphics); | |||
| @@ -175,7 +175,7 @@ public: | |||
| if (glRenderer != nullptr) | |||
| { | |||
| Graphics g (glRenderer); | |||
| Graphics g (*glRenderer); | |||
| g.addTransform (AffineTransform::scale (scale)); | |||
| // This stuff just creates a spinning star shape and fills it.. | |||
| @@ -25,14 +25,18 @@ | |||
| namespace | |||
| { | |||
| template <typename Type> | |||
| bool areCoordsSensibleNumbers (Type x, Type y, Type w, Type h) | |||
| Rectangle<Type> coordsToRectangle (Type x, Type y, Type w, Type h) | |||
| { | |||
| #if JUCE_DEBUG | |||
| const int maxVal = 0x3fffffff; | |||
| return (int) x >= -maxVal && (int) x <= maxVal | |||
| && (int) y >= -maxVal && (int) y <= maxVal | |||
| && (int) w >= -maxVal && (int) w <= maxVal | |||
| && (int) h >= -maxVal && (int) h <= maxVal; | |||
| jassert ((int) x >= -maxVal && (int) x <= maxVal | |||
| && (int) y >= -maxVal && (int) y <= maxVal | |||
| && (int) w >= -maxVal && (int) w <= maxVal | |||
| && (int) h >= -maxVal && (int) h <= maxVal); | |||
| #endif | |||
| return Rectangle<Type> (x, y, w, h); | |||
| } | |||
| } | |||
| @@ -49,11 +53,10 @@ Graphics::Graphics (const Image& imageToDrawOnto) | |||
| jassert (imageToDrawOnto.isValid()); // Can't draw into a null image! | |||
| } | |||
| Graphics::Graphics (LowLevelGraphicsContext* const internalContext) noexcept | |||
| : context (*internalContext), | |||
| Graphics::Graphics (LowLevelGraphicsContext& internalContext) noexcept | |||
| : context (internalContext), | |||
| saveStatePending (false) | |||
| { | |||
| jassert (internalContext != nullptr); | |||
| } | |||
| Graphics::~Graphics() | |||
| @@ -144,10 +147,15 @@ void Graphics::saveStateIfPending() | |||
| } | |||
| } | |||
| void Graphics::setOrigin (const int newOriginX, const int newOriginY) | |||
| void Graphics::setOrigin (Point<int> newOrigin) | |||
| { | |||
| saveStateIfPending(); | |||
| context.setOrigin (newOriginX, newOriginY); | |||
| context.setOrigin (newOrigin); | |||
| } | |||
| void Graphics::setOrigin (int x, int y) | |||
| { | |||
| setOrigin (Point<int> (x, y)); | |||
| } | |||
| void Graphics::addTransform (const AffineTransform& transform) | |||
| @@ -315,37 +323,29 @@ void Graphics::drawFittedText (const String& text, const int x, const int y, con | |||
| const int maximumNumberOfLines, | |||
| const float minimumHorizontalScale) const | |||
| { | |||
| drawFittedText (text,Rectangle<int> (x, y, width, height), | |||
| drawFittedText (text, coordsToRectangle (x, y, width, height), | |||
| justification, maximumNumberOfLines, minimumHorizontalScale); | |||
| } | |||
| //============================================================================== | |||
| void Graphics::fillRect (int x, int y, int width, int height) const | |||
| { | |||
| // passing in a silly number can cause maths problems in rendering! | |||
| jassert (areCoordsSensibleNumbers (x, y, width, height)); | |||
| context.fillRect (Rectangle<int> (x, y, width, height), false); | |||
| } | |||
| void Graphics::fillRect (const Rectangle<int>& r) const | |||
| { | |||
| context.fillRect (r, false); | |||
| } | |||
| void Graphics::fillRect (const Rectangle<float>& rectangle) const | |||
| void Graphics::fillRect (const Rectangle<float>& r) const | |||
| { | |||
| Path p; | |||
| p.addRectangle (rectangle); | |||
| fillPath (p); | |||
| context.fillRect (r); | |||
| } | |||
| void Graphics::fillRect (const float x, const float y, const float width, const float height) const | |||
| void Graphics::fillRect (int x, int y, int width, int height) const | |||
| { | |||
| // passing in a silly number can cause maths problems in rendering! | |||
| jassert (areCoordsSensibleNumbers (x, y, width, height)); | |||
| context.fillRect (coordsToRectangle (x, y, width, height), false); | |||
| } | |||
| fillRect (Rectangle<float> (x, y, width, height)); | |||
| void Graphics::fillRect (float x, float y, float width, float height) const | |||
| { | |||
| fillRect (coordsToRectangle (x, y, width, height)); | |||
| } | |||
| void Graphics::fillRectList (const RectangleList<float>& rectangles) const | |||
| @@ -394,40 +394,29 @@ void Graphics::strokePath (const Path& path, | |||
| } | |||
| //============================================================================== | |||
| void Graphics::drawRect (const int x, const int y, const int width, const int height, | |||
| const int lineThickness) const | |||
| void Graphics::drawRect (float x, float y, float width, float height, float lineThickness) const | |||
| { | |||
| // passing in a silly number can cause maths problems in rendering! | |||
| jassert (areCoordsSensibleNumbers (x, y, width, height)); | |||
| context.fillRect (Rectangle<int> (x, y, width, lineThickness), false); | |||
| context.fillRect (Rectangle<int> (x, y + lineThickness, lineThickness, height - lineThickness * 2), false); | |||
| context.fillRect (Rectangle<int> (x + width - lineThickness, y + lineThickness, lineThickness, height - lineThickness * 2), false); | |||
| context.fillRect (Rectangle<int> (x, y + height - lineThickness, width, lineThickness), false); | |||
| drawRect (coordsToRectangle (x, y, width, height).toFloat()); | |||
| } | |||
| void Graphics::drawRect (const float x, const float y, const float width, const float height, | |||
| const float lineThickness) const | |||
| void Graphics::drawRect (int x, int y, int width, int height, int lineThickness) const | |||
| { | |||
| // passing in a silly number can cause maths problems in rendering! | |||
| jassert (areCoordsSensibleNumbers (x, y, width, height)); | |||
| Path p; | |||
| p.addRectangle (x, y, width, lineThickness); | |||
| p.addRectangle (x, y + lineThickness, lineThickness, height - lineThickness * 2.0f); | |||
| p.addRectangle (x + width - lineThickness, y + lineThickness, lineThickness, height - lineThickness * 2.0f); | |||
| p.addRectangle (x, y + height - lineThickness, width, lineThickness); | |||
| fillPath (p); | |||
| drawRect (coordsToRectangle (x, y, width, height).toFloat()); | |||
| } | |||
| void Graphics::drawRect (const Rectangle<int>& r, const int lineThickness) const | |||
| void Graphics::drawRect (const Rectangle<int>& r, int lineThickness) const | |||
| { | |||
| drawRect (r.getX(), r.getY(), r.getWidth(), r.getHeight(), lineThickness); | |||
| drawRect (r.toFloat(), lineThickness); | |||
| } | |||
| void Graphics::drawRect (const Rectangle<float>& r, const float lineThickness) const | |||
| void Graphics::drawRect (Rectangle<float> r, const float lineThickness) const | |||
| { | |||
| drawRect (r.getX(), r.getY(), r.getWidth(), r.getHeight(), lineThickness); | |||
| RectangleList<float> rects; | |||
| rects.addWithoutMerging (r.removeFromTop (lineThickness)); | |||
| rects.addWithoutMerging (r.removeFromBottom (lineThickness)); | |||
| rects.addWithoutMerging (r.removeFromLeft (lineThickness)); | |||
| rects.addWithoutMerging (r.removeFromRight (lineThickness)); | |||
| context.fillRectList (rects); | |||
| } | |||
| //============================================================================== | |||
| @@ -436,59 +425,46 @@ void Graphics::fillEllipse (const Rectangle<float>& area) const | |||
| fillEllipse (area.getX(), area.getY(), area.getWidth(), area.getHeight()); | |||
| } | |||
| void Graphics::fillEllipse (const float x, const float y, const float width, const float height) const | |||
| void Graphics::fillEllipse (float x, float y, float width, float height) const | |||
| { | |||
| // passing in a silly number can cause maths problems in rendering! | |||
| jassert (areCoordsSensibleNumbers (x, y, width, height)); | |||
| Path p; | |||
| p.addEllipse (x, y, width, height); | |||
| fillPath (p); | |||
| } | |||
| void Graphics::drawEllipse (const float x, const float y, const float width, const float height, | |||
| const float lineThickness) const | |||
| void Graphics::drawEllipse (float x, float y, float width, float height, float lineThickness) const | |||
| { | |||
| // passing in a silly number can cause maths problems in rendering! | |||
| jassert (areCoordsSensibleNumbers (x, y, width, height)); | |||
| Path p; | |||
| p.addEllipse (x, y, width, height); | |||
| strokePath (p, PathStrokeType (lineThickness)); | |||
| } | |||
| void Graphics::fillRoundedRectangle (const float x, const float y, const float width, const float height, const float cornerSize) const | |||
| void Graphics::fillRoundedRectangle (float x, float y, float width, float height, float cornerSize) const | |||
| { | |||
| // passing in a silly number can cause maths problems in rendering! | |||
| jassert (areCoordsSensibleNumbers (x, y, width, height)); | |||
| fillRoundedRectangle (coordsToRectangle (x, y, width, height), cornerSize); | |||
| } | |||
| void Graphics::fillRoundedRectangle (const Rectangle<float>& r, const float cornerSize) const | |||
| { | |||
| Path p; | |||
| p.addRoundedRectangle (x, y, width, height, cornerSize); | |||
| p.addRoundedRectangle (r, cornerSize); | |||
| fillPath (p); | |||
| } | |||
| void Graphics::fillRoundedRectangle (const Rectangle<float>& r, const float cornerSize) const | |||
| void Graphics::drawRoundedRectangle (float x, float y, float width, float height, | |||
| float cornerSize, float lineThickness) const | |||
| { | |||
| fillRoundedRectangle (r.getX(), r.getY(), r.getWidth(), r.getHeight(), cornerSize); | |||
| drawRoundedRectangle (coordsToRectangle (x, y, width, height), cornerSize, lineThickness); | |||
| } | |||
| void Graphics::drawRoundedRectangle (const float x, const float y, const float width, const float height, | |||
| const float cornerSize, const float lineThickness) const | |||
| void Graphics::drawRoundedRectangle (const Rectangle<float>& r, float cornerSize, float lineThickness) const | |||
| { | |||
| // passing in a silly number can cause maths problems in rendering! | |||
| jassert (areCoordsSensibleNumbers (x, y, width, height)); | |||
| Path p; | |||
| p.addRoundedRectangle (x, y, width, height, cornerSize); | |||
| p.addRoundedRectangle (r, cornerSize); | |||
| strokePath (p, PathStrokeType (lineThickness)); | |||
| } | |||
| void Graphics::drawRoundedRectangle (const Rectangle<float>& r, const float cornerSize, const float lineThickness) const | |||
| { | |||
| drawRoundedRectangle (r.getX(), r.getY(), r.getWidth(), r.getHeight(), cornerSize, lineThickness); | |||
| } | |||
| void Graphics::drawArrow (const Line<float>& line, const float lineThickness, const float arrowheadWidth, const float arrowheadLength) const | |||
| void Graphics::drawArrow (const Line<float>& line, float lineThickness, float arrowheadWidth, float arrowheadLength) const | |||
| { | |||
| Path p; | |||
| p.addArrow (line, lineThickness, arrowheadWidth, arrowheadLength); | |||
| @@ -544,25 +520,27 @@ void Graphics::fillCheckerBoard (const Rectangle<int>& area, | |||
| //============================================================================== | |||
| void Graphics::drawVerticalLine (const int x, float top, float bottom) const | |||
| { | |||
| context.drawVerticalLine (x, top, bottom); | |||
| if (top < bottom) | |||
| context.fillRect (Rectangle<float> ((float) x, top, 1.0f, bottom - top)); | |||
| } | |||
| void Graphics::drawHorizontalLine (const int y, float left, float right) const | |||
| { | |||
| context.drawHorizontalLine (y, left, right); | |||
| if (left < right) | |||
| context.fillRect (Rectangle<float> (left, (float) y, right - left, 1.0f)); | |||
| } | |||
| void Graphics::drawLine (const float x1, const float y1, const float x2, const float y2) const | |||
| void Graphics::drawLine (const Line<float>& line) const | |||
| { | |||
| context.drawLine (Line<float> (x1, y1, x2, y2)); | |||
| context.drawLine (line); | |||
| } | |||
| void Graphics::drawLine (const Line<float>& line) const | |||
| void Graphics::drawLine (float x1, float y1, float x2, float y2) const | |||
| { | |||
| context.drawLine (line); | |||
| context.drawLine (Line<float> (x1, y1, x2, y2)); | |||
| } | |||
| void Graphics::drawLine (const float x1, const float y1, const float x2, const float y2, const float lineThickness) const | |||
| void Graphics::drawLine (float x1, float y1, float x2, float y2, float lineThickness) const | |||
| { | |||
| drawLine (Line<float> (x1, y1, x2, y2), lineThickness); | |||
| } | |||
| @@ -616,13 +594,11 @@ void Graphics::setImageResamplingQuality (const Graphics::ResamplingQuality newQ | |||
| } | |||
| //============================================================================== | |||
| void Graphics::drawImageAt (const Image& imageToDraw, | |||
| const int topLeftX, const int topLeftY, | |||
| const bool fillAlphaChannelWithCurrentBrush) const | |||
| void Graphics::drawImageAt (const Image& imageToDraw, int x, int y, bool fillAlphaChannel) const | |||
| { | |||
| drawImageTransformed (imageToDraw, | |||
| AffineTransform::translation ((float) topLeftX, (float) topLeftY), | |||
| fillAlphaChannelWithCurrentBrush); | |||
| AffineTransform::translation ((float) x, (float) y), | |||
| fillAlphaChannel); | |||
| } | |||
| void Graphics::drawImageWithin (const Image& imageToDraw, | |||
| @@ -630,13 +606,10 @@ void Graphics::drawImageWithin (const Image& imageToDraw, | |||
| RectanglePlacement placementWithinTarget, | |||
| const bool fillAlphaChannelWithCurrentBrush) const | |||
| { | |||
| // passing in a silly number can cause maths problems in rendering! | |||
| jassert (areCoordsSensibleNumbers (dx, dy, dw, dh)); | |||
| if (imageToDraw.isValid()) | |||
| drawImageTransformed (imageToDraw, | |||
| placementWithinTarget.getTransformToFit (imageToDraw.getBounds().toFloat(), | |||
| Rectangle<int> (dx, dy, dw, dh).toFloat()), | |||
| coordsToRectangle (dx, dy, dw, dh).toFloat()), | |||
| fillAlphaChannelWithCurrentBrush); | |||
| } | |||
| @@ -645,12 +618,8 @@ void Graphics::drawImage (const Image& imageToDraw, | |||
| int sx, int sy, int sw, int sh, | |||
| const bool fillAlphaChannelWithCurrentBrush) const | |||
| { | |||
| // passing in a silly number can cause maths problems in rendering! | |||
| jassert (areCoordsSensibleNumbers (dx, dy, dw, dh)); | |||
| jassert (areCoordsSensibleNumbers (sx, sy, sw, sh)); | |||
| if (imageToDraw.isValid() && context.clipRegionIntersects (Rectangle<int> (dx, dy, dw, dh))) | |||
| drawImageTransformed (imageToDraw.getClippedImage (Rectangle<int> (sx, sy, sw, sh)), | |||
| if (imageToDraw.isValid() && context.clipRegionIntersects (coordsToRectangle (dx, dy, dw, dh))) | |||
| drawImageTransformed (imageToDraw.getClippedImage (coordsToRectangle (sx, sy, sw, sh)), | |||
| AffineTransform::scale (dw / (float) sw, dh / (float) sh) | |||
| .translated ((float) dx, (float) dy), | |||
| fillAlphaChannelWithCurrentBrush); | |||
| @@ -677,8 +646,7 @@ void Graphics::drawImageTransformed (const Image& imageToDraw, | |||
| } | |||
| //============================================================================== | |||
| Graphics::ScopedSaveState::ScopedSaveState (Graphics& g) | |||
| : context (g) | |||
| Graphics::ScopedSaveState::ScopedSaveState (Graphics& g) : context (g) | |||
| { | |||
| context.saveState(); | |||
| } | |||
| @@ -279,63 +279,48 @@ public: | |||
| void fillRoundedRectangle (const Rectangle<float>& rectangle, | |||
| float cornerSize) const; | |||
| /** Fills a rectangle with a checkerboard pattern, alternating between two colours. | |||
| */ | |||
| /** Fills a rectangle with a checkerboard pattern, alternating between two colours. */ | |||
| void fillCheckerBoard (const Rectangle<int>& area, | |||
| int checkWidth, int checkHeight, | |||
| Colour colour1, Colour colour2) const; | |||
| /** Draws four lines to form a rectangular outline, using the current colour or brush. | |||
| The lines are drawn inside the given rectangle, and greater line thicknesses | |||
| extend inwards. | |||
| /** Draws a rectangular outline, using the current colour or brush. | |||
| The lines are drawn inside the given rectangle, and greater line thicknesses extend inwards. | |||
| @see fillRect | |||
| */ | |||
| void drawRect (int x, int y, int width, int height, int lineThickness = 1) const; | |||
| /** Draws four lines to form a rectangular outline, using the current colour or brush. | |||
| The lines are drawn inside the given rectangle, and greater line thicknesses | |||
| extend inwards. | |||
| /** Draws a rectangular outline, using the current colour or brush. | |||
| The lines are drawn inside the given rectangle, and greater line thicknesses extend inwards. | |||
| @see fillRect | |||
| */ | |||
| void drawRect (float x, float y, float width, float height, float lineThickness = 1.0f) const; | |||
| /** Draws four lines to form a rectangular outline, using the current colour or brush. | |||
| The lines are drawn inside the given rectangle, and greater line thicknesses | |||
| extend inwards. | |||
| /** Draws a rectangular outline, using the current colour or brush. | |||
| The lines are drawn inside the given rectangle, and greater line thicknesses extend inwards. | |||
| @see fillRect | |||
| */ | |||
| void drawRect (const Rectangle<int>& rectangle, int lineThickness = 1) const; | |||
| /** Draws four lines to form a rectangular outline, using the current colour or brush. | |||
| The lines are drawn inside the given rectangle, and greater line thicknesses | |||
| extend inwards. | |||
| /** Draws a rectangular outline, using the current colour or brush. | |||
| The lines are drawn inside the given rectangle, and greater line thicknesses extend inwards. | |||
| @see fillRect | |||
| */ | |||
| void drawRect (const Rectangle<float>& rectangle, float lineThickness = 1.0f) const; | |||
| void drawRect (Rectangle<float> rectangle, float lineThickness = 1.0f) const; | |||
| /** Uses the current colour or brush to draw the outline of a rectangle with rounded corners. | |||
| @see fillRoundedRectangle, Path::addRoundedRectangle | |||
| */ | |||
| void drawRoundedRectangle (float x, float y, float width, float height, | |||
| float cornerSize, float lineThickness) const; | |||
| /** Uses the current colour or brush to draw the outline of a rectangle with rounded corners. | |||
| @see fillRoundedRectangle, Path::addRoundedRectangle | |||
| */ | |||
| void drawRoundedRectangle (const Rectangle<float>& rectangle, | |||
| float cornerSize, float lineThickness) const; | |||
| /** Draws a 1x1 pixel using the current colour or brush. | |||
| /** Fills a 1x1 pixel using the current colour or brush. | |||
| Note that because the context may be transformed, this is effectively the same as | |||
| calling fillRect (x, y, 1, 1), and the actual result may involve multiple pixels. | |||
| */ | |||
| @@ -355,7 +340,6 @@ public: | |||
| void fillEllipse (const Rectangle<float>& area) const; | |||
| /** Draws an elliptical stroke using the current colour or brush. | |||
| @see fillEllipse, Path::addEllipse | |||
| */ | |||
| void drawEllipse (float x, float y, float width, float height, | |||
| @@ -363,26 +347,21 @@ public: | |||
| //============================================================================== | |||
| /** Draws a line between two points. | |||
| The line is 1 pixel wide and drawn with the current colour or brush. | |||
| */ | |||
| void drawLine (float startX, float startY, float endX, float endY) const; | |||
| /** Draws a line between two points with a given thickness. | |||
| @see Path::addLineSegment | |||
| */ | |||
| void drawLine (float startX, float startY, float endX, float endY, | |||
| float lineThickness) const; | |||
| void drawLine (float startX, float startY, float endX, float endY, float lineThickness) const; | |||
| /** Draws a line between two points. | |||
| The line is 1 pixel wide and drawn with the current colour or brush. | |||
| */ | |||
| void drawLine (const Line<float>& line) const; | |||
| /** Draws a line between two points with a given thickness. | |||
| @see Path::addLineSegment | |||
| */ | |||
| void drawLine (const Line<float>& line, float lineThickness) const; | |||
| @@ -422,13 +401,11 @@ public: | |||
| void drawHorizontalLine (int y, float left, float right) const; | |||
| //============================================================================== | |||
| /** Fills a path using the currently selected colour or brush. | |||
| */ | |||
| /** Fills a path using the currently selected colour or brush. */ | |||
| void fillPath (const Path& path, | |||
| const AffineTransform& transform = AffineTransform::identity) const; | |||
| /** Draws a path's outline using the currently selected colour or brush. | |||
| */ | |||
| /** Draws a path's outline using the currently selected colour or brush. */ | |||
| void strokePath (const Path& path, | |||
| const PathStrokeType& strokeType, | |||
| const AffineTransform& transform = AffineTransform::identity) const; | |||
| @@ -459,9 +436,7 @@ public: | |||
| }; | |||
| /** Changes the quality that will be used when resampling images. | |||
| By default a Graphics object will be set to mediumRenderingQuality. | |||
| @see Graphics::drawImage, Graphics::drawImageTransformed, Graphics::drawImageWithin | |||
| */ | |||
| void setImageResamplingQuality (const ResamplingQuality newQuality); | |||
| @@ -560,7 +535,6 @@ public: | |||
| //============================================================================== | |||
| /** Returns the position of the bounding box for the current clipping region. | |||
| @see getClipRegion, clipRegionIntersects | |||
| */ | |||
| Rectangle<int> getClipBounds() const; | |||
| @@ -639,12 +613,11 @@ public: | |||
| class ScopedSaveState | |||
| { | |||
| public: | |||
| ScopedSaveState (Graphics& g); | |||
| ScopedSaveState (Graphics&); | |||
| ~ScopedSaveState(); | |||
| private: | |||
| Graphics& context; | |||
| JUCE_DECLARE_NON_COPYABLE (ScopedSaveState) | |||
| }; | |||
| @@ -666,6 +639,18 @@ public: | |||
| */ | |||
| void endTransparencyLayer(); | |||
| /** Moves the position of the context's origin. | |||
| This changes the position that the context considers to be (0, 0) to | |||
| the specified position. | |||
| So if you call setOrigin with (100, 100), then the position that was previously | |||
| referred to as (100, 100) will subsequently be considered to be (0, 0). | |||
| @see reduceClipRegion, addTransform | |||
| */ | |||
| void setOrigin (Point<int> newOrigin); | |||
| /** Moves the position of the context's origin. | |||
| This changes the position that the context considers to be (0, 0) to | |||
| @@ -695,11 +680,11 @@ public: | |||
| bool isVectorDevice() const; | |||
| //============================================================================== | |||
| /** Create a graphics that uses a given low-level renderer. | |||
| For internal use only. | |||
| NB. The context will NOT be deleted by this object when it is deleted. | |||
| /** Create a graphics that draws with a given low-level renderer. | |||
| This method is intended for use only by people who know what they're doing. | |||
| Note that the LowLevelGraphicsContext will NOT be deleted by this object. | |||
| */ | |||
| Graphics (LowLevelGraphicsContext*) noexcept; | |||
| Graphics (LowLevelGraphicsContext&) noexcept; | |||
| /** @internal */ | |||
| LowLevelGraphicsContext& getInternalContext() const noexcept { return context; } | |||
| @@ -707,7 +692,7 @@ public: | |||
| private: | |||
| //============================================================================== | |||
| LowLevelGraphicsContext& context; | |||
| ScopedPointer <LowLevelGraphicsContext> contextToDelete; | |||
| ScopedPointer<LowLevelGraphicsContext> contextToDelete; | |||
| bool saveStatePending; | |||
| void saveStateIfPending(); | |||
| @@ -58,7 +58,7 @@ public: | |||
| The coordinates are relative to the current origin, and indicate the new position | |||
| of (0, 0). | |||
| */ | |||
| virtual void setOrigin (int x, int y) = 0; | |||
| virtual void setOrigin (Point<int>) = 0; | |||
| virtual void addTransform (const AffineTransform&) = 0; | |||
| virtual float getPhysicalPixelScaleFactor() = 0; | |||
| @@ -80,20 +80,16 @@ public: | |||
| //============================================================================== | |||
| virtual void setFill (const FillType&) = 0; | |||
| virtual void setOpacity (float newOpacity) = 0; | |||
| virtual void setOpacity (float) = 0; | |||
| virtual void setInterpolationQuality (Graphics::ResamplingQuality) = 0; | |||
| //============================================================================== | |||
| virtual void fillRect (const Rectangle<int>&, bool replaceExistingContents) = 0; | |||
| virtual void fillRect (const Rectangle<float>&) = 0; | |||
| virtual void fillRectList (const RectangleList<float>&) = 0; | |||
| virtual void fillPath (const Path&, const AffineTransform&) = 0; | |||
| virtual void drawImage (const Image&, const AffineTransform&) = 0; | |||
| virtual void drawLine (const Line <float>&) = 0; | |||
| virtual void drawVerticalLine (int x, float top, float bottom) = 0; | |||
| virtual void drawHorizontalLine (int y, float left, float right) = 0; | |||
| virtual void drawLine (const Line<float>&) = 0; | |||
| virtual void setFont (const Font&) = 0; | |||
| virtual const Font& getFont() = 0; | |||
| @@ -89,12 +89,12 @@ bool LowLevelGraphicsPostScriptRenderer::isVectorDevice() const | |||
| return true; | |||
| } | |||
| void LowLevelGraphicsPostScriptRenderer::setOrigin (int x, int y) | |||
| void LowLevelGraphicsPostScriptRenderer::setOrigin (Point<int> o) | |||
| { | |||
| if (x != 0 || y != 0) | |||
| if (! o.isOrigin()) | |||
| { | |||
| stateStack.getLast()->xOffset += x; | |||
| stateStack.getLast()->yOffset += y; | |||
| stateStack.getLast()->xOffset += o.x; | |||
| stateStack.getLast()->yOffset += o.y; | |||
| needToClip = true; | |||
| } | |||
| } | |||
| @@ -335,13 +335,18 @@ void LowLevelGraphicsPostScriptRenderer::setInterpolationQuality (Graphics::Resa | |||
| //============================================================================== | |||
| void LowLevelGraphicsPostScriptRenderer::fillRect (const Rectangle<int>& r, const bool /*replaceExistingContents*/) | |||
| { | |||
| fillRect (r.toFloat()); | |||
| } | |||
| void LowLevelGraphicsPostScriptRenderer::fillRect (const Rectangle<float>& r) | |||
| { | |||
| if (stateStack.getLast()->fillType.isColour()) | |||
| { | |||
| writeClip(); | |||
| writeColour (stateStack.getLast()->fillType.colour); | |||
| Rectangle<int> r2 (r.translated (stateStack.getLast()->xOffset, stateStack.getLast()->yOffset)); | |||
| Rectangle<float> r2 (r.translated (stateStack.getLast()->xOffset, stateStack.getLast()->yOffset)); | |||
| out << r2.getX() << ' ' << -r2.getBottom() << ' ' << r2.getWidth() << ' ' << r2.getHeight() << " rectfill\n"; | |||
| } | |||
| @@ -355,12 +360,7 @@ void LowLevelGraphicsPostScriptRenderer::fillRect (const Rectangle<int>& r, cons | |||
| void LowLevelGraphicsPostScriptRenderer::fillRectList (const RectangleList<float>& list) | |||
| { | |||
| for (const Rectangle<float>* r = list.begin(), * const e = list.end(); r != e; ++r) | |||
| { | |||
| Path p; | |||
| p.addRectangle (*r); | |||
| fillPath (p, AffineTransform::identity); | |||
| } | |||
| fillPath (list.toPath(), AffineTransform::identity); | |||
| } | |||
| //============================================================================== | |||
| @@ -512,16 +512,6 @@ void LowLevelGraphicsPostScriptRenderer::drawLine (const Line <float>& line) | |||
| fillPath (p, AffineTransform::identity); | |||
| } | |||
| void LowLevelGraphicsPostScriptRenderer::drawVerticalLine (const int x, float top, float bottom) | |||
| { | |||
| drawLine (Line<float> ((float) x, top, (float) x, bottom)); | |||
| } | |||
| void LowLevelGraphicsPostScriptRenderer::drawHorizontalLine (const int y, float left, float right) | |||
| { | |||
| drawLine (Line<float> (left, (float) y, right, (float) y)); | |||
| } | |||
| //============================================================================== | |||
| void LowLevelGraphicsPostScriptRenderer::setFont (const Font& newFont) | |||
| { | |||
| @@ -45,7 +45,7 @@ public: | |||
| //============================================================================== | |||
| bool isVectorDevice() const override; | |||
| void setOrigin (int x, int y) override; | |||
| void setOrigin (Point<int>) override; | |||
| void addTransform (const AffineTransform&) override; | |||
| float getPhysicalPixelScaleFactor() override; | |||
| @@ -72,12 +72,11 @@ public: | |||
| //============================================================================== | |||
| void fillRect (const Rectangle<int>&, bool replaceExistingContents) override; | |||
| void fillRect (const Rectangle<float>&) override; | |||
| void fillRectList (const RectangleList<float>&) 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; | |||
| //============================================================================== | |||
| const Font& getFont() override; | |||
| @@ -66,13 +66,13 @@ public: | |||
| #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS | |||
| RectangleList (RectangleList&& other) noexcept | |||
| : rects (static_cast <Array <RectangleType >&&> (other.rects)) | |||
| : rects (static_cast<Array<RectangleType>&&> (other.rects)) | |||
| { | |||
| } | |||
| RectangleList& operator= (RectangleList&& other) noexcept | |||
| { | |||
| rects = static_cast <Array <RectangleType >&&> (other.rects); | |||
| rects = static_cast<Array<RectangleType>&&> (other.rects); | |||
| return *this; | |||
| } | |||
| #endif | |||
| @@ -85,17 +85,9 @@ public: | |||
| int getNumRectangles() const noexcept { return rects.size(); } | |||
| /** Returns one of the rectangles at a particular index. | |||
| @returns the rectangle at the index, or an empty rectangle if the | |||
| index is out-of-range. | |||
| @returns the rectangle at the index, or an empty rectangle if the index is out-of-range. | |||
| */ | |||
| RectangleType getRectangle (int index) const noexcept | |||
| { | |||
| if (isPositiveAndBelow (index, rects.size())) | |||
| return rects.getReference (index); | |||
| return RectangleType(); | |||
| } | |||
| RectangleType getRectangle (int index) const noexcept { return rects[index]; } | |||
| //============================================================================== | |||
| /** Removes all rectangles to leave an empty region. */ | |||
| @@ -297,7 +289,6 @@ public: | |||
| return rects.size() > 0; | |||
| } | |||
| /** Removes any areas of the region that lie outside a given rectangle. | |||
| Any rectangles in the list which overlap this will be clipped and subdivided | |||
| @@ -362,7 +353,6 @@ public: | |||
| } | |||
| swapWith (result); | |||
| return ! isEmpty(); | |||
| } | |||
| @@ -139,7 +139,7 @@ public: | |||
| { | |||
| LowLevelGraphicsContext* g = image->createLowLevelContext(); | |||
| g->clipToRectangle (area); | |||
| g->setOrigin (area.getX(), area.getY()); | |||
| g->setOrigin (area.getPosition()); | |||
| return g; | |||
| } | |||
| @@ -2586,7 +2586,7 @@ class StackBasedLowLevelGraphicsContext : public LowLevelGraphicsContext | |||
| { | |||
| public: | |||
| bool isVectorDevice() const override { return false; } | |||
| void setOrigin (int x, int y) override { stack->transform.setOrigin (Point<int> (x, y)); } | |||
| void setOrigin (Point<int> o) override { stack->transform.setOrigin (o); } | |||
| void addTransform (const AffineTransform& t) override { stack->transform.addTransform (t); } | |||
| float getPhysicalPixelScaleFactor() override { return stack->transform.getPhysicalPixelScaleFactor(); } | |||
| Rectangle<int> getClipBounds() const override { return stack->getClipBounds(); } | |||
| @@ -2605,11 +2605,10 @@ public: | |||
| 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 fillRect (const Rectangle<float>& r) override { stack->fillRect (r); } | |||
| void fillRectList (const RectangleList<float>& list) override { stack->fillRectList (list); } | |||
| 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; } | |||
| @@ -35,7 +35,7 @@ public: | |||
| //============================================================================== | |||
| bool isVectorDevice() const override { return false; } | |||
| void setOrigin (int x, int y) override; | |||
| void setOrigin (Point<int>) override; | |||
| void addTransform (const AffineTransform&) override; | |||
| float getPhysicalPixelScaleFactor() override; | |||
| bool clipToRectangle (const Rectangle<int>&) override; | |||
| @@ -60,14 +60,13 @@ public: | |||
| //============================================================================== | |||
| void fillRect (const Rectangle<int>&, bool replaceExistingContents) override; | |||
| void fillRect (const Rectangle<float>&) override; | |||
| void fillRectList (const RectangleList<float>&) override; | |||
| void fillPath (const Path&, const AffineTransform&) override; | |||
| void drawImage (const Image& sourceImage, const AffineTransform&) override; | |||
| //============================================================================== | |||
| void drawLine (const Line<float>&) override; | |||
| void drawVerticalLine (const int x, float top, float bottom) override; | |||
| void drawHorizontalLine (const int y, float left, float right) override; | |||
| void setFont (const Font&) override; | |||
| const Font& getFont() override; | |||
| void drawGlyph (int glyphNumber, const AffineTransform&) override; | |||
| @@ -153,12 +153,12 @@ CoreGraphicsContext::~CoreGraphicsContext() | |||
| } | |||
| //============================================================================== | |||
| void CoreGraphicsContext::setOrigin (int x, int y) | |||
| void CoreGraphicsContext::setOrigin (Point<int> o) | |||
| { | |||
| CGContextTranslateCTM (context, x, -y); | |||
| CGContextTranslateCTM (context, o.x, -o.y); | |||
| if (lastClipRectIsValid) | |||
| lastClipRect.translate (-x, -y); | |||
| lastClipRect.translate (-o.x, -o.y); | |||
| } | |||
| void CoreGraphicsContext::addTransform (const AffineTransform& transform) | |||
| @@ -362,6 +362,11 @@ void CoreGraphicsContext::fillRect (const Rectangle<int>& r, const bool replaceE | |||
| fillCGRect (CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()), replaceExistingContents); | |||
| } | |||
| void CoreGraphicsContext::fillRect (const Rectangle<float>& r) | |||
| { | |||
| fillCGRect (CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()), false); | |||
| } | |||
| void CoreGraphicsContext::fillCGRect (const CGRect& cgRect, const bool replaceExistingContents) | |||
| { | |||
| if (replaceExistingContents) | |||
| @@ -520,42 +525,6 @@ void CoreGraphicsContext::drawLine (const Line<float>& line) | |||
| } | |||
| } | |||
| void CoreGraphicsContext::drawVerticalLine (const int x, float top, float bottom) | |||
| { | |||
| if (state->fillType.isColour()) | |||
| { | |||
| #if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 | |||
| CGContextFillRect (context, CGRectMake (x, flipHeight - bottom, 1.0f, bottom - top)); | |||
| #else | |||
| // On Leopard, unless both coordinates are non-integer, it disables anti-aliasing, so nudge | |||
| // the x coordinate slightly to trick it.. | |||
| CGContextFillRect (context, CGRectMake (x + 1.0f / 256.0f, flipHeight - bottom, 1.0f + 1.0f / 256.0f, bottom - top)); | |||
| #endif | |||
| } | |||
| else | |||
| { | |||
| fillCGRect (CGRectMake ((float) x, flipHeight - bottom, 1.0f, bottom - top), false); | |||
| } | |||
| } | |||
| void CoreGraphicsContext::drawHorizontalLine (const int y, float left, float right) | |||
| { | |||
| if (state->fillType.isColour()) | |||
| { | |||
| #if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 | |||
| CGContextFillRect (context, CGRectMake (left, flipHeight - (y + 1.0f), right - left, 1.0f)); | |||
| #else | |||
| // On Leopard, unless both coordinates are non-integer, it disables anti-aliasing, so nudge | |||
| // the x coordinate slightly to trick it.. | |||
| CGContextFillRect (context, CGRectMake (left, flipHeight - (y + (1.0f + 1.0f / 256.0f)), right - left, 1.0f + 1.0f / 256.0f)); | |||
| #endif | |||
| } | |||
| else | |||
| { | |||
| fillCGRect (CGRectMake (left, flipHeight - (y + 1), right - left, 1.0f), false); | |||
| } | |||
| } | |||
| void CoreGraphicsContext::fillRectList (const RectangleList<float>& list) | |||
| { | |||
| HeapBlock<CGRect> rects (list.getNumRectangles()); | |||
| @@ -82,9 +82,9 @@ public: | |||
| bool isVectorDevice() const { return false; } | |||
| void setOrigin (int x, int y) | |||
| void setOrigin (Point<int> o) | |||
| { | |||
| addTransform (AffineTransform::translation ((float) x, (float) y)); | |||
| addTransform (AffineTransform::translation ((float) o.x, (float) o.y)); | |||
| } | |||
| void addTransform (const AffineTransform& transform) | |||
| @@ -178,6 +178,11 @@ public: | |||
| } | |||
| void fillRect (const Rectangle<int>& r, bool /*replaceExistingContents*/) | |||
| { | |||
| fillRect (r.toFloat()); | |||
| } | |||
| void fillRect (const Rectangle<float>& r) | |||
| { | |||
| renderingTarget->SetTransform (transformToMatrix (currentState->transform)); | |||
| currentState->createBrush(); | |||
| @@ -237,30 +242,6 @@ public: | |||
| renderingTarget->SetTransform (D2D1::IdentityMatrix()); | |||
| } | |||
| void drawVerticalLine (int x, float top, float bottom) | |||
| { | |||
| // xxx doesn't seem to be correctly aligned, may need nudging by 0.5 to match the software renderer's behaviour | |||
| renderingTarget->SetTransform (transformToMatrix (currentState->transform)); | |||
| currentState->createBrush(); | |||
| renderingTarget->DrawLine (D2D1::Point2F ((FLOAT) x, top), | |||
| D2D1::Point2F ((FLOAT) x, bottom), | |||
| currentState->currentBrush); | |||
| renderingTarget->SetTransform (D2D1::IdentityMatrix()); | |||
| } | |||
| void drawHorizontalLine (int y, float left, float right) | |||
| { | |||
| // xxx doesn't seem to be correctly aligned, may need nudging by 0.5 to match the software renderer's behaviour | |||
| renderingTarget->SetTransform (transformToMatrix (currentState->transform)); | |||
| currentState->createBrush(); | |||
| renderingTarget->DrawLine (D2D1::Point2F (left, (FLOAT) y), | |||
| D2D1::Point2F (right, (FLOAT) y), | |||
| currentState->currentBrush); | |||
| renderingTarget->SetTransform (D2D1::IdentityMatrix()); | |||
| } | |||
| void setFont (const Font& newFont) | |||
| { | |||
| currentState->setFont (newFont); | |||
| @@ -723,7 +704,8 @@ private: | |||
| OwnedArray<SavedState> states; | |||
| //============================================================================== | |||
| static D2D1_RECT_F rectangleToRectF (const Rectangle<int>& r) | |||
| template <typename Type> | |||
| static D2D1_RECT_F rectangleToRectF (const Rectangle<Type>& r) | |||
| { | |||
| return D2D1::RectF ((float) r.getX(), (float) r.getY(), (float) r.getRight(), (float) r.getBottom()); | |||
| } | |||
| @@ -1882,7 +1882,7 @@ void Component::paintOverChildren (Graphics&) | |||
| //============================================================================== | |||
| void Component::paintWithinParentContext (Graphics& g) | |||
| { | |||
| g.setOrigin (getX(), getY()); | |||
| g.setOrigin (getPosition()); | |||
| if (cachedImage != nullptr) | |||
| cachedImage->paint (g); | |||
| @@ -2026,7 +2026,7 @@ Image Component::createComponentSnapshot (const Rectangle<int>& areaToGrab, | |||
| r.getWidth(), r.getHeight(), true); | |||
| Graphics imageContext (componentImage); | |||
| imageContext.setOrigin (-r.getX(), -r.getY()); | |||
| imageContext.setOrigin (-r.getPosition()); | |||
| paintEntireComponent (imageContext, true); | |||
| return componentImage; | |||
| @@ -87,8 +87,7 @@ DrawableComposite* Drawable::getParent() const | |||
| void Drawable::transformContextToCorrectOrigin (Graphics& g) | |||
| { | |||
| g.setOrigin (originRelativeToComponent.x, | |||
| originRelativeToComponent.y); | |||
| g.setOrigin (originRelativeToComponent); | |||
| } | |||
| void Drawable::parentHierarchyChanged() | |||
| @@ -39,7 +39,7 @@ void BubbleComponent::paint (Graphics& g) | |||
| getLookAndFeel().drawBubble (g, *this, arrowTip.toFloat(), content.toFloat()); | |||
| g.reduceClipRegion (content); | |||
| g.setOrigin (content.getX(), content.getY()); | |||
| g.setOrigin (content.getPosition()); | |||
| paintContent (g, content.getWidth(), content.getHeight()); | |||
| } | |||
| @@ -403,7 +403,7 @@ public: | |||
| { | |||
| LowLevelGraphicsSoftwareRenderer g (temp); | |||
| g.setOrigin (-clip.getX(), -clip.getY()); | |||
| g.setOrigin (-clip.getPosition()); | |||
| handlePaint (g); | |||
| } | |||
| } | |||
| @@ -906,10 +906,8 @@ Image ListBox::createSnapshotOfSelectedRows (int& imageX, int& imageY) | |||
| if (rowComp != nullptr && isRowSelected (firstRow + i)) | |||
| { | |||
| const Point<int> pos (getLocalPoint (rowComp, Point<int>())); | |||
| Graphics g (snapshot); | |||
| g.setOrigin (pos.getX() - imageX, pos.getY() - imageY); | |||
| g.setOrigin (getLocalPoint (rowComp, Point<int>()) - imageArea.getPosition()); | |||
| if (g.reduceClipRegion (rowComp->getLocalBounds())) | |||
| { | |||
| @@ -187,7 +187,7 @@ void ToolbarItemComponent::paintButton (Graphics& g, const bool over, const bool | |||
| Graphics::ScopedSaveState ss (g); | |||
| g.reduceClipRegion (contentArea); | |||
| g.setOrigin (contentArea.getX(), contentArea.getY()); | |||
| g.setOrigin (contentArea.getPosition()); | |||
| paintButtonArea (g, contentArea.getWidth(), contentArea.getHeight(), over, down); | |||
| } | |||
| @@ -106,7 +106,7 @@ void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) | |||
| { | |||
| ModifierKeys::updateCurrentModifiers(); | |||
| Graphics g (&contextToPaintTo); | |||
| Graphics g (contextToPaintTo); | |||
| if (component.isTransformed()) | |||
| g.addTransform (component.getTransform()); | |||
| @@ -202,7 +202,7 @@ void DocumentWindow::paint (Graphics& g) | |||
| const Rectangle<int> titleBarArea (getTitleBarArea()); | |||
| g.reduceClipRegion (titleBarArea); | |||
| g.setOrigin (titleBarArea.getX(), titleBarArea.getY()); | |||
| g.setOrigin (titleBarArea.getPosition()); | |||
| int titleSpaceX1 = 6; | |||
| int titleSpaceX2 = titleBarArea.getWidth() - 6; | |||
| @@ -259,7 +259,7 @@ public: | |||
| void paintOwner (LowLevelGraphicsContext& llgc) | |||
| { | |||
| Graphics g (&llgc); | |||
| Graphics g (llgc); | |||
| #if JUCE_ENABLE_REPAINT_DEBUGGING | |||
| g.saveState(); | |||