@@ -36,6 +36,7 @@ THE SOFTWARE.
3636#include " base/CCEventFocus.h"
3737#include " base/CCStencilStateManager.h"
3838#include " editor-support/cocostudio/CocosStudioExtension.h"
39+ #include < algorithm>
3940
4041
4142NS_CC_BEGIN
@@ -220,6 +221,9 @@ void Layout::visit(Renderer *renderer, const Mat4 &parentTransform, uint32_t par
220221 return ;
221222 }
222223
224+ if (FLAGS_TRANSFORM_DIRTY & parentFlags || _transformUpdated || _contentSizeDirty)
225+ _clippingRectDirty = true ;
226+
223227 adaptRenderers ();
224228 doLayout ();
225229
@@ -239,7 +243,8 @@ void Layout::visit(Renderer *renderer, const Mat4 &parentTransform, uint32_t par
239243 }
240244 else
241245 {
242- Widget::visit (renderer, parentTransform, parentFlags);
246+ // no need to adapt render again
247+ ProtectedNode::visit (renderer, parentTransform, parentFlags);
243248 }
244249}
245250
@@ -475,16 +480,20 @@ const Rect& Layout::getClippingRect()
475480{
476481 if (_clippingRectDirty)
477482 {
478- const Vec2 worldPos = convertToWorldSpace (Vec2::ZERO);
479- const AffineTransform t = getNodeToWorldAffineTransform ();
480- const float scissorWidth = _contentSize.width * t.a ;
481- const float scissorHeight = _contentSize.height * t.d ;
483+ const auto worldPos1 = convertToWorldSpace (Vec2::ZERO);
484+ const auto worldPos2 = convertToWorldSpace (Vec2 (_contentSize.width , _contentSize.height ));
485+
486+ // Node can be flipped
487+ const auto worldPos = Vec2 (std::min (worldPos1.x , worldPos2.x ), std::min (worldPos1.y , worldPos2.y ));
488+ const auto scissorWidth = std::fabs (worldPos2.x - worldPos1.x );
489+ const auto scissorHeight = std::fabs (worldPos2.y - worldPos1.y );
490+
482491 Layout* parent = this ;
483492
484493 while (parent)
485494 {
486495 parent = dynamic_cast <Layout*>(parent->getParent ());
487- if (parent)
496+ if (parent)
488497 {
489498 if (parent->isClippingEnabled ())
490499 {
@@ -493,49 +502,19 @@ const Rect& Layout::getClippingRect()
493502 }
494503 }
495504 }
496-
505+
497506 if (_clippingParent)
498507 {
499- const Rect& parentClippingRect = _clippingParent->getClippingRect ();
500- float finalX = worldPos.x ;
501- float finalY = worldPos.y ;
502- float finalWidth = scissorWidth;
503- float finalHeight = scissorHeight;
504-
505- const float leftOffset = worldPos.x - parentClippingRect.origin .x ;
506- if (leftOffset < 0 .0f )
507- {
508- finalX = parentClippingRect.origin .x ;
509- finalWidth += leftOffset;
510- }
511- const float rightOffset = (worldPos.x + scissorWidth) - (parentClippingRect.origin .x + parentClippingRect.size .width );
512- if (rightOffset > 0 .0f )
513- {
514- finalWidth -= rightOffset;
515- }
516- const float topOffset = (worldPos.y + scissorHeight) - (parentClippingRect.origin .y + parentClippingRect.size .height );
517- if (topOffset > 0 .0f )
518- {
519- finalHeight -= topOffset;
520- }
521- const float bottomOffset = worldPos.y - parentClippingRect.origin .y ;
522- if (bottomOffset < 0 .0f )
523- {
524- finalY = parentClippingRect.origin .y ;
525- finalHeight += bottomOffset;
526- }
527- if (finalWidth < 0 .0f )
528- {
529- finalWidth = 0 .0f ;
530- }
531- if (finalHeight < 0 .0f )
532- {
533- finalHeight = 0 .0f ;
534- }
535- _clippingRect.origin .x = finalX;
536- _clippingRect.origin .y = finalY;
537- _clippingRect.size .width = finalWidth;
538- _clippingRect.size .height = finalHeight;
508+ const auto & parentClippingRect = _clippingParent->getClippingRect ();
509+
510+ _clippingRect.origin .x = std::max (parentClippingRect.origin .x , worldPos.x );
511+ _clippingRect.origin .y = std::max (parentClippingRect.origin .y , worldPos.y );
512+
513+ const auto right = std::min (parentClippingRect.origin .x + parentClippingRect.size .width , worldPos.x + scissorWidth);
514+ const auto top = std::min (parentClippingRect.origin .y + parentClippingRect.size .height , worldPos.y + scissorHeight);
515+
516+ _clippingRect.size .width = std::max (0 .0f , right - _clippingRect.origin .x );
517+ _clippingRect.size .height = std::max (0 .0f , top - _clippingRect.origin .y );
539518 }
540519 else
541520 {
0 commit comments