| @@ -41501,11 +41501,8 @@ void Component::paintComponent (Graphics& g) | |||||
| } | } | ||||
| } | } | ||||
| void Component::paintTransformedChild (Graphics& g) | |||||
| void Component::paintWithinParentContext (Graphics& g) | |||||
| { | { | ||||
| if (affineTransform_ != 0) | |||||
| g.addTransform (*affineTransform_); | |||||
| g.setOrigin (getX(), getY()); | g.setOrigin (getX(), getY()); | ||||
| paintEntireComponent (g, false); | paintEntireComponent (g, false); | ||||
| } | } | ||||
| @@ -41531,39 +41528,52 @@ void Component::paintComponentAndChildren (Graphics& g) | |||||
| for (int i = 0; i < childComponentList_.size(); ++i) | for (int i = 0; i < childComponentList_.size(); ++i) | ||||
| { | { | ||||
| Component* const child = childComponentList_.getUnchecked (i); | |||||
| Component& child = *childComponentList_.getUnchecked (i); | |||||
| if (child->isVisible() && clipBounds.intersects (child->getBounds())) | |||||
| if (child.isVisible()) | |||||
| { | { | ||||
| g.saveState(); | |||||
| if (child->flags.dontClipGraphicsFlag) | |||||
| if (child.affineTransform_ != 0) | |||||
| { | { | ||||
| child->paintTransformedChild (g); | |||||
| g.saveState(); | |||||
| g.addTransform (*child.affineTransform_); | |||||
| if (child.flags.dontClipGraphicsFlag || g.reduceClipRegion (child.getBounds())) | |||||
| child.paintWithinParentContext (g); | |||||
| g.restoreState(); | |||||
| } | } | ||||
| else | |||||
| else if (clipBounds.intersects (child.getBounds())) | |||||
| { | { | ||||
| if (g.reduceClipRegion (child->getBounds())) | |||||
| { | |||||
| bool nothingClipped = true; | |||||
| g.saveState(); | |||||
| for (int j = i + 1; j < childComponentList_.size(); ++j) | |||||
| if (child.flags.dontClipGraphicsFlag) | |||||
| { | |||||
| child.paintWithinParentContext (g); | |||||
| } | |||||
| else | |||||
| { | |||||
| if (g.reduceClipRegion (child.getBounds())) | |||||
| { | { | ||||
| const Component* const sibling = childComponentList_.getUnchecked (j); | |||||
| bool nothingClipped = true; | |||||
| if (sibling->flags.opaqueFlag && sibling->isVisible()) | |||||
| for (int j = i + 1; j < childComponentList_.size(); ++j) | |||||
| { | { | ||||
| nothingClipped = false; | |||||
| g.excludeClipRegion (sibling->getBounds()); | |||||
| const Component& sibling = *childComponentList_.getUnchecked (j); | |||||
| if (sibling.flags.opaqueFlag && sibling.isVisible() && sibling.affineTransform_ == 0) | |||||
| { | |||||
| nothingClipped = false; | |||||
| g.excludeClipRegion (sibling.getBounds()); | |||||
| } | |||||
| } | } | ||||
| } | |||||
| if (nothingClipped || ! g.isClipEmpty()) | |||||
| child->paintTransformedChild (g); | |||||
| if (nothingClipped || ! g.isClipEmpty()) | |||||
| child.paintWithinParentContext (g); | |||||
| } | |||||
| } | } | ||||
| } | |||||
| g.restoreState(); | |||||
| g.restoreState(); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -82085,6 +82095,7 @@ void Graphics::setOrigin (const int newOriginX, const int newOriginY) | |||||
| void Graphics::addTransform (const AffineTransform& transform) | void Graphics::addTransform (const AffineTransform& transform) | ||||
| { | { | ||||
| saveStateIfPending(); | |||||
| context->addTransform (transform); | context->addTransform (transform); | ||||
| } | } | ||||
| @@ -91528,6 +91539,21 @@ const AffineTransform AffineTransform::scale (const float factorX, | |||||
| 0, factorY, 0); | 0, factorY, 0); | ||||
| } | } | ||||
| const AffineTransform AffineTransform::scaled (const float factorX, const float factorY, | |||||
| const float pivotX, const float pivotY) const throw() | |||||
| { | |||||
| return translated (-pivotX, -pivotY) | |||||
| .scaled (factorX, factorY) | |||||
| .translated (pivotX, pivotY); | |||||
| } | |||||
| const AffineTransform AffineTransform::scale (const float factorX, const float factorY, | |||||
| const float pivotX, const float pivotY) throw() | |||||
| { | |||||
| return AffineTransform (factorX, 0, pivotX * (1.0f - factorX), | |||||
| 0, factorY, pivotY * (1.0f - factorY)); | |||||
| } | |||||
| const AffineTransform AffineTransform::sheared (const float shearX, | const AffineTransform AffineTransform::sheared (const float shearX, | ||||
| const float shearY) const throw() | const float shearY) const throw() | ||||
| { | { | ||||
| @@ -19566,16 +19566,25 @@ public: | |||||
| float pivotY) throw(); | float pivotY) throw(); | ||||
| /** Returns a transform which is the same as this one followed by a re-scaling. | /** Returns a transform which is the same as this one followed by a re-scaling. | ||||
| The scaling is centred around the origin (0, 0). | The scaling is centred around the origin (0, 0). | ||||
| */ | */ | ||||
| const AffineTransform scaled (float factorX, | const AffineTransform scaled (float factorX, | ||||
| float factorY) const throw(); | float factorY) const throw(); | ||||
| /** Returns a transform which is the same as this one followed by a re-scaling. | |||||
| The scaling is centred around the origin provided. | |||||
| */ | |||||
| const AffineTransform scaled (float factorX, float factorY, | |||||
| float pivotX, float pivotY) const throw(); | |||||
| /** Returns a new transform which is a re-scale about the origin. */ | /** Returns a new transform which is a re-scale about the origin. */ | ||||
| static const AffineTransform scale (float factorX, | static const AffineTransform scale (float factorX, | ||||
| float factorY) throw(); | float factorY) throw(); | ||||
| /** Returns a new transform which is a re-scale centred around the point provided. */ | |||||
| static const AffineTransform scale (float factorX, float factorY, | |||||
| float pivotX, float pivotY) throw(); | |||||
| /** Returns a transform which is the same as this one followed by a shear. | /** Returns a transform which is the same as this one followed by a shear. | ||||
| The shear is centred around the origin (0, 0). | The shear is centred around the origin (0, 0). | ||||
| @@ -28002,7 +28011,7 @@ private: | |||||
| void internalHierarchyChanged(); | void internalHierarchyChanged(); | ||||
| void paintComponentAndChildren (Graphics& g); | void paintComponentAndChildren (Graphics& g); | ||||
| void paintComponent (Graphics& g); | void paintComponent (Graphics& g); | ||||
| void paintTransformedChild (Graphics& g); | |||||
| void paintWithinParentContext (Graphics& g); | |||||
| void sendMovedResizedMessages (bool wasMoved, bool wasResized); | void sendMovedResizedMessages (bool wasMoved, bool wasResized); | ||||
| void repaintParent(); | void repaintParent(); | ||||
| void sendFakeMouseMove() const; | void sendFakeMouseMove() const; | ||||
| @@ -1792,11 +1792,8 @@ void Component::paintComponent (Graphics& g) | |||||
| } | } | ||||
| } | } | ||||
| void Component::paintTransformedChild (Graphics& g) | |||||
| void Component::paintWithinParentContext (Graphics& g) | |||||
| { | { | ||||
| if (affineTransform_ != 0) | |||||
| g.addTransform (*affineTransform_); | |||||
| g.setOrigin (getX(), getY()); | g.setOrigin (getX(), getY()); | ||||
| paintEntireComponent (g, false); | paintEntireComponent (g, false); | ||||
| } | } | ||||
| @@ -1822,39 +1819,52 @@ void Component::paintComponentAndChildren (Graphics& g) | |||||
| for (int i = 0; i < childComponentList_.size(); ++i) | for (int i = 0; i < childComponentList_.size(); ++i) | ||||
| { | { | ||||
| Component* const child = childComponentList_.getUnchecked (i); | |||||
| Component& child = *childComponentList_.getUnchecked (i); | |||||
| if (child->isVisible() && clipBounds.intersects (child->getBounds())) | |||||
| if (child.isVisible()) | |||||
| { | { | ||||
| g.saveState(); | |||||
| if (child->flags.dontClipGraphicsFlag) | |||||
| if (child.affineTransform_ != 0) | |||||
| { | { | ||||
| child->paintTransformedChild (g); | |||||
| g.saveState(); | |||||
| g.addTransform (*child.affineTransform_); | |||||
| if (child.flags.dontClipGraphicsFlag || g.reduceClipRegion (child.getBounds())) | |||||
| child.paintWithinParentContext (g); | |||||
| g.restoreState(); | |||||
| } | } | ||||
| else | |||||
| else if (clipBounds.intersects (child.getBounds())) | |||||
| { | { | ||||
| if (g.reduceClipRegion (child->getBounds())) | |||||
| { | |||||
| bool nothingClipped = true; | |||||
| g.saveState(); | |||||
| for (int j = i + 1; j < childComponentList_.size(); ++j) | |||||
| if (child.flags.dontClipGraphicsFlag) | |||||
| { | |||||
| child.paintWithinParentContext (g); | |||||
| } | |||||
| else | |||||
| { | |||||
| if (g.reduceClipRegion (child.getBounds())) | |||||
| { | { | ||||
| const Component* const sibling = childComponentList_.getUnchecked (j); | |||||
| bool nothingClipped = true; | |||||
| if (sibling->flags.opaqueFlag && sibling->isVisible()) | |||||
| for (int j = i + 1; j < childComponentList_.size(); ++j) | |||||
| { | { | ||||
| nothingClipped = false; | |||||
| g.excludeClipRegion (sibling->getBounds()); | |||||
| const Component& sibling = *childComponentList_.getUnchecked (j); | |||||
| if (sibling.flags.opaqueFlag && sibling.isVisible() && sibling.affineTransform_ == 0) | |||||
| { | |||||
| nothingClipped = false; | |||||
| g.excludeClipRegion (sibling.getBounds()); | |||||
| } | |||||
| } | } | ||||
| } | |||||
| if (nothingClipped || ! g.isClipEmpty()) | |||||
| child->paintTransformedChild (g); | |||||
| if (nothingClipped || ! g.isClipEmpty()) | |||||
| child.paintWithinParentContext (g); | |||||
| } | |||||
| } | } | ||||
| } | |||||
| g.restoreState(); | |||||
| g.restoreState(); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -2188,7 +2188,7 @@ private: | |||||
| void internalHierarchyChanged(); | void internalHierarchyChanged(); | ||||
| void paintComponentAndChildren (Graphics& g); | void paintComponentAndChildren (Graphics& g); | ||||
| void paintComponent (Graphics& g); | void paintComponent (Graphics& g); | ||||
| void paintTransformedChild (Graphics& g); | |||||
| void paintWithinParentContext (Graphics& g); | |||||
| void sendMovedResizedMessages (bool wasMoved, bool wasResized); | void sendMovedResizedMessages (bool wasMoved, bool wasResized); | ||||
| void repaintParent(); | void repaintParent(); | ||||
| void sendFakeMouseMove() const; | void sendFakeMouseMove() const; | ||||
| @@ -167,6 +167,7 @@ void Graphics::setOrigin (const int newOriginX, const int newOriginY) | |||||
| void Graphics::addTransform (const AffineTransform& transform) | void Graphics::addTransform (const AffineTransform& transform) | ||||
| { | { | ||||
| saveStateIfPending(); | |||||
| context->addTransform (transform); | context->addTransform (transform); | ||||
| } | } | ||||
| @@ -197,6 +197,21 @@ const AffineTransform AffineTransform::scale (const float factorX, | |||||
| 0, factorY, 0); | 0, factorY, 0); | ||||
| } | } | ||||
| const AffineTransform AffineTransform::scaled (const float factorX, const float factorY, | |||||
| const float pivotX, const float pivotY) const throw() | |||||
| { | |||||
| return translated (-pivotX, -pivotY) | |||||
| .scaled (factorX, factorY) | |||||
| .translated (pivotX, pivotY); | |||||
| } | |||||
| const AffineTransform AffineTransform::scale (const float factorX, const float factorY, | |||||
| const float pivotX, const float pivotY) throw() | |||||
| { | |||||
| return AffineTransform (factorX, 0, pivotX * (1.0f - factorX), | |||||
| 0, factorY, pivotY * (1.0f - factorY)); | |||||
| } | |||||
| const AffineTransform AffineTransform::sheared (const float shearX, | const AffineTransform AffineTransform::sheared (const float shearX, | ||||
| const float shearY) const throw() | const float shearY) const throw() | ||||
| { | { | ||||
| @@ -158,16 +158,25 @@ public: | |||||
| float pivotY) throw(); | float pivotY) throw(); | ||||
| /** Returns a transform which is the same as this one followed by a re-scaling. | /** Returns a transform which is the same as this one followed by a re-scaling. | ||||
| The scaling is centred around the origin (0, 0). | The scaling is centred around the origin (0, 0). | ||||
| */ | */ | ||||
| const AffineTransform scaled (float factorX, | const AffineTransform scaled (float factorX, | ||||
| float factorY) const throw(); | float factorY) const throw(); | ||||
| /** Returns a transform which is the same as this one followed by a re-scaling. | |||||
| The scaling is centred around the origin provided. | |||||
| */ | |||||
| const AffineTransform scaled (float factorX, float factorY, | |||||
| float pivotX, float pivotY) const throw(); | |||||
| /** Returns a new transform which is a re-scale about the origin. */ | /** Returns a new transform which is a re-scale about the origin. */ | ||||
| static const AffineTransform scale (float factorX, | static const AffineTransform scale (float factorX, | ||||
| float factorY) throw(); | float factorY) throw(); | ||||
| /** Returns a new transform which is a re-scale centred around the point provided. */ | |||||
| static const AffineTransform scale (float factorX, float factorY, | |||||
| float pivotX, float pivotY) throw(); | |||||
| /** Returns a transform which is the same as this one followed by a shear. | /** Returns a transform which is the same as this one followed by a shear. | ||||
| The shear is centred around the origin (0, 0). | The shear is centred around the origin (0, 0). | ||||