@@ -111,8 +111,8 @@ TransformKind transformKindOf(Float32List matrix) {
111111
112112 // If matrix contains scaling, rotation, z translation or
113113 // perspective transform, it is not considered simple.
114- final bool isSimple2dTransform =
115- m[ 15 ] == 1.0 && // start reading from the last element to eliminate range checks in subsequent reads.
114+ final bool isSimple2dTransform = m[ 15 ] ==
115+ 1.0 && // start reading from the last element to eliminate range checks in subsequent reads.
116116 m[14 ] == 0.0 && // z translation is NOT simple
117117 // m[13] - y translation is simple
118118 // m[12] - x translation is simple
@@ -126,8 +126,8 @@ TransformKind transformKindOf(Float32List matrix) {
126126 // m[4] - 2D rotation is simple
127127 m[3 ] == 0.0 &&
128128 m[2 ] == 0.0 ;
129- // m[1] - 2D rotation is simple
130- // m[0] - scale x is simple
129+ // m[1] - 2D rotation is simple
130+ // m[0] - scale x is simple
131131
132132 if (! isSimple2dTransform) {
133133 return TransformKind .complex;
@@ -136,8 +136,7 @@ TransformKind transformKindOf(Float32List matrix) {
136136 // From this point on we're sure the transform is 2D, but we don't know if
137137 // it's identity or not. To check, we need to look at the remaining elements
138138 // that were not checked above.
139- final bool isIdentityTransform =
140- m[0 ] == 1.0 &&
139+ final bool isIdentityTransform = m[0 ] == 1.0 &&
141140 m[1 ] == 0.0 &&
142141 m[4 ] == 0.0 &&
143142 m[5 ] == 1.0 &&
@@ -165,7 +164,7 @@ bool isIdentityFloat32ListTransform(Float32List matrix) {
165164/// transform. Consider removing the CSS `transform` property from elements
166165/// that apply identity transform.
167166String float64ListToCssTransform2d (Float32List matrix) {
168- assert (transformKindOf (matrix) != TransformKind .complex);
167+ assert (transformKindOf (matrix) != TransformKind .complex);
169168 return 'matrix(${matrix [0 ]},${matrix [1 ]},${matrix [4 ]},${matrix [5 ]},${matrix [12 ]},${matrix [13 ]})' ;
170169}
171170
@@ -279,10 +278,22 @@ void transformLTRB(Matrix4 transform, Float32List ltrb) {
279278
280279 _tempPointMatrix.multiplyTranspose (transform);
281280
282- ltrb[0 ] = math.min (math.min (math.min (_tempPointData[0 ], _tempPointData[1 ]), _tempPointData[2 ]), _tempPointData[3 ]);
283- ltrb[1 ] = math.min (math.min (math.min (_tempPointData[4 ], _tempPointData[5 ]), _tempPointData[6 ]), _tempPointData[7 ]);
284- ltrb[2 ] = math.max (math.max (math.max (_tempPointData[0 ], _tempPointData[1 ]), _tempPointData[2 ]), _tempPointData[3 ]);
285- ltrb[3 ] = math.max (math.max (math.max (_tempPointData[4 ], _tempPointData[5 ]), _tempPointData[6 ]), _tempPointData[7 ]);
281+ ltrb[0 ] = math.min (
282+ math.min (
283+ math.min (_tempPointData[0 ], _tempPointData[1 ]), _tempPointData[2 ]),
284+ _tempPointData[3 ]);
285+ ltrb[1 ] = math.min (
286+ math.min (
287+ math.min (_tempPointData[4 ], _tempPointData[5 ]), _tempPointData[6 ]),
288+ _tempPointData[7 ]);
289+ ltrb[2 ] = math.max (
290+ math.max (
291+ math.max (_tempPointData[0 ], _tempPointData[1 ]), _tempPointData[2 ]),
292+ _tempPointData[3 ]);
293+ ltrb[3 ] = math.max (
294+ math.max (
295+ math.max (_tempPointData[4 ], _tempPointData[5 ]), _tempPointData[6 ]),
296+ _tempPointData[7 ]);
286297}
287298
288299/// Returns true if [rect] contains every point that is also contained by the
@@ -300,6 +311,13 @@ bool rectContainsOther(ui.Rect rect, ui.Rect other) {
300311/// Counter used for generating clip path id inside an svg <defs> tag.
301312int _clipIdCounter = 0 ;
302313
314+ /// Used for clipping and filter svg resources.
315+ ///
316+ /// Position needs to be absolute since these svgs are sandwiched between
317+ /// canvas elements and can cause layout shifts otherwise.
318+ const String kSvgResourceHeader = '<svg width="0" height="0" '
319+ 'style="position:absolute">' ;
320+
303321/// Converts Path to svg element that contains a clip-path definition.
304322///
305323/// Calling this method updates [_clipIdCounter] . The HTML id of the generated
@@ -311,8 +329,7 @@ String _pathToSvgClipPath(ui.Path path,
311329 double scaleY = 1.0 }) {
312330 _clipIdCounter += 1 ;
313331 final StringBuffer sb = StringBuffer ();
314- sb.write ('<svg width="0" height="0" '
315- 'style="position:absolute">' );
332+ sb.write (kSvgResourceHeader);
316333 sb.write ('<defs>' );
317334
318335 final String clipId = 'svgClip$_clipIdCounter ' ;
@@ -420,10 +437,11 @@ const Set<String> _genericFontFamilies = <String>{
420437///
421438/// For iOS, default to -apple-system, where it should be available, otherwise
422439/// default to Arial. BlinkMacSystemFont is used for Chrome on iOS.
423- final String _fallbackFontFamily = _isMacOrIOS ?
424- '-apple-system, BlinkMacSystemFont' : 'Arial' ;
440+ final String _fallbackFontFamily =
441+ _isMacOrIOS ? '-apple-system, BlinkMacSystemFont' : 'Arial' ;
425442
426- bool get _isMacOrIOS => operatingSystem == OperatingSystem .iOs ||
443+ bool get _isMacOrIOS =>
444+ operatingSystem == OperatingSystem .iOs ||
427445 operatingSystem == OperatingSystem .macOs;
428446
429447/// Create a font-family string appropriate for CSS.
@@ -439,8 +457,10 @@ String? canonicalizeFontFamily(String? fontFamily) {
439457 // on sans-serif.
440458 // Map to San Francisco Text/Display fonts, use -apple-system,
441459 // BlinkMacSystemFont.
442- if (fontFamily == '.SF Pro Text' || fontFamily == '.SF Pro Display' ||
443- fontFamily == '.SF UI Text' || fontFamily == '.SF UI Display' ) {
460+ if (fontFamily == '.SF Pro Text' ||
461+ fontFamily == '.SF Pro Display' ||
462+ fontFamily == '.SF UI Text' ||
463+ fontFamily == '.SF UI Display' ) {
444464 return _fallbackFontFamily;
445465 }
446466 }
@@ -474,27 +494,27 @@ void applyWebkitClipFix(html.Element? containerElement) {
474494 }
475495}
476496
477- final ByteData ? _fontChangeMessage = JSONMessageCodec ().encodeMessage (< String , dynamic > {'type' : 'fontsChange' });
497+ final ByteData ? _fontChangeMessage =
498+ JSONMessageCodec ().encodeMessage (< String , dynamic > {'type' : 'fontsChange' });
478499
479500// Font load callbacks will typically arrive in sequence, we want to prevent
480501// sendFontChangeMessage of causing multiple synchronous rebuilds.
481502// This flag ensures we properly schedule a single call to framework.
482503bool _fontChangeScheduled = false ;
483504
484505FutureOr <void > sendFontChangeMessage () async {
485- if (window._onPlatformMessage != null )
486- if (! _fontChangeScheduled) {
487- _fontChangeScheduled = true ;
488- // Batch updates into next animationframe.
489- html.window.requestAnimationFrame ((num _) {
490- _fontChangeScheduled = false ;
491- window.invokeOnPlatformMessage (
492- 'flutter/system' ,
493- _fontChangeMessage,
494- (_) {},
495- );
496- });
497- }
506+ if (window._onPlatformMessage != null && ! _fontChangeScheduled) {
507+ _fontChangeScheduled = true ;
508+ // Batch updates into next animationframe.
509+ html.window.requestAnimationFrame ((num _) {
510+ _fontChangeScheduled = false ;
511+ window.invokeOnPlatformMessage (
512+ 'flutter/system' ,
513+ _fontChangeMessage,
514+ (_) {},
515+ );
516+ });
517+ }
498518}
499519
500520// Stores matrix in a form that allows zero allocation transforms.
@@ -535,14 +555,12 @@ bool isUnsoundNull(dynamic object) {
535555}
536556
537557bool _offsetIsValid (ui.Offset offset) {
538- assert (offset != null , 'Offset argument was null.' ); // ignore: unnecessary_null_comparison
539558 assert (! offset.dx.isNaN && ! offset.dy.isNaN,
540559 'Offset argument contained a NaN value.' );
541560 return true ;
542561}
543562
544563bool _matrix4IsValid (Float32List matrix4) {
545- assert (matrix4 != null , 'Matrix4 argument was null.' ); // ignore: unnecessary_null_comparison
546564 assert (matrix4.length == 16 , 'Matrix4 must have 16 entries.' );
547565 return true ;
548566}
0 commit comments