1
- using System ;
2
- using System . Collections . Generic ;
3
- using Unity . UIWidgets . external . simplejson ;
1
+ using System . Collections . Generic ;
2
+ using System . Linq ;
3
+ using System . Text ;
4
4
using Unity . UIWidgets . foundation ;
5
5
using Unity . UIWidgets . painting ;
6
6
using Unity . UIWidgets . ui ;
@@ -243,7 +243,7 @@ public Layer firstChild {
243
243
public Layer lastChild {
244
244
get { return this . _lastChild ; }
245
245
}
246
-
246
+
247
247
internal override S find < S > ( Offset regionOffset ) {
248
248
Layer current = this . lastChild ;
249
249
while ( current != null ) {
@@ -282,6 +282,95 @@ bool _debugUltimateNextSiblingOf(Layer child, Layer equals = null) {
282
282
return child == equals ;
283
283
}
284
284
285
+ PictureLayer _highlightConflictingLayer ( PhysicalModelLayer child ) {
286
+ PictureRecorder recorder = new PictureRecorder ( ) ;
287
+ var canvas = new RecorderCanvas ( recorder ) ;
288
+ canvas . drawPath ( child . clipPath , new Paint ( ) {
289
+ color = new Color ( 0xFFAA0000 ) ,
290
+ style = PaintingStyle . stroke ,
291
+ strokeWidth = child . elevation + 10.0f ,
292
+ } ) ;
293
+ PictureLayer pictureLayer = new PictureLayer ( child . clipPath . getBounds ( ) ) ;
294
+ pictureLayer . picture = recorder . endRecording ( ) ;
295
+ pictureLayer . debugCreator = child ;
296
+ child . append ( pictureLayer ) ;
297
+ return pictureLayer ;
298
+ }
299
+
300
+ List < PictureLayer > _processConflictingPhysicalLayers ( PhysicalModelLayer predecessor , PhysicalModelLayer child ) {
301
+ UIWidgetsError . reportError ( new UIWidgetsErrorDetails (
302
+ exception : new UIWidgetsError ( "Painting order is out of order with respect to elevation.\n " +
303
+ "See https://api.flutter.dev/flutter/rendering/debugCheckElevations.html " +
304
+ "for more details." ) ,
305
+ context : "during compositing" ,
306
+ informationCollector : ( StringBuilder builder ) => {
307
+ builder . AppendLine ( "Attempted to composite layer" ) ;
308
+ builder . AppendLine ( child . ToString ( ) ) ;
309
+ builder . AppendLine ( "after layer" ) ;
310
+ builder . AppendLine ( predecessor . ToString ( ) ) ;
311
+ builder . AppendLine ( "which occupies the same area at a higher elevation." ) ;
312
+ }
313
+ ) ) ;
314
+ return new List < PictureLayer > {
315
+ this . _highlightConflictingLayer ( predecessor ) ,
316
+ this . _highlightConflictingLayer ( child )
317
+ } ;
318
+ }
319
+
320
+ protected List < PictureLayer > _debugCheckElevations ( ) {
321
+ List < PhysicalModelLayer > physicalModelLayers =
322
+ this . depthFirstIterateChildren ( ) . OfType < PhysicalModelLayer > ( ) . ToList ( ) ;
323
+ List < PictureLayer > addedLayers = new List < PictureLayer > ( ) ;
324
+
325
+ for ( int i = 0 ; i < physicalModelLayers . Count ; i ++ ) {
326
+ PhysicalModelLayer physicalModelLayer = physicalModelLayers [ i ] ;
327
+ D . assert ( physicalModelLayer . lastChild ? . debugCreator != physicalModelLayer ,
328
+ ( ) => "debugCheckElevations has either already visited this layer or failed to remove the" +
329
+ " added picture from it." ) ;
330
+ float accumulatedElevation = physicalModelLayer . elevation ;
331
+ Layer ancestor = physicalModelLayer . parent ;
332
+ while ( ancestor != null ) {
333
+ if ( ancestor is PhysicalModelLayer modelLayer ) {
334
+ accumulatedElevation += modelLayer . elevation ;
335
+ }
336
+
337
+ ancestor = ancestor . parent ;
338
+ }
339
+
340
+ for ( int j = 0 ; j <= i ; j ++ ) {
341
+ PhysicalModelLayer predecessor = physicalModelLayers [ j ] ;
342
+ float predecessorAccumulatedElevation = predecessor . elevation ;
343
+ ancestor = predecessor . parent ;
344
+ while ( ancestor != null ) {
345
+ if ( ancestor == predecessor ) {
346
+ continue ;
347
+ }
348
+
349
+ if ( ancestor is PhysicalModelLayer modelLayer ) {
350
+ predecessorAccumulatedElevation += modelLayer . elevation ;
351
+ }
352
+
353
+ ancestor = ancestor . parent ;
354
+ }
355
+
356
+ if ( predecessorAccumulatedElevation <= accumulatedElevation ) {
357
+ continue ;
358
+ }
359
+
360
+ Path intersection = Path . combine (
361
+ PathOperation . intersect ,
362
+ predecessor . _debugTransformedClipPath ,
363
+ physicalModelLayer . _debugTransformedClipPath ) ;
364
+
365
+ if ( intersection != null && intersection . computeMetrics ( ) . Any ( ( metric ) => metric . length > 0 ) ) {
366
+ addedLayers . AddRange ( this . _processConflictingPhysicalLayers ( predecessor , physicalModelLayer ) ) ;
367
+ }
368
+ }
369
+ }
370
+
371
+ return addedLayers ;
372
+ }
373
+
285
374
internal override void updateSubtreeNeedsAddToScene ( ) {
286
375
base . updateSubtreeNeedsAddToScene ( ) ;
287
376
Layer child = this . firstChild ;
@@ -419,6 +508,25 @@ public virtual void applyTransform(Layer child, Matrix3 transform) {
419
508
D . assert ( transform != null ) ;
420
509
}
421
510
511
+ public List < Layer > depthFirstIterateChildren ( ) {
512
+ if ( this . firstChild == null ) {
513
+ return new List < Layer > ( ) ;
514
+ }
515
+
516
+ List < Layer > children = new List < Layer > ( ) ;
517
+ Layer child = this . firstChild ;
518
+ while ( child != null ) {
519
+ children . Add ( child ) ;
520
+ if ( child is ContainerLayer containerLayer ) {
521
+ children . AddRange ( containerLayer . depthFirstIterateChildren ( ) ) ;
522
+ }
523
+
524
+ child = child . nextSibling ;
525
+ }
526
+
527
+ return children ;
528
+ }
529
+
422
530
public override List < DiagnosticsNode > debugDescribeChildren ( ) {
423
531
var children = new List < DiagnosticsNode > ( ) ;
424
532
if ( this . firstChild == null ) {
@@ -470,9 +578,27 @@ public override void applyTransform(Layer child, Matrix3 transform) {
470
578
}
471
579
472
580
public Scene buildScene ( SceneBuilder builder ) {
581
+ List < PictureLayer > temporaryLayers = null ;
582
+ D . assert ( ( ) => {
583
+ if ( RenderingDebugUtils . debugCheckElevationsEnabled ) {
584
+ temporaryLayers = this . _debugCheckElevations ( ) ;
585
+ }
586
+
587
+ return true ;
588
+ } ) ;
473
589
this . updateSubtreeNeedsAddToScene ( ) ;
474
590
this . addToScene ( builder ) ;
475
- return builder . build ( ) ;
591
+ Scene scene = builder . build ( ) ;
592
+ D . assert ( ( ) => {
593
+ if ( temporaryLayers != null ) {
594
+ foreach ( PictureLayer temporaryLayer in temporaryLayers ) {
595
+ temporaryLayer . remove ( ) ;
596
+ }
597
+ }
598
+
599
+ return true ;
600
+ } ) ;
601
+ return scene ;
476
602
}
477
603
478
604
internal override flow . Layer addToScene ( SceneBuilder builder , Offset layerOffset = null ) {
@@ -731,7 +857,7 @@ internal override S find<S>(Offset regionOffset) {
731
857
if ( this . _invertedTransform == null ) {
732
858
return null ;
733
859
}
734
-
860
+
735
861
Offset transform = this . _invertedTransform . mapXY ( regionOffset . dx , regionOffset . dy ) ;
736
862
return base . find < S > ( transform ) ;
737
863
}
@@ -756,7 +882,13 @@ internal override flow.Layer addToScene(SceneBuilder builder, Offset layerOffset
756
882
public override void applyTransform ( Layer child , Matrix3 transform ) {
757
883
D . assert ( child != null ) ;
758
884
D . assert ( transform != null ) ;
759
- transform . preConcat ( this . _lastEffectiveTransform ) ;
885
+ D . assert ( this . _lastEffectiveTransform != null || this . transform != null ) ;
886
+ if ( this . _lastEffectiveTransform == null ) {
887
+ transform . preConcat ( this . transform ) ;
888
+ }
889
+ else {
890
+ transform . preConcat ( this . _lastEffectiveTransform ) ;
891
+ }
760
892
}
761
893
762
894
public override void debugFillProperties ( DiagnosticPropertiesBuilder properties ) {
@@ -822,7 +954,7 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties)
822
954
properties . add ( new DiagnosticsProperty < Offset > ( "offset" , this . offset ) ) ;
823
955
}
824
956
}
825
-
957
+
826
958
public class BackdropFilterLayer : ContainerLayer {
827
959
public BackdropFilterLayer ( ImageFilter filter = null ) {
828
960
D . assert ( filter != null ) ;
@@ -1043,7 +1175,7 @@ void _establishTransform() {
1043
1175
protected override bool alwaysNeedsAddToScene {
1044
1176
get { return true ; }
1045
1177
}
1046
-
1178
+
1047
1179
1048
1180
internal override flow . Layer addToScene ( SceneBuilder builder , Offset layerOffset = null ) {
1049
1181
layerOffset = layerOffset ?? Offset . zero ;
@@ -1217,6 +1349,20 @@ public Clip clipBehavior {
1217
1349
}
1218
1350
}
1219
1351
1352
+ internal Path _debugTransformedClipPath {
1353
+ get {
1354
+ ContainerLayer ancestor = this . parent ;
1355
+ Matrix3 matrix = Matrix3 . I ( ) ;
1356
+ while ( ancestor != null && ancestor . parent != null ) {
1357
+ ancestor . applyTransform ( this , matrix ) ;
1358
+ ancestor = ancestor . parent ;
1359
+ }
1360
+
1361
+ return this . clipPath . transform ( matrix ) ;
1362
+ }
1363
+ }
1364
+
1365
+
1220
1366
Clip _clipBehavior ;
1221
1367
1222
1368
public float elevation {
0 commit comments