| 683 | if (visibilityChanged) { |
| 684 | _viewNodeTree->flushVisibilityObservers(); |
| 685 | } |
| 686 | } |
| 687 | |
| 688 | bool ViewNode::doUpdateVisibility(const Valdi::Frame& viewport, |
| 689 | bool parentHasChanged, |
| 690 | bool parentIsVisible, |
| 691 | int& visitedNodes) { |
| 692 | visitedNodes++; |
| 693 | |
| 694 | auto needsUpdate = calculatedViewportNeedsUpdate() || parentHasChanged; |
| 695 | auto childrenNeedsUpdate = calculatedViewportHasChildNeedsUpdate(); |
| 696 | auto viewportChanged = false; |
| 697 | auto changed = false; |
| 698 | |
| 699 | if (needsUpdate) { |
| 700 | Frame clipRect; |
| 701 | |
| 702 | auto visibleInViewport = parentIsVisible; |
| 703 | |
| 704 | // Only bother calculating the viewport if the parent is visible, |
| 705 | // otherwise viewport is assumed to be empty frame. |
| 706 | if (parentIsVisible) { |
| 707 | auto bounds = calculateSelfViewport(); |
| 708 | |
| 709 | if (VALDI_UNLIKELY(ignoreParentViewport())) { |
| 710 | clipRect = bounds; |
| 711 | } else { |
| 712 | visibleInViewport = bounds.intersects(viewport); |
| 713 | if (visibleInViewport) { |
| 714 | clipRect = bounds.intersection(viewport); |
| 715 | } |
| 716 | } |
| 717 | |
| 718 | if (visibleInViewport) { |
| 719 | clipRect.x -= bounds.x; |
| 720 | clipRect.y -= bounds.y; |
| 721 | |
| 722 | // Reverse-map the clip rect from visual (scaled) space back into |
| 723 | // the local coordinate space so children see the correct visible |
| 724 | // range. Negative scale also flips the axis; positive scale != 1 |
| 725 | // only compresses/expands without flipping. |
| 726 | if (_scaleX < 0.0f) { |
| 727 | const float absScaleX = -_scaleX; |
| 728 | clipRect.x = (bounds.width - (clipRect.x + clipRect.width)) / absScaleX; |
| 729 | clipRect.width = clipRect.width / absScaleX; |
| 730 | } else if (_scaleX > 0.0f && _scaleX != 1.0f) { |
| 731 | clipRect.x /= _scaleX; |
| 732 | clipRect.width /= _scaleX; |
| 733 | } |
| 734 | if (_scaleY < 0.0f) { |
| 735 | const float absScaleY = -_scaleY; |
| 736 | clipRect.y = (bounds.height - (clipRect.y + clipRect.height)) / absScaleY; |
| 737 | clipRect.height = clipRect.height / absScaleY; |
| 738 | } else if (_scaleY > 0.0f && _scaleY != 1.0f) { |
| 739 | clipRect.y /= _scaleY; |
| 740 | clipRect.height /= _scaleY; |
| 741 | } |
| 742 |
nothing calls this directly
no test coverage detected