| @@ -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()); | |||
| paintEntireComponent (g, false); | |||
| } | |||
| @@ -41531,39 +41528,52 @@ void Component::paintComponentAndChildren (Graphics& g) | |||
| 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) | |||
| { | |||
| saveStateIfPending(); | |||
| context->addTransform (transform); | |||
| } | |||
| @@ -91528,6 +91539,21 @@ const AffineTransform AffineTransform::scale (const float factorX, | |||
| 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 float shearY) const throw() | |||
| { | |||
| @@ -19566,16 +19566,25 @@ public: | |||
| float pivotY) throw(); | |||
| /** Returns a transform which is the same as this one followed by a re-scaling. | |||
| The scaling is centred around the origin (0, 0). | |||
| */ | |||
| const AffineTransform scaled (float factorX, | |||
| 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. */ | |||
| static const AffineTransform scale (float factorX, | |||
| 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. | |||
| The shear is centred around the origin (0, 0). | |||
| @@ -28002,7 +28011,7 @@ private: | |||
| void internalHierarchyChanged(); | |||
| void paintComponentAndChildren (Graphics& g); | |||
| void paintComponent (Graphics& g); | |||
| void paintTransformedChild (Graphics& g); | |||
| void paintWithinParentContext (Graphics& g); | |||
| void sendMovedResizedMessages (bool wasMoved, bool wasResized); | |||
| void repaintParent(); | |||
| 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()); | |||
| paintEntireComponent (g, false); | |||
| } | |||
| @@ -1822,39 +1819,52 @@ void Component::paintComponentAndChildren (Graphics& g) | |||
| 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 paintComponentAndChildren (Graphics& g); | |||
| void paintComponent (Graphics& g); | |||
| void paintTransformedChild (Graphics& g); | |||
| void paintWithinParentContext (Graphics& g); | |||
| void sendMovedResizedMessages (bool wasMoved, bool wasResized); | |||
| void repaintParent(); | |||
| void sendFakeMouseMove() const; | |||
| @@ -167,6 +167,7 @@ void Graphics::setOrigin (const int newOriginX, const int newOriginY) | |||
| void Graphics::addTransform (const AffineTransform& transform) | |||
| { | |||
| saveStateIfPending(); | |||
| context->addTransform (transform); | |||
| } | |||
| @@ -197,6 +197,21 @@ const AffineTransform AffineTransform::scale (const float factorX, | |||
| 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 float shearY) const throw() | |||
| { | |||
| @@ -158,16 +158,25 @@ public: | |||
| float pivotY) throw(); | |||
| /** Returns a transform which is the same as this one followed by a re-scaling. | |||
| The scaling is centred around the origin (0, 0). | |||
| */ | |||
| const AffineTransform scaled (float factorX, | |||
| 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. */ | |||
| static const AffineTransform scale (float factorX, | |||
| 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. | |||
| The shear is centred around the origin (0, 0). | |||